# HG changeset patch # User Daniel O'Connor # Date 1511077382 -37800 # Node ID 78148730d98d910b291bf946178798f21b200abf Log ePro and Giant IPS status to sqlite DB diff -r 000000000000 -r 78148730d98d vanlogger.py --- /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()