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 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 do_whois(self, addr=None, lolimit=None, hilimit=None): """whois [ <addr>] [ <lolimit> <hilimit> ]""" try: # build a request request = WhoIsRequest() if (addr is None): request.pduDestination = GlobalBroadcast() else: request.pduDestination = Address(addr) if lolimit is not None: request.deviceInstanceRangeLowLimit = int(lolimit) if hilimit is not None: request.deviceInstanceRangeHighLimit = int(hilimit) if _debug: logger.debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: logger.debug(" - iocb: %r", iocb) # give it to the application self.request_io(iocb) except Exception as err: logger.debug("exception: %r", err)
def do_whois(self, args): """whois [ <addr>] [ <lolimit> <hilimit> ]""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_whois %r", args) 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]) if _debug: WhoIsIAmConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: WhoIsIAmConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) except Exception as err: WhoIsIAmConsoleCmd._exception("exception: %r", err)
def next_request(self): if _debug: ReadPropertyApplication._debug("next_request") global device_address, object_identifier, property_list # check to see if we're done if not property_list: if _debug: ReadPropertyApplication._debug(" - done") stop() return # get the next request self.property_identifier = property_list.popleft() if _debug: ReadPropertyApplication._debug(" - property_identifier: %r", self.property_identifier) # build a request request = ReadPropertyRequest( destination=device_address, objectIdentifier=object_identifier, propertyIdentifier=self.property_identifier, ) if _debug: ReadPropertyApplication._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) # set a callback for the response iocb.add_callback(self.complete_request) if _debug: ReadPropertyApplication._debug(" - iocb: %r", iocb) # send the request this_application.request_io(iocb)
def write_text_value(self, request, timeout=10): try: iocb = IOCB(request) iocb.set_timeout(timeout) # pass to the BACnet stack deferred(self.this_application.request_io, iocb) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if not isinstance(apdu, SimpleAckPDU): # expect an ACK self._log.error("Not an ack, see debug for more infos.") return if iocb.ioError: # unsuccessful: error/reject/abort apdu = iocb.ioError reason = find_reason(apdu) raise NoResponseFromController( "APDU Abort Reason : {}".format(reason)) except WritePropertyException as error: # construction error self._log.error(("exception: {!r}".format(error)))
def read_object_list(self, device_id, device_addr): if _debug: ReadAllObjectPropertiesApplication._debug("read_object_list %r %r", device_id, device_addr) # create a context to hold the results context = ObjectPropertyContext(device_id, device_addr) # build a request for the object name request = ReadPropertyRequest( destination=context.device_addr, objectIdentifier=context.device_id, propertyIdentifier='objectList', ) if _debug: ReadAllObjectPropertiesApplication._debug(" - request: %r", request) # make an IOCB, reference the context iocb = IOCB(request) iocb.context = context if _debug: ReadAllObjectPropertiesApplication._debug(" - iocb: %r", iocb) # let us know when its complete iocb.add_callback(self.object_list_results) # give it to the application self.request_io(iocb)
def iam(self, destination=None): """ Build an IAm response. IAm are sent in response to a WhoIs request that; matches our device ID, whose device range includes us, or is a broadcast. Content is defined by the script (deviceId, vendor, etc...) :returns: bool Example:: iam() """ self._log.debug("do_iam") try: # build a response request = self._iam_request(destination=destination) iocb = IOCB(request) # make an IOCB deferred(self.this_application.request_io, iocb) iocb.wait() return True except Exception as error: self._log.error("exception: {!r}".format(error)) return False
def _get_device_info(self): request = ReadPropertyRequest(destination=self.source, objectIdentifier=self.id, propertyIdentifier='objectName') iocb = IOCB(request) iocb.add_callback(self._got_object_name) self.bacnet_adapter.request_io(iocb)
def what_is_network_number(self, args=""): """ winn [ <addr> ] Send a What-Is-Network-Number message. If the address is unspecified the message is locally broadcast. """ args = args.split() # build a request try: request = WhatIsNetworkNumber() if len(args) > 0: request.pduDestination = Address(args[0]) else: request.pduDestination = LocalBroadcast() except: self._log.error( "Cannot build request (invalid arguments) : {}".format(args)) return iocb = IOCB((self.this_application.nsap.local_adapter, request)) # make an IOCB iocb.set_timeout(2) deferred(self.this_application.nse.request_io, iocb) iocb.wait()
def whois_router_to_network(self, args=None): # build a request try: request = WhoIsRouterToNetwork() if not args: request.pduDestination = LocalBroadcast() elif args[0].isdigit(): request.pduDestination = LocalBroadcast() request.wirtnNetwork = int(args[0]) else: request.pduDestination = Address(args[0]) if len(args) > 1: request.wirtnNetwork = int(args[1]) except: self._log.error("WhoIsRouterToNetwork : invalid arguments") return iocb = IOCB((self.this_application.nsap.local_adapter, request)) # make an IOCB iocb.set_timeout(2) deferred(self.this_application.nse.request_io, iocb) iocb.wait() try: self.init_routing_table(str( self.this_application.nse._iartn.pop())) except IndexError: pass
def read_next_object(self, context): if _debug: ReadObjectListApplication._debug("read_next_object %r", context) # if there's nothing more to do, we're done if not context._object_list_queue: if _debug: ReadObjectListApplication._debug(" - all done") context.completed() return # pop off the next object identifier object_id = context._object_list_queue.popleft() if _debug: ReadObjectListApplication._debug(" - object_id: %r", object_id) # build a request for the object name request = ReadPropertyRequest( destination=context.device_addr, objectIdentifier=object_id, propertyIdentifier='objectName', ) if _debug: ReadObjectListApplication._debug(" - request: %r", request) # make an IOCB, reference the context iocb = IOCB(request) iocb.context = context if _debug: ReadObjectListApplication._debug(" - iocb: %r", iocb) # let us know when its complete iocb.add_callback(self.object_name_results) # give it to the application self.request_io(iocb)
def __init__(self, *args): BIPSimpleApplication.__init__(Mock()) self.elementService = Mock() #self.ResponseQueue = Mock() #self.ResponseQueue.get.return_value = ([21, 'degreesCelcius'], Event()) iocb = IOCB() apdu = ReadPropertyMultipleACK(listOfReadAccessResults=[ ReadAccessResult( objectIdentifier=('analogValue', 1), listOfResults=[ ReadAccessResultElement( propertyIdentifier='presentValue', readResult=ReadAccessResultElementChoice( propertyValue=Any(Real(21.0)), )), ReadAccessResultElement( propertyIdentifier='units', readResult=ReadAccessResultElementChoice( propertyValue=Any(Enumerated(62)), )), ], ) ]) iocb.complete(apdu) self.request = Mock() self.request.return_value = iocb
def _get_prop_for_obj(self, obj_id): request = ReadPropertyRequest(destination=self.device.source, objectIdentifier=obj_id, propertyIdentifier='propertyList') iocb = IOCB(request) iocb.add_callback(self._got_properties_for_object, obj_id) self.bacnet_adapter.request_io(iocb)
def send_subscription(self, addr, proc_id, objid, confirmed=None, lifetime=None): if _debug: logger.debug("send_subscription") # build a request request = SubscribeCOVRequest( subscriberProcessIdentifier=proc_id, monitoredObjectIdentifier=objid, ) request.pduDestination = Address(addr) # optional parameters if confirmed is not None: request.issueConfirmedNotifications = confirmed if lifetime is not None: request.lifetime = lifetime self._request = request # make an IOCB iocb = IOCB(request) if _debug: logger.debug(" - iocb: %r", iocb) # callback when it is acknowledged #iocb.add_callback(self.subscription_acknowledged) # 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 addr, obj_type, obj_inst, prop_id = self.point_queue.popleft() # build a request request = ReadPropertyRequest( objectIdentifier=(obj_type, obj_inst), 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 read_prop_vendor(self): #get bacnet source pdu from point_list array. point_list has been override by next_request method addr = point_list[0][0] obj_type = self.obj obj_inst = self.inst prop_id = self.prop # build a request request = ReadPropertyRequest( objectIdentifier=(obj_type, obj_inst), propertyIdentifier=int(prop_id), ) request.pduDestination = Address(addr) request.propertyArrayIndex = self.idx #if _debug: ReadPropertyAnyConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) #if _debug: ReadPropertyAnyConsoleCmd._debug(" - iocb: %r", iocb) # set a callback for the response iocb.add_callback(self.prop_vendor_ack) # give it to the application this_application.request_io(iocb)
def next_request(self): # check to see if we're done if not self.point_queue: stop() return # get the next request point_id, addr, obj_type, obj_inst, prop_id, idx = self.point_queue.popleft() # build a request request = ReadPropertyRequest( objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id, propertyArrayIndex=idx ) request.pduDestination = Address(addr) # make an IOCB iocb = IOCB(request) # set a callback for the response iocb.add_callback(self.complete_request) # send the request self.request_io(iocb)
def whois_router_to_network(self, network=None, *, destination=None): # build a request try: request = WhoIsRouterToNetwork() if network: request.wirtnNetwork = int(network) if destination: request.pduDestination = Address(destination) self._log.debug("WhoIsRouterToNetwork Destination : {}".format( destination)) else: request.pduDestination = LocalBroadcast() except: self._log.error("WhoIsRouterToNetwork : invalid arguments") return iocb = IOCB((self.this_application.nsap.local_adapter, request)) # make an IOCB iocb.set_timeout(2) deferred(self.this_application.nse.request_io, iocb) iocb.wait() try: self.init_routing_table(str( self.this_application.nse._iartn.pop())) except IndexError: pass
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 send(self, apdu): if _debug: ApplicationStateMachine._debug("send(%s) %r", self.name, apdu) # build an IOCB to wrap the request iocb = IOCB(apdu) self.request_io(iocb)
def _get_value_for_prop(self, prop): request = ReadPropertyRequest(destination=self.device.source, objectIdentifier=self.object, propertyIdentifier=prop) iocb = IOCB(request) iocb.add_callback(self._got_prop, prop) self.bacnet_adapter.request_io(iocb)
def do_iam(self, args): """ iam [ <addr> ] Send an I-Am request. If the address is unspecified the message is locally broadcast. """ args = args.split() if _debug: DiscoverConsoleCmd._debug("do_iam %r", args) try: # build a request request = IAmRequest() if (len(args) == 1): request.pduDestination = Address(args[0]) else: request.pduDestination = GlobalBroadcast() # set the parameters from the device object request.iAmDeviceIdentifier = this_device.objectIdentifier request.maxAPDULengthAccepted = this_device.maxApduLengthAccepted request.segmentationSupported = this_device.segmentationSupported request.vendorID = this_device.vendorIdentifier 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 this_application.request_io(iocb) except Exception as err: DiscoverConsoleCmd._exception("exception: %r", err)
def do_request(self): if _debug: ReadPointListApplication._debug('do_request') request = SubscribeCOVRequest(subscriberProcessIdentifier=1234, monitoredObjectIdentifier=('analogInput', 0), issueConfirmedNotifications=False, lifetime=100) request.pduDestination = Address('192.168.2.70') 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) iocb.wait() # do something for success if iocb.ioResponse: if _debug: ReadPointListApplication._debug(" - response: %r", iocb.ioResponse) # do something for error/reject/abort if iocb.ioError: if _debug: ReadPointListApplication._debug(" - error: %r", iocb.ioError)
def do_WhoIsRequest(self, apdu): """Respond to a Who-Is request.""" self._log.debug("do_WhoIsRequest {!r}".format(apdu)) # build a key from the source and parameters key = ( str(apdu.pduSource), apdu.deviceInstanceRangeLowLimit, apdu.deviceInstanceRangeHighLimit, ) low_limit = key[1] high_limit = key[2] # count the times this has been received self.who_is_counter[key] += 1 if low_limit is not None: if self.localDevice.objectIdentifier[1] < low_limit: return if high_limit is not None: if self.localDevice.objectIdentifier[1] > high_limit: return # generate an I-Am self._log.debug("Responding to Who is by a Iam") self.iam_req.pduDestination = apdu.pduSource iocb = IOCB(self.iam_req) # make an IOCB deferred(self.request_io, iocb)
def _get_new_sensors_for_new_device(self, source, device_id): request = ReadPropertyRequest(destination=source, objectIdentifier=device_id, propertyIdentifier="objectList") iocb = IOCB(request) iocb.add_callback(self._got_sensors_for_device) self.bacnet_adapter.request_io(iocb)
def _discovery(self): global device_address # build a request obj_type, prop_id = ('device', 'objectList') # build a request request = ReadPropertyRequest( objectIdentifier=(obj_type, self._device_id), propertyIdentifier=prop_id, ) request.pduSource = Address(this_device._address) request.pduDestination = Address(int(self._addr)) request.propertyArrayIndex = self._instance_list.pop(0) if _debug: BacnetClientConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) # set a callback for the response iocb.add_callback(self._discovery_response) if _debug: BacnetClientConsoleCmd._debug(" - iocb: %r", iocb) # send the request this_application.request_io(iocb)
def do_whois(self, args): if _debug: ThreadedHTTPRequestHandler._debug("do_whois %r", args) 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]) if _debug: ThreadedHTTPRequestHandler._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ThreadedHTTPRequestHandler._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) # no result -- it would be nice if these were the matching I-Am's result = {} except Exception as err: ThreadedHTTPRequestHandler._exception("exception: %r", err) result = { "exception": str(err) } # write the result json.dump(result, self.wfile)
def do_iam(self, args): """iam""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_iam %r", args) try: # build a request request = IAmRequest() request.pduDestination = GlobalBroadcast() # set the parameters from the device object request.iAmDeviceIdentifier = this_device.objectIdentifier request.maxAPDULengthAccepted = this_device.maxApduLengthAccepted request.segmentationSupported = this_device.segmentationSupported request.vendorID = this_device.vendorIdentifier if _debug: WhoIsIAmConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: WhoIsIAmConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) except Exception as err: WhoIsIAmConsoleCmd._exception("exception: %r", err)
def send_subscription(self, context): if _debug: SubscribeCOVApplication._debug("send_subscription %r", context) # build a request request = SubscribeCOVRequest( subscriberProcessIdentifier=context.subscriberProcessIdentifier, monitoredObjectIdentifier=context.monitoredObjectIdentifier, ) request.pduDestination = context.address # optional parameters if context.issueConfirmedNotifications is not None: request.issueConfirmedNotifications = context.issueConfirmedNotifications if context.lifetime is not None: request.lifetime = context.lifetime # make an IOCB iocb = IOCB(request) if _debug: SubscribeCOVApplication._debug(" - iocb: %r", iocb) # callback when it is acknowledged iocb.add_callback(self.subscription_acknowledged) # give it to the application this_application.request_io(iocb)