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

clean up names, sync python versions

This commit is contained in:
Joel Bender 2016-09-14 22:17:07 -04:00
parent af9fd7ead1
commit 06ca93d9c7
4 changed files with 126 additions and 60 deletions

View File

@ -6,6 +6,7 @@ Object
import sys import sys
from copy import copy as _copy from copy import copy as _copy
from collections import defaultdict
from .errors import ConfigurationError, ExecutionError, \ from .errors import ConfigurationError, ExecutionError, \
InvalidParameterDatatype InvalidParameterDatatype
@ -210,6 +211,9 @@ class Property(Logging):
self.identifier, self.datatype.__name__, self.identifier, self.datatype.__name__,
)) ))
# local check if the property is monitored
is_monitored = self.identifier in obj._property_monitors
if arrayIndex is not None: if arrayIndex is not None:
if not issubclass(self.datatype, Array): if not issubclass(self.datatype, Array):
raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray') raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray')
@ -219,14 +223,31 @@ class Property(Logging):
if arry is None: if arry is None:
raise RuntimeError("%s uninitialized array" % (self.identifier,)) raise RuntimeError("%s uninitialized array" % (self.identifier,))
if is_monitored:
old_value = _copy(arry)
# seems to be OK, let the array object take over # seems to be OK, let the array object take over
if _debug: Property._debug(" - forwarding to array") if _debug: Property._debug(" - forwarding to array")
arry[arrayIndex] = value arry[arrayIndex] = value
return # check for monitors, call each one with the old and new value
if is_monitored:
for fn in obj._property_monitors[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn)
fn(old_value, arry)
# seems to be OK else:
obj._values[self.identifier] = value if is_monitored:
old_value = obj._values.get(self.identifier, None)
# seems to be OK
obj._values[self.identifier] = value
# check for monitors, call each one with the old and new value
if is_monitored:
for fn in obj._property_monitors[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn)
fn(old_value, value)
# #
# StandardProperty # StandardProperty
@ -359,6 +380,9 @@ class Object(Logging):
# start with a clean dict of values # start with a clean dict of values
self._values = {} self._values = {}
# empty list of property monitors
self._property_monitors = defaultdict(list)
# start with a clean array of property identifiers # start with a clean array of property identifiers
if 'propertyList' in initargs: if 'propertyList' in initargs:
propertyList = None propertyList = None

View File

@ -212,6 +212,9 @@ class Property:
self.identifier, self.datatype.__name__, self.identifier, self.datatype.__name__,
)) ))
# local check if the property is monitored
is_monitored = self.identifier in obj._property_monitors
if arrayIndex is not None: if arrayIndex is not None:
if not issubclass(self.datatype, Array): if not issubclass(self.datatype, Array):
raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray') raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray')
@ -221,21 +224,31 @@ class Property:
if arry is None: if arry is None:
raise RuntimeError("%s uninitialized array" % (self.identifier,)) raise RuntimeError("%s uninitialized array" % (self.identifier,))
if is_monitored:
old_value = _copy(arry)
# seems to be OK, let the array object take over # seems to be OK, let the array object take over
if _debug: Property._debug(" - forwarding to array") if _debug: Property._debug(" - forwarding to array")
arry[arrayIndex] = value arry[arrayIndex] = value
return # check for monitors, call each one with the old and new value
if is_monitored:
for fn in obj._property_monitors[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn)
fn(old_value, arry)
# seems to be OK else:
old_value = obj._values.get(self.identifier, None) if is_monitored:
obj._values[self.identifier] = value old_value = obj._values.get(self.identifier, None)
# check for monitors, call each one with the old and new value # seems to be OK
if self.identifier in obj._property_monitor: obj._values[self.identifier] = value
for fn in obj._property_monitor[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn) # check for monitors, call each one with the old and new value
fn(old_value, value) if is_monitored:
for fn in obj._property_monitors[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn)
fn(old_value, value)
# #
# StandardProperty # StandardProperty
@ -375,7 +388,7 @@ class Object(object):
self._values = {} self._values = {}
# empty list of property monitors # empty list of property monitors
self._property_monitor = defaultdict(list) self._property_monitors = defaultdict(list)
# start with a clean array of property identifiers # start with a clean array of property identifiers
if 'propertyList' in initargs: if 'propertyList' in initargs:
@ -637,9 +650,9 @@ class AccessCredentialObject(Object):
, OptionalProperty('extendedTimeEnable', Boolean) , OptionalProperty('extendedTimeEnable', Boolean)
, OptionalProperty('authorizationExemptions', SequenceOf(AuthorizationException)) , OptionalProperty('authorizationExemptions', SequenceOf(AuthorizationException))
, OptionalProperty('reliabilityEvaluationInhibit', Boolean) , OptionalProperty('reliabilityEvaluationInhibit', Boolean)
, OptionalProperty('masterExemption', Boolean) # , OptionalProperty('masterExemption', Boolean)
, OptionalProperty('passbackExemption', Boolean) # , OptionalProperty('passbackExemption', Boolean)
, OptionalProperty('occupancyExemption', Boolean) # , OptionalProperty('occupancyExemption', Boolean)
] ]
@register_object_type @register_object_type

