Add entity translations to Powerwall (#98843)

This commit is contained in:
Joost Lekkerkerker 2023-08-22 21:58:57 +02:00 committed by GitHub
parent 0d55718117
commit 0ab0901f0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 191 additions and 53 deletions

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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"
}
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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