import logging.handlers import time import os import json from controllers import ModbusRTURead, EthernetIPRead from tb_gateway_mqtt import TBDeviceMqttClient, RateLimit def parse_config(config_file): """Parses the configuration file and returns a dictionary.""" with open(config_file, 'r') as f: config = json.load(f) return config CONFIG_DATA = parse_config('device_supervisor.cfg') THINGSBOARD_SERVER = CONFIG_DATA['clouds'][0]['args']['host'] ACCESS_TOKEN = CONFIG_DATA['clouds'][0]['args']['username'] # Convert string level to logging level constant logging_levels = { "DEBUG": logging.DEBUG, "INFO": logging.INFO, "WARNING": logging.WARNING, "ERROR": logging.ERROR, "CRITICAL": logging.CRITICAL } log_level_int = logging_levels.get(CONFIG_DATA['misc']['logLvl'], logging.INFO) logging.basicConfig(filename='main.log', level=log_level_int, format='%(asctime)s - %(levelname)s - %(message)s') client = None # default blinking period period = 1.0 # callback function that will call when we will change value of our Shared Attribute def attribute_callback(result, _): logging.info(result) # make sure that you paste YOUR shared attribute name period = result.get('blinkingPeriod', 1.0) # callback function that will call when we will send RPC def rpc_callback(id, request_body): # request body contains method and other parameters logging.info(request_body) method = request_body.get('method') if method == 'getTelemetry': attributes, telemetry = get_data() client.send_attributes(attributes) client.send_telemetry(telemetry) else: logging.error('Unknown method: ' + method) def get_data(controllers=[], measures=[], groups=[]): for measure in measures: logging.info(f"Controller: {measure['ctrlName']}, Measure: {measure['name']}, Group: {measure['group']}") if controllers[measure['ctrlName']]['protocol'] == "Modbus-RTU": logging.info(ModbusRTURead()) elif controllers[measure['ctrlName']]['protocol'] == "EtherNet/IP": logging.info(EthernetIPRead()) attributes = { "latestReportTime": int(round(time.time() * 1000)) } telemetry = { "test": "test" } logging.info(attributes, telemetry) return attributes, telemetry # request attribute callback def sync_state(result, exception=None): global period if exception is not None: logging.info("Exception: " + str(exception)) else: period = result.get('shared', {'blinkingPeriod': 1.0})[ 'blinkingPeriod'] def rearrange_config(config): out = {} for c in config: out[c['name']] = c return out def main(): global client # Example Usage: controllers = rearrange_config(CONFIG_DATA['controllers']) measures = CONFIG_DATA['measures'] groups = rearrange_config(CONFIG_DATA['groups']) logging.info(controllers) client = TBDeviceMqttClient(THINGSBOARD_SERVER, username=ACCESS_TOKEN, rate_limit="10:1,60:60,") client.connect() client.request_attributes( shared_keys=['blinkingPeriod'], callback=sync_state) # now attribute_callback will process shared attribute request from server sub_id_1 = client.subscribe_to_attribute( "blinkingPeriod", attribute_callback) sub_id_2 = client.subscribe_to_all_attributes(attribute_callback) # now rpc_callback will process rpc requests from server client.set_server_side_rpc_request_handler(rpc_callback) while not client.stopped: attributes, telemetry = get_data(controllers=controllers, measures=measures, groups=groups) client.send_attributes(attributes) client.send_telemetry({"ts": int(round(time.time() * 1000)), "values": telemetry}) time.sleep(60) if __name__ == '__main__': main()