162 lines
5.6 KiB
Python
162 lines
5.6 KiB
Python
"""Sensors definition for SWS12500."""
|
|
|
|
import logging
|
|
|
|
from homeassistant.components.sensor import SensorEntity
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.core import HomeAssistant, callback
|
|
from homeassistant.helpers.device_registry import DeviceEntryType
|
|
from homeassistant.helpers.entity import DeviceInfo, generate_entity_id
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
|
|
from . import WeatherDataUpdateCoordinator
|
|
from .const import (
|
|
BATTERY_LIST,
|
|
CHILL_INDEX,
|
|
DOMAIN,
|
|
HEAT_INDEX,
|
|
OUTSIDE_HUMIDITY,
|
|
OUTSIDE_TEMP,
|
|
SENSORS_TO_LOAD,
|
|
WIND_AZIMUT,
|
|
WIND_DIR,
|
|
WIND_SPEED,
|
|
WSLINK,
|
|
UnitOfBat,
|
|
)
|
|
from .sensors_common import WeatherSensorEntityDescription
|
|
from .sensors_weather import SENSOR_TYPES_WEATHER_API
|
|
from .sensors_wslink import SENSOR_TYPES_WSLINK
|
|
from .utils import battery_level_to_icon, battery_level_to_text, chill_index, heat_index
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up Weather Station sensors."""
|
|
|
|
coordinator: WeatherDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
|
|
|
sensors_to_load: list = []
|
|
sensors: list = []
|
|
_wslink = config_entry.options.get(WSLINK)
|
|
|
|
SENSOR_TYPES = SENSOR_TYPES_WSLINK if _wslink else SENSOR_TYPES_WEATHER_API
|
|
|
|
# Check if we have some sensors to load.
|
|
if sensors_to_load := config_entry.options.get(SENSORS_TO_LOAD, []):
|
|
if WIND_DIR in sensors_to_load:
|
|
sensors_to_load.append(WIND_AZIMUT)
|
|
if (OUTSIDE_HUMIDITY in sensors_to_load) and (OUTSIDE_TEMP in sensors_to_load):
|
|
sensors_to_load.append(HEAT_INDEX)
|
|
|
|
if (WIND_SPEED in sensors_to_load) and (OUTSIDE_TEMP in sensors_to_load):
|
|
sensors_to_load.append(CHILL_INDEX)
|
|
sensors = [
|
|
WeatherSensor(hass, description, coordinator)
|
|
for description in SENSOR_TYPES
|
|
if description.key in sensors_to_load
|
|
]
|
|
async_add_entities(sensors)
|
|
|
|
|
|
class WeatherSensor( # pyright: ignore[reportIncompatibleVariableOverride]
|
|
CoordinatorEntity[WeatherDataUpdateCoordinator], SensorEntity
|
|
): # pyright: ignore[reportIncompatibleVariableOverride]
|
|
"""Implementation of Weather Sensor entity."""
|
|
|
|
_attr_has_entity_name = True
|
|
_attr_should_poll = False
|
|
|
|
def __init__(
|
|
self,
|
|
hass: HomeAssistant,
|
|
description: WeatherSensorEntityDescription,
|
|
coordinator: WeatherDataUpdateCoordinator,
|
|
) -> None:
|
|
"""Initialize sensor."""
|
|
super().__init__(coordinator)
|
|
self.hass = hass
|
|
self.coordinator = coordinator
|
|
self.entity_description = description
|
|
self._attr_unique_id = description.key
|
|
self._data = None
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Handle listeners to reloaded sensors."""
|
|
|
|
await super().async_added_to_hass()
|
|
|
|
self.coordinator.async_add_listener(self._handle_coordinator_update)
|
|
|
|
@callback
|
|
def _handle_coordinator_update(self) -> None:
|
|
"""Handle updated data from the coordinator."""
|
|
self._data = self.coordinator.data.get(self.entity_description.key)
|
|
|
|
super()._handle_coordinator_update()
|
|
|
|
self.async_write_ha_state()
|
|
|
|
@property
|
|
def native_value(self): # pyright: ignore[reportIncompatibleVariableOverride]
|
|
"""Return value of entity."""
|
|
|
|
_wslink = self.coordinator.config.options.get(WSLINK)
|
|
|
|
if self.coordinator.data and (WIND_AZIMUT in self.entity_description.key):
|
|
return self.entity_description.value_fn(self.coordinator.data.get(WIND_DIR)) # pyright: ignore[ reportAttributeAccessIssue]
|
|
|
|
if (
|
|
self.coordinator.data
|
|
and (HEAT_INDEX in self.entity_description.key)
|
|
and not _wslink
|
|
):
|
|
return self.entity_description.value_fn(heat_index(self.coordinator.data)) # pyright: ignore[ reportAttributeAccessIssue]
|
|
|
|
if (
|
|
self.coordinator.data
|
|
and (CHILL_INDEX in self.entity_description.key)
|
|
and not _wslink
|
|
):
|
|
return self.entity_description.value_fn(chill_index(self.coordinator.data)) # pyright: ignore[ reportAttributeAccessIssue]
|
|
|
|
return (
|
|
None if self._data == "" else self.entity_description.value_fn(self._data) # pyright: ignore[ reportAttributeAccessIssue]
|
|
)
|
|
|
|
@property
|
|
def suggested_entity_id(self) -> str:
|
|
"""Return name."""
|
|
return generate_entity_id("sensor.{}", self.entity_description.key)
|
|
|
|
@property
|
|
def icon(self) -> str | None: # pyright: ignore[reportIncompatibleVariableOverride]
|
|
"""Return the dynamic icon for battery representation."""
|
|
|
|
if self.entity_description.key in BATTERY_LIST:
|
|
if self.native_value:
|
|
battery_level = battery_level_to_text(self.native_value)
|
|
return battery_level_to_icon(battery_level)
|
|
|
|
return battery_level_to_icon(UnitOfBat.UNKNOWN)
|
|
|
|
return self.entity_description.icon
|
|
|
|
@property
|
|
def device_info(self) -> DeviceInfo: # pyright: ignore[reportIncompatibleVariableOverride]
|
|
"""Device info."""
|
|
return DeviceInfo(
|
|
connections=set(),
|
|
name="Weather Station SWS 12500",
|
|
entry_type=DeviceEntryType.SERVICE,
|
|
identifiers={(DOMAIN,)}, # type: ignore[arg-type]
|
|
manufacturer="Schizza",
|
|
model="Weather Station SWS 12500",
|
|
)
|