35
35
from bacpypes3 .comm import bind
36
36
37
37
from thingsboard_gateway .connectors .bacnet .application_service_access_point import ApplicationServiceAccessPoint
38
- from thingsboard_gateway .connectors .bacnet .device import Device
39
38
from thingsboard_gateway .connectors .bacnet .entities .device_object_config import DeviceObjectConfig
40
39
41
40
@@ -106,61 +105,48 @@ async def do_who_is(self, device_address):
106
105
async def get_object_identifiers_with_segmentation (
107
106
self , device_address : Address , device_identifier : ObjectIdentifier
108
107
) -> List [ObjectIdentifier ]:
109
- try :
110
- object_list = await self .read_property (
111
- device_address , device_identifier , "objectList"
112
- )
113
- return object_list
114
- except AbortPDU as e :
115
- self .__log .warning (f"{ device_identifier } objectList abort: { e } " )
116
- except ErrorRejectAbortNack as e :
117
- self .__log .warning (f"{ device_identifier } objectList error/reject: { e } " )
118
- except ErrorPDU :
119
- self .__log .error ('ErrorPDU reading object-list' )
120
- except Exception as e :
121
- self .__log .error (f"{ device_identifier } objectList error: { e } " )
108
+ object_list = await self .__send_request_wrapper (self .read_property ,
109
+ err_msg = f"Failed to read { device_identifier } object-list" ,
110
+ address = device_address ,
111
+ objid = device_identifier ,
112
+ prop = 'objectList' ,
113
+ array_index = 0 )
114
+
115
+ if object_list is None :
116
+ return []
122
117
123
- return []
118
+ return object_list
124
119
125
120
async def get_object_identifiers_without_segmentation (
126
121
self , device_address : Address , device_identifier : ObjectIdentifier
127
122
) -> List [ObjectIdentifier ]:
128
123
object_list = []
129
124
130
- try :
131
- object_list_length = await self .read_property (
132
- device_address ,
133
- device_identifier ,
134
- "objectList" ,
135
- array_index = 0 ,
136
- )
137
- except ErrorPDU :
138
- self .__log .error ('ErrorPDU reading object-list length' )
139
- return []
140
- except Exception as e :
141
- self .__log .error ('%s error reading object-list length: %s' , device_identifier , e )
125
+ object_list_length = await self .__send_request_wrapper (self .read_property ,
126
+ err_msg = f"Failed to read { device_identifier } object-list length" , # noqa
127
+ address = device_address ,
128
+ objid = device_identifier ,
129
+ prop = 'objectList' ,
130
+ array_index = 0 )
131
+
132
+ if object_list_length is None :
142
133
return []
143
134
144
135
for i in range (object_list_length ):
145
- try :
146
- object_identifier = await self .read_property (
147
- device_address ,
148
- device_identifier ,
149
- "objectList" ,
150
- array_index = i + 1 ,
151
- )
152
-
153
- if object_identifier [0 ].__str__ () == 'device' :
154
- continue
155
-
156
- object_list .append (object_identifier )
157
- except ErrorPDU :
158
- self .__log .error ('ErrorPDU reading object-list[%d]' , i + 1 )
136
+ object_identifier = await self .__send_request_wrapper (self .read_property ,
137
+ err_msg = f"Failed to read { device_identifier } object-list[{ i + 1 } ]" , # noqa
138
+ address = device_address ,
139
+ objid = device_identifier ,
140
+ prop = 'objectList' ,
141
+ array_index = i + 1 )
142
+ if object_identifier is None :
159
143
continue
160
- except Exception as e :
161
- self . __log . error ( '%s error reading object-list[%d]: %s' , device_identifier , i + 1 , e )
144
+
145
+ if object_identifier [ 0 ]. __str__ () == 'device' :
162
146
continue
163
147
148
+ object_list .append (object_identifier )
149
+
164
150
return object_list
165
151
166
152
async def read_multiple_objects (self , device , object_list ):
@@ -180,17 +166,9 @@ async def read_multiple_objects(self, device, object_list):
180
166
destination = Address (device .details .address ),
181
167
)
182
168
183
- result = None
184
- try :
185
- result = await self .request (request )
186
- except AbortPDU as e :
187
- self .__log .warning ("%s objectList abort: %s" , device .details .object_id , e )
188
- except ErrorRejectAbortNack as e :
189
- self .__log .warning ("%s objectList error/reject: %s" , device .details .object_id , e )
190
- except ErrorPDU :
191
- self .__log .error ('ErrorPDU reading object-list' )
192
- except Exception as e :
193
- self .__log .error ("%s objectList error: %s" , device .details .object_id , e )
169
+ result = await self .__send_request_wrapper (self .request ,
170
+ err_msg = f"Failed to read { device .details .object_id } objects" ,
171
+ apdu = request )
194
172
195
173
if not isinstance (result , ReadPropertyMultipleACK ):
196
174
self .__log .error ("Invalid response type: %s" , type (result ))
@@ -200,7 +178,7 @@ async def read_multiple_objects(self, device, object_list):
200
178
201
179
return decoded_result
202
180
203
- async def get_device_objects (self , device ):
181
+ async def get_device_objects (self , device , with_all_properties = False ):
204
182
if device .details .is_segmentation_supported ():
205
183
object_list = await self .get_object_identifiers_with_segmentation (device .details .address ,
206
184
device .details .identifier )
@@ -212,7 +190,8 @@ async def get_device_objects(self, device):
212
190
self .__log .warning ("%s no objects to read" , device .details .object_id )
213
191
return
214
192
215
- object_list = [{'objectId' : obj , 'propertyId' : 'object-name' } for obj in object_list ]
193
+ object_list = [{'objectId' : obj , 'propertyId' : 'object-name' if not with_all_properties else 'all' }
194
+ for obj in object_list ]
216
195
217
196
return ObjectIterator (self , device , object_list , self .read_multiple_objects )
218
197
@@ -238,16 +217,18 @@ def __get_read_access_specifications(self, object_list, vendor_id):
238
217
self .__log .warning (f"unknown object type: { object_id } , { object_class } " )
239
218
continue
240
219
241
- property_identifier = PropertyIdentifier (object ['propertyId' ])
220
+ properties = []
221
+ if not isinstance (object ['propertyId' ], set ):
222
+ object ['propertyId' ] = {object ['propertyId' ]}
242
223
243
- property_class = object_class . get_property_type ( property_identifier )
244
- if property_class is None :
245
- self . __log . warning ( f" { object_id } unknown property: { property_identifier } " )
246
- continue
224
+ for prop in object [ 'propertyId' ]:
225
+ property_identifier = PropertyIdentifier ( prop )
226
+
227
+ properties . append ( property_identifier )
247
228
248
229
ras = ReadAccessSpecification (
249
230
objectIdentifier = object_id ,
250
- listOfPropertyReferences = [ property_identifier ] ,
231
+ listOfPropertyReferences = properties ,
251
232
)
252
233
253
234
read_access_specifications .append (ras )
@@ -380,7 +361,7 @@ def __init__(self, app, device, object_list, func):
380
361
self .app = app
381
362
self .items = object_list
382
363
self .device = device
383
- self .limit = device . details . get_max_apdu_count ()
364
+ self .limit = self . get_limit ()
384
365
self .func = func
385
366
self .index = 0
386
367
@@ -396,3 +377,17 @@ async def get_next(self):
396
377
r = await self .func (self .device , result )
397
378
398
379
return r , result , finished
380
+
381
+ def get_limit (self ):
382
+ max_prop_count = 0
383
+
384
+ for item in self .items :
385
+ cur_prop_count = len (item ['propertyId' ]) if isinstance (item ['propertyId' ], set ) else 1
386
+ if item ['propertyId' ] == 'all' :
387
+ max_prop_count = 6
388
+ break
389
+
390
+ if cur_prop_count > max_prop_count :
391
+ max_prop_count = cur_prop_count
392
+
393
+ return int (self .device .details .get_max_apdu_count () / max_prop_count ) if max_prop_count > 0 else 1
0 commit comments