Skip to content

Commit f3ab228

Browse files
committed
Add Energy Calculator script to poll InfluxDB for energy values #593
1 parent 680c953 commit f3ab228

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

tools/energy/README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Energy Calculator
2+
3+
This script polls the InfluxDB to compute energy (kWh) for a specified time period.
4+
5+
## Setup
6+
7+
Install influxdb library:
8+
9+
```bash
10+
pip install influxdb
11+
```
12+
13+
## Usage
14+
15+
```
16+
Usage: python energy.py -s <start_time> -e <end_time> -h <host> -p <port> -u <username> -w <password> -d <database> -j
17+
-s <start_time> Start time in the format 'YYYY-MM-DDTHH:MM:SSZ'
18+
-e <end_time> End time in the format 'YYYY-MM-DDTHH:MM:SSZ'
19+
-h <host> InfluxDB host (default is 'localhost')
20+
-p <port> InfluxDB port (default is 8086)
21+
-u <username> InfluxDB username
22+
-w <password> InfluxDB password
23+
-d <database> InfluxDB database (default is 'powerwall')
24+
-j Output JSON format
25+
```
26+
27+
## Examples
28+
29+
### Default Time Range
30+
31+
```bash
32+
python3 energy.py -h 192.168.1.100
33+
```
34+
35+
```
36+
Energy Calculator
37+
-----------------
38+
Enter start time [2025-01-01T00:00:00Z]:
39+
Enter end time [2025-01-31T23:59:59Z]:
40+
41+
Connecting to InfluxDB at 192.168.1.100:8086 as None using database powerwall...
42+
43+
Querying energy values from 2025-01-01T00:00:00Z to 2025-01-31T23:59:59Z...
44+
45+
Energy values:
46+
47+
Home Solar PW In PW Out Grid In Grid Out
48+
------------------------------------------------------------------------------------------
49+
937.87 kWh 589.30 kWh 415.75 kWh 469.55 kWh 441.60 kWh 39.13 kWh
50+
```
51+
52+
### Specify Range
53+
54+
```bash
55+
python3 energy.py -h 192.168.1.100 -s "2024-01-01T00:00:00Z" -e "2025-01-31T23:59:59Z"
56+
```
57+
58+
```
59+
Energy Calculator
60+
-----------------
61+
Start time: 2024-01-01T00:00:00Z
62+
End time: 2025-01-31T23:59:59Z
63+
64+
Connecting to InfluxDB at 192.168.1.100:8086 as None using database powerwall...
65+
66+
Querying energy values from 2024-01-01T00:00:00Z to 2025-01-31T23:59:59Z...
67+
68+
Energy values:
69+
70+
Home Solar PW In PW Out Grid In Grid Out
71+
------------------------------------------------------------------------------------------
72+
14.10 MWh 12.42 MWh 6.10 MWh 6.74 MWh 4.38 MWh 2.06 MWh
73+
```
74+
75+
### JSON Output
76+
77+
```bash
78+
python3 energy.py -h 10.0.1.26 -s "2024-01-01T00:00:00Z" -e "2025-01-01T00:00:00Z" -j
79+
```
80+
81+
```json
82+
{
83+
"home": 13165.40484380579,
84+
"solar": 11831.718628749133,
85+
"from_pw": 5686.209712180349,
86+
"to_pw": 6273.8019262416665,
87+
"from_grid": 3939.267602490971,
88+
"to_grid": 2016.390444631733
89+
}
90+
```

