From d8c1f7cb00fa42120e9fc6931166dcb7fa314882 Mon Sep 17 00:00:00 2001 From: James Kirikland Garner Date: Fri, 16 Dec 2022 19:24:03 -0800 Subject: [PATCH] fussing --- Test/test_Profile.py | 49 +++++++++++++++++++++++++++++++++ config.py | 12 ++------ lib/oven.py | 26 +++++++++++++---- storage/profiles/test-fast.json | 2 +- 4 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 Test/test_Profile.py diff --git a/Test/test_Profile.py b/Test/test_Profile.py new file mode 100644 index 0000000..7c579b2 --- /dev/null +++ b/Test/test_Profile.py @@ -0,0 +1,49 @@ +from lib.oven import Profile +import os +import json + +def get_profile(): + profile_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'storage', 'profiles', "test-fast.json")) + print(profile_path) + with open(profile_path) as infile: + profile_json = json.dumps(json.load(infile)) + profile = Profile(profile_json) + + return profile + + +def test_get_target_temperature(): + profile = get_profile() + + temperature = profile.get_target_temperature(3000) + assert int(temperature) == 178 + + temperature = profile.get_target_temperature(6004) + assert temperature == 801.0 + + +def test_shift_remaining_segments(): + profile = get_profile() + + now = 6000 + shift_seconds = 100 + profile.shift_remaining_segments(now, shift_seconds) + + assert profile.data[0][0] == 0 + assert profile.data[1][0] == 3600 + assert profile.data[2][0] == 10900 + assert profile.data[3][0] == 14500 + assert profile.data[4][0] == 16500 + assert profile.data[5][0] == 19500 + + +def test_get_next_point(): + profile = get_profile() + + now = 6000 + segment = profile.get_next_point(now) + assert segment == 2 + + now = 14405 + segment = profile.get_next_point(now) + assert segment == 4 diff --git a/config.py b/config.py index 415d64a..4efc69e 100644 --- a/config.py +++ b/config.py @@ -97,21 +97,13 @@ pid_kp = 25 # Proportional 25,200,200 pid_ki = 10 # Integral pid_kd = 200 # Derivative -######################################################################## -# -# Initial heating and Integral Windup -# -# this setting is deprecated and is no longer used. this happens by -# default and is the expected behavior. -stop_integral_windup = True - ######################################################################## # # Simulation parameters simulate = True sim_t_env = 60.0 # deg C sim_c_heat = 500.0 # J/K heat capacity of heat element -sim_c_oven = 5000.0 # J/K heat capacity of oven +sim_c_oven = 10000.0 # J/K heat capacity of oven sim_p_heat = 5450.0 # W heating power of oven sim_R_o_nocool = 0.5 # K/W thermal resistance oven -> environment sim_R_o_cool = 0.05 # K/W " with cooling @@ -135,7 +127,7 @@ time_scale_profile = "m" # s = Seconds | m = Minutes | h = Hours - Enter and vi # naturally cool off. If your SSR has failed/shorted/closed circuit, this # 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 = 2350 #2264 #cone 7 # 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/oven.py b/lib/oven.py index 411db71..7abad72 100644 --- a/lib/oven.py +++ b/lib/oven.py @@ -314,7 +314,7 @@ class Oven(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.daemon = True - self.temperature = 0 + self.temperature = 70 self.time_step = config.sensor_time_wait self.reset() @@ -356,11 +356,12 @@ class Oven(threading.Thread): # kiln too cold, wait for it to heat up if self.target - temp > config.pid_control_window: log.info("kiln must catch up, too cold, shifting schedule") - self.start_time = self.get_start_time() + self.profile.shift_remaining_segments(self.runtime, 10) + self.totaltime = self.profile.get_duration() # kiln too hot, wait for it to cool down if temp - self.target > config.pid_control_window: - log.info("kiln must catch up, too hot, shifting schedule") - self.start_time = self.get_start_time() + self.profile.shift_remaining_segments(self.runtime, 10) + self.totaltime = self.profile.get_duration() def update_runtime(self): @@ -679,6 +680,21 @@ class Profile(): return (prev_point, next_point) + def get_next_point(self, now): + next_point = None # Handle error if nothing found + for i in range(len(self.data)): + if now < self.data[i][0]: + next_point = i + break + + return next_point + + def shift_remaining_segments(self, now, shift_seconds): + next_point = self.get_next_point(now) + for i in range(len(self.data)): + if i >= next_point: + self.data[i][0] += shift_seconds + def get_target_temperature(self, time): if time > self.get_duration(): return 0 @@ -733,7 +749,7 @@ class PID(): icomp = (error * timeDelta * (1/self.ki)) self.iterm += (error * timeDelta * (1/self.ki)) dErr = (error - self.lastErr) / timeDelta - output = self.kp * error + self.iterm + self.kd * dErr + output = self.kp * error #+ self.iterm + self.kd * dErr output = sorted([-1 * window_size, output, window_size])[1] out4logs = output output = float(output / window_size) diff --git a/storage/profiles/test-fast.json b/storage/profiles/test-fast.json index b863af2..67a3f1d 100644 --- a/storage/profiles/test-fast.json +++ b/storage/profiles/test-fast.json @@ -1 +1 @@ -{"data": [[0, 200], [3600, 200], [10800, 2000], [14400, 2250], [16400, 2250], [19400, 70]], "type": "profile", "name": "test-fast"} +{"data": [[0, 70], [3600, 200], [10800, 2000], [14400, 2250], [16400, 2250], [19400, 1000]], "type": "profile", "name": "test-fast"}