diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index e86d1314b5a..d05ec1f5453 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -70,9 +70,10 @@ MQTT_PUBLISH_SCHEMA = vol.Schema({ vol.Required(ATTR_TOPIC): mqtt_topic, vol.Exclusive(ATTR_PAYLOAD, 'payload'): object, vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, 'payload'): cv.string, - vol.Required(ATTR_QOS, default=DEFAULT_QOS): vol.In([0, 1, 2]), - vol.Required(ATTR_RETAIN, default=DEFAULT_RETAIN): vol.Coerce(bool), -}) + vol.Required(ATTR_QOS, default=DEFAULT_QOS): + vol.All(vol.Coerce(int), vol.In([0, 1, 2])), + vol.Required(ATTR_RETAIN, default=DEFAULT_RETAIN): vol.Boolean(), +}, required=True) def _build_publish_data(topic, qos, retain): @@ -194,7 +195,8 @@ def setup(hass, config): qos = call.data[ATTR_QOS] retain = call.data[ATTR_RETAIN] try: - payload = payload or template.render(hass, payload_template) + payload = (payload if payload_template is None else + template.render(hass, payload_template)) or '' except template.jinja2.TemplateError as exc: _LOGGER.error( "Unable to publish to '%s': rendering payload template of " diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index 04f5f574413..d57504562c1 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -104,14 +104,31 @@ class TestMQTT(unittest.TestCase): def test_service_call_without_payload_or_payload_template(self): """Test the service call without payload or payload template. - If neither 'payload' or 'payload_template' is provided then fail. + Send empty message if neither 'payload' nor 'payload_template' + are provided. """ # Call the service directly because the helper functions require you to # provide a payload. self.hass.services.call(mqtt.DOMAIN, mqtt.SERVICE_PUBLISH, { mqtt.ATTR_TOPIC: "test/topic" }, blocking=True) - self.assertFalse(mqtt.MQTT_CLIENT.publish.called) + self.assertTrue(mqtt.MQTT_CLIENT.publish.called) + self.assertEqual(mqtt.MQTT_CLIENT.publish.call_args[0][1], "") + + def test_service_call_with_ascii_qos_retain_flags(self): + """Test the service call with args that can be misinterpreted. + + Empty payload message and ascii formatted qos and retain flags. + """ + self.hass.services.call(mqtt.DOMAIN, mqtt.SERVICE_PUBLISH, { + mqtt.ATTR_TOPIC: "test/topic", + mqtt.ATTR_PAYLOAD: "", + mqtt.ATTR_QOS: '2', + mqtt.ATTR_RETAIN: 'no' + }, blocking=True) + self.assertTrue(mqtt.MQTT_CLIENT.publish.called) + self.assertEqual(mqtt.MQTT_CLIENT.publish.call_args[0][2], 2) + self.assertFalse(mqtt.MQTT_CLIENT.publish.call_args[0][3]) def test_subscribe_topic(self): """Test the subscription of a topic."""