def services_supported(service_list): all_services = ServicesSupported().bitNames supported_services = [ i for i in range(len(service_list)) if service_list[i] == 1 ] for key, value in all_services.items(): if value in supported_services: yield key
def _init_bacnet(self): # local bacnet device ldo = LocalDeviceObject( objectName=self._config.bacnet.get('objectName'), objectIdentifier=int(self._config.bacnet.get('objectIdentifier')), maxApduLengthAccepted=int(self._config.bacnet.get('maxApduLengthAccepted')), segmentationSupported=self._config.bacnet.get('segmentationSupported'), vendorIdentifier=int(self._config.bacnet.get('vendorIdentifier')),) # Send an empty support string pss = ServicesSupported() ldo.protocolServicesSupported = pss.value # TODO: look to use domain name resolution on address info = self._config.bacnet.get('address') hostname = "" for i, c in enumerate(info): if c is '/' or c is ':': break hostname += c suffix = info[i:] # MRH: The way BACpypes binds to the interface for broadcast is tricky with containers # overload this for now if docker_test(): import fcntl hostname = socket.gethostname() netmask = socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, socket.SOCK_DGRAM), 0x891b, struct.pack(b'256s', b'eth0'))[20:24]) suffix = "/" + str(sum([bin(int(x)).count('1') for x in netmask.split('.')])) + ":47808" print("host %s" % hostname) addr = socket.gethostbyname(hostname) print("bacnet stack using %s" % (addr + suffix)) self.bacnet_app = BACnet(ldo, addr + suffix)
def setup_device(self, address, max_apdu_len=1024, seg_supported='segmentedBoth', obj_id=599, obj_name='sMap BACnet driver', ven_id=15): _log.info('seg_supported ' + str(seg_supported)) _log.info('max_apdu_len ' + str(max_apdu_len)) _log.info('obj_id ' + str(obj_id)) _log.info('obj_name ' + str(obj_name)) _log.info('ven_id ' + str(ven_id)) this_device = LocalDeviceObject( objectName=obj_name, objectIdentifier=obj_id, maxApduLengthAccepted=max_apdu_len, segmentationSupported=seg_supported, vendorIdentifier=ven_id, ) # build a bit string that knows about the bit names and leave it empty. We respond to NOTHING. pss = ServicesSupported() # set the property value to be just the bits this_device.protocolServicesSupported = pss.value self.this_application = BACnet_application(this_device, address) server_thread = threading.Thread(target=bacpypes.core.run) # exit the BACnet App thread when the main thread terminates server_thread.daemon = True server_thread.start()
def createApplication(device): global applicationCount, applications try: #Defining Device threadName = 'app_' + str(applicationCount) localDevice = LocalDeviceObject( objectName=device.getObjectName(), objectIdentifier=int(device.getObjectIdentifier()), maxApduLengthAccepted=int(device.getMaxApduLengthAccepted()), segmentationSupported=device.getSegmentationSupported(), vendorIdentifier=int(device.getVendorIdentifier()), ) pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['writeProperty'] = 1 localDevice.protocolServicesSupported = pss.value application = Application(localDevice, device.getDeviceAddress()) applications.append(application) applicationThread = BACpypeThread(threadName) applicationThread.start() applicationCount += 1 except Exception, e: print "Error: doStart()" ErrorHandler(e, device)
def configure(self, context): super().configure(context) # bacnet device config self.ldo = LocalDeviceObject(objectName=self.name(), objectIdentifier=int(self.id()), maxApduLengthAccepted=int( self.max_apdu_length()), segmentationSupported=self.segmentation(), vendorIdentifier=int(self.vendor_id())) # Send an empty support string pss = ServicesSupported() ldo.protocolServicesSupported = pss.value info = self.address() hostname = "" for i, c in enumerate(info): if c is '/' or c is ':': break hostname += c suffix = info[i:] addr = socket.gethostbyname(hostname) self.this_application = SimpleApplication(self.ldo, addr + suffix)
def doStart(device): global this_application, this_device, applicationThread, has_started has_started = False try: #Defining Device this_device = LocalDeviceObject( objectName=device.getObjectName(), objectIdentifier=int(device.getObjectIdentifier()), maxApduLengthAccepted=int(device.getMaxApduLengthAccepted()), segmentationSupported=device.getSegmentationSupported(), vendorIdentifier=int(device.getVendorIdentifier()), ) pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['writeProperty'] = 1 this_device.protocolServicesSupported = pss.value this_application = Application(this_device, device.getDeviceAddress()) #Start BACpypes Thread applicationThread = BACpypeThread('BACPYPE-APP') applicationThread.start() has_started = True return has_started except Exception, e: ErrorHandler(e,device)
def __init__(self, address, device_id, network, *, poll=10, from_backup=None, segmentation_supported=True): """ Initialization require address, device id and bacnetApp (the script itself) :param addr: address of the device (ex. '2:5') :param device_id: bacnet device ID (boid) :param network: defined by BAC0.connect() :param poll: (int) if > 0, will poll every points each x seconds. :type address: (str) :type device_id: int :type network: BAC0.scripts.ReadWriteScript.ReadWriteScript """ self.properties = DeviceProperties() self.properties.address = address self.properties.device_id = device_id self.properties.network = network self.properties.pollDelay = poll self.properties.name = '' self.properties.objects_list = [] self.properties.pss = ServicesSupported() self.properties.serving_chart = {} self.properties.charts = [] self.properties.multistates = {} self.segmentation_supported = segmentation_supported self.db = None # Todo : find a way to normalize the name of the db self.properties.db_name = '' self.points = [] self._polling_task = namedtuple('_polling_task', ['task', 'running']) self._polling_task.task = None self._polling_task.running = False self._notes = namedtuple('_notes', ['timestamp', 'notes']) self._notes.timestamp = [] self._notes.notes = [] self._notes.notes.append("Controller initialized") self._notes.timestamp.append(datetime.now()) if from_backup: filename = from_backup db_name = filename.split('.')[0] if os.path.isfile(filename): self.properties.db_name = db_name self.new_state(DeviceDisconnected) else: raise FileNotFoundError("Can't find %s on drive" % filename) else: self.new_state(DeviceDisconnected)
def get_server_application(self): if _debug: DeviceAbstraction._debug(" - creating application") # make a device object this_device = LocalDeviceObject(objectName="Betelgeuse", objectIdentifier=args.device_id, maxApduLengthAccepted=1024, segmentationSupported="segmentedBoth", vendorIdentifier=15) # build a bit string that knows about the bit names pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['readPropertyMultiple'] = 1 pss['writeProperty'] = 1 # set the property value to be just the bits this_device.protocolServicesSupported = pss.value # make a sample application this_application = ReadPropertyMultipleApplication( this_device, args.interface) registers = self.registers[('byte', True)] #Currently we don't actually enforce read only properties. for register in registers: if _debug: DeviceAbstraction._debug( " - creating object of type: %s, %i", register.object_type, register.instance_number) klass = get_object_class(register.object_type) ravo = klass(objectIdentifier=(register.object_type, register.instance_number), objectName=register.point_name) ravo.WriteProperty("presentValue", 0, direct=True) this_application.add_object(ravo) registers = self.registers[('byte', False)] for register in registers: if _debug: DeviceAbstraction._debug( " - creating object of type: %s, %i", register.object_type, register.instance_number) klass = get_object_class(register.object_type) ravo = klass(objectIdentifier=(register.object_type, register.instance_number), objectName=register.point_name) ravo.WriteProperty("presentValue", 0, direct=True) this_application.add_object(ravo) return this_application
def main(): global this_device, 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), ) 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) # enable sleeping will help with threads enable_sleeping() _log.debug("running") run() _log.debug("fini")
def setup_device(self, async_call, address, max_apdu_len=1024, seg_supported='segmentedBoth', obj_id=599, obj_name='sMap BACnet driver', ven_id=15): _log.info('seg_supported ' + str(seg_supported)) _log.info('max_apdu_len ' + str(max_apdu_len)) _log.info('obj_id ' + str(obj_id)) _log.info('obj_name ' + str(obj_name)) _log.info('ven_id ' + str(ven_id)) # Check to see if they gave a valid apdu length. if encode_max_apdu_length_accepted(max_apdu_len) is None: raise ValueError( "Invalid max_apdu_len: {} Valid options are 50, " "128, 206, 480, 1024, and 1476".format(max_apdu_len)) this_device = LocalDeviceObject( objectName=obj_name, objectIdentifier=obj_id, maxApduLengthAccepted=max_apdu_len, segmentationSupported=seg_supported, vendorIdentifier=ven_id, ) # build a bit string that knows about the bit names. pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 # set the property value to be just the bits this_device.protocolServicesSupported = pss.value def i_am_callback(address, device_id, max_apdu_len, seg_supported, vendor_id): async_call.send(None, self.i_am, address, device_id, max_apdu_len, seg_supported, vendor_id) #i_am_callback('foo', 'bar', 'baz', 'foobar', 'foobaz') self.this_application = BACnet_application(i_am_callback, this_device, address) kwargs = {"spin": 0.1, "sigterm": None, "sigusr1": None} server_thread = threading.Thread(target=bacpypes.core.run, kwargs=kwargs) # exit the BACnet App thread when the main thread terminates server_thread.daemon = True server_thread.start()
def __init__(self, address=None, device_id=None, network=None, *, poll=10, from_backup=None, segmentation_supported=True, object_list=None, auto_save=False, clear_history_on_save=False, history_size=None): self.properties = DeviceProperties() self.properties.address = address self.properties.device_id = device_id self.properties.network = network self.properties.pollDelay = poll self.properties.name = '' self.properties.objects_list = [] self.properties.pss = ServicesSupported() self.properties.multistates = {} self.properties.auto_save = auto_save self.properties.clear_history_on_save = clear_history_on_save self.properties.history_size = history_size self.segmentation_supported = segmentation_supported self.custom_object_list = object_list #self.db = None # Todo : find a way to normalize the name of the db self.properties.db_name = '' self.points = [] self.trendlogs = {} self._polling_task = namedtuple('_polling_task', ['task', 'running']) self._polling_task.task = None self._polling_task.running = False self._find_overrides_running = False self._release_overrides_running = False self.note("Controller initialized") if from_backup: filename = from_backup db_name = filename.split('.')[0] self.properties.network = None if os.path.isfile(filename): self.properties.db_name = db_name self.new_state(DeviceDisconnected) else: raise FileNotFoundError( "Can't find {} on drive".format(filename)) else: if self.properties.network and self.properties.address and self.properties.device_id: self.new_state(DeviceDisconnected) else: raise BadDeviceDefinition('Please provide address, device id and network or specify from_backup argument')
def __init__(self, address, device_id, network, *, poll=10, from_backup=None, segmentation_supported=True, object_list=None): self._log = logging.getLogger('BAC0.core.devices.%s' \ % self.__class__.__name__) self._log.setLevel(logging.INFO) self.properties = DeviceProperties() self.properties.address = address self.properties.device_id = device_id self.properties.network = network self.properties.pollDelay = poll self.properties.name = '' self.properties.objects_list = [] self.properties.pss = ServicesSupported() self.properties.serving_chart = {} self.properties.charts = [] self.properties.multistates = {} self.segmentation_supported = segmentation_supported self.custom_object_list = object_list self.db = None # Todo : find a way to normalize the name of the db self.properties.db_name = '' self.points = [] self._polling_task = namedtuple('_polling_task', ['task', 'running']) self._polling_task.task = None self._polling_task.running = False self._notes = namedtuple('_notes', ['timestamp', 'notes']) self._notes.timestamp = [] self._notes.notes = [] self._notes.notes.append("Controller initialized") self._notes.timestamp.append(datetime.now()) if from_backup: filename = from_backup db_name = filename.split('.')[0] if os.path.isfile(filename): self.properties.db_name = db_name self.new_state(DeviceDisconnected) else: raise FileNotFoundError("Can't find %s on drive" % filename) else: self.new_state(DeviceDisconnected)
def setup_device(self, address, max_apdu_len=1024, seg_supported='segmentedBoth', obj_id=599, obj_name='sMap BACnet driver', ven_id=15): global this_application #We use a singleton device if this_application is not None: return print 'seg_supported', seg_supported print 'max_apdu_len', max_apdu_len print 'obj_id', obj_id print 'obj_name', obj_name print 'ven_id', ven_id #Check to see if they gave a valid apdu length. if encode_max_apdu_response(max_apdu_len) is None: raise ValueError( 'Invalid max_apdu_len: Valid options are 50, 128, 206, 480, 1024, and 1476' ) this_device = LocalDeviceObject( objectName=obj_name, objectIdentifier=obj_id, maxApduLengthAccepted=max_apdu_len, segmentationSupported=seg_supported, vendorIdentifier=ven_id, ) # build a bit string that knows about the bit names and leave it empty. We respond to NOTHING. pss = ServicesSupported() # set the property value to be just the bits this_device.protocolServicesSupported = pss.value this_application = BACnet_application(this_device, address) #We must use traditional python threads, otherwise the driver will # hang during startup while trying to scrape actuator values. # I think this is because the reactor hasn't started before we start trying # to use the other threads. #reactor.callInThread(bacpypes.core.run) #reactor.addSystemEventTrigger("before", "shutdown", bacpypes.core.stop) server_thread = threading.Thread(target=bacpypes.core.run) # exit the BACnet App thread when the main thread terminates server_thread.daemon = True server_thread.start()
def __init__(self): self.name = "Unknown" self.address = None self.device_id = None self.network = None self.pollDelay = None self.objects_list = None self.pss = ServicesSupported() self.multistates = None self.db_name = None self.segmentation_supported = True self.history_size = None self.bacnet_properties = {}
def __init__(self): self.name = 'Unknown' self.address = None self.device_id = None self.network = None self.pollDelay = None self.objects_list = None self.pss = ServicesSupported() #self.serving_chart = None #self.charts = None self.multistates = None self.db_name = None self.segmentation_supported = True
def startApp(self): """ Define the local device, including services supported. Once defined, start the BACnet stack in its own thread. """ self._log.debug("Create Local Device") try: # make a device object self.this_device = LocalDeviceObject( objectName= self.localObjName, objectIdentifier= self.Boid, maxApduLengthAccepted=int(self.maxAPDULengthAccepted), segmentationSupported=self.segmentationSupported, vendorIdentifier= self.vendorId, vendorName= self.vendorName, modelName= self.modelName, systemStatus= self.systemStatus, description='http://christiantremblay.github.io/BAC0/', firmwareRevision=''.join(sys.version.split('|')[:2]), applicationSoftwareVersion=infos.__version__, protocolVersion=1, protocolRevision=0, ) # build a bit string that knows about the bit names pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['writeProperty'] = 1 pss['readPropertyMultiple'] = 1 # set the property value to be just the bits self.this_device.protocolServicesSupported = pss.value # make a simple application self.this_application = ScriptApplication(self.this_device, self.localIPAddr) self._log.debug("Starting") self._initialized = True try: self._startAppThread() except: self._log.warning("Error opening socket") raise self._log.debug("Running") except Exception as error: self._log.error("an error has occurred: %s", error) finally: self._log.debug("finally")
def startApp(self): """ This function is used to define the local device, including services supported. Once the application is defined, calls the _startAppThread which will handle the thread creation """ log_debug("App initialization") try: # make a device object self.this_device = LocalDeviceObject( objectName=self.localObjName, objectIdentifier=int(self.Boid), maxApduLengthAccepted=int(self.maxAPDULengthAccepted), segmentationSupported=self.segmentationSupported, vendorIdentifier=int(self.vendorId), vendorName=self.vendorName, modelName=self.modelName, systemStatus=self.systemStatus, description='http://christiantremblay.github.io/BAC0/', firmwareRevision=''.join(sys.version.split('|')[:2]), applicationSoftwareVersion=infos.__version__, protocolVersion=1, protocolRevision=0, ) # build a bit string that knows about the bit names pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['writeProperty'] = 1 pss['readPropertyMultiple'] = 1 # set the property value to be just the bits self.this_device.protocolServicesSupported = pss.value # make a simple application self.this_application = ScriptApplication( self.this_device, self.localIPAddr) log_debug("Starting") self._initialized = True self._startAppThread() log_debug("Running") except Exception as error: log_exception("an error has occurred: %s", error) finally: log_debug("finally")
def run(self): try: self.thisDevice = LocalDeviceObject(self.objectName,self.objectIdentifier,self.maxApduLengthAccepted self.segmentationSupported,self.vendorIdentifier) # 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 self.thisDevice.protocolServicesSupported = pss.value self.thisApplication = BacnetApplication(self.thisDevice, address) self.thisConsole = BacnetConsoleCmd() _log.debug("running") bacpypes.core.run() except Exception, e: logging.error("error %s in creating device %s:%s"%(e,self.type,self,id))
def setup_device(self, address, max_apdu_len=1024, seg_supported='segmentedBoth', obj_id=599, obj_name='sMap BACnet driver', ven_id=15): _log.info('seg_supported ' + str(seg_supported)) _log.info('max_apdu_len ' + str(max_apdu_len)) _log.info('obj_id ' + str(obj_id)) _log.info('obj_name ' + str(obj_name)) _log.info('ven_id ' + str(ven_id)) # Check to see if they gave a valid apdu length. if encode_max_apdu_response(max_apdu_len) is None: raise ValueError( 'Invalid max_apdu_len: {} Valid options are 50, 128, 206, 480, 1024, and 1476' .format(max_apdu_len)) this_device = LocalDeviceObject( objectName=obj_name, objectIdentifier=obj_id, maxApduLengthAccepted=max_apdu_len, segmentationSupported=seg_supported, vendorIdentifier=ven_id, ) # build a bit string that knows about the bit names and leave it empty. We respond to NOTHING. pss = ServicesSupported() # set the property value to be just the bits this_device.protocolServicesSupported = pss.value self.this_application = BACnet_application(this_device, address) server_thread = threading.Thread(target=bacpypes.core.run) # exit the BACnet App thread when the main thread terminates server_thread.daemon = True request = WhoIsRequest() request.pduDestination = GlobalBroadcast() server_thread.start()
def main(): if _debug: main._debug("initialization") global this_application try: # parse the command line arguments args = ConfigArgumentParser(description=__doc__).parse_args() if _debug: main._debug("initialization") if _debug: main._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), ) # 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 = ReadPropertyApplication(this_device, args.ini.address) this_console = ReadWritePropertyConsoleCmd() main._debug("running") run() except Exception, e: main._exception("an error has occurred: %s", e)
def doStart(device): global this_application, this_device, applicationThread, request_addr, has_started has_started = True try: #args = ConfigArgumentParser(description=__doc__).parse_args() #Defining Device this_device = LocalDeviceObject( objectName=device.getObjectName(), objectIdentifier=int(device.getObjectIdentifier()), maxApduLengthAccepted=int(device.getMaxApduLengthAccepted()), segmentationSupported=device.getSegmentationSupported(), vendorIdentifier=int(device.getVendorIdentifier()), ) print request_addr = device.getRequestAddress() pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 pss['readProperty'] = 1 pss['writeProperty'] = 1 this_device.protocolServicesSupported = pss.value this_application = Application(this_device, device.getDeviceAddress()) print "this Addr:" + str(device.getDeviceAddress()) #Start BACpypes Thread applicationThread = BACpypeThread('BACPYPE-APP') applicationThread.start() except Exception: has_started = False finally: #print "Finally\n" return has_started
def setup_device(self, address, port): this_device = LocalDeviceObject( objectName="sMap BACnet driver", objectIdentifier=599, maxApduLengthAccepted=1024, segmentationSupported="segmentedBoth", vendorIdentifier=15, ) # build a bit string that knows about the bit names and leave it empty. We respond to NOTHING. pss = ServicesSupported() # set the property value to be just the bits this_device.protocolServicesSupported = pss.value self.this_application = BACnet_application(this_device, address + ':' + str(port)) server_thread = threading.Thread(target=self.this_application.run_me) # exit the server thread when the main thread terminates server_thread.daemon = True server_thread.start()
def __init__(self, address=None, device_id=None, network=None, *, poll=10, from_backup=None, segmentation_supported=True, object_list=None, auto_save=False, save_resampling="1s", clear_history_on_save=False, history_size=None, reconnect_on_failure=True): self.properties = DeviceProperties() self.properties.address = address self.properties.device_id = device_id self.properties.network = network self.properties.pollDelay = poll self.properties.fast_polling = True if poll < 10 else False self.properties.name = "" self.properties.vendor_id = 0 self.properties.objects_list = [] self.properties.pss = ServicesSupported() self.properties.multistates = {} self.properties.auto_save = auto_save self.properties.save_resampling = save_resampling self.properties.clear_history_on_save = clear_history_on_save self.properties.default_history_size = history_size self._reconnect_on_failure = reconnect_on_failure self.segmentation_supported = segmentation_supported self.custom_object_list = object_list # self.db = None # Todo : find a way to normalize the name of the db self.properties.db_name = "" self.points = [] self._list_of_trendlogs = {} self._polling_task = namedtuple("_polling_task", ["task", "running"]) self._polling_task.task = None self._polling_task.running = False self._find_overrides_running = False self._release_overrides_running = False self.note("Controller initialized") if from_backup: filename = from_backup db_name = filename.split(".")[0] self.properties.network = None if os.path.isfile(filename): self.properties.db_name = db_name self.new_state(DeviceDisconnected) else: raise FileNotFoundError( "Can't find {} on drive".format(filename)) else: if (self.properties.network and self.properties.address and self.properties.device_id is not None): self.new_state(DeviceDisconnected) else: raise BadDeviceDefinition( "Please provide address, device id and network or specify from_backup argument" )
args = arg_parser.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), ) # build a bit string that knows about the bit names pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 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) _log.debug("running") request = WhoIsRequest() if args.address is not None: request.pduDestination = Address(args.address) else:
def setup_device(self, async_call, address, max_apdu_len=1024, seg_supported='segmentedBoth', obj_id=599, obj_name='sMap BACnet driver', ven_id=15, request_check_interval=100): _log.info('seg_supported ' + str(seg_supported)) _log.info('max_apdu_len ' + str(max_apdu_len)) _log.info('obj_id ' + str(obj_id)) _log.info('obj_name ' + str(obj_name)) _log.info('ven_id ' + str(ven_id)) # Check to see if they gave a valid apdu length. if encode_max_apdu_length_accepted(max_apdu_len) is None: raise ValueError( "Invalid max_apdu_len: {} Valid options are 50, 128, 206, 480, 1024, and 1476" .format(max_apdu_len)) this_device = LocalDeviceObject( objectName=obj_name, objectIdentifier=obj_id, maxApduLengthAccepted=max_apdu_len, segmentationSupported=seg_supported, vendorIdentifier=ven_id, ) # build a bit string that knows about the bit names. pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 # set the property value to be just the bits this_device.protocolServicesSupported = pss.value def i_am_callback(address, device_id, max_apdu_len, seg_supported, vendor_id): async_call.send(None, self.i_am, address, device_id, max_apdu_len, seg_supported, vendor_id) def send_cov_subscription_callback(device_address, subscriber_process_identifier, monitored_object_identifier, lifetime, point_name): """ Asynchronous cov subscription callback for gevent """ async_call.send(None, self.send_cov_subscription, device_address, subscriber_process_identifier, monitored_object_identifier, lifetime, point_name) def forward_cov_callback(point_name, apdu, result_dict): """ Asynchronous callback to forward cov values to the platform driver for gevent """ async_call.send(None, self.forward_cov, point_name, apdu, result_dict) self.bacnet_application = BACnetApplication( i_am_callback, send_cov_subscription_callback, forward_cov_callback, request_check_interval, this_device, address) # Having a recurring task makes the spin value kind of irrelevant. kwargs = {"spin": 0.1, "sigterm": None, "sigusr1": None} server_thread = threading.Thread(target=bacpypes.core.run, kwargs=kwargs) # exit the BACnet App thread when the main thread terminates server_thread.daemon = True server_thread.start()