diff --git a/hydrobot.py b/hydrobot.py --- a/hydrobot.py +++ b/hydrobot.py @@ -6,10 +6,12 @@ import configparser import datetime from canard import can, messaging from canard.hw import socketcan +from canard.hw import cantact from canard.file import jsondb from influxdb import InfluxDBClient from influxdb import SeriesHelper from apscheduler.schedulers.background import BackgroundScheduler +import PID #TODO #fix temperature offsets @@ -80,6 +82,8 @@ class CanBus: self.database = database self.dev = socketcan.SocketCanDev("can0") + #self.dev = cantact.CantactDev("/dev/ttyACM8") + #self.dev.set_bitrate(500000) parser = jsondb.JsonDbParser() self.msgdb = parser.parse('hydrobot_can.json') @@ -123,6 +127,7 @@ class CanBus: self.dev.send(self.relay_send_msg.encode()) def set_output(self, module, output, state): + print("Output! " + module + " " + output + " " + str(state)) msg = self.msgdb.lookup_message(module) msg.lookup_signal(output).value = state self.dev.send(msg.encode()) @@ -165,13 +170,48 @@ class Scheduler: if item[0] == 'off_duration': off_duration = ast.literal_eval(item[1]) if trigger == 'cron': - self.apscheduler.add_job(self.canbus.set_output, trigger, [module, output, 1], day = on_time[0], day_of_week = on_time[1], hour = on_time[2], minute = on_time[3], second = on_time[4]) - self.apscheduler.add_job(self.canbus.set_output, trigger, [module, output, 0], day = off_time[0], day_of_week = off_time[1], hour = off_time[2], minute = off_time[3], second = off_time[4]) + on_job = self.apscheduler.add_job(self.canbus.set_output, trigger, [module, output, 1], day = on_time[0], day_of_week = on_time[1], hour = on_time[2], minute = on_time[3], second = on_time[4]) + off_job = self.apscheduler.add_job(self.canbus.set_output, trigger, [module, output, 0], day = off_time[0], day_of_week = off_time[1], hour = off_time[2], minute = off_time[3], second = off_time[4]) + + #evalute the current state of the cron trigger and set output on if needed + if on_job.next_run_time > off_job.next_run_time: + self.canbus.set_output(module, output, 1) + if trigger == 'interval': self.apscheduler.add_job(self.interval_off, trigger, [module, output, section + "_off", section + "_on", on_duration], id = section + "_off", weeks = off_duration[0], days = off_duration[1], hours = off_duration[2], minutes = off_duration[3], seconds = off_duration[4]) timer = self.apscheduler.add_job(self.interval_on, trigger, [module, output, section + "_off", section + "_on", off_duration], id = section + "_on", weeks = on_duration[0], days = on_duration[1], hours = on_duration[2], minutes = on_duration[3], seconds = on_duration[4]) timer.pause() - + + if "pid" in section: + items = config.items(section) + for item in items: + if item[0] == 'module_out': + module_out = item[1] + if item[0] == 'output': + signal_out = item[1] + if item[0] == 'module_in': + module_in = item[1] + if item[0] == 'input': + signal_in = item[1] + if item[0] == 'kp': + kp = item[1] + if item[0] == 'ki': + ki = item[1] + if item[0] == 'kd': + kd = item[1] + if item[0] == 'rate': + rate = item[1] + if item[0] == 'setpoint': + setpoint = item[1] + + pid = PID.PID(float(setpoint)) + pid.SetKp(kp) + pid.SetKi(ki) + pid.SetKd(kd) + pid.Reset() + self.apscheduler.add_job(self.process_PID, "interval", [pid, module_out, signal_out, module_in, signal_in], seconds = int(rate)) + + def interval_off(self, module, output, timer_off, timer_on, on_duration): self.canbus.set_output(module, output, 1) self.apscheduler.get_job(timer_on).reschedule("interval", weeks = on_duration[0], days = on_duration[1], hours = on_duration[2], minutes = on_duration[3], seconds = on_duration[4]) @@ -187,7 +227,16 @@ class Scheduler: self.apscheduler.get_job(timer_on).pause() if DEBUG_TIMER: print("Turning " + timer_off + "! " + str(datetime.datetime.now().time())) - + + def process_PID(self, pid, module_out, signal_out, module_in, signal_in): + msg = self.canbus.msgdb.lookup_message(module_in) + input_reading = msg.lookup_signal(signal_in).value + input_reading = 19 + pid_out = pid.Update(input_reading) + if pid_out > 0: + self.canbus.set_output(module_out, signal_out, 1) + run_time = datetime.datetime.now() + datetime.timedelta(milliseconds=pid_out) + self.apscheduler.add_job(self.canbus.set_output, "date", run_date=run_time, args=[module_out, signal_out, 0]) def func(): print(1) @@ -205,8 +254,8 @@ def main(): scheduler.start() while True: - - time.sleep(1) + canbus.dev.send(can.Frame(0x7FF, 8, [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88])) + time.sleep(0.001) if __name__ == "__main__":