Add list as possible values for State On/Off ModBus Switch (#127444)

* add possibility to set multiple val on state

* Add support for list also in state_off
This commit is contained in:
Claudio Ruggeri - CR-Tech 2024-10-18 10:10:47 +02:00 committed by GitHub
parent 5a0ef149a5
commit 49d534e779
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 105 additions and 6 deletions

View file

@ -234,8 +234,10 @@ BASE_SWITCH_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
CALL_TYPE_X_REGISTER_HOLDINGS,
]
),
vol.Optional(CONF_STATE_OFF): cv.positive_int,
vol.Optional(CONF_STATE_ON): cv.positive_int,
vol.Optional(CONF_STATE_OFF): vol.All(
cv.ensure_list, [cv.positive_int]
),
vol.Optional(CONF_STATE_ON): vol.All(cv.ensure_list, [cv.positive_int]),
vol.Optional(CONF_DELAY, default=0): cv.positive_int,
}
),

View file

@ -297,8 +297,10 @@ class BaseSwitch(BasePlatform, ToggleEntity, RestoreEntity):
self._verify_type = convert[
config[CONF_VERIFY].get(CONF_INPUT_TYPE, config[CONF_WRITE_TYPE])
][0]
self._state_on = config[CONF_VERIFY].get(CONF_STATE_ON, self.command_on)
self._state_off = config[CONF_VERIFY].get(CONF_STATE_OFF, self._command_off)
self._state_on = config[CONF_VERIFY].get(CONF_STATE_ON, [self.command_on])
self._state_off = config[CONF_VERIFY].get(
CONF_STATE_OFF, [self._command_off]
)
else:
self._verify_active = False
@ -363,9 +365,9 @@ class BaseSwitch(BasePlatform, ToggleEntity, RestoreEntity):
self._attr_is_on = bool(result.bits[0] & 1)
else:
value = int(result.registers[0])
if value == self._state_on:
if value in self._state_on:
self._attr_is_on = True
elif value == self._state_off:
elif value in self._state_off:
self._attr_is_on = False
elif value is not None:
_LOGGER.error(

View file

@ -44,6 +44,7 @@ from tests.common import async_fire_time_changed
ENTITY_ID = f"{SWITCH_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
ENTITY_ID2 = f"{ENTITY_ID}_2"
ENTITY_ID3 = f"{ENTITY_ID}_3"
@pytest.mark.parametrize(
@ -153,6 +154,42 @@ ENTITY_ID2 = f"{ENTITY_ID}_2"
}
]
},
{
CONF_SWITCHES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1234,
CONF_DEVICE_ADDRESS: 10,
CONF_COMMAND_OFF: 0x00,
CONF_COMMAND_ON: 0x01,
CONF_DEVICE_CLASS: "switch",
CONF_VERIFY: {
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_ADDRESS: 1235,
CONF_STATE_OFF: 0,
CONF_STATE_ON: [1, 2, 3],
},
}
]
},
{
CONF_SWITCHES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1236,
CONF_DEVICE_ADDRESS: 10,
CONF_COMMAND_OFF: 0x00,
CONF_COMMAND_ON: 0x01,
CONF_DEVICE_CLASS: "switch",
CONF_VERIFY: {
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_ADDRESS: 1235,
CONF_STATE_OFF: [0, 5, 6],
CONF_STATE_ON: 1,
},
}
]
},
],
)
async def test_config_switch(hass: HomeAssistant, mock_modbus) -> None:
@ -218,6 +255,18 @@ async def test_config_switch(hass: HomeAssistant, mock_modbus) -> None:
None,
STATE_OFF,
),
(
[0x03],
False,
{CONF_VERIFY: {CONF_STATE_ON: [1, 3]}},
STATE_ON,
),
(
[0x04],
False,
{CONF_VERIFY: {CONF_STATE_OFF: [0, 4]}},
STATE_OFF,
),
],
)
async def test_all_switch(hass: HomeAssistant, mock_do_cycle, expected) -> None:
@ -269,6 +318,13 @@ async def test_restore_state_switch(
CONF_SCAN_INTERVAL: 0,
CONF_VERIFY: {},
},
{
CONF_NAME: f"{TEST_ENTITY_NAME} 3",
CONF_ADDRESS: 18,
CONF_WRITE_TYPE: CALL_TYPE_REGISTER_HOLDING,
CONF_SCAN_INTERVAL: 0,
CONF_VERIFY: {CONF_STATE_ON: [1, 3]},
},
],
},
],
@ -306,6 +362,19 @@ async def test_switch_service_turn(
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID2).state == STATE_OFF
mock_modbus.read_holding_registers.return_value = ReadResult([0x03])
assert hass.states.get(ENTITY_ID3).state == STATE_OFF
await hass.services.async_call(
"switch", "turn_on", service_data={"entity_id": ENTITY_ID3}
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID3).state == STATE_ON
mock_modbus.read_holding_registers.return_value = ReadResult([0x00])
await hass.services.async_call(
"switch", "turn_off", service_data={"entity_id": ENTITY_ID3}
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID3).state == STATE_OFF
mock_modbus.write_register.side_effect = ModbusException("fail write_")
await hass.services.async_call(
@ -319,6 +388,12 @@ async def test_switch_service_turn(
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE
mock_modbus.write_register.side_effect = ModbusException("fail write_")
await hass.services.async_call(
"switch", "turn_on", service_data={"entity_id": ENTITY_ID3}
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID3).state == STATE_UNAVAILABLE
@pytest.mark.parametrize(
@ -334,6 +409,26 @@ async def test_switch_service_turn(
}
]
},
{
CONF_SWITCHES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1236,
CONF_WRITE_TYPE: CALL_TYPE_COIL,
CONF_VERIFY: {CONF_STATE_ON: [1, 3]},
}
]
},
{
CONF_SWITCHES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 1235,
CONF_WRITE_TYPE: CALL_TYPE_COIL,
CONF_VERIFY: {CONF_STATE_OFF: [0, 5]},
}
]
},
],
)
async def test_service_switch_update(hass: HomeAssistant, mock_modbus_ha) -> None: