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

first crack at #148

This commit is contained in:
Joel Bender 2017-11-17 02:02:24 -05:00
parent 5d1649c59c
commit 9750c0f13c
3 changed files with 77 additions and 48 deletions

View File

@ -396,13 +396,6 @@ class Object(object):
# empty list of property monitors # empty list of property monitors
self._property_monitors = defaultdict(list) self._property_monitors = defaultdict(list)
# start with a clean array of property identifiers
if 'propertyList' in initargs:
propertyList = None
else:
propertyList = ArrayOf(PropertyIdentifier)()
initargs['propertyList'] = propertyList
# initialize the object # initialize the object
for propid, prop in self._properties.items(): for propid, prop in self._properties.items():
if propid in initargs: if propid in initargs:
@ -411,20 +404,12 @@ class Object(object):
# defer to the property object for error checking # defer to the property object for error checking
prop.WriteProperty(self, initargs[propid], direct=True) prop.WriteProperty(self, initargs[propid], direct=True)
# add it to the property list if we are building one
if propertyList is not None:
propertyList.append(propid)
elif prop.default is not None: elif prop.default is not None:
if _debug: Object._debug(" - setting %s from default", propid) if _debug: Object._debug(" - setting %s from default", propid)
# default values bypass property interface # default values bypass property interface
self._values[propid] = prop.default self._values[propid] = prop.default
# add it to the property list if we are building one
if propertyList is not None:
propertyList.append(propid)
else: else:
if not prop.optional: if not prop.optional:
if _debug: Object._debug(" - %s value required", propid) if _debug: Object._debug(" - %s value required", propid)
@ -485,13 +470,6 @@ class Object(object):
self._properties[prop.identifier] = prop self._properties[prop.identifier] = prop
self._values[prop.identifier] = prop.default self._values[prop.identifier] = prop.default
# tell the object it has a new property
if 'propertyList' in self._values:
property_list = self.propertyList
if prop.identifier not in property_list:
if _debug: Object._debug(" - adding to property list")
property_list.append(prop.identifier)
def delete_property(self, prop): def delete_property(self, prop):
"""Delete a property from an object. The property is an instance of """Delete a property from an object. The property is an instance of
a Property or one of its derived classes, but only the property a Property or one of its derived classes, but only the property
@ -507,13 +485,6 @@ class Object(object):
if prop.identifier in self._values: if prop.identifier in self._values:
del self._values[prop.identifier] del self._values[prop.identifier]
# remove the property identifier from its list of know properties
if 'propertyList' in self._values:
property_list = self.propertyList
if prop.identifier in property_list:
if _debug: Object._debug(" - removing from property list")
property_list.remove(prop.identifier)
def ReadProperty(self, propid, arrayIndex=None): def ReadProperty(self, propid, arrayIndex=None):
if _debug: Object._debug("ReadProperty %r arrayIndex=%r", propid, arrayIndex) if _debug: Object._debug("ReadProperty %r arrayIndex=%r", propid, arrayIndex)

View File

