Mercurial > ~darius > hgwebdir.cgi > vanlogger
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78148730d98d |
---|---|
1 #!/usr/bin/env python | |
2 | |
3 import sys | |
4 | |
5 sys.path.append('/home/pi/logger') | |
6 import datetime | |
7 import epro.epro as epro | |
8 import giant.giant as giant | |
9 import serial | |
10 import sqlite3 | |
11 | |
12 def create(cur): | |
13 cur.execute(''' | |
14 CREATE TABLE IF NOT EXISTS eprolog( | |
15 tstamp INTEGER NOT NULL, | |
16 main_voltage REAL NOT NULL, | |
17 aux_voltage REAL NOT NULL, | |
18 battery_curr REAL NOT NULL, | |
19 amp_hours REAL NOT NULL, | |
20 state_of_charge REAL NOT NULL, | |
21 time_remaining REAL NOT NULL, | |
22 battery_temp REAL, | |
23 auto_sync_volts BOOLEAN NOT NULL, | |
24 auto_sync_curr BOOLEAN NOT NULL, | |
25 e501 BOOLEAN NOT NULL, | |
26 alarm_test BOOLEAN NOT NULL, | |
27 light BOOLEAN NOT NULL, | |
28 display_test BOOLEAN NOT NULL, | |
29 temp_sensor BOOLEAN NOT NULL, | |
30 aux_hv BOOLEAN NOT NULL, | |
31 aux_lv BOOLEAN NOT NULL, | |
32 installer_lock BOOLEAN NOT NULL, | |
33 main_hv BOOLEAN NOT NULL, | |
34 main_lv BOOLEAN NOT NULL, | |
35 low_battery BOOLEAN NOT NULL, | |
36 battery_flat BOOLEAN NOT NULL, | |
37 battery_full BOOLEAN NOT NULL, | |
38 battery_charged BOOLEAN NOT NULL, | |
39 no_sync BOOLEAN NOT NULL, | |
40 monitor_reset BOOLEAN NOT NULL | |
41 ); | |
42 ''') | |
43 | |
44 cur.execute(''' | |
45 CREATE TABLE IF NOT EXISTS giantlog( | |
46 tstamp INTEGER NOT NULL, | |
47 ac_act_power REAL NOT NULL, | |
48 ac_app_power REAL NOT NULL, | |
49 ac_frequency REAL NOT NULL, | |
50 ac_volts REAL NOT NULL, | |
51 batt_chr_curr REAL NOT NULL, | |
52 batt_dis_curr REAL NOT NULL, | |
53 battery_cap REAL NOT NULL, | |
54 battery_volts REAL NOT NULL, | |
55 batt_volt_ofs REAL NOT NULL, | |
56 bus_voltage REAL NOT NULL, | |
57 grid_frequency REAL NOT NULL, | |
58 grid_volts REAL NOT NULL, | |
59 hs_temperature REAL NOT NULL, | |
60 load_pct REAL NOT NULL, | |
61 pv1_chrg_pow REAL NOT NULL, | |
62 pv1_current REAL NOT NULL, | |
63 pv1_volts REAL NOT NULL, | |
64 scc1_volts REAL NOT NULL, | |
65 scc1_charging BOOLEAN NOT NULL, | |
66 switch BOOLEAN NOT NULL, | |
67 float_charge BOOLEAN NOT NULL, | |
68 ac_charging BOOLEAN NOT NULL, | |
69 sbu_prio BOOLEAN NOT NULL, | |
70 b_volt_steady BOOLEAN NOT NULL, | |
71 charging BOOLEAN NOT NULL | |
72 ); | |
73 ''') | |
74 | |
75 def log_epro(p, cur): | |
76 # Check we have all the packets we need in the queue | |
77 msgtypes = set([x.msgtype for x in p.packets]) | |
78 wantedtypes = set([ | |
79 epro.MainVoltage.MSGTYPE, | |
80 epro.AmpHours.MSGTYPE, | |
81 epro.BatteryCurrent.MSGTYPE, | |
82 epro.StateOfCharge.MSGTYPE, | |
83 epro.TimeRemaining.MSGTYPE, | |
84 epro.BatteryTemperature.MSGTYPE, | |
85 epro.MonitorStatus.MSGTYPE, | |
86 epro.AuxVoltage.MSGTYPE, | |
87 ]) | |
88 if msgtypes < wantedtypes: | |
89 return | |
90 | |
91 row = {} | |
92 usedtypes = set() | |
93 while len(p.packets) > 0: | |
94 pkt = p.packets.pop() # Read latest packets first | |
95 if pkt.msgtype == epro.MainVoltage.MSGTYPE: | |
96 row['main_voltage'] = pkt.volts | |
97 elif pkt.msgtype == epro.AmpHours.MSGTYPE: | |
98 row['amp_hours'] = pkt.amphrs | |
99 elif pkt.msgtype == epro.BatteryCurrent.MSGTYPE: | |
100 row['battery_curr'] = pkt.amps | |
101 elif pkt.msgtype == epro.StateOfCharge.MSGTYPE: | |
102 row['state_of_charge'] = pkt.soc | |
103 elif pkt.msgtype == epro.TimeRemaining.MSGTYPE: | |
104 row['time_remaining'] = pkt.time | |
105 elif pkt.msgtype == epro.BatteryTemperature.MSGTYPE: | |
106 row['battery_temp'] = pkt.temp | |
107 elif pkt.msgtype == epro.MonitorStatus.MSGTYPE: | |
108 row['auto_sync_volts'] = pkt.autosyncvolt | |
109 row['auto_sync_curr'] = pkt.autosyncamp | |
110 row['e501'] = pkt.e501compat | |
111 row['alarm_test'] = pkt.alarmtst | |
112 row['light'] = pkt.backlight | |
113 row['display_test'] = pkt.disptst | |
114 row['temp_sensor'] = pkt.tempsense | |
115 row['aux_hv'] = pkt.auxhv | |
116 row['aux_lv'] = pkt.auxlv | |
117 row['installer_lock'] = pkt.lock | |
118 row['main_hv'] = pkt.mainhv | |
119 row['main_lv'] = pkt.mainlv | |
120 row['low_battery'] = pkt.lowbatalarm | |
121 row['battery_flat'] = pkt.batflat | |
122 row['battery_full'] = pkt.batfull | |
123 row['battery_charged'] = pkt.charged | |
124 row['no_sync'] = pkt.nosync | |
125 row['monitor_reset'] = pkt.monreset | |
126 elif pkt.msgtype == epro.AuxVoltage.MSGTYPE: | |
127 row['aux_voltage'] = pkt.volts | |
128 | |
129 usedtypes.add(pkt.msgtype) | |
130 if usedtypes >= wantedtypes: | |
131 p.packets = [] | |
132 break | |
133 | |
134 row['tstamp'] = int(datetime.datetime.now().strftime('%s')) | |
135 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) | |
136 | |
137 def log_giant(gstat, cur): | |
138 row = {} | |
139 row['ac_act_power'] = gstat['ACActPower'] | |
140 row['ac_app_power'] = gstat['ACAppPower'] | |
141 row['ac_frequency'] = gstat['ACFreq'] | |
142 row['ac_volts'] = gstat['ACVolts'] | |
143 row['batt_chr_curr'] = gstat['BattChrCurr'] | |
144 row['batt_dis_curr'] = gstat['BattDisCurr'] | |
145 row['battery_cap'] = gstat['BattCap'] | |
146 row['battery_volts'] = gstat['BattVolts'] | |
147 row['batt_volt_ofs'] = gstat['BattVoltOfs'] | |
148 row['bus_voltage'] = gstat['BusVolts'] | |
149 row['grid_frequency'] = gstat['GridFreq'] | |
150 row['grid_volts'] = gstat['GridVolts'] | |
151 row['hs_temperature'] = gstat['HSTemp'] | |
152 row['load_pct'] = gstat['LoadPct'] | |
153 row['pv1_chrg_pow'] = gstat['PVChrgPow1'] | |
154 row['pv1_current'] = gstat['PVCurr1'] | |
155 row['pv1_volts'] = gstat['PVVolt1'] | |
156 row['scc1_volts'] = gstat['SCC1Volt'] | |
157 row['scc1_charging'] = gstat['Status']['SCC1Charging'] | |
158 row['switch'] = gstat['Status']['Switch'] | |
159 row['float_charge'] = gstat['Status']['FloatCharge'] | |
160 if gstat['Status']['ChargeType'] == 'Both' or gstat['Status']['ChargeType'] == 'AC': | |
161 row['ac_charging'] = True | |
162 else: | |
163 row['ac_charging'] = False | |
164 row['sbu_prio'] = gstat['Status']['SBUPrio'] | |
165 row['b_volt_steady'] = gstat['Status']['BattVoltSteady'] | |
166 row['charging'] = gstat['Status']['Charging'] | |
167 | |
168 row['tstamp'] = int(datetime.datetime.now().strftime('%s')) | |
169 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) | |
170 | |
171 def main(): | |
172 dbh = sqlite3.connect('/home/pi/vanlogger/log.db') | |
173 cur = dbh.cursor() | |
174 create(cur) | |
175 s = serial.Serial('/dev/ttyUSB0', 2400, parity='E') | |
176 s.timeout = 0.2 | |
177 | |
178 p = epro.Processor() | |
179 ips = giant.GiantIPS() | |
180 | |
181 then = None | |
182 while True: | |
183 dolog = False | |
184 if then == None or datetime.datetime.now() - then > datetime.timedelta(seconds = 60): | |
185 dolog = True | |
186 print('Logging') | |
187 then = datetime.datetime.now() | |
188 p.process(s.read(1024)) | |
189 if dolog: | |
190 log_epro(p, cur) | |
191 dbh.commit() | |
192 | |
193 gstat = None | |
194 try: | |
195 gstat = ips.getStatus() | |
196 except: | |
197 pass | |
198 if gstat != None and dolog: | |
199 log_giant(gstat, cur) | |
200 dbh.commit() | |
201 #print(gstat) | |
202 | |
203 if __name__ == '__main__': | |
204 main() |