Parse data from one sensor to another

Hi guys, I might have asked that question before in deferent flavours, but that’s because I never really got it to work…(edited)

I have a sensor with the following data: “{‘Timer1’: {‘Arm’: 1, ‘Mode’: 0, ‘Time’: ‘06:30’, ‘Window’: 0, ‘Days’: ‘1111111’, ‘Repeat’: 1, ‘Output’: 1, ‘Action’: 1}}”

I want to parse that data to JSON and put it in another sensor as attributes. is it possible?

Assuming that the problem is the fancy single quotes and that this is not just a cut/paste formatting error* you need to replace them with double quotes, then it is a valid JSON string according to an on-line parser I tried:

This template sensor will do that, but you have not given anywhere near the amount of information required to complete this fully so you will have to fill in the blanks.

- platform: template
  sensors:
    a_sensor_containing_a_json_attribute:
      friendly_name: "A sensor containing a JSON attribute"
      value_template: "{{states('sensor.where_the_value_comes_from') }}"
      attribute_templates: >-
        the_jason_string: >-
          {{ states('sensor.original_sensor_object_id').replace('’','"').replace('‘','"') }}

You need to change and or add:

a_sensor_containing_a_json_attribute: # the name you want to call the new sensor, likewise with the friendly name

sensor.where_the_value_comes_from # the sensor you want to add the attribute to. You’re actually making a new sensor. You can’t add an attribute to the existing one.

the_jason_string # replace with the name you want to call the attribute.

sensor.original_sensor_object_id # the sensor that contains the JSON string you want to add.

*If the fancy single quotes are due to a cut/paste formatting error you need to learn how to format your post correctly. See point 11 here: How to help us help you - or How to ask a good question In which case the attribute template becomes:

      attribute_templates: >-
        the_jason_string: >-
          {{ states('sensor.original_sensor_object_id').replace("''","\"") }}

This replaces single quotes with double quotes in the JSON string.

Hi, you were correct the first time. it is a single quotes that came from the device I reading.

I understood what you wrote and heading to try them right away.

One more question. the data is there in a very specific time… that means I nead the parsing to happen as an automation. otherwise everytime the data change in the source it will change in the template sensor as well.
How can I do that in an automation?

THANKS!

1 Like

Is the >- needed there? The documentation’s example doesn’t use it.

FWIW I was going to provide an example I have for an MQTT Sensor then discovered that the Template Sensor doesn’t define attributes the same way.

No it is not. Well spotted.

Corrected:

      attribute_templates:
        the_jason_string: >-
          {{ states('sensor.original_sensor_object_id').replace("''","\"") }}

Do you reckon that quote escaping is correct in the replace function?

The single quote escaping (with another single quote) is. I’ve used it before. Just not sure about the double quote.

Curiously, the single-quote escaping didn’t work for me. However, two other variations did work.

{% set x = "'hello' 'world'" %}

A) {{ x.replace("''","\"") }}

B) {{ x.replace("'",'"') }}

C) {{ x.replace("'","\"") }}

1 Like

Strange. I have used it before:

Also I wasn’t aware B) was allowed. Good to know I can mix quotes like that.

what’s making the sensor? I’d like to see that yaml. I have solutions, but until I see that intial setup, I won’t be able to make the simplest solution for you.

It appears that in this particular case, the two sequential single-quotes are interpreted literally and not escaped.

This version demonstrates how escaping is required.

{% set x = "'hello' 'world'" %}

{{ x.replace('\'',"\"") }}

It depends on what is chosen to delimit the string. Using the same delimiter within that string will require it to be escaped.

1 Like

Is there any preference between .replace() and |replace()

Seems to work the same way for me. I typically use .replace but that’s just habit.

The data is coming from a tasmota sonoff. this is the timer info.

Is this discovered automatically or did you configure it?

@petro
I trigger the data by posting MQTT message “Timer1”, and the information is than posted in the stat/results topic. I collect that from there

@tom_l
Two questions:

  1. Can do that in automation? the data is there in a very specific time… that means I nead the parsing to happen as an automation. otherwise everytime the data change in the source it will change in the template sensor as well.
  2. There are more than one attribute in the data. how can I iterate on all the string?

Ok, So you post this to an MQTT Topic…

And then is that MQTT topic Auto discovered? I feel like you aren’t reading my response and giving the least amount of information.

  1. Do you have a configuration for this device?
  2. Is it discovered?

Seeing that these 2 questions somehow escape your mind, I will offer a solution that I think will work.

Configure (Not Discover) the mqtt sensor. Use this configuration for the sensor. BTW, this is literally the example in the documentation doing exactly what you want.

  - platform: mqtt
    name: "Timer 1"
    state_topic: "tele/sonoff/sensor"
    value_template: "{{ value_json.Timer1.Arm }}"
    json_attributes_topic: "tele/sonoff/sensor" #< ----- CHANGE THIS TO YOUR DEVICE TOPIC.
    json_attributes_template: "{{ value_json.Timer1 | tojson }}"

It will create a sensor: sensor.timer_1 that will contain the state equal to the arm value. and the attributes will be: arm, mode, time, window, days, repeat, output, and action.

So if you want to create any separate sensor with that information, you’ll make a template sensor using the following code, but changing the attribute.

  - platform: template
    sensors:
      time_1_mode:
        friendly_name: Timer 1 Mode
        value_template: "{{ state_attr('sensor.timer_1','Mode') }}"

Hi @petro,

Ill try to ellaborate…

There is no way to pull the timer data directly. It is not posted in any topic as default so I can pull it.
The only way is to post a message to ‘cmnd/timer1’, and the data is then posted in the topic ‘stat/results’.

Now, I cant put a constant sensor on the ‘stat/results’ topic, since the result of every command is posted there. So I need to time this… send the command, and only then go and collect the data.

Now, I tried what you suggested before, but I got an error in the log saying it is not a JSON data, and now I know why.

So the task is like this:

  1. Trigger the ‘cmnd/timer1’ command every 15 minutes (Done)
  2. collect the data from ‘stat/results’ (Done)
  3. replace the quotes
  4. put the new data as a JSON template with attribute

I hope I managed to give all the info I have. sorry…
and thanks again for your patience.

BTW, the example from the documentation is wrong. there is no topic ‘tele/sonoff/sensor’… so the data cannot be pulled as explained above

You have to change it to whatever topic your results are posted from. It’s not a copy paste example. It’s showing you what it could look like.

Notice how the comment says:

Humor me and please take a screenshot of the developer tools → template page with the following code: CHANGE THE ENTITY_ID IN THE CODE TO YOUR stat/results ENTITY. Also make sure you push the correct result to the sensor before taking the screenshot.

{{ states('sensor.xxxx') }}

Hi,
I triggered the command and after the result appeared on the sensor.
this is the screenshot:

The problem is that the info on that sensor can change because every time I issue a command the result is posted there.
Thats why I wanted to do it in automation, so I collect the data only after yriggering the result I need

Hi, I also tried to parse the incoming data, and HA refused to load because of something similar to what you wrote.
After the following line:

value_template: "{{ value_json.replace'\'',"\"" }}"

I get that in the log:

ERROR (SyncWorker_0) [homeassistant.util.yaml.loader] while scanning a double-quoted scalar

After some playing with the text, I am sure it because of the double brackets there.

What do I need to change for the line to be accepted?

Thanks!

Please read the link I posted on formatting your code properly. You need to use code blocks not quote. It is messing up your quotation marks and leads to confusion.