1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00
ha-core/homeassistant/components/starline/account.py
epenet 1a5333f376
Use DeviceInfo in starline (#58576)
Co-authored-by: epenet <epenet@users.noreply.github.com>
2021-10-28 09:40:01 +02:00

179 lines
6.1 KiB
Python

"""StarLine Account."""
from __future__ import annotations
from collections.abc import Callable
from datetime import datetime, timedelta
from typing import Any
from starline import StarlineApi, StarlineDevice
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.event import async_track_time_interval
from .const import (
_LOGGER,
DATA_EXPIRES,
DATA_SLID_TOKEN,
DATA_SLNET_TOKEN,
DATA_USER_ID,
DEFAULT_SCAN_INTERVAL,
DEFAULT_SCAN_OBD_INTERVAL,
DOMAIN,
)
class StarlineAccount:
"""StarLine Account class."""
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Initialize StarLine account."""
self._hass: HomeAssistant = hass
self._config_entry: ConfigEntry = config_entry
self._update_interval: int = DEFAULT_SCAN_INTERVAL
self._update_obd_interval: int = DEFAULT_SCAN_OBD_INTERVAL
self._unsubscribe_auto_updater: Callable | None = None
self._unsubscribe_auto_obd_updater: Callable | None = None
self._api: StarlineApi = StarlineApi(
config_entry.data[DATA_USER_ID], config_entry.data[DATA_SLNET_TOKEN]
)
def _check_slnet_token(self, interval: int) -> None:
"""Check SLNet token expiration and update if needed."""
now = datetime.now().timestamp()
slnet_token_expires = self._config_entry.data[DATA_EXPIRES]
if now + interval > slnet_token_expires:
self._update_slnet_token()
def _update_slnet_token(self) -> None:
"""Update SLNet token."""
slid_token = self._config_entry.data[DATA_SLID_TOKEN]
try:
slnet_token, slnet_token_expires, user_id = self._api.get_user_id(
slid_token
)
self._api.set_slnet_token(slnet_token)
self._api.set_user_id(user_id)
self._hass.config_entries.async_update_entry(
self._config_entry,
data={
**self._config_entry.data,
DATA_SLNET_TOKEN: slnet_token,
DATA_EXPIRES: slnet_token_expires,
DATA_USER_ID: user_id,
},
)
except Exception as err: # pylint: disable=broad-except
_LOGGER.error("Error updating SLNet token: %s", err)
def _update_data(self):
"""Update StarLine data."""
self._check_slnet_token(self._update_interval)
self._api.update()
def _update_obd_data(self):
"""Update StarLine OBD data."""
self._check_slnet_token(self._update_obd_interval)
self._api.update_obd()
@property
def api(self) -> StarlineApi:
"""Return the instance of the API."""
return self._api
async def update(self, unused=None):
"""Update StarLine data."""
await self._hass.async_add_executor_job(self._update_data)
async def update_obd(self, unused=None):
"""Update StarLine OBD data."""
await self._hass.async_add_executor_job(self._update_obd_data)
def set_update_interval(self, interval: int) -> None:
"""Set StarLine API update interval."""
_LOGGER.debug("Setting update interval: %ds", interval)
self._update_interval = interval
if self._unsubscribe_auto_updater is not None:
self._unsubscribe_auto_updater()
delta = timedelta(seconds=interval)
self._unsubscribe_auto_updater = async_track_time_interval(
self._hass, self.update, delta
)
def set_update_obd_interval(self, interval: int) -> None:
"""Set StarLine API OBD update interval."""
_LOGGER.debug("Setting OBD update interval: %ds", interval)
self._update_obd_interval = interval
if self._unsubscribe_auto_obd_updater is not None:
self._unsubscribe_auto_obd_updater()
delta = timedelta(seconds=interval)
self._unsubscribe_auto_obd_updater = async_track_time_interval(
self._hass, self.update_obd, delta
)
def unload(self):
"""Unload StarLine API."""
_LOGGER.debug("Unloading StarLine API")
if self._unsubscribe_auto_updater is not None:
self._unsubscribe_auto_updater()
self._unsubscribe_auto_updater = None
if self._unsubscribe_auto_obd_updater is not None:
self._unsubscribe_auto_obd_updater()
self._unsubscribe_auto_obd_updater = None
@staticmethod
def device_info(device: StarlineDevice) -> DeviceInfo:
"""Device information for entities."""
return DeviceInfo(
identifiers={(DOMAIN, device.device_id)},
manufacturer="StarLine",
model=device.typename,
name=device.name,
sw_version=device.fw_version,
)
@staticmethod
def gps_attrs(device: StarlineDevice) -> dict[str, Any]:
"""Attributes for device tracker."""
return {
"updated": datetime.utcfromtimestamp(device.position["ts"]).isoformat(),
"online": device.online,
}
@staticmethod
def balance_attrs(device: StarlineDevice) -> dict[str, Any]:
"""Attributes for balance sensor."""
return {
"operator": device.balance.get("operator"),
"state": device.balance.get("state"),
"updated": device.balance.get("ts"),
}
@staticmethod
def gsm_attrs(device: StarlineDevice) -> dict[str, Any]:
"""Attributes for GSM sensor."""
return {
"raw": device.gsm_level,
"imei": device.imei,
"phone": device.phone,
"online": device.online,
}
@staticmethod
def engine_attrs(device: StarlineDevice) -> dict[str, Any]:
"""Attributes for engine switch."""
return {
"autostart": device.car_state.get("r_start"),
"ignition": device.car_state.get("run"),
}
@staticmethod
def errors_attrs(device: StarlineDevice) -> dict[str, Any]:
"""Attributes for errors sensor."""
return {"errors": device.errors.get("errors")}