From 3688c95cbfc2135a08ddfa1236f5f78ed6004f98 Mon Sep 17 00:00:00 2001 From: Thomas Klaehn Date: Wed, 30 Mar 2022 12:01:05 +0200 Subject: [PATCH] Fix: prevent multiple objects of heat in case of config reload --- control/_Control.py | 11 ++++++----- heat/_Heat.py | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/control/_Control.py b/control/_Control.py index 72574bf..ad5b6ba 100644 --- a/control/_Control.py +++ b/control/_Control.py @@ -14,7 +14,7 @@ import heat class Control(threading.Thread): def __init__(self, configfile): - super(Control, self).__init__() + threading.Thread.__init__(self) self.__run_condition = True self.__config_file = configfile self.__config = None @@ -26,6 +26,7 @@ class Control(threading.Thread): self.__temperature = None def reload_config(self): + self.__log.info("Reloading configuration triggered") self.__trigger_read_config = True def load_config(self): @@ -38,6 +39,8 @@ class Control(threading.Thread): shutil.copyfile("config/config.json", self.__config_file) with open(self.__config_file, "r", encoding="UTF-8") as handle: self.__config = json.load(handle) + if self.__heat is not None: + self.__heat.stop() self.__heat = heat.Heat(int(self.__config['heat'][0]['pin'])) for _ in range(len(self.__config['water'])): self.__water_state.append(False) @@ -50,15 +53,13 @@ class Control(threading.Thread): GPIO.output(pin, 1) def run(self): - self.load_config() - self.__heat.off() - self.__heat.start() while self.__run_condition: if self.__trigger_read_config: self.__trigger_read_config = False self.load_config() + self.__heat.start() - tmp = float(self.__sensor.get_temperature()) + tmp = round(float(self.__sensor.get_temperature()), 1) if tmp != self.__temperature: self.__temperature = tmp self.__log.info("Temperature: %.1f °C", self.__temperature) diff --git a/heat/_Heat.py b/heat/_Heat.py index 44f0207..6f61f0e 100644 --- a/heat/_Heat.py +++ b/heat/_Heat.py @@ -1,5 +1,6 @@ import datetime +import logging import threading import time @@ -7,26 +8,31 @@ import RPi.GPIO as GPIO class Heat(threading.Thread): def __init__(self, pin): - super(Heat, self).__init__() + threading.Thread.__init__(self) self.__pin = pin self.__state = False + self.__lock = threading.Lock() GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(pin, GPIO.OUT) - if GPIO.input(pin): + if not GPIO.input(pin): self.__state = True self.__run_condition = True self.__next_update = datetime.datetime.now() def on(self): - self.__state = True - GPIO.output(self.__pin, 0) + """Switch the heat on""" + with self.__lock: + self.__state = True + GPIO.output(self.__pin, 0) def off(self): - self.__state = False - GPIO.output(self.__pin, 1) + """Switch the heat off""" + with self.__lock: + self.__state = False + GPIO.output(self.__pin, 1) def run(self): self.__next_update = datetime.datetime.now() @@ -43,8 +49,10 @@ class Heat(threading.Thread): self.off() def stop(self): + """Stop the controlling thead""" self.__run_condition = False self.join() def state(self): + """Return the state of the heat""" return self.__state