Automating the sharing of sensors and switches between HA's using MQTT Discovery and Statestream

I use several HA’s on the same network and want to share the sensor / switch state between HA’s. I use MQTT statestream to stream the states of its sensors / switches to its MQTT broker. I put this automation below to allow other HA’s to use MQTT discovery which automatically create’s all the sensors for it’s use. It will populate all the sensors / switches config data on restart (and on every state change).

automation mqtt_discovery_config_post:
  alias: mqtt_discovery_config_post
  trigger:
    - platform: state
      entity_id:
        - switch.fireplace  
        - switch.homearm  
        - switch.kitchen_light  
        - switch.outside_lights 
        - switch.sound 
        - binary_sensor.basement_bedrooms_windows  
        - binary_sensor.basement_east_door  
        - binary_sensor.basement_hall_motion  
        - binary_sensor.dining_room_windows  
        - binary_sensor.doorbell  
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.to_state.entity_id | replace('script', 'binary_sensor')  | replace('input_text', 'sensor')| replace('.', '/') | replace('switch', 'binary_sensor') }}/config"
        payload: "{\"name\": \"{{ trigger.to_state.attributes.friendly_name | title }}\", \"device_class\": \"{{ trigger.to_state.attributes.device_class }}\", \"pl_off\":\"off\", \"pl_on\":\"on\"}"
        retain: true
12 Likes

I changed the automation so it looks for the entities in the MQTT broker so I don’t have to specify. I also found it didn’t add all the entities at restart.

automation mqtt_config_entity_creator:
  alias: mqtt_config_entity_creator
  trigger:
    - platform: mqtt
      topic: 'homeassistant/binary_sensor/#'
    - platform: mqtt
      topic: 'homeassistant/switch/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'device_class' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"device_class\": {{ trigger.payload }}, \"pl_off\":\"off\", \"pl_on\":\"on\"}"
        retain: true

Thank you so much! Going to be testing this out today!!!

Great, you might want to shut off the automation after a period of time, especially with retain on.

  initial_state: 'on'

- delay:
    minutes: 1   
- service: automation.turn_off
  entity_id:  mqtt_config_entity_creator

I broke out the switches and added an automation to read the command topic and turn on / off switches.

automation mqtt_config_entity_creator_sensor:
  alias: mqtt_config_entity_creator_sensor
  trigger:
    - platform: mqtt
      topic: 'homeassistant/binary_sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'device_class' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/binary_sensor/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"device_class\": {{ trigger.payload }}, \"pl_off\":\"off\", \"pl_on\":\"on\"}"
        retain: true
automation mqtt_config_entity_creator_switch:
  alias: mqtt_config_entity_creator_switch
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/switch/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"device_class\": \"{{ trigger.payload }}\", \"pl_off\":\"off\", \"pl_on\":\"on\",  \"command_topic\": \"homeassistant/switch/{{ trigger.topic.split('/')[2] }}/set\" }"
        retain: true
automation mqtt_command_switch:
  alias: mqtt_command_switch
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  action:
    - service_template: 'switch.turn_{{trigger.payload | lower }}'
      data_template:
        entity_id: switch.{{ trigger.topic.split('/')[2] }}

I added lights and sensors .

These automations will look at the MQTT Broker under the homeassistant topic that MQTT Statestream uses by default. It will create config payloads for binary_sensors, sensors, switches and lights so MQTT Discovery on another HA will populate these entities automatically. The last automation will allow control of the lights and switches from the other HA.

#########################################################################################       #########################################################################################
automation mqtt_config_entity_creator_sensor:
  alias: mqtt_config_entity_creator_sensor
  trigger:
    - platform: mqtt
      topic: 'homeassistant/binary_sensor/#'
    - platform: mqtt
      topic: 'homeassistant/sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'device_class' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/binary_sensor/{{ trigger.topic.split('/')[2] }}/config"
#        payload: ""         
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"device_class\": {{ trigger.payload }}, \"pl_off\":\"off\", \"pl_on\":\"on\"}"
        retain: true
