def test_object_identifier_tuple(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_tuple") with self.assertRaises(ValueError): ObjectIdentifier((0, -1)) with self.assertRaises(ValueError): ObjectIdentifier((0, ObjectIdentifier.maximum_instance_number + 1))
def test_object_identifier(self): if _debug: TestObjectIdentifier._debug("test_object_identifier") obj = ObjectIdentifier() assert obj.value == ('analogInput', 0) with self.assertRaises(TypeError): ObjectIdentifier(1.0)
def test_object_identifier_int(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_int") obj = ObjectIdentifier(1) assert obj.value == ('analogInput', 1) assert str(obj) == "ObjectIdentifier(analogInput,1)" obj = ObjectIdentifier(0x0400002) assert obj.value == ('analogOutput', 2) assert str(obj) == "ObjectIdentifier(analogOutput,2)"
def test_object_identifier_tuple(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_tuple") obj = ObjectIdentifier(('analogInput', 0)) assert obj.value == ('analogInput', 0) obj = ObjectIdentifier((u'analogInput', 0)) assert obj.value == (u'analogInput', 0) with self.assertRaises(ValueError): ObjectIdentifier((0, -1)) with self.assertRaises(ValueError): ObjectIdentifier((0, ObjectIdentifier.maximum_instance_number + 1))
def next_request(self): if _debug: ReadPointListApplication._debug("next_request") # check to see if we're done if not self.point_queue: if _debug: ReadPointListApplication._debug(" - done") stop() return # get the next request addr, obj_id, prop_id = self.point_queue.popleft() obj_id = ObjectIdentifier(obj_id).value # build a request request = ReadPropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if _debug: ReadPointListApplication._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) # set a callback for the response iocb.add_callback(self.complete_request) if _debug: ReadPointListApplication._debug(" - iocb: %r", iocb) # send the request this_application.request_io(iocb)
def do_read(self, args): """read <addr> <objid> <prop> [ <indx> ]""" args = args.split() if _debug: TestConsoleCmd._debug("do_read %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value datatype = get_datatype(obj_id[0], prop_id) if not datatype: raise ValueError, "invalid property for object type" # build a request request = ReadPropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if len(args) == 4: request.propertyArrayIndex = int(args[3]) if _debug: TestConsoleCmd._debug(" - request: %r", request) # give it to the application vlan_app_1.request(request) except Exception, e: TestConsoleCmd._exception("exception: %r", e)
def __write_value(self, config_obj_id: str, _value: float) -> None: try: # get config obj obj = self.__get_object(config_obj_id) obj_id = obj.get('object_id') obj_id = ObjectIdentifier(obj_id).value # make a bacpypes obj id addr = self.__get_device() prop_id = self.__get_prop() # write <addr> <objid> <prop> <value> value = float(_value) self.logger.debug(f"write: {config_obj_id} {_value} for port \'{obj.get('name')}\' {str(obj_id)} {prop_id} {value}") request = WritePropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id ) request.pduDestination = Address(addr) # the value to write datatype = get_datatype(obj_id[0], prop_id) value = datatype(value) request.propertyValue = Any() try: request.propertyValue.cast_in(value) except Exception as err: self.logger.critical(f"write: {err}") iocb = IOCB(request) self.app.request_io(iocb) self.logger.debug("write: waiting for response...") loopCount = 0 while loopCount < 20 and not iocb.ioResponse: loopCount += 1 run_once() asyncore.loop(timeout=0.2, count=1) time.sleep(0.2) self.logger.debug(f"write: loopy {loopCount}") stop() # do something for success if iocb.ioResponse: self.logger.debug(f"write: iocb response success!") apdu = iocb.ioResponse # should be an ack if not isinstance(iocb.ioResponse, SimpleAckPDU): self.logger.error(f"write: Not an ACK") return self.logger.debug(f"write: received ACK") # do something for error/reject/abort if iocb.ioError: self.logger.error(f"write: ioError {str(iocb.ioError)}") except Exception as err: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_tb(exc_traceback, file=sys.stdout) self.logger.critical(f"write: {err}")
def object_identifier_decode(tag): """Decode an object_identifier application tag into an object_identifier.""" if _debug: object_identifier_decode._debug("object_identifier_decode %r", tag) obj = ObjectIdentifier(tag) if _debug: object_identifier_decode._debug(" - obj: %r", obj) return obj
def test_object_identifier_endec(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_endec") with self.assertRaises(InvalidTag): obj = ObjectIdentifier(object_identifier_tag('')) # test standard types object_identifier_endec(('analogInput', 0), '00000000')
def test_object_identifier_tag(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_tag") tag = Tag(Tag.applicationTagClass, Tag.objectIdentifierAppTag, 1, xtob('06000003')) obj = ObjectIdentifier(tag) assert obj.value == ('pulseConverter', 3) tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob('')) with self.assertRaises(InvalidTag): ObjectIdentifier(tag) tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) with self.assertRaises(InvalidTag): ObjectIdentifier(tag) tag = Tag(Tag.openingTagClass, 0) with self.assertRaises(InvalidTag): ObjectIdentifier(tag)
def run(self): if _debug: ReadPointListThread._debug("run") global this_application # loop through the points for obj_id, prop_id in self.point_list: obj_id = ObjectIdentifier(obj_id).value # build a request request = ReadPropertyRequest( destination=self.device_address, objectIdentifier=obj_id, propertyIdentifier=prop_id, ) if _debug: ReadPointListThread._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadPointListThread._debug(" - iocb: %r", iocb) # give it to the application deferred(this_application.request_io, iocb) # wait for the response iocb.wait() if iocb.ioResponse: apdu = iocb.ioResponse # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier) if _debug: ReadPointListThread._debug(" - datatype: %r", datatype) if not datatype: raise TypeError("unknown datatype") # special case for array parts, others are managed by cast_out if issubclass(datatype, Array) and (apdu.propertyArrayIndex is not None): if apdu.propertyArrayIndex == 0: value = apdu.propertyValue.cast_out(Unsigned) else: value = apdu.propertyValue.cast_out(datatype.subtype) else: value = apdu.propertyValue.cast_out(datatype) if _debug: ReadPointListThread._debug(" - value: %r", value) # save the value self.response_values.append(value) if iocb.ioError: if _debug: ReadPointListThread._debug(" - error: %r", iocb.ioError) self.response_values.append(iocb.ioError) if _debug: ReadPointListThread._debug(" - fini")
def whohas( self, object_id=None, object_name=None, instance_range_low_limit=0, instance_range_high_limit=4194303, destination=None, global_broadcast=False, ): """ Object ID : analogInput:1 Object Name : string Instance Range Low Limit : 0 Instance Range High Limit : 4194303 destination (optional) : If empty, local broadcast will be used. global_broadcast : False """ obj_id = ObjectIdentifier(object_id) if object_name and not object_id: obj_name = CharacterString(object_name) obj = WhoHasObject(objectName=obj_name) elif object_id and not object_name: obj = WhoHasObject(objectIdentifier=obj_id) else: obj = WhoHasObject(objectIdentifier=obj_id, objectName=obj_name) limits = WhoHasLimits( deviceInstanceRangeLowLimit=instance_range_low_limit, deviceInstanceRangeHighLimit=instance_range_high_limit, ) request = WhoHasRequest(object=obj, limits=limits) if destination: request.pduDestination = Address(destination) else: if global_broadcast: request.pduDestination = GlobalBroadcast() else: request.pduDestination = LocalBroadcast() iocb = IOCB(request) # make an IOCB iocb.set_timeout(2) deferred(self.this_application.request_io, iocb) iocb.wait() iocb = IOCB(request) # make an IOCB self.this_application._last_i_have_received = [] if iocb.ioResponse: # successful response apdu = iocb.ioResponse if iocb.ioError: # unsuccessful: error/reject/abort pass time.sleep(3) # self.discoveredObjects = self.this_application.i_am_counter return self.this_application._last_i_have_received
def main(): global args, this_application # parse the command line arguments parser = ConfigArgumentParser(description=__doc__) # add an argument for seconds per dog parser.add_argument("daddr", help="destination address") parser.add_argument("objid", help="object identifier") parser.add_argument("propid", help="property identifier") # list of values to write parser.add_argument("values", metavar="N", nargs="+", help="values to write") # add an argument for seconds between writes parser.add_argument("--delay", type=float, help="delay between writes in seconds", default=5.0) # now parse the arguments args = parser.parse_args() # convert the parameters args.daddr = Address(args.daddr) args.objid = ObjectIdentifier(args.objid).value args.propid = PropertyIdentifier(args.propid).value 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 = BIPSimpleApplication(this_device, args.ini.address) # make a dog, task scheduling is in milliseconds dog = PrairieDog(args.delay * 1000) if _debug: _log.debug(" - dog: %r", dog) _log.debug("running") run() _log.debug("fini")
def test_ObjectIdentifier(self): """Test valid inputs to ObjectIdentifier ObjectIdentifier(<object type>, <object instance number>) # Assume default object type ObjectIdentifier(<object instance number>) # Assumes default object type # Parse string ObjectIdentifier('<object type>:<object instance number>') """ res = ObjectIdentifier(1).value # ('analogInput', 1) self.assertEqual(res[0], 'analogInput') self.assertEqual(res[1], 1) res = ObjectIdentifier('analogValue:1').value # ('analogValue', 1) self.assertEqual(res[0], 'analogValue') self.assertEqual(res[1], 1) res = ObjectIdentifier(2).value # ('analogInput', 2) self.assertEqual(res[0], 'analogInput') self.assertEqual(res[1], 2) res = ObjectIdentifier(5, 1).value # ('binaryValue', 1) self.assertEqual(res[0], 'binaryValue') self.assertEqual(res[1], 1) return None
def object_identifier_endec(v, x): """Pass the value to ObjectIdentifier, construct a tag from the hex string, and compare results of encode and decoding each other.""" if _debug: object_identifier_endec._debug("object_identifier_endec %r %r", v, x) tag = object_identifier_tag(x) if _debug: object_identifier_endec._debug(" - tag: %r, %r", tag, tag.tagData) obj = ObjectIdentifier(v) if _debug: object_identifier_endec._debug(" - obj: %r, %r", obj, obj.value) assert object_identifier_encode(obj) == tag assert object_identifier_decode(tag) == obj
def form_iocb(device, config=None, request_type="readProperty"): config = config if config is not None else device address = device["address"] if isinstance(device["address"], Address) else Address(device["address"]) object_id = ObjectIdentifier(config["objectId"]) property_id = config.get("propertyId") value = config.get("propertyValue") property_index = config.get("propertyIndex") priority = config.get("priority") vendor = device.get("vendor", config.get("vendorId", 0)) request = None iocb = None if request_type == "readProperty": try: request = ReadPropertyRequest( objectIdentifier=object_id, propertyIdentifier=property_id ) request.pduDestination = address if property_index is not None: request.propertyArrayIndex = int(property_index) iocb = IOCB(request) except Exception as e: log.exception(e) elif request_type == "writeProperty": datatype = get_datatype(object_id.value[0], property_id, vendor) if (isinstance(value, str) and value.lower() == 'null') or value is None: value = Null() request = WritePropertyRequest( objectIdentifier=object_id, propertyIdentifier=property_id ) request.pduDestination = address request.propertyValue = Any() try: value = datatype(value) request.propertyValue = Any(value) except AttributeError as e: log.debug(e) except Exception as error: log.exception("WriteProperty cast error: %r", error) if property_index is not None: request.propertyArrayIndex = property_index if priority is not None: request.priority = priority iocb = IOCB(request) else: log.error("Request type is not found or not implemented") return iocb
def request_values( self, device_address_str: str, objects: Sequence[Tuple[Union[int, str], int]], chunk_size: Optional[int] = None, request_timeout: Optional[Timedelta] = None, ): device_address = Address(device_address_str) device_info: DeviceInfo = self.deviceInfoCache.get_device_info( device_address) # we adjusted chunking for object property request, which requested 3 properties per object # here we request only 1 property so scale chunk_scale = 3 if not chunk_size: chunk_size = 20 * chunk_scale if device_info and device_info.segmentationSupported == "noSegmentation": chunk_size = 4 * chunk_scale logger.debug( f"Chunking for device {device_address_str} is {chunk_size}") for objects_chunk in chunks(objects, chunk_size): prop_reference_list = [ PropertyReference(propertyIdentifier="presentValue") ] read_access_specs = [ ReadAccessSpecification( objectIdentifier=ObjectIdentifier(object_identifier), listOfPropertyReferences=prop_reference_list, ) for object_identifier in objects_chunk ] request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_specs) request.pduDestination = device_address iocb = IOCB(request) iocb.add_callback(self._iocb_callback) if request_timeout: iocb.set_timeout(request_timeout.s) deferred(self.request_io, iocb)
def object_identifier_statement(value): if _debug: object_identifier_statement._debug("object_identifier_statement %r", value) # split into two pieces object_type, object_instance = re.split('[, ]+', value) if object_type.isdigit(): object_type = int(object_type) if _debug: object_identifier_statement._debug(" - object_type: %r", object_type) object_instance = int(object_instance) if _debug: object_identifier_statement._debug(" - object_instance: %r", object_instance) return ObjectIdentifier(object_type, object_instance)
def next_request(self): if _debug: PrairieDog._debug("next_request") # check to see if we're done if not self.point_queue: if _debug: PrairieDog._debug(" - done") # dump out the results for request, response in zip(point_list, self.response_values): print(request, response) # no longer busy self.is_busy = False return # get the next request addr, obj_id, prop_id = self.point_queue.popleft() obj_id = ObjectIdentifier(obj_id).value # build a request request = ReadPropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if _debug: PrairieDog._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: PrairieDog._debug(" - iocb: %r", iocb) # set a callback for the response iocb.add_callback(self.complete_request) # give it to the application self.request_io(iocb)
def next_request(self): if _debug: ReadPointListApplication._debug("next_request") # check to see if we're done if not self.point_queue: if _debug: ReadPointListApplication._debug(" - done") stop() return # get the next request point_info = self.point_queue.popleft() if _debug: ReadPointListApplication._debug(" - point_info: %r", point_info) # build a request request = ReadPropertyRequest( destination=Address(point_info["address"]), objectIdentifier=ObjectIdentifier(point_info["objectIdentifier"]).value, propertyIdentifier=point_info.get("propertyIdentifier", "presentValue"), ) if _debug: ReadPointListApplication._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) iocb.point_info = point_info # set a callback for the response iocb.add_callback(self.complete_request) if _debug: ReadPointListApplication._debug(" - iocb: %r", iocb) # send the request this_application.request_io(iocb)
def test_object_identifier_str(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_str") obj = ObjectIdentifier("analogInput:1") assert obj.value == ('analogInput', 1) assert str(obj) == "ObjectIdentifier(analogInput,1)" obj = ObjectIdentifier("8:123") assert obj.value == ('device', 123) assert str(obj) == "ObjectIdentifier(device,123)" with self.assertRaises(ValueError): ObjectIdentifier("x") with self.assertRaises(ValueError): ObjectIdentifier(":1") with self.assertRaises(ValueError): ObjectIdentifier("1:") with self.assertRaises(ValueError): ObjectIdentifier("a:b")
def do_read(self, args): """read <addr> <objid> <prop> [ <indx> ]""" args = args.split() if _debug: ReadPropertyAnyConsoleCmd._debug("do_read %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value if prop_id.isdigit(): prop_id = int(prop_id) # build a request request = ReadPropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if len(args) == 4: request.propertyArrayIndex = int(args[3]) if _debug: ReadPropertyAnyConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadPropertyAnyConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application deferred(this_application.request_io, iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: apdu = iocb.ioResponse if _debug: ReadPropertyAnyConsoleCmd._debug(" - apdu: %r", apdu) try: tag_list = apdu.propertyValue.tagList # all tags application encoded non_app_tags = [ tag for tag in tag_list if tag.tagClass != Tag.applicationTagClass ] if non_app_tags: raise RuntimeError( "value has some non-application tags") # all the same type first_tag = tag_list[0] other_type_tags = [ tag for tag in tag_list[1:] if tag.tagNumber != first_tag.tagNumber ] if other_type_tags: raise RuntimeError( "all the tags must be the same type") # find the datatype datatype = Tag._app_tag_class[first_tag.tagNumber] if _debug: ReadPropertyAnyConsoleCmd._debug( " - datatype: %r", datatype) if not datatype: raise RuntimeError("unknown datatype") # more than one then it's an array of these if len(tag_list) > 1: datatype = ArrayOf(datatype) if _debug: ReadPropertyAnyConsoleCmd._debug( " - array: %r", datatype) # cast out the value value = apdu.propertyValue.cast_out(datatype) if _debug: ReadPropertyAnyConsoleCmd._debug( " - value: %r", value) sys.stdout.write("%s (%s)\n" % (value, datatype)) except RuntimeError as err: sys.stdout.write("error: %s\n" % (err, )) sys.stdout.flush() # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: ReadPropertyAnyConsoleCmd._exception("exception: %r", error)
def do_write(self, args): """ write <indx> <value> write 0 <len> write [ <value> ]... """ args = args.split() ReadWritePropertyConsoleCmd._debug("do_write %r", args) try: addr, obj_id = context obj_id = ObjectIdentifier(obj_id).value prop_id = 'eventMessageTexts' indx = None if args and args[0].isdigit(): indx = int(args[0]) if indx == 0: value = Unsigned(int(args[1])) else: value = CharacterString(args[1]) else: value = ArrayOf(CharacterString)(args[0:]) # build a request request = WritePropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id ) request.pduDestination = Address(addr) # save the value request.propertyValue = Any() try: request.propertyValue.cast_in(value) except Exception as error: ReadWritePropertyConsoleCmd._exception("WriteProperty cast error: %r", error) # optional array index if indx is not None: request.propertyArrayIndex = indx if _debug: ReadWritePropertyConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadWritePropertyConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: # should be an ack if not isinstance(iocb.ioResponse, SimpleAckPDU): if _debug: ReadWritePropertyConsoleCmd._debug(" - not an ack") return sys.stdout.write("ack\n") # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: ReadWritePropertyConsoleCmd._exception("exception: %r", error)
def do_readrange(self, args): """readrange <addr> <objid> <prop> [ <indx> ] [ p <indx> <count> ] [ s <seq> <count> ] [ t <date> <time> <count> ] """ args = args.split() if _debug: ReadRangeConsoleCmd._debug("do_readrange %r", args) try: addr = Address(args.pop(0)) obj_id = ObjectIdentifier(args.pop(0)).value prop_id = args.pop(0) datatype = get_datatype(obj_id[0], prop_id) if not datatype: raise ValueError("invalid property for object type") # build a request request = ReadRangeRequest(destination=addr, objectIdentifier=obj_id, propertyIdentifier=prop_id) # index is optional if args: if args[0].isdigit(): if not issubclass(datatype, Array): raise ValueError("property is not an array") request.propertyArrayIndex = int(args.pop(0)) datatype = datatype.subtype if not issubclass(datatype, List): raise ValueError("property is not a list") # range is optional if args: range_type = args.pop(0) if range_type == "p": rbp = RangeByPosition(referenceIndex=int(args[0]), count=int(args[1])) request.range = Range(byPosition=rbp) elif range_type == "s": rbs = RangeBySequenceNumber(referenceSequenceNumber=int( args[0]), count=int(args[1])) request.range = Range(bySequenceNumber=rbs) elif range_type == "t": rbt = RangeByTime( referenceTime=DateTime(date=Date(args[0]), time=Time(args[1])), count=int(args[2]), ) request.range = Range(byTime=rbt) else: raise ValueError("unknown range type: %r" % (range_type, )) if _debug: ReadRangeConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadRangeConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application deferred(this_application.request_io, iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: apdu = iocb.ioResponse if _debug: ReadRangeConsoleCmd._debug(" - apdu: %r", apdu) # should be an ack if not isinstance(apdu, ReadRangeACK): if _debug: ReadRangeConsoleCmd._debug(" - not an ack") return # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier) if _debug: ReadRangeConsoleCmd._debug(" - datatype: %r", datatype) if not datatype: raise TypeError("unknown datatype") sys.stdout.write("firstSequenceNumber: %s\n" % (apdu.firstSequenceNumber, )) sys.stdout.write("resultFlags: %s\n" % (apdu.resultFlags, )) # cast out the data into a list value = apdu.itemData.cast_out(datatype) # dump it out for i, item in enumerate(value): sys.stdout.write("[%d]\n" % (i, )) item.debug_contents(file=sys.stdout, indent=2) sys.stdout.flush() # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + "\n") except Exception as error: ReadRangeConsoleCmd._exception("exception: %r", error)
def test_object_identifier_copy(self): if _debug: TestObjectIdentifier._debug("test_object_identifier_copy") obj1 = ObjectIdentifier(('analogInput', 1)) obj2 = ObjectIdentifier(obj1) assert obj2.value == ('analogInput', 1)
def do_write(self, args): """write <addr> <objid> <prop> <value> [ <indx> ] [ <priority> ]""" args = args.split() ReadWritePropertyConsoleCmd._debug("do_write %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value if not get_object_class(obj_id[0], VendorAVObject.vendor_id): raise ValueError("unknown object type") if prop_id.isdigit(): prop_id = int(prop_id) if _debug: ReadWritePropertyConsoleCmd._debug(" - prop_id: %r", prop_id) value = args[3] indx = None if len(args) >= 5: if args[4] != "-": indx = int(args[4]) if _debug: ReadWritePropertyConsoleCmd._debug(" - indx: %r", indx) priority = None if len(args) >= 6: priority = int(args[5]) if _debug: ReadWritePropertyConsoleCmd._debug(" - priority: %r", priority) # get the datatype datatype = get_datatype(obj_id[0], prop_id, VendorAVObject.vendor_id) if _debug: ReadWritePropertyConsoleCmd._debug(" - datatype: %r", datatype) # change atomic values into something encodeable, null is a special case if (value == 'null'): value = Null() elif issubclass(datatype, Atomic): if datatype is Integer: value = int(value) elif datatype is Real: value = float(value) elif datatype is Unsigned: value = int(value) value = datatype(value) elif issubclass(datatype, Array) and (indx is not None): if indx == 0: value = Integer(value) elif issubclass(datatype.subtype, Atomic): value = datatype.subtype(value) elif not isinstance(value, datatype.subtype): raise TypeError("invalid result datatype, expecting %s" % (datatype.subtype.__name__, )) elif not isinstance(value, datatype): raise TypeError("invalid result datatype, expecting %s" % (datatype.__name__, )) if _debug: ReadWritePropertyConsoleCmd._debug( " - encodeable value: %r %s", value, type(value)) # build a request request = WritePropertyRequest(objectIdentifier=obj_id, propertyIdentifier=prop_id) request.pduDestination = Address(addr) # save the value request.propertyValue = Any() try: request.propertyValue.cast_in(value) except Exception as error: ReadWritePropertyConsoleCmd._exception( "WriteProperty cast error: %r", error) # optional array index if indx is not None: request.propertyArrayIndex = indx # optional priority if priority is not None: request.priority = priority if _debug: ReadWritePropertyConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadWritePropertyConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application deferred(this_application.request_io, iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: sys.stdout.write("ack\n") # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: ReadWritePropertyConsoleCmd._exception("exception: %r", error)
def do_write(self, args): """write <addr> <objid> <prop> [ <indx> ]""" args = args.split() if _debug: WriteSomethingConsoleCmd._debug("do_write %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value if prop_id.isdigit(): prop_id = int(prop_id) # build a request request = WritePropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if len(args) == 4: request.propertyArrayIndex = int(args[3]) # build a custom datastructure tag_list = TagList([ OpeningTag(1), ContextTag(0, xtob('9c40')), ContextTag(1, xtob('02')), ContextTag(2, xtob('02')), ClosingTag(1) ]) if _debug: WriteSomethingConsoleCmd._debug(" - tag_list: %r", tag_list) # stuff the tag list into an Any request.propertyValue = Any() request.propertyValue.decode(tag_list) if _debug: WriteSomethingConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: WriteSomethingConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application deferred(this_application.request_io, iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: # should be an ack if not isinstance(iocb.ioResponse, SimpleAckPDU): if _debug: WriteSomethingConsoleCmd._debug(" - not an ack") return sys.stdout.write("ack\n") # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: WriteSomethingConsoleCmd._exception("exception: %r", error)
def do_read(self, args): """read <addr> <type>:<inst> <prop> [ <indx> ]""" args = args.split() if _debug: BacnetClientConsoleCmd._debug("do_read %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value datatype = get_datatype(obj_id[0], prop_id) if not datatype: raise ValueError("invalid property for object type") # build a request request = ReadPropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if len(args) == 4: request.propertyArrayIndex = int(args[3]) if _debug: BacnetClientConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: BacnetClientConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) # wait for it to complete iocb.wait() # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') # do something for success elif iocb.ioResponse: apdu = iocb.ioResponse # should be an ack if not isinstance(apdu, ReadPropertyACK): if _debug: BacnetClientConsoleCmd._debug(" - not an ack") return # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier) if _debug: BacnetClientConsoleCmd._debug(" - datatype: %r", datatype) if not datatype: raise TypeError("unknown datatype") # special case for array parts, others are managed by cast_out if issubclass(datatype, Array) and (apdu.propertyArrayIndex is not None): if apdu.propertyArrayIndex == 0: value = apdu.propertyValue.cast_out(Unsigned) else: value = apdu.propertyValue.cast_out(datatype.subtype) else: value = apdu.propertyValue.cast_out(datatype) if _debug: BacnetClientConsoleCmd._debug(" - value: %r", value) sys.stdout.write(str(value) + '\n') if hasattr(value, 'debug_contents'): value.debug_contents(file=sys.stdout) sys.stdout.flush() # do something with nothing? else: if _debug: BacnetClientConsoleCmd._debug( " - ioError or ioResponse expected") except Exception as error: BacnetClientConsoleCmd._exception("exception: %r", error)
def do_write(self, args): """write <addr> <type>:<inst> <prop> <value> [ <indx> ] [ <priority> ]""" args = args.split() BacnetClientConsoleCmd._debug("do_write %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value value = args[3] indx = None if len(args) >= 5: if args[4] != "-": indx = int(args[4]) if _debug: BacnetClientConsoleCmd._debug(" - indx: %r", indx) priority = None if len(args) >= 6: priority = int(args[5]) if _debug: BacnetClientConsoleCmd._debug(" - priority: %r", priority) # get the datatype datatype = get_datatype(obj_id[0], prop_id) if _debug: BacnetClientConsoleCmd._debug(" - datatype: %r", datatype) # change atomic values into something encodeable, null is a special case if (value == 'null'): value = Null() elif issubclass(datatype, AnyAtomic): dtype, dvalue = value.split(':', 1) if _debug: BacnetClientConsoleCmd._debug( " - dtype, dvalue: %r, %r", dtype, dvalue) datatype = { 'b': Boolean, 'u': lambda x: Unsigned(int(x)), 'i': lambda x: Integer(int(x)), 'r': lambda x: Real(float(x)), 'd': lambda x: Double(float(x)), 'o': OctetString, 'c': CharacterString, 'bs': BitString, 'date': Date, 'time': Time, 'id': ObjectIdentifier, }[dtype] if _debug: BacnetClientConsoleCmd._debug(" - datatype: %r", datatype) value = datatype(dvalue) if _debug: BacnetClientConsoleCmd._debug(" - value: %r", value) elif issubclass(datatype, Atomic): if datatype is Integer: value = int(value) elif datatype is Real: value = float(value) elif datatype is Unsigned: value = int(value) value = datatype(value) elif issubclass(datatype, Array) and (indx is not None): if indx == 0: value = Integer(value) elif issubclass(datatype.subtype, Atomic): value = datatype.subtype(value) elif not isinstance(value, datatype.subtype): raise TypeError("invalid result datatype, expecting %s" % (datatype.subtype.__name__, )) elif not isinstance(value, datatype): raise TypeError("invalid result datatype, expecting %s" % (datatype.__name__, )) if _debug: BacnetClientConsoleCmd._debug(" - encodeable value: %r %s", value, type(value)) # build a request request = WritePropertyRequest(objectIdentifier=obj_id, propertyIdentifier=prop_id) request.pduDestination = Address(addr) # save the value request.propertyValue = Any() try: request.propertyValue.cast_in(value) except Exception as error: BacnetClientConsoleCmd._exception( "WriteProperty cast error: %r", error) # optional array index if indx is not None: request.propertyArrayIndex = indx # optional priority if priority is not None: request.priority = priority if _debug: BacnetClientConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: BacnetClientConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: # should be an ack if not isinstance(iocb.ioResponse, SimpleAckPDU): if _debug: BacnetClientConsoleCmd._debug(" - not an ack") return sys.stdout.write("ack\n") # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: BacnetClientConsoleCmd._exception("exception: %r", error)
def do_read(self, args): """read <addr> <objid> <prop> [ <indx> ]""" args = args.split() if _debug: ReadWritePropertyConsoleCmd._debug("do_read %r", args) try: addr, obj_id, prop_id = args[:3] obj_id = ObjectIdentifier(obj_id).value if prop_id.isdigit(): prop_id = int(prop_id) if _debug: ReadWritePropertyConsoleCmd._debug(" - prop_id: %r", prop_id) datatype = get_datatype(obj_id[0], prop_id, VendorAVObject.vendor_id) if not datatype: raise ValueError("invalid property for object type") # build a request request = ReadPropertyRequest( objectIdentifier=obj_id, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if len(args) == 4: request.propertyArrayIndex = int(args[3]) if _debug: ReadWritePropertyConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadWritePropertyConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application deferred(this_application.request_io, iocb) # wait for it to complete iocb.wait() # do something for success if iocb.ioResponse: apdu = iocb.ioResponse # peek at the value tag value_tag = apdu.propertyValue.tagList.Peek() if _debug: ReadWritePropertyConsoleCmd._debug(" - value_tag: %r", value_tag) # make sure that it is application tagged if value_tag.tagClass != Tag.applicationTagClass: sys.stdout.write("value is not application encoded\n") else: # find the datatype datatype = Tag._app_tag_class[value_tag.tagNumber] if _debug: ReadWritePropertyConsoleCmd._debug( " - datatype: %r", datatype) if not datatype: raise TypeError("unknown datatype") # cast out the value value = apdu.propertyValue.cast_out(datatype) if _debug: ReadWritePropertyConsoleCmd._debug( " - value: %r", value) sys.stdout.write("%s (%s)\n" % (value, datatype)) sys.stdout.flush() # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: ReadWritePropertyConsoleCmd._exception("exception: %r", error)