Why device map only works with discovey and not within yaml?

I am started to use home assistant and got the whole mqtt device thing working. But what I dont get is why I can only create mqtt entities via yaml configuration and not a device map for these (as its written in the docs).

Ive create a small node app witch reads the yaml and sends the entities with device map via mqtt. It works and does what I want, but why isnt the same possible via yaml config?

Short answer - design choice.

Long answer - it’s more likely that software publishing the required Discovery topics will pick unique identifiers. Humans typing it in YAML are less likely to manage that.

Understood.

But the downside is that its not possible to create a (git) versioned configuration of you smart hone system.

And also I bet that most system currently dont support MQTT discovery and so it requires hacks like mine with the node app (witch is mostly useless).

That’s not necessarily a limitation because you can use a script to create entities via MQTT Discovery.

I explained the process in this post (and it’s what I have used to create all of my MQTT-based entities and related devices which don’t natively support MQTT Discovery):

It’s simple and easy.

1 Like

Sure it is. I’ve been pushing my config to git for years, I could grab any of those versions if I wanted to.

If you want a 100% manually configured platform then, bluntly, HA isn’t a good option for you. Something like OpenHAB may suit you better.

It’s entirely possible. If you’re just creating sensors, you can use the scripts I created in combination with an automation. It’s only built for timestamp sensors but any of the device_classes would work and adding unit_of_measurement wouldn’t be hard.

Script

mqtt_automated_states:
  sequence:
  - variables: &mqtt-variables
      root: "homeassistant"
      topic_root: >
        {%- if domain is not defined or unique_id is not defined %}
          {{- [ root, 'error'] | join('/') }}
        {%- else %}
          {{- [ root, domain, unique_id ] | join('/') }}
        {%- endif %}
  - service: mqtt.publish
    data:
      topic: "{{ topic_root ~ '/state' }}"
      payload: >
        {{ { 'state': state, 'attributes': attributes | default({}) } | tojson }}
      retain: "{{ retain | default('true') }}"

mqtt_automated_config:
  sequence:
  - variables:
      name: >
        {{ unique_id | replace('_', ' ') | title }}
      <<: *mqtt-variables
      payload: >
        {%- set items = [
          ( "name", name),
          ( "unique_id", unique_id),
          ( "state_topic", topic_root ~ "/state"),
          ( "value_template", "{{ value_json.state }}"),
          ( "json_attributes_topic", topic_root ~ "/state"),
          ( "json_attributes_template", "{{ value_json.attributes | tojson }}"),
          ( "device_class", device_class ),
        ] %}
        {% set ns = namespace(items=[]) %}
        {%- for k, v in items %}
          {%- if v is defined %}
            {%- set ns.items = ns.items + [ '"{}": "{}"'.format(k, v) ] %}
          {%- endif %}
        {%- endfor %}
        {{ ("{" ~ ns.items | join(', ') ~ "}") }}
  - service: mqtt.publish
    data:
      topic: "{{ topic_root ~ '/config' }}"
      payload: "{{ payload | tojson }}"

use

On startup this creates discovery for a bunch of door timestamps so I know the last time a door opened. I’m just providing it with unique_id and the rest is set up through the defaults in the script. YOu can change the device class to temperature or anything else. Or adjust the script above for unit_of_measurement (which I can help you with) and add a unit of measurement.

- alias: Doors - MQTT Discovery on Startup
  id: mqtt_store_door_states_discovery
  mode: single
  trigger:
  - platform: homeassistant
    event: start
  variables:
    doors:
    # - test_door_last_opened
    - main_door_last_opened
    - sliding_door_last_opened
    - garage_door_tilt_last_opened
    - garage_entry_door_last_opened
    - rear_garage_door_tilt_last_opened
  action:
  - repeat:
      count: "{{ doors | length }}"
      sequence:
      - service: script.mqtt_automated_config
        data:
          domain: sensor
          unique_id: "{{ doors[repeat.index - 1] }}"
          device_class: timestamp

Then if you want to update the sensor from HA instead of the sensor itself you can use this service:

  - service: script.mqtt_automated_states
    data:
      domain: sensor
      unique_id: "{{ unique_id }}"
      state: "{{ timestamp }}"
      attributes: "{{ { 'who': who, 'count': count, 'source': source, 'count_timestamp': count_timestamp } | tojson }}"

attributes can be a yaml dictionary and you just need to provide the proper unique ID that you set on startup.