From 86880853a4f0397bfffdfe9543fff95847d50e1e Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Fri, 27 Nov 2020 17:08:51 +0100 Subject: [PATCH 1/4] correctly unpack bbmd info for WhoIsRouterForeign.py --- samples/WhoIsRouterForeign.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/WhoIsRouterForeign.py b/samples/WhoIsRouterForeign.py index af77f400..c378378e 100755 --- a/samples/WhoIsRouterForeign.py +++ b/samples/WhoIsRouterForeign.py @@ -34,9 +34,9 @@ @bacpypes_debugging class WhoIsRouterApplication(BIPNetworkApplication): - def __init__(self, *args): + def __init__(self, *args, **kwargs): if _debug: WhoIsRouterApplication._debug("__init__ %r", args) - BIPNetworkApplication.__init__(self, *args) + BIPNetworkApplication.__init__(self, *args, **kwargs) def request(self, adapter, npdu): if _debug: WhoIsRouterApplication._debug("request %r %r", adapter, npdu) @@ -120,8 +120,8 @@ def main(): # make a simple application this_application = WhoIsRouterApplication( args.ini.address, - Address(args.ini.foreignbbmd), - int(args.ini.foreignttl), + bbmdAddress=Address(args.ini.foreignbbmd), + bbmdTTL=int(args.ini.foreignttl) ) if _debug: _log.debug(" - this_application: %r", this_application) From 3fcfa40a95239396d5cc71bc3cb7ff067237b842 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 6 Apr 2021 17:11:27 +0200 Subject: [PATCH 2/4] try SubscribeCOVPropertyRequest --- py34/bacpypes/service/cov.py | 83 +++++++++++++++++++++++++++++++++++- samples/COVClient.py | 13 ++++-- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/py34/bacpypes/service/cov.py b/py34/bacpypes/service/cov.py index 02887131..cbf87fdb 100644 --- a/py34/bacpypes/service/cov.py +++ b/py34/bacpypes/service/cov.py @@ -90,7 +90,7 @@ class Subscription(OneShotTask, DebugContents): 'lifetime', ) - def __init__(self, obj_ref, client_addr, proc_id, obj_id, confirmed, lifetime): + def __init__(self, obj_ref, client_addr, proc_id, obj_id, confirmed, lifetime, cov_inc): if _debug: Subscription._debug("__init__ %r %r %r %r %r %r", obj_ref, client_addr, proc_id, obj_id, confirmed, lifetime) OneShotTask.__init__(self) @@ -103,6 +103,7 @@ def __init__(self, obj_ref, client_addr, proc_id, obj_id, confirmed, lifetime): self.obj_id = obj_id self.confirmed = confirmed self.lifetime = lifetime + self.covIncrement = cov_inc # if lifetime is non-zero, schedule the subscription to expire if lifetime != 0: @@ -756,3 +757,83 @@ def do_SubscribeCOVRequest(self, apdu): if _debug: ChangeOfValueServices._debug(" - send a notification") deferred(cov_detection.send_cov_notifications, cov) + def do_SubscribeCOVPropertyRequest(self, apdu): + if _debug: ChangeOfValueServices._debug("do_SubscribeCOVPropertyRequest %r", apdu) + + # extract the pieces + client_addr = apdu.pduSource + proc_id = apdu.subscriberProcessIdentifier + obj_id = apdu.monitoredObjectIdentifier + confirmed = apdu.issueConfirmedNotifications + lifetime = apdu.lifetime + prop_id = apdu.monitoredPropertyIdentifier + cov_inc = apdu.covIncrement + + print("Dap: prop_id: {}, cov_inc: {}".format(prop_id,cov_inc)) + # request is to cancel the subscription + cancel_subscription = (confirmed is None) and (lifetime is None) + + # find the object + obj = self.get_object_id(obj_id) + if _debug: ChangeOfValueServices._debug(" - object: %r", obj) + if not obj: + raise ExecutionError(errorClass='object', errorCode='unknownObject') + + # check to see if the object supports COV + if not obj._object_supports_cov: + raise ExecutionError(errorClass='services', errorCode='covSubscriptionFailed') + + # look for an algorithm already associated with this object + cov_detection = self.cov_detections.get(obj, None) + + # if there isn't one, make one and associate it with the object + if not cov_detection: + # look for an associated class and if it's not there it's not supported + criteria_class = criteria_type_map.get(obj_id[0], None) + if not criteria_class: + raise ExecutionError(errorClass='services', errorCode='covSubscriptionFailed') + + # make one of these and bind it to the object + cov_detection = criteria_class(obj) + + # keep track of it for other subscriptions + self.cov_detections[obj] = cov_detection + if _debug: ChangeOfValueServices._debug(" - cov_detection: %r", cov_detection) + + # can a match be found? + cov = cov_detection.cov_subscriptions.find(client_addr, proc_id, obj_id) + if _debug: ChangeOfValueServices._debug(" - cov: %r", cov) + + # if a match was found, update the subscription + if cov: + if cancel_subscription: + if _debug: ChangeOfValueServices._debug(" - cancel the subscription") + self.cancel_subscription(cov) + else: + if _debug: ChangeOfValueServices._debug(" - renew the subscription") + cov.renew_subscription(lifetime) + else: + if cancel_subscription: + if _debug: ChangeOfValueServices._debug(" - cancel a subscription that doesn't exist") + else: + if _debug: ChangeOfValueServices._debug(" - create a subscription") + + # make a subscription + cov = Subscription(obj, client_addr, proc_id, obj_id, + confirmed, lifetime, cov_inc) + if _debug: ChangeOfValueServices._debug(" - cov: %r", cov) + + # add it to our subscriptions lists + self.add_subscription(cov) + + # success + response = SimpleAckPDU(context=apdu) + + # return the result + self.response(response) + + # if the subscription is not being canceled, it is new or renewed, + # so send it a notification when you get a chance. + if not cancel_subscription: + if _debug: ChangeOfValueServices._debug(" - send a notification") + deferred(cov_detection.send_cov_notifications, cov) \ No newline at end of file diff --git a/samples/COVClient.py b/samples/COVClient.py index 41673e79..012c8e52 100755 --- a/samples/COVClient.py +++ b/samples/COVClient.py @@ -15,11 +15,12 @@ from bacpypes.iocb import IOCB from bacpypes.pdu import Address -from bacpypes.apdu import SubscribeCOVRequest, SimpleAckPDU, RejectPDU, AbortPDU +from bacpypes.apdu import SubscribeCOVRequest, SimpleAckPDU, RejectPDU, AbortPDU, SubscribeCOVPropertyRequest from bacpypes.primitivedata import ObjectIdentifier from bacpypes.app import BIPSimpleApplication from bacpypes.local.device import LocalDeviceObject +from bacpypes.basetypes import PropertyReference # some debugging _debug = 0 @@ -145,8 +146,14 @@ def do_subscribe(self, args): lifetime = None # build a request - request = SubscribeCOVRequest( - subscriberProcessIdentifier=proc_id, monitoredObjectIdentifier=obj_id + # request = SubscribeCOVRequest( + # subscriberProcessIdentifier=proc_id, monitoredObjectIdentifier=obj_id + # ) + request = SubscribeCOVPropertyRequest( + subscriberProcessIdentifier=proc_id, + monitoredObjectIdentifier=obj_id, + monitoredPropertyIdentifier=PropertyReference(propertyIdentifier=85), + covIncrement=2 ) request.pduDestination = Address(addr) From 37a6e485f5168122ed45b26de166d0cf614d7a0c Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 6 Apr 2021 17:12:34 +0200 Subject: [PATCH 3/4] remove do_SubscribeCOVRequest to get better git-diff --- py34/bacpypes/service/cov.py | 77 ------------------------------------ 1 file changed, 77 deletions(-) diff --git a/py34/bacpypes/service/cov.py b/py34/bacpypes/service/cov.py index cbf87fdb..b519f7a2 100644 --- a/py34/bacpypes/service/cov.py +++ b/py34/bacpypes/service/cov.py @@ -680,83 +680,6 @@ def cov_abort(self, cov, request, response): ### delete the rest of the pending requests for this client - def do_SubscribeCOVRequest(self, apdu): - if _debug: ChangeOfValueServices._debug("do_SubscribeCOVRequest %r", apdu) - - # extract the pieces - client_addr = apdu.pduSource - proc_id = apdu.subscriberProcessIdentifier - obj_id = apdu.monitoredObjectIdentifier - confirmed = apdu.issueConfirmedNotifications - lifetime = apdu.lifetime - - # request is to cancel the subscription - cancel_subscription = (confirmed is None) and (lifetime is None) - - # find the object - obj = self.get_object_id(obj_id) - if _debug: ChangeOfValueServices._debug(" - object: %r", obj) - if not obj: - raise ExecutionError(errorClass='object', errorCode='unknownObject') - - # check to see if the object supports COV - if not obj._object_supports_cov: - raise ExecutionError(errorClass='services', errorCode='covSubscriptionFailed') - - # look for an algorithm already associated with this object - cov_detection = self.cov_detections.get(obj, None) - - # if there isn't one, make one and associate it with the object - if not cov_detection: - # look for an associated class and if it's not there it's not supported - criteria_class = criteria_type_map.get(obj_id[0], None) - if not criteria_class: - raise ExecutionError(errorClass='services', errorCode='covSubscriptionFailed') - - # make one of these and bind it to the object - cov_detection = criteria_class(obj) - - # keep track of it for other subscriptions - self.cov_detections[obj] = cov_detection - if _debug: ChangeOfValueServices._debug(" - cov_detection: %r", cov_detection) - - # can a match be found? - cov = cov_detection.cov_subscriptions.find(client_addr, proc_id, obj_id) - if _debug: ChangeOfValueServices._debug(" - cov: %r", cov) - - # if a match was found, update the subscription - if cov: - if cancel_subscription: - if _debug: ChangeOfValueServices._debug(" - cancel the subscription") - self.cancel_subscription(cov) - else: - if _debug: ChangeOfValueServices._debug(" - renew the subscription") - cov.renew_subscription(lifetime) - else: - if cancel_subscription: - if _debug: ChangeOfValueServices._debug(" - cancel a subscription that doesn't exist") - else: - if _debug: ChangeOfValueServices._debug(" - create a subscription") - - # make a subscription - cov = Subscription(obj, client_addr, proc_id, obj_id, confirmed, lifetime) - if _debug: ChangeOfValueServices._debug(" - cov: %r", cov) - - # add it to our subscriptions lists - self.add_subscription(cov) - - # success - response = SimpleAckPDU(context=apdu) - - # return the result - self.response(response) - - # if the subscription is not being canceled, it is new or renewed, - # so send it a notification when you get a chance. - if not cancel_subscription: - if _debug: ChangeOfValueServices._debug(" - send a notification") - deferred(cov_detection.send_cov_notifications, cov) - def do_SubscribeCOVPropertyRequest(self, apdu): if _debug: ChangeOfValueServices._debug("do_SubscribeCOVPropertyRequest %r", apdu) From dfecdc21ab1558075428b95b1fd57d5f74388f8b Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 6 Apr 2021 17:17:00 +0200 Subject: [PATCH 4/4] clean up --- py34/bacpypes/service/cov.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py34/bacpypes/service/cov.py b/py34/bacpypes/service/cov.py index b519f7a2..1eb9063d 100644 --- a/py34/bacpypes/service/cov.py +++ b/py34/bacpypes/service/cov.py @@ -692,7 +692,6 @@ def do_SubscribeCOVPropertyRequest(self, apdu): prop_id = apdu.monitoredPropertyIdentifier cov_inc = apdu.covIncrement - print("Dap: prop_id: {}, cov_inc: {}".format(prop_id,cov_inc)) # request is to cancel the subscription cancel_subscription = (confirmed is None) and (lifetime is None)