Use EntityDescription - starline (#54431)
This commit is contained in:
parent
05de7a78d1
commit
f9ebb29541
3 changed files with 206 additions and 83 deletions
|
@ -1,57 +1,92 @@
|
|||
"""Reads vehicle status from StarLine API."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DEVICE_CLASS_DOOR,
|
||||
DEVICE_CLASS_LOCK,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_PROBLEM,
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
|
||||
from .account import StarlineAccount, StarlineDevice
|
||||
from .const import DOMAIN
|
||||
from .entity import StarlineEntity
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"hbrake": ["Hand Brake", DEVICE_CLASS_POWER],
|
||||
"hood": ["Hood", DEVICE_CLASS_DOOR],
|
||||
"trunk": ["Trunk", DEVICE_CLASS_DOOR],
|
||||
"alarm": ["Alarm", DEVICE_CLASS_PROBLEM],
|
||||
"door": ["Doors", DEVICE_CLASS_LOCK],
|
||||
}
|
||||
|
||||
@dataclass
|
||||
class StarlineRequiredKeysMixin:
|
||||
"""Mixin for required keys."""
|
||||
|
||||
name_: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class StarlineBinarySensorEntityDescription(
|
||||
BinarySensorEntityDescription, StarlineRequiredKeysMixin
|
||||
):
|
||||
"""Describes Starline binary_sensor entity."""
|
||||
|
||||
|
||||
BINARY_SENSOR_TYPES: tuple[StarlineBinarySensorEntityDescription, ...] = (
|
||||
StarlineBinarySensorEntityDescription(
|
||||
key="hbrake",
|
||||
name_="Hand Brake",
|
||||
device_class=DEVICE_CLASS_POWER,
|
||||
),
|
||||
StarlineBinarySensorEntityDescription(
|
||||
key="hood",
|
||||
name_="Hood",
|
||||
device_class=DEVICE_CLASS_DOOR,
|
||||
),
|
||||
StarlineBinarySensorEntityDescription(
|
||||
key="trunk",
|
||||
name_="Trunk",
|
||||
device_class=DEVICE_CLASS_DOOR,
|
||||
),
|
||||
StarlineBinarySensorEntityDescription(
|
||||
key="alarm",
|
||||
name_="Alarm",
|
||||
device_class=DEVICE_CLASS_PROBLEM,
|
||||
),
|
||||
StarlineBinarySensorEntityDescription(
|
||||
key="door",
|
||||
name_="Doors",
|
||||
device_class=DEVICE_CLASS_LOCK,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry, async_add_entities):
|
||||
"""Set up the StarLine sensors."""
|
||||
account: StarlineAccount = hass.data[DOMAIN][entry.entry_id]
|
||||
entities = []
|
||||
for device in account.api.devices.values():
|
||||
for key, value in SENSOR_TYPES.items():
|
||||
if key in device.car_state:
|
||||
sensor = StarlineSensor(account, device, key, *value)
|
||||
if sensor.is_on is not None:
|
||||
entities.append(sensor)
|
||||
entities = [
|
||||
sensor
|
||||
for device in account.api.devices.values()
|
||||
for description in BINARY_SENSOR_TYPES
|
||||
if description.key in device.car_state
|
||||
if (sensor := StarlineSensor(account, device, description)).is_on is not None
|
||||
]
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class StarlineSensor(StarlineEntity, BinarySensorEntity):
|
||||
"""Representation of a StarLine binary sensor."""
|
||||
|
||||
entity_description: StarlineBinarySensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
account: StarlineAccount,
|
||||
device: StarlineDevice,
|
||||
key: str,
|
||||
name: str,
|
||||
device_class: str,
|
||||
description: StarlineBinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize sensor."""
|
||||
super().__init__(account, device, key, name)
|
||||
self._device_class = device_class
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of the binary sensor."""
|
||||
return self._device_class
|
||||
super().__init__(account, device, description.key, description.name_)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
"""Reads vehicle status from StarLine API."""
|
||||
from homeassistant.components.sensor import DEVICE_CLASS_TEMPERATURE, SensorEntity
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ELECTRIC_POTENTIAL_VOLT,
|
||||
LENGTH_KILOMETERS,
|
||||
|
@ -13,48 +21,94 @@ from .account import StarlineAccount, StarlineDevice
|
|||
from .const import DOMAIN
|
||||
from .entity import StarlineEntity
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"battery": ["Battery", None, ELECTRIC_POTENTIAL_VOLT, None],
|
||||
"balance": ["Balance", None, None, "mdi:cash-multiple"],
|
||||
"ctemp": ["Interior Temperature", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None],
|
||||
"etemp": ["Engine Temperature", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None],
|
||||
"gsm_lvl": ["GSM Signal", None, PERCENTAGE, None],
|
||||
"fuel": ["Fuel Volume", None, None, "mdi:fuel"],
|
||||
"errors": ["OBD Errors", None, None, "mdi:alert-octagon"],
|
||||
"mileage": ["Mileage", None, LENGTH_KILOMETERS, "mdi:counter"],
|
||||
}
|
||||
|
||||
@dataclass
|
||||
class StarlineRequiredKeysMixin:
|
||||
"""Mixin for required keys."""
|
||||
|
||||
name_: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class StarlineSensorEntityDescription(
|
||||
SensorEntityDescription, StarlineRequiredKeysMixin
|
||||
):
|
||||
"""Describes Starline binary_sensor entity."""
|
||||
|
||||
|
||||
SENSOR_TYPES: tuple[StarlineSensorEntityDescription, ...] = (
|
||||
StarlineSensorEntityDescription(
|
||||
key="battery",
|
||||
name_="Battery",
|
||||
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="balance",
|
||||
name_="Balance",
|
||||
icon="mdi:cash-multiple",
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="ctemp",
|
||||
name_="Interior Temperature",
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="etemp",
|
||||
name_="Engine Temperature",
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="gsm_lvl",
|
||||
name_="GSM Signal",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="fuel",
|
||||
name_="Fuel Volume",
|
||||
icon="mdi:fuel",
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="errors",
|
||||
name_="OBD Errors",
|
||||
icon="mdi:alert-octagon",
|
||||
),
|
||||
StarlineSensorEntityDescription(
|
||||
key="mileage",
|
||||
name_="Mileage",
|
||||
native_unit_of_measurement=LENGTH_KILOMETERS,
|
||||
icon="mdi:counter",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry, async_add_entities):
|
||||
"""Set up the StarLine sensors."""
|
||||
account: StarlineAccount = hass.data[DOMAIN][entry.entry_id]
|
||||
entities = []
|
||||
for device in account.api.devices.values():
|
||||
for key, value in SENSOR_TYPES.items():
|
||||
sensor = StarlineSensor(account, device, key, *value)
|
||||
if sensor.state is not None:
|
||||
entities.append(sensor)
|
||||
entities = [
|
||||
sensor
|
||||
for device in account.api.devices.values()
|
||||
for description in SENSOR_TYPES
|
||||
if (sensor := StarlineSensor(account, device, description)).state is not None
|
||||
]
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class StarlineSensor(StarlineEntity, SensorEntity):
|
||||
"""Representation of a StarLine sensor."""
|
||||
|
||||
entity_description: StarlineSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
account: StarlineAccount,
|
||||
device: StarlineDevice,
|
||||
key: str,
|
||||
name: str,
|
||||
device_class: str,
|
||||
unit: str,
|
||||
icon: str,
|
||||
description: StarlineSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize StarLine sensor."""
|
||||
super().__init__(account, device, key, name)
|
||||
self._device_class = device_class
|
||||
self._unit = unit
|
||||
self._icon = icon
|
||||
super().__init__(account, device, description.key, description.name_)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
|
@ -66,7 +120,7 @@ class StarlineSensor(StarlineEntity, SensorEntity):
|
|||
)
|
||||
if self._key == "gsm_lvl":
|
||||
return icon_for_signal_level(signal_level=self._device.gsm_level_percent)
|
||||
return self._icon
|
||||
return self.entity_description.icon
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
|
@ -100,12 +154,7 @@ class StarlineSensor(StarlineEntity, SensorEntity):
|
|||
return PERCENTAGE
|
||||
if type_value == "litres":
|
||||
return VOLUME_LITERS
|
||||
return self._unit
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the class of the sensor."""
|
||||
return self._device_class
|
||||
return self.entity_description.native_unit_of_measurement
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
|
|
|
@ -1,51 +1,86 @@
|
|||
"""Support for StarLine switch."""
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
|
||||
from .account import StarlineAccount, StarlineDevice
|
||||
from .const import DOMAIN
|
||||
from .entity import StarlineEntity
|
||||
|
||||
SWITCH_TYPES = {
|
||||
"ign": ["Engine", "mdi:engine-outline", "mdi:engine-off-outline"],
|
||||
"webasto": ["Webasto", "mdi:radiator", "mdi:radiator-off"],
|
||||
"out": [
|
||||
"Additional Channel",
|
||||
"mdi:access-point-network",
|
||||
"mdi:access-point-network-off",
|
||||
],
|
||||
"poke": ["Horn", "mdi:bullhorn-outline", "mdi:bullhorn-outline"],
|
||||
}
|
||||
|
||||
@dataclass
|
||||
class StarlineRequiredKeysMixin:
|
||||
"""Mixin for required keys."""
|
||||
|
||||
name_: str
|
||||
icon_on: str
|
||||
icon_off: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class StarlineSwitchEntityDescription(
|
||||
SwitchEntityDescription, StarlineRequiredKeysMixin
|
||||
):
|
||||
"""Describes Starline switch entity."""
|
||||
|
||||
|
||||
SWITCH_TYPES: tuple[StarlineSwitchEntityDescription, ...] = (
|
||||
StarlineSwitchEntityDescription(
|
||||
key="ign",
|
||||
name_="Engine",
|
||||
icon_on="mdi:engine-outline",
|
||||
icon_off="mdi:engine-off-outline",
|
||||
),
|
||||
StarlineSwitchEntityDescription(
|
||||
key="webasto",
|
||||
name_="Webasto",
|
||||
icon_on="mdi:radiator",
|
||||
icon_off="mdi:radiator-off",
|
||||
),
|
||||
StarlineSwitchEntityDescription(
|
||||
key="out",
|
||||
name_="Additional Channel",
|
||||
icon_on="mdi:access-point-network",
|
||||
icon_off="mdi:access-point-network-off",
|
||||
),
|
||||
StarlineSwitchEntityDescription(
|
||||
key="poke",
|
||||
name_="Horn",
|
||||
icon_on="mdi:bullhorn-outline",
|
||||
icon_off="mdi:bullhorn-outline",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry, async_add_entities):
|
||||
"""Set up the StarLine switch."""
|
||||
account: StarlineAccount = hass.data[DOMAIN][entry.entry_id]
|
||||
entities = []
|
||||
for device in account.api.devices.values():
|
||||
if device.support_state:
|
||||
for key, value in SWITCH_TYPES.items():
|
||||
switch = StarlineSwitch(account, device, key, *value)
|
||||
if switch.is_on is not None:
|
||||
entities.append(switch)
|
||||
entities = [
|
||||
switch
|
||||
for device in account.api.devices.values()
|
||||
if device.support_state
|
||||
for description in SWITCH_TYPES
|
||||
if (switch := StarlineSwitch(account, device, description)).is_on is not None
|
||||
]
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class StarlineSwitch(StarlineEntity, SwitchEntity):
|
||||
"""Representation of a StarLine switch."""
|
||||
|
||||
entity_description: StarlineSwitchEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
account: StarlineAccount,
|
||||
device: StarlineDevice,
|
||||
key: str,
|
||||
name: str,
|
||||
icon_on: str,
|
||||
icon_off: str,
|
||||
description: StarlineSwitchEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the switch."""
|
||||
super().__init__(account, device, key, name)
|
||||
self._icon_on = icon_on
|
||||
self._icon_off = icon_off
|
||||
super().__init__(account, device, description.key, description.name_)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
@ -62,7 +97,11 @@ class StarlineSwitch(StarlineEntity, SwitchEntity):
|
|||
@property
|
||||
def icon(self):
|
||||
"""Icon to use in the frontend, if any."""
|
||||
return self._icon_on if self.is_on else self._icon_off
|
||||
return (
|
||||
self.entity_description.icon_on
|
||||
if self.is_on
|
||||
else self.entity_description.icon_off
|
||||
)
|
||||
|
||||
@property
|
||||
def assumed_state(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue