Use SensorEntityDescription in emoncms (#130451)

This commit is contained in:
Alexandre CUER 2024-11-26 19:25:00 +01:00 committed by GitHub
parent 7d5ba342c6
commit f1655c5d1a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 219 additions and 34 deletions

View File

@ -10,16 +10,31 @@ from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA, PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorDeviceClass, SensorDeviceClass,
SensorEntity, SensorEntity,
SensorEntityDescription,
SensorStateClass, SensorStateClass,
) )
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
CONF_API_KEY, CONF_API_KEY,
CONF_ID, CONF_ID,
CONF_UNIT_OF_MEASUREMENT, CONF_UNIT_OF_MEASUREMENT,
CONF_URL, CONF_URL,
CONF_VALUE_TEMPLATE, CONF_VALUE_TEMPLATE,
PERCENTAGE,
UnitOfApparentPower,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfFrequency,
UnitOfPower, UnitOfPower,
UnitOfPressure,
UnitOfSoundPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfVolume,
UnitOfVolumeFlowRate,
) )
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
@ -41,6 +56,146 @@ from .const import (
) )
from .coordinator import EmoncmsCoordinator from .coordinator import EmoncmsCoordinator
SENSORS: dict[str | None, SensorEntityDescription] = {
"kWh": SensorEntityDescription(
key="energy|kWh",
translation_key="energy",
device_class=SensorDeviceClass.ENERGY,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
state_class=SensorStateClass.TOTAL_INCREASING,
),
"Wh": SensorEntityDescription(
key="energy|Wh",
translation_key="energy",
device_class=SensorDeviceClass.ENERGY,
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
state_class=SensorStateClass.TOTAL_INCREASING,
),
"kW": SensorEntityDescription(
key="power|kW",
translation_key="power",
device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.KILO_WATT,
state_class=SensorStateClass.MEASUREMENT,
),
"W": SensorEntityDescription(
key="power|W",
translation_key="power",
device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.WATT,
state_class=SensorStateClass.MEASUREMENT,
),
"V": SensorEntityDescription(
key="voltage",
translation_key="voltage",
device_class=SensorDeviceClass.VOLTAGE,
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT,
),
"A": SensorEntityDescription(
key="current",
translation_key="current",
device_class=SensorDeviceClass.CURRENT,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
state_class=SensorStateClass.MEASUREMENT,
),
"VA": SensorEntityDescription(
key="apparent_power",
translation_key="apparent_power",
device_class=SensorDeviceClass.APPARENT_POWER,
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
state_class=SensorStateClass.MEASUREMENT,
),
"°C": SensorEntityDescription(
key="temperature|celsius",
translation_key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
),
"°F": SensorEntityDescription(
key="temperature|fahrenheit",
translation_key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
),
"K": SensorEntityDescription(
key="temperature|kelvin",
translation_key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.KELVIN,
state_class=SensorStateClass.MEASUREMENT,
),
"Hz": SensorEntityDescription(
key="frequency",
translation_key="frequency",
device_class=SensorDeviceClass.FREQUENCY,
native_unit_of_measurement=UnitOfFrequency.HERTZ,
state_class=SensorStateClass.MEASUREMENT,
),
"hPa": SensorEntityDescription(
key="pressure",
translation_key="pressure",
device_class=SensorDeviceClass.PRESSURE,
native_unit_of_measurement=UnitOfPressure.HPA,
state_class=SensorStateClass.MEASUREMENT,
),
"dB": SensorEntityDescription(
key="decibel",
translation_key="decibel",
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
native_unit_of_measurement=UnitOfSoundPressure.DECIBEL,
state_class=SensorStateClass.MEASUREMENT,
),
"": SensorEntityDescription(
key="volume|cubic_meter",
translation_key="volume",
device_class=SensorDeviceClass.VOLUME_STORAGE,
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
state_class=SensorStateClass.MEASUREMENT,
),
"m³/h": SensorEntityDescription(
key="flow|cubic_meters_per_hour",
translation_key="flow",
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
),
"l/m": SensorEntityDescription(
key="flow|liters_per_minute",
translation_key="flow",
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
native_unit_of_measurement=UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
state_class=SensorStateClass.MEASUREMENT,
),
"m/s": SensorEntityDescription(
key="speed|meters_per_second",
translation_key="speed",
device_class=SensorDeviceClass.SPEED,
native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
state_class=SensorStateClass.MEASUREMENT,
),
"µg/m³": SensorEntityDescription(
key="concentration|microgram_per_cubic_meter",
translation_key="concentration",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
),
"ppm": SensorEntityDescription(
key="concentration|microgram_parts_per_million",
translation_key="concentration",
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
),
"%": SensorEntityDescription(
key="percent",
translation_key="percent",
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
}
ATTR_FEEDID = "FeedId" ATTR_FEEDID = "FeedId"
ATTR_FEEDNAME = "FeedName" ATTR_FEEDNAME = "FeedName"
ATTR_LASTUPDATETIME = "LastUpdated" ATTR_LASTUPDATETIME = "LastUpdated"
@ -173,6 +328,8 @@ async def async_setup_entry(
class EmonCmsSensor(CoordinatorEntity[EmoncmsCoordinator], SensorEntity): class EmonCmsSensor(CoordinatorEntity[EmoncmsCoordinator], SensorEntity):
"""Implementation of an Emoncms sensor.""" """Implementation of an Emoncms sensor."""
_attr_has_entity_name = True
def __init__( def __init__(
self, self,
coordinator: EmoncmsCoordinator, coordinator: EmoncmsCoordinator,
@ -187,33 +344,15 @@ class EmonCmsSensor(CoordinatorEntity[EmoncmsCoordinator], SensorEntity):
elem = {} elem = {}
if self.coordinator.data: if self.coordinator.data:
elem = self.coordinator.data[self.idx] elem = self.coordinator.data[self.idx]
self._attr_name = f"{name} {elem[FEED_NAME]}" self._attr_translation_placeholders = {
self._attr_native_unit_of_measurement = unit_of_measurement "emoncms_details": f"{elem[FEED_TAG]} {elem[FEED_NAME]}",
}
self._attr_unique_id = f"{unique_id}-{elem[FEED_ID]}" self._attr_unique_id = f"{unique_id}-{elem[FEED_ID]}"
if unit_of_measurement in ("kWh", "Wh"): description = SENSORS.get(unit_of_measurement)
self._attr_device_class = SensorDeviceClass.ENERGY if description is not None:
self._attr_state_class = SensorStateClass.TOTAL_INCREASING self.entity_description = description
elif unit_of_measurement == "W": else:
self._attr_device_class = SensorDeviceClass.POWER self._attr_native_unit_of_measurement = unit_of_measurement
self._attr_state_class = SensorStateClass.MEASUREMENT
elif unit_of_measurement == "V":
self._attr_device_class = SensorDeviceClass.VOLTAGE
self._attr_state_class = SensorStateClass.MEASUREMENT
elif unit_of_measurement == "A":
self._attr_device_class = SensorDeviceClass.CURRENT
self._attr_state_class = SensorStateClass.MEASUREMENT
elif unit_of_measurement == "VA":
self._attr_device_class = SensorDeviceClass.APPARENT_POWER
self._attr_state_class = SensorStateClass.MEASUREMENT
elif unit_of_measurement in ("°C", "°F", "K"):
self._attr_device_class = SensorDeviceClass.TEMPERATURE
self._attr_state_class = SensorStateClass.MEASUREMENT
elif unit_of_measurement == "Hz":
self._attr_device_class = SensorDeviceClass.FREQUENCY
self._attr_state_class = SensorStateClass.MEASUREMENT
elif unit_of_measurement == "hPa":
self._attr_device_class = SensorDeviceClass.PRESSURE
self._attr_state_class = SensorStateClass.MEASUREMENT
self._update_attributes(elem) self._update_attributes(elem)
def _update_attributes(self, elem: dict[str, Any]) -> None: def _update_attributes(self, elem: dict[str, Any]) -> None:

View File

@ -24,6 +24,52 @@
"already_configured": "This server is already configured" "already_configured": "This server is already configured"
} }
}, },
"entity": {
"sensor": {
"energy": {
"name": "Energy {emoncms_details}"
},
"power": {
"name": "Power {emoncms_details}"
},
"percent": {
"name": "Percentage {emoncms_details}"
},
"voltage": {
"name": "Voltage {emoncms_details}"
},
"current": {
"name": "Current {emoncms_details}"
},
"apparent_power": {
"name": "Apparent power {emoncms_details}"
},
"temperature": {
"name": "Temperature {emoncms_details}"
},
"frequency": {
"name": "Frequency {emoncms_details}"
},
"pressure": {
"name": "Pressure {emoncms_details}"
},
"decibel": {
"name": "Decibel {emoncms_details}"
},
"volume": {
"name": "Volume {emoncms_details}"
},
"flow": {
"name": "Flow rate {emoncms_details}"
},
"speed": {
"name": "Speed {emoncms_details}"
},
"concentration": {
"name": "Concentration {emoncms_details}"
}
}
},
"options": { "options": {
"error": { "error": {
"api_error": "[%key:component::emoncms::config::error::api_error%]" "api_error": "[%key:component::emoncms::config::error::api_error%]"

View File

@ -1,5 +1,5 @@
# serializer version: 1 # serializer version: 1
# name: test_coordinator_update[sensor.emoncms_1_1_1_1_parameter_1-entry] # name: test_coordinator_update[sensor.temperature_tag_parameter_1-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({
}), }),
@ -13,8 +13,8 @@
'disabled_by': None, 'disabled_by': None,
'domain': 'sensor', 'domain': 'sensor',
'entity_category': None, 'entity_category': None,
'entity_id': 'sensor.emoncms_1_1_1_1_parameter_1', 'entity_id': 'sensor.temperature_tag_parameter_1',
'has_entity_name': False, 'has_entity_name': True,
'hidden_by': None, 'hidden_by': None,
'icon': None, 'icon': None,
'id': <ANY>, 'id': <ANY>,
@ -25,16 +25,16 @@
}), }),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>, 'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None, 'original_icon': None,
'original_name': 'emoncms@1.1.1.1 parameter 1', 'original_name': 'Temperature tag parameter 1',
'platform': 'emoncms', 'platform': 'emoncms',
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': None, 'translation_key': 'temperature',
'unique_id': '123-53535292-1', 'unique_id': '123-53535292-1',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>, 'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}) })
# --- # ---
# name: test_coordinator_update[sensor.emoncms_1_1_1_1_parameter_1-state] # name: test_coordinator_update[sensor.temperature_tag_parameter_1-state]
StateSnapshot({ StateSnapshot({
'attributes': ReadOnlyDict({ 'attributes': ReadOnlyDict({
'FeedId': '1', 'FeedId': '1',
@ -45,12 +45,12 @@
'Tag': 'tag', 'Tag': 'tag',
'UserId': '1', 'UserId': '1',
'device_class': 'temperature', 'device_class': 'temperature',
'friendly_name': 'emoncms@1.1.1.1 parameter 1', 'friendly_name': 'Temperature tag parameter 1',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>, 'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}), }),
'context': <ANY>, 'context': <ANY>,
'entity_id': 'sensor.emoncms_1_1_1_1_parameter_1', 'entity_id': 'sensor.temperature_tag_parameter_1',
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,