178 lines
5.1 KiB
Python
178 lines
5.1 KiB
Python
import numpy as np
|
|
|
|
import json
|
|
import os
|
|
import serial
|
|
import subprocess
|
|
import threading
|
|
import time
|
|
|
|
from humidifier import Humidifier, HumidifierV2
|
|
from humidifier_v3 import HumidifierV3
|
|
from controller import Controller
|
|
|
|
import utils
|
|
from utils import start_process, send_update
|
|
|
|
SERIAL_PATH = "/dev/ttyACM0"
|
|
SERIAL_BAUD = 115200
|
|
|
|
SAMPLE_PERIOD = 0.5
|
|
DECIMATION_RATE = 1
|
|
|
|
try:
|
|
is_mock = os.environ['MOCK']
|
|
except KeyError:
|
|
is_mock = False
|
|
|
|
print("controller start")
|
|
start_process()
|
|
|
|
if is_mock:
|
|
import mock_serial
|
|
s = mock_serial.MockSerial()
|
|
else:
|
|
s = serial.Serial(SERIAL_PATH, SERIAL_BAUD, timeout = 0.3)
|
|
print("pausing for bootloader...")
|
|
time.sleep(10)
|
|
print("pause done")
|
|
|
|
def reset_serial():
|
|
global s
|
|
if not is_mock:
|
|
s.close()
|
|
s = serial.Serial(SERIAL_PATH, SERIAL_BAUD, timeout = 0.3)
|
|
time.sleep(10)
|
|
|
|
humidifier = HumidifierV3()
|
|
controller = Controller([humidifier])
|
|
|
|
exiting = False
|
|
# run thread to process data from process's stdout
|
|
def stdout_loop():
|
|
global process, controller, humidifier, humidifier2
|
|
while not exiting:
|
|
msg = utils.process.stdout.readline()
|
|
if len(msg) <= 1:
|
|
continue
|
|
print("got message ", msg)
|
|
try:
|
|
msg_js = json.loads(msg)
|
|
if "query_params" in msg_js:
|
|
if msg_js["query_params"]:
|
|
send_update({"params": {
|
|
"target_lower": controller.target_lower,
|
|
"target_upper": controller.target_upper,
|
|
"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:
|
|
if type(msg_js["set_params"]) is dict:
|
|
set_params = msg_js["set_params"]
|
|
if "name" in set_params and "value" in set_params:
|
|
name, value = set_params["name"], set_params["value"]
|
|
if type(value) is float:
|
|
if name == "target_lower":
|
|
controller.target_lower = value
|
|
elif name == "target_upper":
|
|
controller.target_upper = 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 name == "off_threshold_volts2":
|
|
humidifier2.off_threshold = value
|
|
elif name == "on_threshold_volts2":
|
|
humidifier2.on_threshold = value
|
|
elif name == "toggle_cooldown2":
|
|
humidifier2.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:
|
|
print("received bad json ", msg)
|
|
stdout_thread = threading.Thread(target=stdout_loop)
|
|
stdout_thread.start()
|
|
|
|
|
|
frame_num = 0
|
|
last_sample = 0
|
|
try:
|
|
while True:
|
|
now = time.time()
|
|
if now - last_sample < SAMPLE_PERIOD:
|
|
time.sleep(SAMPLE_PERIOD - (now - last_sample) + 0.001)
|
|
continue
|
|
last_sample = now
|
|
|
|
#print("write s")
|
|
s.write(b"s")
|
|
s.flush()
|
|
resp = s.read(120)
|
|
#print("read", resp)
|
|
if len(resp) == 0:
|
|
reset_serial()
|
|
time.sleep(5)
|
|
continue
|
|
parts = resp.split(b",")
|
|
humidity = float(parts[0])
|
|
temp = float(parts[1])
|
|
#volts = float(parts[2])
|
|
#volts2 = float(parts[3])
|
|
#print(parts)
|
|
|
|
try:
|
|
controller.update(s, humidity)
|
|
|
|
if frame_num == 0:
|
|
#print(humidity, temp, volts)
|
|
update = {
|
|
"data": {
|
|
"time": int(now*1000),
|
|
"temp": temp,
|
|
"hum": humidity,
|
|
"hv": 1 if humidifier.on else 0,
|
|
"hv2": 1 if humidifier.on else 0,
|
|
}
|
|
}
|
|
send_update(update)
|
|
frame_num = (frame_num + 1) % DECIMATION_RATE
|
|
except Exception as e:
|
|
print("pipe errored out, restarting: ", e)
|
|
# restart the process I guess
|
|
exiting = True
|
|
utils.process.kill()
|
|
time.sleep(0.1)
|
|
stdout_thread.join()
|
|
exiting = False
|
|
|
|
start_process()
|
|
|
|
stdout_thread = threading.Thread(target=stdout_loop)
|
|
stdout_thread.start()
|
|
|
|
finally:
|
|
# kill ssh connection
|
|
exiting = True
|
|
utils.process.kill()
|
|
stdout_thread.join()
|