Mqtt split json data to variables

Hi!
Beginner regarding yaml/json and trying to achieve this: from a json like

[{“id”:31,“type”:0,“data”:65535}] (one variable) or
[{“id”:2,“type”:3,“data”:82},{“id”:2,“type”:1,“data”:21}] (two variables)

I want to put data in variables depending of the unique id

I have managed to catch one variable with code below:

mqtt:
sensor:
- name: “FDRS Node 31 id”
state_topic: “fdrs/data”
value_template: “{{ (value | from_json)[0].id }}”

- name: "FDRS Node 31 data"
  state_topic: "fdrs/data"
  value_template: "{{ (value | from_json)[0].data }}"

But without selecting on id. I have tried a number of approches but can’t get any to work. Can anyone point me in the direct direction what approach to use ?

Best Regards Håkan

Try this in Developer Tools / Template and play with it to get what you want:

{% set value = [{"id":2,"type":3,"data":82},{"id":2,"type":1,"data":21}]|to_json %}
{{ value|from_json|selectattr('id','eq',2)|first }}
{{ (value|from_json|selectattr('id','eq',2)|first)['data'] }}

Not sure what you mean by “unique ID” when the second example has two id: 2 items…

Thanks for such quick reply!

- name: "FDRS Node 31 data"
  state_topic: "fdrs/data"
  value_template: "{{ (value_json | selectattr('id','eq',31) | list | first).data}}"

The unique id is 2 in the case with two variables and 31 in the case with one variable, thats the one I need to catch to separate what sensor sending data

Understood. Do you have what you need now?

Creates sensor but data unknown. What about the example with two var’s ?

Please post the correctly-formatted YAML for the sensor you currently have. See here for formatting instructions:

How do you want the two variables recorded? Separate sensors?

Works for me

Obviously, you have to have a “differentiator”, here different ids

Thank’s ALL for help. I apologize if I given you the impression that I wan’t you to write code for me ! The suggestions you have given me has pointed me in the right direction and I
will try to solve how to deal with the fact that some sensors have one and others can have.two or more variables. If possible have all variable’s for a sensor belonging to a unit with entities.

Hope code is correct formatted below


    - name: "FDRS Node 5 data test"
      state_topic: "fdrs/data"
      value_template: "{{ (value_json | selectattr('id','eq',5) | list | first).data}}"
[{"id":31,"type":0,"data":65535}]

[{"id":2,"type":3,"data":57},{"id":2,"type":1,"data":21}]

Regards Håkan

Got it but howto load set json = .... with incoming data without hardcoding as in your example ?

You use value_json — see here:

An “entity” (sensor) in HA has one and only one “state” (=value).
It can have attributes, which are “secondary” values. See

Now managed to separate values filtering on id and type and data is nicely incoming BUT another problem now is that values are not sustained, shows up for a second or so and entity is blank until another data arrives from Lora DHT node. Data from mcp23017 Node shows up ok. I suspect it has to do with map(attribute='data') | list | first

#FDRS      This text will be hidden
#mcp23017 node
    - name: "FDRS Node 31 data"
      state_topic: "fdrs/data"
      value_template: "{{ (value_json | selectattr('id','eq',31) | list | first).data}}"

#Lora DHT node
    - name: "FDRS Node 2 humidity"
      state_topic: "fdrs/data"
      value_template: "{{ value_json | selectattr('id', 'eq', 2) | selectattr('type', 'eq', 3) | map(attribute='data') | list | first }}"
    - name: "FDRS Node 2 temperature"
      state_topic: "fdrs/data"
      value_template: "{{ value_json | selectattr('id', 'eq', 2) | selectattr('type', 'eq', 1) | map(attribute='data') | list | first }}" 

Am I missing something in the value_template ?

Read and googled a’lot but can’t find a solution

Best Regards Håkan

OK, so the topic is sending data for id 31 and updating the 31 sensor, then when it sends for id 2, the 31 sensor goes blank? Try this:

    - name: "FDRS Node 31 data"
      state_topic: "fdrs/data"
      value_template: >
        {% set fdrs_list = value_json|selectattr('id','eq',31)|list %}
        {% if fdrs_list %}
          {{ fdrs_list[0]['data'] }}
        {% else %}
          {{ this.state }}
        {% endif %}

and similarly for the other sensor(s).

The this.state in the else carries over the prior state if the list of items with id 31 is empty.

Hi
Maybe I was unclear. Sensor 31 works ok all the time. The problem is with
Sensor 2, sending two variables that briefly shows data and then goes blank until new value arrives. I have tried with an automation ( se below) and it stores the first value but never updates, so this isn’t working.

input_number:
  my_sensor_value:
    name: FDRS_2_temp
    min: -0
    max: 100
    step: 1    





automation:
  - alias: Update FDRS_2_temp
    trigger:
      platform: mqtt
      topic: "fdrs/data"
    action:
      service: input_number.set
      target:
        entity_id: input_number.my_sensor_value
      data:
        value: "{{ trigger.payload_json | selectattr('id', 'eq', 2) | selectattr('type', 'eq', 1) | map(attribute='data') | list | first }}"
    

fdrs_visible
fdrs_invisible

I think we understood you, and Troon provided you the solution.
If a new value for an id (be it 31 or 2, the idea is the same) is not in the topic payload, just keep the previous value.

1 Like

Thank you both for excellent help. It works now and I’ve learned a’lot from you :+1: