Deprecate and remove lazy_error from modbus (#105037)

pull/105080/head
jan iversen 2023-12-05 13:08:33 +01:00 committed by GitHub
parent 5b59e043fa
commit 0638088aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 66 additions and 273 deletions

View File

@ -24,10 +24,11 @@ from homeassistant.const import (
STATE_OFF,
STATE_ON,
)
from homeassistant.core import callback
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import Entity, ToggleEntity
from homeassistant.helpers.event import async_call_later, async_track_time_interval
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.restore_state import RestoreEntity
from .const import (
@ -61,6 +62,7 @@ from .const import (
CONF_VIRTUAL_COUNT,
CONF_WRITE_TYPE,
CONF_ZERO_SUPPRESS,
MODBUS_DOMAIN,
SIGNAL_START_ENTITY,
SIGNAL_STOP_ENTITY,
DataType,
@ -74,8 +76,34 @@ _LOGGER = logging.getLogger(__name__)
class BasePlatform(Entity):
"""Base for readonly platforms."""
def __init__(self, hub: ModbusHub, entry: dict[str, Any]) -> None:
def __init__(
self, hass: HomeAssistant, hub: ModbusHub, entry: dict[str, Any]
) -> None:
"""Initialize the Modbus binary sensor."""
if CONF_LAZY_ERROR in entry:
async_create_issue(
hass,
MODBUS_DOMAIN,
"removed_lazy_error_count",
breaks_in_ha_version="2024.7.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="removed_lazy_error_count",
translation_placeholders={
"config_key": "lazy_error_count",
"integration": MODBUS_DOMAIN,
"url": "https://www.home-assistant.io/integrations/modbus",
},
)
_LOGGER.warning(
"`close_comm_on_error`: is deprecated and will be removed in version 2024.4"
)
_LOGGER.warning(
"`lazy_error_count`: is deprecated and will be removed in version 2024.7"
)
self._hub = hub
self._slave = entry.get(CONF_SLAVE, None) or entry.get(CONF_DEVICE_ADDRESS, 0)
self._address = int(entry[CONF_ADDRESS])
@ -92,8 +120,6 @@ class BasePlatform(Entity):
self._attr_device_class = entry.get(CONF_DEVICE_CLASS)
self._attr_available = True
self._attr_unit_of_measurement = None
self._lazy_error_count = entry[CONF_LAZY_ERROR]
self._lazy_errors = self._lazy_error_count
def get_optional_numeric_config(config_name: str) -> int | float | None:
if (val := entry.get(config_name)) is None:
@ -153,9 +179,9 @@ class BasePlatform(Entity):
class BaseStructPlatform(BasePlatform, RestoreEntity):
"""Base class representing a sensor/climate."""
def __init__(self, hub: ModbusHub, config: dict) -> None:
def __init__(self, hass: HomeAssistant, hub: ModbusHub, config: dict) -> None:
"""Initialize the switch."""
super().__init__(hub, config)
super().__init__(hass, hub, config)
self._swap = config[CONF_SWAP]
self._data_type = config[CONF_DATA_TYPE]
self._structure: str = config[CONF_STRUCTURE]
@ -247,10 +273,10 @@ class BaseStructPlatform(BasePlatform, RestoreEntity):
class BaseSwitch(BasePlatform, ToggleEntity, RestoreEntity):
"""Base class representing a Modbus switch."""
def __init__(self, hub: ModbusHub, config: dict) -> None:
def __init__(self, hass: HomeAssistant, hub: ModbusHub, config: dict) -> None:
"""Initialize the switch."""
config[CONF_INPUT_TYPE] = ""
super().__init__(hub, config)
super().__init__(hass, hub, config)
self._attr_is_on = False
convert = {
CALL_TYPE_REGISTER_HOLDING: (
@ -343,15 +369,10 @@ class BaseSwitch(BasePlatform, ToggleEntity, RestoreEntity):
)
self._call_active = False
if result is None:
if self._lazy_errors:
self._lazy_errors -= 1
return
self._lazy_errors = self._lazy_error_count
self._attr_available = False
self.async_write_ha_state()
return
self._lazy_errors = self._lazy_error_count
self._attr_available = True
if self._verify_type in (CALL_TYPE_COIL, CALL_TYPE_DISCRETE):
self._attr_is_on = bool(result.bits[0] & 1)

View File

@ -54,7 +54,7 @@ async def async_setup_platform(
slave_count = entry.get(CONF_SLAVE_COUNT, None) or entry.get(
CONF_VIRTUAL_COUNT, 0
)
sensor = ModbusBinarySensor(hub, entry, slave_count)
sensor = ModbusBinarySensor(hass, hub, entry, slave_count)
if slave_count > 0:
sensors.extend(await sensor.async_setup_slaves(hass, slave_count, entry))
sensors.append(sensor)
@ -64,12 +64,18 @@ async def async_setup_platform(
class ModbusBinarySensor(BasePlatform, RestoreEntity, BinarySensorEntity):
"""Modbus binary sensor."""
def __init__(self, hub: ModbusHub, entry: dict[str, Any], slave_count: int) -> None:
def __init__(
self,
hass: HomeAssistant,
hub: ModbusHub,
entry: dict[str, Any],
slave_count: int,
) -> None:
"""Initialize the Modbus binary sensor."""
self._count = slave_count + 1
self._coordinator: DataUpdateCoordinator[list[int] | None] | None = None
self._result: list[int] = []
super().__init__(hub, entry)
super().__init__(hass, hub, entry)
async def async_setup_slaves(
self, hass: HomeAssistant, slave_count: int, entry: dict[str, Any]
@ -109,14 +115,9 @@ class ModbusBinarySensor(BasePlatform, RestoreEntity, BinarySensorEntity):
)
self._call_active = False
if result is None:
if self._lazy_errors:
self._lazy_errors -= 1
return
self._lazy_errors = self._lazy_error_count
self._attr_available = False
self._result = []
else:
self._lazy_errors = self._lazy_error_count
self._attr_available = True
if self._input_type in (CALL_TYPE_COIL, CALL_TYPE_DISCRETE):
self._result = result.bits

View File

@ -67,7 +67,7 @@ async def async_setup_platform(
entities = []
for entity in discovery_info[CONF_CLIMATES]:
hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
entities.append(ModbusThermostat(hub, entity))
entities.append(ModbusThermostat(hass, hub, entity))
async_add_entities(entities)
@ -79,11 +79,12 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
def __init__(
self,
hass: HomeAssistant,
hub: ModbusHub,
config: dict[str, Any],
) -> None:
"""Initialize the modbus thermostat."""
super().__init__(hub, config)
super().__init__(hass, hub, config)
self._target_temperature_register = config[CONF_TARGET_TEMP]
self._target_temperature_write_registers = config[
CONF_TARGET_TEMP_WRITE_REGISTERS
@ -288,15 +289,9 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
self._slave, register, self._count, register_type
)
if result is None:
if self._lazy_errors:
self._lazy_errors -= 1
return -1
self._lazy_errors = self._lazy_error_count
self._attr_available = False
return -1
self._lazy_errors = self._lazy_error_count
if raw:
# Return the raw value read from the register, do not change
# the object's state

View File

@ -51,7 +51,7 @@ async def async_setup_platform(
covers = []
for cover in discovery_info[CONF_COVERS]:
hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
covers.append(ModbusCover(hub, cover))
covers.append(ModbusCover(hass, hub, cover))
async_add_entities(covers)
@ -63,11 +63,12 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
def __init__(
self,
hass: HomeAssistant,
hub: ModbusHub,
config: dict[str, Any],
) -> None:
"""Initialize the modbus cover."""
super().__init__(hub, config)
super().__init__(hass, hub, config)
self._state_closed = config[CONF_STATE_CLOSED]
self._state_closing = config[CONF_STATE_CLOSING]
self._state_open = config[CONF_STATE_OPEN]
@ -142,14 +143,9 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity):
self._slave, self._address, 1, self._input_type
)
if result is None:
if self._lazy_errors:
self._lazy_errors -= 1
return
self._lazy_errors = self._lazy_error_count
self._attr_available = False
self.async_write_ha_state()
return
self._lazy_errors = self._lazy_error_count
self._attr_available = True
if self._input_type == CALL_TYPE_COIL:
self._set_attr_state(bool(result.bits[0] & 1))

View File

@ -30,7 +30,7 @@ async def async_setup_platform(
for entry in discovery_info[CONF_FANS]:
hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
fans.append(ModbusFan(hub, entry))
fans.append(ModbusFan(hass, hub, entry))
async_add_entities(fans)

View File

@ -29,7 +29,7 @@ async def async_setup_platform(
lights = []
for entry in discovery_info[CONF_LIGHTS]:
hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
lights.append(ModbusLight(hub, entry))
lights.append(ModbusLight(hass, hub, entry))
async_add_entities(lights)

View File

@ -1,7 +1,7 @@
"""Support for Modbus Register sensors."""
from __future__ import annotations
from datetime import datetime, timedelta
from datetime import datetime
import logging
from typing import Any
@ -19,7 +19,6 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
@ -53,7 +52,7 @@ async def async_setup_platform(
slave_count = entry.get(CONF_SLAVE_COUNT, None) or entry.get(
CONF_VIRTUAL_COUNT, 0
)
sensor = ModbusRegisterSensor(hub, entry, slave_count)
sensor = ModbusRegisterSensor(hass, hub, entry, slave_count)
if slave_count > 0:
sensors.extend(await sensor.async_setup_slaves(hass, slave_count, entry))
sensors.append(sensor)
@ -65,12 +64,13 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreSensor, SensorEntity):
def __init__(
self,
hass: HomeAssistant,
hub: ModbusHub,
entry: dict[str, Any],
slave_count: int,
) -> None:
"""Initialize the modbus register sensor."""
super().__init__(hub, entry)
super().__init__(hass, hub, entry)
if slave_count:
self._count = self._count * (slave_count + 1)
self._coordinator: DataUpdateCoordinator[list[int] | None] | None = None
@ -114,13 +114,6 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreSensor, SensorEntity):
self._slave, self._address, self._count, self._input_type
)
if raw_result is None:
if self._lazy_errors:
self._lazy_errors -= 1
self._cancel_call = async_call_later(
self.hass, timedelta(seconds=1), self.async_update
)
return
self._lazy_errors = self._lazy_error_count
self._attr_available = False
self._attr_native_value = None
if self._coordinator:
@ -142,7 +135,6 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreSensor, SensorEntity):
else:
self._attr_native_value = result
self._attr_available = self._attr_native_value is not None
self._lazy_errors = self._lazy_error_count
self.async_write_ha_state()

View File

@ -70,9 +70,13 @@
}
},
"issues": {
"removed_lazy_error_count": {
"title": "`{config_key}` configuration key is being removed",
"description": "Please remove the `{config_key}` key from the {integration} entry in your configuration.yaml file and restart Home Assistant to fix this issue. All errors will be reported, as lazy_error_count is accepted but ignored"
},
"deprecated_close_comm_config": {
"title": "`{config_key}` configuration key is being removed",
"description": "Please remove the `{config_key}` key from the {integration} entry in your configuration.yaml file and restart Home Assistant to fix this issue.\n\nCommunication is automatically closed on errors, see [the documentation]({url}) for other error handling parameters."
"description": "Please remove the `{config_key}` key from the {integration} entry in your `configuration.yaml` file and restart Home Assistant to fix this issue. All errors will be reported, as `lazy_error_count` is accepted but ignored."
},
"deprecated_retry_on_empty": {
"title": "`{config_key}` configuration key is being removed",

View File

@ -30,7 +30,7 @@ async def async_setup_platform(
for entry in discovery_info[CONF_SWITCHES]:
hub: ModbusHub = get_hub(hass, discovery_info[CONF_NAME])
switches.append(ModbusSwitch(hub, entry))
switches.append(ModbusSwitch(hass, hub, entry))
async_add_entities(switches)

View File

@ -1,5 +1,4 @@
"""Thetests for the Modbus sensor component."""
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.binary_sensor import DOMAIN as SENSOR_DOMAIN
@ -10,7 +9,6 @@ from homeassistant.components.modbus.const import (
CALL_TYPE_REGISTER_INPUT,
CONF_DEVICE_ADDRESS,
CONF_INPUT_TYPE,
CONF_LAZY_ERROR,
CONF_SLAVE_COUNT,
CONF_VIRTUAL_COUNT,
MODBUS_DOMAIN,
@ -26,13 +24,12 @@ from homeassistant.const import (
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
from .conftest import TEST_ENTITY_NAME, ReadResult
ENTITY_ID = f"{SENSOR_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
SLAVE_UNIQUE_ID = "ground_floor_sensor"
@ -57,7 +54,6 @@ SLAVE_UNIQUE_ID = "ground_floor_sensor"
CONF_SLAVE: 10,
CONF_INPUT_TYPE: CALL_TYPE_DISCRETE,
CONF_DEVICE_CLASS: "door",
CONF_LAZY_ERROR: 10,
}
]
},
@ -69,7 +65,6 @@ SLAVE_UNIQUE_ID = "ground_floor_sensor"
CONF_DEVICE_ADDRESS: 10,
CONF_INPUT_TYPE: CALL_TYPE_DISCRETE,
CONF_DEVICE_CLASS: "door",
CONF_LAZY_ERROR: 10,
}
]
},
@ -196,44 +191,6 @@ async def test_all_binary_sensor(hass: HomeAssistant, expected, mock_do_cycle) -
assert hass.states.get(ENTITY_ID).state == expected
@pytest.mark.parametrize(
"do_config",
[
{
CONF_BINARY_SENSORS: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 51,
CONF_INPUT_TYPE: CALL_TYPE_COIL,
CONF_SCAN_INTERVAL: 10,
CONF_LAZY_ERROR: 2,
},
],
},
],
)
@pytest.mark.parametrize(
("register_words", "do_exception", "start_expect", "end_expect"),
[
(
[False * 16],
True,
STATE_UNKNOWN,
STATE_UNAVAILABLE,
),
],
)
async def test_lazy_error_binary_sensor(
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for given config."""
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect
@pytest.mark.parametrize(
"do_config",
[

View File

@ -1,5 +1,4 @@
"""The tests for the Modbus climate component."""
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
@ -22,7 +21,6 @@ from homeassistant.components.modbus.const import (
CONF_HVAC_MODE_REGISTER,
CONF_HVAC_MODE_VALUES,
CONF_HVAC_ONOFF_REGISTER,
CONF_LAZY_ERROR,
CONF_TARGET_TEMP,
CONF_TARGET_TEMP_WRITE_REGISTERS,
CONF_WRITE_REGISTERS,
@ -40,7 +38,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant, State
from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
from .conftest import TEST_ENTITY_NAME, ReadResult
ENTITY_ID = f"{CLIMATE_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
@ -77,7 +75,6 @@ ENTITY_ID = f"{CLIMATE_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 20,
CONF_DATA_TYPE: DataType.INT32,
CONF_LAZY_ERROR: 10,
}
],
},
@ -581,46 +578,6 @@ async def test_restore_state_climate(
assert state.attributes[ATTR_TEMPERATURE] == 37
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_LAZY_ERROR: 1,
}
],
},
],
)
@pytest.mark.parametrize(
("register_words", "do_exception", "start_expect", "end_expect"),
[
(
[0x8000],
True,
"17",
STATE_UNAVAILABLE,
),
],
)
async def test_lazy_error_climate(
hass: HomeAssistant, mock_do_cycle: FrozenDateTimeFactory, start_expect, end_expect
) -> None:
"""Run test for sensor."""
hass.states.async_set(ENTITY_ID, 17)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect
@pytest.mark.parametrize(
"do_config",
[

View File

@ -1,5 +1,4 @@
"""The tests for the Modbus cover component."""
from freezegun.api import FrozenDateTimeFactory
from pymodbus.exceptions import ModbusException
import pytest
@ -9,7 +8,6 @@ from homeassistant.components.modbus.const import (
CALL_TYPE_REGISTER_HOLDING,
CONF_DEVICE_ADDRESS,
CONF_INPUT_TYPE,
CONF_LAZY_ERROR,
CONF_STATE_CLOSED,
CONF_STATE_CLOSING,
CONF_STATE_OPEN,
@ -33,7 +31,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant, State
from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
from .conftest import TEST_ENTITY_NAME, ReadResult
ENTITY_ID = f"{COVER_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
ENTITY_ID2 = f"{ENTITY_ID}_2"
@ -59,7 +57,6 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 20,
CONF_LAZY_ERROR: 10,
}
]
},
@ -71,7 +68,6 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_DEVICE_ADDRESS: 10,
CONF_SCAN_INTERVAL: 20,
CONF_LAZY_ERROR: 10,
}
]
},
@ -127,45 +123,6 @@ async def test_coil_cover(hass: HomeAssistant, expected, mock_do_cycle) -> None:
assert hass.states.get(ENTITY_ID).state == expected
@pytest.mark.parametrize(
"do_config",
[
{
CONF_COVERS: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_INPUT_TYPE: CALL_TYPE_COIL,
CONF_ADDRESS: 1234,
CONF_SLAVE: 1,
CONF_SCAN_INTERVAL: 10,
CONF_LAZY_ERROR: 2,
},
],
},
],
)
@pytest.mark.parametrize(
("register_words", "do_exception", "start_expect", "end_expect"),
[
(
[0x00],
True,
STATE_OPEN,
STATE_UNAVAILABLE,
),
],
)
async def test_lazy_error_cover(
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for given config."""
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect
@pytest.mark.parametrize(
"do_config",
[

View File

@ -11,7 +11,6 @@ from homeassistant.components.modbus.const import (
CONF_DEVICE_ADDRESS,
CONF_FANS,
CONF_INPUT_TYPE,
CONF_LAZY_ERROR,
CONF_STATE_OFF,
CONF_STATE_ON,
CONF_VERIFY,
@ -66,7 +65,6 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
CONF_SLAVE: 1,
CONF_COMMAND_OFF: 0x00,
CONF_COMMAND_ON: 0x01,
CONF_LAZY_ERROR: 10,
CONF_VERIFY: {
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_ADDRESS: 1235,
@ -84,7 +82,6 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
CONF_DEVICE_ADDRESS: 1,
CONF_COMMAND_OFF: 0x00,
CONF_COMMAND_ON: 0x01,
CONF_LAZY_ERROR: 10,
CONF_VERIFY: {
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_ADDRESS: 1235,

View File

@ -10,7 +10,6 @@ from homeassistant.components.modbus.const import (
CALL_TYPE_REGISTER_INPUT,
CONF_DEVICE_ADDRESS,
CONF_INPUT_TYPE,
CONF_LAZY_ERROR,
CONF_STATE_OFF,
CONF_STATE_ON,
CONF_VERIFY,
@ -55,7 +54,6 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1234,
CONF_WRITE_TYPE: CALL_TYPE_COIL,
CONF_LAZY_ERROR: 10,
}
]
},

View File

@ -1,7 +1,6 @@
"""The tests for the Modbus sensor component."""
import struct
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.modbus.const import (
@ -10,7 +9,6 @@ from homeassistant.components.modbus.const import (
CONF_DATA_TYPE,
CONF_DEVICE_ADDRESS,
CONF_INPUT_TYPE,
CONF_LAZY_ERROR,
CONF_MAX_VALUE,
CONF_MIN_VALUE,
CONF_NAN_VALUE,
@ -49,7 +47,7 @@ from homeassistant.core import HomeAssistant, State
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
from .conftest import TEST_ENTITY_NAME, ReadResult
from tests.common import mock_restore_cache_with_extra_data
@ -80,7 +78,6 @@ SLAVE_UNIQUE_ID = "ground_floor_sensor"
CONF_SCALE: 1,
CONF_OFFSET: 0,
CONF_STATE_CLASS: SensorStateClass.MEASUREMENT,
CONF_LAZY_ERROR: 10,
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_DEVICE_CLASS: "battery",
}
@ -97,7 +94,6 @@ SLAVE_UNIQUE_ID = "ground_floor_sensor"
CONF_SCALE: 1,
CONF_OFFSET: 0,
CONF_STATE_CLASS: SensorStateClass.MEASUREMENT,
CONF_LAZY_ERROR: 10,
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_DEVICE_CLASS: "battery",
}
@ -1142,41 +1138,6 @@ async def test_unpack_ok(hass: HomeAssistant, mock_do_cycle, expected) -> None:
assert hass.states.get(ENTITY_ID).state == expected
@pytest.mark.parametrize(
"do_config",
[
{
CONF_SENSORS: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 51,
CONF_SCAN_INTERVAL: 10,
CONF_LAZY_ERROR: 1,
},
],
},
],
)
@pytest.mark.parametrize(
("register_words", "do_exception"),
[
(
[0x8000],
True,
),
],
)
async def test_lazy_error_sensor(
hass: HomeAssistant, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for sensor."""
hass.states.async_set(ENTITY_ID, 17)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).state == "17"
await do_next_cycle(hass, mock_do_cycle, 5)
assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE
@pytest.mark.parametrize(
"do_config",
[

View File

@ -2,7 +2,6 @@
from datetime import timedelta
from unittest import mock
from freezegun.api import FrozenDateTimeFactory
from pymodbus.exceptions import ModbusException
import pytest
@ -13,7 +12,6 @@ from homeassistant.components.modbus.const import (
CALL_TYPE_REGISTER_INPUT,
CONF_DEVICE_ADDRESS,
CONF_INPUT_TYPE,
CONF_LAZY_ERROR,
CONF_STATE_OFF,
CONF_STATE_ON,
CONF_VERIFY,
@ -39,7 +37,7 @@ from homeassistant.core import HomeAssistant, State
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
from .conftest import TEST_ENTITY_NAME, ReadResult
from tests.common import async_fire_time_changed
@ -64,7 +62,6 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1234,
CONF_WRITE_TYPE: CALL_TYPE_COIL,
CONF_LAZY_ERROR: 10,
}
]
},
@ -227,46 +224,6 @@ async def test_all_switch(hass: HomeAssistant, mock_do_cycle, expected) -> None:
assert hass.states.get(ENTITY_ID).state == expected
@pytest.mark.parametrize(
"do_config",
[
{
CONF_SWITCHES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1234,
CONF_SLAVE: 1,
CONF_WRITE_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_SCAN_INTERVAL: 10,
CONF_LAZY_ERROR: 2,
CONF_VERIFY: {},
},
],
},
],
)
@pytest.mark.parametrize(
("register_words", "do_exception", "start_expect", "end_expect"),
[
(
[0x00],
True,
STATE_OFF,
STATE_UNAVAILABLE,
),
],
)
async def test_lazy_error_switch(
hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory
) -> None:
"""Run test for given config."""
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == start_expect
await do_next_cycle(hass, mock_do_cycle, 11)
assert hass.states.get(ENTITY_ID).state == end_expect
@pytest.mark.parametrize(
"mock_test_state",
[(State(ENTITY_ID, STATE_ON),), (State(ENTITY_ID, STATE_OFF),)],