This commit is contained in:
James Kirikland Garner 2022-12-16 19:24:03 -08:00
parent 5df0bc503a
commit d8c1f7cb00
4 changed files with 73 additions and 16 deletions

49
Test/test_Profile.py Normal file
View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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"}