Fix handling undecoded mqtt sensor payloads (#118633)
parent
9366a4e69b
commit
3653a51288
|
@ -237,28 +237,32 @@ class MqttSensor(MqttEntity, RestoreSensor):
|
|||
payload = msg.payload
|
||||
if payload is PayloadSentinel.DEFAULT:
|
||||
return
|
||||
new_value = str(payload)
|
||||
if not isinstance(payload, str):
|
||||
_LOGGER.warning(
|
||||
"Invalid undecoded state message '%s' received from '%s'",
|
||||
payload,
|
||||
msg.topic,
|
||||
)
|
||||
return
|
||||
if self._numeric_state_expected:
|
||||
if new_value == "":
|
||||
if payload == "":
|
||||
_LOGGER.debug("Ignore empty state from '%s'", msg.topic)
|
||||
elif new_value == PAYLOAD_NONE:
|
||||
elif payload == PAYLOAD_NONE:
|
||||
self._attr_native_value = None
|
||||
else:
|
||||
self._attr_native_value = new_value
|
||||
self._attr_native_value = payload
|
||||
return
|
||||
if self.device_class in {
|
||||
None,
|
||||
SensorDeviceClass.ENUM,
|
||||
} and not check_state_too_long(_LOGGER, new_value, self.entity_id, msg):
|
||||
self._attr_native_value = new_value
|
||||
} and not check_state_too_long(_LOGGER, payload, self.entity_id, msg):
|
||||
self._attr_native_value = payload
|
||||
return
|
||||
try:
|
||||
if (payload_datetime := dt_util.parse_datetime(new_value)) is None:
|
||||
if (payload_datetime := dt_util.parse_datetime(payload)) is None:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
_LOGGER.warning(
|
||||
"Invalid state message '%s' from '%s'", msg.payload, msg.topic
|
||||
)
|
||||
_LOGGER.warning("Invalid state message '%s' from '%s'", payload, msg.topic)
|
||||
self._attr_native_value = None
|
||||
return
|
||||
if self.device_class == SensorDeviceClass.DATE:
|
||||
|
|
|
@ -110,6 +110,42 @@ async def test_setting_sensor_value_via_mqtt_message(
|
|||
assert state.attributes.get("unit_of_measurement") == "fav unit"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"unit_of_measurement": "%",
|
||||
"device_class": "battery",
|
||||
"encoding": "",
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
)
|
||||
async def test_handling_undecoded_sensor_value(
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the setting of the value via MQTT."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
state = hass.states.get("sensor.test")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", b"88")
|
||||
state = hass.states.get("sensor.test")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert (
|
||||
"Invalid undecoded state message 'b'88'' received from 'test-topic'"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue