Fix: prevent multiple objects of heat in case of config reload

This commit is contained in:
Thomas Klaehn 2022-03-30 12:01:05 +02:00
parent b5db8b943d
commit 3688c95cbf
2 changed files with 20 additions and 11 deletions

View File

@ -14,7 +14,7 @@ import heat
class Control(threading.Thread): class Control(threading.Thread):
def __init__(self, configfile): def __init__(self, configfile):
super(Control, self).__init__() threading.Thread.__init__(self)
self.__run_condition = True self.__run_condition = True
self.__config_file = configfile self.__config_file = configfile
self.__config = None self.__config = None
@ -26,6 +26,7 @@ class Control(threading.Thread):
self.__temperature = None self.__temperature = None
def reload_config(self): def reload_config(self):
self.__log.info("Reloading configuration triggered")
self.__trigger_read_config = True self.__trigger_read_config = True
def load_config(self): def load_config(self):
@ -38,6 +39,8 @@ class Control(threading.Thread):
shutil.copyfile("config/config.json", self.__config_file) shutil.copyfile("config/config.json", self.__config_file)
with open(self.__config_file, "r", encoding="UTF-8") as handle: with open(self.__config_file, "r", encoding="UTF-8") as handle:
self.__config = json.load(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'])) self.__heat = heat.Heat(int(self.__config['heat'][0]['pin']))
for _ in range(len(self.__config['water'])): for _ in range(len(self.__config['water'])):
self.__water_state.append(False) self.__water_state.append(False)
@ -50,15 +53,13 @@ class Control(threading.Thread):
GPIO.output(pin, 1) GPIO.output(pin, 1)
def run(self): def run(self):
self.load_config()
self.__heat.off()
self.__heat.start()
while self.__run_condition: while self.__run_condition:
if self.__trigger_read_config: if self.__trigger_read_config:
self.__trigger_read_config = False self.__trigger_read_config = False
self.load_config() self.load_config()
self.__heat.start()
tmp = float(self.__sensor.get_temperature()) tmp = round(float(self.__sensor.get_temperature()), 1)
if tmp != self.__temperature: if tmp != self.__temperature:
self.__temperature = tmp self.__temperature = tmp
self.__log.info("Temperature: %.1f °C", self.__temperature) self.__log.info("Temperature: %.1f °C", self.__temperature)

View File

@ -1,5 +1,6 @@
import datetime import datetime
import logging
import threading import threading
import time import time
@ -7,26 +8,31 @@ import RPi.GPIO as GPIO
class Heat(threading.Thread): class Heat(threading.Thread):
def __init__(self, pin): def __init__(self, pin):
super(Heat, self).__init__() threading.Thread.__init__(self)
self.__pin = pin self.__pin = pin
self.__state = False self.__state = False
self.__lock = threading.Lock()
GPIO.setwarnings(False) GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT) GPIO.setup(pin, GPIO.OUT)
if GPIO.input(pin): if not GPIO.input(pin):
self.__state = True self.__state = True
self.__run_condition = True self.__run_condition = True
self.__next_update = datetime.datetime.now() self.__next_update = datetime.datetime.now()
def on(self): def on(self):
self.__state = True """Switch the heat on"""
GPIO.output(self.__pin, 0) with self.__lock:
self.__state = True
GPIO.output(self.__pin, 0)
def off(self): def off(self):
self.__state = False """Switch the heat off"""
GPIO.output(self.__pin, 1) with self.__lock:
self.__state = False
GPIO.output(self.__pin, 1)
def run(self): def run(self):
self.__next_update = datetime.datetime.now() self.__next_update = datetime.datetime.now()
@ -43,8 +49,10 @@ class Heat(threading.Thread):
self.off() self.off()
def stop(self): def stop(self):
"""Stop the controlling thead"""
self.__run_condition = False self.__run_condition = False
self.join() self.join()
def state(self): def state(self):
"""Return the state of the heat"""
return self.__state return self.__state