@ -14,6 +14,8 @@ from ..object import register_object_type, registered_object_types, \
Property, DeviceObject Property, DeviceObject
from ..task import FunctionTask from ..task import FunctionTask
from .object import LocalObject
# some debugging # some debugging
_debug = 0 _debug = 0
_log = ModuleLogger(globals()) _log = ModuleLogger(globals())
@ -67,7 +69,7 @@ class CurrentTimeProperty(Property):
# #
@bacpypes_debugging @bacpypes_debugging
class LocalDeviceObject(DeviceObject): class LocalDeviceObject(LocalObject, DeviceObject):
properties = \ properties = \
[ CurrentTimeProperty('localTime') [ CurrentTimeProperty('localTime')
@ -102,12 +104,24 @@ class LocalDeviceObject(DeviceObject):
raise RuntimeError("vendorIdentifier required to auto-register the LocalDeviceObject class") raise RuntimeError("vendorIdentifier required to auto-register the LocalDeviceObject class")
register_object_type(self.__class__, vendor_id=kwargs['vendorIdentifier']) register_object_type(self.__class__, vendor_id=kwargs['vendorIdentifier'])
# check for local time # check for properties this class implements
if 'localDate' in kwargs: if 'localDate' in kwargs:
raise RuntimeError("localDate is provided by LocalDeviceObject and cannot be overridden") raise RuntimeError("localDate is provided by LocalDeviceObject and cannot be overridden")
if 'localTime' in kwargs: if 'localTime' in kwargs:
raise RuntimeError("localTime is provided by LocalDeviceObject and cannot be overridden") raise RuntimeError("localTime is provided by LocalDeviceObject and cannot be overridden")
# the object identifier is required for the object list
if 'objectIdentifier' not in kwargs:
raise RuntimeError("objectIdentifier is required")
# the object list is provided
if 'objectList' in kwargs:
raise RuntimeError("objectList is provided by LocalDeviceObject and cannot be overridden")
else:
kwargs['objectList'] = ArrayOf(ObjectIdentifier)([
kwargs['objectIdentifier'],
])
# check for a minimum value # check for a minimum value
if kwargs['maxApduLengthAccepted'] < 50: if kwargs['maxApduLengthAccepted'] < 50:
raise ValueError("invalid max APDU length accepted") raise ValueError("invalid max APDU length accepted")
@ -116,20 +130,7 @@ class LocalDeviceObject(DeviceObject):
if _debug: LocalDeviceObject._debug(" - updated kwargs: %r", kwargs) if _debug: LocalDeviceObject._debug(" - updated kwargs: %r", kwargs)
# proceed as usual # proceed as usual
DeviceObject.__init__(self, **kwargs) LocalObject.__init__(self, **kwargs)
# create a default implementation of an object list for local devices.
# If it is specified in the kwargs, that overrides this default.
if ('objectList' not in kwargs):
self.objectList = ArrayOf(ObjectIdentifier)([self.objectIdentifier])
# if the object has a property list and one wasn't provided
# in the kwargs, then it was created by default and the objectList
# property should be included
if ('propertyList' not in kwargs) and self.propertyList:
# make sure it's not already there
if 'objectList' not in self.propertyList:
self.propertyList.append('objectList')
# #
# Who-Is I-Am Services # Who-Is I-Am Services

View File

@ -3,20 +3,77 @@
from ..debugging import bacpypes_debugging, ModuleLogger from ..debugging import bacpypes_debugging, ModuleLogger
from ..capability import Capability from ..capability import Capability
from ..basetypes import ErrorType from ..basetypes import ErrorType, PropertyIdentifier
from ..primitivedata import Atomic, Null, Unsigned from ..primitivedata import Atomic, Null, Unsigned
from ..constructeddata import Any, Array from ..constructeddata import Any, Array, ArrayOf
from ..apdu import Error, \ from ..apdu import Error, \
SimpleAckPDU, ReadPropertyACK, ReadPropertyMultipleACK, \ SimpleAckPDU, ReadPropertyACK, ReadPropertyMultipleACK, \
ReadAccessResult, ReadAccessResultElement, ReadAccessResultElementChoice ReadAccessResult, ReadAccessResultElement, ReadAccessResultElementChoice
from ..errors import ExecutionError from ..errors import ExecutionError
from ..object import PropertyError from ..object import Object, PropertyError
# some debugging # some debugging
_debug = 0 _debug = 0
_log = ModuleLogger(globals()) _log = ModuleLogger(globals())
#
# LocalObject
#
@bacpypes_debugging
class LocalObject(Object):
def __init__(self, **kwargs):
if _debug: LocalObject._debug("__init__ %r", kwargs)
# check for property list
if 'propertyList' in kwargs:
raise RuntimeError("propertyList is provided by LocalObject and cannot be overridden")
# proceed as usual
Object.__init__(self, **kwargs)
# make a list of the properties that were provided
property_list = [k for k, v in self._values.items()
if v is not None
and k not in ('objectName', 'objectType', 'objectIdentifier', 'propertyList')
]
if _debug: LocalObject._debug(" - property_list: %r", property_list)
# store the value
self._values['propertyList'] = ArrayOf(PropertyIdentifier)([property_list])
def add_property(self, prop):
"""Add a property to an object."""
if _debug: LocalObject._debug("add_property %r", prop)
# let the Object class do its thing
Object.add_property(self, prop)
# update the property list
property_list = self.propertyList
property_identifier = prop.identifier
if property_identifier in ('objectName', 'objectType', 'objectIdentifier', 'propertyList'):
pass
elif property_identifier not in property_list:
if _debug: LocalObject._debug(" - adding to property list")
property_list.append(property_identifier)
def delete_property(self, prop):
"""Delete a property from an object."""
if _debug: LocalObject._debug("delete_property %r", prop)
# let the Object class do its thing
Object.delete_property(self, prop)
# remove the property identifier from its list of know properties
property_list = self.propertyList
property_identifier = prop.identifier
if property_identifier in property_list:
if _debug: LocalObject._debug(" - removing from property list")
property_list.remove(property_identifier)
# #
# ReadProperty and WriteProperty Services # ReadProperty and WriteProperty Services
# #