It’s relatively easy to control equipment connected through MQTT from Home Assistant. However, to make Home Assistant-controlled devices available over MQTT requires a bit more work and I have not found a good guide on how to connect them. I wanted to find a generic pattern that makes it easy to add more lights possible to control through MQTT.
This article shows how to make a light in Home Assistant available to switch on and off through MQTT, and to update the state of the MQTT topic based on the device state. A topic will be made into a Light in Home Assistant, and an existing Light in Home Assistant will be connected to it. The state will be updated between them: When one state changes to on or off, the other will be changed too.
The system can enter a “twitching” state if/when the switching occurs too frequently, and the state is changed faster than the system can update itself. This has happened on my Raspberry Pi when pushing the system, but not in normal use.
The devices I connected for this article are two IKEA TRÅDFRI bulbs, connected through the IKEA Gateway, controlled mainly with an IKEA remote control. The IKEA Gateway is connected to Home Automation and two lights were connected to MQTT: lights.koksbordet
(Swedish for kitchen table) and lights.bedroom_tablelamp
. I am a beginner with Home Assistant, having using OpenHAB for a long time, and still do, in parallel with Home Assistant.
The configuration for how to connect to the MQTT broker and to the IKEA TRÅDFRI gateway is left out from the article. The lamps from the IKEA TRÅDFRI were discovered automatically and not added in the configuration files.
Three key parts of the Home Automation configuration is covered: Light devices, Automation rules and the main configuration file. I have put my lights and automation configuration in external files: lights.yaml and automation.yaml. This is accomplished by adding below two rows to the configuration.yaml file:
automation: !include automations.yaml
light: !include light.yaml
I used a simple MQTT topic with 1
representing the on state, and a 0
the off state. When sending 1
to MQTT topic indoors/kitchen/table
, the kitchen table lamp is expected to light up, and turn off when we send a 0
.
The MQTT configuration for the kitchen table lamp MQTT topic is listed below. On state change, it will send the new state to the MQTT topic, 0
or 1
. On receiving either value on the topic, the corresponding Home Assistant state for the light will be set.
Two MQTT topics are defined, one for the kitchen table lamp, and one for the bedroom tablelamp. The Home Assistant light names are used, with a suffix of _mqtt
. The _mqtt
suffix is used in the automation rule to identify the link between MQTT light and connected Home Assistant Light:
The MQTT configuration for the two lights is straightforward.
# The light.yaml file for the two Trådfri lamps
---
- platform: mqtt
name: 'koksbordet_mqtt'
command_topic: "indoors/kitchen/table"
state_topic: "indoors/kitchen/table"
payload_on: 1
payload_off: 0
- platform: mqtt
name: 'bedroom_tablelamp_mqtt'
command_topic: "indoors/bedroom/tablelamp"
state_topic: "indoors/bedroom/tablelamp"
payload_on: 1
payload_off: 0
The IKEA TRÅDFRI gateway has two lamps, each connected to an IKEA TRÅDFRI remote control to change color and brightness. Turning the light on and off is the only thing we will do in this article.
The two lights are named without the _mqtt
prefix above:
Both are connected to the IKEA TRÅDFRI gateway.
The connection between lights and MQTT took me a long time to figure out as started in the wrong end, connecting lights and switches, and trying out templating, rather than figuring out the automations. Once I learned the automations part, it was quite straightforward to connect the lights with MQTT. What I wanted next was to make it easy to add new lights in the future, to the list of entities in entity_id:
.
I am down to one code block where I need to add each “real” light and each MQTT light twice, once for on, and once for off. It’s good enough for now.
The first part of automations.yaml
deals with turning on and off the MQTT light when the “real” lights change state. Using the powerful Home Assistant automation templating, the triggering entity_id can be reused in the action section. I use the Jinja2 string concatenation character +
to bind the trigger entity id together with the suffix _mqtt
for selecting the light to turn on.
As all the MQTT entities we have defined have an _mqtt
suffix, the automation template action will find it when triggering the turn_on/turn_off service. Add the entitiy_ids that should trigger their respective MQTT lights to entity_id:
.
- alias: 'Make lights switch on MQTT shadows'
trigger:
# Multiple entities for which you want to trigger shadow state.
- platform: state
entity_id: light.koksbordet, light.bedroom_tablelamp
to: 'on'
action:
- service: light.turn_on
data_template:
entity_id: "{{ trigger.entity_id + '_mqtt' }}"
- alias: 'Make lights switch off MQTT shadows'
trigger:
# Multiple entities for which you want to trigger shadow state.
- platform: state
entity_id: light.koksbordet, light.bedroom_tablelamp
to: 'off'
action:
- service: light.turn_off
data_template:
entity_id: "{{ trigger.entity_id + '_mqtt' }}"
The other direction is needed too, to ensure the lights will receive the state changes from MQTT. Jinja2 is used here too, this time it’s the replace()
function that is used, to remove the _mqtt
suffix of the triggering entity_id. This way, the “real” lamp will assume the state of the MQTT corresponding lamp.
- alias: 'Make MQTT shadows switch lights'
trigger:
# Multiple entities for which you want to trigger shadow state.
- platform: state
entity_id: light.koksbordet_mqtt, light.bedroom_tablelamp_mqtt
to: 'on'
action:
- service: light.turn_on
data_template:
entity_id: "{{ trigger.entity_id | replace('_mqtt', '') }}"
- alias: 'Make MQTT shadows switch lights'
trigger:
# Multiple entities for which you want to trigger shadow state.
- platform: state
entity_id: light.koksbordet_mqtt, light.bedroom_tablelamp_mqtt
to: 'off'
action:
- service: light.turn_off
data_template:
entity_id: "{{ trigger.entity_id | replace('_mqtt', '') }}"
The templating solution for automation makes it easy to add the functionality to a large number of lamps by just adding them to automations.yaml
and not have to copy the automation code to many places. Using Jinja2 and trigger.entity_id
to find the corresponding light simplified the configuration tremendeously.
The use of MQTT enables OpenHAB and Home Assistant to share state and have the lights configured in both platforms and in sync, which is a great use case for an event driven architecture.