def _get_access_spec(self, obj_data, properties): count = 0 obj_type, obj_inst = obj_data prop_ref_list = [] for prop, prop_index in properties: prop_ref = PropertyReference(propertyIdentifier=prop) if prop_index is not None: prop_ref.propertyArrayIndex = prop_index prop_ref_list.append(prop_ref) count += 1 return (ReadAccessSpecification(objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_ref_list), count)
def build_property_reference_list(obj_type, list_of_properties): property_reference_list = [] for prop in list_of_properties: idx = None if "@idx:" in prop: prop, idx = prop.split("@idx:") prop_id = validate_property_id(obj_type, prop) prop_reference = PropertyReference(propertyIdentifier=prop_id) if idx: prop_reference.propertyArrayIndex = int(idx) property_reference_list.append(prop_reference) return property_reference_list
def _get_access_spec(self, obj_data, properties): count = 0 obj_type, obj_inst = obj_data prop_ref_list = [] for prop, prop_index in properties: prop_ref = PropertyReference(propertyIdentifier=prop) if prop_index is not None: prop_ref.propertyArrayIndex = prop_index prop_ref_list.append(prop_ref) count += 1 return (ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_ref_list), count)
def do_read(self, args): """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )...""" args = args.split() if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args) try: i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError, "unknown object type" obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError, "invalid property for object type" # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError, "provide at least one property" # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError, "at least one read access specification required" # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) if _debug: ReadPropertyMultipleConsoleCmd._debug(" - request: %r", request) # give it to the application this_application.request(request) except Exception, e: ReadPropertyMultipleConsoleCmd._exception("exception: %r", e)
def do_read(self, args): """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )...""" args = args.split() if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args) try: i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type") # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) if _debug: ReadPropertyMultipleConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadPropertyMultipleConsoleCmd._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: apdu = iocb.ioResponse # should be an ack if not isinstance(apdu, ReadPropertyMultipleACK): if _debug: ReadPropertyMultipleConsoleCmd._debug( " - not an ack") return # loop through the results for result in apdu.listOfReadAccessResults: # here is the object identifier objectIdentifier = result.objectIdentifier if _debug: ReadPropertyMultipleConsoleCmd._debug( " - objectIdentifier: %r", objectIdentifier) # now come the property values per object for element in result.listOfResults: # get the property and array index propertyIdentifier = element.propertyIdentifier if _debug: ReadPropertyMultipleConsoleCmd._debug( " - propertyIdentifier: %r", propertyIdentifier) propertyArrayIndex = element.propertyArrayIndex if _debug: ReadPropertyMultipleConsoleCmd._debug( " - propertyArrayIndex: %r", propertyArrayIndex) # here is the read result readResult = element.readResult sys.stdout.write(propertyIdentifier) if propertyArrayIndex is not None: sys.stdout.write("[" + str(propertyArrayIndex) + "]") # check for an error if readResult.propertyAccessError is not None: sys.stdout.write( " ! " + str(readResult.propertyAccessError) + '\n') else: # here is the value propertyValue = readResult.propertyValue # find the datatype datatype = get_datatype(objectIdentifier[0], propertyIdentifier) if _debug: ReadPropertyMultipleConsoleCmd._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 (propertyArrayIndex is not None): if propertyArrayIndex == 0: value = propertyValue.cast_out(Unsigned) else: value = propertyValue.cast_out( datatype.subtype) else: value = propertyValue.cast_out(datatype) if _debug: ReadPropertyMultipleConsoleCmd._debug( " - value: %r", value) sys.stdout.write(" = " + str(value) + '\n') sys.stdout.flush() # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception, error: ReadPropertyMultipleConsoleCmd._exception("exception: %r", error)
def do_rpm(self, args): """ rpm <devid> ( <objid> ( <prop> [ <indx> ] )... )... Send a Read-Property-Multiple request to a device identified by its device identifier. """ args = args.split() if _debug: DiscoverConsoleCmd._debug("do_rpm %r", args) try: i = 0 devid = int(args[i]) if _debug: DiscoverConsoleCmd._debug(" - devid: %r", devid) i += 1 # map the devid identifier to an address from the database addr = snapshot.get_value(devid, '-', 'address') if not addr: raise ValueError("unknown device") if _debug: DiscoverConsoleCmd._debug(" - addr: %r", addr) read_access_spec_list = [] while i < len(args): obj_id = ObjectIdentifier(args[i]).value if _debug: DiscoverConsoleCmd._debug(" - obj_id: %r", obj_id) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if _debug: DiscoverConsoleCmd._debug(" - prop_id: %r", prop_id) if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_id[0], prop_id) if not datatype: raise ValueError( "invalid property for object type") # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=obj_id, listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) if _debug: DiscoverConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: DiscoverConsoleCmd._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: DiscoverConsoleCmd._debug(" - apdu: %r", apdu) # should be an ack if not isinstance(apdu, ReadPropertyMultipleACK): if _debug: DiscoverConsoleCmd._debug(" - not an ack") return # loop through the results for result in apdu.listOfReadAccessResults: # here is the object identifier objectIdentifier = result.objectIdentifier if _debug: DiscoverConsoleCmd._debug(" - objectIdentifier: %r", objectIdentifier) # now come the property values per object for element in result.listOfResults: # get the property and array index propertyIdentifier = element.propertyIdentifier if _debug: DiscoverConsoleCmd._debug( " - propertyIdentifier: %r", propertyIdentifier) propertyArrayIndex = element.propertyArrayIndex if _debug: DiscoverConsoleCmd._debug( " - propertyArrayIndex: %r", propertyArrayIndex) # here is the read result readResult = element.readResult property_label = str(propertyIdentifier) if propertyArrayIndex is not None: property_label += "[" + str( propertyArrayIndex) + "]" # check for an error if readResult.propertyAccessError is not None: if interactive: print("{} ! {}".format( property_label, readResult.propertyAccessError)) else: # here is the value propertyValue = readResult.propertyValue # find the datatype datatype = get_datatype(objectIdentifier[0], propertyIdentifier) if _debug: DiscoverConsoleCmd._debug( " - datatype: %r", datatype) if not datatype: str_value = '?' else: # special case for array parts, others are managed by cast_out if issubclass(datatype, Array) and (propertyArrayIndex is not None): if propertyArrayIndex == 0: datatype = Unsigned else: datatype = datatype.subtype if _debug: DiscoverConsoleCmd._debug( " - datatype: %r", datatype) value = propertyValue.cast_out(datatype) if _debug: DiscoverConsoleCmd._debug( " - value: %r", value) # convert the value to a string if hasattr(value, 'dict_contents'): dict_contents = value.dict_contents( as_class=OrderedDict) str_value = json.dumps(dict_contents) else: str_value = str(value) if interactive: print("{}: {}".format(property_label, str_value)) # save it in the snapshot snapshot.upsert(devid, '{}:{}'.format(*objectIdentifier), property_label, str_value) # do something for error/reject/abort if iocb.ioError: if interactive: print(str(iocb.ioError)) except Exception as error: DiscoverConsoleCmd._exception("exception: %r", error)
def build_rpm_request(self, args): """ Build request from args """ i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ("all", "required", "optional"): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type : {} | {}".format( (obj_type, prop_id) ) ) # build a property reference prop_reference = PropertyReference(propertyIdentifier=prop_id) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 prop_reference_list.append(prop_reference) if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) read_access_spec_list.append(read_access_spec) if not read_access_spec_list: raise RuntimeError("at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list ) request.pduDestination = Address(addr) self._log.debug("{:<20} {!r}".format("REQUEST", request)) return request
def create_ReadPropertyMultipleRequest(args): """ Create a request to compare with called arg """ args = args.split() i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type : %s | %s" % (obj_type, prop_id)) # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) return request
def readMultiple(self, args): """ This function build a readMultiple request wait for the answer and return the value :param args: String with <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )... :returns: data read from device (str representing data like 10 or True) *Example*:: import BAC0 myIPAddr = '192.168.1.10' bacnet = BAC0.ReadWriteScript(localIPAddr = myIPAddr) bacnet.readMultiple('2:5 analogInput 1 presentValue units') will read controller with a MAC address of 5 in the network 2 Will ask for the present Value and the units of analog input 1 (AI:1) """ args = args.split() print_debug("readMultiple %r", args) try: i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError("invalid property for object type : %s | %s" % (obj_type, prop_id)) # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError("at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) print_debug(" - request: %r", request) # give it to the application self.this_application.request(request) except ReadPropertyMultipleException as error: ReadProperty._exception("exception: %r", error) data = None while True: try: data, evt = self.this_application.ResponseQueue.get(timeout=self._TIMEOUT) evt.set() return data except Empty: print('No response from controller') return None
def do_read(self, args): """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )...""" args = args.split() if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args) try: i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError("invalid property for object type") # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError("at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) if _debug: ReadPropertyMultipleConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ReadPropertyMultipleConsoleCmd._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: apdu = iocb.ioResponse # should be an ack if not isinstance(apdu, ReadPropertyMultipleACK): if _debug: ReadPropertyMultipleConsoleCmd._debug(" - not an ack") return # loop through the results for result in apdu.listOfReadAccessResults: # here is the object identifier objectIdentifier = result.objectIdentifier if _debug: ReadPropertyMultipleConsoleCmd._debug(" - objectIdentifier: %r", objectIdentifier) # now come the property values per object for element in result.listOfResults: # get the property and array index propertyIdentifier = element.propertyIdentifier if _debug: ReadPropertyMultipleConsoleCmd._debug(" - propertyIdentifier: %r", propertyIdentifier) propertyArrayIndex = element.propertyArrayIndex if _debug: ReadPropertyMultipleConsoleCmd._debug(" - propertyArrayIndex: %r", propertyArrayIndex) # here is the read result readResult = element.readResult sys.stdout.write(propertyIdentifier) if propertyArrayIndex is not None: sys.stdout.write("[" + str(propertyArrayIndex) + "]") # check for an error if readResult.propertyAccessError is not None: sys.stdout.write(" ! " + str(readResult.propertyAccessError) + '\n') else: # here is the value propertyValue = readResult.propertyValue # find the datatype datatype = get_datatype(objectIdentifier[0], propertyIdentifier) if _debug: ReadPropertyMultipleConsoleCmd._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 (propertyArrayIndex is not None): if propertyArrayIndex == 0: value = propertyValue.cast_out(Unsigned) else: value = propertyValue.cast_out(datatype.subtype) else: value = propertyValue.cast_out(datatype) if _debug: ReadPropertyMultipleConsoleCmd._debug(" - value: %r", value) sys.stdout.write(" = " + str(value) + '\n') sys.stdout.flush() # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: ReadPropertyMultipleConsoleCmd._exception("exception: %r", error)
def readMultiple(self, args): """ This function build a readMultiple request wait for the answer and return the value :param args: String with <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )... :returns: data read from device (str representing data like 10 or True) *Example*:: import BAC0 myIPAddr = '192.168.1.10' bacnet = BAC0.ReadWriteScript(localIPAddr = myIPAddr) bacnet.readMultiple('2:5 analogInput 1 presentValue units') will read controller with a MAC address of 5 in the network 2 Will ask for the present Value and the units of analog input 1 (AI:1) """ args = args.split() print_debug("readMultiple %r", args) try: i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type : %s | %s" % (obj_type, prop_id)) # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) print_debug(" - request: %r", request) # give it to the application self.this_application.request(request) except ReadPropertyMultipleException as error: ReadProperty._exception("exception: %r", error) data = None while True: try: data, evt = self.this_application.ResponseQueue.get( timeout=self._TIMEOUT) evt.set() return data except Empty: print('No response from controller') return None
def read_properties(self, target_address, point_map, max_per_request=None, use_read_multiple=True): """Read a set of points and return the results""" if not use_read_multiple: return self.read_using_single_request(target_address, point_map) #Set max_per_request really high if not set. if max_per_request is None: max_per_request = self._max_per_request _log.debug("Reading {count} points on {target}, max per" " scrape: {max}".format(count=len(point_map), target=target_address, max=max_per_request)) # This will be used to get the results mapped # back on the the names reverse_point_map = {} #Used to group properties together for the request. object_property_map = defaultdict(list) for name, properties in point_map.iteritems(): if len(properties) == 3: object_type, instance_number, property_name = properties property_index = None elif len(properties) == 4: object_type, instance_number, property_name, property_index = properties else: _log.error( "skipping {} in request to {}: incorrect number of parameters" .format(name, target_address)) reverse_point_map[object_type, instance_number, property_name, property_index] = name object_property_map[object_type, instance_number].append( (property_name, property_index)) result_dict = {} finished = False while not finished: read_access_spec_list = [] count = 0 for _ in xrange(max_per_request): try: obj_data, properties = object_property_map.popitem() except KeyError: finished = True break obj_type, obj_inst = obj_data prop_ref_list = [] for prop, prop_index in properties: prop_ref = PropertyReference(propertyIdentifier=prop) if prop_index is not None: prop_ref.propertyArrayIndex = prop_index prop_ref_list.append(prop_ref) count += 1 read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_ref_list) read_access_spec_list.append(read_access_spec) if read_access_spec_list: _log.debug( "Requesting {count} properties from {target}".format( count=count, target=target_address)) request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list) request.pduDestination = Address(target_address) iocb = self.iocb_class(request) self.this_application.submit_request(iocb) bacnet_results = iocb.ioResult.get(10) _log.debug( "Received read response from {target} count: {count}". format(count=count, target=target_address)) for prop_tuple, value in bacnet_results.iteritems(): name = reverse_point_map[prop_tuple] result_dict[name] = value return result_dict
def create_ReadPropertyMultipleRequest(args): """ Create a request to compare with called arg """ args = args.split() i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type : %s | %s" % (obj_type, prop_id)) # build a property reference prop_reference = PropertyReference(propertyIdentifier=prop_id, ) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError("at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) return request
def read_properties(self, target_address, point_map, max_per_request=None): """Read a set of points and return the results""" #Set max_per_request really high if not set. if max_per_request is None: max_per_request = 1000000 _log.debug("Reading {count} points on {target}, max per scrape: {max}".format(count=len(point_map), target=target_address, max=max_per_request)) #This will be used to get the results mapped # back on the the names reverse_point_map = {} #Used to group properties together for the request. object_property_map = defaultdict(list) for name, properties in point_map.iteritems(): if len(properties) == 3: object_type, instance_number, property_name = properties property_index = None elif len(properties) == 4: object_type, instance_number, property_name, property_index = properties else: _log.error("skipping {} in request to {}: incorrect number of parameters".format(name, target_address)) reverse_point_map[object_type, instance_number, property_name, property_index] = name object_property_map[object_type, instance_number].append((property_name, property_index)) result_dict={} finished = False while not finished: read_access_spec_list = [] count = 0 for _ in xrange(max_per_request): try: obj_data, properties = object_property_map.popitem() except KeyError: finished = True break obj_type, obj_inst = obj_data prop_ref_list = [] for prop, prop_index in properties: prop_ref = PropertyReference(propertyIdentifier=prop) if prop_index is not None: prop_ref.propertyArrayIndex = prop_index prop_ref_list.append(prop_ref) count += 1 read_access_spec = ReadAccessSpecification(objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_ref_list) read_access_spec_list.append(read_access_spec) if read_access_spec_list: _log.debug("Requesting {count} properties from {target}".format(count=count, target=target_address)) request = ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_spec_list) request.pduDestination = Address(target_address) iocb = self.iocb_class(request) self.this_application.submit_request(iocb) bacnet_results = iocb.ioResult.get(10) _log.debug("Received read response from {target}".format(count=count, target=target_address)) for prop_tuple, value in bacnet_results.iteritems(): name = reverse_point_map[prop_tuple] result_dict[name] = value return result_dict
def build_rpm_request(self, args, vendor_id=0): """ Build request from args """ self._log.debug(args) i = 0 addr = args[i] i += 1 vendor_id = vendor_id read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif "@obj_" in obj_type: obj_type = int(obj_type.split("_")[1]) elif not get_object_class(obj_type, vendor_id=vendor_id): raise ValueError("Unknown object type : {}".format(obj_type)) obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if "@obj_" in prop_id: break if prop_id not in PropertyIdentifier.enumerations: try: if "@prop_" in prop_id: prop_id = int(prop_id.split("_")[1]) self._log.debug( "Proprietary property : {} | {} -> Vendor : {}" .format(obj_type, prop_id, vendor_id)) else: break except: break elif prop_id in ( "all", "required", "optional", "objectName", "objectType", "objectIdentifier", "polarity", ): pass else: datatype = get_datatype(obj_type, prop_id, vendor_id=vendor_id) if not datatype: raise ValueError( "invalid property for object type : {} | {}". format(obj_type, prop_id)) i += 1 # build a property reference prop_reference = PropertyReference(propertyIdentifier=prop_id) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 prop_reference_list.append(prop_reference) if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) read_access_spec_list.append(read_access_spec) if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list) request.pduDestination = Address(addr) return request
def build_rpm_request(self, args): """ Build request from args """ i = 0 addr = args[i] i += 1 read_access_spec_list = [] while i < len(args): obj_type = args[i] i += 1 if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") obj_inst = int(args[i]) i += 1 prop_reference_list = [] while i < len(args): prop_id = args[i] if prop_id not in PropertyIdentifier.enumerations: break i += 1 if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type : {} | {}".format( (obj_type, prop_id))) # build a property reference prop_reference = PropertyReference(propertyIdentifier=prop_id) # check for an array index if (i < len(args)) and args[i].isdigit(): prop_reference.propertyArrayIndex = int(args[i]) i += 1 prop_reference_list.append(prop_reference) if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list) read_access_spec_list.append(read_access_spec) if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list) request.pduDestination = Address(addr) self._log.debug("{:<20} {!r}".format( 'REQUEST', request)) return request
def do_read(self, addr, properties): """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )...""" read_access_spec_list = [] try: for obj_type, obj_inst, props in properties: if type(obj_type) is int: pass elif obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError("unknown object type") prop_reference_list = [] for prop_id, idx in props: if prop_id not in PropertyIdentifier.enumerations: break if prop_id in ('all', 'required', 'optional'): pass else: datatype = get_datatype(obj_type, prop_id) if not datatype: raise ValueError( "invalid property for object type") # build a property reference prop_reference = PropertyReference( propertyIdentifier=prop_id, ) # check for an array index if idx is not None: prop_reference.propertyArrayIndex = int(idx) # add it to the list prop_reference_list.append(prop_reference) # check for at least one property if not prop_reference_list: raise ValueError("provide at least one property") # build a read access specification read_access_spec = ReadAccessSpecification( objectIdentifier=(obj_type, obj_inst), listOfPropertyReferences=prop_reference_list, ) # add it to the list read_access_spec_list.append(read_access_spec) # check for at least one if not read_access_spec_list: raise RuntimeError( "at least one read access specification required") # build the request request = ReadPropertyMultipleRequest( listOfReadAccessSpecs=read_access_spec_list, ) request.pduDestination = Address(addr) if _debug: logger.debug(" - request: %r", request) self._request = request # make an IOCB iocb = IOCB(request) if _debug: logger.debug(" - iocb: %r", iocb) # give it to the application self.request_io(iocb) # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n') except Exception as error: logger.debug("exception: %r", error)