from threading import Event from loguru import logger from MqttBase import AbstractMqttPublisher import json import datetime def floatAdaptor(i): return float(f"{i:0.2f}") if i else 0.0 def onOffAdaptor(i): return bool(i) class FromDevices(AbstractMqttPublisher): def __init__(self, config, modbusHandler): super().__init__(config) self.modbusHandler = modbusHandler def localLoop(self): cnt = 0 while not self.killBill: cnt += 1 for device in self.config.output: try: payload = {} payload['status'] = "Error" payload['timestamp'] = datetime.datetime.isoformat(datetime.datetime.utcnow()) logger.debug(f"{device.name=} {device.publish_topic=}") if not device.enabled: logger.debug(f" device disabled, skipping") continue if cnt % device.scan_rate != 0: logger.debug(f" not scan_rate yet, skipping") continue for registers in device.registers: logger.debug(f" {registers.name=} {registers.address=} {registers.register_type=}") rawValue = self.modbusHandler.readRegister(registers.register_type, device.slave_id, registers.address, registers.data_type) logger.debug(f" {rawValue=}") if registers.adaptor == "floatAdaptor": value = floatAdaptor(rawValue) elif registers.adaptor == "onOffAdaptor": value = onOffAdaptor(rawValue) else: value = rawValue logger.debug(f" {value=}") payload[registers.attribute] = value payload['status'] = "Ok" except Exception as e: logger.error(f"Caught exception: {str(e)}") payload['cnt'] = cnt payloadStr = json.dumps(payload) self.client.publish(device.publish_topic, payloadStr) logger.debug(f"mqtt message sent: {device.publish_topic} -> {payloadStr}") self.killEvent.wait(timeout=float(self.config.global_.scan_interval))