forked from richo/homeassistant-franklinwh
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy path__init__.py
More file actions
124 lines (102 loc) · 4.1 KB
/
__init__.py
File metadata and controls
124 lines (102 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""The FranklinWH integration.
Complete rewrite by Joshua Seidel (@JoshuaSeidel) with Anthropic Claude Sonnet 4.5.
Originally inspired by @richo's homeassistant-franklinwh integration.
Uses the franklinwh-python library by @richo.
"""
from __future__ import annotations
import logging
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
import voluptuous as vol
from .const import (
CONF_GATEWAY_ID,
CONF_LOCAL_HOST,
CONF_USE_LOCAL_API,
DOMAIN,
SERVICE_SET_BATTERY_RESERVE,
SERVICE_SET_OPERATION_MODE,
)
from .coordinator import FranklinWHCoordinator
_LOGGER = logging.getLogger(__name__)
PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.SWITCH]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up FranklinWH from a config entry."""
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
gateway_id = entry.data[CONF_GATEWAY_ID]
use_local_api = entry.data.get(CONF_USE_LOCAL_API, False)
local_host = entry.data.get(CONF_LOCAL_HOST)
# Create coordinator
coordinator = FranklinWHCoordinator(
hass=hass,
username=username,
password=password,
gateway_id=gateway_id,
use_local_api=use_local_api,
local_host=local_host,
)
# Fetch initial data
try:
await coordinator.async_config_entry_first_refresh()
_LOGGER.debug("FranklinWH initial data fetch complete")
except ConfigEntryAuthFailed as err:
_LOGGER.error("Authentication failed: %s", err)
raise
except Exception as err:
_LOGGER.error("Error setting up FranklinWH: %s", err)
raise ConfigEntryNotReady from err
# Store coordinator
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = coordinator
# Set up platforms
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
# Register services
async def handle_set_operation_mode(call: ServiceCall) -> None:
"""Handle the set_operation_mode service call."""
mode = call.data.get("mode")
try:
await coordinator.async_set_operation_mode(mode)
except Exception as err:
_LOGGER.error("Failed to set operation mode: %s", err)
async def handle_set_battery_reserve(call: ServiceCall) -> None:
"""Handle the set_battery_reserve service call."""
reserve_percent = call.data.get("reserve_percent")
try:
await coordinator.async_set_battery_reserve(reserve_percent)
except Exception as err:
_LOGGER.error("Failed to set battery reserve: %s", err)
# Register services only once
if not hass.services.has_service(DOMAIN, SERVICE_SET_OPERATION_MODE):
hass.services.async_register(
DOMAIN,
SERVICE_SET_OPERATION_MODE,
handle_set_operation_mode,
schema=vol.Schema(
{
vol.Required("mode"): vol.In(
["self_use", "backup", "time_of_use", "clean_backup"]
)
}
),
)
if not hass.services.has_service(DOMAIN, SERVICE_SET_BATTERY_RESERVE):
hass.services.async_register(
DOMAIN,
SERVICE_SET_BATTERY_RESERVE,
handle_set_battery_reserve,
schema=vol.Schema(
{vol.Required("reserve_percent"): vol.All(vol.Coerce(int), vol.Range(min=0, max=100))}
),
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload config entry."""
await async_unload_entry(hass, entry)
await async_setup_entry(hass, entry)