tools/energy/energy.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env python
2+
"""
3+
Polls the InfluxDB database for energy values and prints them to the console.
4+
5+
Requires the InfluxDB Python client library:
6+
pip install influxdb
7+
8+
Usage:
9+
energy.py -s <start_time> -e <end_time> -h <host> -p <port>
10+
-u <username> -w <password> -d <database> -j
11+
where:
12+
<start_time> and <end_time> are in the format "YYYY-MM-DDTHH:MM:SSZ"
13+
<host> is the InfluxDB host (default is "localhost")
14+
e.g. python energy.py -s "2025-01-01T00:00:00Z" -e "2025-01-31T23:59:59Z" -h "localhost"
15+
16+
The script will print the energy values for the specified time range.
17+
18+
By: Jason Cox
19+
Date: 1 March 2025
20+
github.com/jasonacox/Powerwall-Dashboard
21+
22+
"""
23+
import sys
24+
import getopt
25+
from influxdb import InfluxDBClient
26+
import json
27+
28+
# Defaults
29+
host = "localhost"
30+
port = 8086
31+
username = None
32+
password = None
33+
database = "powerwall"
34+
start_time = None
35+
end_time = None
36+
json_output = False
37+
38+
# Process command line arguments
39+
def usage():
40+
print("Usage: python energy.py -s <start_time> -e <end_time> -h <host> -p <port> -u <username> -w <password> -d <database> -j")
41+
print(" -s <start_time> Start time in the format 'YYYY-MM-DDTHH:MM:SSZ'")
42+
print(" -e <end_time> End time in the format 'YYYY-MM-DDTHH:MM:SSZ'")
43+
print(" -h <host> InfluxDB host (default is 'localhost')")
44+
print(" -p <port> InfluxDB port (default is 8086)")
45+
print(" -u <username> InfluxDB username")
46+
print(" -w <password> InfluxDB password")
47+
print(" -d <database> InfluxDB database (default is 'powerwall')")
48+
print(" -j Output JSON format")
49+
sys.exit(2)
50+
51+
try:
52+
opts, args = getopt.getopt(sys.argv[1:], "s:e:h:p:u:w:d:j")
53+
except getopt.GetoptError:
54+
usage()
55+
56+
for opt, arg in opts:
57+
if opt == '-s':
58+
start_time = arg
59+
elif opt == '-e':
60+
end_time = arg
61+
elif opt == '-h':
62+
host = arg
63+
elif opt == '-p':
64+
port = int(arg)
65+
elif opt == '-u':
66+
username = arg
67+
elif opt == '-w':
68+
password = arg
69+
elif opt == '-d':
70+
database = arg
71+
elif opt == '-j':
72+
json_output = True
73+
74+
# Print Header
75+
if not json_output:
76+
print("Energy Calculator")
77+
print("-----------------")
78+
# Ask user for start and end time if not provided
79+
if not start_time:
80+
start_time = "2025-01-01T00:00:00Z"
81+
user = input(f"Enter start time [{start_time}]: ")
82+
if user:
83+
start_time = user
84+
else:
85+
print(f"Start time: {start_time}")
86+
if not end_time:
87+
end_time = "2025-01-31T23:59:59Z"
88+
user = input(f"Enter end time [{end_time}]: ")
89+
if user:
90+
end_time = user
91+
else:
92+
print(f"End time: {end_time}")
93+
print("")
94+
else:
95+
# Ensure start and end time are provided
96+
if not start_time or not end_time:
97+
print("Error: Start and end time must be provided for JSON output")
98+
sys.exit(2)
99+
100+
# Create an InfluxDB client
101+
if not json_output:
102+
print(f"Connecting to InfluxDB at {host}:{port} as {username} using database {database}...")
103+
try:
104+
client = InfluxDBClient(host, port, username, password, database)
105+
client.ping()
106+
except:
107+
print(f"Error: Could not connect to InfluxDB at {host}:{port} as {username} using database {database}")
108+
sys.exit(2)
109+
110+
# Define the query
111+
def get_energy_values(start_time, end_time):
112+
query = f"""
113+
SELECT integral(home)/1000/3600 AS home,
114+
integral(solar)/1000/3600 AS solar,
115+
integral(from_pw)/1000/3600 AS from_pw,
116+
integral(to_pw)/1000/3600 AS to_pw,
117+
integral(from_grid)/1000/3600 AS from_grid,
118+
integral(to_grid)/1000/3600 AS to_grid
119+
FROM powerwall.autogen.http
120+
WHERE time >= '{start_time}' AND time <= '{end_time}'
121+
"""
122+
return query
123+
124+
# Execute the query
125+
if not json_output:
126+
print("")
127+
print(f"Querying energy values from {start_time} to {end_time}...")
128+
try:
129+
result = client.query(get_energy_values(start_time, end_time))
130+
except Exception as e:
131+
print(f"Error: Could not query InfluxDB: {e}")
132+
sys.exit(2)
133+
134+
# Print the results
135+
if json_output:
136+
output = {}
137+
# Convert the result to JSON
138+
for record in result.get_points():
139+
output = {
140+
"home": record['home'],
141+
"solar": record['solar'],
142+
"from_pw": record['from_pw'],
143+
"to_pw": record['to_pw'],
144+
"from_grid": record['from_grid'],
145+
"to_grid": record['to_grid'],
146+
"unit": "kWh"
147+
}
148+
print(json.dumps(output, indent=4))
149+
else:
150+
print("")
151+
print("Energy values:")
152+
print("")
153+
print(f"{'Home':<15}{'Solar':<15}{'PW In':<15}{'PW Out':<15}{'Grid In':<15}{'Grid Out':<15}")
154+
print("-" * 90)
155+
for record in result.get_points():
156+
def format_value(value):
157+
if value < 1000:
158+
return f"{value:.2f} kWh"
159+
else:
160+
return f"{value / 1000:.2f} MWh"
161+
162+
home = format_value(record['home'])
163+
solar = format_value(record['solar'])
164+
from_pw = format_value(record['from_pw'])
165+
to_pw = format_value(record['to_pw'])
166+
from_grid = format_value(record['from_grid'])
167+
to_grid = format_value(record['to_grid'])
168+
169+
print(f"{home:<15}{solar:<15}{from_pw:<15}{to_pw:<15}{from_grid:<15}{to_grid:<15}")
170+
171+
print("")

0 commit comments

Comments
 (0)