Add entity translations to Tomorrow.io (#99632)

This commit is contained in:
Joost Lekkerkerker 2023-10-25 12:15:09 +02:00 committed by GitHub
parent 4812d62ccf
commit d2f8c527a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 74 deletions

View File

@ -327,6 +327,7 @@ class TomorrowioEntity(CoordinatorEntity[TomorrowioDataUpdateCoordinator]):
"""Base Tomorrow.io Entity."""
_attr_attribution = ATTRIBUTION
_attr_has_entity_name = True
def __init__(
self,
@ -340,7 +341,6 @@ class TomorrowioEntity(CoordinatorEntity[TomorrowioDataUpdateCoordinator]):
self._config_entry = config_entry
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self._config_entry.data[CONF_API_KEY])},
name=INTEGRATION_NAME,
manufacturer=INTEGRATION_NAME,
sw_version=f"v{self.api_version}",
entry_type=DeviceEntryType.SERVICE,

View File

@ -25,7 +25,6 @@ from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
CONF_API_KEY,
CONF_NAME,
PERCENTAGE,
UnitOfIrradiance,
UnitOfLength,
@ -75,10 +74,6 @@ from .const import (
class TomorrowioSensorEntityDescription(SensorEntityDescription):
"""Describes a Tomorrow.io sensor entity."""
# TomorrowioSensor does not support UNDEFINED or None,
# restrict the type to str.
name: str = ""
attribute: str = ""
unit_imperial: str | None = None
unit_metric: str | None = None
@ -111,16 +106,16 @@ def convert_ppb_to_ugm3(molecular_weight: int | float) -> Callable[[float], floa
SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="feels_like",
translation_key="feels_like",
attribute=TMRW_ATTR_FEELS_LIKE,
name="Feels Like",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
),
TomorrowioSensorEntityDescription(
key="dew_point",
translation_key="dew_point",
attribute=TMRW_ATTR_DEW_POINT,
name="Dew Point",
icon="mdi:thermometer-water",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
@ -130,7 +125,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="pressure_surface_level",
attribute=TMRW_ATTR_PRESSURE_SURFACE_LEVEL,
name="Pressure (Surface Level)",
native_unit_of_measurement=UnitOfPressure.HPA,
device_class=SensorDeviceClass.PRESSURE,
state_class=SensorStateClass.MEASUREMENT,
@ -140,7 +134,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="global_horizontal_irradiance",
attribute=TMRW_ATTR_SOLAR_GHI,
name="Global Horizontal Irradiance",
unit_imperial=UnitOfIrradiance.BTUS_PER_HOUR_SQUARE_FOOT,
unit_metric=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
imperial_conversion=(1 / 3.15459),
@ -150,8 +143,8 @@ SENSOR_TYPES = (
# Data comes in as km, convert to miles for imperial
TomorrowioSensorEntityDescription(
key="cloud_base",
translation_key="cloud_base",
attribute=TMRW_ATTR_CLOUD_BASE,
name="Cloud Base",
icon="mdi:cloud-arrow-down",
unit_imperial=UnitOfLength.MILES,
unit_metric=UnitOfLength.KILOMETERS,
@ -166,8 +159,8 @@ SENSOR_TYPES = (
# Data comes in as km, convert to miles for imperial
TomorrowioSensorEntityDescription(
key="cloud_ceiling",
translation_key="cloud_ceiling",
attribute=TMRW_ATTR_CLOUD_CEILING,
name="Cloud Ceiling",
icon="mdi:cloud-arrow-up",
unit_imperial=UnitOfLength.MILES,
unit_metric=UnitOfLength.KILOMETERS,
@ -181,16 +174,16 @@ SENSOR_TYPES = (
),
TomorrowioSensorEntityDescription(
key="cloud_cover",
translation_key="cloud_cover",
attribute=TMRW_ATTR_CLOUD_COVER,
name="Cloud Cover",
icon="mdi:cloud-percent",
native_unit_of_measurement=PERCENTAGE,
),
# Data comes in as m/s, convert to mi/h for imperial
TomorrowioSensorEntityDescription(
key="wind_gust",
translation_key="wind_gust",
attribute=TMRW_ATTR_WIND_GUST,
name="Wind Gust",
icon="mdi:weather-windy",
unit_imperial=UnitOfSpeed.MILES_PER_HOUR,
unit_metric=UnitOfSpeed.METERS_PER_SECOND,
@ -202,10 +195,9 @@ SENSOR_TYPES = (
),
TomorrowioSensorEntityDescription(
key="precipitation_type",
attribute=TMRW_ATTR_PRECIPITATION_TYPE,
name="Precipitation Type",
value_map=PrecipitationType,
translation_key="precipitation_type",
attribute=TMRW_ATTR_PRECIPITATION_TYPE,
value_map=PrecipitationType,
icon="mdi:weather-snowy-rainy",
),
# Data comes in as ppb, convert to µg/m^3
@ -213,7 +205,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="ozone",
attribute=TMRW_ATTR_OZONE,
name="Ozone",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
multiplication_factor=convert_ppb_to_ugm3(48),
device_class=SensorDeviceClass.OZONE,
@ -222,7 +213,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="particulate_matter_2_5_mm",
attribute=TMRW_ATTR_PARTICULATE_MATTER_25,
name="Particulate Matter < 2.5 μm",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
device_class=SensorDeviceClass.PM25,
state_class=SensorStateClass.MEASUREMENT,
@ -230,7 +220,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="particulate_matter_10_mm",
attribute=TMRW_ATTR_PARTICULATE_MATTER_10,
name="Particulate Matter < 10 μm",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
device_class=SensorDeviceClass.PM10,
state_class=SensorStateClass.MEASUREMENT,
@ -240,7 +229,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="nitrogen_dioxide",
attribute=TMRW_ATTR_NITROGEN_DIOXIDE,
name="Nitrogen Dioxide",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
multiplication_factor=convert_ppb_to_ugm3(46.01),
device_class=SensorDeviceClass.NITROGEN_DIOXIDE,
@ -250,7 +238,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="carbon_monoxide",
attribute=TMRW_ATTR_CARBON_MONOXIDE,
name="Carbon Monoxide",
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
multiplication_factor=1 / 1000,
device_class=SensorDeviceClass.CO,
@ -261,7 +248,6 @@ SENSOR_TYPES = (
TomorrowioSensorEntityDescription(
key="sulphur_dioxide",
attribute=TMRW_ATTR_SULPHUR_DIOXIDE,
name="Sulphur Dioxide",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
multiplication_factor=convert_ppb_to_ugm3(64.07),
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
@ -269,90 +255,82 @@ SENSOR_TYPES = (
),
TomorrowioSensorEntityDescription(
key="us_epa_air_quality_index",
translation_key="us_epa_air_quality_index",
attribute=TMRW_ATTR_EPA_AQI,
name="US EPA Air Quality Index",
device_class=SensorDeviceClass.AQI,
state_class=SensorStateClass.MEASUREMENT,
),
TomorrowioSensorEntityDescription(
key="us_epa_primary_pollutant",
attribute=TMRW_ATTR_EPA_PRIMARY_POLLUTANT,
name="US EPA Primary Pollutant",
value_map=PrimaryPollutantType,
translation_key="primary_pollutant",
attribute=TMRW_ATTR_EPA_PRIMARY_POLLUTANT,
value_map=PrimaryPollutantType,
),
TomorrowioSensorEntityDescription(
key="us_epa_health_concern",
attribute=TMRW_ATTR_EPA_HEALTH_CONCERN,
name="US EPA Health Concern",
value_map=HealthConcernType,
translation_key="health_concern",
attribute=TMRW_ATTR_EPA_HEALTH_CONCERN,
value_map=HealthConcernType,
icon="mdi:hospital",
),
TomorrowioSensorEntityDescription(
key="china_mep_air_quality_index",
translation_key="china_mep_air_quality_index",
attribute=TMRW_ATTR_CHINA_AQI,
name="China MEP Air Quality Index",
device_class=SensorDeviceClass.AQI,
),
TomorrowioSensorEntityDescription(
key="china_mep_primary_pollutant",
translation_key="china_mep_primary_pollutant",
attribute=TMRW_ATTR_CHINA_PRIMARY_POLLUTANT,
name="China MEP Primary Pollutant",
value_map=PrimaryPollutantType,
translation_key="primary_pollutant",
),
TomorrowioSensorEntityDescription(
key="china_mep_health_concern",
translation_key="china_mep_health_concern",
attribute=TMRW_ATTR_CHINA_HEALTH_CONCERN,
name="China MEP Health Concern",
value_map=HealthConcernType,
translation_key="health_concern",
icon="mdi:hospital",
),
TomorrowioSensorEntityDescription(
key="tree_pollen_index",
translation_key="pollen_index",
attribute=TMRW_ATTR_POLLEN_TREE,
name="Tree Pollen Index",
icon="mdi:tree",
value_map=PollenIndex,
translation_key="pollen_index",
),
TomorrowioSensorEntityDescription(
key="weed_pollen_index",
translation_key="weed_pollen_index",
attribute=TMRW_ATTR_POLLEN_WEED,
name="Weed Pollen Index",
value_map=PollenIndex,
translation_key="pollen_index",
icon="mdi:flower-pollen",
),
TomorrowioSensorEntityDescription(
key="grass_pollen_index",
translation_key="grass_pollen_index",
attribute=TMRW_ATTR_POLLEN_GRASS,
name="Grass Pollen Index",
icon="mdi:grass",
value_map=PollenIndex,
translation_key="pollen_index",
),
TomorrowioSensorEntityDescription(
key="fire_index",
translation_key="fire_index",
attribute=TMRW_ATTR_FIRE_INDEX,
name="Fire Index",
icon="mdi:fire",
),
TomorrowioSensorEntityDescription(
key="uv_index",
translation_key="uv_index",
attribute=TMRW_ATTR_UV_INDEX,
name="UV Index",
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:sun-wireless",
),
TomorrowioSensorEntityDescription(
key="uv_radiation_health_concern",
translation_key="uv_radiation_health_concern",
attribute=TMRW_ATTR_UV_HEALTH_CONCERN,
name="UV Radiation Health Concern",
value_map=UVDescription,
translation_key="uv_index",
icon="mdi:weather-sunny-alert",
),
)
@ -399,7 +377,6 @@ class BaseTomorrowioSensorEntity(TomorrowioEntity, SensorEntity):
"""Initialize Tomorrow.io Sensor Entity."""
super().__init__(config_entry, coordinator, api_version)
self.entity_description = description
self._attr_name = f"{self._config_entry.data[CONF_NAME]} - {description.name}"
self._attr_unique_id = f"{self._config_entry.unique_id}_{description.key}"
if self.entity_description.native_unit_of_measurement is None:
self._attr_native_unit_of_measurement = description.unit_metric

View File

@ -33,36 +33,39 @@
},
"entity": {
"sensor": {
"health_concern": {
"state": {
"good": "Good",
"moderate": "Moderate",
"unhealthy_for_sensitive_groups": "Unhealthy for Sensitive Groups",
"unhealthy": "Unhealthy",
"very_unhealthy": "Very Unhealthy",
"hazardous": "Hazardous"
}
"feels_like": {
"name": "Feels like"
},
"pollen_index": {
"state": {
"none": "None",
"very_low": "Very Low",
"low": "Low",
"medium": "Medium",
"high": "High",
"very_high": "Very High"
}
"dew_point": {
"name": "Dew point"
},
"cloud_base": {
"name": "Cloud base"
},
"cloud_ceiling": {
"name": "Cloud ceiling"
},
"cloud_cover": {
"name": "Cloud cover"
},
"wind_gust": {
"name": "Wind gust"
},
"precipitation_type": {
"name": "Precipitation type",
"state": {
"none": "None",
"rain": "Rain",
"snow": "Snow",
"freezing_rain": "Freezing Rain",
"ice_pellets": "Ice Pellets"
"freezing_rain": "Freezing rain",
"ice_pellets": "Ice pellets"
}
},
"us_epa_air_quality_index": {
"name": "US EPA air quality index"
},
"primary_pollutant": {
"name": "US EPA primary pollutant",
"state": {
"pm25": "[%key:component::sensor::entity_component::pm25::name%]",
"pm10": "[%key:component::sensor::entity_component::pm10::name%]",
@ -72,7 +75,83 @@
"so2": "[%key:component::sensor::entity_component::sulphur_dioxide::name%]"
}
},
"health_concern": {
"name": "US EPA health concern",
"state": {
"good": "Good",
"moderate": "Moderate",
"unhealthy_for_sensitive_groups": "Unhealthy for sensitive groups",
"unhealthy": "Unhealthy",
"very_unhealthy": "Very unhealthy",
"hazardous": "Hazardous"
}
},
"china_mep_air_quality_index": {
"name": "China MEP air quality index"
},
"china_mep_primary_pollutant": {
"name": "China MEP primary pollutant",
"state": {
"pm25": "[%key:component::sensor::entity_component::pm25::name%]",
"pm10": "[%key:component::sensor::entity_component::pm10::name%]",
"o3": "[%key:component::sensor::entity_component::ozone::name%]",
"no2": "[%key:component::sensor::entity_component::nitrogen_dioxide::name%]",
"co": "[%key:component::sensor::entity_component::carbon_monoxide::name%]",
"so2": "[%key:component::sensor::entity_component::sulphur_dioxide::name%]"
}
},
"china_mep_health_concern": {
"name": "China MEP health concern",
"state": {
"good": "[%key:component::tomorrowio::entity::sensor::health_concern::state::good%]",
"moderate": "[%key:component::tomorrowio::entity::sensor::health_concern::state::moderate%]",
"unhealthy_for_sensitive_groups": "[%key:component::tomorrowio::entity::sensor::health_concern::state::unhealthy_for_sensitive_groups%]",
"unhealthy": "[%key:component::tomorrowio::entity::sensor::health_concern::state::unhealthy%]",
"very_unhealthy": "[%key:component::tomorrowio::entity::sensor::health_concern::state::very_unhealthy%]",
"hazardous": "[%key:component::tomorrowio::entity::sensor::health_concern::state::hazardous%]"
}
},
"pollen_index": {
"name": "Tree pollen index",
"state": {
"none": "None",
"very_low": "Very low",
"low": "Low",
"medium": "Medium",
"high": "High",
"very_high": "Very high"
}
},
"weed_pollen_index": {
"name": "Weed pollen index",
"state": {
"none": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::none%]",
"very_low": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::very_low%]",
"low": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::low%]",
"medium": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::medium%]",
"high": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::high%]",
"very_high": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::very_high%]"
}
},
"grass_pollen_index": {
"name": "Grass pollen index",
"state": {
"none": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::none%]",
"very_low": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::very_low%]",
"low": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::low%]",
"medium": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::medium%]",
"high": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::high%]",
"very_high": "[%key:component::tomorrowio::entity::sensor::pollen_index::state::very_high%]"
}
},
"fire_index": {
"name": "Fire index"
},
"uv_index": {
"name": "UV index"
},
"uv_radiation_health_concern": {
"name": "UV radiation health concern",
"state": {
"low": "Low",
"moderate": "Moderate",

View File

@ -24,7 +24,6 @@ from homeassistant.components.weather import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_API_KEY,
CONF_NAME,
UnitOfLength,
UnitOfPrecipitationDepth,
UnitOfPressure,
@ -118,7 +117,7 @@ class TomorrowioWeatherEntity(TomorrowioEntity, SingleCoordinatorWeatherEntity):
self._attr_entity_registry_enabled_default = (
forecast_type == DEFAULT_FORECAST_TYPE
)
self._attr_name = f"{config_entry.data[CONF_NAME]} - {forecast_type.title()}"
self._attr_name = forecast_type.title()
self._attr_unique_id = _calculate_unique_id(
config_entry.unique_id, forecast_type
)

View File

@ -37,8 +37,8 @@ O3 = "ozone"
CO = "carbon_monoxide"
NO2 = "nitrogen_dioxide"
SO2 = "sulphur_dioxide"
PM25 = "particulate_matter_2_5_mm"
PM10 = "particulate_matter_10_mm"
PM25 = "pm2_5"
PM10 = "pm10"
MEP_AQI = "china_mep_air_quality_index"
MEP_HEALTH_CONCERN = "china_mep_health_concern"
MEP_PRIMARY_POLLUTANT = "china_mep_primary_pollutant"
@ -51,10 +51,10 @@ WEED_POLLEN = "weed_pollen_index"
TREE_POLLEN = "tree_pollen_index"
FEELS_LIKE = "feels_like"
DEW_POINT = "dew_point"
PRESSURE_SURFACE_LEVEL = "pressure_surface_level"
PRESSURE_SURFACE_LEVEL = "pressure"
SNOW_ACCUMULATION = "snow_accumulation"
ICE_ACCUMULATION = "ice_accumulation"
GHI = "global_horizontal_irradiance"
GHI = "irradiance"
CLOUD_BASE = "cloud_base"
CLOUD_COVER = "cloud_cover"
CLOUD_CEILING = "cloud_ceiling"
@ -121,6 +121,7 @@ async def _setup(
data = _get_config_schema(hass, SOURCE_USER)(config)
data[CONF_NAME] = DEFAULT_NAME
config_entry = MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data=data,
options={CONF_TIMESTEP: DEFAULT_TIMESTEP},

View File

@ -78,6 +78,7 @@ async def _setup_config_entry(hass: HomeAssistant, config: dict[str, Any]) -> St
data = _get_config_schema(hass, SOURCE_USER)(config)
data[CONF_NAME] = DEFAULT_NAME
config_entry = MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data=data,
options={CONF_TIMESTEP: DEFAULT_TIMESTEP},
@ -228,7 +229,7 @@ async def test_v4_weather(hass: HomeAssistant, tomorrowio_config_entry_update) -
ATTR_FORECAST_WIND_BEARING: 239.6,
ATTR_FORECAST_WIND_SPEED: 34.16, # 9.49 m/s -> km/h
}
assert weather_state.attributes[ATTR_FRIENDLY_NAME] == "Tomorrow.io - Daily"
assert weather_state.attributes[ATTR_FRIENDLY_NAME] == "Tomorrow.io Daily"
assert weather_state.attributes[ATTR_WEATHER_HUMIDITY] == 23
assert weather_state.attributes[ATTR_WEATHER_OZONE] == 46.53
assert weather_state.attributes[ATTR_WEATHER_PRECIPITATION_UNIT] == "mm"
@ -261,7 +262,7 @@ async def test_v4_weather_legacy_entities(hass: HomeAssistant) -> None:
ATTR_FORECAST_WIND_BEARING: 239.6,
ATTR_FORECAST_WIND_SPEED: 34.16, # 9.49 m/s -> km/h
}
assert weather_state.attributes[ATTR_FRIENDLY_NAME] == "Tomorrow.io - Daily"
assert weather_state.attributes[ATTR_FRIENDLY_NAME] == "Tomorrow.io Daily"
assert weather_state.attributes[ATTR_WEATHER_HUMIDITY] == 23
assert weather_state.attributes[ATTR_WEATHER_OZONE] == 46.53
assert weather_state.attributes[ATTR_WEATHER_PRECIPITATION_UNIT] == "mm"