Handle numeric versions in mqtt update (#83218)

* Handle numeric versions in mqtt update

* Remove need for type:ignore

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
pull/83482/head
Joe Rogers 2022-12-04 15:52:48 -05:00 committed by Paulus Schoutsen
parent d14324c792
commit eb0450ad0c
2 changed files with 108 additions and 6 deletions

View File

@ -172,14 +172,22 @@ class MqttUpdate(MqttEntity, UpdateEntity, RestoreEntity):
)
return
json_payload = {}
json_payload: Any | dict = {}
try:
json_payload = json_loads(payload)
_LOGGER.debug(
"JSON payload detected after processing payload '%s' on topic %s",
json_payload,
msg.topic,
)
if isinstance(json_payload, dict):
_LOGGER.debug(
"JSON payload detected after processing payload '%s' on topic %s",
json_payload,
msg.topic,
)
else:
_LOGGER.debug(
"Non-dictionary JSON payload detected after processing payload '%s' on topic %s",
payload,
msg.topic,
)
json_payload = {"installed_version": payload}
except JSON_DECODE_EXCEPTIONS:
_LOGGER.debug(
"No valid (JSON) payload detected after processing payload '%s' on topic %s",

View File

@ -110,6 +110,54 @@ async def test_run_update_setup(hass, mqtt_mock_entry_with_yaml_config):
assert state.attributes.get("latest_version") == "2.0.0"
async def test_run_update_setup_float(hass, mqtt_mock_entry_with_yaml_config):
"""Test that it fetches the given payload when the version is parsable as a number."""
installed_version_topic = "test/installed-version"
latest_version_topic = "test/latest-version"
await async_setup_component(
hass,
mqtt.DOMAIN,
{
mqtt.DOMAIN: {
update.DOMAIN: {
"state_topic": installed_version_topic,
"latest_version_topic": latest_version_topic,
"name": "Test Update",
"release_summary": "Test release summary",
"release_url": "https://example.com/release",
"title": "Test Update Title",
"entity_picture": "https://example.com/icon.png",
}
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
async_fire_mqtt_message(hass, installed_version_topic, "1.9")
async_fire_mqtt_message(hass, latest_version_topic, "1.9")
await hass.async_block_till_done()
state = hass.states.get("update.test_update")
assert state.state == STATE_OFF
assert state.attributes.get("installed_version") == "1.9"
assert state.attributes.get("latest_version") == "1.9"
assert state.attributes.get("release_summary") == "Test release summary"
assert state.attributes.get("release_url") == "https://example.com/release"
assert state.attributes.get("title") == "Test Update Title"
assert state.attributes.get("entity_picture") == "https://example.com/icon.png"
async_fire_mqtt_message(hass, latest_version_topic, "2.0")
await hass.async_block_till_done()
state = hass.states.get("update.test_update")
assert state.state == STATE_ON
assert state.attributes.get("installed_version") == "1.9"
assert state.attributes.get("latest_version") == "2.0"
async def test_value_template(hass, mqtt_mock_entry_with_yaml_config):
"""Test that it fetches the given payload with a template."""
installed_version_topic = "test/installed-version"
@ -156,6 +204,52 @@ async def test_value_template(hass, mqtt_mock_entry_with_yaml_config):
assert state.attributes.get("latest_version") == "2.0.0"
async def test_value_template_float(hass, mqtt_mock_entry_with_yaml_config):
"""Test that it fetches the given payload with a template when the version is parsable as a number."""
installed_version_topic = "test/installed-version"
latest_version_topic = "test/latest-version"
await async_setup_component(
hass,
mqtt.DOMAIN,
{
mqtt.DOMAIN: {
update.DOMAIN: {
"state_topic": installed_version_topic,
"value_template": "{{ value_json.installed }}",
"latest_version_topic": latest_version_topic,
"latest_version_template": "{{ value_json.latest }}",
"name": "Test Update",
}
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
async_fire_mqtt_message(hass, installed_version_topic, '{"installed":"1.9"}')
async_fire_mqtt_message(hass, latest_version_topic, '{"latest":"1.9"}')
await hass.async_block_till_done()
state = hass.states.get("update.test_update")
assert state.state == STATE_OFF
assert state.attributes.get("installed_version") == "1.9"
assert state.attributes.get("latest_version") == "1.9"
assert (
state.attributes.get("entity_picture")
== "https://brands.home-assistant.io/_/mqtt/icon.png"
)
async_fire_mqtt_message(hass, latest_version_topic, '{"latest":"2.0"}')
await hass.async_block_till_done()
state = hass.states.get("update.test_update")
assert state.state == STATE_ON
assert state.attributes.get("installed_version") == "1.9"
assert state.attributes.get("latest_version") == "2.0"
async def test_empty_json_state_message(hass, mqtt_mock_entry_with_yaml_config):
"""Test an empty JSON payload."""
state_topic = "test/state-topic"