Parameterize everything
This commit is contained in:
parent
80916bc3fa
commit
251d23446a
|
@ -73,6 +73,10 @@ def reset_serial():
|
||||||
|
|
||||||
class Humidifier:
|
class Humidifier:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.off_threshold = 0.2
|
||||||
|
self.on_threshold = 2.6
|
||||||
|
self.toggle_cooldown = 7
|
||||||
|
|
||||||
self.on = False
|
self.on = False
|
||||||
self.history = np.zeros(10)
|
self.history = np.zeros(10)
|
||||||
self.switch_timeout = 0
|
self.switch_timeout = 0
|
||||||
|
@ -87,13 +91,13 @@ class Humidifier:
|
||||||
#print(self.history)
|
#print(self.history)
|
||||||
avg = np.sum(self.history)/self.history.shape[0]
|
avg = np.sum(self.history)/self.history.shape[0]
|
||||||
if self.on:
|
if self.on:
|
||||||
if avg < 0.2:
|
if avg < self.off_threshold:
|
||||||
self.on = False
|
self.on = False
|
||||||
print("send status off")
|
print("send status off")
|
||||||
send_update({"status": {"humidifier": False}})
|
send_update({"status": {"humidifier": False}})
|
||||||
self.switch_timeout = time.time() + 1
|
self.switch_timeout = time.time() + 1
|
||||||
else:
|
else:
|
||||||
if avg > 2.6:
|
if avg > self.on_threshold:
|
||||||
self.on = True
|
self.on = True
|
||||||
print("send status on")
|
print("send status on")
|
||||||
send_update({"status": {"humidifier": True}})
|
send_update({"status": {"humidifier": True}})
|
||||||
|
@ -102,17 +106,56 @@ class Humidifier:
|
||||||
def toggle(self, s):
|
def toggle(self, s):
|
||||||
if time.time() > self.switch_timeout:
|
if time.time() > self.switch_timeout:
|
||||||
s.write(b"h")
|
s.write(b"h")
|
||||||
self.switch_timeout = time.time() + 7
|
self.switch_timeout = time.time() + self.toggle_cooldown
|
||||||
|
|
||||||
|
class Controller:
|
||||||
|
def __init__(self):
|
||||||
|
self.target_lower = 0.85
|
||||||
|
self.target_upper = 0.90
|
||||||
|
self.feedforward_coeff = 50
|
||||||
|
|
||||||
|
self.manual_mode = False
|
||||||
|
self.manual_on = False
|
||||||
|
self.manual_timeout = 0
|
||||||
|
self.manual_duration = 120
|
||||||
|
|
||||||
|
self.humidifier_history = np.zeros(30)
|
||||||
|
self.first_sample = False
|
||||||
|
|
||||||
|
def update(self, humidifier, humidity):
|
||||||
|
if self.first_sample:
|
||||||
|
self.humidifier_history[:] = humidity
|
||||||
|
self.first_sample = False
|
||||||
|
else:
|
||||||
|
self.humidifier_history[:-1] = self.humidifier_history[1:]
|
||||||
|
self.humidifier_history[-1] = humidity
|
||||||
|
|
||||||
|
# compensate for the slow response time by adding a little feed forward
|
||||||
|
# using the slope of the humidifier data
|
||||||
|
slope = (self.humidifier_history[-1] - self.humidifier_history[0])/self.humidifier_history.shape[0]
|
||||||
|
comp_humidity = humidity + self.feedforward_coeff*slope
|
||||||
|
|
||||||
|
if self.manual_mode and time.time() > self.manual_timeout:
|
||||||
|
self.manual_mode = False
|
||||||
|
|
||||||
|
if self.manual_mode:
|
||||||
|
if humidifier.off and self.manual_on:
|
||||||
|
humidifier.toggle(s)
|
||||||
|
elif humdifier.on and not self.manual_on:
|
||||||
|
humidifier.toggle(s)
|
||||||
|
else:
|
||||||
|
if comp_humidity < self.target_lower and humidifier.off:
|
||||||
|
humidifier.toggle(s)
|
||||||
|
elif comp_humidity > self.target_upper and humidifier.on:
|
||||||
|
humidifier.toggle(s)
|
||||||
|
|
||||||
humidifier = Humidifier()
|
humidifier = Humidifier()
|
||||||
target_lower = 0.85
|
controller = Controller()
|
||||||
target_upper = 0.90
|
|
||||||
feedforward_coeff = 50
|
|
||||||
|
|
||||||
exiting = False
|
exiting = False
|
||||||
# run thread to process data from process's stdout
|
# run thread to process data from process's stdout
|
||||||
def stdout_loop():
|
def stdout_loop():
|
||||||
global process, target_lower, target_upper, feedforward_coeff
|
global process, controller, humidifier
|
||||||
while not exiting:
|
while not exiting:
|
||||||
msg = process.stdout.readline()
|
msg = process.stdout.readline()
|
||||||
if len(msg) == 0:
|
if len(msg) == 0:
|
||||||
|
@ -123,33 +166,56 @@ def stdout_loop():
|
||||||
if "query_params" in msg_js:
|
if "query_params" in msg_js:
|
||||||
if msg_js["query_params"]:
|
if msg_js["query_params"]:
|
||||||
send_update({"params": {
|
send_update({"params": {
|
||||||
"target_lower": target_lower,
|
"target_lower": controller.target_lower,
|
||||||
"target_upper": target_upper,
|
"target_upper": controller.target_upper,
|
||||||
"feedforward_coeff": feedforward_coeff
|
"feedforward_coeff": controller.feedforward_coeff,
|
||||||
|
"manual_timeout": controller.manual_timeout,
|
||||||
|
"manual_duration_s": controller.manual_duration,
|
||||||
|
"manual_mode": 1.0 if controller.manual_mode else 0.0,
|
||||||
|
"manual_hum_on": 1.0 if controller.manual_on else 0.0,
|
||||||
|
|
||||||
|
"off_threshold_volts": humidifier.off_threshold,
|
||||||
|
"on_threshold_volts": humidifier.on_threshold,
|
||||||
|
"toggle_cooldown": humidifier.toggle_cooldown
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
elif "set_params" in msg_js:
|
elif "set_params" in msg_js:
|
||||||
if type(msg_js["set_params"]) is dict:
|
if type(msg_js["set_params"]) is dict:
|
||||||
set_params = msg_js["set_params"]
|
set_params = msg_js["set_params"]
|
||||||
if "name" in set_params and "value" in set_params:
|
if "name" in set_params and "value" in set_params:
|
||||||
if type(set_params["value"]) is float:
|
name, value = set_params["name"], set_params["value"]
|
||||||
if set_params["name"] == "target_lower":
|
if type(value) is float:
|
||||||
target_lower = set_params["value"]
|
if name == "target_lower":
|
||||||
elif set_params["name"] == "target_upper":
|
controller.target_lower = value
|
||||||
target_upper = set_params["value"]
|
elif name == "target_upper":
|
||||||
elif set_params["name"] == "feedforward_coeff":
|
controller.target_upper = value
|
||||||
feedforward_coeff = set_params["value"]
|
elif name == "feedforward_coeff":
|
||||||
|
controller.feedforward_coeff = value
|
||||||
|
elif name == "manual_timeout":
|
||||||
|
controller.manual_timeout = value
|
||||||
|
elif name == "manual_duration_s":
|
||||||
|
controller.manual_duration = value
|
||||||
|
elif name == "off_threshold_volts":
|
||||||
|
humidifier.off_threshold = value
|
||||||
|
elif name == "on_threshold_volts":
|
||||||
|
humidifier.on_threshold = value
|
||||||
|
elif name == "toggle_cooldown":
|
||||||
|
humidifier.toggle_cooldown = value
|
||||||
|
elif "manual_mode" in msg_js:
|
||||||
|
controller.manual_mode = msg_js["manual_mode"]
|
||||||
|
if controller.manual_mode:
|
||||||
|
controller.manual_timeout = time.time() + controller.manual_duration
|
||||||
|
elif "manual_mode_on" in msg_js:
|
||||||
|
controller.manual_on = msg_js["manual_mode_on"]
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
print("received bad json ", msg)
|
print("received bad json ", msg)
|
||||||
stdout_thread = threading.Thread(target=stdout_loop)
|
stdout_thread = threading.Thread(target=stdout_loop)
|
||||||
stdout_thread.start()
|
stdout_thread.start()
|
||||||
|
|
||||||
|
|
||||||
humidifier_history = np.zeros(30)
|
|
||||||
first_sample = False
|
|
||||||
frame_num = 0
|
frame_num = 0
|
||||||
|
last_sample = 0
|
||||||
try:
|
try:
|
||||||
last_sample = 0
|
|
||||||
while True:
|
while True:
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if now - last_sample < SAMPLE_PERIOD:
|
if now - last_sample < SAMPLE_PERIOD:
|
||||||
|
@ -167,24 +233,10 @@ try:
|
||||||
humidity = float(parts[0])
|
humidity = float(parts[0])
|
||||||
temp = float(parts[1])
|
temp = float(parts[1])
|
||||||
volts = float(parts[2])
|
volts = float(parts[2])
|
||||||
if first_sample:
|
|
||||||
humidifier_history[:] = humidity
|
|
||||||
first_sample = False
|
|
||||||
else:
|
|
||||||
humidifier_history[:-1] = humidifier_history[1:]
|
|
||||||
humidifier_history[-1] = humidity
|
|
||||||
|
|
||||||
# compensate for the slow response time by adding a little feed forward
|
|
||||||
# using the slope of the humidifier data
|
|
||||||
slope = (humidifier_history[-1] - humidifier_history[0])/humidifier_history.shape[0]
|
|
||||||
comp_humidity = humidity + feedforward_coeff*slope
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
humidifier.update(volts)
|
humidifier.update(volts)
|
||||||
if comp_humidity < target_lower and humidifier.off:
|
controller.update(humidifier, humidity)
|
||||||
humidifier.toggle(s)
|
|
||||||
elif comp_humidity > target_upper and humidifier.on:
|
|
||||||
humidifier.toggle(s)
|
|
||||||
|
|
||||||
if frame_num == 0:
|
if frame_num == 0:
|
||||||
print(humidity, temp, volts)
|
print(humidity, temp, volts)
|
||||||
|
|
Loading…
Reference in New Issue