refactored restart code
This commit is contained in:
parent
4601d92eeb
commit
7f5b1396b6
@ -163,5 +163,3 @@ ignore_emergencies = False
|
|||||||
automatic_restarts = True
|
automatic_restarts = True
|
||||||
automatic_restart_window = 15 # max minutes since power outage
|
automatic_restart_window = 15 # max minutes since power outage
|
||||||
automatic_restart_state_file = "/home/jason/repos/kiln-controller/state/kiln_controller_state.json"
|
automatic_restart_state_file = "/home/jason/repos/kiln-controller/state/kiln_controller_state.json"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
79
lib/oven.py
79
lib/oven.py
@ -193,9 +193,6 @@ class Oven(threading.Thread):
|
|||||||
self.target = 0
|
self.target = 0
|
||||||
self.heat = 0
|
self.heat = 0
|
||||||
self.pid = PID(ki=config.pid_ki, kd=config.pid_kd, kp=config.pid_kp)
|
self.pid = PID(ki=config.pid_ki, kd=config.pid_kd, kp=config.pid_kp)
|
||||||
# for restarts, save the IDLE state to the state file
|
|
||||||
if config.automatic_restarts == True:
|
|
||||||
self.save_state()
|
|
||||||
|
|
||||||
def run_profile(self, profile, startat=0):
|
def run_profile(self, profile, startat=0):
|
||||||
self.reset()
|
self.reset()
|
||||||
@ -224,6 +221,7 @@ class Oven(threading.Thread):
|
|||||||
|
|
||||||
def abort_run(self):
|
def abort_run(self):
|
||||||
self.reset()
|
self.reset()
|
||||||
|
self.save_automatic_restart_state()
|
||||||
|
|
||||||
def kiln_must_catch_up(self):
|
def kiln_must_catch_up(self):
|
||||||
'''shift the whole schedule forward in time by one time_step
|
'''shift the whole schedule forward in time by one time_step
|
||||||
@ -314,78 +312,72 @@ class Oven(threading.Thread):
|
|||||||
if os.path.isfile(config.automatic_restart_state_file):
|
if os.path.isfile(config.automatic_restart_state_file):
|
||||||
state_age = os.path.getmtime(config.automatic_restart_state_file)
|
state_age = os.path.getmtime(config.automatic_restart_state_file)
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if((now - state_age)/60 <= config.automatic_restart_window):
|
minutes = (now - state_age)/60
|
||||||
|
if(minutes <= config.automatic_restart_window):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def save_automatic_restart_state(self):
|
||||||
def automatic_restart(self):
|
# only save state if the feature is enabled
|
||||||
'''takes one of two actions
|
|
||||||
if RUNNING, saves state every duty cycle
|
|
||||||
if IDLE, checks and then starts last known good profile where it died
|
|
||||||
'''
|
|
||||||
# check if automatic_restart setting is True
|
|
||||||
if not config.automatic_restarts == True:
|
if not config.automatic_restarts == True:
|
||||||
return
|
return False
|
||||||
|
self.save_state()
|
||||||
|
|
||||||
if self.state == "RUNNING":
|
def should_i_automatic_restart(self):
|
||||||
# save state every duty cycle (2s by default)
|
# only automatic restart if the feature is enabled
|
||||||
self.save_state()
|
if not config.automatic_restarts == True:
|
||||||
return
|
return False
|
||||||
|
|
||||||
# check if within window (use file timestamp and setting)
|
|
||||||
if self.state_file_is_old():
|
if self.state_file_is_old():
|
||||||
log.info("restart not possible. outside restart window")
|
log.info("restart not possible. state file too old.")
|
||||||
return
|
return False
|
||||||
|
|
||||||
# restart the last known profile where it died
|
|
||||||
self.restart()
|
|
||||||
|
|
||||||
def restart(self):
|
|
||||||
if os.path.isfile(config.automatic_restart_state_file):
|
if os.path.isfile(config.automatic_restart_state_file):
|
||||||
with open(config.automatic_restart_state_file) as infile: d = json.load(infile)
|
with open(config.automatic_restart_state_file) as infile: d = json.load(infile)
|
||||||
else:
|
else:
|
||||||
log.info("restart not possible. no state file found.")
|
log.info("restart not possible. no state file found.")
|
||||||
return
|
return False
|
||||||
# check if last profile finished
|
if d["state"] != "RUNNING":
|
||||||
#if d["totaltime"] - d["runtime"] > 60:
|
# this log statement is too noisy.
|
||||||
if d["state"] == "RUNNING":
|
#log.info("restart not possible. state = %s" % (d["state"]))
|
||||||
startat = d["runtime"]/60
|
return False
|
||||||
filename = "%s.json" % (d["profile"])
|
return True
|
||||||
profile_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'storage','profiles',filename))
|
|
||||||
|
|
||||||
log.info("restarting profile = %s at minute = %d" % (profile_path,startat))
|
def automatic_restart(self):
|
||||||
with open(profile_path) as infile:
|
with open(config.automatic_restart_state_file) as infile: d = json.load(infile)
|
||||||
profile_json = json.dumps(json.load(infile))
|
startat = d["runtime"]/60
|
||||||
profile = Profile(profile_json)
|
filename = "%s.json" % (d["profile"])
|
||||||
self.run_profile(profile,startat=startat)
|
profile_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'storage','profiles',filename))
|
||||||
self.ovenwatcher.record(profile)
|
|
||||||
|
|
||||||
|
log.info("restarting profile = %s at minute = %d" % (profile_path,startat))
|
||||||
|
with open(profile_path) as infile:
|
||||||
|
profile_json = json.dumps(json.load(infile))
|
||||||
|
profile = Profile(profile_json)
|
||||||
|
self.run_profile(profile,startat=startat)
|
||||||
|
self.ovenwatcher.record(profile)
|
||||||
|
|
||||||
def set_ovenwatcher(self,watcher):
|
def set_ovenwatcher(self,watcher):
|
||||||
|
log.info("ovenwatcher set in oven class")
|
||||||
self.ovenwatcher = watcher
|
self.ovenwatcher = watcher
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
if self.state == "IDLE":
|
if self.state == "IDLE":
|
||||||
self.automatic_restart()
|
if self.should_i_automatic_restart() == True:
|
||||||
|
self.automatic_restart()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
continue
|
continue
|
||||||
if self.state == "RUNNING":
|
if self.state == "RUNNING":
|
||||||
|
self.save_automatic_restart_state()
|
||||||
self.kiln_must_catch_up()
|
self.kiln_must_catch_up()
|
||||||
self.update_runtime()
|
self.update_runtime()
|
||||||
self.update_target_temp()
|
self.update_target_temp()
|
||||||
self.heat_then_cool()
|
self.heat_then_cool()
|
||||||
self.reset_if_emergency()
|
self.reset_if_emergency()
|
||||||
self.reset_if_schedule_ended()
|
self.reset_if_schedule_ended()
|
||||||
self.automatic_restart()
|
|
||||||
|
|
||||||
class SimulatedOven(Oven):
|
class SimulatedOven(Oven):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reset()
|
|
||||||
self.board = BoardSimulated()
|
self.board = BoardSimulated()
|
||||||
|
|
||||||
self.t_env = config.sim_t_env
|
self.t_env = config.sim_t_env
|
||||||
self.c_heat = config.sim_c_heat
|
self.c_heat = config.sim_c_heat
|
||||||
self.c_oven = config.sim_c_oven
|
self.c_oven = config.sim_c_oven
|
||||||
@ -398,8 +390,7 @@ class SimulatedOven(Oven):
|
|||||||
self.t = self.t_env # deg C temp of oven
|
self.t = self.t_env # deg C temp of oven
|
||||||
self.t_h = self.t_env #deg C temp of heating element
|
self.t_h = self.t_env #deg C temp of heating element
|
||||||
|
|
||||||
# call parent init
|
super().__init__()
|
||||||
Oven.__init__(self)
|
|
||||||
|
|
||||||
# start thread
|
# start thread
|
||||||
self.start()
|
self.start()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user