def build_rrange_request( self, args, range_params=None, arr_index=None, vendor_id=0, bacoid=None ): addr, obj_type, obj_inst, prop_id = args[:4] vendor_id = vendor_id bacoid = bacoid if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type, vendor_id=vendor_id): raise ValueError("Unknown object type {}".format(obj_type)) obj_inst = int(obj_inst) if prop_id.isdigit(): prop_id = int(prop_id) datatype = get_datatype(obj_type, prop_id, vendor_id=vendor_id) if not datatype: raise ValueError("invalid property for object type") # build a request request = ReadRangeRequest( objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id ) request.pduDestination = Address(addr) if range_params is not None: range_type, first, date, time, count = range_params if range_type == "p": rbp = RangeByPosition(referenceIndex=int(first), count=int(count)) request.range = Range(byPosition=rbp) elif range_type == "s": rbs = RangeBySequenceNumber( referenceSequenceNumber=int(first), count=int(count) ) request.range = Range(bySequenceNumber=rbs) elif range_type == "t": rbt = RangeByTime( referenceTime=DateTime( date=Date(date).value, time=Time(time).value ), count=int(count), ) request.range = Range(byTime=rbt) elif range_type == "x": # should be missing required parameter request.range = Range() else: raise ValueError("unknown range type: %r" % (range_type,)) if len(args) == 5: request.propertyArrayIndex = int(args[4]) self._log.debug("{:<20} {!r}".format("REQUEST", request)) return request
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)