Exemplo n.º 1
0
class Exterior(object):
    def __init__(self, mqttConfig, on_update, logFile):
        self.temperature = None
        self.topic = "therminator/in/exterior_temperature"
        self.connect(mqttConfig, logFile)
        self.on_update = on_update

    def on_message(self, client, userdata, message):
        if message.topic == self.topic:
            if self.temperature != float(message.payload):
                self.temperature = float(message.payload)
                self.update()

    def requestValues(self):
        topic = "therminator/request"
        requestMessage = "\"exterior_temperature\""
        self.client.publish(topic, requestMessage)

    def connect(self, mqttConfig, logFile):
        self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"],
                                   logFile)
        topics = [(self.topic, 1)]
        self.client.subscribe(self, topics)
        self.requestValues()

    def getTemperature(self):
        return self.temperature

    def update(self):
        self.on_update()
Exemplo n.º 2
0
 def __init__(self, moduleType, dependencies, mqttConfig, logFile):
     logging.basicConfig(filename=logFile, level=logging.DEBUG)
     self.moduleType = moduleType
     self.dependencies = dependencies
     self.brokenDependencies = []
     self.unconfirmedDependencies = dependencies
     self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"], logFile)
     self.heartbeatTopic = "therminator/heartbeat"
     self.client.subscribe(self, [(self.heartbeatTopic,2)])
     self.responseTimeout = 20
     self.heartbeatInterval = 60
     self.onDependenciesComplete = None
     self.heartbeatThread = threading.Thread(target=self.heartbeatLoop, daemon=True)
     self.heartbeatThread.start()
Exemplo n.º 3
0
class Home(object):
    def __init__(self, mqttConfig, on_update, logFile):
        logging.basicConfig(filename=logFile, level=logging.DEBUG)
        self.away = False
        self.mode = None
        self.topicAway = "therminator/in/away"
        self.topicMode = "therminator/in/mode"
        self.connect(mqttConfig, logFile)
        self.on_update = on_update

    def on_message(self, client, userdata, message):
        if message.topic == self.topicAway:
            if self.away != int(message.payload):
                self.away = int(message.payload)
                self.update()
        if message.topic == self.topicMode:
            logging.debug("Received mode '{:}'".format(
                str(message.payload, 'utf-8')))
            if self.mode != str(message.payload, 'utf-8'):
                logging.debug("Switching to mode '{:}'".format(
                    str(message.payload, 'utf-8')))
                self.mode = str(message.payload, 'utf-8')
                self.update()

    def requestValues(self):
        topic = "therminator/request"
        requestMessageAway = "\"away\""
        requestMessageMode = "\"mode\""
        self.client.publish(topic, requestMessageAway)
        self.client.publish(topic, requestMessageMode)

    def connect(self, mqttConfig, logFile):
        self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"],
                                   logFile)
        topics = [(self.topicAway, 1), (self.topicMode, 1)]
        self.client.subscribe(self, topics)
        self.requestValues()

    def isAway(self):
        return self.away

    def update(self):
        self.on_update()

    def getMode(self):
        return self.mode
Exemplo n.º 4
0
 def __init__(self, name, config):
     logFile = '/var/log/thermostat.log'
     logging.basicConfig(filename=logFile, level=logging.DEBUG)
     logging.debug("Loading radiator heating interface '{:}'".format(name));
     self.address  = config["address"]
     self.port = config["port"]
     self.name = name
     if "username" in config.keys() and "password" in config.keys():
         self.username = config["username"]
         self.password = config["password"]
     else:
         self.username = None
         self.password = None
     self.temperature = None
     self.setpoint = None
     self.enabled = False
     self.client = MqttProvider(self.address, self.port, logFile)
     self.connect()
