Files @ 22b6999f8bdd
Branch filter:

Location: HydroBot/hydrobot-software/hydrobot.py - annotation

matthewreed
Added timers in the config file
d1142fbbace4
1aa7eed26cdb
1aa7eed26cdb
22b6999f8bdd
22b6999f8bdd
a5b830d92afd
d1142fbbace4
d1142fbbace4
1aa7eed26cdb
a5b830d92afd
a5b830d92afd
a5b830d92afd
a5b830d92afd
22b6999f8bdd
a5b830d92afd
a5b830d92afd
d1142fbbace4
22b6999f8bdd
a5b830d92afd
1aa7eed26cdb
1aa7eed26cdb
d1142fbbace4
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
1aa7eed26cdb
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
22b6999f8bdd
daaed5044a8c
daaed5044a8c
daaed5044a8c
1aa7eed26cdb
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
d1142fbbace4
daaed5044a8c
daaed5044a8c
daaed5044a8c
1aa7eed26cdb
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
a5b830d92afd
a5b830d92afd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
1aa7eed26cdb
daaed5044a8c
daaed5044a8c
a5b830d92afd
a5b830d92afd
a5b830d92afd
a5b830d92afd
a5b830d92afd
a5b830d92afd
a5b830d92afd
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
a5b830d92afd
a5b830d92afd
22b6999f8bdd
22b6999f8bdd
a5b830d92afd
22b6999f8bdd
1aa7eed26cdb
1aa7eed26cdb
d1142fbbace4
daaed5044a8c
daaed5044a8c
daaed5044a8c
daaed5044a8c
a5b830d92afd
a5b830d92afd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
22b6999f8bdd
a5b830d92afd
d1142fbbace4
1aa7eed26cdb
1aa7eed26cdb
1aa7eed26cdb
1aa7eed26cdb
1aa7eed26cdb
1aa7eed26cdb
1aa7eed26cdb
import sys
import time
import _thread
import ast
import configparser
from canard import can, messaging
from canard.hw import socketcan
from canard.file import jsondb
from influxdb import InfluxDBClient
from apscheduler.schedulers.background import BackgroundScheduler

#TODO
#fix temperature offset
#database series helper
#database time interval logging
#add system name to database

config = configparser.ConfigParser(allow_no_value = True)
config.read("hydrobot.conf")
DEBUG_CAN = config.getboolean("debug", "can")
DEBUG_CAN_DETAIL = config.getboolean("debug", "can_detail")

class Database:
    
    def __init__(self):
        host = config.get("database", "host")
        port = config.get("database", "port")
        username = config.get("database", "username")
        password = config.get("database", "password")
        database = config.get("database", "database")
        self.name = config.get("system", "name")
        self.client = InfluxDBClient(host, port, username, password, database)

    def log_data(self, msgdb, message):
        if message == msgdb.AirSense:
            json_body = [
                {
                    "measurement": self.name + "_air_temp",
                    "fields": {
                        "value": (float)(message.Temperature.value)
                    }
                },
                {
                    "measurement": self.name + "_air_humidity",
                    "fields": {
                        "value": (float)(message.Humidity.value)
                    }
                },
                {
                    "measurement": self.name + "_air_pressure",
                    "fields": {
                        "value": (float)(message.Pressure.value)
                    }
                }
            ]
            self.client.write_points(json_body)
        if message == msgdb.RelayDriveIn:
            json_body = [
                {
                    "measurement": self.name + "_input_1",
                    "fields": {
                        "value": (float)(message.Input1.value)
                    }
                },
                {
                    "measurement": self.name + "_input_2",
                    "fields": {
                        "value": (float)(message.Input2.value)
                    }
                },
                {
                    "measurement": self.name + "_input_3",
                    "fields": {
                        "value": (float)(message.Input3.value)
                    }
                },
                {
                    "measurement": self.name + "_input_4",
                    "fields": {
                        "value": (float)(message.Input4.value)
                    }
                }
            ]
            self.client.write_points(json_body)


class CanBus:
    
    def __init__(self, database):
        
        self.database = database

        self.dev = socketcan.SocketCanDev("can0")
        
        parser = jsondb.JsonDbParser()
        self.msgdb = parser.parse('hydrobot_can.json')
        
        self.temp_msg = self.msgdb.AirSense
        self.relay_msg = self.msgdb.RelayDriveIn
        self.relay_send_msg = self.msgdb.RelayDriveOut
        
    def start(self):
        self.dev.start()
        
    def start_receive(self):
        _thread.start_new_thread(self.process_can, ())

    def process_can(self):
        while True:
            frame = self.dev.recv()
            message = self.msgdb.decode(frame)
            if message:
                if DEBUG_CAN:
                    print("Received CAN message! ID: " + hex(message.id))
                for s in message._signals.values():
                    if DEBUG_CAN_DETAIL:
                        print(s)
                        print(s.value)
                    self.database.log_data(self.msgdb, message)
                
    def send_can(self):
        self.relay_send_msg.Nothing.value = 0
        if self.relay_send_msg.Output1.value == 0:
            self.relay_send_msg.Output1.value = 1
        else:
            self.relay_send_msg.Output1.value = 0
        self.relay_send_msg.Output2.value = 1
        self.relay_send_msg.Output3.value = 1
        self.relay_send_msg.Output4.value = 1
        if DEBUG_CAN:
            print("Send CAN message! ID: " + hex(self.relay_send_msg.id))
        if DEBUG_CAN_DETAIL:
            print(self.relay_send_msg)
        self.dev.send(self.relay_send_msg.encode())
        
    def set_output(self, module, output, state):
        msg = self.msgdb.lookup_message(module)
        msg.lookup_signal(output).value = state
        print(msg)
        self.dev.send(msg.encode())

def main():
    
    database = Database()
    canbus = CanBus(database)
    canbus.start()
    canbus.start_receive()
    
    scheduler = BackgroundScheduler()
    
    for section in config.sections():
        if "timer" in section:
            items = config.items(section)
            for item in items:
                if item[0] == 'trigger':
                    trigger = item[1]
                if item[0] == 'module':
                    module = item[1]
                if item[0] == 'output':
                    output = item[1]
                if item[0] == 'on_time':
                    on_time = ast.literal_eval(item[1])
                if item[0] == 'off_time':
                    off_time = ast.literal_eval(item[1])
                if item[0] == 'on_duration':
                    on_duration = ast.literal_eval(item[1])
            if trigger == 'cron':
                scheduler.add_job(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])
                scheduler.add_job(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])
            if trigger == 'interval':
                scheduler.add_job(canbus.set_output, trigger, [module, output, 1], weeks = on_duration[0], days = on_duration[1], hours = on_duration[2], minutes = on_duration[3], seconds = on_duration[4])
    
    scheduler.start()

    while True:
        
        time.sleep(1)
        

if __name__ == "__main__":
    main()