From 855e7d3eecbcc938587c5f4657770acdc95fe5ff Mon Sep 17 00:00:00 2001 From: John Pickup Date: Thu, 22 Jun 2023 07:28:35 +0100 Subject: [PATCH] Add a mutex to the display and refresh more often --- config.py | 2 +- lib/ovenDisplay.py | 109 +++++++++++++++++++++++---------------------- 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/config.py b/config.py index da3f458..80b89e9 100644 --- a/config.py +++ b/config.py @@ -127,7 +127,7 @@ time_scale_profile = "m" # s = Seconds | m = Minutes | h = Hours - Enter and vi # means your kiln receives full power until your house burns down. # this should not replace you watching your kiln or use of a kiln-sitter #emergency_shutoff_temp = 2264 #cone 7 -emergency_shutoff_temp = 1300 # TODO: check if the change of temp scale also changes interpretation of these constants +emergency_shutoff_temp = 1400 # If the current temperature is outside the pid control window, # delay the schedule until it does back inside. This allows for heating diff --git a/lib/ovenDisplay.py b/lib/ovenDisplay.py index f2efef2..bc97e37 100644 --- a/lib/ovenDisplay.py +++ b/lib/ovenDisplay.py @@ -28,16 +28,18 @@ class OvenDisplay(threading.Thread): self.profiles = None self.profile = None threading.Thread.__init__(self) + self.display_lock = threading.Lock() self.daemon = True # oven setup self.oven = oven self.ovenWatcher = ovenWatcher ovenWatcher.add_observer(self) self.sleep_time = sleepTime - draw.rectangle((0, 0, width, height), (0, 0, 0)) - self.text("Initialising...", (25, 25), fnt25, (255,255,255)) - displayhatmini.display() - displayhatmini.set_led(0.0, 0.0, 0.0) + with self.display_lock: + draw.rectangle((0, 0, width, height), (0, 0, 0)) + self.text("Initialising...", (25, 25), fnt25, (255,255,255)) + displayhatmini.display() + displayhatmini.set_led(0.0, 0.0, 0.0) self.start() def run(self): @@ -54,6 +56,7 @@ class OvenDisplay(threading.Thread): self.prev_profile() if (b_pressed): self.next_profile() + self.update_display(self.oven.get_state()) time.sleep(self.sleep_time) def update_profiles(self, new_profiles): @@ -65,58 +68,62 @@ class OvenDisplay(threading.Thread): # {'cost': 0, 'runtime': 0, 'temperature': 23.176953125, 'target': 0, 'state': 'IDLE', 'heat': 0, 'totaltime': 0, 'kwh_rate': 0.33631, 'currency_type': '£', 'profile': None, 'pidstats': {}} # {'cost': 0.003923616666666667, 'runtime': 0.003829, 'temperature': 23.24140625, 'target': 100.00079770833334, 'state': 'RUNNING', 'heat': 1.0, 'totaltime': 3600, 'kwh_rate': 0.33631, 'currency_type': '£', 'profile': 'test-200-250', 'pidstats': {'time': 1686902305.0, 'timeDelta': 5.027144, 'setpoint': 100.00079770833334, 'ispoint': 23.253125, 'err': 76.74767270833334, 'errDelta': 0, 'p': 1918.6918177083335, 'i': 0, 'd': 0, 'kp': 25, 'ki': 10, 'kd': 200, 'pid': 0, 'out': 1}} def update_display(self, oven_state): - draw.rectangle((0, 0, width, height), (0, 0, 0)) - log.info(oven_state) - if (oven_state['temperature'] is not None): - self.text("{0:2.0f}°C".format(oven_state['temperature']), (10, 10), fnt75, (255, 255, 255)) - else: - self.text("---°C", (10, 10), fnt75, (255, 255, 255)) - - if (oven_state['target'] is not None): - self.text("Target: {0:2.0f}°C".format(oven_state['target']), (10, 90), fnt25, (255, 255, 255)) - else: - self.text("Target: ---°C", (10, 90), fnt25, (255, 255, 255)) - - - if (oven_state['profile'] is not None): - active_profile_name = oven_state['profile'] - else: - if (self.profile is not None): - active_profile_name = self.profile['name'] + with self.display_lock: + draw.rectangle((0, 0, width, height), (0, 0, 0)) + # TODO - remove this - will use up too much disk + log.info(oven_state) + if (oven_state['temperature'] is not None): + self.text("{0:2.0f}°C".format(oven_state['temperature']), (10, 10), fnt75, (255, 255, 255)) else: - active_profile_name = 'No Programme' + self.text("---°C", (10, 10), fnt75, (255, 255, 255)) - self.text(active_profile_name, (10, 125), fnt25, (255, 255, 255)) + if (oven_state['target'] is not None): + self.text("Target: {0:2.0f}°C".format(oven_state['target']), (10, 90), fnt25, (255, 255, 255)) + else: + self.text("Target: ---°C", (10, 90), fnt25, (255, 255, 255)) - if (oven_state['state'] is None): - self.text("Initialising", (10, 10), fnt25, (255, 255, 255)) - displayhatmini.set_led(0.0, 0.0, 0.0) - else: - self.text(oven_state['state'], (10, 160), fnt25, (255, 255, 255)) - if (oven_state['state'] == 'IDLE'): - if (self.profile is None): - # no light indicates we can't start a programme - displayhatmini.set_led(0.0, 0.0, 0.0) + + if (oven_state['profile'] is not None): + active_profile_name = oven_state['profile'] + else: + if (self.profile is not None): + active_profile_name = self.profile['name'] else: - # green light indicates we can start a programme - displayhatmini.set_led(0.0, 0.5, 0.0) + active_profile_name = 'No Programme' + + self.text(active_profile_name, (10, 125), fnt25, (100, 255, 255)) + + if (oven_state['state'] is None): + self.text("Initialising", (10, 10), fnt25, (255, 255, 255)) + displayhatmini.set_led(0.0, 0.0, 0.0) else: self.text(oven_state['state'], (10, 160), fnt25, (255, 255, 255)) - if (oven_state['heat'] == 1.0): - displayhatmini.set_led(1.0, 0.0, 0.0) + if (oven_state['state'] == 'IDLE'): + if (self.profile is None): + # no light indicates we can't start a programme + displayhatmini.set_led(0.0, 0.0, 0.0) + else: + # green light indicates we can start a programme + displayhatmini.set_led(0.0, 0.5, 0.0) else: - displayhatmini.set_led(0.0, 0.0, 1.0) - message = '' - if (oven_state['totaltime'] is not None and oven_state['runtime'] is not None): - total_time = oven_state['totaltime'] - run_time = oven_state['runtime'] - time_left = total_time - run_time - time_left_str = str(datetime.timedelta(seconds=round(time_left))) - message = 'Remaining: ' + time_left_str; - if (oven_state['status'] is not None and oven_state['status'] != ""): - message = oven_state['status'] - self.text(message, (10, 195), fnt25, (255, 255, 255)) - displayhatmini.display() + self.text(oven_state['state'], (10, 160), fnt25, (255, 255, 255)) + if (oven_state['heat'] == 1.0): + displayhatmini.set_led(1.0, 0.0, 0.0) + else: + displayhatmini.set_led(0.0, 0.0, 1.0) + message = '' + message_colour = (0,255,255) + if (oven_state['totaltime'] is not None and oven_state['runtime'] is not None): + total_time = oven_state['totaltime'] + run_time = oven_state['runtime'] + time_left = total_time - run_time + time_left_str = str(datetime.timedelta(seconds=round(time_left))) + message = 'Remaining: ' + time_left_str; + if (oven_state['status'] is not None and oven_state['status'] != ""): + message = oven_state['status'] + message_colour = (255,0,0) + self.text(message, (10, 195), fnt25, message_colour) + displayhatmini.display() def send(self,oven_state_json): #log.info(oven_state_json) @@ -129,7 +136,6 @@ class OvenDisplay(threading.Thread): def stop_oven(self): log.info("Aborting run") self.oven.abort_run() - self.update_display(self.oven.get_state()) def start_oven(self): if (self.profile is None): @@ -139,21 +145,18 @@ class OvenDisplay(threading.Thread): profile_json = json.dumps(self.profile) oven_profile = Profile(profile_json) self.oven.run_profile(oven_profile) - self.update_display(self.oven.get_state()) def prev_profile(self): log.info("Prev profile") idx = self.find_profile_idx() new_idx = (idx - 1) % len(self.profiles) self.profile = self.profiles[new_idx] - self.update_display(self.oven.get_state()) def next_profile(self): log.info("Next profile") idx = self.find_profile_idx() new_idx = (idx + 1) % len(self.profiles) self.profile = self.profiles[new_idx] - self.update_display(self.oven.get_state()) def find_profile_idx(self): for idx, p in enumerate(self.profiles):