From f73636701cfb878e41377b05873d116cfbcd8308 Mon Sep 17 00:00:00 2001
From: marktilles <82381104+marktilles@users.noreply.github.com>
Date: Mon, 5 Jul 2021 22:20:46 +0200
Subject: [PATCH] Update
---
.DS_Store | Bin 6148 -> 0 bytes
lib/.DS_Store | Bin 6148 -> 0 bytes
lib/oven.py | 157 ++++++++++++++++++++++++++++++++++-------------
public/.DS_Store | Bin 6148 -> 0 bytes
4 files changed, 114 insertions(+), 43 deletions(-)
delete mode 100644 .DS_Store
delete mode 100644 lib/.DS_Store
delete mode 100644 public/.DS_Store
diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index a9211d2295a9c7dd5bf246bdd3793fb5f1c56103..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6148
zcmeHK%}&EG40g5woe*LN1RQhWw!`=pJ0Mj94&0E6-~b33Izgq
DmI@8jgyW^$$2V>g67CND$xpi
zE&P&5qy506n`hBoKpA{rAr=iL<=XcoC&?Wnyy5tKx6QI}NUMKgh$pm$ky~G4=Mt
z{7O0dKwso3^aoX;hjFtKP!W^48w@_3ho@e)#Zc85Q{Q8JTrBf+sZG=5B&+n&|Wr
zJrq3&9q55F8^4IMi$vjHr?e@^AO{Uy2;maiqoL6X6vDy`FaylMpJ%`wYTopp-wAJk
z8DIv!n*ll>Br2iru&`*34s1*bfJmQ_M$o2Of^wuo-(g`9M^J=KMYO5Hl^DXNqhGo>
z-(g|Vrh{K-%h`z(ZB6?8xL%`6$4Kwhg
G47>uVZ(Dr;
diff --git a/lib/.DS_Store b/lib/.DS_Store
deleted file mode 100644
index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6148
zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3
zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ
zLs35+`xjp>T0 (self.time_step * 2):
+ if self.bad_count + self.ok_count:
+ self.bad_percent = (self.bad_count / (self.bad_count + self.ok_count)) * 100
+ else:
+ self.bad_percent = 0
+ self.bad_count = 0
+ self.ok_count = 0
+ self.bad_stamp = time.time()
+
+ temp = self.thermocouple.get()
+ self.noConnection = self.thermocouple.noConnection
+ self.shortToGround = self.thermocouple.shortToGround
+ self.shortToVCC = self.thermocouple.shortToVCC
+ self.unknownError = self.thermocouple.unknownError
+
+ is_bad_value = self.noConnection | self.unknownError
+ if config.honour_theromocouple_short_errors:
+ is_bad_value |= self.shortToGround | self.shortToVCC
+
+ if not is_bad_value:
+ temps.append(temp)
+ if len(temps) > config.temperature_average_samples:
+ del temps[0]
+ self.ok_count += 1
+
+ else:
+ log.error("Problem reading temp N/C:%s GND:%s VCC:%s ???:%s" % (self.noConnection,self.shortToGround,self.shortToVCC,self.unknownError))
+ self.bad_count += 1
+
+ if len(temps):
+ self.temperature = sum(temps) / len(temps)
+ time.sleep(self.sleeptime)
class Oven(threading.Thread):
'''parent oven class. this has all the common code
@@ -155,8 +184,22 @@ class Oven(threading.Thread):
self.pid = PID(ki=config.pid_ki, kd=config.pid_kd, kp=config.pid_kp)
def run_profile(self, profile, startat=0):
- log.info("Running schedule %s" % profile.name)
self.reset()
+
+ if self.board.temp_sensor.noConnection:
+ log.info("Refusing to start profile - thermocouple not connected")
+ return
+ if self.board.temp_sensor.shortToGround:
+ log.info("Refusing to start profile - thermocouple short to ground")
+ return
+ if self.board.temp_sensor.shortToVCC:
+ log.info("Refusing to start profile - thermocouple short to VCC")
+ return
+ if self.board.temp_sensor.unknownError:
+ log.info("Refusing to start profile - thermocouple unknown error")
+ return
+
+ log.info("Running schedule %s" % profile.name)
self.profile = profile
self.totaltime = profile.get_duration()
self.state = "RUNNING"
@@ -186,6 +229,9 @@ class Oven(threading.Thread):
def update_runtime(self):
runtime_delta = datetime.datetime.now() - self.start_time
+ if runtime_delta.total_seconds() < 0:
+ runtime_delta = datetime.timedelta(0)
+
if self.startat > 0:
self.runtime = self.startat + runtime_delta.total_seconds()
else:
@@ -195,12 +241,24 @@ class Oven(threading.Thread):
self.target = self.profile.get_target_temperature(self.runtime)
def reset_if_emergency(self):
- '''reset if the temperature is way TOO HOT'''
+ '''reset if the temperature is way TOO HOT, or other critical errors detected'''
if (self.board.temp_sensor.temperature + config.thermocouple_offset >=
config.emergency_shutoff_temp):
log.info("emergency!!! temperature too high, shutting down")
self.reset()
+ if self.board.temp_sensor.noConnection:
+ log.info("emergency!!! lost connection to thermocouple, shutting down")
+ self.reset()
+
+ if self.board.temp_sensor.unknownError:
+ log.info("emergency!!! unknown thermocouple error, shutting down")
+ self.reset()
+
+ if self.board.temp_sensor.bad_percent > 30:
+ log.info("emergency!!! too many errors in a short period, shutting down")
+ self.reset()
+
def reset_if_schedule_ended(self):
if self.runtime > self.totaltime:
log.info("schedule ended, shutting down")
@@ -214,6 +272,8 @@ class Oven(threading.Thread):
'state': self.state,
'heat': self.heat,
'totaltime': self.totaltime,
+ 'kwh_rate': config.kwh_rate,
+ 'currency_type': config.currency_type,
'profile': self.profile.name if self.profile else None,
}
return state
@@ -249,10 +309,10 @@ class SimulatedOven(Oven):
# set temps to the temp of the surrounding environment
self.t = self.t_env # deg C temp of oven
self.t_h = self.t_env #deg C temp of heating element
-
+
# call parent init
Oven.__init__(self)
-
+
# start thread
self.start()
log.info("SimulatedOven started")
@@ -310,9 +370,9 @@ class SimulatedOven(Oven):
self.runtime,
self.totaltime,
time_left))
-
+
# we don't actually spend time heating & cooling during
- # a simulation, so sleep.
+ # a simulation, so sleep.
time.sleep(self.time_step)
@@ -329,6 +389,10 @@ class RealOven(Oven):
# start thread
self.start()
+ def reset(self):
+ super().reset()
+ self.output.cool(0)
+
def heat_then_cool(self):
pid = self.pid.compute(self.target,
self.board.temp_sensor.temperature +
@@ -341,8 +405,10 @@ class RealOven(Oven):
if heat_on > 0:
self.heat = 1.0
- self.output.heat(heat_on)
- self.output.cool(heat_off)
+ if heat_on:
+ self.output.heat(heat_on)
+ if heat_off:
+ self.output.cool(heat_off)
time_left = self.totaltime - self.runtime
log.info("temp=%.2f, target=%.2f, pid=%.3f, heat_on=%.2f, heat_off=%.2f, run_time=%d, total_time=%d, time_left=%d" %
(self.board.temp_sensor.temperature + config.thermocouple_offset,
@@ -400,7 +466,7 @@ class PID():
self.lastErr = 0
# FIX - this was using a really small window where the PID control
- # takes effect from -1 to 1. I changed this to various numbers and
+ # takes effect from -1 to 1. I changed this to various numbers and
# settled on -50 to 50 and then divide by 50 at the end. This results
# in a larger PID control window and much more accurate control...
# instead of what used to be binary on/off control.
@@ -413,8 +479,12 @@ class PID():
error = float(setpoint - ispoint)
if self.ki > 0:
- self.iterm += (error * timeDelta * (1/self.ki))
-
+ if config.stop_integral_windup == True:
+ if abs(self.kp * error) < window_size:
+ self.iterm += (error * timeDelta * (1/self.ki))
+ else:
+ self.iterm += (error * timeDelta * (1/self.ki))
+
dErr = (error - self.lastErr) / timeDelta
output = self.kp * error + self.iterm + self.kd * dErr
out4logs = output
@@ -426,15 +496,16 @@ class PID():
if output < 0:
output = 0
- #if output > 1:
- # output = 1
-
output = float(output / window_size)
- if out4logs > 0:
- log.info("pid percents pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs,
- ((self.kp * error)/out4logs)*100,
- (self.iterm/out4logs)*100,
- ((self.kd * dErr)/out4logs)*100))
+ if out4logs > 0:
+# log.info("pid percents pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs,
+# ((self.kp * error)/out4logs)*100,
+# (self.iterm/out4logs)*100,
+# ((self.kd * dErr)/out4logs)*100))
+ log.info("pid actuals pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs,
+ self.kp * error,
+ self.iterm,
+ self.kd * dErr))
return output
diff --git a/public/.DS_Store b/public/.DS_Store
deleted file mode 100644
index eba7a31ae9f14d044b5485778d28c257b6f7c216..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6148
zcmeHK%}T>S5Z-NTO%bsNQIC7^)Wnc96tPr;<`cnj)CDOS4kE;i8om#iP
zk!8(>*g4pnHbmAw+;528c6&OlS)1Ffqto8q!(;X|eSXora`*(5tQnlaD;R|>-n-*y
zD5G2O&vIt5gv0-&E(iF(8UG4Q7t;FXTsabQcPwk~WAYpnq7fudksu5q3MhAPDn
fi=}uAR0;S68i2OJTqAfu=tn@&Kn*eQqYQiiE_zZp