diff --git a/homeassistant/components/switch/mqtt.py b/homeassistant/components/switch/mqtt.py index 69f12536c5f..1075888e199 100644 --- a/homeassistant/components/switch/mqtt.py +++ b/homeassistant/components/switch/mqtt.py @@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/switch.mqtt/ """ import logging +from typing import Optional import voluptuous as vol @@ -29,12 +30,14 @@ DEFAULT_NAME = 'MQTT Switch' DEFAULT_PAYLOAD_ON = 'ON' DEFAULT_PAYLOAD_OFF = 'OFF' DEFAULT_OPTIMISTIC = False +CONF_UNIQUE_ID = 'unique_id' PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_ICON): cv.icon, vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string, vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string, + vol.Optional(CONF_UNIQUE_ID): cv.string, vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema) @@ -62,6 +65,7 @@ async def async_setup_platform(hass, config, async_add_devices, config.get(CONF_OPTIMISTIC), config.get(CONF_PAYLOAD_AVAILABLE), config.get(CONF_PAYLOAD_NOT_AVAILABLE), + config.get(CONF_UNIQUE_ID), value_template, )]) @@ -72,7 +76,8 @@ class MqttSwitch(MqttAvailability, SwitchDevice): def __init__(self, name, icon, state_topic, command_topic, availability_topic, qos, retain, payload_on, payload_off, optimistic, - payload_available, payload_not_available, value_template): + payload_available, payload_not_available, + unique_id: Optional[str], value_template): """Initialize the MQTT switch.""" super().__init__(availability_topic, qos, payload_available, payload_not_available) @@ -87,6 +92,7 @@ class MqttSwitch(MqttAvailability, SwitchDevice): self._payload_off = payload_off self._optimistic = optimistic self._template = value_template + self._unique_id = unique_id async def async_added_to_hass(self): """Subscribe to MQTT events.""" @@ -139,6 +145,11 @@ class MqttSwitch(MqttAvailability, SwitchDevice): """Return true if we do optimistic updates.""" return self._optimistic + @property + def unique_id(self): + """Return a unique ID.""" + return self._unique_id + @property def icon(self): """Return the icon.""" diff --git a/tests/components/switch/test_mqtt.py b/tests/components/switch/test_mqtt.py index b5e2a0b0395..24db0540012 100644 --- a/tests/components/switch/test_mqtt.py +++ b/tests/components/switch/test_mqtt.py @@ -248,3 +248,26 @@ class TestSwitchMQTT(unittest.TestCase): state = self.hass.states.get('switch.test') self.assertEqual(STATE_ON, state.state) + + def test_unique_id(self): + """Test unique id option only creates one switch per unique_id.""" + assert setup_component(self.hass, switch.DOMAIN, { + switch.DOMAIN: [{ + 'platform': 'mqtt', + 'name': 'Test 1', + 'state_topic': 'test-topic', + 'command_topic': 'command-topic', + 'unique_id': 'TOTALLY_UNIQUE' + }, { + 'platform': 'mqtt', + 'name': 'Test 2', + 'state_topic': 'test-topic', + 'command_topic': 'command-topic', + 'unique_id': 'TOTALLY_UNIQUE' + }] + }) + + fire_mqtt_message(self.hass, 'test-topic', 'payload') + self.hass.block_till_done() + assert len(self.hass.states.async_entity_ids()) == 2 + # all switches group is 1, unique id created is 1