Creating a device with multiple sensor entities via MQTT Discovery

Hello,

My goal is to create a device with multiple sensor entities. For example, a barbecue thermometer with 2 temperature sensors. I’m using RTL_433 to generate MQTT messages.

I’ve attempted to follow the guide provided here:

I’ve followed the commands verbatim in the example, just to test out creating a device with multiple sensors. I get 2 entities which receive temperature updates, but there is no device which groups them together.

For reference, a previous poster had this issue and claims to have figured it out, but didn’t leave any specific information. See: How to implement a custom MQTT device (Home Theater Receiver)

I’ve scoured the internet but have been unable to find a good example. There are so many posts and videos using YAML configuration, which supposedly does not support multiple sensors per device.

Any help would be greatly appreciated!

For starters, can someone confirm that example in MQTT Configuration for multiple sensors actually creates a device with multiple sensor entities? I’m not sure what the expected behavior is, as the example doesn’t include results.

I was able to get a single sensor to have numerous state attributes, but I don’t think this is what I want.

Thank you!

1 Like

You can achieve multiple mqtt sensors via yaml without the use of scripts, recent conversation regarding the same, here:

FWIWI, 2 sensors linked to the same device.
The dev object is key.

{
  "uniq_id": "mqtt_sensor.temperature_humidity_sensor_49e0_battery",
  "name": "Temperature Humidity Sensor 49E0 Battery",
  "stat_t": "ha_stream/sensor/temperature_humidity_sensor_49e0_battery/state",
  "json_attr_t": "ha_stream/sensor/temperature_humidity_sensor_49e0_battery/attributes",
  "avty_t": "ha_stream/sensor/temperature_humidity_sensor_49e0_battery/availability",
  "dev_cla": "battery",
  "unit_of_meas": "%",
  "stat_cla": "measurement",
  "dev": {
    "mf": "Xiaomi",
    "mdl": "LYWSD03MMC",
    "name": "Temperature/Humidity Sensor 49E0",
    "ids": [
      "A4:C1:38:EB:49:E0"
    ]
  }
}

{
  "uniq_id": "mqtt_sensor.temperature_humidity_sensor_49e0_voltage",
  "name": "Temperature Humidity Sensor 49E0 Voltage",
  "stat_t": "ha_stream/sensor/temperature_humidity_sensor_49e0_voltage/state",
  "json_attr_t": "ha_stream/sensor/temperature_humidity_sensor_49e0_voltage/attributes",
  "avty_t": "ha_stream/sensor/temperature_humidity_sensor_49e0_voltage/availability",
  "dev_cla": "voltage",
  "unit_of_meas": "V",
  "stat_cla": "measurement",
  "dev": {
    "mf": "Xiaomi",
    "mdl": "LYWSD03MMC",
    "name": "Temperature/Humidity Sensor 49E0",
    "ids": [
      "A4:C1:38:EB:49:E0"
    ]
  }
}

2 Likes

Thanks everybody! I was able to modify the script @123 wrote to work for my needs! As @koying mentioned, I think the dev object is key. It would be great to get the MQTT Configuration documentation updated, as I’m sure this is a common desire.

Also, let me apologize for not finding these previous conversations. I searched youtube, google, and some here in this forum, but it was difficult finding relevant information applicable to modern home assistant.

Just to recap what I did:

I created a scripts.yaml configuration file according to this page.

In configuration.yaml I added:

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
mqtt: !include mqtt.yaml

In this example, I’m configuring a Home Assistant to read sensor data from Honeywell Security Model 5816 Door/Window Sensor. The output from rtl_433 looks like this:

{
    "time": "2023-06-27 01:02:18",
    "model": "Honeywell-Security",
    "id": 181554,
    "channel": 8,
    "event": 160,
    "state": "open",
    "contact_open": 1,
    "reed_open": 1,
    "alarm": 0,
    "tamper": 0,
    "battery_ok": 1,
    "heartbeat": 0
}

In the new scripts.yaml file, I pasted the following code:

create_sensors:
  alias: "Create sensors via MQTT Discovery"
  sequence:
    - service: mqtt.publish
      data:
        topic: homeassistant/sensor/dw181554reed/config
        retain: true
        payload: >
          {
            "name": "DW181554 Reed",
            "unique_id": "dw181554_reed",
            "state_topic": "rtl_433/Honeywell-Security/181554",
            "value_template": {% raw %}"{{ value_json.reed_open }}"{% endraw %},
            "device": {
                "identifiers": ["dw181554"],
                "name": "DW181554",
                "model": "Model 5816",
                "manufacturer": "Honeywell Security"
            }
          }

    - service: mqtt.publish
      data:
        topic: homeassistant/sensor/dw181554tamper/config
        retain: true
        payload: >
          {
            "name": "DW181554 Tamper",
            "unique_id": "dw181554_tamper",
            "state_topic": "rtl_433/Honeywell-Security/181554",
            "value_template": {% raw %}"{{ value_json.tamper }}"{% endraw %},
            "device": {
                "identifiers": ["dw181554"],
                "name": "DW181554",
                "model": "Model 5816",
                "manufacturer": "Honeywell Security"
            }
          }

    - service: mqtt.publish
      data:
        topic: homeassistant/sensor/dw181554contact/config
        retain: true
        payload: >
          {
            "name": "DW181554 Contact",
            "unique_id": "dw181554_contact",
            "state_topic": "rtl_433/Honeywell-Security/181554",
            "value_template": {% raw %}"{{ value_json.contact_open }}"{% endraw %},
            "device": {
                "identifiers": ["dw181554"],
                "name": "DW181554",
                "model": "Model 5816",
                "manufacturer": "Honeywell Security"
            }
          }

    - service: mqtt.publish
      data:
        topic: homeassistant/sensor/dw181554battery/config
        retain: true
        payload: >
          {
            "name": "DW181554 Battery",
            "unique_id": "dw181554_battery",
            "state_topic": "rtl_433/Honeywell-Security/181554",
            "value_template": {% raw %}"{{ value_json.battery_ok }}"{% endraw %},
            "device": {
                "identifiers": ["dw181554"],
                "name": "DW181554",
                "model": "Model 5816",
                "manufacturer": "Honeywell Security"
            }
          }

    - service: mqtt.publish
      data:
        topic: homeassistant/sensor/dw181554heartbeat/config
        retain: true
        payload: >
          {
            "name": "DW181554 Heartbeat",
            "unique_id": "dw181554_heartbeat",
            "state_topic": "rtl_433/Honeywell-Security/181554",
            "value_template": {% raw %}"{{ value_json.heartbeat }}"{% endraw %},
            "device": {
                "identifiers": ["dw181554"],
                "name": "DW181554",
                "model": "Model 5816",
                "manufacturer": "Honeywell Security"
            }
          }

The script can then be found in Home Assistant Settings > Automations & Scenes > Scripts. Just run it.

And the resulting device looks like this, with an entity for each sensor:

1 Like

For future reference, it’s customary to assign the Solution tag to the post that answers/solves the original question/problem. In this situation, you used the supplied answer and example, then marked your own post with the tag. If everyone did that, all topics would end with the author “solving” their own question/problem.

FAQ guideline 21

Understood. There was an error in the post you linked that required adding the {% raw %} / {% endraw %} tags, which I included in the solution here. I’m just trying to make it easy for others to find the most concise solution. I :heartpulse: your post.

Here’s an issue to update the MQTT Configuration documentation:

(someone else beat me to it)

I just wanted to say thank you, this thread was super informative in helping me do something similar.

One small mention is that the PLC I was working with used a bunch of underscores, dashes and other strange things that made the reference in JSON invalid using the dot method.
For example, where you have:

{{ value_json.reed_open }}

I found it better (and solved all my problems) but using:

{{ value_json['reed_open'] }}

I also had some good results adding a few things to the payload:

            "unit_of_measurement" : "%",
            "icon" :"mdi:water-percent",

Thanks again, it all really helped!

1 Like

Hi,
I’m new to HA. I also try to add my custom device with multiple sensors via MQTT discovery.
The official documentation is just owful - the example json’s are contradictory.

So far I’m going with the eexample ofr “device-based discovery”.

{
  "dev": {
    "ids": "ea334450945afc",
    "name": "Kitchen",
    "mf": "Bla electronics",
    "mdl": "xya",
    "sw": "1.0",
    "sn": "ea334450945afc",
    "hw": "1.0rev2",
  },
  "o": {
    "name":"bla2mqtt",
    "sw": "2.1",
    "url": "https://bla2mqtt.example.com/support",
  },
  "cmps": {
    "some_unique_component_id1": {
      "p": "sensor",
      "device_class":"temperature",
      "unit_of_measurement":"°C",
      "value_template":"{{ value_json.temperature}}",
      "unique_id":"temp01ae_t",
    },
    "some_unique_id2": {
      "p": "sensor",
      "device_class":"humidity",
      "unit_of_measurement":"%",
      "value_template":"{{ value_json.humidity}}",
      "unique_id":"temp01ae_h",
    }
  },
  "state_topic":"sensorBedroom/state",
  "qos": 2,
}

When I publish it device appears immediately but has no sensors.
Also why state_topic is per device, not per sensor. The payload format for this case i not described at all

I really appreciate any help

1 Like

Do you have a recent version of HA?
Component-based discovery has been added in the last couple of releases.

Yes, I downloaded it two days ago:

  • Core: 2024.12.5
  • Supervisor: 2024.12.0
  • Operating System: 14.1
  • Frontend: 20241127.8

If it so fresh I guess it’s not supposed to work :slight_smile:

What do you actually send to the “sensorBedroom/state” topic?

well… before sending anything I was hoping to see that device discovered as it should (show both components aggregated under device name)
But I don’t:

while MQTT log states something that it was disovered and can’t be discovered again, just update:

2024-12-29 21:34:43.299 DEBUG (MainThread) [homeassistant.components.mqtt.client] Received message on homeassistant/sensor/device123/config (qos=0): b'{"dev": {"ids": "ea334450945afc", "name": "Kitchen", "mf": "Bla electronics", "mdl": "xya", "sw": "1.0", "sn": "ea334450945afc", "hw": "1.0rev2"}, "o": {"name": "bla2mqtt", "sw": "2.1", "url": "https://bla2mqtt.example.com/support"}, "cmps": {"some_unique_component_id1": {"p": "sensor", "device_class": "temperature", "unit_of_measurement": "\\u00b0C", "value_template": "{{ value_json.temperature}}", "unique_id": "temp01ae_t"}, "some_unique_id2": {"p": "sensor", "device_class": "humidity", "unit_of_measurement": "%", "value_template": "{{ value_json.humidity}}", "unique_id": "temp01ae_h"}}, "state_topic": "sensorBedroom/state", "qos": 2}'
2024-12-29 21:34:43.300 DEBUG (MainThread) [homeassistant.components.mqtt.discovery] Process component discovery payload {'state_topic': 'sensorBedroom/state', 'qos': 2, 'device': {'serial_number': 'ea334450945afc', 'model': 'xya', 'name': 'Kitchen', 'sw_version': '1.0', 'hw_version': '1.0rev2', 'manufacturer': 'Bla electronics', 'identifiers': 'ea334450945afc'}, 'origin': {'name': 'bla2mqtt', 'sw_version': '2.1', 'support_url': 'https://bla2mqtt.example.com/support'}, 'components': {'some_unique_component_id1': {'device_class': 'temperature', 'unit_of_measurement': '°C', 'value_template': '{{ value_json.temperature}}', 'unique_id': 'temp01ae_t', 'platform': 'sensor'}, 'some_unique_id2': {'device_class': 'humidity', 'unit_of_measurement': '%', 'value_template': '{{ value_json.humidity}}', 'unique_id': 'temp01ae_h', 'platform': 'sensor'}}}
2024-12-29 21:34:43.300 DEBUG (MainThread) [homeassistant.components.mqtt.discovery] Component has already been discovered: sensor device123, sending update from external application bla2mqtt, version: 2.1, support URL: https://bla2mqtt.example.com/support
2024-12-29 21:34:43.300 DEBUG (MainThread) [homeassistant.components.mqtt.entity] Got update for entity with hash: ('sensor', 'device123') '{'state_topic': 'sensorBedroom/state', 'qos': 2, 'device': {'serial_number': 'ea334450945afc', 'model': 'xya', 'name': 'Kitchen', 'sw_version': '1.0', 'hw_version': '1.0rev2', 'manufacturer': 'Bla electronics', 'identifiers': 'ea334450945afc'}, 'origin': {'name': 'bla2mqtt', 'sw_version': '2.1', 'support_url': 'https://bla2mqtt.example.com/support'}, 'components': {'some_unique_component_id1': {'device_class': 'temperature', 'unit_of_measurement': '°C', 'value_template': '{{ value_json.temperature}}', 'unique_id': 'temp01ae_t', 'platform': 'sensor'}, 'some_unique_id2': {'device_class': 'humidity', 'unit_of_measurement': '%', 'value_template': '{{ value_json.humidity}}', 'unique_id': 'temp01ae_h', 'platform': 'sensor'}}}'
2024-12-29 21:34:43.300 DEBUG (MainThread) [homeassistant.components.mqtt.entity] Ignoring unchanged update for: sensor.mqtt_sensor
2024-12-29 21:34:43.300 DEBUG (MainThread) [homeassistant.components.mqtt.discovery] Pending discovery for ('sensor', 'device123'): deque([])