View File

@ -6,6 +6,7 @@ Object
import sys import sys
from copy import copy as _copy from copy import copy as _copy
from collections import defaultdict
from .errors import ConfigurationError, ExecutionError, \ from .errors import ConfigurationError, ExecutionError, \
InvalidParameterDatatype InvalidParameterDatatype
@ -211,6 +212,9 @@ class Property:
self.identifier, self.datatype.__name__, self.identifier, self.datatype.__name__,
)) ))
# local check if the property is monitored
is_monitored = self.identifier in obj._property_monitors
if arrayIndex is not None: if arrayIndex is not None:
if not issubclass(self.datatype, Array): if not issubclass(self.datatype, Array):
raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray') raise ExecutionError(errorClass='property', errorCode='propertyIsNotAnArray')
@ -220,14 +224,31 @@ class Property:
if arry is None: if arry is None:
raise RuntimeError("%s uninitialized array" % (self.identifier,)) raise RuntimeError("%s uninitialized array" % (self.identifier,))
if is_monitored:
old_value = _copy(arry)
# seems to be OK, let the array object take over # seems to be OK, let the array object take over
if _debug: Property._debug(" - forwarding to array") if _debug: Property._debug(" - forwarding to array")
arry[arrayIndex] = value arry[arrayIndex] = value
return # check for monitors, call each one with the old and new value
if is_monitored:
for fn in obj._property_monitors[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn)
fn(old_value, arry)
# seems to be OK else:
obj._values[self.identifier] = value if is_monitored:
old_value = obj._values.get(self.identifier, None)
# seems to be OK
obj._values[self.identifier] = value
# check for monitors, call each one with the old and new value
if is_monitored:
for fn in obj._property_monitors[self.identifier]:
if _debug: Property._debug(" - monitor: %r", fn)
fn(old_value, value)
# #
# StandardProperty # StandardProperty
@ -366,6 +387,9 @@ class Object:
# start with a clean dict of values # start with a clean dict of values
self._values = {} self._values = {}
# empty list of property monitors
self._property_monitors = defaultdict(list)
# start with a clean array of property identifiers # start with a clean array of property identifiers
if 'propertyList' in initargs: if 'propertyList' in initargs:
propertyList = None propertyList = None
@ -626,9 +650,9 @@ class AccessCredentialObject(Object):
, OptionalProperty('extendedTimeEnable', Boolean) , OptionalProperty('extendedTimeEnable', Boolean)
, OptionalProperty('authorizationExemptions', SequenceOf(AuthorizationException)) , OptionalProperty('authorizationExemptions', SequenceOf(AuthorizationException))
, OptionalProperty('reliabilityEvaluationInhibit', Boolean) , OptionalProperty('reliabilityEvaluationInhibit', Boolean)
, OptionalProperty('masterExemption', Boolean) # , OptionalProperty('masterExemption', Boolean)
, OptionalProperty('passbackExemption', Boolean) # , OptionalProperty('passbackExemption', Boolean)
, OptionalProperty('occupancyExemption', Boolean) # , OptionalProperty('occupancyExemption', Boolean)
] ]
@register_object_type @register_object_type

