import json import logging import mqtt import nagios import time try: from config import APP_NAME as ROOT_LOGGER_NAME except ImportError: ROOT_LOGGER_NAME = 'root' logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) class base(object): FOLLOW_REQUEST_WARNING = 5 # Seconds, till warning comes up, if device does not follow the command FOLLOW_REQUEST_ERROR = 60 # Seconds, till error comes up, if device does not follow the command FOLLOW_KEYS = ["current_heating_setpoint", ] # BATTERY_LVL_WARNING = 10 BATTERY_LVL_ERROR = 5 def __init__(self, mqtt_client: mqtt.mqtt_client, topic): self.topic = topic # mqtt_client.add_callback(topic, self.__rx__) mqtt_client.add_callback(topic + '/#', self.__rx__) # self.__target_storage__ = {} self.__state_storage__ = {} # self.battery = None def __rx__(self, client, userdata, message): pass def target(self, key, value): tm_t, value_t = self.__target_storage__.get(key, (0, None)) if value != value_t: self.__target_storage__[key] = time.time(), value logger.debug("Target value for device identified: %s: %s", key, repr(value)) def state(self, key, value): self.__state_storage__[key] = time.time(), value logger.debug("Device state identified: %s: %s", key, repr(value)) def status(self, key): # # FOLLOW SETPOINT # if key in self.FOLLOW_KEYS: tm_s, value_s = self.__state_storage__.get(key, (0, None)) try: tm_t, value_t = self.__target_storage__[key] except KeyError: if value_s is not None: return {"status": nagios.Nagios.WARNING, "msg": "Current temperature setpoint %.1f°C (age=%.1fs), but never received a setpoint" % (value_s, time.time()-tm_s)} return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no data received or unknown monitoring"} else: tm = time.time() dt = tm - tm_t if value_t != value_s and dt > self.FOLLOW_REQUEST_ERROR: return {"status": nagios.Nagios.ERROR, "msg": "Requested setpoint unequal valve setpoint since %.1f°C (age=%.1fs)" % (value_s, time.time()-tm_s)} elif value_t != value_s and dt > self.FOLLOW_REQUEST_WARNING: return {"status": nagios.Nagios.WARNING, "msg": "Requested setpoint unequal valve setpoint since %.1f°C (age=%.1fs)" % (value_s, time.time()-tm_s)} return {"status": nagios.Nagios.OK, "msg": "Requested setpoint equal valve setpoint %.1f°C (age=%.1fs)" % (value_s, time.time()-tm_s)} # # BATTERY # elif key == "battery": if self.battery is None: return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no data received or unknown monitoring"} elif self.battery < self.BATTERY_LVL_ERROR: return {"status": nagios.Nagios.ERROR, "msg": "Battery level critical low (%.1f%%)" % self.battery} elif self.battery < self.BATTERY_LVL_WARNING: return {"status": nagios.Nagios.WARNING, "msg": "Battery level low (%.1f%%)" % self.battery} else: return {"status": nagios.Nagios.OK, "msg": "Battery okay (%.1f%%)" % self.battery} class group(object): def __init__(self, *args, **kwargs): pass class shelly_sw1(base): pass class tradfri_sw(base): pass class tradfri_sw_br(base): pass class tradfri_sw_br_ct(base): pass class tradfri_button(base): pass class livarno_sw_br_ct(base): pass class brennenstuhl_heatingvalve(base): def __init__(self, mqtt_client: mqtt.mqtt_client, topic): base.__init__(self, mqtt_client, topic) def __rx__(self, client, userdata, message): payload = json.loads(message.payload) if "current_heating_setpoint" in payload: if message.topic == self.topic + '/set': self.target("current_heating_setpoint", payload["current_heating_setpoint"]) if message.topic == self.topic: self.state("current_heating_setpoint", payload["current_heating_setpoint"]) if "battery" in payload and message.topic == self.topic: self.battery = payload["battery"] class silvercrest_powerplug(base): pass class silvercrest_motion_sensor(base): pass class my_powerplug(base): pass class audio_status(base): pass class remote(base): pass