Exemplo n.º 5
0
class MQTTBoilerInterface(BoilerInterface):
    def __init__(self, configFilename):
        config = None
        with open(configFilename) as f:
            config = json.load(f)
        logging.debug(config)
        self.address = config["address"]
        self.port = config["port"]
        if "username" in config.keys() and "password" in config.keys():
            self.username = config["username"]
            self.password = config["password"]
        else:
            self.username = None
            self.password = None
        self.returnTemperature = 0
        self.waterTemperature = 0
        self.gain = config["gain"]
        pidParmaeters = config["pid"]
        self.PID = PID(pidParmaeters["p"], pidParmaeters["i"],
                       pidParmaeters["d"], pidParmaeters["errorSumLimit"],
                       pidParmaeters["historyRange"])
        logFile = "/var/log/thermostat.log"
        self.client = MqttProvider(self.address, self.port, logFile)

    def setOutput(self, outputValue):
        outputValue *= self.gain
        outputValue = min(100, max(0, outputValue))
        self.client.publish("therminator/out/boiler_output", outputValue)

    def setMode(self, mode):
        logging.debug("Switching to mode '{:}'".format(mode))
        self.client.publish("therminator/out/mode", mode)
        self.client.publish("therminator/in/mode", mode)
Exemplo n.º 6
0
 def __init__(self, configFilename):
     config = None
     with open(configFilename) as f:
         config = json.load(f)
     logging.debug(config)
     self.address = config["address"]
     self.port = config["port"]
     if "username" in config.keys() and "password" in config.keys():
         self.username = config["username"]
         self.password = config["password"]
     else:
         self.username = None
         self.password = None
     self.returnTemperature = 0
     self.waterTemperature = 0
     self.gain = config["gain"]
     pidParmaeters = config["pid"]
     self.PID = PID(pidParmaeters["p"], pidParmaeters["i"],
                    pidParmaeters["d"], pidParmaeters["errorSumLimit"],
                    pidParmaeters["historyRange"])
     logFile = "/var/log/thermostat.log"
     self.client = MqttProvider(self.address, self.port, logFile)
