Add entity name translations to AVM Fritz!SmartHome (#90707)

* add entity name translation

* sort and capitalize

* adjust tests

* sort entities
pull/90855/head
Michael 2023-04-03 19:04:09 +02:00 committed by Paulus Schoutsen
parent 0c12d45581
commit eaaf24d326
7 changed files with 67 additions and 42 deletions

View File

@ -113,8 +113,8 @@ class FritzBoxEntity(CoordinatorEntity[FritzboxDataUpdateCoordinator], ABC):
self.ain = ain
if entity_description is not None:
self._attr_has_entity_name = True
self.entity_description = entity_description
self._attr_name = f"{self.data.name} {entity_description.name}"
self._attr_unique_id = f"{ain}_{entity_description.key}"
else:
self._attr_name = self.data.name

View File

@ -40,14 +40,14 @@ class FritzBinarySensorEntityDescription(
BINARY_SENSOR_TYPES: Final[tuple[FritzBinarySensorEntityDescription, ...]] = (
FritzBinarySensorEntityDescription(
key="alarm",
name="Alarm",
translation_key="alarm",
device_class=BinarySensorDeviceClass.WINDOW,
suitable=lambda device: device.has_alarm, # type: ignore[no-any-return]
is_on=lambda device: device.alert_state, # type: ignore[no-any-return]
),
FritzBinarySensorEntityDescription(
key="lock",
name="Button Lock on Device",
translation_key="lock",
device_class=BinarySensorDeviceClass.LOCK,
entity_category=EntityCategory.CONFIG,
suitable=lambda device: device.lock is not None,
@ -55,7 +55,7 @@ BINARY_SENSOR_TYPES: Final[tuple[FritzBinarySensorEntityDescription, ...]] = (
),
FritzBinarySensorEntityDescription(
key="device_lock",
name="Button Lock via UI",
translation_key="device_lock",
device_class=BinarySensorDeviceClass.LOCK,
entity_category=EntityCategory.CONFIG,
suitable=lambda device: device.device_lock is not None,
@ -87,17 +87,6 @@ class FritzboxBinarySensor(FritzBoxDeviceEntity, BinarySensorEntity):
entity_description: FritzBinarySensorEntityDescription
def __init__(
self,
coordinator: FritzboxDataUpdateCoordinator,
ain: str,
entity_description: FritzBinarySensorEntityDescription,
) -> None:
"""Initialize the FritzBox entity."""
super().__init__(coordinator, ain, entity_description)
self._attr_name = f"{self.data.name} {entity_description.name}"
self._attr_unique_id = f"{ain}_{entity_description.key}"
@property
def is_on(self) -> bool | None:
"""Return true if sensor is on."""

View File

@ -91,7 +91,7 @@ def value_scheduled_preset(device: FritzhomeDevice) -> str:
SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
FritzSensorEntityDescription(
key="temperature",
name="Temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
@ -101,7 +101,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="humidity",
name="Humidity",
translation_key="humidity",
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
@ -110,7 +110,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="battery",
name="Battery",
translation_key="battery",
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
@ -119,7 +119,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="power_consumption",
name="Power Consumption",
translation_key="power_consumption",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
@ -128,7 +128,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="voltage",
name="Voltage",
translation_key="voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
@ -137,7 +137,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="electric_current",
name="Electric Current",
translation_key="electric_current",
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
device_class=SensorDeviceClass.CURRENT,
state_class=SensorStateClass.MEASUREMENT,
@ -146,7 +146,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="total_energy",
name="Total Energy",
translation_key="total_energy",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
@ -156,7 +156,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
# Thermostat Sensors
FritzSensorEntityDescription(
key="comfort_temperature",
name="Comfort Temperature",
translation_key="comfort_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
suitable=suitable_comfort_temperature,
@ -164,7 +164,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="eco_temperature",
name="Eco Temperature",
translation_key="eco_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
suitable=suitable_eco_temperature,
@ -172,7 +172,7 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="nextchange_temperature",
name="Next Scheduled Temperature",
translation_key="nextchange_temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
suitable=suitable_nextchange_temperature,
@ -180,20 +180,20 @@ SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
),
FritzSensorEntityDescription(
key="nextchange_time",
name="Next Scheduled Change Time",
translation_key="nextchange_time",
device_class=SensorDeviceClass.TIMESTAMP,
suitable=suitable_nextchange_time,
native_value=lambda device: utc_from_timestamp(device.nextchange_endperiod),
),
FritzSensorEntityDescription(
key="nextchange_preset",
name="Next Scheduled Preset",
translation_key="nextchange_preset",
suitable=suitable_nextchange_temperature,
native_value=value_nextchange_preset,
),
FritzSensorEntityDescription(
key="scheduled_preset",
name="Current Scheduled Preset",
translation_key="scheduled_preset",
suitable=suitable_nextchange_temperature,
native_value=value_scheduled_preset,
),

View File

@ -36,5 +36,41 @@
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
}
},
"entity": {
"binary_sensor": {
"alarm": { "name": "Alarm" },
"device_lock": { "name": "Button lock via UI" },
"lock": { "name": "Button lock on device" }
},
"sensor": {
"battery": {
"name": "[%key:component::sensor::entity_component::battery::name%]"
},
"comfort_temperature": { "name": "Comfort temperature" },
"eco_temperature": { "name": "Eco temperature" },
"electric_current": {
"name": "[%key:component::sensor::entity_component::current::name%]"
},
"humidity": {
"name": "[%key:component::sensor::entity_component::humidity::name%]"
},
"nextchange_preset": { "name": "Next scheduled preset" },
"nextchange_temperature": { "name": "Next scheduled temperature" },
"nextchange_time": { "name": "Next scheduled change time" },
"power_consumption": {
"name": "[%key:component::sensor::entity_component::power::name%]"
},
"scheduled_preset": { "name": "Current scheduled preset" },
"temperature": {
"name": "[%key:component::sensor::entity_component::temperature::name%]"
},
"total_energy": {
"name": "[%key:component::sensor::entity_component::energy::name%]"
},
"voltage": {
"name": "[%key:component::sensor::entity_component::voltage::name%]"
}
}
}
}

View File

@ -48,7 +48,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state.state == STATE_OFF
assert (
state.attributes[ATTR_FRIENDLY_NAME]
== f"{CONF_FAKE_NAME} Button Lock on Device"
== f"{CONF_FAKE_NAME} Button lock on device"
)
assert state.attributes[ATTR_DEVICE_CLASS] == BinarySensorDeviceClass.LOCK
assert ATTR_STATE_CLASS not in state.attributes
@ -57,7 +57,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state
assert state.state == STATE_OFF
assert (
state.attributes[ATTR_FRIENDLY_NAME] == f"{CONF_FAKE_NAME} Button Lock via UI"
state.attributes[ATTR_FRIENDLY_NAME] == f"{CONF_FAKE_NAME} Button lock via UI"
)
assert state.attributes[ATTR_DEVICE_CLASS] == BinarySensorDeviceClass.LOCK
assert ATTR_STATE_CLASS not in state.attributes

View File

@ -85,7 +85,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state
assert state.state == "22.0"
assert (
state.attributes[ATTR_FRIENDLY_NAME] == f"{CONF_FAKE_NAME} Comfort Temperature"
state.attributes[ATTR_FRIENDLY_NAME] == f"{CONF_FAKE_NAME} Comfort temperature"
)
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfTemperature.CELSIUS
assert ATTR_STATE_CLASS not in state.attributes
@ -93,7 +93,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
state = hass.states.get(f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_eco_temperature")
assert state
assert state.state == "16.0"
assert state.attributes[ATTR_FRIENDLY_NAME] == f"{CONF_FAKE_NAME} Eco Temperature"
assert state.attributes[ATTR_FRIENDLY_NAME] == f"{CONF_FAKE_NAME} Eco temperature"
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfTemperature.CELSIUS
assert ATTR_STATE_CLASS not in state.attributes
@ -104,7 +104,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state.state == "22.0"
assert (
state.attributes[ATTR_FRIENDLY_NAME]
== f"{CONF_FAKE_NAME} Next Scheduled Temperature"
== f"{CONF_FAKE_NAME} Next scheduled temperature"
)
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfTemperature.CELSIUS
assert ATTR_STATE_CLASS not in state.attributes
@ -116,7 +116,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state.state == "1970-01-01T00:00:00+00:00"
assert (
state.attributes[ATTR_FRIENDLY_NAME]
== f"{CONF_FAKE_NAME} Next Scheduled Change Time"
== f"{CONF_FAKE_NAME} Next scheduled change time"
)
assert ATTR_STATE_CLASS not in state.attributes
@ -125,7 +125,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state.state == PRESET_COMFORT
assert (
state.attributes[ATTR_FRIENDLY_NAME]
== f"{CONF_FAKE_NAME} Next Scheduled Preset"
== f"{CONF_FAKE_NAME} Next scheduled preset"
)
assert ATTR_STATE_CLASS not in state.attributes
@ -136,7 +136,7 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
assert state.state == PRESET_ECO
assert (
state.attributes[ATTR_FRIENDLY_NAME]
== f"{CONF_FAKE_NAME} Current Scheduled Preset"
== f"{CONF_FAKE_NAME} Current scheduled preset"
)
assert ATTR_STATE_CLASS not in state.attributes

View File

@ -62,16 +62,16 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
SensorStateClass.MEASUREMENT,
],
[
f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_power_consumption",
f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_power",
"5.678",
f"{CONF_FAKE_NAME} Power Consumption",
f"{CONF_FAKE_NAME} Power",
UnitOfPower.WATT,
SensorStateClass.MEASUREMENT,
],
[
f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_total_energy",
f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_energy",
"1.234",
f"{CONF_FAKE_NAME} Total Energy",
f"{CONF_FAKE_NAME} Energy",
UnitOfEnergy.KILO_WATT_HOUR,
SensorStateClass.TOTAL_INCREASING,
],
@ -83,9 +83,9 @@ async def test_setup(hass: HomeAssistant, fritz: Mock) -> None:
SensorStateClass.MEASUREMENT,
],
[
f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_electric_current",
f"{SENSOR_DOMAIN}.{CONF_FAKE_NAME}_current",
"0.025",
f"{CONF_FAKE_NAME} Electric Current",
f"{CONF_FAKE_NAME} Current",
UnitOfElectricCurrent.AMPERE,
SensorStateClass.MEASUREMENT,
],