mirror of
https://github.com/home-assistant/core.git
synced 2026-02-14 23:28:42 +00:00
Expose power and energy sensors for vera metered switches (#161028)
This commit is contained in:
@@ -11,12 +11,14 @@ from homeassistant.components.sensor import (
|
||||
ENTITY_ID_FORMAT,
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
LIGHT_LUX,
|
||||
PERCENTAGE,
|
||||
Platform,
|
||||
UnitOfEnergy,
|
||||
UnitOfPower,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
@@ -36,13 +38,19 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
|
||||
entities: list[SensorEntity] = [
|
||||
VeraSensor(device, controller_data)
|
||||
for device in controller_data.devices[Platform.SENSOR]
|
||||
],
|
||||
True,
|
||||
)
|
||||
]
|
||||
|
||||
for device in controller_data.devices[Platform.SWITCH]:
|
||||
if device.power is not None:
|
||||
entities.append(VeraPowerSensor(device, controller_data))
|
||||
if device.energy is not None:
|
||||
entities.append(VeraEnergySensor(device, controller_data))
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class VeraSensor(VeraEntity[veraApi.VeraSensor], SensorEntity):
|
||||
@@ -109,3 +117,45 @@ class VeraSensor(VeraEntity[veraApi.VeraSensor], SensorEntity):
|
||||
self._attr_native_value = "Tripped" if tripped else "Not Tripped"
|
||||
else:
|
||||
self._attr_native_value = "Unknown"
|
||||
|
||||
|
||||
class VeraPowerSensor(VeraEntity[veraApi.VeraSwitch], SensorEntity):
|
||||
"""Power sensor derived from a Vera switch with metering."""
|
||||
|
||||
_attr_device_class = SensorDeviceClass.POWER
|
||||
_attr_has_entity_name = True
|
||||
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||
_attr_native_unit_of_measurement = UnitOfPower.WATT
|
||||
|
||||
def __init__(
|
||||
self, vera_device: veraApi.VeraSwitch, controller_data: ControllerData
|
||||
) -> None:
|
||||
"""Initialize the power sensor."""
|
||||
VeraEntity.__init__(self, vera_device, controller_data)
|
||||
self._unique_id = f"{self._unique_id}_power"
|
||||
|
||||
def update(self) -> None:
|
||||
"""Update the sensor state."""
|
||||
super().update()
|
||||
self._attr_native_value = self.vera_device.power
|
||||
|
||||
|
||||
class VeraEnergySensor(VeraEntity[veraApi.VeraSwitch], SensorEntity):
|
||||
"""Energy sensor derived from a Vera switch with metering."""
|
||||
|
||||
_attr_device_class = SensorDeviceClass.ENERGY
|
||||
_attr_has_entity_name = True
|
||||
_attr_state_class = SensorStateClass.TOTAL_INCREASING
|
||||
_attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
|
||||
|
||||
def __init__(
|
||||
self, vera_device: veraApi.VeraSwitch, controller_data: ControllerData
|
||||
) -> None:
|
||||
"""Initialize the energy sensor."""
|
||||
VeraEntity.__init__(self, vera_device, controller_data)
|
||||
self._unique_id = f"{self._unique_id}_energy"
|
||||
|
||||
def update(self) -> None:
|
||||
"""Update the sensor state."""
|
||||
super().update()
|
||||
self._attr_native_value = self.vera_device.energy
|
||||
|
||||
@@ -11,6 +11,7 @@ import pyvera as pv
|
||||
from homeassistant.components.sensor import async_rounded_state
|
||||
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, LIGHT_LUX, PERCENTAGE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .common import ComponentFactory, new_simple_controller_config
|
||||
|
||||
@@ -201,3 +202,97 @@ async def test_scene_controller_sensor(
|
||||
update_callback(vera_device)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(entity_id).state == "id0"
|
||||
|
||||
|
||||
async def test_switch_power_and_energy_sensors_created(
|
||||
hass: HomeAssistant,
|
||||
vera_component_factory: ComponentFactory,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test that switches with metering expose power and energy sensors."""
|
||||
vera_switch: pv.VeraSwitch = MagicMock(spec=pv.VeraSwitch)
|
||||
vera_switch.device_id = 1
|
||||
vera_switch.vera_device_id = vera_switch.device_id
|
||||
vera_switch.comm_failure = False
|
||||
vera_switch.name = "metered_switch"
|
||||
vera_switch.category = 0
|
||||
vera_switch.power = 12
|
||||
vera_switch.energy = 3
|
||||
|
||||
vera_sensor: pv.VeraSensor = MagicMock(spec=pv.VeraSensor)
|
||||
vera_sensor.device_id = 2
|
||||
vera_sensor.vera_device_id = vera_sensor.device_id
|
||||
vera_sensor.comm_failure = False
|
||||
vera_sensor.name = "dummy_sensor"
|
||||
vera_sensor.category = pv.CATEGORY_TEMPERATURE_SENSOR
|
||||
vera_sensor.temperature = "20"
|
||||
|
||||
await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
devices=(vera_switch, vera_sensor)
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
power_entity_id = entity_registry.async_get_entity_id(
|
||||
"sensor", "vera", "vera_1111_1_power"
|
||||
)
|
||||
energy_entity_id = entity_registry.async_get_entity_id(
|
||||
"sensor", "vera", "vera_1111_1_energy"
|
||||
)
|
||||
|
||||
assert power_entity_id is not None
|
||||
assert energy_entity_id is not None
|
||||
|
||||
power_state = hass.states.get(power_entity_id)
|
||||
assert power_state is not None
|
||||
assert power_state.state == "12"
|
||||
assert power_state.attributes[ATTR_UNIT_OF_MEASUREMENT] == "W"
|
||||
|
||||
energy_state = hass.states.get(energy_entity_id)
|
||||
assert energy_state is not None
|
||||
assert energy_state.state == "3"
|
||||
assert energy_state.attributes[ATTR_UNIT_OF_MEASUREMENT] == "kWh"
|
||||
|
||||
|
||||
async def test_switch_without_metering_does_not_create_power_energy_sensors(
|
||||
hass: HomeAssistant,
|
||||
vera_component_factory: ComponentFactory,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test that non-metered switches do not create power/energy sensors."""
|
||||
vera_switch: pv.VeraSwitch = MagicMock(spec=pv.VeraSwitch)
|
||||
vera_switch.device_id = 1
|
||||
vera_switch.vera_device_id = vera_switch.device_id
|
||||
vera_switch.comm_failure = False
|
||||
vera_switch.name = "plain_switch"
|
||||
vera_switch.category = 0
|
||||
vera_switch.power = None
|
||||
vera_switch.energy = None
|
||||
|
||||
vera_sensor: pv.VeraSensor = MagicMock(spec=pv.VeraSensor)
|
||||
vera_sensor.device_id = 2
|
||||
vera_sensor.vera_device_id = vera_sensor.device_id
|
||||
vera_sensor.comm_failure = False
|
||||
vera_sensor.name = "dummy_sensor"
|
||||
vera_sensor.category = pv.CATEGORY_TEMPERATURE_SENSOR
|
||||
vera_sensor.temperature = "20"
|
||||
|
||||
await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
devices=(vera_switch, vera_sensor)
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
power_entity_id = entity_registry.async_get_entity_id(
|
||||
"sensor", "vera", "vera_1111_1_power"
|
||||
)
|
||||
energy_entity_id = entity_registry.async_get_entity_id(
|
||||
"sensor", "vera", "vera_1111_1_energy"
|
||||
)
|
||||
|
||||
assert power_entity_id is None
|
||||
assert energy_entity_id is None
|
||||
|
||||
Reference in New Issue
Block a user