Exemplo n.º 7
0
 def __init__(self, configFilename):
     logFile = "/var/log/setpoint_monitor.log"
     logging.basicConfig(filename=logFile, level=logging.DEBUG)
     logging.debug("{:} Loading setpoint monitor".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
     mqtt = {}
     self.setup = {}
     self.zones = []
     with open(configFilename) as f:
         config = json.load(f)
         with open(config["mqtt"]["configFile"]) as f2:
             mqtt = json.load(f2)
         with open(config["setup"]["configFile"]) as f2:
             self.setup = json.load(f2)
     self.mqtt = MqttProvider(mqtt["address"], mqtt["port"], logFile)
     self.firstContact = True
     self.watchdog = Watchdog(Modules.MONITOR, [Modules.CONNECTOR], mqtt, logFile)
     self.watchdog.onDependenciesComplete = self.onDependenciesComplete
     signal.pause()
Exemplo n.º 8
0
 def __init__(self, config, logFilename, syslog):
     print("Logging to {:}".format(syslog))
     logging.basicConfig(filename=syslog, level=logging.DEBUG)
     self.zones = []
     self.boiler = None
     self.lock = False
     self.fullUpdate = True
     self.mode = None
     self.fontPath = "/usr/local/share/fonts/VoiceActivatedBB_reg.otf"
     self.boldFontPath = "/usr/local/share/fonts/VoiceActivatedBB_bold.otf"
     self.logFile = logFilename
     self.awayFontSize = 1
     self.delayedUpdateTimer = None
     self.setup, self.mqtt, self.fullUpdateInterval = self.loadConfig(config)
     self.client = MqttProvider(self.mqtt["address"], self.mqtt["port"], syslog)
     self.away = False
     self.firstContact = True
     self.watchdog = Watchdog(Modules.DISPLAY, [Modules.CONNECTOR, Modules.MONITOR, Modules.THERMOSTAT], self.mqtt, syslog)
     self.watchdog.onDependenciesComplete = self.onDependenciesComplete
Exemplo n.º 9
0
class Watchdog(threading.Thread):

    def __init__(self, moduleType, dependencies, mqttConfig, logFile):
        logging.basicConfig(filename=logFile, level=logging.DEBUG)
        self.moduleType = moduleType
        self.dependencies = dependencies
        self.brokenDependencies = []
        self.unconfirmedDependencies = dependencies
        self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"], logFile)
        self.heartbeatTopic = "therminator/heartbeat"
        self.client.subscribe(self, [(self.heartbeatTopic,2)])
        self.responseTimeout = 20
        self.heartbeatInterval = 60
        self.onDependenciesComplete = None
        self.heartbeatThread = threading.Thread(target=self.heartbeatLoop, daemon=True)
        self.heartbeatThread.start()

    def heartbeatLoop(self):
        while(True):
            self.requestPulse()
            time.sleep(self.heartbeatInterval - self.responseTimeout)

    def on_message(self, client, userdata, message):
        if message.topic == self.heartbeatTopic:
            payload = str(message.payload, "utf-8")
            if payload == "ping":
                self.client.publish(self.heartbeatTopic, self.moduleType)
            elif payload in self.unconfirmedDependencies:
                self.unconfirmedDependencies.remove(payload)
                if len(self.unconfirmedDependencies) == 0:
                    self.onDependenciesComplete()

    def requestPulse(self):
        self.brokenDependencies = []
        self.unconfirmedDependencies = self.dependencies
        self.client.publish(self.heartbeatTopic, "ping")
        time.sleep(self.responseTimeout)
        if len(self.unconfirmedDependencies) > 0:
            self.brokenDependencies = self.unconfirmedDependencies
            self.error = "{:} : Failed response from following depedencies {:} for module {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.moduleType, self.brokenDependencies)
            logging.error(self.error)
Exemplo n.º 10
0
 def connect(self, mqttConfig, logFile):
     self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"],
                                logFile)
     topics = [(self.topic, 1)]
     self.client.subscribe(self, topics)
     self.requestValues()
Exemplo n.º 11
0
 def connect(self, mqttConfig, logFile):
     self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"],
                                logFile)
     topics = [(self.topicReq, 1), (self.topicDel, 1), (self.topicRet, 1),
               (self.topicFlow, 1)]
     self.client.subscribe(self, topics)
Exemplo n.º 12
0
class Boiler(object):
    def __init__(self, mqttConfig, on_update, logFile):
        self.requestedPower = 0
        self.deliveredPower = 0
        self.returnTemperature = 0
        self.flowTemperature = 0
        self.topicReq = "therminator/out/boiler_output"
        self.topicDel = "therminator/in/boiler_output"
        self.topicRet = "therminator/in/return_temperature"
        self.topicFlow = "therminator/in/flow_temperature"
        self.connect(mqttConfig, logFile)
        self.on_update = on_update

    def on_message(self, client, userdata, message):
        if message.topic == self.topicReq:
            if self.requestedPower != float(message.payload):
                self.requestedPower = float(message.payload)
                self.update()
        elif message.topic == self.topicDel:
            if self.deliveredPower != float(message.payload):
                self.deliveredPower = float(message.payload)
                self.update()
        if message.topic == self.topicRet:
            if self.returnTemperature != float(message.payload):
                self.returnTemperature = float(message.payload)
        elif message.topic == self.topicFlow:
            if self.flowTemperature != float(message.payload):
                self.flowTemperature = float(message.payload)

    def requestValues(self):
        topic = "therminator/request"
        requestMessageTemp = "\"{:}_temperature\"".format(self.name)
        requestMessageSP = "\"{:}_setpoint\"".format(self.name)
        requestMessageRet = "\"{:}_temperature\"".format(self.name)
        requestMessageFlow = "\"{:}_setpoint\"".format(self.name)
        self.client.publish(topic, requestMessageTemp)
        self.client.publish(topic, requestMessageSP)
        self.client.publish(topic, requestMessageRet)
        self.client.publish(topic, requestMessageFlow)

    def connect(self, mqttConfig, logFile):
        self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"],
                                   logFile)
        topics = [(self.topicReq, 1), (self.topicDel, 1), (self.topicRet, 1),
                  (self.topicFlow, 1)]
        self.client.subscribe(self, topics)

    def getRequestedPower(self):
        return self.requestedPower

    def getDeliveredPower(self):
        return self.deliveredPower

    def getReturnTemperature(self):
        return self.returnTemperature

    def getFlowTemperature(self):
        return self.flowTemperature

    def update(self):
        self.on_update()
Exemplo n.º 13
0
 def connect(self, mqttConfig, logFile):
     self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"],
                                logFile)
Exemplo n.º 14
0
class RadiatorHeatingInterface(HeatingInterface):
    def __init__(self, name, config):
        logFile = '/var/log/thermostat.log'
        logging.basicConfig(filename=logFile, level=logging.DEBUG)
        logging.debug("Loading radiator heating interface '{:}'".format(name));
        self.address  = config["address"]
        self.port = config["port"]
        self.name = name
        if "username" in config.keys() and "password" in config.keys():
            self.username = config["username"]
            self.password = config["password"]
        else:
            self.username = None
            self.password = None
        self.temperature = None
        self.setpoint = None
        self.enabled = False
        self.client = MqttProvider(self.address, self.port, logFile)
        self.connect()

    def getTemperature(self):
        return self.temperature

    def getSetpoint(self):
        return self.setpoint

    def getEnabled(self):
        return self.enabled

    def setSetpoint(self, setpoint):
        if self.setpoint != setpoint:
            self.client.publish("therminator/out/{:}_setpoint".format(self.name), setpoint)
            self.setpoint = setpoint

    def setOutput(self, outputValue):
        pass

    def on_message(self, client, userdata, message):
        try:
            if message.topic == self.topic_temp:
                logging.debug("{:} : Received message {:} on topic {:}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message.topic, message.payload))
                self.temperature = float(message.payload)
            elif message.topic == self.topic_sp:
                logging.debug("{:} : Received message {:} on topic {:}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message.topic, message.payload))
                self.setpoint = float(message.payload)
            elif message.topic == self.topic_enabled:
                logging.debug("{:} : Received message {:} on topic {:}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message.topic, message.payload))
                self.enabled = int(message.payload)
        except Exception as e:
            logging.error("{:} : Error {:}".format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), e))

    def requestValues(self):
        topic = "therminator/request"
        requestMessageTemp = "\"{:}_temperature\"".format(self.name)
        requestMessageEnabled = "\"{:}_enabled\"".format(self.name)
        requestMessageSP = "\"{:}_setpoint\"".format(self.name)
        self.client.publish(topic, requestMessageTemp)
        self.client.publish(topic, requestMessageEnabled)
        self.client.publish(topic, requestMessageSP)

    def connect(self):
        self.topic_temp = "therminator/in/{:}_temperature".format(self.name)
        self.topic_enabled = "therminator/in/{:}_enabled".format(self.name)
        self.topic_sp = "therminator/in/{:}_setpoint".format(self.name)
        topics = [(self.topic_temp, 2), (self.topic_sp, 2), (self.topic_enabled, 2)]
        self.client.subscribe(self, topics)
        self.requestValues()
Exemplo n.º 15
0
 def connect(self, mqttConfig, logFile):
     self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"], logFile)
     topics = [(self.topicTemp, 2), (self.topicSP, 2), (self.topicLvl, 2), (self.topicEnabled, 2), (self.topicBattery, 2)]
     self.client.subscribe(self, topics)
     self.requestValues()
Exemplo n.º 16
0
class Zone(object):
    def __init__(self, config, mqttConfig, on_update, logFile):
        logging.basicConfig(filename=logFile, level=logging.DEBUG)
        self.offTemperature = 10
        self.offDelay = 10
        self.temperature = None
        self.setpoint = None
        self.level = None
        self.enabled = True
        self.battery = None
        self.name = config["id"]
        self.label = config["label"]
        self.topicTemp = "therminator/in/{:}_temperature".format(self.name)
        self.topicSP = "therminator/in/{:}_setpoint".format(self.name)
        self.topicLvl = "therminator/in/{:}_level".format(self.name)
        self.topicEnabled = "therminator/in/{:}_enabled".format(self.name)
        self.topicBattery = "therminator/in/{:}_battery".format(self.name)
        self.icon = config["icon"]
        self.connect(mqttConfig, logFile)
        self.on_update = on_update
        self.tempEnabled = True
        self.enabledCheckThread = None

    def enabledCheck(self):
        logging.debug("Checking if {:} is enabled".format(self.name))
        if self.enabled != self.tempEnabled:
            logging.debug("{:} : Enabled status changed from  {:} to {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.enabled, self.tempEnabled))
            self.enabled = self.tempEnabled
            self.update()
        logging.debug("{:} : Checking {:} done".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.name))

    def on_message(self, client, userdata, message):
        changed = False
        if message.topic == self.topicTemp:
            if self.temperature != float(message.payload):
                self.temperature = float(message.payload)
                logging.debug("{:} : Temperature change detected {:}°C for {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.temperature, self.name))
                self.update()
        elif message.topic == self.topicSP:
            if self.setpoint != float(message.payload):
                self.setpoint = float(message.payload)
                logging.debug("{:} : Setpoint change detected {:}°C for {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.setpoint, self.name))
                self.update()
        elif message.topic == self.topicBattery:
            if self.battery != int(message.payload):
                self.battery = int(message.payload)
                logging.debug("{:} : Battery change detected {:}\% for {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.battery, self.name))
                self.update()
        elif message.topic == self.topicLvl:
            if self.level != float(message.payload):
                self.level = float(message.payload)
                logging.debug("{:} : Level change detected {:}\% for {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.level, self.name))
                #self.update()
        elif message.topic == self.topicEnabled:
            self.tempEnabled = int((message.payload))
            logging.debug("{:} : Status detected {:}\% for {:}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.tempEnabled, self.name))
            if self.enabledCheckThread:
                self.enabledCheckThread.cancel()
            self.enabledCheckThread = threading.Timer(self.offDelay, self.enabledCheck)
            self.enabledCheckThread.start()

    def requestValues(self):
        topic = "therminator/request"
        requestMessageTemp = "\"{:}_temperature\"".format(self.name)
        requestMessageSP = "\"{:}_setpoint\"".format(self.name)
        requestMessageLvl = "\"{:}_level\"".format(self.name)
        requestMessageEnabled = "\"{:}_enabled\"".format(self.name)
        self.client.publish(topic, requestMessageTemp)
        self.client.publish(topic, requestMessageSP)
        self.client.publish(topic, requestMessageLvl)
        self.client.publish(topic, requestMessageEnabled)

    def connect(self, mqttConfig, logFile):
        self.client = MqttProvider(mqttConfig["address"], mqttConfig["port"], logFile)
        topics = [(self.topicTemp, 2), (self.topicSP, 2), (self.topicLvl, 2), (self.topicEnabled, 2), (self.topicBattery, 2)]
        self.client.subscribe(self, topics)
        self.requestValues()

    def getTemperature(self):
        return self.temperature

    def getSetpoint(self):
        return self.setpoint

    def getBattery(self):
        return self.battery

    def getName(self):
        return self.name

    def getLabel(self):
        return self.label

    def isEnabled(self):
        return self.enabled

    def update(self):
        self.on_update()

    def getLevel(self):
        return self.level