I didn’t find a word on discovery doc page about how payload to state topic should look like. So I dont’t send andything

Update
Finally I got it working!
Apparently discovery topic must be

<prefix>/device/<id>/config

not

<prefix>/sensor/<id>/config

:man_facepalming:

2 Likes

hello everyone,
i try to use this example,but the device doesn’t appear.
can someone explain,how to insert an entire device in mqtt entities?
i need to insert an entities with a windows and a switch
thank you

can someone explain,how to insert an entire device in mqtt entities?

Are you writing your own MQTT device that will also publish Discovery messages?

This works:

I’ve created a garage door device that combines a 2 channel relay (Tasmota) and 2 door sensors (ZigBee2MQTT) into a single device called GarageDoor. In my case auto discovery for Tasmota and Zigbee2MQTT is turned off. The 2 door sensors are the top and the bottom of the door so I can tell if it is open or closed.

Only one device appears in the list of devices and that is “GarageDoor”. When you click on the device you can see the 2 door sensors and their battery levels.

In addition to what is shown below there are some automations that are triggered by changes in the door sensor states. These automations publish the door state ( open, closed, closing and opening) to MQTT topic virt/Garage-Door/STATE based on the sensor states.

Here is the configuration:

configuration.yaml

mqtt: !include mqtt.yaml

mqtt.yaml

binary_sensor: !include_dir_merge_list MQTT/BinarySensor
cover: !include_dir_merge_list MQTT/Cover
sensor: !include_dir_merge_list MQTT/Sensor

MQTT/Cover/GarageDoor.yaml

- availability:
  - payload_available: Online
    payload_not_available: Offline
    topic: tele/Garage-Door/LWT
  command_topic: cmnd/Garage-Door/EVENT
  device:
    configuration_url: http://esp-020.local/
    identifiers:
    - GarageDoorSwitch
    - GarageDoor
    manufacturer: Terry
    model: RollerDor
    name: GarageDoor
    suggested_area: Garage
  device_class: garage
  name: Garage Door
  object_id: garagedoor_cover
  origin:
    name: Terry
  payload_close: Close
  payload_open: Open
  state_closed: closed
  state_closing: closing
  state_open: open
  state_opening: opening
  state_stopped: stopped
  state_topic: virt/Garage-Door/STATE
  unique_id: GarageDoor_Tasmota
  value_template: '{{ value_json.state }}'

MQTT/Sensor/BottomSensor.yaml

- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - BottomSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: battery
  enabled_by_default: true
  entity_category: diagnostic
  name: Bottom Battery
  object_id: doorbottom_battery
  origin:
    name: Terry
  state_class: measurement
  state_topic: zigbee2mqtt/BottomSensor
  unique_id: BottomSensor_battery_zigbee2mqtt
  unit_of_measurement: '%'
  value_template: '{{ value_json.battery }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - BottomSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  enabled_by_default: false
  entity_category: diagnostic
  icon: mdi:signal
  name: Bottom Linkquality
  object_id: doorbottom_linkquality
  origin:
    name: Terry
  state_class: measurement
  state_topic: zigbee2mqtt/BottomSensor
  unique_id: BottomSensor_linkquality_zigbee2mqtt
  unit_of_measurement: lqi
  value_template: '{{ value_json.linkquality }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - BottomSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: voltage
  enabled_by_default: false
  entity_category: diagnostic
  name: Bottom Voltage
  object_id: doorbottom_voltage
  origin:
    name: Terry
  state_class: measurement
  state_topic: zigbee2mqtt/BottomSensor
  unique_id: BottomSensor_voltage_zigbee2mqtt
  unit_of_measurement: mV
  value_template: '{{ value_json.voltage }}'

