Files
matrix64/home_assistant.py

117 lines
3.8 KiB
Python

"""
Home Assistant API client for Matrix64 LED display.
"""
import requests
from config import (
HA_TOKEN, HASS_URL,
BRIGHTNESS_ENTITY_ID, WEATHER_ENTITY_ID,
INTERIOR_TEMP_ENTITY_ID, INTERIOR_HUMIDITY_ENTITY_ID,
TESLA_BATTERY_ENTITY, TESLA_RANGE_ENTITY,
TESLA_CHARGING_ENTITY, TESLA_PLUGGED_ENTITY,
SOLAR_PRODUCTION_ENTITY, SOLAR_BATTERY_ENTITY,
SOLAR_BATTERY_POWER_ENTITY, SOLAR_GRID_POWER_ENTITY,
SOLAR_LOAD_POWER_ENTITY, SOLAR_TODAY_ENERGY_ENTITY,
TESLA_CHARGER_POWER_ENTITY
)
def get_entity_value(entity_id):
"""Fetch entity state from Home Assistant."""
headers = {
"Authorization": f"Bearer {HA_TOKEN}",
"Content-Type": "application/json",
}
url = f"{HASS_URL}/api/states/{entity_id}"
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
return response.json()
else:
print(f"Failed to retrieve entity {entity_id}: {response.text}")
return None
except Exception as e:
print(f"Error fetching {entity_id}: {e}")
return None
def get_weather():
"""Get weather attributes from Home Assistant."""
weather = get_entity_value(WEATHER_ENTITY_ID)
if weather:
return weather.get("attributes", {})
return {}
def get_weather_description():
"""Get current weather state/condition."""
weather = get_entity_value(WEATHER_ENTITY_ID)
if weather:
return weather.get("state", "unknown")
return "unknown"
def get_interior_weather():
"""Get interior temperature and humidity from BTH01-3132 sensor."""
temp_data = get_entity_value(INTERIOR_TEMP_ENTITY_ID)
humidity_data = get_entity_value(INTERIOR_HUMIDITY_ENTITY_ID)
temperature = temp_data.get("state") if temp_data else None
humidity = humidity_data.get("state") if humidity_data else None
return {"humidity": humidity, "temperature": temperature}
def get_brightness():
"""Get screen brightness value."""
brightness = get_entity_value(BRIGHTNESS_ENTITY_ID)
if brightness:
return brightness.get("state")
return None
def get_tesla_status():
"""Get Tesla Model 3 status from Home Assistant."""
battery = get_entity_value(TESLA_BATTERY_ENTITY)
range_km = get_entity_value(TESLA_RANGE_ENTITY)
charging = get_entity_value(TESLA_CHARGING_ENTITY)
plugged = get_entity_value(TESLA_PLUGGED_ENTITY)
return {
"battery": int(float(battery.get("state", 0))) if battery else None,
"range": int(float(range_km.get("state", 0))) if range_km else None,
"charging": charging.get("state") == "on" if charging else False,
"plugged": plugged.get("state") == "on" if plugged else False,
}
def get_solar_status():
"""Get solar/inverter status from Home Assistant."""
production = get_entity_value(SOLAR_PRODUCTION_ENTITY)
battery = get_entity_value(SOLAR_BATTERY_ENTITY)
battery_power = get_entity_value(SOLAR_BATTERY_POWER_ENTITY)
grid_power = get_entity_value(SOLAR_GRID_POWER_ENTITY)
load_power = get_entity_value(SOLAR_LOAD_POWER_ENTITY)
today_energy = get_entity_value(SOLAR_TODAY_ENERGY_ENTITY)
tesla_charger = get_entity_value(TESLA_CHARGER_POWER_ENTITY)
def safe_float(entity, default=None):
if entity:
try:
return float(entity.get("state", 0))
except (ValueError, TypeError):
pass
return default
# Tesla charger power (already in W)
tesla_power_w = safe_float(tesla_charger, 0)
return {
"production": safe_float(production),
"battery_pct": safe_float(battery),
"battery_power": safe_float(battery_power),
"grid_power": safe_float(grid_power),
"load_power": safe_float(load_power),
"today_energy": safe_float(today_energy),
"tesla_power": tesla_power_w,
}