Remove stale template_topic code for mqtt publish service (#121604)

This commit is contained in:
Jan Bouwhuis 2024-07-09 18:22:08 +02:00 committed by GitHub
parent e44f00cf7c
commit 5b25c24539
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 3 additions and 122 deletions

View File

@ -113,7 +113,6 @@ _LOGGER = logging.getLogger(__name__)
SERVICE_PUBLISH = "publish" SERVICE_PUBLISH = "publish"
SERVICE_DUMP = "dump" SERVICE_DUMP = "dump"
ATTR_TOPIC_TEMPLATE = "topic_template"
ATTR_PAYLOAD_TEMPLATE = "payload_template" ATTR_PAYLOAD_TEMPLATE = "payload_template"
MAX_RECONNECT_WAIT = 300 # seconds MAX_RECONNECT_WAIT = 300 # seconds
@ -159,16 +158,14 @@ CONFIG_SCHEMA = vol.Schema(
MQTT_PUBLISH_SCHEMA = vol.All( MQTT_PUBLISH_SCHEMA = vol.All(
vol.Schema( vol.Schema(
{ {
vol.Exclusive(ATTR_TOPIC, CONF_TOPIC): valid_publish_topic, vol.Required(ATTR_TOPIC): valid_publish_topic,
vol.Exclusive(ATTR_TOPIC_TEMPLATE, CONF_TOPIC): cv.string,
vol.Exclusive(ATTR_PAYLOAD, CONF_PAYLOAD): cv.string, vol.Exclusive(ATTR_PAYLOAD, CONF_PAYLOAD): cv.string,
vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, CONF_PAYLOAD): cv.string, vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, CONF_PAYLOAD): cv.string,
vol.Optional(ATTR_QOS, default=DEFAULT_QOS): valid_qos_schema, vol.Optional(ATTR_QOS, default=DEFAULT_QOS): valid_qos_schema,
vol.Optional(ATTR_RETAIN, default=DEFAULT_RETAIN): cv.boolean, vol.Optional(ATTR_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
}, },
required=True, required=True,
), )
cv.has_at_least_one_key(ATTR_TOPIC, ATTR_TOPIC_TEMPLATE),
) )
@ -290,29 +287,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_publish_service(call: ServiceCall) -> None: async def async_publish_service(call: ServiceCall) -> None:
"""Handle MQTT publish service calls.""" """Handle MQTT publish service calls."""
msg_topic: str | None = call.data.get(ATTR_TOPIC) msg_topic: str | None = call.data.get(ATTR_TOPIC)
msg_topic_template: str | None = call.data.get(ATTR_TOPIC_TEMPLATE)
payload: PublishPayloadType = call.data.get(ATTR_PAYLOAD) payload: PublishPayloadType = call.data.get(ATTR_PAYLOAD)
payload_template: str | None = call.data.get(ATTR_PAYLOAD_TEMPLATE) payload_template: str | None = call.data.get(ATTR_PAYLOAD_TEMPLATE)
qos: int = call.data[ATTR_QOS] qos: int = call.data[ATTR_QOS]
retain: bool = call.data[ATTR_RETAIN] retain: bool = call.data[ATTR_RETAIN]
if msg_topic_template is not None:
rendered_topic: Any = MqttCommandTemplate(
template.Template(msg_topic_template),
hass=hass,
).async_render()
try:
msg_topic = valid_publish_topic(rendered_topic)
except vol.Invalid as err:
err_str = str(err)
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="invalid_publish_topic",
translation_placeholders={
"error": err_str,
"topic": str(rendered_topic),
"topic_template": str(msg_topic_template),
},
) from err
if payload_template is not None: if payload_template is not None:
payload = MqttCommandTemplate( payload = MqttCommandTemplate(

View File

@ -270,9 +270,6 @@
"invalid_platform_config": { "invalid_platform_config": {
"message": "Reloading YAML config for manually configured MQTT `{domain}` item failed. See logs for more details." "message": "Reloading YAML config for manually configured MQTT `{domain}` item failed. See logs for more details."
}, },
"invalid_publish_topic": {
"message": "Unable to publish: topic template `{topic_template}` produced an invalid topic `{topic}` after rendering ({error})"
},
"mqtt_not_setup_cannot_subscribe": { "mqtt_not_setup_cannot_subscribe": {
"message": "Cannot subscribe to topic \"{topic}\", make sure MQTT is set up correctly." "message": "Cannot subscribe to topic \"{topic}\", make sure MQTT is set up correctly."
}, },

View File

@ -32,7 +32,7 @@ from homeassistant.const import (
) )
import homeassistant.core as ha import homeassistant.core as ha
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr, entity_registry as er, template from homeassistant.helpers import device_registry as dr, entity_registry as er, template
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import async_get_platforms from homeassistant.helpers.entity_platform import async_get_platforms
@ -260,100 +260,6 @@ async def test_service_call_without_topic_does_not_publish(
assert not mqtt_mock.async_publish.called assert not mqtt_mock.async_publish.called
async def test_service_call_with_topic_and_topic_template_does_not_publish(
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
) -> None:
"""Test the service call with topic/topic template.
If both 'topic' and 'topic_template' are provided then fail.
"""
mqtt_mock = await mqtt_mock_entry()
topic = "test/topic"
topic_template = "test/{{ 'topic' }}"
with pytest.raises(vol.Invalid):
await hass.services.async_call(
mqtt.DOMAIN,
mqtt.SERVICE_PUBLISH,
{
mqtt.ATTR_TOPIC: topic,
mqtt.ATTR_TOPIC_TEMPLATE: topic_template,
mqtt.ATTR_PAYLOAD: "payload",
},
blocking=True,
)
assert not mqtt_mock.async_publish.called
async def test_service_call_with_invalid_topic_template_does_not_publish(
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
) -> None:
"""Test the service call with a problematic topic template."""
mqtt_mock = await mqtt_mock_entry()
with pytest.raises(MqttCommandTemplateException) as exc:
await hass.services.async_call(
mqtt.DOMAIN,
mqtt.SERVICE_PUBLISH,
{
mqtt.ATTR_TOPIC_TEMPLATE: "test/{{ 1 | no_such_filter }}",
mqtt.ATTR_PAYLOAD: "payload",
},
blocking=True,
)
assert str(exc.value) == (
"TemplateError: TemplateAssertionError: No filter named 'no_such_filter'. "
"rendering template, template: "
"'test/{{ 1 | no_such_filter }}' and payload: None"
)
assert not mqtt_mock.async_publish.called
async def test_service_call_with_template_topic_renders_template(
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
) -> None:
"""Test the service call with rendered topic template.
If 'topic_template' is provided and 'topic' is not, then render it.
"""
mqtt_mock = await mqtt_mock_entry()
await hass.services.async_call(
mqtt.DOMAIN,
mqtt.SERVICE_PUBLISH,
{
mqtt.ATTR_TOPIC_TEMPLATE: "test/{{ 1+1 }}",
mqtt.ATTR_PAYLOAD: "payload",
},
blocking=True,
)
assert mqtt_mock.async_publish.called
assert mqtt_mock.async_publish.call_args[0][0] == "test/2"
async def test_service_call_with_template_topic_renders_invalid_topic(
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
) -> None:
"""Test the service call with rendered, invalid topic template.
If a wildcard topic is rendered, then fail.
"""
mqtt_mock = await mqtt_mock_entry()
with pytest.raises(ServiceValidationError) as exc:
await hass.services.async_call(
mqtt.DOMAIN,
mqtt.SERVICE_PUBLISH,
{
mqtt.ATTR_TOPIC_TEMPLATE: "test/{{ '+' if True else 'topic' }}/topic",
mqtt.ATTR_PAYLOAD: "payload",
},
blocking=True,
)
assert str(exc.value) == (
"Unable to publish: topic template `test/{{ '+' if True else 'topic' }}/topic` "
"produced an invalid topic `test/+/topic` after rendering "
"(Wildcards cannot be used in topic names)"
)
assert not mqtt_mock.async_publish.called
async def test_service_call_with_invalid_rendered_template_topic_doesnt_render_template( async def test_service_call_with_invalid_rendered_template_topic_doesnt_render_template(
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
) -> None: ) -> None: