core/tests/components/homewizard/test_sensor.py

748 lines
23 KiB
Python
Raw Normal View History

"""Test the update coordinator for HomeWizard."""
from datetime import timedelta
from unittest.mock import AsyncMock, patch
from aiohwenergy.errors import DisabledError
from homeassistant.components.sensor import (
ATTR_STATE_CLASS,
STATE_CLASS_MEASUREMENT,
STATE_CLASS_TOTAL_INCREASING,
)
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_FRIENDLY_NAME,
ATTR_ICON,
ATTR_UNIT_OF_MEASUREMENT,
DEVICE_CLASS_ENERGY,
DEVICE_CLASS_GAS,
DEVICE_CLASS_POWER,
ENERGY_KILO_WATT_HOUR,
POWER_WATT,
VOLUME_CUBIC_METERS,
)
from homeassistant.helpers import entity_registry as er
import homeassistant.util.dt as dt_util
from .generator import get_mock_device
from tests.common import async_fire_time_changed
async def test_sensor_entity_smr_version(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads smr version."""
api = get_mock_device()
api.data.available_datapoints = [
"smr_version",
]
api.data.smr_version = 50
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_dsmr_version")
entry = entity_registry.async_get("sensor.product_name_aabbccddeeff_dsmr_version")
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_smr_version"
assert not entry.disabled
assert state.state == "50"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) DSMR Version"
)
assert ATTR_STATE_CLASS not in state.attributes
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert ATTR_DEVICE_CLASS not in state.attributes
assert state.attributes.get(ATTR_ICON) == "mdi:counter"
async def test_sensor_entity_meter_model(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads meter model."""
api = get_mock_device()
api.data.available_datapoints = [
"meter_model",
]
api.data.meter_model = "Model X"
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_smart_meter_model")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_smart_meter_model"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_meter_model"
assert not entry.disabled
assert state.state == "Model X"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Smart Meter Model"
)
assert ATTR_STATE_CLASS not in state.attributes
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert ATTR_DEVICE_CLASS not in state.attributes
assert state.attributes.get(ATTR_ICON) == "mdi:gauge"
async def test_sensor_entity_wifi_ssid(hass, mock_config_entry_data, mock_config_entry):
"""Test entity loads wifi ssid."""
api = get_mock_device()
api.data.available_datapoints = [
"wifi_ssid",
]
api.data.wifi_ssid = "My Wifi"
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_wifi_ssid")
entry = entity_registry.async_get("sensor.product_name_aabbccddeeff_wifi_ssid")
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_wifi_ssid"
assert not entry.disabled
assert state.state == "My Wifi"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Wifi SSID"
)
assert ATTR_STATE_CLASS not in state.attributes
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert ATTR_DEVICE_CLASS not in state.attributes
assert state.attributes.get(ATTR_ICON) == "mdi:wifi"
async def test_sensor_entity_wifi_strength(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads wifi strength."""
api = get_mock_device()
api.data.available_datapoints = [
"wifi_strength",
]
api.data.wifi_strength = 42
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
entry = entity_registry.async_get("sensor.product_name_aabbccddeeff_wifi_strength")
assert entry
assert entry.unique_id == "aabbccddeeff_wifi_strength"
assert entry.disabled
async def test_sensor_entity_total_power_import_t1_kwh(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads total power import t1."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_import_t1_kwh",
]
api.data.total_power_import_t1_kwh = 1234.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_total_power_import_t1")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_total_power_import_t1_kwh"
assert not entry.disabled
assert state.state == "1234.123"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Total Power Import T1"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_TOTAL_INCREASING
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_KILO_WATT_HOUR
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_ENERGY
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_total_power_import_t2_kwh(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads total power import t2."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_import_t2_kwh",
]
api.data.total_power_import_t2_kwh = 1234.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_total_power_import_t2")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_total_power_import_t2"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_total_power_import_t2_kwh"
assert not entry.disabled
assert state.state == "1234.123"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Total Power Import T2"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_TOTAL_INCREASING
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_KILO_WATT_HOUR
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_ENERGY
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_total_power_export_t1_kwh(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads total power export t1."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_export_t1_kwh",
]
api.data.total_power_export_t1_kwh = 1234.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_total_power_export_t1")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_total_power_export_t1"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_total_power_export_t1_kwh"
assert not entry.disabled
assert state.state == "1234.123"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Total Power Export T1"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_TOTAL_INCREASING
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_KILO_WATT_HOUR
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_ENERGY
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_total_power_export_t2_kwh(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads total power export t2."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_export_t2_kwh",
]
api.data.total_power_export_t2_kwh = 1234.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_total_power_export_t2")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_total_power_export_t2"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_total_power_export_t2_kwh"
assert not entry.disabled
assert state.state == "1234.123"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Total Power Export T2"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_TOTAL_INCREASING
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_KILO_WATT_HOUR
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_ENERGY
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_active_power(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads active power."""
api = get_mock_device()
api.data.available_datapoints = [
"active_power_w",
]
api.data.active_power_w = 123.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_active_power")
entry = entity_registry.async_get("sensor.product_name_aabbccddeeff_active_power")
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_active_power_w"
assert not entry.disabled
assert state.state == "123.123"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Active Power"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_active_power_l1(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads active power l1."""
api = get_mock_device()
api.data.available_datapoints = [
"active_power_l1_w",
]
api.data.active_power_l1_w = 123.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_active_power_l1")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_active_power_l1"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_active_power_l1_w"
assert not entry.disabled
assert state.state == "123.123"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Active Power L1"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_active_power_l2(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads active power l2."""
api = get_mock_device()
api.data.available_datapoints = [
"active_power_l2_w",
]
api.data.active_power_l2_w = 456.456
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_active_power_l2")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_active_power_l2"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_active_power_l2_w"
assert not entry.disabled
assert state.state == "456.456"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Active Power L2"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_active_power_l3(
hass, mock_config_entry_data, mock_config_entry
):
"""Test entity loads active power l3."""
api = get_mock_device()
api.data.available_datapoints = [
"active_power_l3_w",
]
api.data.active_power_l3_w = 789.789
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_active_power_l3")
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_active_power_l3"
)
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_active_power_l3_w"
assert not entry.disabled
assert state.state == "789.789"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Active Power L3"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_total_gas(hass, mock_config_entry_data, mock_config_entry):
"""Test entity loads total gas."""
api = get_mock_device()
api.data.available_datapoints = [
"total_gas_m3",
]
api.data.total_gas_m3 = 50
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
state = hass.states.get("sensor.product_name_aabbccddeeff_total_gas")
entry = entity_registry.async_get("sensor.product_name_aabbccddeeff_total_gas")
assert entry
assert state
assert entry.unique_id == "aabbccddeeff_total_gas_m3"
assert not entry.disabled
assert state.state == "50"
assert (
state.attributes.get(ATTR_FRIENDLY_NAME)
== "Product Name (aabbccddeeff) Total Gas"
)
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_TOTAL_INCREASING
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == VOLUME_CUBIC_METERS
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_GAS
assert ATTR_ICON not in state.attributes
async def test_sensor_entity_disabled_when_null(
hass, mock_config_entry_data, mock_config_entry
):
"""Test sensor disables data with null by default."""
api = get_mock_device()
api.data.available_datapoints = [
"active_power_l2_w",
"active_power_l3_w",
"total_gas_m3",
]
api.data.active_power_l2_w = None
api.data.active_power_l3_w = None
api.data.total_gas_m3 = None
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_active_power_l2"
)
assert entry is None
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_active_power_l3"
)
assert entry is None
entry = entity_registry.async_get("sensor.product_name_aabbccddeeff_total_gas")
assert entry is None
async def test_sensor_entity_export_disabled_when_unused(
hass, mock_config_entry_data, mock_config_entry
):
"""Test sensor disables export if value is 0."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_export_t1_kwh",
"total_power_export_t2_kwh",
]
api.data.total_power_export_t1_kwh = 0
api.data.total_power_export_t2_kwh = 0
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_total_power_export_t1"
)
assert entry
assert entry.disabled
entry = entity_registry.async_get(
"sensor.product_name_aabbccddeeff_total_power_export_t2"
)
assert entry
assert entry.disabled
async def test_sensors_unreachable(hass, mock_config_entry_data, mock_config_entry):
"""Test sensor handles api unreachable."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_import_t1_kwh",
]
api.data.total_power_import_t1_kwh = 1234.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
api.update = AsyncMock(return_value=True)
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
utcnow = dt_util.utcnow()
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert (
hass.states.get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
).state
== "1234.123"
)
api.update = AsyncMock(return_value=False)
async_fire_time_changed(hass, utcnow + timedelta(seconds=5))
await hass.async_block_till_done()
assert (
hass.states.get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
).state
== "unavailable"
)
api.update = AsyncMock(return_value=True)
async_fire_time_changed(hass, utcnow + timedelta(seconds=10))
await hass.async_block_till_done()
assert (
hass.states.get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
).state
== "1234.123"
)
async def test_api_disabled(hass, mock_config_entry_data, mock_config_entry):
"""Test sensor handles api unreachable."""
api = get_mock_device()
api.data.available_datapoints = [
"total_power_import_t1_kwh",
]
api.data.total_power_import_t1_kwh = 1234.123
with patch(
"aiohwenergy.HomeWizardEnergy",
return_value=api,
):
api.update = AsyncMock(return_value=True)
entry = mock_config_entry
entry.data = mock_config_entry_data
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
utcnow = dt_util.utcnow()
assert (
hass.states.get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
).state
== "1234.123"
)
api.update = AsyncMock(side_effect=DisabledError)
async_fire_time_changed(hass, utcnow + timedelta(seconds=5))
await hass.async_block_till_done()
assert (
hass.states.get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
).state
== "unavailable"
)
api.update = AsyncMock(return_value=True)
async_fire_time_changed(hass, utcnow + timedelta(seconds=10))
await hass.async_block_till_done()
assert (
hass.states.get(
"sensor.product_name_aabbccddeeff_total_power_import_t1"
).state
== "1234.123"
)