Switch PV curve to HA History API for full day data
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
Home Assistant API client for Matrix64 LED display.
|
Home Assistant API client for Matrix64 LED display.
|
||||||
"""
|
"""
|
||||||
import requests
|
import requests
|
||||||
|
import datetime
|
||||||
from config import (
|
from config import (
|
||||||
HA_TOKEN, HASS_URL,
|
HA_TOKEN, HASS_URL,
|
||||||
BRIGHTNESS_ENTITY_ID, WEATHER_ENTITY_ID,
|
BRIGHTNESS_ENTITY_ID, WEATHER_ENTITY_ID,
|
||||||
@@ -114,3 +115,47 @@ def get_solar_status():
|
|||||||
"today_energy": safe_float(today_energy),
|
"today_energy": safe_float(today_energy),
|
||||||
"tesla_power": tesla_power_w,
|
"tesla_power": tesla_power_w,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_solar_history():
|
||||||
|
"""Get today's solar production history from HA History API.
|
||||||
|
Returns list of (hour_float, watts) tuples."""
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {HA_TOKEN}",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
url = (f"{HASS_URL}/api/history/period/{start_str}"
|
||||||
|
f"?filter_entity_id={SOLAR_PRODUCTION_ENTITY}"
|
||||||
|
f"&minimal_response&no_attributes")
|
||||||
|
try:
|
||||||
|
response = requests.get(url, headers=headers, timeout=15)
|
||||||
|
if response.status_code != 200:
|
||||||
|
return []
|
||||||
|
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):
|
||||||
|
continue
|
||||||
|
return points
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error fetching solar history: {e}")
|
||||||
|
return []
|
||||||
|
|||||||
22
matrix.py
22
matrix.py
@@ -26,7 +26,7 @@ from weather_icons import draw_weather_icon
|
|||||||
from home_assistant import (
|
from home_assistant import (
|
||||||
get_weather, get_weather_description,
|
get_weather, get_weather_description,
|
||||||
get_interior_weather, get_brightness, get_tesla_status,
|
get_interior_weather, get_brightness, get_tesla_status,
|
||||||
get_solar_status
|
get_solar_status, get_solar_history
|
||||||
)
|
)
|
||||||
from netdata import get_hdd_temps
|
from netdata import get_hdd_temps
|
||||||
from mqtt_listener import MQTTListener
|
from mqtt_listener import MQTTListener
|
||||||
@@ -133,8 +133,8 @@ class Matrix64Display(SampleBase):
|
|||||||
self.hdd_temps = None
|
self.hdd_temps = None
|
||||||
self.tesla = None
|
self.tesla = None
|
||||||
self.solar = None
|
self.solar = None
|
||||||
self.pv_history = [] # list of (timestamp, production_w) for today's curve
|
self.pv_history = [] # list of (hour_float, watts) from HA history
|
||||||
self.pv_history_date = None # track current day to reset history
|
self.last_pv_history_update = 0
|
||||||
|
|
||||||
# View state
|
# View state
|
||||||
self.current_view = 0
|
self.current_view = 0
|
||||||
@@ -259,14 +259,6 @@ class Matrix64Display(SampleBase):
|
|||||||
|
|
||||||
self.tesla = get_tesla_status()
|
self.tesla = get_tesla_status()
|
||||||
self.solar = get_solar_status()
|
self.solar = get_solar_status()
|
||||||
# Record PV history for today's curve
|
|
||||||
if self.solar and self.solar.get("production") is not None:
|
|
||||||
now = datetime.datetime.now()
|
|
||||||
today = now.date()
|
|
||||||
if self.pv_history_date != today:
|
|
||||||
self.pv_history = []
|
|
||||||
self.pv_history_date = today
|
|
||||||
self.pv_history.append((now.hour + now.minute / 60.0, self.solar["production"]))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error updating data: {e}")
|
print(f"Error updating data: {e}")
|
||||||
|
|
||||||
@@ -814,6 +806,14 @@ class Matrix64Display(SampleBase):
|
|||||||
self.update_hdd_temps()
|
self.update_hdd_temps()
|
||||||
self.last_update = current_time
|
self.last_update = current_time
|
||||||
|
|
||||||
|
# Update PV history every 5 minutes
|
||||||
|
if current_time - self.last_pv_history_update >= 300:
|
||||||
|
try:
|
||||||
|
self.pv_history = get_solar_history()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error updating PV history: {e}")
|
||||||
|
self.last_pv_history_update = current_time
|
||||||
|
|
||||||
if current_time - self.last_update >= 15:
|
if current_time - self.last_update >= 15:
|
||||||
self.update_brightness()
|
self.update_brightness()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user