Skip to content

Commit 5b40953

Browse files
authored
Merge pull request #1768 from samson0v/master
BACnet connector improvements
2 parents b37836d + 8b35974 commit 5b40953

3 files changed

Lines changed: 56 additions & 6 deletions

File tree

thingsboard_gateway/connectors/bacnet/application.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
SimpleAckPDU,
3333
ErrorRejectAbortNack
3434
)
35+
from bacpypes3.comm import bind
3536

37+
from thingsboard_gateway.connectors.bacnet.application_service_access_point import ApplicationServiceAccessPoint
3638
from thingsboard_gateway.connectors.bacnet.device import Device
3739
from thingsboard_gateway.connectors.bacnet.entities.device_object_config import DeviceObjectConfig
3840

@@ -45,6 +47,9 @@ def __init__(self, device_object_config: DeviceObjectConfig, indication_callback
4547
self.__device_object = DeviceObject(**self.__device_object_config.device_object_config)
4648
super().__init__(self.__device_object, Address(self.__device_object_config.address))
4749

50+
self.asap = ApplicationServiceAccessPoint(self.device_object, self.device_info_cache)
51+
bind(self, self.asap, self.nsap)
52+
4853
self.__log = logger
4954
self.__indication_callback = indication_callback
5055
self.__confirmation_queue = Queue(1_000_000)
@@ -125,17 +130,22 @@ async def get_object_identifiers_without_segmentation(
125130
"objectList",
126131
array_index=0,
127132
)
133+
except Exception as e:
134+
self.__log.error('%s error reading object-list length: %s', device_identifier, e)
135+
return []
128136

129-
for i in range(object_list_length):
137+
for i in range(object_list_length):
138+
try:
130139
object_identifier = await self.read_property(
131140
device_address,
132141
device_identifier,
133142
"objectList",
134143
array_index=i + 1,
135144
)
136145
object_list.append(object_identifier)
137-
except ErrorRejectAbortNack as err:
138-
self.__log.info(f"{device_identifier} object-list length error/reject: {err}")
146+
except Exception as e:
147+
self.__log.error('%s error reading object-list[%d]: %s', device_identifier, i + 1, e)
148+
continue
139149

140150
return object_list
141151

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from bacpypes3.appservice import ApplicationServiceAccessPoint as AppServiceAccessPoint, ServiceAccessPoint
2+
from bacpypes3.apdu import (
3+
APCISequence,
4+
APDU,
5+
AbortPDU,
6+
ComplexAckPDU,
7+
ConfirmedRequestPDU,
8+
ErrorPDU,
9+
RejectPDU,
10+
SimpleAckPDU,
11+
UnconfirmedRequestPDU,
12+
)
13+
14+
15+
class ApplicationServiceAccessPoint(AppServiceAccessPoint):
16+
async def sap_response(self, apdu: APDU) -> None:
17+
if isinstance(apdu, SimpleAckPDU):
18+
xpdu = apdu
19+
20+
elif isinstance(
21+
apdu, (UnconfirmedRequestPDU, ConfirmedRequestPDU, ComplexAckPDU, ErrorPDU)
22+
):
23+
try:
24+
xpdu = APCISequence.decode(apdu)
25+
except Exception:
26+
if isinstance(apdu, UnconfirmedRequestPDU):
27+
return
28+
29+
if isinstance(apdu, ConfirmedRequestPDU):
30+
return
31+
32+
xpdu = apdu
33+
elif isinstance(apdu, (RejectPDU, AbortPDU)):
34+
xpdu = apdu
35+
else:
36+
raise RuntimeError(f"invalid APDU (10): {type(apdu)}")
37+
38+
await ServiceAccessPoint.sap_response(self, xpdu)

thingsboard_gateway/connectors/bacnet/device.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
from asyncio import sleep
16-
from re import escape, match, fullmatch
16+
from re import escape, match, fullmatch, compile
1717
from time import monotonic
1818

1919
from bacpypes3.primitivedata import ObjectIdentifier
@@ -119,9 +119,11 @@ def get_address_regex(initial_config_address):
119119
if pattern == '*:*:*':
120120
return r'.*'
121121
elif pattern == '*:*':
122-
return r'^([^:,@]+)(:[^:,@]+)?(:(47808))?$'
122+
return compile(r'^([^:,@]+)(:[^:,@]+)?(:(47808))?$')
123123
elif pattern == '*':
124-
return r'^(0:[^:,@]+|[^\d:,@][^:,@]*:47808|[^:,@]+)$'
124+
return compile(r'^(0:[^:,@]+|[^\d:,@][^:,@]*:47808|[^:,@]+)$')
125+
elif match(r"\*:\d+", pattern):
126+
return compile(r'^([^:,@]+)(:[^:,@]+)?(:(47808))?$')
125127
while i < len(pattern):
126128
if pattern[i] == 'X':
127129
while i < len(pattern) and pattern[i] == 'X':

0 commit comments

Comments
 (0)