From 0ab0901f0f3dc8cc118bc56359b23dd7e8bdce0c Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Tue, 22 Aug 2023 21:58:57 +0200 Subject: [PATCH] Add entity translations to Powerwall (#98843) --- .../components/powerwall/binary_sensor.py | 9 +- homeassistant/components/powerwall/entity.py | 2 + homeassistant/components/powerwall/sensor.py | 20 ++- .../components/powerwall/strings.json | 137 ++++++++++++++++++ homeassistant/components/powerwall/switch.py | 3 +- .../powerwall/test_binary_sensor.py | 33 +++-- tests/components/powerwall/test_sensor.py | 40 ++--- 7 files changed, 191 insertions(+), 53 deletions(-) diff --git a/homeassistant/components/powerwall/binary_sensor.py b/homeassistant/components/powerwall/binary_sensor.py index 0bb089898d1..084ec0ea8a6 100644 --- a/homeassistant/components/powerwall/binary_sensor.py +++ b/homeassistant/components/powerwall/binary_sensor.py @@ -44,7 +44,7 @@ async def async_setup_entry( class PowerWallRunningSensor(PowerWallEntity, BinarySensorEntity): """Representation of an Powerwall running sensor.""" - _attr_name = "Powerwall Status" + _attr_translation_key = "status" _attr_device_class = BinarySensorDeviceClass.POWER @property @@ -61,7 +61,7 @@ class PowerWallRunningSensor(PowerWallEntity, BinarySensorEntity): class PowerWallConnectedSensor(PowerWallEntity, BinarySensorEntity): """Representation of an Powerwall connected sensor.""" - _attr_name = "Powerwall Connected to Tesla" + _attr_translation_key = "connected_to_tesla" _attr_device_class = BinarySensorDeviceClass.CONNECTIVITY @property @@ -78,7 +78,7 @@ class PowerWallConnectedSensor(PowerWallEntity, BinarySensorEntity): class PowerWallGridServicesActiveSensor(PowerWallEntity, BinarySensorEntity): """Representation of a Powerwall grid services active sensor.""" - _attr_name = "Grid Services Active" + _attr_translation_key = "grid_services_active" _attr_device_class = BinarySensorDeviceClass.POWER @property @@ -95,7 +95,7 @@ class PowerWallGridServicesActiveSensor(PowerWallEntity, BinarySensorEntity): class PowerWallGridStatusSensor(PowerWallEntity, BinarySensorEntity): """Representation of an Powerwall grid status sensor.""" - _attr_name = "Grid Status" + _attr_translation_key = "grid_status" _attr_device_class = BinarySensorDeviceClass.POWER @property @@ -112,7 +112,6 @@ class PowerWallGridStatusSensor(PowerWallEntity, BinarySensorEntity): class PowerWallChargingStatusSensor(PowerWallEntity, BinarySensorEntity): """Representation of an Powerwall charging status sensor.""" - _attr_name = "Powerwall Charging" _attr_device_class = BinarySensorDeviceClass.BATTERY_CHARGING @property diff --git a/homeassistant/components/powerwall/entity.py b/homeassistant/components/powerwall/entity.py index db1f5997e3e..f0cfec2cbc5 100644 --- a/homeassistant/components/powerwall/entity.py +++ b/homeassistant/components/powerwall/entity.py @@ -20,6 +20,8 @@ from .models import PowerwallData, PowerwallRuntimeData class PowerWallEntity(CoordinatorEntity[DataUpdateCoordinator[PowerwallData]]): """Base class for powerwall entities.""" + _attr_has_entity_name = True + def __init__(self, powerwall_data: PowerwallRuntimeData) -> None: """Initialize the entity.""" base_info = powerwall_data[POWERWALL_BASE_INFO] diff --git a/homeassistant/components/powerwall/sensor.py b/homeassistant/components/powerwall/sensor.py index cf20e51314f..3f02c925f9d 100644 --- a/homeassistant/components/powerwall/sensor.py +++ b/homeassistant/components/powerwall/sensor.py @@ -69,7 +69,7 @@ def _get_meter_average_voltage(meter: Meter) -> float: POWERWALL_INSTANT_SENSORS = ( PowerwallSensorEntityDescription( key="instant_power", - name="Now", + translation_key="instant_power", state_class=SensorStateClass.MEASUREMENT, device_class=SensorDeviceClass.POWER, native_unit_of_measurement=UnitOfPower.KILO_WATT, @@ -77,7 +77,7 @@ POWERWALL_INSTANT_SENSORS = ( ), PowerwallSensorEntityDescription( key="instant_frequency", - name="Frequency Now", + translation_key="instant_frequency", state_class=SensorStateClass.MEASUREMENT, device_class=SensorDeviceClass.FREQUENCY, native_unit_of_measurement=UnitOfFrequency.HERTZ, @@ -86,7 +86,7 @@ POWERWALL_INSTANT_SENSORS = ( ), PowerwallSensorEntityDescription( key="instant_current", - name="Average Current Now", + translation_key="instant_current", state_class=SensorStateClass.MEASUREMENT, device_class=SensorDeviceClass.CURRENT, native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, @@ -95,7 +95,7 @@ POWERWALL_INSTANT_SENSORS = ( ), PowerwallSensorEntityDescription( key="instant_voltage", - name="Average Voltage Now", + translation_key="instant_voltage", state_class=SensorStateClass.MEASUREMENT, device_class=SensorDeviceClass.VOLTAGE, native_unit_of_measurement=UnitOfElectricPotential.VOLT, @@ -136,7 +136,7 @@ async def async_setup_entry( class PowerWallChargeSensor(PowerWallEntity, SensorEntity): """Representation of an Powerwall charge sensor.""" - _attr_name = "Powerwall Charge" + _attr_translation_key = "charge" _attr_state_class = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = PERCENTAGE _attr_device_class = SensorDeviceClass.BATTERY @@ -167,10 +167,8 @@ class PowerWallEnergySensor(PowerWallEntity, SensorEntity): self.entity_description = description super().__init__(powerwall_data) self._meter = meter - self._attr_name = f"Powerwall {self._meter.value.title()} {description.name}" - self._attr_unique_id = ( - f"{self.base_unique_id}_{self._meter.value}_{description.key}" - ) + self._attr_translation_key = f"{meter.value}_{description.translation_key}" + self._attr_unique_id = f"{self.base_unique_id}_{meter.value}_{description.key}" @property def native_value(self) -> float: @@ -181,7 +179,7 @@ class PowerWallEnergySensor(PowerWallEntity, SensorEntity): class PowerWallBackupReserveSensor(PowerWallEntity, SensorEntity): """Representation of the Powerwall backup reserve setting.""" - _attr_name = "Powerwall Backup Reserve" + _attr_translation_key = "backup_reserve" _attr_state_class = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = PERCENTAGE _attr_device_class = SensorDeviceClass.BATTERY @@ -215,7 +213,7 @@ class PowerWallEnergyDirectionSensor(PowerWallEntity, SensorEntity): """Initialize the sensor.""" super().__init__(powerwall_data) self._meter = meter - self._attr_name = f"Powerwall {meter.value.title()} {meter_direction.title()}" + self._attr_translation_key = f"{meter.value}_{meter_direction}" self._attr_unique_id = f"{self.base_unique_id}_{meter.value}_{meter_direction}" @property diff --git a/homeassistant/components/powerwall/strings.json b/homeassistant/components/powerwall/strings.json index 6306d52838e..dacf63a68dd 100644 --- a/homeassistant/components/powerwall/strings.json +++ b/homeassistant/components/powerwall/strings.json @@ -33,5 +33,142 @@ "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" } + }, + "entity": { + "binary_sensor": { + "status": { + "name": "Status" + }, + "connected_to_tesla": { + "name": "Connected to Tesla" + }, + "grid_status": { + "name": "Grid status" + }, + "grid_services_active": { + "name": "Grid services active" + } + }, + "sensor": { + "charge": { + "name": "Charge" + }, + "solar_instant_power": { + "name": "Solar power" + }, + "solar_instant_frequency": { + "name": "Solar frequency" + }, + "solar_instant_current": { + "name": "Solar current" + }, + "solar_instant_voltage": { + "name": "Solar voltage" + }, + "site_instant_power": { + "name": "Site power" + }, + "site_instant_frequency": { + "name": "Site frequency" + }, + "site_instant_current": { + "name": "Site current" + }, + "site_instant_voltage": { + "name": "Site voltage" + }, + "battery_instant_power": { + "name": "Battery power" + }, + "battery_instant_frequency": { + "name": "Battery frequency" + }, + "battery_instant_current": { + "name": "Battery current" + }, + "battery_instant_voltage": { + "name": "Battery voltage" + }, + "load_instant_power": { + "name": "Load power" + }, + "load_instant_frequency": { + "name": "Load frequency" + }, + "load_instant_current": { + "name": "Load current" + }, + "load_instant_voltage": { + "name": "Load voltage" + }, + "generator_instant_power": { + "name": "Generator power" + }, + "generator_instant_frequency": { + "name": "Generator frequency" + }, + "generator_instant_current": { + "name": "Generator current" + }, + "generator_instant_voltage": { + "name": "Generator voltage" + }, + "busway_instant_power": { + "name": "Busway power" + }, + "busway_instant_frequency": { + "name": "Busway frequency" + }, + "busway_instant_current": { + "name": "Busway current" + }, + "busway_instant_voltage": { + "name": "Busway voltage" + }, + "backup_reserve": { + "name": "Backup reserve" + }, + "solar_import": { + "name": "Solar import" + }, + "solar_export": { + "name": "Solar export" + }, + "site_import": { + "name": "Site import" + }, + "site_export": { + "name": "Site export" + }, + "battery_import": { + "name": "Battery import" + }, + "battery_export": { + "name": "Battery export" + }, + "load_import": { + "name": "Load import" + }, + "load_export": { + "name": "Load export" + }, + "generator_import": { + "name": "Generator import" + }, + "generator_export": { + "name": "Generator export" + }, + "busway_import": { + "name": "Busway import" + }, + "busway_export": { + "name": "Busway export" + } + }, + "switch": { + "off_grid_operation": { + "name": "Off-grid operation" + } + } } } diff --git a/homeassistant/components/powerwall/switch.py b/homeassistant/components/powerwall/switch.py index 48db62df97a..8516890d633 100644 --- a/homeassistant/components/powerwall/switch.py +++ b/homeassistant/components/powerwall/switch.py @@ -34,8 +34,7 @@ async def async_setup_entry( class PowerwallOffGridEnabledEntity(PowerWallEntity, SwitchEntity): """Representation of a Switch entity for Powerwall Off-grid operation.""" - _attr_name = "Off-Grid operation" - _attr_has_entity_name = True + _attr_translation_key = "off_grid_operation" _attr_entity_category = EntityCategory.CONFIG _attr_device_class = SwitchDeviceClass.SWITCH diff --git a/tests/components/powerwall/test_binary_sensor.py b/tests/components/powerwall/test_binary_sensor.py index acea33186a8..b0a62f42368 100644 --- a/tests/components/powerwall/test_binary_sensor.py +++ b/tests/components/powerwall/test_binary_sensor.py @@ -26,47 +26,50 @@ async def test_sensors(hass: HomeAssistant) -> None: assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - state = hass.states.get("binary_sensor.grid_services_active") + state = hass.states.get("binary_sensor.mysite_grid_services_active") assert state.state == STATE_ON expected_attributes = { - "friendly_name": "Grid Services Active", + "friendly_name": "MySite Grid services active", "device_class": "power", } # Only test for a subset of attributes in case # HA changes the implementation and a new one appears assert all(item in state.attributes.items() for item in expected_attributes.items()) - state = hass.states.get("binary_sensor.grid_status") - assert state.state == STATE_ON - expected_attributes = {"friendly_name": "Grid Status", "device_class": "power"} - # Only test for a subset of attributes in case - # HA changes the implementation and a new one appears - assert all(item in state.attributes.items() for item in expected_attributes.items()) - - state = hass.states.get("binary_sensor.powerwall_status") + state = hass.states.get("binary_sensor.mysite_grid_status") assert state.state == STATE_ON expected_attributes = { - "friendly_name": "Powerwall Status", + "friendly_name": "MySite Grid status", "device_class": "power", } # Only test for a subset of attributes in case # HA changes the implementation and a new one appears assert all(item in state.attributes.items() for item in expected_attributes.items()) - state = hass.states.get("binary_sensor.powerwall_connected_to_tesla") + state = hass.states.get("binary_sensor.mysite_status") assert state.state == STATE_ON expected_attributes = { - "friendly_name": "Powerwall Connected to Tesla", + "friendly_name": "MySite Status", + "device_class": "power", + } + # Only test for a subset of attributes in case + # HA changes the implementation and a new one appears + assert all(item in state.attributes.items() for item in expected_attributes.items()) + + state = hass.states.get("binary_sensor.mysite_connected_to_tesla") + assert state.state == STATE_ON + expected_attributes = { + "friendly_name": "MySite Connected to Tesla", "device_class": "connectivity", } # Only test for a subset of attributes in case # HA changes the implementation and a new one appears assert all(item in state.attributes.items() for item in expected_attributes.items()) - state = hass.states.get("binary_sensor.powerwall_charging") + state = hass.states.get("binary_sensor.mysite_charging") assert state.state == STATE_ON expected_attributes = { - "friendly_name": "Powerwall Charging", + "friendly_name": "MySite Charging", "device_class": "battery_charging", } # Only test for a subset of attributes in case diff --git a/tests/components/powerwall/test_sensor.py b/tests/components/powerwall/test_sensor.py index a0d4d7f9e96..e7772571c86 100644 --- a/tests/components/powerwall/test_sensor.py +++ b/tests/components/powerwall/test_sensor.py @@ -47,58 +47,58 @@ async def test_sensors( assert reg_device.manufacturer == "Tesla" assert reg_device.name == "MySite" - state = hass.states.get("sensor.powerwall_load_now") + state = hass.states.get("sensor.mysite_load_power") assert state.state == "1.971" attributes = state.attributes assert attributes[ATTR_DEVICE_CLASS] == "power" assert attributes[ATTR_UNIT_OF_MEASUREMENT] == "kW" assert attributes[ATTR_STATE_CLASS] == "measurement" - assert attributes[ATTR_FRIENDLY_NAME] == "Powerwall Load Now" + assert attributes[ATTR_FRIENDLY_NAME] == "MySite Load power" - state = hass.states.get("sensor.powerwall_load_frequency_now") + state = hass.states.get("sensor.mysite_load_frequency") assert state.state == "60" attributes = state.attributes assert attributes[ATTR_DEVICE_CLASS] == "frequency" assert attributes[ATTR_UNIT_OF_MEASUREMENT] == "Hz" assert attributes[ATTR_STATE_CLASS] == "measurement" - assert attributes[ATTR_FRIENDLY_NAME] == "Powerwall Load Frequency Now" + assert attributes[ATTR_FRIENDLY_NAME] == "MySite Load frequency" - state = hass.states.get("sensor.powerwall_load_average_voltage_now") + state = hass.states.get("sensor.mysite_load_voltage") assert state.state == "120.7" attributes = state.attributes assert attributes[ATTR_DEVICE_CLASS] == "voltage" assert attributes[ATTR_UNIT_OF_MEASUREMENT] == "V" assert attributes[ATTR_STATE_CLASS] == "measurement" - assert attributes[ATTR_FRIENDLY_NAME] == "Powerwall Load Average Voltage Now" + assert attributes[ATTR_FRIENDLY_NAME] == "MySite Load voltage" - state = hass.states.get("sensor.powerwall_load_average_current_now") + state = hass.states.get("sensor.mysite_load_current") assert state.state == "0" attributes = state.attributes assert attributes[ATTR_DEVICE_CLASS] == "current" assert attributes[ATTR_UNIT_OF_MEASUREMENT] == "A" assert attributes[ATTR_STATE_CLASS] == "measurement" - assert attributes[ATTR_FRIENDLY_NAME] == "Powerwall Load Average Current Now" + assert attributes[ATTR_FRIENDLY_NAME] == "MySite Load current" - assert float(hass.states.get("sensor.powerwall_load_export").state) == 1056.8 - assert float(hass.states.get("sensor.powerwall_load_import").state) == 4693.0 + assert float(hass.states.get("sensor.mysite_load_export").state) == 1056.8 + assert float(hass.states.get("sensor.mysite_load_import").state) == 4693.0 - state = hass.states.get("sensor.powerwall_battery_now") + state = hass.states.get("sensor.mysite_battery_power") assert state.state == "-8.55" - assert float(hass.states.get("sensor.powerwall_battery_export").state) == 3620.0 - assert float(hass.states.get("sensor.powerwall_battery_import").state) == 4216.2 + assert float(hass.states.get("sensor.mysite_battery_export").state) == 3620.0 + assert float(hass.states.get("sensor.mysite_battery_import").state) == 4216.2 - state = hass.states.get("sensor.powerwall_solar_now") + state = hass.states.get("sensor.mysite_solar_power") assert state.state == "10.49" - assert float(hass.states.get("sensor.powerwall_solar_export").state) == 9864.2 - assert float(hass.states.get("sensor.powerwall_solar_import").state) == 28.2 + assert float(hass.states.get("sensor.mysite_solar_export").state) == 9864.2 + assert float(hass.states.get("sensor.mysite_solar_import").state) == 28.2 - state = hass.states.get("sensor.powerwall_charge") + state = hass.states.get("sensor.mysite_charge") assert state.state == "47" expected_attributes = { "unit_of_measurement": PERCENTAGE, - "friendly_name": "Powerwall Charge", + "friendly_name": "MySite Charge", "device_class": "battery", } # Only test for a subset of attributes in case @@ -106,11 +106,11 @@ async def test_sensors( for key, value in expected_attributes.items(): assert state.attributes[key] == value - state = hass.states.get("sensor.powerwall_backup_reserve") + state = hass.states.get("sensor.mysite_backup_reserve") assert state.state == "15" expected_attributes = { "unit_of_measurement": PERCENTAGE, - "friendly_name": "Powerwall Backup Reserve", + "friendly_name": "MySite Backup reserve", "device_class": "battery", } # Only test for a subset of attributes in case