2021-05-24 11:08:24 +00:00
|
|
|
"""The Wallbox integration."""
|
|
|
|
from datetime import timedelta
|
|
|
|
import logging
|
|
|
|
|
|
|
|
import requests
|
|
|
|
from wallbox import Wallbox
|
|
|
|
|
|
|
|
from homeassistant import exceptions
|
|
|
|
from homeassistant.config_entries import ConfigEntry
|
|
|
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
|
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
|
|
|
|
|
|
|
from .const import CONF_CONNECTIONS, CONF_ROUND, CONF_SENSOR_TYPES, CONF_STATION, DOMAIN
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
PLATFORMS = ["sensor"]
|
|
|
|
UPDATE_INTERVAL = 30
|
|
|
|
|
|
|
|
|
|
|
|
class WallboxHub:
|
|
|
|
"""Wallbox Hub class."""
|
|
|
|
|
|
|
|
def __init__(self, station, username, password, hass):
|
|
|
|
"""Initialize."""
|
|
|
|
self._station = station
|
|
|
|
self._username = username
|
|
|
|
self._password = password
|
|
|
|
self._wallbox = Wallbox(self._username, self._password)
|
|
|
|
self._hass = hass
|
|
|
|
self._coordinator = DataUpdateCoordinator(
|
|
|
|
hass,
|
|
|
|
_LOGGER,
|
|
|
|
# Name of the data. For logging purposes.
|
|
|
|
name="wallbox",
|
|
|
|
update_method=self.async_get_data,
|
|
|
|
# Polling interval. Will only be polled if there are subscribers.
|
|
|
|
update_interval=timedelta(seconds=UPDATE_INTERVAL),
|
|
|
|
)
|
|
|
|
|
|
|
|
def _authenticate(self):
|
|
|
|
"""Authenticate using Wallbox API."""
|
|
|
|
try:
|
|
|
|
self._wallbox.authenticate()
|
|
|
|
return True
|
|
|
|
except requests.exceptions.HTTPError as wallbox_connection_error:
|
|
|
|
if wallbox_connection_error.response.status_code == 403:
|
|
|
|
raise InvalidAuth from wallbox_connection_error
|
|
|
|
raise ConnectionError from wallbox_connection_error
|
|
|
|
|
|
|
|
def _get_data(self):
|
|
|
|
"""Get new sensor data for Wallbox component."""
|
|
|
|
try:
|
|
|
|
self._authenticate()
|
|
|
|
data = self._wallbox.getChargerStatus(self._station)
|
|
|
|
|
|
|
|
filtered_data = {k: data[k] for k in CONF_SENSOR_TYPES if k in data}
|
|
|
|
|
|
|
|
for key, value in filtered_data.items():
|
2021-10-18 13:54:38 +00:00
|
|
|
if sensor_round := CONF_SENSOR_TYPES[key][CONF_ROUND]:
|
2021-05-24 11:08:24 +00:00
|
|
|
try:
|
|
|
|
filtered_data[key] = round(value, sensor_round)
|
|
|
|
except TypeError:
|
|
|
|
_LOGGER.debug("Cannot format %s", key)
|
|
|
|
|
|
|
|
return filtered_data
|
|
|
|
except requests.exceptions.HTTPError as wallbox_connection_error:
|
|
|
|
raise ConnectionError from wallbox_connection_error
|
|
|
|
|
|
|
|
async def async_coordinator_first_refresh(self):
|
|
|
|
"""Refresh coordinator for the first time."""
|
|
|
|
await self._coordinator.async_config_entry_first_refresh()
|
|
|
|
|
|
|
|
async def async_authenticate(self) -> bool:
|
|
|
|
"""Authenticate using Wallbox API."""
|
|
|
|
return await self._hass.async_add_executor_job(self._authenticate)
|
|
|
|
|
|
|
|
async def async_get_data(self) -> bool:
|
|
|
|
"""Get new sensor data for Wallbox component."""
|
|
|
|
data = await self._hass.async_add_executor_job(self._get_data)
|
|
|
|
return data
|
|
|
|
|
|
|
|
@property
|
|
|
|
def coordinator(self):
|
|
|
|
"""Return the coordinator."""
|
|
|
|
return self._coordinator
|
|
|
|
|
|
|
|
|
2021-05-27 15:39:06 +00:00
|
|
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
2021-05-24 11:08:24 +00:00
|
|
|
"""Set up Wallbox from a config entry."""
|
|
|
|
wallbox = WallboxHub(
|
|
|
|
entry.data[CONF_STATION],
|
|
|
|
entry.data[CONF_USERNAME],
|
|
|
|
entry.data[CONF_PASSWORD],
|
|
|
|
hass,
|
|
|
|
)
|
|
|
|
|
|
|
|
await wallbox.async_authenticate()
|
|
|
|
|
|
|
|
await wallbox.async_coordinator_first_refresh()
|
|
|
|
|
|
|
|
hass.data.setdefault(DOMAIN, {CONF_CONNECTIONS: {}})
|
|
|
|
hass.data[DOMAIN][CONF_CONNECTIONS][entry.entry_id] = wallbox
|
|
|
|
|
|
|
|
for platform in PLATFORMS:
|
|
|
|
hass.async_create_task(
|
|
|
|
hass.config_entries.async_forward_entry_setup(entry, platform)
|
|
|
|
)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2021-10-06 08:48:11 +00:00
|
|
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
2021-05-24 11:08:24 +00:00
|
|
|
"""Unload a config entry."""
|
2021-06-10 07:56:35 +00:00
|
|
|
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
2021-05-24 11:08:24 +00:00
|
|
|
if unload_ok:
|
|
|
|
hass.data[DOMAIN]["connections"].pop(entry.entry_id)
|
|
|
|
|
|
|
|
return unload_ok
|
|
|
|
|
|
|
|
|
|
|
|
class InvalidAuth(exceptions.HomeAssistantError):
|
|
|
|
"""Error to indicate there is invalid auth."""
|