forked from home-assistant/core
Add sensor platform to SMHI
This commit is contained in:
@@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
|
|
||||||
from .coordinator import SMHIConfigEntry, SMHIDataUpdateCoordinator
|
from .coordinator import SMHIConfigEntry, SMHIDataUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.WEATHER]
|
PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: SMHIConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: SMHIConfigEntry) -> bool:
|
||||||
|
@@ -61,3 +61,8 @@ class SMHIDataUpdateCoordinator(DataUpdateCoordinator[SMHIForecastData]):
|
|||||||
daily=_forecast_daily,
|
daily=_forecast_daily,
|
||||||
hourly=_forecast_hourly,
|
hourly=_forecast_hourly,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current(self) -> SMHIForecast:
|
||||||
|
"""Return the current metrics."""
|
||||||
|
return self.data.daily[0]
|
||||||
|
@@ -16,7 +16,6 @@ class SmhiWeatherBaseEntity(CoordinatorEntity[SMHIDataUpdateCoordinator]):
|
|||||||
|
|
||||||
_attr_attribution = "Swedish weather institute (SMHI)"
|
_attr_attribution = "Swedish weather institute (SMHI)"
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
_attr_name = None
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -26,7 +25,7 @@ class SmhiWeatherBaseEntity(CoordinatorEntity[SMHIDataUpdateCoordinator]):
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the SMHI base weather entity."""
|
"""Initialize the SMHI base weather entity."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._attr_unique_id = f"{latitude}, {longitude}"
|
self._attr_unique_id: str = f"{latitude}, {longitude}"
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
identifiers={(DOMAIN, f"{latitude}, {longitude}")},
|
identifiers={(DOMAIN, f"{latitude}, {longitude}")},
|
||||||
|
27
homeassistant/components/smhi/icons.json
Normal file
27
homeassistant/components/smhi/icons.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"thunder": {
|
||||||
|
"default": "mdi:lightning-bolt"
|
||||||
|
},
|
||||||
|
"total_cloud": {
|
||||||
|
"default": "mdi:cloud"
|
||||||
|
},
|
||||||
|
"low_cloud": {
|
||||||
|
"default": "mdi:cloud-arrow-down"
|
||||||
|
},
|
||||||
|
"medium_cloud": {
|
||||||
|
"default": "mdi:cloud-arrow-right"
|
||||||
|
},
|
||||||
|
"high_cloud": {
|
||||||
|
"default": "mdi:cloud-arrow-up"
|
||||||
|
},
|
||||||
|
"precipitation_category": {
|
||||||
|
"default": "mdi:weather-pouring"
|
||||||
|
},
|
||||||
|
"frozen_precipitation": {
|
||||||
|
"default": "mdi:weather-snowy-rainy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
139
homeassistant/components/smhi/sensor.py
Normal file
139
homeassistant/components/smhi/sensor.py
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
"""Sensor platform for SMHI integration."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
)
|
||||||
|
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE, PERCENTAGE
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
|
from .coordinator import SMHIConfigEntry, SMHIDataUpdateCoordinator
|
||||||
|
from .entity import SmhiWeatherBaseEntity
|
||||||
|
|
||||||
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_percentage_values(entity: SMHISensor, key: str) -> int | None:
|
||||||
|
"""Return percentage values in correct range."""
|
||||||
|
value: int | None = entity.coordinator.current.get(key) # type: ignore[assignment]
|
||||||
|
if value and 0 <= value <= 100:
|
||||||
|
return value
|
||||||
|
if value:
|
||||||
|
return 0
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class SMHISensorEntityDescription(SensorEntityDescription):
|
||||||
|
"""Describes SMHI sensor entity."""
|
||||||
|
|
||||||
|
value_fn: Callable[[SMHISensor], StateType | datetime]
|
||||||
|
|
||||||
|
|
||||||
|
SENSOR_DESCRIPTIONS: tuple[SMHISensorEntityDescription, ...] = (
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="thunder",
|
||||||
|
translation_key="thunder",
|
||||||
|
value_fn=lambda entity: get_percentage_values(entity, "thunder"),
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
),
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="total_cloud",
|
||||||
|
translation_key="total_cloud",
|
||||||
|
value_fn=lambda entity: get_percentage_values(entity, "total_cloud"),
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
),
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="low_cloud",
|
||||||
|
translation_key="low_cloud",
|
||||||
|
value_fn=lambda entity: get_percentage_values(entity, "low_cloud"),
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
),
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="medium_cloud",
|
||||||
|
translation_key="medium_cloud",
|
||||||
|
value_fn=lambda entity: get_percentage_values(entity, "medium_cloud"),
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
),
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="high_cloud",
|
||||||
|
translation_key="high_cloud",
|
||||||
|
value_fn=lambda entity: get_percentage_values(entity, "high_cloud"),
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
),
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="precipitation_category",
|
||||||
|
translation_key="precipitation_category",
|
||||||
|
value_fn=lambda entity: str(
|
||||||
|
get_percentage_values(entity, "precipitation_category")
|
||||||
|
),
|
||||||
|
device_class=SensorDeviceClass.ENUM,
|
||||||
|
options=["0", "1", "2", "3", "4", "5", "6"],
|
||||||
|
),
|
||||||
|
SMHISensorEntityDescription(
|
||||||
|
key="frozen_precipitation",
|
||||||
|
translation_key="frozen_precipitation",
|
||||||
|
value_fn=lambda entity: get_percentage_values(entity, "frozen_precipitation"),
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: SMHIConfigEntry,
|
||||||
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up SMHI sensor platform."""
|
||||||
|
|
||||||
|
coordinator = entry.runtime_data
|
||||||
|
location = entry.data
|
||||||
|
async_add_entities(
|
||||||
|
SMHISensor(
|
||||||
|
location[CONF_LOCATION][CONF_LATITUDE],
|
||||||
|
location[CONF_LOCATION][CONF_LONGITUDE],
|
||||||
|
coordinator=coordinator,
|
||||||
|
entity_description=description,
|
||||||
|
)
|
||||||
|
for description in SENSOR_DESCRIPTIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SMHISensor(SmhiWeatherBaseEntity, SensorEntity):
|
||||||
|
"""Representation of a SMHI Sensor."""
|
||||||
|
|
||||||
|
entity_description: SMHISensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
latitude: str,
|
||||||
|
longitude: str,
|
||||||
|
coordinator: SMHIDataUpdateCoordinator,
|
||||||
|
entity_description: SMHISensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initiate SMHI Sensor."""
|
||||||
|
self.entity_description = entity_description
|
||||||
|
super().__init__(
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
coordinator,
|
||||||
|
)
|
||||||
|
self._attr_unique_id += f"-{entity_description.key}"
|
||||||
|
|
||||||
|
def update_entity_data(self) -> None:
|
||||||
|
"""Refresh the entity data."""
|
||||||
|
if self.coordinator.data.daily:
|
||||||
|
self._attr_native_value = self.entity_description.value_fn(self)
|
@@ -23,5 +23,39 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"wrong_location": "Location Sweden only"
|
"wrong_location": "Location Sweden only"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"thunder": {
|
||||||
|
"name": "Thunder probability"
|
||||||
|
},
|
||||||
|
"total_cloud": {
|
||||||
|
"name": "Total cloud coverage"
|
||||||
|
},
|
||||||
|
"low_cloud": {
|
||||||
|
"name": "Low cloud coverage"
|
||||||
|
},
|
||||||
|
"medium_cloud": {
|
||||||
|
"name": "Medium cloud coverage"
|
||||||
|
},
|
||||||
|
"high_cloud": {
|
||||||
|
"name": "High cloud coverage"
|
||||||
|
},
|
||||||
|
"precipitation_category": {
|
||||||
|
"name": "Precipitation category",
|
||||||
|
"state": {
|
||||||
|
"0": "No precipitation",
|
||||||
|
"1": "Snow",
|
||||||
|
"2": "Snow and rain",
|
||||||
|
"3": "Rain",
|
||||||
|
"4": "Drizzle",
|
||||||
|
"5": "Freezing rain",
|
||||||
|
"6": "Freezing drizzle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frozen_precipitation": {
|
||||||
|
"name": "Frozen precipitation"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -111,6 +111,7 @@ class SmhiWeather(SmhiWeatherBaseEntity, SingleCoordinatorWeatherEntity):
|
|||||||
_attr_supported_features = (
|
_attr_supported_features = (
|
||||||
WeatherEntityFeature.FORECAST_DAILY | WeatherEntityFeature.FORECAST_HOURLY
|
WeatherEntityFeature.FORECAST_DAILY | WeatherEntityFeature.FORECAST_HOURLY
|
||||||
)
|
)
|
||||||
|
_attr_name = None
|
||||||
|
|
||||||
def update_entity_data(self) -> None:
|
def update_entity_data(self) -> None:
|
||||||
"""Refresh the entity data."""
|
"""Refresh the entity data."""
|
||||||
|
Reference in New Issue
Block a user