def test_remote_broadcast_routed(self): if _debug: TestRemoteBroadcast._debug("test_remote_broadcast_routed") if not settings.route_aware: if _debug: TestRemoteBroadcast._debug(" - not route aware") return # match test_addr = RemoteBroadcast(1, route=Address("1.2.3.4")) self.match_address(test_addr, 3, 1, None, None) assert str(test_addr) == "1:*@1.2.3.4"
def test_remote_station_bytes_routed(self): if _debug: TestRemoteStation._debug("test_remote_station_bytes_routed") if not settings.route_aware: if _debug: TestRemoteStation._debug(" - not route aware") return # multi-byte strings are hex encoded test_addr = RemoteStation(1, xtob('0102'), route=Address("1.2.3.4")) self.match_address(test_addr, 4, 1, 2, '0102') assert str(test_addr) == "1:[email protected]" test_addr = RemoteStation(1, xtob('010203'), route=Address("1.2.3.4")) self.match_address(test_addr, 4, 1, 3, '010203') assert str(test_addr) == "1:[email protected]" # match with an IPv4 address test_addr = RemoteStation(1, xtob('01020304bac0'), route=Address("1.2.3.4")) self.match_address(test_addr, 4, 1, 6, '01020304bac0') assert str(test_addr) == "1:[email protected]"
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 create_sensor(self, _id: int) -> Sensor: if self.get_sensor(_id): raise ValueError(f"Sensor {_id} already exists on network") sensor = Sensor(_id, Address(self._address_index.to_bytes(4, "big"))) self._sensors[_id] = sensor self.add_node(sensor.get_node()) self._address_index += 1 return sensor
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_rtn(self, args): """rtn <addr> <net> ... """ args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_rtn %r", args) # provide the address and a list of network numbers router_address = Address(args[0]) network_list = [int(arg) for arg in args[1:]] # pass along to the service access point this_application.nsap.update_router_references(None, router_address, network_list)
def main(): global this_application, device_address, object_identifier, property_list # parse the command line arguments parser = ConfigArgumentParser(description=__doc__) parser.add_argument( "address", help="device address", ) parser.add_argument( "objtype", help="object types, e.g., analogInput", ) parser.add_argument( "objinstance", type=int, help="object instance", ) args = parser.parse_args() if _debug: _log.debug("initialization") if _debug: _log.debug(" - args: %r", args) # interpret the address device_address = Address(args.address) if _debug: _log.debug(" - device_address: %r", device_address) # build an identifier object_identifier = (args.objtype, args.objinstance) if _debug: _log.debug(" - object_identifier: %r", object_identifier) # get the object class object_class = get_object_class(args.objtype) if _debug: _log.debug(" - object_class: %r", object_class) # make a queue of the properties property_list = deque(prop.identifier for prop in object_class.properties) if _debug: _log.debug(" - property_list: %r", property_list) # 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 = ReadPropertyApplication(this_device, args.ini.address) # fire off a request when the core has a chance deferred(this_application.next_request) _log.debug("running") run() _log.debug("fini")
def __init__(self, device_address, point_list): if _debug: ReadPointListThread._debug("__init__ %r %r", device_address, point_list) Thread.__init__(self) # save the address self.device_address = Address(device_address) # turn the point list into a queue self.point_list = point_list # make a list of the response values self.response_values = []
def dcc(self, address=None, duration=None, password=None, state=None): """ Will send DeviceCommunicationControl request """ if not self._started: raise ApplicationNotStarted( "BACnet stack not running - use startApp()") if not address: raise ValueError("Provide address for request") if not state: raise ValueError( "Provide state ('enable', 'disable', 'disableInitiation'") # build a request request = DeviceCommunicationControlRequest() request.enableDisable = DeviceCommunicationControlRequestEnableDisable.enumerations[ state] request.pduDestination = Address(address) if duration: request.duration = Unsigned16(duration) request.password = CharacterString(password) self._log.debug("{:>12} {}".format("- request:", request)) iocb = IOCB(request) # make an IOCB # pass to the BACnet stack deferred(self.this_application.request_io, iocb) # Unconfirmed request...so wait until complete iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if not isinstance(apdu, SimpleAckPDU): # expect an ACK self._log.warning("Not an ack, see debug for more infos.") self._log.debug("Not an ack. | APDU : {} / {}".format( (apdu, type(apdu)))) return if iocb.ioError: # unsuccessful: error/reject/abort apdu = iocb.ioError reason = find_reason(apdu) raise NoResponseFromController( "APDU Abort Reason : {}".format(reason)) self._log.info( "DeviceCommunicationControl request sent to device : {}".format( address))
def test_remote_station_ints_routed(self): if _debug: TestRemoteStation._debug("test_remote_station_ints_routed") if not settings.route_aware: if _debug: TestRemoteStation._debug(" - not route aware") return # test integer test_addr = RemoteStation(1, 1, route=Address("1.2.3.4")) self.match_address(test_addr, 4, 1, 1, '01') assert str(test_addr) == "1:[email protected]" test_addr = RemoteStation(1, 254, route=Address("1.2.3.4")) self.match_address(test_addr, 4, 1, 1, 'fe') assert str(test_addr) == "1:[email protected]" # test station address with self.assertRaises(ValueError): RemoteStation(1, -1) with self.assertRaises(ValueError): RemoteStation(1, 256)
def test_delete_fail(self): """Test deleting an FDT entry from a non-BBMD.""" if _debug: TestNonBBMD._debug("test_delete_fail") # read the broadcast distribution table, get a nack self.td.start_state.doc("1-5-0") \ .send(DeleteForeignDeviceTableEntry(Address("1.2.3.4"), destination=self.iut.address)).doc("1-5-1") \ .receive(Result, bvlciResultCode=0x0050).doc("1-5-2") \ .success() # run the group self.tnet.run()
def main(): global this_device, this_application, this_console # 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( objectName=args.ini.objectname, objectIdentifier=int(args.ini.objectidentifier), maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted), segmentationSupported=args.ini.segmentationsupported, vendorIdentifier=int(args.ini.vendoridentifier), ) if _debug: _log.debug(" - this_device: %r", this_device) # build a bit string that knows about the bit names pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['writeProperty'] = 1 # set the property value to be just the bits this_device.protocolServicesSupported = pss.value # make a simple application this_application = WhoIsIAmApplication( this_device, args.ini.address, Address(args.ini.foreignbbmd), int(args.ini.foreignttl), ) if _debug: _log.debug(" - this_application: %r", this_application) # get the services supported services_supported = this_application.get_services_supported() if _debug: _log.debug(" - services_supported: %r", services_supported) # let the device object know this_device.protocolServicesSupported = services_supported.value # make a console this_console = WhoIsIAmConsoleCmd() if _debug: _log.debug(" - this_console: %r", this_console) _log.debug("running") run() _log.debug("finally")
def bind(self, vlan, address, net): if _debug: VLANRouter._debug("bind %r %r %r", vlan, address, net) # create a VLAN node for the router with the given address vlan_node = Node(Address(address)) # add it to the VLAN vlan.add_node(vlan_node) # bind the router stack to the vlan network through this node self.nsap.bind(vlan_node, net) if _debug: _log.debug(" - bound to vlan")
def add_network(self, address, vlan, net): if _debug: RouterNode._debug("add_network %r %r %r", address, vlan, net) # convert the address to an Address address = Address(address) # create a node, added to the network node = Node(address, vlan) if _debug: RouterNode._debug(" - node: %r", node) # bind the BIP stack to the local network self.nsap.bind(node, net)
def __init__(self, localDevice, localAddress, deviceInfoCache=None, aseID=None): if _debug: MSTPSimpleApplication._debug( "__init__ %r %r deviceInfoCache=%r aseID=%r", localDevice, localAddress, deviceInfoCache, aseID) ApplicationIOController.__init__(self, localDevice, deviceInfoCache, aseID=aseID) # local address might be useful for subclasses if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) self.localDevice = localDevice # include a application decoder self.asap = ApplicationServiceAccessPoint() # pass the device object to the state machine access point so it # can know if it should support segmentation self.smap = StateMachineAccessPoint(localDevice) # the segmentation state machines need access to the same device # information cache as the application self.smap.deviceInfoCache = self.deviceInfoCache # a network service access point will be needed self.nsap = NetworkServiceAccessPoint() # give the NSAP a generic network layer service element self.nse = NetworkServiceElement() bind(self.nse, self.nsap) # bind the top layers bind(self, self.asap, self.smap, self.nsap) # create a generic MSTP stack, bound to the Annex J server # on the MSTP multiplexer self.mstp = MSTPSimple() self.mux = MSTPMultiplexer(self.localDevice, self.localAddress) # bind the bottom layers bind(self.mstp, self.mux.annexH) # bind the MSTP stack to the network, no network number self.nsap.bind(self.mstp)
def address(self): """ IP Address using bacpypes Address format """ port = "" if self._port: port = ":{}".format(self._port) return Address("{}/{}{}".format( self.interface.ip.compressed, self.interface.exploded.split("/")[-1], port, ))
def __init__(self, objectName, deviceInstance, address, aseID=None): if _debug: VLANApplication._debug("__init__ %r %r %r aseID=%r", objectName, deviceInstance, address, aseID) # make an address vlan_address = Address(address) _log.debug(" - vlan_address: %r", vlan_address) # make a device object vlan_device = LocalDeviceObject( objectName=objectName, objectIdentifier=("device", deviceInstance), maxApduLengthAccepted=1024, segmentationSupported="noSegmentation", vendorIdentifier=15, ) _log.debug(" - vlan_device: %r", vlan_device) # continue with the initialization Application.__init__(self, vlan_device, vlan_address, aseID) # include a application decoder self.asap = ApplicationServiceAccessPoint() # pass the device object to the state machine access point so it # can know if it should support segmentation self.smap = StateMachineAccessPoint(vlan_device) # the segmentation state machines need access to the same device # information cache as the application self.smap.deviceInfoCache = self.deviceInfoCache # a network service access point will be needed self.nsap = NetworkServiceAccessPoint() # give the NSAP a generic network layer service element self.nse = NetworkServiceElement() bind(self.nse, self.nsap) # bind the top layers bind(self, self.asap, self.smap, self.nsap) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) if _debug: VLANApplication._debug(" - vlan_node: %r", self.vlan_node) # bind the stack to the node, no network number self.nsap.bind(self.vlan_node) if _debug: VLANApplication._debug(" - node bound")
def send_request( target_args, app ): # build a request request = ReadPropertyRequest( objectIdentifier=( target_args['type'], target_args['instance'] ), propertyIdentifier=target_args['property'] ) request.pduDestination = Address( target_args['address'] ) # make an IOCB iocb = IOCB( request ) # give it to the application app.request_io( iocb ) # wait for it to complete iocb.wait() # Handle completion: error, success, neither if iocb.ioError: # Error success = False message = str( iocb.ioError ) result = '' elif iocb.ioResponse: # Success success = True message = '' # Get the response PDU apdu = iocb.ioResponse # Extract the returned value datatype = get_datatype( apdu.objectIdentifier[0], apdu.propertyIdentifier ) if issubclass( datatype, Array ) and (apdu.propertyArrayIndex is not None): if apdu.propertyArrayIndex == 0: result = apdu.propertyValue.cast_out( Unsigned ) else: result = apdu.propertyValue.cast_out( datatype.subtype ) else: result = apdu.propertyValue.cast_out( datatype ) else: # Neither success = False message = 'Request terminated unexpectedly' result = '' rsp = { target_args['property']: result } return success, message, rsp
def do_read(self, args): """read <addr> <type> <inst> <prop> [ <indx> ]""" global this_application args = args.split() if _debug: ReadWritePropertyConsoleCmd._debug("do_read %r", args) try: addr, obj_type, obj_inst, prop_id = args[:4] if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type, VendorAVObject.vendor_id): raise ValueError, "unknown object type" if _debug: ReadWritePropertyConsoleCmd._debug(" - obj_type: %r", obj_type) obj_inst = int(obj_inst) if _debug: ReadWritePropertyConsoleCmd._debug(" - obj_inst: %r", obj_inst) if prop_id.isdigit(): prop_id = int(prop_id) if _debug: ReadWritePropertyConsoleCmd._debug(" - prop_id: %r", prop_id) datatype = get_datatype(obj_type, prop_id, VendorAVObject.vendor_id) if not datatype: raise ValueError, "invalid property for object type" # build a request request = ReadPropertyRequest( objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if len(args) == 5: request.propertyArrayIndex = int(args[4]) if _debug: ReadWritePropertyConsoleCmd._debug(" - request: %r", request) # give it to the application this_application.request(request) except Exception, e: ReadWritePropertyConsoleCmd._exception("exception: %r", e)
def write_property(self, target_address, value, object_type, instance_number, property_name, priority=None, index=None): """Write to a property.""" # target_address = IP or network address of device # setvalue = the value you want to set to # object_type = protocol related object type: eg: Analog Input (AI), Analog Output etc # instance_number = the interger id of the property you want to change (brightness, state etc) # property = always set to "presentValue" # priority = the priority of your settings. Higher priority settings takes over request = WritePropertyRequest( objectIdentifier=(object_type, instance_number), propertyIdentifier=property_name) datatype = get_datatype(object_type, property_name) bac_value = Null() if issubclass(datatype, Atomic): if datatype is Integer: value = int(value) elif datatype is Real: value = float(value) elif datatype is Unsigned: value = int(value) bac_value = datatype(value) elif issubclass(datatype, Array) and (index is not None): if index == 0: bac_value = Integer(value) elif issubclass(datatype.subtype, Atomic): bac_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__,)) request.propertyValue = Any() request.propertyValue.cast_in(bac_value) request.pduDestination = Address(target_address) #Optional index if index is not None: request.propertyArrayIndex = index #Optional priority if priority is not None: request.priority = priority iocb = IOCB(request, self.async_call) self.this_application.submit_request(iocb) result = iocb.ioResult.wait() if isinstance(result, SimpleAckPDU): return value raise RuntimeError("Failed to set value: " + str(result))
def whois(self, *args): """ Build a WhoIs request :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois() # WhoIs broadcast globally. Every device will respond with an IAm whois('2:5') # WhoIs looking for the device at (Network 2, Address 5) whois('10 1000') # WhoIs looking for devices in the ID range (10 - 1000) """ if not self._started: raise ApplicationNotStarted( "BACnet stack not running - use startApp()") if args: args = args[0].split() msg = args if args else "any" self._log.debug("do_whois {!r}".format(msg)) # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) self._log.debug("{:>12} {}".format("- request:", request)) iocb = IOCB(request) # make an IOCB # pass to the BACnet stack self.this_application.request_io(iocb) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if iocb.ioError: # unsuccessful: error/reject/abort pass self.discoveredDevices = self.this_application.i_am_counter return self.discoveredDevices
def write_property(self, target_address, value, object_type, instance_number, property_name, priority=None, index=None): """ Write to a property. """ _log.debug(write_debug_str.format(target=target_address, type=object_type, instance=instance_number, property=property_name, priority=priority, index=index, value=value)) request = WritePropertyRequest(objectIdentifier=(object_type, instance_number), propertyIdentifier=property_name) datatype = get_datatype(object_type, property_name) bac_value = None if value is None or value == 'null': bac_value = Null() elif issubclass(datatype, Atomic): bac_value = self._cast_value(value, datatype) elif issubclass(datatype, Array) and (index is not None): if index == 0: bac_value = Integer(value) elif issubclass(datatype.subtype, Atomic): bac_value = datatype.subtype(value) elif not isinstance(value, datatype.subtype): raise TypeError("invalid result datatype, expecting {}".format(datatype.subtype.__name__,)) elif not isinstance(value, datatype): raise TypeError("invalid result datatype, expecting %s".format(datatype.__name__,)) request.propertyValue = Any() request.propertyValue.cast_in(bac_value) request.pduDestination = Address(target_address) # Optional index if index is not None: request.propertyArrayIndex = index # Optional priority if priority is not None: request.priority = priority iocb = self.iocb_class(request) self.bacnet_application.submit_request(iocb) result = iocb.ioResult.get(10) if isinstance(result, SimpleAckPDU): return value raise RuntimeError("Failed to set value: " + str(result))
def run(self): if _debug: ReadPointListThread._debug("run") global this_application # loop through the points for addr, obj_id, prop_id in self.point_queue: # build a request request = ReadPropertyRequest( objectIdentifier=ObjectIdentifier(obj_id).value, propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) 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) # done stop()
def test_init_router(self, mocker: MockFixture) -> None: mocker.patch("bacprop.bacnet.network._VLANRouter") network = VirtualSensorNetwork("0.0.0.0") router_node = network.nodes[0] # The router node on the network should be address 1 assert router_node.address == Address((1).to_bytes(4, "big")) # pylint: disable=no-member network._router.bind.assert_called_once_with(router_node, 1) # type: ignore network._router.start.assert_called_once() # type: ignore
def make_weeklySchedule_request(self, destination, object_instance, weeklySchedule): request = WritePropertyRequest( objectIdentifier=("schedule", object_instance), propertyIdentifier="weeklySchedule", ) address = Address(destination) request.pduDestination = address request.propertyValue = Any() request.propertyValue.cast_in(weeklySchedule) request.priority = 15 return request
def on_message(self, client, userdata, msg): """Callback for when a PUBLISH message is received from the server. """ if _debug: MQTTSniffer._debug("on_message ...") if _debug: MQTTSniffer._debug(" - msg.topic: %r", msg.topic) if _debug: MQTTSniffer._debug(" - payload: %r", btox(msg.payload)) topic_address = Address(xtob(msg.topic.split('/')[-1])) if _debug: MQTTSniffer._debug(" - topic_address: %r", topic_address) packet_data = decode_packet(msg.payload, topic_address) print(packet_data) packet_data.debug_contents(file=sys.stdout)
def write_property(self,target_address, value, object_type, instance_number, property_name, priority=None, index=None): """Write to a property.""" request = WritePropertyRequest( objectIdentifier=(object_type, instance_number), propertyIdentifier=property_name) datatype = get_datatype(object_type, property_name) if (value is None or value == 'null'): bac_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) bac_value = datatype(value) elif issubclass(datatype, Array) and (index is not None): if index == 0: bac_value = Integer(value) elif issubclass(datatype.subtype, Atomic): bac_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__,)) request.propertyValue = Any() request.propertyValue.cast_in(bac_value) request.pduDestination = Address(target_address) # Optional index if index is not None: request.propertyArrayIndex = index # Optional priority if priority is not None: request.priority = priority iocb = IOCB(request, AsyncCall()) self.this_application.submit_request(iocb) result = iocb.ioResult.wait() if isinstance(result, SimpleAckPDU): return value raise RuntimeError("Failed to set value: " + str(result)) #k= write_property("2001:127", 1, "binaryOutput", 1, "presentValue", priority=None, index=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)) # process point map and populate object_property_map and # reverse_point_map (object_property_map, reverse_point_map) = self._get_object_properties(point_map, target_address) result_dict = {} finished = False while not finished: read_access_spec_list = [] count = 0 for _ in range(max_per_request): try: obj_data, properties = object_property_map.popitem() except KeyError: finished = True break (spec_list, spec_count) = self._get_access_spec(obj_data, properties) count += spec_count read_access_spec_list.append(spec_list) 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.bacnet_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.items(): name = reverse_point_map[prop_tuple] result_dict[name] = value return result_dict
def read(device, portObject): request_addr = device.getRequestAddress() obj_type = portObject.getType() port = portObject.getPortNum() prop_id = portObject.getProp() maximumWait = 6 #seconds try: #Jordan Trying to open thread in application #applicationThread = BACpypeThread('BACPYPE-APP') #applicationThread.start() #--------------------------read property request #verify datatype # print "Reading..." print request_addr, obj_type, port, prop_id if obj_type.isdigit(): obj_type = int(obj_type) elif not get_object_class(obj_type): raise ValueError, "unknown object type" datatype = get_datatype(obj_type, prop_id) if not datatype: print ValueError, ": invalid property for object type" port = int(port) #build request request = ReadPropertyRequest( objectIdentifier=(obj_type, port), propertyIdentifier=prop_id, ) request.pduDestination = Address(request_addr) time.sleep(.01) #I dont know why, but this makes the code work correctly. #submit request this_application.request(request) # print "Waiting for reply..." #wait for request wait = 0 while this_application._Application__response_value == None and wait <= maximumWait: wait = wait + .01 time.sleep(.01) returnVal = this_application._Application__response_value except Exception, e: returnVal = None print 'An error has happened (CPLRW 126): ' + str(e) + "\n"
def whois(self, *args): """ Creation of a whois requests Requets is given to the app :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois() #will create a broadcast whois request and every device will response by a Iam whois('2:5') #will create a whois request aimed at device 5 whois('10 1000') #will create a whois request looking for device ID 10 to 1000 """ if args: args = args[0].split() if not args: msg = "any" else: msg = args log_debug("do_whois %r" % msg) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) log_debug(" - request: %r" % request) # give it to the application self.this_application.request(request) except Exception as error: log_exception("exception: %r" % error) self.discoveredDevices = self.this_application.i_am_counter return self.discoveredDevices