1
0
mirror of https://github.com/JoelBender/bacpypes synced 2025-09-28 22:15:23 +08:00

try SubscribeCOVPropertyRequest

This commit is contained in:
Damien Picard 2021-04-06 17:11:27 +02:00
parent 86880853a4
commit 3fcfa40a95
2 changed files with 92 additions and 4 deletions

View File

@ -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 @@ class Subscription(OneShotTask, DebugContents):
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 @@ class ChangeOfValueServices(Capability):
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)

View File

@ -15,11 +15,12 @@ from bacpypes.core import run, deferred, enable_sleeping
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 @@ class SubscribeCOVConsoleCmd(ConsoleCmd):
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)