#########################################################################################
#########################################################################################
automation mqtt_config_entity_creator_switch_light:
  alias: mqtt_config_entity_creator_switch
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
#        payload: ""        
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\",  \"pl_off\":\"off\", \"pl_on\":\"on\",  \"command_topic\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/set\" }"
        retain: true
#########################################################################################
#########################################################################################
automation mqtt_command_switch:
  alias: mqtt_command_switch
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  action:
    - service_template: "{{ trigger.topic.split('/')[1] }}.turn_{{trigger.payload | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
2 Likes

This works flawlessly! Thank you so much!

1 Like

Hey, so I tried to make an automation to send sensor states too.

I have a dedicated Hass.io instance with a zigbee & zwave radio that then publishes via MQTT Statestream component to my Primary Hass.io running in a virtual machine.

I want to publish temperature sensors and any other sensors with a state. My automation works, but loses the device_class if specified. As a workaround, I’m using customize to put the device class back.

#########################################################################################
#########################################################################################

- alias: mqtt_config_entity_creator_binary_sensor
  trigger:
    - platform: mqtt
      topic: 'homeassistant/binary_sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'device_class' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/binary_sensor/{{ trigger.topic.split('/')[2] }}/config"
#        payload: ""         
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"device_class\": {{ trigger.payload }}, \"pl_off\":\"off\", \"pl_on\":\"on\"}"
        retain: true
#########################################################################################
#########################################################################################

- alias: mqtt_config_entity_creator_switch_or_light
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
#        payload: ""        
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\",  \"pl_off\":\"off\", \"pl_on\":\"on\",  \"command_topic\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/set\" }"
        retain: true
#########################################################################################
#########################################################################################

- alias: mqtt_command_switch_or_light
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  action:
    - service_template: "{{ trigger.topic.split('/')[1] }}.turn_{{trigger.payload | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
        
#########################################################################################
#########################################################################################

- alias: mqtt_config_entity_creator_sensor
  trigger:
    - platform: mqtt
      topic: 'homeassistant/sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.topic.split('/')[2] }}/config"
#        payload: ""         
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"state_topic\": \"homeassistant/sensor/{{ trigger.topic.split('/')[2] }}/state\"}"
        retain: true
#########################################################################################
#########################################################################################

Thanks, I did the same. I think I’ll add units of measurement as well to the sensors as most my sensor have that attribute and I’ll use customizer if they don’t.

I added uniq_id to the config so that the mqtt entities show up in configuration/integration. In the automation below, I made sure all the sensors in rpi3 had a unit of measurement so the config will trigger and include that.

########################################################################################
#########################################################################################
automation mqtt_config_entity_creator_sensor:
  initial_state: 'on'
  alias: mqtt_config_entity_creator_sensor
  trigger:
    - platform: mqtt
      topic: 'rpi3/sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'unit_of_measurement' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"unit_of_meas\":{{ trigger.payload }},\"state_topic\": \"rpi3/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/state\",\"uniq_id\": \"{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}\" }"
        retain: true
#########################################################################################
#########################################################################################
1 Like

Thanks for this automation. I think I could use it to connect my inside HA to my outside HA. However I get an error I do not know how to fix. I’m trying to use my inside fibaro sensor connected to my alarm to turn off my outside lights. So if the alarm is set, turn off outside lights.
In the inside HA i I have a MQTT statestream working. (I see in MQTT fx that the binary sensor is published as either on or off in the topic homeassistant/binary_sensor/sensor_jablotro_sensor_2/state.
I then use your whole automation scripts in the outside HA and stating in the config of the outside HA. MQTT discovery. If I then swith alarm on or off I got an error in the outside HA:

2019-03-20 11:08:55 ERROR (MainThread) [homeassistant.components.mqtt.binary_sensor] Exception in async_discover when dispatching ‘mqtt_discovery_new_binary_sensor_mqtt’: ({‘device_class’: ‘’, ‘state_topic’: ‘homeassistant/binary_sensor/sensor_jablotro_sensor_2/state’, ‘payload_on’: ‘on’, ‘payload_off’: ‘off’, ‘platform’: ‘mqtt’, ‘name’: ‘Armed’},)
Traceback (most recent call last):
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/config_validation.py”, line 643, in call
return super().call(data)
File “/srv/homeassistant/lib/python3.5/site-packages/voluptuous/schema_builder.py”, line 267, in call
return self._compiled([], data)
File “/srv/homeassistant/lib/python3.5/site-packages/voluptuous/schema_builder.py”, line 589, in validate_dict
return base_validate(path, iteritems(data), out)
File “/srv/homeassistant/lib/python3.5/site-packages/voluptuous/schema_builder.py”, line 427, in validate_mapping
raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: value is not allowed for dictionary value @ data[‘device_class’]

If I search for this error I see a couple of recent threads so maybe it is a problem of a recent HASSIO version (using 0.89?) Anybody knows how to fix this?

I found out that I had to customize the sensor in the inside HA in the device class as “lock”. Then it was created in the outside HA! Only the icon of the lock is a bit strange in that if it is on I see an open lock…

Thanks for this, it’s what I’ve been looking for. I had a question about the integrations tab though. The sensors that I’m discovering are things like my cable modem state, software version, etc, so they don’t really have a device class or unit of measurement. All the sensors show up on the integrations tab in a box titled “Entities without devices”. Is there a way to divide them up by device?

Thanks,

Denny

You might try to define the class of the sensor (or binary sensor) through customization so that it will be defined in the integration.

Device Class

The way these sensors are displayed in the frontend can be modified in the customize section. The following device classes are supported for sensors:

  • None : Generic sensor. This is the default and doesn’t need to be set.
  • battery : Percentage of battery that is left.
  • humidity : Percentage of humidity in the air.
  • illuminance : The current light level in lx or lm.
  • signal_strength : Signal strength in dB or dBm.
  • temperature : Temperature in °C or °F.
  • power : Power in W or kW.
  • pressure : Pressure in hPa or mbar.
  • timestamp : Datetime object or timestamp string.

DEVICE CLASS

The way these sensors are displayed in the frontend can be modified in the customize section. The following device classes are supported for binary sensors:

  • None : Generic on/off. This is the default and doesn’t need to be set.
  • battery : On means low, Off means normal
  • cold : On means cold, Off means normal
  • connectivity : On means connected, Off means disconnected
  • door : On means open, Off means closed
  • garage_door : On means open, Off means closed
  • gas : On means gas detected, Off means no gas (clear)
  • heat : On means hot, Off means normal
  • light : On means light detected, Off means no light
  • lock : On means open (unlocked), Off means closed (locked)
  • moisture : On means moisture detected (wet), Off means no moisture (dry)
  • motion : On means motion detected, Off means no motion (clear)
  • moving : On means moving, Off means not moving (stopped)
  • occupancy : On means occupied, Off means not occupied (clear)
  • opening : On means open, Off means closed
  • plug : On means device is plugged in, Off means device is unplugged
  • power : On means power detected, Off means no power
  • presence : On means home, Off means away
  • problem : On means problem detected, Off means no problem (OK)
  • safety : On means unsafe, Off means safe
  • smoke : On means smoke detected, Off means no smoke (clear)
  • sound : On means sound detected, Off means no sound (clear)
  • vibration : On means vibration detected, Off means no vibration (clear)
  • window : On means open, Off means closed

Thanks. I’ve messed around with it and found various ways NOT to make it work :slight_smile: For now I’m happy with them just coming over to my main instance.

I did find this for when you goober it up good and do things like advertise sensor.time, etc that you want to undo. There is a NodeJS app named MQTT-Forget:

But you need to tell it to forget both your homeassistant/ topic and your trigger topic, or else they just keep coming back.

Thanks,

Denny

I just realized that all my mqtt sensors / lights / switches that have auto config show up on the integration page saying they are without entities. I think this is wrong as all the entities have devices and device classes.

image

Is there a way for the lights to have a brightness setting? Or is it just going to be on/off?

There is although it might need a separate automation depending if some light are just on/off and some are with brightness.

Take a look here for all the config possibilities.

Try adding the brightness into the payload of this automation and remove switch as it won’t be applicable.

#########################################################################################
#########################################################################################
automation mqtt_config_entity_creator_switch_light:
  alias: mqtt_config_entity_creator_switch
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
#        payload: ""        
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\",  \"pl_off\":\"off\", \"pl_on\":\"on\",  \"command_topic\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/set\" }"
        retain: true

I would start by determining which of these are used by your lights.

    'bri_cmd_t':           'brightness_command_topic',
    'bri_scl':             'brightness_scale',
    'bri_stat_t':          'brightness_state_topic',
    'bri_tpl':             'brightness_template',
    'bri_val_tpl':         'brightness_value_template'

Thanks! I didn’t see this but after messing around for most of the day I figured it out. Exhausted but I’ll post my config at some point. Much appreciated for the starting guide though, was extremely helpful!

Just follow up here is my config for lights, switches, sensors, binary sensors, locks and covers. I realized this morning that transitions aren’t working so I’m going to have to modify my lights a bit to get them to work (looks like I’ll be going for the JSON format), but figured this might help someone else. The brightness control works just fine.

Automations for the “master” instance:

- alias: "MQTT Light and Switch Toggle"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  action:
    - service_template: "{{ trigger.topic.split('/')[1] }}.turn_{{trigger.payload | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"

- alias: "MQTT Light Brightness"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'brightness' }}"
  - condition: template
    value_template:  "{{ trigger.topic.split('/')[4] == 'set' }}"
  action:
    - service: light.turn_on
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
        brightness: "{{trigger.payload}}"

- alias: "MQTT Cover Toggle"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/cover/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  action:
    - service_template: "cover.{{trigger.payload | lower }}_cover"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"

- alias: "MQTT Lock Toggle"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/lock/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'set' }}"
  action:
    - service_template: "lock.{{trigger.payload | lower }}"
      data_template:
        entity_id: "{{ trigger.topic.split('/')[1] }}.{{ trigger.topic.split('/')[2] }}"
        code: !secret door_code

And these are the automations running on the slave instance (note I have the binary sensor turn off because it was spamming messages. I think I fixed that but I left the automation in as I don’t think it hurts):

- alias: "MQTT Discovery Switch Creator"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/switch/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\",  \"pl_off\":\"off\", \"pl_on\":\"on\",  \"stat_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/state\",  \"cmd_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/set\" }"
        retain: true

- alias: "MQTT Discovery Light Creator"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/light/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"pl_off\":\"off\", \"pl_on\":\"on\",  \"cmd_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/set\",  \"stat_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/state\",  \"bri_stat_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/brightness\",  \"bri_cmd_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/brightness/set\" }"
        retain: true

- alias: "MQTT Discovery Binary Sensor Creator"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/binary_sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"    
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/binary_sensor/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"pl_off\":\"off\", \"pl_on\":\"on\", \"stat_t\": \"homeassistant/{{ trigger.topic.split('/')[1] }}/{{ trigger.topic.split('/')[2] }}/state\"}"
        retain: true

- alias: "HASS Restart Binary Sensor Automation Toggle"
  initial_state: 'on'
  hide_entity: True
  trigger:
    platform: homeassistant
    event: start
  action:
  - service: automation.turn_on
    entity_id: automation.mqtt_discovery_binary_sensor_creator
  - delay: 0:00:10
  - service: automation.turn_off
    entity_id: automation.mqtt_discovery_binary_sensor_creator

- alias: "MQTT Discovery Sensor Creator"
  trigger:
    - platform: mqtt
      topic: 'homeassistant/sensor/#'
  condition:
    condition: template
    value_template:  "{{ trigger.topic.split('/')[3] == 'state' }}"   
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.topic.split('/')[2] }}/config"
        payload: "{\"name\": \"{{ trigger.topic.split('/')[2]| replace('_', ' ') | title }}\", \"state_topic\": \"homeassistant/sensor/{{ trigger.topic.split('/')[2] }}/state\"}"
        retain: true