View File

@ -12,31 +12,31 @@ _debug = 0
_log = ModuleLogger(globals()) _log = ModuleLogger(globals())
# #
# Detection Transfer # PropertyMonitor
# #
@bacpypes_debugging @bacpypes_debugging
class DetectionTransfer: class PropertyMonitor:
def __init__(self, eda, parameter, obj, prop, filter=None): def __init__(self, algorithm, parameter, obj, prop, filter=None):
if _debug: DetectionTransfer._debug("__init__ ...") if _debug: PropertyMonitor._debug("__init__ ...")
# keep track of the parameter values # keep track of the parameter values
self.eda = eda self.algorithm = algorithm
self.parameter = parameter self.parameter = parameter
self.obj = obj self.obj = obj
self.prop = prop self.prop = prop
self.filter = None self.filter = None
def property_change(self, old_value, new_value): def property_change(self, old_value, new_value):
if _debug: DetectionTransfer._debug("property_change %r %r", old_value, new_value) if _debug: PropertyMonitor._debug("property_change %r %r", old_value, new_value)
# set the parameter value # set the parameter value
setattr(self.eda, self.parameter, new_value) setattr(self.algorithm, self.parameter, new_value)
# if this is already triggered, don't bother checking for more # if the algorithm is already triggered, don't bother checking for more
if self.eda._triggered: if self.algorithm._triggered:
if _debug: DetectionTransfer._debug(" - already triggered") if _debug: PropertyMonitor._debug(" - already triggered")
return return
# if there is a special filter, use it, otherwise use != # if there is a special filter, use it, otherwise use !=
@ -44,20 +44,20 @@ class DetectionTransfer:
trigger = self.filter(old_value, new_value) trigger = self.filter(old_value, new_value)
else: else:
trigger = (old_value != new_value) trigger = (old_value != new_value)
if _debug: DetectionTransfer._debug(" - trigger: %r", trigger) if _debug: PropertyMonitor._debug(" - trigger: %r", trigger)
# trigger it # trigger it
if trigger: if trigger:
deferred(self.eda.evaluate) deferred(self.algorithm._execute)
self.eda._triggered = True self.algorithm._triggered = True
# #
# transfer_filter # monitor_filter
# #
def transfer_filter(parameter): def monitor_filter(parameter):
def transfer_filter_decorator(fn): def transfer_filter_decorator(fn):
fn._transfer_filter = parameter fn._monitor_filter = parameter
return fn return fn
return transfer_filter_decorator return transfer_filter_decorator
@ -73,7 +73,7 @@ class DetectionAlgorithm:
if _debug: DetectionAlgorithm._debug("__init__ %r") if _debug: DetectionAlgorithm._debug("__init__ %r")
# transfer objects # transfer objects
self._transfers = [] self._monitors = []
# triggered # triggered
self._triggered = False self._triggered = False
@ -82,29 +82,29 @@ class DetectionAlgorithm:
if _debug: DetectionAlgorithm._debug("bind %r", kwargs) if _debug: DetectionAlgorithm._debug("bind %r", kwargs)
# build a map of functions that have a transfer filter # build a map of functions that have a transfer filter
transfer_filters = {} monitor_filters = {}
for attr_name in dir(self): for attr_name in dir(self):
attr = getattr(self, attr_name) attr = getattr(self, attr_name)
if hasattr(attr, "_transfer_filter"): if hasattr(attr, "_monitor_filter"):
transfer_filters[attr._transfer_filter] = attr monitor_filters[attr._monitor_filter] = attr
if _debug: DetectionAlgorithm._debug(" - transfer_filters %r", kwargs) if _debug: DetectionAlgorithm._debug(" - monitor_filters %r", kwargs)
for parameter, (obj, prop) in kwargs.items(): for parameter, (obj, prop) in kwargs.items():
if not hasattr(self, parameter): if not hasattr(self, parameter):
if _debug: DetectionAlgorithm._debug(" - no matching parameter: %r", parameter) if _debug: DetectionAlgorithm._debug(" - no matching parameter: %r", parameter)
# make a transfer object # make a property monitor
xfr = DetectionTransfer(self, parameter, obj, prop) monitor = PropertyMonitor(self, parameter, obj, prop)
# check to see if there is a custom filter for it # check to see if there is a custom filter for it
if parameter in transfer_filters: if parameter in monitor_filters:
xfr.filter = transfer_filters[parameter] monitor.filter = monitor_filters[parameter]
# keep track of all of these objects for if/when we unbind # keep track of all of these objects for if/when we unbind
self._transfers.append(xfr) self._monitors.append(monitor)
# add the property value monitor function # add the property value monitor function
obj._property_monitor[prop].append(xfr.property_change) obj._property_monitors[prop].append(monitor.property_change)
# set the parameter value to the property value if it's not None # set the parameter value to the property value if it's not None
property_value = obj._values[prop] property_value = obj._values[prop]
@ -116,17 +116,24 @@ class DetectionAlgorithm:
if _debug: DetectionAlgorithm._debug("unbind %r", kwargs) if _debug: DetectionAlgorithm._debug("unbind %r", kwargs)
# remove the property value monitor functions # remove the property value monitor functions
for xfr in self._transfers: for xfr in self._monitors:
obj._property_monitor[property].remove(xfr.property_change) obj._property_monitor[property].remove(xfr.property_change)
# abandon the array of transfers # abandon the array of transfers
self._transfers = [] self._monitors = []
def evaluate(self): def _execute(self):
if _debug: DetectionAlgorithm._debug("evaluate %r", kwargs) if _debug: DetectionAlgorithm._debug("_execute")
# provided by the derived class
self.execute()
# turn the trigger off
self._triggered = False self._triggered = False
def execute(self):
raise notImplementedError("execute not implemented")
# #
# SampleEventDetection # SampleEventDetection
# #
@ -138,34 +145,32 @@ class SampleEventDetection(DetectionAlgorithm):
if _debug: SampleEventDetection._debug("__init__ %r %r", self, kwargs) if _debug: SampleEventDetection._debug("__init__ %r %r", self, kwargs)
DetectionAlgorithm.__init__(self) DetectionAlgorithm.__init__(self)
# provide an interesting default value # provide default values
self.pParameter = None self.pParameter = None
self.pSetPoint = None self.pSetPoint = None
# bind to the parameter values provided # bind to the parameter values provided
self.bind(**kwargs) self.bind(**kwargs)
@transfer_filter('pParameter') @monitor_filter('pParameter')
def parameter_filter(self, old_value, new_value): def parameter_filter(self, old_value, new_value):
if _debug: SampleEventDetection._debug("parameter_filter %r %r", old_value, new_value) if _debug: SampleEventDetection._debug("parameter_filter %r %r", old_value, new_value)
return (old_value != new_value) return (old_value != new_value)
def evaluate(self): def execute(self):
if _debug: SampleEventDetection._debug("evaluate") if _debug: SampleEventDetection._debug("execute")
# if _triggered is true this function was called because of some # if _triggered is true this function was called because of some
# parameter change, but could have been called for some other reason # parameter change, but could have been called for some other reason
if self._triggered: if self._triggered:
if _debug: SampleEventDetection._debug(" - was triggered") if _debug: SampleEventDetection._debug(" - was triggered")
self._triggered = False
else: else:
if _debug: SampleEventDetection._debug(" - was not triggered") if _debug: SampleEventDetection._debug(" - was not triggered")
# check for things # check for things
if self.pParameter != self.pSetPoint: if self.pParameter != self.pSetPoint:
print("ding!") if _debug: SampleEventDetection._debug(" - parameter is wrong")
# #
# #