Mercurial > ~darius > hgwebdir.cgi > vanlogger
view vanlogger.py @ 11:e1bec6dfd524
Improve start/end/days handling
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Fri, 22 Dec 2017 13:19:43 +0100 |
parents | f77cc29d0b47 |
children | 65be58857ed4 59cf68be7feb bacb798e6731 |
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 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 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()