Enable homeassistant.update_entity service for all modbus platforms (#49918)
* Rename _update() to update() A platform neeed a function update(), even though polling is false, this is due to the service: homeassistant.update_entity, which calls update() * Update test harnesss to script testing. Test homeassistant.update_entity in all platforms. This call calls update() in the platform to get a new reading. * Add reuse parameter. * Move service call from helper to tests. * Change run_service_update --> prepare_service_update. * Remove entity_id parameter.
This commit is contained in:
parent
1bd9826684
commit
8adbc62a6e
11 changed files with 188 additions and 21 deletions
|
@ -129,7 +129,7 @@ class ModbusBinarySensor(BinarySensorEntity):
|
|||
async def async_added_to_hass(self):
|
||||
"""Handle entity which will be added."""
|
||||
async_track_time_interval(
|
||||
self.hass, lambda arg: self._update(), self._scan_interval
|
||||
self.hass, lambda arg: self.update(), self._scan_interval
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -162,7 +162,7 @@ class ModbusBinarySensor(BinarySensorEntity):
|
|||
"""Return True if entity is available."""
|
||||
return self._available
|
||||
|
||||
def _update(self):
|
||||
def update(self):
|
||||
"""Update the state of the sensor."""
|
||||
if self._input_type == CALL_TYPE_COIL:
|
||||
result = self._hub.read_coils(self._slave, self._address, 1)
|
||||
|
|
|
@ -133,7 +133,7 @@ class ModbusThermostat(ClimateEntity):
|
|||
async def async_added_to_hass(self):
|
||||
"""Handle entity which will be added."""
|
||||
async_track_time_interval(
|
||||
self.hass, lambda arg: self._update(), self._scan_interval
|
||||
self.hass, lambda arg: self.update(), self._scan_interval
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -214,14 +214,14 @@ class ModbusThermostat(ClimateEntity):
|
|||
self._target_temperature_register,
|
||||
register_value,
|
||||
)
|
||||
self._update()
|
||||
self.update()
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
return self._available
|
||||
|
||||
def _update(self):
|
||||
def update(self):
|
||||
"""Update Target & Current Temperature."""
|
||||
self._target_temperature = self._read_register(
|
||||
CALL_TYPE_REGISTER_HOLDING, self._target_temperature_register
|
||||
|
|
|
@ -107,7 +107,7 @@ class ModbusCover(CoverEntity, RestoreEntity):
|
|||
self._value = state.state
|
||||
|
||||
async_track_time_interval(
|
||||
self.hass, lambda arg: self._update(), self._scan_interval
|
||||
self.hass, lambda arg: self.update(), self._scan_interval
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -161,7 +161,7 @@ class ModbusCover(CoverEntity, RestoreEntity):
|
|||
else:
|
||||
self._write_register(self._state_open)
|
||||
|
||||
self._update()
|
||||
self.update()
|
||||
|
||||
def close_cover(self, **kwargs: Any) -> None:
|
||||
"""Close cover."""
|
||||
|
@ -170,9 +170,9 @@ class ModbusCover(CoverEntity, RestoreEntity):
|
|||
else:
|
||||
self._write_register(self._state_closed)
|
||||
|
||||
self._update()
|
||||
self.update()
|
||||
|
||||
def _update(self):
|
||||
def update(self):
|
||||
"""Update the state of the cover."""
|
||||
if self._coil is not None and self._status_register is None:
|
||||
self._value = self._read_coil()
|
||||
|
|
|
@ -229,7 +229,7 @@ class ModbusRegisterSensor(RestoreEntity, SensorEntity):
|
|||
self._value = state.state
|
||||
|
||||
async_track_time_interval(
|
||||
self.hass, lambda arg: self._update(), self._scan_interval
|
||||
self.hass, lambda arg: self.update(), self._scan_interval
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -282,7 +282,7 @@ class ModbusRegisterSensor(RestoreEntity, SensorEntity):
|
|||
registers.reverse()
|
||||
return registers
|
||||
|
||||
def _update(self):
|
||||
def update(self):
|
||||
"""Update the state of the sensor."""
|
||||
if self._register_type == CALL_TYPE_REGISTER_INPUT:
|
||||
result = self._hub.read_input_registers(
|
||||
|
|
|
@ -99,7 +99,7 @@ class ModbusSwitch(SwitchEntity, RestoreEntity):
|
|||
|
||||
if self._verify_active:
|
||||
async_track_time_interval(
|
||||
self.hass, lambda arg: self._update(), self._scan_interval
|
||||
self.hass, lambda arg: self.update(), self._scan_interval
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -132,7 +132,7 @@ class ModbusSwitch(SwitchEntity, RestoreEntity):
|
|||
else:
|
||||
self._available = True
|
||||
if self._verify_active:
|
||||
self._update()
|
||||
self.update()
|
||||
else:
|
||||
self._is_on = True
|
||||
self.schedule_update_ha_state()
|
||||
|
@ -146,12 +146,12 @@ class ModbusSwitch(SwitchEntity, RestoreEntity):
|
|||
else:
|
||||
self._available = True
|
||||
if self._verify_active:
|
||||
self._update()
|
||||
self.update()
|
||||
else:
|
||||
self._is_on = False
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def _update(self):
|
||||
def update(self):
|
||||
"""Update the entity state."""
|
||||
if not self._verify_active:
|
||||
return
|
||||
|
|
|
@ -201,3 +201,21 @@ async def base_config_test(
|
|||
config_modbus=config_modbus,
|
||||
expect_init_to_fail=expect_init_to_fail,
|
||||
)
|
||||
|
||||
|
||||
async def prepare_service_update(hass, config):
|
||||
"""Run test for service write_coil."""
|
||||
|
||||
config_modbus = {
|
||||
DOMAIN: {
|
||||
CONF_NAME: DEFAULT_HUB,
|
||||
CONF_TYPE: "tcp",
|
||||
CONF_HOST: "modbusTest",
|
||||
CONF_PORT: 5001,
|
||||
**config,
|
||||
},
|
||||
}
|
||||
assert await async_setup_component(hass, DOMAIN, config_modbus)
|
||||
await hass.async_block_till_done()
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
await hass.async_block_till_done()
|
||||
|
|
|
@ -19,7 +19,7 @@ from homeassistant.const import (
|
|||
STATE_UNAVAILABLE,
|
||||
)
|
||||
|
||||
from .conftest import base_config_test, base_test
|
||||
from .conftest import ReadResult, base_config_test, base_test, prepare_service_update
|
||||
|
||||
|
||||
@pytest.mark.parametrize("do_discovery", [False, True])
|
||||
|
@ -99,3 +99,34 @@ async def test_all_binary_sensor(hass, do_type, regs, expected):
|
|||
scan_interval=5,
|
||||
)
|
||||
assert state == expected
|
||||
|
||||
|
||||
async def test_service_binary_sensor_update(hass, mock_pymodbus):
|
||||
"""Run test for service homeassistant.update_entity."""
|
||||
|
||||
entity_id = "binary_sensor.test"
|
||||
config = {
|
||||
CONF_BINARY_SENSORS: [
|
||||
{
|
||||
CONF_NAME: "test",
|
||||
CONF_ADDRESS: 1234,
|
||||
CONF_INPUT_TYPE: CALL_TYPE_COIL,
|
||||
}
|
||||
]
|
||||
}
|
||||
mock_pymodbus.read_coils.return_value = ReadResult([0x00])
|
||||
await prepare_service_update(
|
||||
hass,
|
||||
config,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
mock_pymodbus.read_coils.return_value = ReadResult([0x01])
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_ON
|
||||
|
|
|
@ -10,7 +10,7 @@ from homeassistant.components.modbus.const import (
|
|||
)
|
||||
from homeassistant.const import CONF_NAME, CONF_SCAN_INTERVAL, CONF_SLAVE
|
||||
|
||||
from .conftest import base_config_test, base_test
|
||||
from .conftest import ReadResult, base_config_test, base_test, prepare_service_update
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -76,3 +76,28 @@ async def test_temperature_climate(hass, regs, expected):
|
|||
scan_interval=5,
|
||||
)
|
||||
assert state == expected
|
||||
|
||||
|
||||
async def test_service_climate_update(hass, mock_pymodbus):
|
||||
"""Run test for service homeassistant.update_entity."""
|
||||
|
||||
entity_id = "climate.test"
|
||||
config = {
|
||||
CONF_CLIMATES: [
|
||||
{
|
||||
CONF_NAME: "test",
|
||||
CONF_TARGET_TEMP: 117,
|
||||
CONF_CURRENT_TEMP: 117,
|
||||
CONF_SLAVE: 10,
|
||||
}
|
||||
]
|
||||
}
|
||||
mock_pymodbus.read_input_registers.return_value = ReadResult([0x00])
|
||||
await prepare_service_update(
|
||||
hass,
|
||||
config,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == "auto"
|
||||
|
|
|
@ -4,7 +4,12 @@ import logging
|
|||
import pytest
|
||||
|
||||
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
|
||||
from homeassistant.components.modbus.const import CALL_TYPE_COIL, CONF_REGISTER
|
||||
from homeassistant.components.modbus.const import (
|
||||
CALL_TYPE_COIL,
|
||||
CALL_TYPE_REGISTER_HOLDING,
|
||||
CONF_REGISTER,
|
||||
CONF_STATUS_REGISTER_TYPE,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_COVERS,
|
||||
CONF_NAME,
|
||||
|
@ -14,7 +19,7 @@ from homeassistant.const import (
|
|||
STATE_OPEN,
|
||||
)
|
||||
|
||||
from .conftest import base_config_test, base_test
|
||||
from .conftest import ReadResult, base_config_test, base_test, prepare_service_update
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -168,3 +173,32 @@ async def test_unsupported_config_cover(hass, read_type, caplog):
|
|||
|
||||
assert len(caplog.records) == 1
|
||||
assert caplog.records[0].levelname == "WARNING"
|
||||
|
||||
|
||||
async def test_service_cover_update(hass, mock_pymodbus):
|
||||
"""Run test for service homeassistant.update_entity."""
|
||||
|
||||
entity_id = "cover.test"
|
||||
config = {
|
||||
CONF_COVERS: [
|
||||
{
|
||||
CONF_NAME: "test",
|
||||
CONF_REGISTER: 1234,
|
||||
CONF_STATUS_REGISTER_TYPE: CALL_TYPE_REGISTER_HOLDING,
|
||||
}
|
||||
]
|
||||
}
|
||||
mock_pymodbus.read_holding_registers.return_value = ReadResult([0x00])
|
||||
await prepare_service_update(
|
||||
hass,
|
||||
config,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_CLOSED
|
||||
mock_pymodbus.read_holding_registers.return_value = ReadResult([0x01])
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_OPEN
|
||||
|
|
|
@ -40,7 +40,7 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.core import State
|
||||
|
||||
from .conftest import base_config_test, base_test
|
||||
from .conftest import ReadResult, base_config_test, base_test, prepare_service_update
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -621,3 +621,32 @@ async def test_swap_sensor_wrong_config(hass, caplog, swap_type):
|
|||
expect_init_to_fail=True,
|
||||
)
|
||||
assert caplog.messages[-1].startswith("Error in sensor " + sensor_name + " swap")
|
||||
|
||||
|
||||
async def test_service_sensor_update(hass, mock_pymodbus):
|
||||
"""Run test for service homeassistant.update_entity."""
|
||||
|
||||
entity_id = "sensor.test"
|
||||
config = {
|
||||
CONF_SENSORS: [
|
||||
{
|
||||
CONF_NAME: "test",
|
||||
CONF_ADDRESS: 1234,
|
||||
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_INPUT,
|
||||
}
|
||||
]
|
||||
}
|
||||
mock_pymodbus.read_input_registers.return_value = ReadResult([27])
|
||||
await prepare_service_update(
|
||||
hass,
|
||||
config,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == "27"
|
||||
mock_pymodbus.read_input_registers.return_value = ReadResult([32])
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == "32"
|
||||
|
|
|
@ -25,7 +25,7 @@ from homeassistant.const import (
|
|||
STATE_ON,
|
||||
)
|
||||
|
||||
from .conftest import base_config_test, base_test
|
||||
from .conftest import ReadResult, base_config_test, base_test, prepare_service_update
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -220,3 +220,33 @@ async def test_register_state_switch(hass, regs, expected):
|
|||
scan_interval=5,
|
||||
)
|
||||
assert state == expected
|
||||
|
||||
|
||||
async def test_service_switch_update(hass, mock_pymodbus):
|
||||
"""Run test for service homeassistant.update_entity."""
|
||||
|
||||
entity_id = "switch.test"
|
||||
config = {
|
||||
CONF_SWITCHES: [
|
||||
{
|
||||
CONF_NAME: "test",
|
||||
CONF_ADDRESS: 1234,
|
||||
CONF_WRITE_TYPE: CALL_TYPE_COIL,
|
||||
CONF_VERIFY: {},
|
||||
}
|
||||
]
|
||||
}
|
||||
mock_pymodbus.read_coils.return_value = ReadResult([0x01])
|
||||
await prepare_service_update(
|
||||
hass,
|
||||
config,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_ON
|
||||
mock_pymodbus.read_coils.return_value = ReadResult([0x00])
|
||||
await hass.services.async_call(
|
||||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue