Solve modbus binary slave problem (#82338)

* Solve modbus binary slave problem.
This commit is contained in:
jan iversen 2022-11-26 11:11:50 +01:00 committed by GitHub
parent e1a0f8314e
commit 8ed4ce64c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 113 deletions

View file

@ -60,7 +60,7 @@ class ModbusBinarySensor(BasePlatform, RestoreEntity, BinarySensorEntity):
"""Initialize the Modbus binary sensor."""
self._count = slave_count + 1
self._coordinator: DataUpdateCoordinator[Any] | None = None
self._result = None
self._result: list = []
super().__init__(hub, entry)
async def async_setup_slaves(
@ -106,15 +106,15 @@ class ModbusBinarySensor(BasePlatform, RestoreEntity, BinarySensorEntity):
return
self._lazy_errors = self._lazy_error_count
self._attr_available = False
self._result = None
self._result = []
else:
self._lazy_errors = self._lazy_error_count
self._attr_available = True
self._result = result
if self._input_type in (CALL_TYPE_COIL, CALL_TYPE_DISCRETE):
self._attr_is_on = bool(result.bits[0] & 1)
self._result = result.bits
else:
self._attr_is_on = bool(result.registers[0] & 1)
self._result = result.registers
self._attr_is_on = bool(self._result[0] & 1)
self.async_write_ha_state()
if self._coordinator:
@ -132,8 +132,7 @@ class SlaveSensor(CoordinatorEntity, RestoreEntity, BinarySensorEntity):
self._attr_name = f"{entry[CONF_NAME]} {idx}"
self._attr_device_class = entry.get(CONF_DEVICE_CLASS)
self._attr_available = False
self._result_inx = int(idx / 8)
self._result_bit = 2 ** (idx % 8)
self._result_inx = idx
super().__init__(coordinator)
async def async_added_to_hass(self) -> None:
@ -148,5 +147,5 @@ class SlaveSensor(CoordinatorEntity, RestoreEntity, BinarySensorEntity):
"""Handle updated data from the coordinator."""
result = self.coordinator.data
if result:
self._attr_is_on = result.bits[self._result_inx] & self._result_bit
self._attr_is_on = bool(result[self._result_inx] & 1)
super()._handle_coordinator_update()

View file

@ -117,35 +117,50 @@ async def test_config_binary_sensor(hass, mock_modbus):
"register_words,do_exception,expected",
[
(
[0xFF],
[True] * 8,
False,
STATE_ON,
),
(
[0x01],
[False] * 8,
False,
STATE_OFF,
),
(
[False] + [True] * 7,
False,
STATE_OFF,
),
(
[True] + [False] * 7,
False,
STATE_ON,
),
(
[0x00],
False,
STATE_OFF,
),
(
[0x80],
False,
STATE_OFF,
),
(
[0xFE],
False,
STATE_OFF,
),
(
[0x00],
[False] * 8,
True,
STATE_UNAVAILABLE,
),
(
[1] * 8,
False,
STATE_ON,
),
(
[2] * 8,
False,
STATE_OFF,
),
(
[4] + [1] * 7,
False,
STATE_OFF,
),
(
[1] + [8] * 7,
False,
STATE_ON,
),
],
)
async def test_all_binary_sensor(hass, expected, mock_do_cycle):
@ -173,7 +188,7 @@ async def test_all_binary_sensor(hass, expected, mock_do_cycle):
"register_words,do_exception,start_expect,end_expect",
[
(
[0x00],
[False * 16],
True,
STATE_UNKNOWN,
STATE_UNAVAILABLE,
@ -289,6 +304,34 @@ async def test_config_slave_binary_sensor(hass, mock_modbus):
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 51,
CONF_INPUT_TYPE: CALL_TYPE_COIL,
}
]
},
{
CONF_BINARY_SENSORS: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 51,
CONF_INPUT_TYPE: CALL_TYPE_DISCRETE,
}
]
},
{
CONF_BINARY_SENSORS: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 51,
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_HOLDING,
}
]
},
{
CONF_BINARY_SENSORS: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_ADDRESS: 51,
CONF_INPUT_TYPE: CALL_TYPE_REGISTER_INPUT,
}
]
},
@ -299,106 +342,33 @@ async def test_config_slave_binary_sensor(hass, mock_modbus):
[
(
{CONF_SLAVE_COUNT: 1},
[0x01],
STATE_ON,
[
STATE_OFF,
],
[False] * 8,
STATE_OFF,
[STATE_OFF],
),
(
{CONF_SLAVE_COUNT: 1},
[0x02],
STATE_OFF,
[
STATE_ON,
],
[True] + [False] * 7,
STATE_ON,
[STATE_OFF],
),
(
{CONF_SLAVE_COUNT: 1},
[0x04],
[False, True] + [False] * 6,
STATE_OFF,
[
STATE_OFF,
],
[STATE_ON],
),
(
{CONF_SLAVE_COUNT: 7},
[0x01],
[True, False] * 4,
STATE_ON,
[
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
],
[STATE_OFF, STATE_ON] * 3 + [STATE_OFF],
),
(
{CONF_SLAVE_COUNT: 7},
[0x82],
STATE_OFF,
[
STATE_ON,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_ON,
],
),
(
{CONF_SLAVE_COUNT: 10},
[0x01, 0x00],
{CONF_SLAVE_COUNT: 31},
[True, False] * 16,
STATE_ON,
[
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
],
),
(
{CONF_SLAVE_COUNT: 10},
[0x01, 0x01],
STATE_ON,
[
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_ON,
STATE_OFF,
STATE_OFF,
],
),
(
{CONF_SLAVE_COUNT: 10},
[0x81, 0x01],
STATE_ON,
[
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_OFF,
STATE_ON,
STATE_ON,
STATE_OFF,
STATE_OFF,
],
[STATE_OFF, STATE_ON] * 15 + [STATE_OFF],
),
],
)