mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Remove stale template_topic
code for mqtt publish service (#121604)
This commit is contained in:
parent
e44f00cf7c
commit
5b25c24539
@ -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(
|
||||||
|
@ -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."
|
||||||
},
|
},
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user