mirror of
https://github.com/JoelBender/bacpypes
synced 2025-10-05 22:18:16 +08:00
169 lines
4.9 KiB
Python
Executable File
169 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
"""
|
|
Server with a Trend Log Object
|
|
"""
|
|
|
|
from bacpypes.debugging import bacpypes_debugging, ModuleLogger
|
|
from bacpypes.consolelogging import ConfigArgumentParser
|
|
|
|
from bacpypes.core import run
|
|
from bacpypes.errors import ExecutionError, RejectException
|
|
from bacpypes.primitivedata import Date, Time
|
|
from bacpypes.constructeddata import Array, List, ListOf, SequenceOfAny
|
|
from bacpypes.basetypes import DateTime, LogRecord, LogRecordLogDatum, StatusFlags
|
|
from bacpypes.apdu import ReadRangeACK
|
|
|
|
from bacpypes.app import BIPSimpleApplication
|
|
from bacpypes.local.device import LocalDeviceObject
|
|
from bacpypes.object import PropertyError, TrendLogObject
|
|
|
|
|
|
# some debugging
|
|
_debug = 0
|
|
_log = ModuleLogger(globals())
|
|
|
|
# globals
|
|
this_application = None
|
|
|
|
|
|
#
|
|
# ReadRangeApplication
|
|
#
|
|
|
|
|
|
@bacpypes_debugging
|
|
class ReadRangeApplication(BIPSimpleApplication):
|
|
def __init__(self, *args):
|
|
if _debug:
|
|
ReadRangeApplication._debug("__init__ %r", args)
|
|
BIPSimpleApplication.__init__(self, *args)
|
|
|
|
def do_ReadRangeRequest(self, apdu):
|
|
if _debug:
|
|
ReadRangeApplication._debug("do_ReadRangeRequest %r", apdu)
|
|
|
|
# extract the object identifier
|
|
objId = apdu.objectIdentifier
|
|
|
|
# get the object
|
|
obj = self.get_object_id(objId)
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - object: %r", obj)
|
|
|
|
if not obj:
|
|
raise ExecutionError(errorClass="object", errorCode="unknownObject")
|
|
|
|
# get the datatype
|
|
datatype = obj.get_datatype(apdu.propertyIdentifier)
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - datatype: %r", datatype)
|
|
|
|
# must be a list, or an array of lists
|
|
if issubclass(datatype, List):
|
|
pass
|
|
elif (
|
|
(apdu.propertyArrayIndex is not None)
|
|
and issubclass(datatype, Array)
|
|
and issubclass(datatype.subtype, List)
|
|
):
|
|
pass
|
|
else:
|
|
raise ExecutionError(errorClass="property", errorCode="propertyIsNotAList")
|
|
|
|
# get the value
|
|
value = obj.ReadProperty(apdu.propertyIdentifier, apdu.propertyArrayIndex)
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - value: %r", value)
|
|
if value is None:
|
|
raise PropertyError(apdu.propertyIdentifier)
|
|
if isinstance(value, List):
|
|
ReadRangeApplication._debug(" - value is a list of: %r", datatype.subtype)
|
|
|
|
if apdu.range.byPosition:
|
|
range_by_position = apdu.range.byPosition
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - range_by_position: %r", range_by_position)
|
|
|
|
elif apdu.range.bySequenceNumber:
|
|
range_by_sequence_number = apdu.range.bySequenceNumber
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - range_by_sequence_number: %r", range_by_sequence_number)
|
|
|
|
elif apdu.range.byTime:
|
|
range_by_time = apdu.range.byTime
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - range_by_time: %r", range_by_time)
|
|
|
|
else:
|
|
raise RejectException("missingRequiredParameter")
|
|
|
|
# this is an ack
|
|
resp = ReadRangeACK(context=apdu)
|
|
resp.objectIdentifier = objId
|
|
resp.propertyIdentifier = apdu.propertyIdentifier
|
|
resp.propertyArrayIndex = apdu.propertyArrayIndex
|
|
|
|
resp.resultFlags = [1, 1, 0]
|
|
resp.itemCount = len(value)
|
|
|
|
# save the result in the item data
|
|
resp.itemData = SequenceOfAny()
|
|
resp.itemData.cast_in(datatype(value))
|
|
if _debug:
|
|
ReadRangeApplication._debug(" - resp: %r", resp)
|
|
|
|
# return the result
|
|
self.response(resp)
|
|
|
|
|
|
#
|
|
# __main__
|
|
#
|
|
|
|
|
|
def main():
|
|
global this_application
|
|
|
|
# parse the command line arguments
|
|
args = ConfigArgumentParser(description=__doc__).parse_args()
|
|
|
|
if _debug:
|
|
_log.debug("initialization")
|
|
if _debug:
|
|
_log.debug(" - args: %r", args)
|
|
|
|
# make a device object
|
|
this_device = LocalDeviceObject(ini=args.ini)
|
|
if _debug:
|
|
_log.debug(" - this_device: %r", this_device)
|
|
|
|
# make a simple application
|
|
this_application = ReadRangeApplication(this_device, args.ini.address)
|
|
|
|
timestamp = DateTime(date=Date().now().value, time=Time().now().value)
|
|
# log_status = LogStatus([0,0,0])
|
|
log_record_datum = LogRecordLogDatum(booleanValue=False)
|
|
status_flags = StatusFlags([0, 0, 0, 0])
|
|
log_record = LogRecord(
|
|
timestamp=timestamp, logDatum=log_record_datum, statusFlags=status_flags
|
|
)
|
|
|
|
trend_log_object = TrendLogObject(
|
|
objectIdentifier=("trendLog", 1),
|
|
objectName="Trend-Log-1",
|
|
logBuffer=[log_record],
|
|
)
|
|
_log.debug(" - trend_log_object: %r", trend_log_object)
|
|
this_application.add_object(trend_log_object)
|
|
|
|
_log.debug("running")
|
|
|
|
run()
|
|
|
|
_log.debug("fini")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|