Report modbus buffer too small or too big to unpack (#57838)
parent
38586d2cf1
commit
cca7da77ad
|
@ -160,7 +160,7 @@ class BaseStructPlatform(BasePlatform, RestoreEntity):
|
|||
registers.reverse()
|
||||
return registers
|
||||
|
||||
def unpack_structure_result(self, registers: list[int]) -> str:
|
||||
def unpack_structure_result(self, registers: list[int]) -> str | None:
|
||||
"""Convert registers to proper result."""
|
||||
|
||||
registers = self._swap_registers(registers)
|
||||
|
@ -168,7 +168,13 @@ class BaseStructPlatform(BasePlatform, RestoreEntity):
|
|||
if self._data_type == DataType.STRING:
|
||||
return byte_string.decode()
|
||||
|
||||
val = struct.unpack(self._structure, byte_string)
|
||||
try:
|
||||
val = struct.unpack(self._structure, byte_string)
|
||||
except struct.error as err:
|
||||
recv_size = len(registers) * 2
|
||||
msg = f"Received {recv_size} bytes, unpack error {err}"
|
||||
_LOGGER.error(msg)
|
||||
return None
|
||||
# Issue: https://github.com/home-assistant/core/issues/41944
|
||||
# If unpack() returns a tuple greater than 1, don't try to process the value.
|
||||
# Instead, return the values of unpack(...) separated by commas.
|
||||
|
|
|
@ -166,7 +166,8 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||
|
||||
self._lazy_errors = self._lazy_error_count
|
||||
self._value = self.unpack_structure_result(result.registers)
|
||||
self._attr_available = True
|
||||
if not self._value:
|
||||
self._attr_available = False
|
||||
return None
|
||||
self._attr_available = True
|
||||
return float(self._value)
|
||||
|
|
|
@ -74,6 +74,9 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity):
|
|||
return
|
||||
|
||||
self._attr_native_value = self.unpack_structure_result(result.registers)
|
||||
if self._attr_native_value is None:
|
||||
self._attr_available = False
|
||||
else:
|
||||
self._attr_available = True
|
||||
self._lazy_errors = self._lazy_error_count
|
||||
self._attr_available = True
|
||||
self.async_write_ha_state()
|
||||
|
|
|
@ -94,11 +94,13 @@ async def test_temperature_climate(hass, expected, mock_do_cycle):
|
|||
{
|
||||
CONF_CLIMATES: [
|
||||
{
|
||||
CONF_COUNT: 2,
|
||||
CONF_NAME: TEST_ENTITY_NAME,
|
||||
CONF_TARGET_TEMP: 117,
|
||||
CONF_ADDRESS: 117,
|
||||
CONF_SLAVE: 10,
|
||||
CONF_SCAN_INTERVAL: 0,
|
||||
CONF_DATA_TYPE: DataType.INT32,
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -559,6 +559,44 @@ async def test_all_sensor(hass, mock_do_cycle, expected):
|
|||
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: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"config_addon,register_words",
|
||||
[
|
||||
(
|
||||
{
|
||||
CONF_COUNT: 1,
|
||||
CONF_DATA_TYPE: DataType.INT16,
|
||||
},
|
||||
[7, 9],
|
||||
),
|
||||
(
|
||||
{
|
||||
CONF_COUNT: 2,
|
||||
CONF_DATA_TYPE: DataType.INT32,
|
||||
},
|
||||
[7],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_wrong_unpack(hass, mock_do_cycle):
|
||||
"""Run test for sensor."""
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"do_config",
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue