def main(): # 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=('device', int(args.ini.objectidentifier)), maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted), segmentationSupported=args.ini.segmentationsupported, vendorIdentifier=int(args.ini.vendoridentifier), ) # make a sample application this_application = BIPSimpleApplication(this_device, args.ini.address) # add the additional service this_application.add_capability(ReadWritePropertyMultipleServices) # 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 random input object accumulator = AccumulatorObject( objectIdentifier=('accumulator', 1), objectName='Something1', presentValue=100, statusFlags=[0, 0, 0, 0], eventState='normal', scale=Scale(floatScale=2.3), units='btusPerPoundDryAir', ) if _debug: _log.debug(" - accumulator: %r", accumulator) # add it to the device this_application.add_object(accumulator) if _debug: _log.debug(" - object list: %r", this_device.objectList) # create a task that bumps the value by one every 10 seconds pulse_task = PulseTask(accumulator, 1, 10 * 1000) if _debug: _log.debug(" - pulse_task: %r", pulse_task) _log.debug("running") run() _log.debug("fini")
def main(): # 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=('device', int(args.ini.objectidentifier)), maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted), segmentationSupported=args.ini.segmentationsupported, vendorIdentifier=int(args.ini.vendoridentifier), ) # make a sample application this_application = BIPSimpleApplication(this_device, args.ini.address) # add the additional service this_application.add_capability(ReadWritePropertyMultipleServices) # 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 random input object accumulator = AccumulatorObject( objectIdentifier=('accumulator', 1), objectName='Something1', presentValue=100, statusFlags = [0, 0, 0, 0], eventState='normal', scale=Scale(floatScale=2.3), units='btusPerPoundDryAir', ) if _debug: _log.debug(" - accumulator: %r", accumulator) # add it to the device this_application.add_object(accumulator) if _debug: _log.debug(" - object list: %r", this_device.objectList) # create a task that bumps the value by one every 10 seconds pulse_task = PulseTask(accumulator, 1, 10 * 1000) if _debug: _log.debug(" - pulse_task: %r", pulse_task) _log.debug("running") run() _log.debug("fini")
def main(): # 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 sample application this_application = BIPSimpleApplication(this_device, args.ini.address) # add the capability to server file content this_application.add_capability(FileServices) # 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 record access file, add to the device f1 = TestRecordFile( objectIdentifier=('file', 1), objectName='RecordAccessFile1' ) _log.debug(" - f1: %r", f1) this_application.add_object(f1) # make a stream access file, add to the device f2 = TestStreamFile( objectIdentifier=('file', 2), objectName='StreamAccessFile2' ) _log.debug(" - f2: %r", f2) this_application.add_object(f2) _log.debug("running") run() _log.debug("fini")
def main(): # 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 sample application this_application = BIPSimpleApplication(this_device, args.ini.address) # add the capability to server file content this_application.add_capability(FileServices) # 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 record access file, add to the device f1 = TestRecordFile(objectIdentifier=('file', 1), objectName='RecordAccessFile1') _log.debug(" - f1: %r", f1) this_application.add_object(f1) # make a stream access file, add to the device f2 = TestStreamFile(objectIdentifier=('file', 2), objectName='StreamAccessFile2') _log.debug(" - f2: %r", f2) this_application.add_object(f2) _log.debug("running") run() _log.debug("fini")
def main(): # 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) # add the additional service this_application.add_capability(ReadWritePropertyMultipleServices) # make a random input object accumulator = AccumulatorObject( objectIdentifier=('accumulator', 1), objectName='Something1', presentValue=100, statusFlags = [0, 0, 0, 0], eventState='normal', scale=Scale(floatScale=2.3), units='btusPerPoundDryAir', ) if _debug: _log.debug(" - accumulator: %r", accumulator) # add it to the device this_application.add_object(accumulator) if _debug: _log.debug(" - object list: %r", this_device.objectList) # create a task that bumps the value by one every 10 seconds pulse_task = PulseTask(accumulator, 1, 10 * 1000) if _debug: _log.debug(" - pulse_task: %r", pulse_task) _log.debug("running") run() _log.debug("fini")
def main(): # 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) # add the capability to server file content this_application.add_capability(FileServices) # make a record access file, add to the device f1 = TestRecordFile( objectIdentifier=('file', 1), objectName='RecordAccessFile1' ) _log.debug(" - f1: %r", f1) this_application.add_object(f1) # make a stream access file, add to the device f2 = TestStreamFile( objectIdentifier=('file', 2), objectName='StreamAccessFile2' ) _log.debug(" - f2: %r", f2) this_application.add_object(f2) _log.debug("running") run() _log.debug("fini")
def main(): device_info = { 'ip': '10.169.204.200', 'netmask': 23, 'port': 47809, 'objectName': 'FHL-DAF-DUSTMETER', 'objectIdentifier': 522020, 'vendorIdentifier': 15, 'location': 'FHL-DAF-CLEAN-ROOM', 'vendorName': 'DESY-ATLAS', 'modelName': 'DUST-METERS', 'softwareVersion': 'bacpypes_v0.16.2_py27', 'description': 'FHL-DAF clean room dustmeter server' } print device_info this_device = LocalDeviceObject( objectName=device_info['objectName'], objectIdentifier=device_info['objectIdentifier'], vendorIdentifier=device_info['vendorIdentifier']) this_device._values['location'] = CharacterString(device_info['location']) this_device._values['vendorName'] = CharacterString( device_info['vendorName']) this_device._values['modelName'] = CharacterString( device_info['modelName']) this_device._values['applicationSoftwareVersion'] = CharacterString( device_info['softwareVersion']) this_device._values['description'] = CharacterString( device_info['description']) this_addr = str(device_info['ip'] + '/' + str(device_info['netmask']) + ':' + str(device_info['port'])) print 'bacnet server will listen at', this_addr this_application = BIPSimpleApplication(this_device, this_addr) this_application.add_capability(ReadWritePropertyMultipleServices) this_device.protocolServicesSupported = this_application.get_services_supported( ).value meter_info = [ { 'name': 'dustmeter_a19', 'index': 1, 'host': 'fhlrs232_a19.desy.de', 'description': 'dustmeter on RS232-Ethernet bridge at somewhere', }, { 'name': 'dustmeter_a27', 'index': 2, 'host': 'fhlrs232_a27.desy.de', 'description': 'dustmeter on RS232-Ethernet bridge at somewhere', }, { 'name': 'dustmeter_a40', 'index': 3, 'host': 'fhlrs232_a40.desy.de', 'description': 'dustmeter on RS232-Ethernet bridge at somewhere', }, { 'name': 'dustmeter_a43', 'index': 4, 'host': 'fhlrs232_a43.desy.de', 'description': 'dustmeter on RS232-Ethernet bridge at somewhere', }, { 'name': 'dustmeter_a49', 'index': 5, 'host': 'fhlrs232_a49.desy.de', 'description': 'dustmeter on RS232-Ethernet bridge at somewhere', }, { 'name': 'dustmeter_a56', 'index': 6, 'host': 'fhlrs232_a56.desy.de', 'description': 'dustmeter on RS232-Ethernet bridge at somewhere', }, ] meters = [] for info in meter_info: m = dustmeter.DustMeter(name=info['name'], host=info['host']) m.start() meters.append(m) objs = [] for info in meter_info: ai_obj = AnalogInputObject(objectIdentifier=('analogInput', info['index']), \ objectName=info['name']) ai_obj._values['description'] = CharacterString(info['description']) ai_obj._values['deviceType'] = CharacterString( 'Particles(>0.5um) PerCubicFoot') ai_obj._values['units'] = EngineeringUnits('noUnits') ai_obj._values['updateInterval'] = Unsigned(60) ai_obj._values['resolution'] = Real(100) this_application.add_object(ai_obj) objs.append(ai_obj) mythread = dataThread(meters, objs) mythread.start() run() mythread.stop() mythread.join() for m in meters: m.stop() m.join() print "end of join"
this_device._values["location"] = CharacterString(device_info["location"]) this_device._values["vendorName"] = CharacterString( device_info["vendorName"]) this_device._values["modelName"] = CharacterString( device_info["modelName"]) this_device._values["applicationSoftwareVersion"] = CharacterString( device_info["softwareVersion"]) this_device._values["description"] = CharacterString( device_info["description"]) this_addr = "{}/{}:{}".format(device_info["ip"], device_info["netmask"], device_info["port"]) print("bacnet server will listen at {}".format(this_addr)) this_application = BIPSimpleApplication(this_device, this_addr) this_application.add_capability(ReadWritePropertyMultipleServices) this_device.protocolServicesSupported = this_application.get_services_supported( ).value meters_active = [] ai_objs = [] idx = 1 print("Initializing meters...") for key, metermodule in METERS.items(): if not key in cparser["server"]: print("No key '{}' in config server section. Skipping".format(key)) continue metersections = cparser["server"][key].split() missing_metersections = set(metersections) - set(cparser.keys()) if len(missing_metersections) != 0: print("Missing config sections for meters: " +
def main(): if not path.exists("server.cfg"): logger.error("Error: File server.cfg not found.") exit(1) cparser = configparser.ConfigParser() cparser.read("server.cfg") if not "server" in cparser: logger.error("Invalid config: No server section") exit(1) required_keys = { "ip", "port", "objectname", "vendoridentifier", "location", "vendorname", "modelname", "description" } missing_keys = required_keys - set(cparser["server"].keys()) if len(missing_keys) != 0: logger.error("Missing config keys in server section: " + (" ".join(missing_keys))) exit(1) device_info = { 'ip': cparser["server"]["ip"], 'netmask': 23, 'port': cparser["server"]["port"], 'objectName': cparser["server"]["objectName"], 'objectIdentifier': 522020, 'vendorIdentifier': int(cparser["server"]["vendorIdentifier"]), 'location': cparser["server"]["location"], 'vendorName': cparser["server"]["vendorName"], 'modelName': cparser["server"]["modelName"], 'softwareVersion': "bacpypes_{}_python{}.{}.{}".format(bacpypes_version, version_info[0], version_info[1], version_info[2]), 'description': cparser["server"]["description"] } logger.info("=== INIT ===") logger.info(device_info) this_device = LocalDeviceObject( objectName=device_info["objectName"], objectIdentifier=device_info["objectIdentifier"], vendorIdentifier=device_info["vendorIdentifier"]) this_device._values['location'] = CharacterString(device_info['location']) this_device._values['vendorName'] = CharacterString( device_info['vendorName']) this_device._values['modelName'] = CharacterString( device_info['modelName']) this_device._values['applicationSoftwareVersion'] = CharacterString( device_info['softwareVersion']) this_device._values['description'] = CharacterString( device_info['description']) this_addr = str(device_info['ip'] + '/' + str(device_info['netmask']) + ':' + str(device_info['port'])) logger.info("bacnet server will listen at {}".format(this_addr)) this_application = BIPSimpleApplication(this_device, this_addr) this_application.add_capability(ReadWritePropertyMultipleServices) this_device.protocolServicesSupported = this_application.get_services_supported( ).value meters_active = [] ai_objs = [] idx = 1 logger.info("Initializing meters...") for key, metermodule in METERS.items(): if not key in cparser["server"]: logger.warning( "No key '{}' in config server section. Skipping".format(key)) continue metersections = cparser["server"][key].split() missing_metersections = set(metersections) - set(cparser.keys()) if len(missing_metersections) != 0: logger.error("Missing config sections for meters: " + "".join(missing_metersections)) exit(1) for metersection in metersections: info = cparser[metersection] ms = metermodule.getMeters(info) logger.info("Got {} meter(s) from {}".format( len(ms), metersection)) meters_active.extend(ms) for m in ms: m.name = "{}_{}".format(metersection, m.name) ai_obj = AnalogInputObject(objectIdentifier=("analogInput", idx), objectName=m.name) if "description" in info: ai_obj._values["description"] = CharacterString( info["description"]) if "deviceType" in info: ai_obj._values["deviceType"] = CharacterString( info["deviceType"]) ai_obj._values["units"] = EngineeringUnits("noUnits") if "updateInterval" in info: try: updateInterval = int(info["updateInterval"]) if updateInterval < 0: raise ValueError("Invalid negative value :" + info["updateInterval"]) except ValueError as e: logger.error( "Value of updateInterval in section {}: {}".format( metersection, e)) exit(1) ai_obj._values["updateInterval"] = Unsigned(updateInterval) if "resolution" in info: try: resolution = float(info["resolution"]) except ValueError as e: logger.error( "Value of updateInterval in section {}: {}".format( metersection, e)) exit(1) ai_obj._values["resolution"] = Real(resolution) this_application.add_object(ai_obj) ai_objs.append(ai_obj) idx += 1 fname = m.name output_csv = os.path.join(str('/var/www/html'), fname + u".csv") mode = 'a' if sys.version_info.major < 3: mode += 'b' with open(output_csv, mode) as f: header = OrderedDict([('# time', None), (m.name, None)]) writer = csv.DictWriter(f, fieldnames=header, extrasaction=u"ignore") writer.writeheader() f.close() for m in meters_active: m.start() datathread = DataThread(meters_active, ai_objs) datathread.start() bacpypesrun() datathread.stop() datathread.join() for m in meters_active: m.stop() m.join()
class BACServer(metaclass=Singleton): def __init__(self): self.__config: Union[BACnetSetting, None] = None self.__bacnet_server: Union[BACnetServerModel, None] = None self.__registry: Dict[str, Commandable] = {} self.__sync_status: bool = False self.__running: bool = False self.ldo = None self.__bacnet = None self._thread = None @property def config(self) -> Union[BACnetSetting, None]: return self.__config def status(self) -> bool: return bool(self.config and self.config.enabled and self.__bacnet and self.__sync_status) def start_bac(self, config: BACnetSetting): self.__config = config self.__bacnet_server = BACnetServerModel.create_default_server_if_does_not_exist( self.config) self.loop_forever() def loop_forever(self): while True: try: if not self.__running: self.connect(self.__bacnet_server) setting: AppSetting = current_app.config[ AppSetting.FLASK_KEY] if setting.mqtt.enabled: mqtt_client = MqttClient() while not mqtt_client.status(): logger.warning( "MQTT is not connected, waiting for MQTT connection successful..." ) time.sleep(self.config.attempt_reconnect_secs) self.sync_stack() self.__running = True else: self.sync_stack() self.__running = True time.sleep(2) except Exception as e: logger.error(e) logger.warning( "BACnet is not connected, waiting for BACnet server connection..." ) time.sleep(self.config.attempt_reconnect_secs) def stop_bacnet(self): if self.__bacnet: self.__bacnet.close_socket() bacnet_stop() def start_bacnet(self, bacnet_server): self.__bacnet_server = bacnet_server FlaskThread(target=self.connect, args=(bacnet_server, )).start() # create_bacnet_stack def restart_bacnet(self, bacnet_server): if self.__bacnet: self.stop_bacnet() self.__reset_variable() self.start_bacnet(bacnet_server) def __reset_variable(self): self.ldo = None self.__bacnet = None self._thread = None self.__running = False self.__registry = {} def sync_stack(self): for point in BACnetPointModel.query.filter_by( object_type=PointType.analogOutput): self.add_point(point, False) for point in BACnetPointModel.query.filter_by( object_type=PointType.analogValue): self.add_point(point, False) self.__sync_status = True self.__running = True def connect(self, bacnet_server): address = self._ip_address(bacnet_server) version = get_version() description = "nube-io bacnet server" self.ldo = LocalDeviceObject( objectName=bacnet_server.local_obj_name, objectIdentifier=int(bacnet_server.device_id), maxApduLengthAccepted=1024, segmentationSupported="segmentedBoth", vendorIdentifier=bacnet_server.vendor_id, firmwareRevision=CharacterString(version), modelName=CharacterString(bacnet_server.model_name), vendorName=CharacterString(bacnet_server.vendor_name), description=CharacterString(description), systemStatus=DeviceStatus(1), applicationSoftwareVersion=CharacterString(version), databaseRevision=0) self.__bacnet = BIPSimpleApplication(self.ldo, address) self.__bacnet.add_capability(ReadWritePropertyMultipleServices) self.sync_stack() FlaskThread(target=bacnet_run).start() # start bacpypes thread def add_point(self, point: BACnetPointModel, _update_point_store=True): [priority_array, present_value] = default_values(point.priority_array_write, point.relinquish_default) if point.use_next_available_address: point.address = BACnetPointModel.get_next_available_address( point.address) object_identifier = create_object_identifier(point.object_type.name, point.address) if point.object_type.name == "analogOutput": register_object_type(AnalogOutputCmdObject) p = AnalogOutputFeedbackObject( profileName=point.uuid, objectIdentifier=(point.object_type.name, point.address), objectName=point.object_name, relinquishDefault=point.relinquish_default, presentValue=present_value, priorityArray=priority_array, eventState=point.event_state.name, statusFlags=StatusFlags(), units=EngineeringUnits(point.units.name), description=point.description, outOfService=False, ) self.__bacnet.add_object(p) self.__registry[object_identifier] = p elif point.object_type.name == "analogValue": register_object_type(AnalogValueCmdObject) p = AnalogValueFeedbackObject( profileName=point.uuid, objectIdentifier=(point.object_type.name, point.address), objectName=point.object_name, relinquishDefault=point.relinquish_default, presentValue=present_value, priorityArray=priority_array, eventState=point.event_state.name, statusFlags=StatusFlags(), units=EngineeringUnits(point.units.name), description=point.description, outOfService=False, ) self.__bacnet.add_object(p) self.__registry[object_identifier] = p if _update_point_store: # make it so on start of app not to update the point store update_point_store(point.uuid, present_value) setting: AppSetting = current_app.config[AppSetting.FLASK_KEY] if setting.mqtt.enabled: priority = get_highest_priority_field(point.priority_array_write) mqtt_client = MqttClient() mqtt_client.publish_value( ('ao', object_identifier, point.object_name), present_value, priority) def remove_point(self, point): object_identifier = create_object_identifier(point.object_type.name, point.address) self.__bacnet.delete_object(self.__registry[object_identifier]) del self.__registry[object_identifier] def remove_all_points(self): object_identifiers = copy.deepcopy(list(self.__registry.keys())) for object_identifier in object_identifiers: self.__bacnet.delete_object(self.__registry[object_identifier]) del self.__registry[object_identifier] def _ip_address(self, bacnet_server): use_nic = self.config.enable_ip_by_nic_name if use_nic: ip_by_nic_name = self.config.ip_by_nic_name address = IP.get_nic_ipv4(ip_by_nic_name) return address else: ip = bacnet_server.ip port = bacnet_server.port mask = None try: ip, subnet_mask_and_port = ip.split("/") try: mask, port = subnet_mask_and_port.split(":") except ValueError: mask = subnet_mask_and_port except ValueError: ip = ip if not mask: mask = 24 if not port: port = 47808 address = "{}/{}:{}".format(ip, mask, port) return address