mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Allow manual scan and add delay in switch verify. (#50974)
This commit is contained in:
parent
2583e4bdc9
commit
be13a73db8
@ -140,6 +140,8 @@ def control_scan_interval(config: dict) -> dict:
|
||||
for entry in hub[conf_key]:
|
||||
scan_interval = entry.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
|
||||
if scan_interval < MINIMUM_SCAN_INTERVAL:
|
||||
if scan_interval == 0:
|
||||
continue
|
||||
_LOGGER.warning(
|
||||
"%s %s scan_interval(%d) is adjusted to minimum(%d)",
|
||||
component,
|
||||
@ -236,6 +238,7 @@ SWITCH_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
|
||||
),
|
||||
vol.Optional(CONF_STATE_OFF): cv.positive_int,
|
||||
vol.Optional(CONF_STATE_ON): cv.positive_int,
|
||||
vol.Optional(CONF_DELAY, default=0): cv.positive_int,
|
||||
}
|
||||
),
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class BasePlatform(Entity):
|
||||
self._input_type = entry[CONF_INPUT_TYPE]
|
||||
self._value = None
|
||||
self._available = True
|
||||
self._scan_interval = timedelta(seconds=entry[CONF_SCAN_INTERVAL])
|
||||
self._scan_interval = int(entry[CONF_SCAN_INTERVAL])
|
||||
|
||||
@abstractmethod
|
||||
async def async_update(self, now=None):
|
||||
@ -44,7 +44,10 @@ class BasePlatform(Entity):
|
||||
|
||||
async def async_base_added_to_hass(self):
|
||||
"""Handle entity which will be added."""
|
||||
async_track_time_interval(self.hass, self.async_update, self._scan_interval)
|
||||
if self._scan_interval > 0:
|
||||
async_track_time_interval(
|
||||
self.hass, self.async_update, timedelta(seconds=self._scan_interval)
|
||||
)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -8,11 +8,13 @@ from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_COMMAND_OFF,
|
||||
CONF_COMMAND_ON,
|
||||
CONF_DELAY,
|
||||
CONF_NAME,
|
||||
CONF_SWITCHES,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
@ -64,6 +66,7 @@ class ModbusSwitch(BasePlatform, SwitchEntity, RestoreEntity):
|
||||
if config[CONF_VERIFY] is None:
|
||||
config[CONF_VERIFY] = {}
|
||||
self._verify_active = True
|
||||
self._verify_delay = config[CONF_VERIFY].get(CONF_DELAY, 0)
|
||||
self._verify_address = config[CONF_VERIFY].get(
|
||||
CONF_ADDRESS, config[CONF_ADDRESS]
|
||||
)
|
||||
@ -87,38 +90,34 @@ class ModbusSwitch(BasePlatform, SwitchEntity, RestoreEntity):
|
||||
"""Return true if switch is on."""
|
||||
return self._is_on
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Set switch on."""
|
||||
|
||||
async def _async_turn(self, command):
|
||||
"""Evaluate switch result."""
|
||||
result = await self._hub.async_pymodbus_call(
|
||||
self._slave, self._address, self._command_on, self._write_type
|
||||
self._slave, self._address, command, self._write_type
|
||||
)
|
||||
if result is None:
|
||||
self._available = False
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
self._available = True
|
||||
if not self._verify_active:
|
||||
self._is_on = command == self._command_on
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
if self._verify_delay:
|
||||
async_call_later(self.hass, self._verify_delay, self.async_update)
|
||||
else:
|
||||
self._available = True
|
||||
if self._verify_active:
|
||||
await self.async_update()
|
||||
else:
|
||||
self._is_on = True
|
||||
self.async_write_ha_state()
|
||||
await self.async_update()
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Set switch on."""
|
||||
await self._async_turn(self._command_on)
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Set switch off."""
|
||||
result = await self._hub.async_pymodbus_call(
|
||||
self._slave, self._address, self._command_off, self._write_type
|
||||
)
|
||||
if result is None:
|
||||
self._available = False
|
||||
self.async_write_ha_state()
|
||||
else:
|
||||
self._available = True
|
||||
if self._verify_active:
|
||||
await self.async_update()
|
||||
else:
|
||||
self._is_on = False
|
||||
self.async_write_ha_state()
|
||||
await self._async_turn(self._command_off)
|
||||
|
||||
async def async_update(self, now=None):
|
||||
"""Update the entity state."""
|
||||
|
@ -1,4 +1,7 @@
|
||||
"""The tests for the Modbus switch component."""
|
||||
from datetime import timedelta
|
||||
from unittest import mock
|
||||
|
||||
from pymodbus.exceptions import ModbusException
|
||||
import pytest
|
||||
|
||||
@ -19,10 +22,12 @@ from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_COMMAND_OFF,
|
||||
CONF_COMMAND_ON,
|
||||
CONF_DELAY,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_HOST,
|
||||
CONF_NAME,
|
||||
CONF_PORT,
|
||||
CONF_SCAN_INTERVAL,
|
||||
CONF_SLAVE,
|
||||
CONF_SWITCHES,
|
||||
CONF_TYPE,
|
||||
@ -32,10 +37,11 @@ from homeassistant.const import (
|
||||
)
|
||||
from homeassistant.core import State
|
||||
from homeassistant.setup import async_setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .conftest import ReadResult, base_config_test, base_test, prepare_service_update
|
||||
|
||||
from tests.common import mock_restore_cache
|
||||
from tests.common import async_fire_time_changed, mock_restore_cache
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -72,6 +78,7 @@ from tests.common import mock_restore_cache
|
||||
CONF_ADDRESS: 1235,
|
||||
CONF_STATE_OFF: 0,
|
||||
CONF_STATE_ON: 1,
|
||||
CONF_DELAY: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -93,6 +100,7 @@ from tests.common import mock_restore_cache
|
||||
CONF_COMMAND_OFF: 0x00,
|
||||
CONF_COMMAND_ON: 0x01,
|
||||
CONF_DEVICE_CLASS: "switch",
|
||||
CONF_SCAN_INTERVAL: 0,
|
||||
CONF_VERIFY: None,
|
||||
},
|
||||
],
|
||||
@ -292,3 +300,46 @@ async def test_service_switch_update(hass, mock_pymodbus):
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
|
||||
async def test_delay_switch(hass, mock_pymodbus):
|
||||
"""Run test for switch verify delay."""
|
||||
|
||||
switch_name = "test_switch"
|
||||
entity_id = f"{SWITCH_DOMAIN}.{switch_name}"
|
||||
|
||||
config = {
|
||||
MODBUS_DOMAIN: [
|
||||
{
|
||||
CONF_TYPE: "tcp",
|
||||
CONF_HOST: "modbusTestHost",
|
||||
CONF_PORT: 5501,
|
||||
CONF_SWITCHES: [
|
||||
{
|
||||
CONF_NAME: switch_name,
|
||||
CONF_ADDRESS: 51,
|
||||
CONF_SCAN_INTERVAL: 0,
|
||||
CONF_VERIFY: {
|
||||
CONF_DELAY: 1,
|
||||
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
mock_pymodbus.read_holding_registers.return_value = ReadResult([0x01])
|
||||
now = dt_util.utcnow()
|
||||
with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now):
|
||||
assert await async_setup_component(hass, MODBUS_DOMAIN, config) is True
|
||||
await hass.async_block_till_done()
|
||||
await hass.services.async_call(
|
||||
"switch", "turn_on", service_data={"entity_id": entity_id}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
now = now + timedelta(seconds=2)
|
||||
with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now):
|
||||
async_fire_time_changed(hass, now)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(entity_id).state == STATE_ON
|
Loading…
x
Reference in New Issue
Block a user