MQTT/Sensor/TopSensor.yaml

- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - TopSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: battery
  enabled_by_default: true
  entity_category: diagnostic
  name: Top Battery
  object_id: doortop_battery
  origin:
    name: Terry
  state_class: measurement
  state_topic: zigbee2mqtt/TopSensor
  unique_id: TopSensor_battery_zigbee2mqtt
  unit_of_measurement: '%'
  value_template: '{{ value_json.battery }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - TopSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  enabled_by_default: false
  entity_category: diagnostic
  icon: mdi:signal
  name: Top Linkquality
  object_id: doortop_linkquality
  origin:
    name: Terry
  state_class: measurement
  state_topic: zigbee2mqtt/TopSensor
  unique_id: TopSensor_linkquality_zigbee2mqtt
  unit_of_measurement: lqi
  value_template: '{{ value_json.linkquality }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - TopSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: voltage
  enabled_by_default: false
  entity_category: diagnostic
  name: Top Voltage
  object_id: doortop_voltage
  origin:
    name: Terry
  state_class: measurement
  state_topic: zigbee2mqtt/TopSensor
  unique_id: TopSensor_voltage_zigbee2mqtt
  unit_of_measurement: mV
  value_template: '{{ value_json.voltage }}'

MQTT/BinarySensor/BottomSensor.yaml

- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - BottomSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: battery
  entity_category: diagnostic
  name: Bottom Battery
  object_id: doorbottom_battery_low
  origin:
    name: Terry
  payload_off: false
  payload_on: true
  state_topic: zigbee2mqtt/BottomSensor
  unique_id: BottomSensor_battery_low_zigbee2mqtt
  value_template: '{{ value_json.battery_low }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - BottomSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: door
  name: Bottom
  object_id: doorbottom_contact
  origin:
    name: Terry
  payload_off: true
  payload_on: false
  state_topic: zigbee2mqtt/BottomSensor
  unique_id: BottomSensor_contact_zigbee2mqtt
  value_template: '{{ value_json.contact }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - BottomSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: tamper
  name: Bottom Tamper
  object_id: doorbottom_tamper
  origin:
    name: Terry
  payload_off: false
  payload_on: true
  state_topic: zigbee2mqtt/BottomSensor
  unique_id: BottomSensor_tamper_zigbee2mqtt
  value_template: '{{ value_json.tamper }}'

MQTT/BinarySensor/TopSensor.yaml

- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - TopSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: battery
  entity_category: diagnostic
  name: Top Battery
  object_id: doortop_battery_low
  origin:
    name: Terry
  payload_off: false
  payload_on: true
  state_topic: zigbee2mqtt/TopSensor
  unique_id: TopSensor_battery_low_zigbee2mqtt
  value_template: '{{ value_json.battery_low }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - TopSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: door
  name: Top
  object_id: doortop_contact
  origin:
    name: Terry
  payload_off: true
  payload_on: false
  state_topic: zigbee2mqtt/TopSensor
  unique_id: TopSensor_contact_zigbee2mqtt
  value_template: '{{ value_json.contact }}'
- availability:
  - topic: zigbee2mqtt/bridge/state
  device:
    identifiers:
    - TopSensor
    - GarageDoor
    manufacturer: TuYa
    model: Door sensor (TS0203)
    name: GarageDoor
    suggested_area: Garage
    via_device: zigbee2mqtt_bridge_0x00124b001cde4f30
  device_class: tamper
  name: Top Tamper
  object_id: doortop_tamper
  origin:
    name: Terry
  payload_off: false
  payload_on: true
  state_topic: zigbee2mqtt/TopSensor
  unique_id: TopSensor_tamper_zigbee2mqtt
  value_template: '{{ value_json.tamper }}'

Hopefully this should show you how you can provision complex devices via MQTT configurations files.
NOTE: Not everyone will like the way I’ve split everything up into separate files so you can combine everything into a single file if that is what you prefer.

1 Like