mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 19:57:07 +00:00
Improve error handling and logging on MQTT update entity state updates when template rederings fails (#141960)
This commit is contained in:
parent
2b9c903429
commit
fa3832fbd7
@ -26,7 +26,7 @@ from . import subscription
|
|||||||
from .config import DEFAULT_RETAIN, MQTT_RO_SCHEMA
|
from .config import DEFAULT_RETAIN, MQTT_RO_SCHEMA
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_RETAIN, CONF_STATE_TOPIC, PAYLOAD_EMPTY_JSON
|
from .const import CONF_COMMAND_TOPIC, CONF_RETAIN, CONF_STATE_TOPIC, PAYLOAD_EMPTY_JSON
|
||||||
from .entity import MqttEntity, async_setup_entity_entry_helper
|
from .entity import MqttEntity, async_setup_entity_entry_helper
|
||||||
from .models import MqttValueTemplate, ReceiveMessage
|
from .models import MqttValueTemplate, PayloadSentinel, ReceiveMessage
|
||||||
from .schemas import MQTT_ENTITY_COMMON_SCHEMA
|
from .schemas import MQTT_ENTITY_COMMON_SCHEMA
|
||||||
from .util import valid_publish_topic, valid_subscribe_topic
|
from .util import valid_publish_topic, valid_subscribe_topic
|
||||||
|
|
||||||
@ -136,7 +136,18 @@ class MqttUpdate(MqttEntity, UpdateEntity, RestoreEntity):
|
|||||||
@callback
|
@callback
|
||||||
def _handle_state_message_received(self, msg: ReceiveMessage) -> None:
|
def _handle_state_message_received(self, msg: ReceiveMessage) -> None:
|
||||||
"""Handle receiving state message via MQTT."""
|
"""Handle receiving state message via MQTT."""
|
||||||
payload = self._templates[CONF_VALUE_TEMPLATE](msg.payload)
|
payload = self._templates[CONF_VALUE_TEMPLATE](
|
||||||
|
msg.payload, PayloadSentinel.DEFAULT
|
||||||
|
)
|
||||||
|
|
||||||
|
if payload is PayloadSentinel.DEFAULT:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Unable to process payload '%s' for topic %s, with value template '%s'",
|
||||||
|
msg.payload,
|
||||||
|
msg.topic,
|
||||||
|
self._config.get(CONF_VALUE_TEMPLATE),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if not payload or payload == PAYLOAD_EMPTY_JSON:
|
if not payload or payload == PAYLOAD_EMPTY_JSON:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""The tests for mqtt update component."""
|
"""The tests for mqtt update component."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from typing import Any
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -225,6 +226,71 @@ async def test_value_template(
|
|||||||
assert state.attributes.get("latest_version") == "2.0.0"
|
assert state.attributes.get("latest_version") == "2.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"hass_config",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
mqtt.DOMAIN: {
|
||||||
|
update.DOMAIN: {
|
||||||
|
"state_topic": "test/update",
|
||||||
|
"value_template": (
|
||||||
|
"{\"latest_version\":\"{{ value_json['update']['latest_version'] }}\","
|
||||||
|
"\"installed_version\":\"{{ value_json['update']['installed_version'] }}\","
|
||||||
|
"\"update_percentage\":{{ value_json['update'].get('progress', 'null') }}}"
|
||||||
|
),
|
||||||
|
"name": "Test Update",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_errornous_value_template(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
) -> None:
|
||||||
|
"""Test that it fetches the given payload with a template or handles the exception."""
|
||||||
|
state_topic = "test/update"
|
||||||
|
await mqtt_mock_entry()
|
||||||
|
|
||||||
|
# Simulate a template redendering error with payload
|
||||||
|
# without "update" mapping
|
||||||
|
example_payload: dict[str, Any] = {
|
||||||
|
"child_lock": "UNLOCK",
|
||||||
|
"current": 0.02,
|
||||||
|
"energy": 212.92,
|
||||||
|
"indicator_mode": "off/on",
|
||||||
|
"linkquality": 65,
|
||||||
|
"power": 0,
|
||||||
|
"power_outage_memory": "off",
|
||||||
|
"state": "ON",
|
||||||
|
"voltage": 232,
|
||||||
|
}
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, state_topic, json.dumps(example_payload))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert hass.states.get("update.test_update") is not None
|
||||||
|
assert "Unable to process payload '" in caplog.text
|
||||||
|
|
||||||
|
# Add update info
|
||||||
|
example_payload["update"] = {
|
||||||
|
"latest_version": "2.0.0",
|
||||||
|
"installed_version": "1.9.0",
|
||||||
|
"progress": 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, state_topic, json.dumps(example_payload))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("update.test_update")
|
||||||
|
assert state is not None
|
||||||
|
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes.get("installed_version") == "1.9.0"
|
||||||
|
assert state.attributes.get("latest_version") == "2.0.0"
|
||||||
|
assert state.attributes.get("update_percentage") == 20
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"hass_config",
|
"hass_config",
|
||||||
[
|
[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user