-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Energy Calculator script to poll InfluxDB for energy values #593
- Loading branch information
Showing
2 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Energy Calculator | ||
|
||
This script polls the InfluxDB to compute energy (kWh) for a specified time period. | ||
|
||
## Setup | ||
|
||
Install influxdb library: | ||
|
||
```bash | ||
pip install influxdb | ||
``` | ||
|
||
## Usage | ||
|
||
``` | ||
Usage: python energy.py -s <start_time> -e <end_time> -h <host> -p <port> -u <username> -w <password> -d <database> -j | ||
-s <start_time> Start time in the format 'YYYY-MM-DDTHH:MM:SSZ' | ||
-e <end_time> End time in the format 'YYYY-MM-DDTHH:MM:SSZ' | ||
-h <host> InfluxDB host (default is 'localhost') | ||
-p <port> InfluxDB port (default is 8086) | ||
-u <username> InfluxDB username | ||
-w <password> InfluxDB password | ||
-d <database> InfluxDB database (default is 'powerwall') | ||
-j Output JSON format | ||
``` | ||
|
||
## Examples | ||
|
||
### Default Time Range | ||
|
||
```bash | ||
python3 energy.py -h 192.168.1.100 | ||
``` | ||
|
||
``` | ||
Energy Calculator | ||
----------------- | ||
Enter start time [2025-01-01T00:00:00Z]: | ||
Enter end time [2025-01-31T23:59:59Z]: | ||
Connecting to InfluxDB at 192.168.1.100:8086 as None using database powerwall... | ||
Querying energy values from 2025-01-01T00:00:00Z to 2025-01-31T23:59:59Z... | ||
Energy values: | ||
Home Solar PW In PW Out Grid In Grid Out | ||
------------------------------------------------------------------------------------------ | ||
937.87 kWh 589.30 kWh 415.75 kWh 469.55 kWh 441.60 kWh 39.13 kWh | ||
``` | ||
|
||
### Specify Range | ||
|
||
```bash | ||
python3 energy.py -h 192.168.1.100 -s "2024-01-01T00:00:00Z" -e "2025-01-31T23:59:59Z" | ||
``` | ||
|
||
``` | ||
Energy Calculator | ||
----------------- | ||
Start time: 2024-01-01T00:00:00Z | ||
End time: 2025-01-31T23:59:59Z | ||
Connecting to InfluxDB at 192.168.1.100:8086 as None using database powerwall... | ||
Querying energy values from 2024-01-01T00:00:00Z to 2025-01-31T23:59:59Z... | ||
Energy values: | ||
Home Solar PW In PW Out Grid In Grid Out | ||
------------------------------------------------------------------------------------------ | ||
14.10 MWh 12.42 MWh 6.10 MWh 6.74 MWh 4.38 MWh 2.06 MWh | ||
``` | ||
|
||
### JSON Output | ||
|
||
```bash | ||
python3 energy.py -h 10.0.1.26 -s "2024-01-01T00:00:00Z" -e "2025-01-01T00:00:00Z" -j | ||
``` | ||
|
||
```json | ||
{ | ||
"home": 13165.40484380579, | ||
"solar": 11831.718628749133, | ||
"from_pw": 5686.209712180349, | ||
"to_pw": 6273.8019262416665, | ||
"from_grid": 3939.267602490971, | ||
"to_grid": 2016.390444631733 | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
#!/usr/bin/env python | ||
""" | ||
Polls the InfluxDB database for energy values and prints them to the console. | ||
Requires the InfluxDB Python client library: | ||
pip install influxdb | ||
Usage: | ||
energy.py -s <start_time> -e <end_time> -h <host> -p <port> | ||
-u <username> -w <password> -d <database> -j | ||
where: | ||
<start_time> and <end_time> are in the format "YYYY-MM-DDTHH:MM:SSZ" | ||
<host> is the InfluxDB host (default is "localhost") | ||
e.g. python energy.py -s "2025-01-01T00:00:00Z" -e "2025-01-31T23:59:59Z" -h "localhost" | ||
The script will print the energy values for the specified time range. | ||
By: Jason Cox | ||
Date: 1 March 2025 | ||
github.com/jasonacox/Powerwall-Dashboard | ||
""" | ||
import sys | ||
import getopt | ||
from influxdb import InfluxDBClient | ||
import json | ||
|
||
# Defaults | ||
host = "localhost" | ||
port = 8086 | ||
username = None | ||
password = None | ||
database = "powerwall" | ||
start_time = None | ||
end_time = None | ||
json_output = False | ||
|
||
# Process command line arguments | ||
def usage(): | ||
print("Usage: python energy.py -s <start_time> -e <end_time> -h <host> -p <port> -u <username> -w <password> -d <database> -j") | ||
print(" -s <start_time> Start time in the format 'YYYY-MM-DDTHH:MM:SSZ'") | ||
print(" -e <end_time> End time in the format 'YYYY-MM-DDTHH:MM:SSZ'") | ||
print(" -h <host> InfluxDB host (default is 'localhost')") | ||
print(" -p <port> InfluxDB port (default is 8086)") | ||
print(" -u <username> InfluxDB username") | ||
print(" -w <password> InfluxDB password") | ||
print(" -d <database> InfluxDB database (default is 'powerwall')") | ||
print(" -j Output JSON format") | ||
sys.exit(2) | ||
|
||
try: | ||
opts, args = getopt.getopt(sys.argv[1:], "s:e:h:p:u:w:d:j") | ||
except getopt.GetoptError: | ||
usage() | ||
|
||
for opt, arg in opts: | ||
if opt == '-s': | ||
start_time = arg | ||
elif opt == '-e': | ||
end_time = arg | ||
elif opt == '-h': | ||
host = arg | ||
elif opt == '-p': | ||
port = int(arg) | ||
elif opt == '-u': | ||
username = arg | ||
elif opt == '-w': | ||
password = arg | ||
elif opt == '-d': | ||
database = arg | ||
elif opt == '-j': | ||
json_output = True | ||
|
||
# Print Header | ||
if not json_output: | ||
print("Energy Calculator") | ||
print("-----------------") | ||
# Ask user for start and end time if not provided | ||
if not start_time: | ||
start_time = "2025-01-01T00:00:00Z" | ||
user = input(f"Enter start time [{start_time}]: ") | ||
if user: | ||
start_time = user | ||
else: | ||
print(f"Start time: {start_time}") | ||
if not end_time: | ||
end_time = "2025-01-31T23:59:59Z" | ||
user = input(f"Enter end time [{end_time}]: ") | ||
if user: | ||
end_time = user | ||
else: | ||
print(f"End time: {end_time}") | ||
print("") | ||
else: | ||
# Ensure start and end time are provided | ||
if not start_time or not end_time: | ||
print("Error: Start and end time must be provided for JSON output") | ||
sys.exit(2) | ||
|
||
# Create an InfluxDB client | ||
if not json_output: | ||
print(f"Connecting to InfluxDB at {host}:{port} as {username} using database {database}...") | ||
try: | ||
client = InfluxDBClient(host, port, username, password, database) | ||
client.ping() | ||
except: | ||
print(f"Error: Could not connect to InfluxDB at {host}:{port} as {username} using database {database}") | ||
sys.exit(2) | ||
|
||
# Define the query | ||
def get_energy_values(start_time, end_time): | ||
query = f""" | ||
SELECT integral(home)/1000/3600 AS home, | ||
integral(solar)/1000/3600 AS solar, | ||
integral(from_pw)/1000/3600 AS from_pw, | ||
integral(to_pw)/1000/3600 AS to_pw, | ||
integral(from_grid)/1000/3600 AS from_grid, | ||
integral(to_grid)/1000/3600 AS to_grid | ||
FROM powerwall.autogen.http | ||
WHERE time >= '{start_time}' AND time <= '{end_time}' | ||
""" | ||
return query | ||
|
||
# Execute the query | ||
if not json_output: | ||
print("") | ||
print(f"Querying energy values from {start_time} to {end_time}...") | ||
try: | ||
result = client.query(get_energy_values(start_time, end_time)) | ||
except Exception as e: | ||
print(f"Error: Could not query InfluxDB: {e}") | ||
sys.exit(2) | ||
|
||
# Print the results | ||
if json_output: | ||
output = {} | ||
# Convert the result to JSON | ||
for record in result.get_points(): | ||
output = { | ||
"home": record['home'], | ||
"solar": record['solar'], | ||
"from_pw": record['from_pw'], | ||
"to_pw": record['to_pw'], | ||
"from_grid": record['from_grid'], | ||
"to_grid": record['to_grid'], | ||
"unit": "kWh" | ||
} | ||
print(json.dumps(output, indent=4)) | ||
else: | ||
print("") | ||
print("Energy values:") | ||
print("") | ||
print(f"{'Home':<15}{'Solar':<15}{'PW In':<15}{'PW Out':<15}{'Grid In':<15}{'Grid Out':<15}") | ||
print("-" * 90) | ||
for record in result.get_points(): | ||
def format_value(value): | ||
if value < 1000: | ||
return f"{value:.2f} kWh" | ||
else: | ||
return f"{value / 1000:.2f} MWh" | ||
|
||
home = format_value(record['home']) | ||
solar = format_value(record['solar']) | ||
from_pw = format_value(record['from_pw']) | ||
to_pw = format_value(record['to_pw']) | ||
from_grid = format_value(record['from_grid']) | ||
to_grid = format_value(record['to_grid']) | ||
|
||
print(f"{home:<15}{solar:<15}{from_pw:<15}{to_pw:<15}{from_grid:<15}{to_grid:<15}") | ||
|
||
print("") |