def net_obj_id(self, obj, inst, prop, idx): self.obj = obj self.inst = inst self.prop = prop self.idx = idx deferred(self.read_prop_vendor)
def main(): global this_application # 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(ini=args.ini) if _debug: _log.debug(" - this_device: %r", this_device) # make a simple application this_application = BIPSimpleApplication(this_device, args.ini.address) # create a thread and read_thread = ReadPointListThread(point_list) if _debug: _log.debug(" - read_thread: %r", read_thread) # start it running when the core is running deferred(read_thread.start) _log.debug("running") run() # dump out the results for request, response in zip(point_list, read_thread.response_values): print(request, response) _log.debug("fini")
def prop_vendor_ack(self, iocb): # do something for success if iocb.ioResponse: apdu = iocb.ioResponse # decode results from bacnet_settings's read property self.response_bacset = net.dcode(apdu) # get actual proxy IP from Device actual_IP = self.response_bacset[1] # Check public IP public_IP = self.get_public_ip() print public_IP # check if IPs are real IPV4 # If both IPs are different, do a write property to the correct object if self.validate_ip(actual_IP) and self.validate_ip(public_IP): if actual_IP != public_IP: self.proxyIP = public_IP deferred(self.write_bac_set) print actual_IP, public_IP else: print "IPs are the same" stop() else: print "IPs are not valid" stop() #deferred(self.write_bac_set) # do something for error/reject/abort if iocb.ioError: sys.stdout.write(str(iocb.ioError) + '\n')
def complete_request(self, iocb): if _debug: ReadPropertyApplication._debug("complete_request %r", iocb) if iocb.ioResponse: apdu = iocb.ioResponse # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], self.property_identifier) if _debug: ReadPropertyApplication._debug(" - datatype: %r", datatype) if not datatype: raise TypeError("unknown datatype") # special case for array parts, others are managed by cast_out value = apdu.propertyValue.cast_out(datatype) if _debug: ReadPropertyApplication._debug(" - value: %r", value) sys.stdout.write(self.property_identifier + " = " + str(value) + '\n') if hasattr(value, 'debug_contents'): value.debug_contents(stream=sys.stdout) sys.stdout.flush() if iocb.ioError: if _debug: ReadPropertyApplication._debug(" - error: %r", iocb.ioError) # if it is an unknown property, just skip to the next one if getattr(iocb.ioError, 'errorCode', '') != 'unknownProperty': sys.stdout.write(self.property_identifier + "! " + str(iocb.ioError) + '\n') sys.stdout.flush() # fire off another request deferred(self.next_request)
def object_name_results(self, iocb): if _debug: ReadObjectListApplication._debug("object_name_results %r", iocb) # extract the context context = iocb.context # do something for error/reject/abort if iocb.ioError: context.completed(iocb.ioError) return # do something for success apdu = iocb.ioResponse # should be an ack if not isinstance(apdu, ReadPropertyACK): if _debug: ReadObjectListApplication._debug(" - not an ack") context.completed(RuntimeError("read property ack expected")) return # pull out the name object_name = apdu.propertyValue.cast_out(CharacterString) if _debug: ReadObjectListApplication._debug(" - object_name: %r", object_name) # store it in the context context.object_names.append(object_name) # read the next one deferred(self.read_next_object, context)
def object_list_results(self, iocb): if _debug: ReadObjectListApplication._debug("object_list_results %r", iocb) # extract the context context = iocb.context # do something for error/reject/abort if iocb.ioError: context.completed(iocb.ioError) return # do something for success apdu = iocb.ioResponse # should be an ack if not isinstance(apdu, ReadPropertyACK): if _debug: ReadObjectListApplication._debug(" - not an ack") context.completed(RuntimeError("read property ack expected")) return # pull out the content object_list = apdu.propertyValue.cast_out(ArrayOfObjectIdentifier) if _debug: ReadObjectListApplication._debug(" - object_list: %r", object_list) # store it in the context context.object_list = object_list # make a queue of the identifiers to read, start reading them context._object_list_queue = deque(object_list) deferred(self.read_next_object, context)
def main(): global this_application # 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), ) # make a simple application this_application = ReadPointListApplication(point_list, this_device, args.ini.address) # fire off a request when the core has a chance deferred(this_application.next_request) _log.debug("running") run() # dump out the results for request, response in zip(point_list, this_application.response_values): print(request, response) _log.debug("fini")
def _trigger(self): """Called to launch the next request in the queue.""" if _debug: IOQController._debug("_trigger") # if we are busy, do nothing if self.state != CTRL_IDLE: if _debug: IOQController._debug(" - not idle") return # if there is nothing to do, return if not self.ioQueue.queue: if _debug: IOQController._debug(" - empty queue") return # get the next iocb iocb = self.ioQueue.get() try: # hopefully there won't be an error err = None # let derived class figure out how to process this self.process_io(iocb) except: # extract the error err = sys.exc_info()[1] # if there was an error, abort the request if err: self.abort_io(iocb, err) # if we're idle, call again if self.state == CTRL_IDLE: deferred(IOQController._trigger, self)
def indication(self, apdu): if _debug: WhoIsIAmApplication._debug("indication %r", apdu) if (isinstance(self._request, WhoIsRequest)) and (isinstance( apdu, IAmRequest)): device_type, device_instance = apdu.iAmDeviceIdentifier if device_type != 'device': raise DecodingError("invalid object type") if (self._request.deviceInstanceRangeLowLimit is not None) and \ (device_instance < self._request.deviceInstanceRangeLowLimit): pass elif (self._request.deviceInstanceRangeHighLimit is not None) and \ (device_instance > self._request.deviceInstanceRangeHighLimit): pass else: # Received I-am from target's Device instance dev_ObjID = apdu.iAmDeviceIdentifier dev_pdusource = apdu.pduSource point_list[0][0] = str(dev_pdusource) point_list[1][0] = str(dev_pdusource) point_list[0][2] = dev_ObjID[1] point_list[1][2] = dev_ObjID[1] #fire off request. read device properties model name and software version deferred(self.next_request) # forward it along BIPSimpleApplication.indication(self, apdu)
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 main(): # make a device object this_device = LocalDeviceObject(objectName=config.bacnet_device['object_name'], objectIdentifier=config.bacnet_device['object_identifier'], maxApduLengthAccepted=config.bacnet_device['max_apdu_length_accepted'], segmentationSupported=config.bacnet_device['segmentation_supported'], vendorIdentifier=config.bacnet_device['vendor_identifier'], ) # point list, set according to your device point_list = [ # point_id, addr, obj_type, obj_inst, prop_id, idx (1, '10.117.73.53', 'analogInput', 1, 'presentValue', None), (2, '10.117.73.53', 'analogInput', 2, 'presentValue', None), (3, '10.117.73.53', 'analogInput', 3, 'presentValue', None), (4, '10.117.73.53', 'analogInput', 4, 'presentValue', None), (5, '10.117.73.53', 'analogInput', 5, 'presentValue', None), (6, '10.117.73.53', 'analogInput', 6, 'presentValue', None), ] # make a simple application this_application = MyEMSApplication(point_list, this_device, config.bacnet_device['local_address'], Address(config.bacnet_device['foreignBBMD']), int(config.bacnet_device['foreignTTL'])) # fire off a request when the core has a chance deferred(this_application.next_request) run() # dump out the results for request, response in zip(point_list, this_application.response_values): print(request, response)
def main(): global this_application # 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(ini=args.ini) if _debug: _log.debug(" - this_device: %r", this_device) # make a simple application this_application = SubscribeCOVApplication(this_device, args.ini.address) # make a subscription context context = SubscriptionContext(Address("10.0.1.31"), ('analogValue', 1), False, 60) # send the subscription when the stack is ready deferred(this_application.send_subscription, context) _log.debug("running") run() _log.debug("fini")
def main(): global this_application # 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(ini=args.ini) if _debug: _log.debug(" - this_device: %r", this_device) # make a simple application this_application = ReadPointListApplication(point_list, this_device, args.ini.address) # fire off a request when the core has a chance deferred(this_application.next_request) _log.debug("running") run() # dump out the results for request, response in zip(point_list, this_application.response_values): print(request, response) _log.debug("fini")
def complete_request(self, iocb): if _debug: ReadPointListApplication._debug("complete_request %r", iocb) if iocb.ioResponse: apdu = iocb.ioResponse # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier) if _debug: ReadPointListApplication._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: ReadPointListApplication._debug(" - value: %r", value) # save the value self.response_values.append(value) if iocb.ioError: if _debug: ReadPointListApplication._debug(" - error: %r", iocb.ioError) self.response_values.append(iocb.ioError) # fire off another request deferred(self.next_request)
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 confirmation(self, apdu): if _debug: PrairieDog._debug("confirmation %r", apdu) if isinstance(apdu, Error): if _debug: PrairieDog._debug(" - error: %r", apdu) self.response_values.append(apdu) elif isinstance(apdu, AbortPDU): if _debug: PrairieDog._debug(" - abort: %r", apdu) self.response_values.append(apdu) elif (isinstance(self._request, ReadPropertyRequest)) and (isinstance(apdu, ReadPropertyACK)): # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier) if _debug: PrairieDog._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: PrairieDog._debug(" - value: %r", value) # save the value self.response_values.append(value) # fire off another request deferred(self.next_request)
def complete_request(self, iocb): if iocb.ioResponse: apdu = iocb.ioResponse # find the datatype datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier) 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) # save the value self.response_values.append(value) if iocb.ioError: self.response_values.append(iocb.ioError) # fire off another request deferred(self.next_request)
def main(): global vendor_id # 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(ini=args.ini) if _debug: _log.debug(" - this_device: %r", this_device) # make a sample application this_application = BIPSimpleApplication(this_device, args.ini.address) # create the objects and add them to the application create_objects(this_application) # run this update when the stack is ready deferred(update_weather_data) if _debug: _log.debug("running") run() if _debug: _log.debug("fini")
def property_change(self, old_value, new_value): if _debug: DetectionMonitor._debug("property_change %r %r", old_value, new_value) # set the parameter value setattr(self.algorithm, self.parameter, new_value) # if the algorithm is already triggered, don't bother checking for more if self.algorithm._triggered: if _debug: DetectionMonitor._debug(" - already triggered") return # if there is a special filter, use it, otherwise use != if self.filter: trigger = self.filter(old_value, new_value) else: trigger = (old_value != new_value) if _debug: DetectionMonitor._debug(" - trigger: %r", trigger) # trigger it if trigger: deferred(self.algorithm._execute) if _debug: DetectionMonitor._debug(" - deferred: %r", self.algorithm._execute) self.algorithm._triggered = True
def getData(collection): global this_application, device_address, object_identifier, property_list # 清空数组 global result, tag_list, tag_keys, count print collection result = [] tag_list = [] tag_keys = {} count = 0 parser = ConfigArgumentParser(description=__doc__) args = parser.parse_args() tag_list = collection["bacnet_items"] try: this_device = LocalDeviceObject(ini=args.ini) this_application = ReadPropertyApplication(this_device, args.ini.address) deferred(this_application.requests) run() this_application.close_socket() except Exception as e: print str(e) return {"data": "采集失败", "success": "false"} import datetime dt = datetime.datetime.now() timestamp = dt.strftime("%Y-%m-%d %H:%M:%S") for item in tag_keys: result.append({ "timestamp": timestamp, "value": None, "item": tag_keys[item]['tag'], "quality": "Error" }) return {"data": result, "success": "true"}
def complete_io(self, iocb, msg): """Called by a handler to return data to the client.""" if _debug: IOQController._debug("complete_io %r %r", iocb, msg) # check to see if it is completing the active one if iocb is not self.active_iocb: raise RuntimeError, "not the current iocb" # normal completion IOController.complete_io(self, iocb, msg) # no longer an active iocb self.active_iocb = None # check to see if we should wait a bit if self.wait_time: # change our state self.state = CTRL_WAITING # schedule a call in the future task = FunctionTask(IOQController._wait_trigger, self) task.install_task(_time() + self.wait_time) else: # change our state self.state = CTRL_IDLE # look for more to do deferred(IOQController._trigger, self)
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 handle_read(self): if _debug: MSTPDirector._debug("handle_read") try: msg, addr = self.socket.recvfrom(512) if _debug: MSTPDirector._debug(" - received %d octets ", len(msg)) pdu = PDU(msg,destination=int(str(self.address))) mstp_src = pdu.get() pdu.pduSource = Address(mstp_src) if _debug: MSTPDirector._debug("Received MSTP PDU={}".format(str(pdu))) # send the PDU up to the client deferred(self._response, pdu) except socket.timeout as err: if _debug: MSTPDirector._debug(" - socket timeout: %s", err) except socket.error as err: if err.args[0] == 11: pass else: if _debug: MSTPDirector._debug(" - socket error: %s", err) # pass along to a handler self.handle_error(err) except Exception as e: MSTPDirector._error('Exception in handle_read: {}'.format(e))
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 WriteValues(PointList): global this_application, this_ServerAdress # create a thread thread_list = [] print(PointList) # loop through the address and point lists #for points in PointList: # create a thread #print(points) read_thread = WritePointListThread(this_ServerAdress, PointList) if _debug: _log.debug(" - read_thread: %r", read_thread) thread_list.append(read_thread) # create a thread supervisor thread_supervisor = ReadWriteThreadSupervisor(thread_list) # start it running when the core is running deferred(thread_supervisor.start) _log.debug("running") run() # dump out the results for read_thread in thread_list: for request, response in zip(read_thread.point_list, read_thread.response_values): print(request, response)
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 whois(self, *args, global_broadcast=False): """ Build a WhoIs request :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois(global_broadcast=True) # 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: if global_broadcast: request.pduDestination = GlobalBroadcast() else: request.pduDestination = LocalBroadcast() if len(args) == 2: try: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) except ValueError: pass self._log.debug("{:>12} {}".format("- request:", request)) iocb = IOCB(request) # make an IOCB self.this_application._last_i_am_received = [] # 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 iocb.ioError: # unsuccessful: error/reject/abort pass time.sleep(3) self.discoveredDevices = self.this_application.i_am_counter return self.this_application._last_i_am_received
def do_write_property(self, device, callback=None): try: iocb = device if isinstance(device, IOCB) else self.form_iocb(device, request_type="writeProperty") deferred(self.request_io, iocb) self.requests_in_progress.update({iocb: {"callback": callback}}) iocb.add_callback(self.__general_cb) except Exception as error: log.exception("exception: %r", error)
def response(self, apdu): if _debug: TestApplication._debug("response %r", apdu) # check for loopback if apdu.pduDestination == self.localAddress: if _debug: TestApplication._debug(" - loopback") deferred(self.confirmation, apdu) else: BIPSimpleApplication.response(self, apdu)
def run_application(objectidentifier: int): global this_device global this_application # parse the command line arguments parser = ConfigArgumentParser(description=__doc__) # add an argument for interval parser.add_argument( 'device_id', type=int, help='device identifier', ) # add an argument for interval parser.add_argument( 'device_addr', type=str, help='device address', ) # make a device object this_device = LocalDeviceObject( objectName="objectpropertyreader", objectIdentifier=599, maxApduLengthAccepted=1024, segmentationSupported="segmentedBoth", vendorIdentifier=15, ) import netifaces from ipaddress import IPv4Network wifi_ip = netifaces.ifaddresses('en0')[netifaces.AF_INET][0] #Addres of this device which will perform the querying. address = wifi_ip['addr'] + "/" + str( IPv4Network("0.0.0.0/" + wifi_ip['netmask']).prefixlen) + ":47809" # make a simple application this_application = ReadAllObjectPropertiesApplication(this_device, address) # build a device object identifier device_id = ('device', objectidentifier) # Address of device being queried. device_addr = Address( wifi_ip['addr'] + "/" + str(IPv4Network("0.0.0.0/" + wifi_ip['netmask']).prefixlen) + ":47808") # kick off the process after the core is up and running deferred(this_application.read_object_list, device_id, device_addr) _log.debug("running") run() _log.debug("fini")
def write(self, args, vendor_id=0): """ Build a WriteProperty request, wait for an answer, and return status [True if ok, False if not]. :param args: String with <addr> <type> <inst> <prop> <value> [ <indx> ] [ <priority> ] :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.write('2:5 analogValue 1 presentValue 100') Direct the controller at (Network 2, address 5) to write 100 to the presentValues of its analogValue 1 (AV:1) """ if not self._started: raise ApplicationNotStarted("BACnet stack not running - use startApp()") args = args.split() self.log_title("Write property", args) try: # build a WriteProperty request iocb = IOCB(self.build_wp_request(args, vendor_id=vendor_id)) # pass to the BACnet stack deferred(self.this_application.request_io, iocb) self._log.debug("{:<20} {!r}".format("iocb", iocb)) except WritePropertyException as error: # construction error self._log.exception("exception: {!r}".format(error)) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if not isinstance(iocb.ioResponse, 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 raise NoResponseFromController()
def main(): global this_application # 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), ) # make a simple application this_application = BIPSimpleApplication(this_device, args.ini.address) # 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 # create a thread and read_thread = ReadPointListThread(point_list) if _debug: _log.debug(" - read_thread: %r", read_thread) # start it running when the core is running deferred(read_thread.start) _log.debug("running") run() # dump out the results for request, response in zip(point_list, read_thread.response_values): print(request, response) _log.debug("fini")
def abort_io(self, iocb, err): """Called by a handler or a client to abort a transaction.""" if _debug: IOQController._debug("abort_io %r %r", iocb, err) # normal abort IOController.abort_io(self, iocb, err) # check to see if it is completing the active one if iocb is not self.active_iocb: if _debug: IOQController._debug(" - not current iocb") return # no longer an active iocb self.active_iocb = None # change our state self.state = CTRL_IDLE # look for more to do deferred(IOQController._trigger, self)
def do_read(self, args): """read <addr> <unitID> <register> [ <count> ] :param addr: IP address of the MODBUS/TCP device or gateway :param unitID: unit identifier :param register: register in 5-digit or 6-digit format :param count: number of registers to read, defaults to one This command generates a :class:`ReadCoilsRequest`, :class:`ReadDiscreteInputsRequest`, :class:`ReadInputRegistersRequest`, or :class:`ReadMultipleRegistersRequest` depending on the address prefix; 0, 1, 3, or 4. """ args = args.split() if _debug: ConsoleClient._debug("do_read %r", args) if (len(args) < 3): print("address, unit and register required") return # get the address and unit, and register addr, unitID, register = args[:3] # address might have a port if ':' in addr: addr, port = addr.split(':') server_address = (addr, int(port)) else: server_address = (addr, 502) # unit identifier unitID = int(unitID) if _debug: ConsoleClient._debug(" - addr, unitID: %r, %r", addr, unitID) # get the register and count register = int(register) if len(args) == 4: rcount = int(args[3]) else: rcount = 1 if _debug: ConsoleClient._debug(" - register, rcount: %r, %r", register, rcount) # decode the register into a type digits = int(math.log10(register)) + 1 if digits <= 4: # must be a coil registerType = 0 elif digits == 5: registerType = register // 10000 register = register % 10000 elif digits == 6: registerType = register // 100000 register = register % 100000 else: print("5 or 6 digit addresses please") return if _debug: ConsoleClient._debug(" - registerType, register: %r, %r", registerType, register) # build a request if registerType == 0: # coil req = ReadCoilsRequest(register - 1, rcount) elif registerType == 1: # discrete inputs req = ReadDiscreteInputsRequest(register - 1, rcount) elif registerType == 3: # input register req = ReadInputRegistersRequest(register - 1, rcount) elif registerType == 4: # holding register req = ReadMultipleRegistersRequest(register - 1, rcount) else: print("unsupported register type") return # set the destination req.pduDestination = server_address req.mpduUnitID = unitID if _debug: ConsoleClient._debug(" - req: %r", req) # make an IOCB iocb = IOCB(req) if _debug: ConsoleClient._debug(" - iocb: %r", iocb) # submit the request via the main thread deferred(self.controller.request_io, iocb) # wait for the response iocb.wait() # exceptions if iocb.ioError: print("error: %r" % (iocb.ioError,)) return # extract the response resp = iocb.ioResponse if _debug: ConsoleClient._debug(" - resp: %r", resp) # read responses if isinstance(resp, ExceptionResponse): print(" ::= " + str(resp)) elif isinstance(resp, ReadCoilsResponse): print(" ::= " + str(resp.bits)) elif isinstance(resp, ReadDiscreteInputsResponse): print(" ::= " + str(resp.bits)) elif isinstance(resp, ReadInputRegistersResponse): print(" ::= " + str(resp.registers)) for dtype, codec in ModbusStruct.items(): try: value = codec.unpack(resp.registers) print(" " + dtype + " ::= " + str(value)) except Exception as err: if _debug: ConsoleClient._debug("unpack exception %r: %r", codec, err) elif isinstance(resp, ReadMultipleRegistersResponse): print(" ::= " + str(resp.registers)) for dtype, codec in ModbusStruct.items(): try: value = codec.unpack(resp.registers) print(" " + dtype + " ::= " + str(value)) except Exception as err: if _debug: ConsoleClient._debug("unpack exception %r: %r", codec, err) else: raise TypeError("unsupported response")
segmentationSupported=args.ini.segmentationsupported, vendorIdentifier=int(args.ini.vendoridentifier), ) # make a simple application this_application = ReadPointListApplication(point_list, this_device, args.ini.address) # 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 # fire off a request when the core has a chance deferred(this_application.next_request) _log.debug("running") run() # dump out the results for request, response in zip(point_list, this_application.response_values): print request, response except Exception, e: _log.exception("an error has occurred: %s", e) finally: _log.debug("finally")
def read(self, args, arr_index=None, vendor_id=0, bacoid=None): """ Build a ReadProperty 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/24' bacnet = BAC0.connect(ip = myIPAddr) bacnet.read('2:5 analogInput 1 presentValue') Requests the controller at (Network 2, address 5) for the presentValue of its analog input 1 (AI:1). """ if not self._started: raise ApplicationNotStarted("BACnet stack not running - use startApp()") args_split = args.split() self.log_title("Read property", args_split) vendor_id = vendor_id bacoid = bacoid try: # build ReadProperty request iocb = IOCB( self.build_rp_request( args_split, arr_index=arr_index, vendor_id=vendor_id, bacoid=bacoid ) ) # pass to the BACnet stack deferred(self.this_application.request_io, iocb) self._log.debug("{:<20} {!r}".format("iocb", iocb)) except ReadPropertyException as error: # construction error self._log.exception("exception: {!r}".format(error)) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if not isinstance(apdu, ReadPropertyACK): # expecting 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 # find the datatype datatype = get_datatype( apdu.objectIdentifier[0], apdu.propertyIdentifier, vendor_id=vendor_id ) 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) self._log.debug("{:<20} {:<20}".format("value", "datatype")) self._log.debug("{!r:<20} {!r:<20}".format(value, datatype)) return value if iocb.ioError: # unsuccessful: error/reject/abort apdu = iocb.ioError reason = find_reason(apdu) if reason == "segmentationNotSupported": self._log.warning( "Segmentation not supported... will read properties one by one..." ) self._log.debug("The Request was : {}".format(args_split)) value = self._split_the_read_request(args, arr_index) return value else: if reason == "unknownProperty": # if "priorityArray" in args: # self._log.debug("Unknown property {}".format(args)) # else: # self._log.warning("Unknown property {}".format(args)) if "description" in args: return "Not Implemented" elif "inactiveText" in args: return "Off" elif "activeText" in args: return "On" else: raise UnknownPropertyError("Unknown property {}".format(args)) elif reason == "unknownObject": self._log.warning("Unknown object {}".format(args)) raise UnknownObjectError("Unknown object {}".format(args)) else: # Other error... consider NoResponseFromController (65) # even if the realy reason is another one raise NoResponseFromController( "APDU Abort Reason : {}".format(reason) )
def readMultiple(self, args): """ Build a ReadPropertyMultiple request, wait for the answer and return the values :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/24' bacnet = BAC0.connect(ip = myIPAddr) bacnet.readMultiple('2:5 analogInput 1 presentValue units') Requests the controller at (Network 2, address 5) for the (presentValue and units) of its analog input 1 (AI:1). """ if not self._started: raise ApplicationNotStarted("BACnet stack not running - use startApp()") args = args.split() values = [] self.log_title("Read Multiple", args) try: # build an ReadPropertyMultiple request iocb = IOCB(self.build_rpm_request(args)) # pass to the BACnet stack deferred(self.this_application.request_io, iocb) self._log.debug("{:<20} {!r}".format("iocb", iocb)) except ReadPropertyMultipleException as error: # construction error self._log.exception("exception: {!r}".format(error)) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if not isinstance(apdu, ReadPropertyMultipleACK): # expecting an ACK self._log.debug("{:<20}".format("not an ack")) self._log.warning( "Not an Ack. | APDU : {} / {}".format((apdu, type(apdu))) ) return # loop through the results for result in apdu.listOfReadAccessResults: # here is the object identifier objectIdentifier = result.objectIdentifier self.log_subtitle( "{!r} : {!r}".format(objectIdentifier[0], objectIdentifier[1]), width=114, ) self._log.debug( "{:<20} {:<20} {:<30} {:<20}".format( "propertyIdentifier", "propertyArrayIndex", "value", "datatype" ) ) self._log.debug("-" * 114) # now come the property values per object for element in result.listOfResults: # get the property and array index propertyIdentifier = element.propertyIdentifier propertyArrayIndex = element.propertyArrayIndex readResult = element.readResult if readResult.propertyAccessError is not None: self._log.debug( "Property Access Error for {}".format( readResult.propertyAccessError ) ) values.append(None) else: # here is the value propertyValue = readResult.propertyValue # find the datatype datatype = get_datatype(objectIdentifier[0], propertyIdentifier) 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) self._log.debug( "{!r:<20} {!r:<20} {!r:<30} {!r:<20}".format( propertyIdentifier, propertyArrayIndex, value, datatype ) ) values.append(value) return values if iocb.ioError: # unsuccessful: error/reject/abort apdu = iocb.ioError reason = find_reason(apdu) self._log.warning("APDU Abort Reject Reason : {}".format(reason)) self._log.debug("The Request was : {}".format(args)) if reason == "unrecognizedService": raise UnrecognizedService() elif reason == "segmentationNotSupported": raise SegmentationNotSupported() elif reason == "unknownObject": self._log.warning("Unknown object {}".format(args)) raise UnknownObjectError("Unknown object {}".format(args)) elif reason == "unknownProperty": self._log.warning("325 Unknown property {}".format(args)) values.append("") return values else: self._log.warning("No response from controller") values.append("") return values
def do_write(self, args): """write <addr> <unitID> <register> <value> :param addr: IP address of the MODBUS/TCP device or gateway :param unitID: unit identifier :param register: register in 5-digit or 6-digit format :param value: value to write This command generates a :class:`WriteSingleCoil`, or :class:`WriteSingleRegisterRequest` depending on the address prefix; 0 or 4. """ args = args.split() if _debug: ConsoleClient._debug("do_write %r", args) if (len(args) < 3): print("address, unit and register required") return # get the address and unit addr, unitID, register, value = args # address might have a port if ':' in addr: addr, port = addr.split(':') server_address = (addr, int(port)) else: server_address = (addr, 502) # unit identifier unitID = int(unitID) if _debug: ConsoleClient._debug(" - addr, unitID: %r, %r", server_address, unitID) # get the register and count register = int(register) if _debug: ConsoleClient._debug(" - register: %r", register) # decode the register into a type digits = int(math.log10(register)) + 1 if digits <= 4: # must be a coil registerType = 0 elif digits == 5: registerType = register // 10000 register = register % 10000 elif digits == 6: registerType = register // 100000 register = register % 100000 else: print("5 or 6 digit addresses please") return if _debug: ConsoleClient._debug(" - registerType, register: %r, %r", registerType, register) # value value = int(value) if _debug: ConsoleClient._debug(" - value: %r", value) # build a request if registerType == 0: # coil req = WriteSingleCoilRequest(register - 1, value) elif registerType == 4: # holding register req = WriteSingleRegisterRequest(register - 1, value) else: print("unsupported register type") return # set the destination req.pduDestination = server_address req.mpduUnitID = unitID if _debug: ConsoleClient._debug(" - req: %r", req) # make an IOCB iocb = IOCB(req) if _debug: ConsoleClient._debug(" - iocb: %r", iocb) # submit the request via the main thread deferred(self.controller.request_io, iocb) # wait for the response iocb.wait() # exceptions if iocb.ioError: print("error: %r" % (iocb.ioError,)) return # extract the response resp = iocb.ioResponse if _debug: ConsoleClient._debug(" - resp: %r", resp) # write responses if isinstance(iocb.ioResponse, WriteSingleCoilResponse): print(" ::= " + str(iocb.ioResponse.value)) elif isinstance(iocb.ioResponse, WriteSingleRegisterResponse): print(" ::= " + str(iocb.ioResponse.value)) else: raise TypeError("unsupported response")
def main(): """ Main function, called when run as an application. """ global server_address # parse the command line arguments parser = ArgumentParser(description=__doc__) parser.add_argument( "host", nargs='?', help="address of host (default %r)" % (SERVER_HOST,), default=SERVER_HOST, ) parser.add_argument( "port", nargs='?', type=int, help="server port (default %r)" % (SERVER_PORT,), default=SERVER_PORT, ) parser.add_argument( "--hello", action="store_true", default=False, help="send a hello message", ) args = parser.parse_args() if _debug: _log.debug("initialization") if _debug: _log.debug(" - args: %r", args) # extract the server address and port host = args.host port = args.port server_address = (host, port) if _debug: _log.debug(" - server_address: %r", server_address) # build the stack this_console = ConsoleClient() if _debug: _log.debug(" - this_console: %r", this_console) this_middle_man = MiddleMan() if _debug: _log.debug(" - this_middle_man: %r", this_middle_man) this_director = TCPClientDirector() if _debug: _log.debug(" - this_director: %r", this_director) bind(this_console, this_middle_man, this_director) bind(MiddleManASE(), this_director) # create a task manager for scheduled functions task_manager = TaskManager() if _debug: _log.debug(" - task_manager: %r", task_manager) # don't wait to connect deferred(this_director.connect, server_address) # send hello maybe if args.hello: deferred(this_middle_man.indication, PDU(xtob('68656c6c6f0a'))) if _debug: _log.debug("running") run() if _debug: _log.debug("fini")