diff vanlogger.py @ 0:78148730d98d

Log ePro and Giant IPS status to sqlite DB
author Daniel O'Connor <darius@dons.net.au>
date Sun, 19 Nov 2017 18:13:02 +1030
parents
children f77cc29d0b47
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vanlogger.py	Sun Nov 19 18:13:02 2017 +1030
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+
+import sys
+
+sys.path.append('/home/pi/logger')
+import datetime
+import epro.epro as epro
+import giant.giant as giant
+import serial
+import sqlite3
+
+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 giantlog(
+    tstamp			INTEGER NOT NULL,
+	ac_act_power	REAL NOT NULL,
+	ac_app_power	REAL NOT NULL,
+	ac_frequency	REAL NOT NULL,
+	ac_volts		REAL NOT NULL,
+	batt_chr_curr	REAL NOT NULL,
+	batt_dis_curr	REAL NOT NULL,
+    battery_cap		REAL NOT NULL,
+	battery_volts	REAL NOT NULL,
+	batt_volt_ofs	REAL NOT NULL,
+	bus_voltage		REAL NOT NULL,
+	grid_frequency	REAL NOT NULL,
+	grid_volts		REAL NOT NULL,
+	hs_temperature	REAL NOT NULL,
+	load_pct		REAL NOT NULL,
+	pv1_chrg_pow	REAL NOT NULL,
+	pv1_current		REAL NOT NULL,
+	pv1_volts		REAL NOT NULL,
+	scc1_volts		REAL NOT NULL,
+    scc1_charging	BOOLEAN NOT NULL,
+    switch			BOOLEAN NOT NULL,
+	float_charge	BOOLEAN NOT NULL,
+    ac_charging 	BOOLEAN NOT NULL,
+	sbu_prio		BOOLEAN NOT NULL,
+	b_volt_steady	BOOLEAN NOT NULL,
+    charging		BOOLEAN 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 log_giant(gstat, cur):
+    row = {}
+    row['ac_act_power'] = gstat['ACActPower']
+    row['ac_app_power'] = gstat['ACAppPower']
+    row['ac_frequency'] = gstat['ACFreq']
+    row['ac_volts'] = gstat['ACVolts']
+    row['batt_chr_curr'] = gstat['BattChrCurr']
+    row['batt_dis_curr'] = gstat['BattDisCurr']
+    row['battery_cap'] = gstat['BattCap']
+    row['battery_volts'] = gstat['BattVolts']
+    row['batt_volt_ofs'] = gstat['BattVoltOfs']
+    row['bus_voltage'] = gstat['BusVolts']
+    row['grid_frequency'] = gstat['GridFreq']
+    row['grid_volts'] = gstat['GridVolts']
+    row['hs_temperature'] = gstat['HSTemp']
+    row['load_pct'] = gstat['LoadPct']
+    row['pv1_chrg_pow'] = gstat['PVChrgPow1']
+    row['pv1_current'] = gstat['PVCurr1']
+    row['pv1_volts'] = gstat['PVVolt1']
+    row['scc1_volts'] = gstat['SCC1Volt']
+    row['scc1_charging'] = gstat['Status']['SCC1Charging']
+    row['switch'] = gstat['Status']['Switch']
+    row['float_charge'] = gstat['Status']['FloatCharge']
+    if gstat['Status']['ChargeType'] == 'Both' or gstat['Status']['ChargeType'] == 'AC':
+        row['ac_charging'] = True
+    else:
+        row['ac_charging'] = False
+    row['sbu_prio'] = gstat['Status']['SBUPrio']
+    row['b_volt_steady'] = gstat['Status']['BattVoltSteady']
+    row['charging'] = gstat['Status']['Charging']
+
+    row['tstamp'] = int(datetime.datetime.now().strftime('%s'))
+    cur.execute('INSERT INTO giantlog VALUES(:tstamp, :ac_act_power, :ac_app_power, :ac_frequency, :ac_volts, :batt_chr_curr, :batt_dis_curr, :battery_cap, :battery_volts, :batt_volt_ofs, :bus_voltage, :grid_frequency, :grid_volts, :hs_temperature, :load_pct, :pv1_chrg_pow, :pv1_current, :pv1_volts, :scc1_volts, :scc1_charging, :switch, :float_charge, :ac_charging, :sbu_prio, :b_volt_steady, :charging)', row)
+
+def main():
+    dbh = sqlite3.connect('/home/pi/vanlogger/log.db')
+    cur = dbh.cursor()
+    create(cur)
+    s = serial.Serial('/dev/ttyUSB0', 2400, parity='E')
+    s.timeout = 0.2
+
+    p = epro.Processor()
+    ips = giant.GiantIPS()
+
+    then = None
+    while True:
+        dolog = False
+        if then == None or datetime.datetime.now() - then > datetime.timedelta(seconds = 60):
+            dolog = True
+            print('Logging')
+            then = datetime.datetime.now()
+        p.process(s.read(1024))
+        if dolog:
+            log_epro(p, cur)
+            dbh.commit()
+
+        gstat = None
+        try:
+            gstat = ips.getStatus()
+        except:
+            pass
+        if gstat != None and dolog:
+            log_giant(gstat, cur)
+            dbh.commit()
+            #print(gstat)
+
+if __name__ == '__main__':
+    main()