Add consumption curve to PV graph, fix text-curve overlap

This commit is contained in:
Joan
2026-03-20 13:33:20 +01:00
parent be3d23bb79
commit b038f2ee8f
2 changed files with 97 additions and 74 deletions

View File

@@ -118,8 +118,8 @@ def get_solar_status():
def get_solar_history():
"""Get today's solar production history from HA History API.
Returns list of (hour_float, watts) tuples."""
"""Get today's solar production and consumption history from HA History API.
Returns dict with 'production' and 'consumption' lists of (hour_float, watts)."""
headers = {
"Authorization": f"Bearer {HA_TOKEN}",
"Content-Type": "application/json",
@@ -127,35 +127,45 @@ def get_solar_history():
now = datetime.datetime.now()
start = now.replace(hour=0, minute=0, second=0, microsecond=0)
start_str = start.strftime("%Y-%m-%dT%H:%M:%S")
entities = f"{SOLAR_PRODUCTION_ENTITY},{SOLAR_LOAD_POWER_ENTITY}"
url = (f"{HASS_URL}/api/history/period/{start_str}"
f"?filter_entity_id={SOLAR_PRODUCTION_ENTITY}"
f"?filter_entity_id={entities}"
f"&minimal_response&no_attributes")
try:
response = requests.get(url, headers=headers, timeout=15)
if response.status_code != 200:
return []
return {"production": [], "consumption": []}
data = response.json()
if not data or not data[0]:
return []
points = []
for entry in data[0]:
try:
state = float(entry.get("state", 0))
ts = entry.get("last_changed", "")
# Parse ISO timestamp
if "+" in ts:
ts = ts.split("+")[0]
elif ts.endswith("Z"):
ts = ts[:-1]
dt = datetime.datetime.fromisoformat(ts)
# Convert UTC to local time
utc_offset = now - datetime.datetime.utcnow()
dt_local = dt + utc_offset
hour_f = dt_local.hour + dt_local.minute / 60.0
points.append((hour_f, state))
except (ValueError, TypeError):
utc_offset = now - datetime.datetime.utcnow()
def parse_entries(entries):
points = []
for entry in entries:
try:
state = float(entry.get("state", 0))
ts = entry.get("last_changed", "")
if "+" in ts:
ts = ts.split("+")[0]
elif ts.endswith("Z"):
ts = ts[:-1]
dt = datetime.datetime.fromisoformat(ts)
dt_local = dt + utc_offset
hour_f = dt_local.hour + dt_local.minute / 60.0
points.append((hour_f, state))
except (ValueError, TypeError):
continue
return points
result = {"production": [], "consumption": []}
for entity_data in data:
if not entity_data:
continue
return points
entity_id = entity_data[0].get("entity_id", "")
if entity_id == SOLAR_PRODUCTION_ENTITY:
result["production"] = parse_entries(entity_data)
elif entity_id == SOLAR_LOAD_POWER_ENTITY:
result["consumption"] = parse_entries(entity_data)
return result
except Exception as e:
print(f"Error fetching solar history: {e}")
return []
return {"production": [], "consumption": []}