view vanlogger.py @ 26:00845d271007

Add Giant IPS udev rule
author Daniel O'Connor <darius@dons.net.au>
date Wed, 25 Sep 2019 21:35:40 +0930
parents bacb798e6731
children 718b963b0dfa
line wrap: on
line source

#!/usr/bin/env python

import sys

sys.path.append('/home/pi/logger')
import datetime
import epro.epro as epro
import json
import serial
import sqlite3
import subprocess
import sys

def create(cur):
    cur.execute('''
CREATE TABLE IF NOT EXISTS eprolog(
    tstamp			INTEGER NOT NULL,
    main_voltage	REAL NOT NULL,
    aux_voltage		REAL NOT NULL,
    battery_curr	REAL NOT NULL,
    amp_hours		REAL NOT NULL,
    state_of_charge	REAL NOT NULL,
    time_remaining	REAL NOT NULL,
    battery_temp	REAL,
    auto_sync_volts	BOOLEAN NOT NULL,
    auto_sync_curr	BOOLEAN NOT NULL,
    e501			BOOLEAN NOT NULL,
    alarm_test		BOOLEAN NOT NULL,
    light			BOOLEAN NOT NULL,
    display_test	BOOLEAN NOT NULL,
    temp_sensor		BOOLEAN NOT NULL,
    aux_hv			BOOLEAN NOT NULL,
    aux_lv			BOOLEAN NOT NULL,
    installer_lock	BOOLEAN NOT NULL,
    main_hv			BOOLEAN NOT NULL,
    main_lv			BOOLEAN NOT NULL,
	low_battery 	BOOLEAN NOT NULL,
    battery_flat	BOOLEAN NOT NULL,
    battery_full	BOOLEAN NOT NULL,
    battery_charged	BOOLEAN NOT NULL,
    no_sync			BOOLEAN NOT NULL,
    monitor_reset	BOOLEAN NOT NULL
);
''')

    cur.execute('''
CREATE TABLE IF NOT EXISTS victron(
    tstamp		INTEGER NOT NULL,
    ACIn_L1_volts	REAL NOT NULL,
    ACIn_L1_freq	REAL NOT NULL,
    ACIn_L1_curent	REAL NOT NULL,
    ACIn_active		BOOLEAN NOT NULL,
    ACOut_L1_volts	REAL NOT NULL,
    ACOut_L1_freq	REAL NOT NULL,
    ACOut_L1_curent	REAL NOT NULL,
    Battery_Voltage	REAL NOT NULL,
    Battery_Current	REAL NOT NULL
);
''')
 


def log_epro(p, cur):
    # Check we have all the packets we need in the queue
    msgtypes = set([x.msgtype for x in p.packets])
    wantedtypes = set([
        epro.MainVoltage.MSGTYPE,
        epro.AmpHours.MSGTYPE,
        epro.BatteryCurrent.MSGTYPE,
        epro.StateOfCharge.MSGTYPE,
        epro.TimeRemaining.MSGTYPE,
        epro.BatteryTemperature.MSGTYPE,
        epro.MonitorStatus.MSGTYPE,
        epro.AuxVoltage.MSGTYPE,
        ])
    if msgtypes < wantedtypes:
        return

    row = {}
    usedtypes = set()
    while len(p.packets) > 0:
        pkt = p.packets.pop() # Read latest packets first
        if pkt.msgtype == epro.MainVoltage.MSGTYPE:
            row['main_voltage'] = pkt.volts
        elif pkt.msgtype == epro.AmpHours.MSGTYPE:
            row['amp_hours'] = pkt.amphrs
        elif pkt.msgtype == epro.BatteryCurrent.MSGTYPE:
            row['battery_curr'] = pkt.amps
        elif pkt.msgtype == epro.StateOfCharge.MSGTYPE:
            row['state_of_charge'] = pkt.soc
        elif pkt.msgtype == epro.TimeRemaining.MSGTYPE:
            row['time_remaining'] = pkt.time
        elif pkt.msgtype == epro.BatteryTemperature.MSGTYPE:
            row['battery_temp'] = pkt.temp
        elif pkt.msgtype == epro.MonitorStatus.MSGTYPE:
            row['auto_sync_volts'] = pkt.autosyncvolt
            row['auto_sync_curr'] = pkt.autosyncamp
            row['e501'] = pkt.e501compat
            row['alarm_test'] = pkt.alarmtst
            row['light'] = pkt.backlight
            row['display_test'] = pkt.disptst
            row['temp_sensor'] = pkt.tempsense
            row['aux_hv'] = pkt.auxhv
            row['aux_lv'] = pkt.auxlv
            row['installer_lock'] = pkt.lock
            row['main_hv'] = pkt.mainhv
            row['main_lv'] = pkt.mainlv
            row['low_battery'] = pkt.lowbatalarm
            row['battery_flat'] = pkt.batflat
            row['battery_full'] = pkt.batfull
            row['battery_charged'] = pkt.charged
            row['no_sync'] = pkt.nosync
            row['monitor_reset'] = pkt.monreset
        elif pkt.msgtype == epro.AuxVoltage.MSGTYPE:
            row['aux_voltage'] = pkt.volts

        usedtypes.add(pkt.msgtype)
        if usedtypes >= wantedtypes:
            p.packets = []
            break

    row['tstamp'] = int(datetime.datetime.now().strftime('%s'))
    cur.execute('INSERT INTO eprolog VALUES (:tstamp, :main_voltage, :aux_voltage, :battery_curr, :amp_hours, :state_of_charge, :time_remaining, :battery_temp, :auto_sync_volts, :auto_sync_curr, :e501, :alarm_test, :light, :display_test, :temp_sensor, :aux_hv, :aux_lv, :installer_lock, :main_hv, :main_lv, :low_battery, :battery_flat, :battery_full, :battery_charged, :no_sync, :monitor_reset)', row)

def main():
    print 'Started'
    dbh = sqlite3.connect('/home/pi/vanlogger/log.db')
    cur = dbh.cursor()
    create(cur)
    #s = serial.Serial('/dev/ttyS0', 2400, parity='E')
    s = serial.Serial('/dev/ttyS0', 2400)
    s.timeout = 0.2

    p = epro.Processor()

    then = None
    lasteprolog = datetime.datetime.now()
    while True:
        if datetime.datetime.now() - lasteprolog > datetime.timedelta(hours = 1):
	    print('Stale ePro data')
	    sys.exit(1)
        dolog = False
        if then == None or datetime.datetime.now() - then > datetime.timedelta(seconds = 60):
            dolog = True
            then = datetime.datetime.now()
        p.process(s.read(1024))
        if dolog:
            lasteprolog = datetime.datetime.now()
            log_epro(p, cur)
            dbh.commit()

if __name__ == '__main__':
    main()