Json templating with newline

Hi all,

I am attempting to parse a string that is received by an MQTT sensor into a ‘state’ and then relevant attributes. However I am struggling with the fact that the message received has a newline \n which I think is messing things up.

The input string being received via MQTT is: (changed) 20.00\n(into ) 17.80.
I am attempting to set the state of the MQTT sensor to be 17.80 and the attributes to have a NewValue 17.80 and an OldValue 20.00.

This is the configuration of my MQTT sensor:

  - name: Test
    state_topic: test/test
    qos: 2
    value_template: >-
      {{ value | regex_findall_index('(?<=\(into \) ).*') }}
    json_attributes_topic: test/test
    json_attributes_template: >-
      {{ (value |
      replace('(changed) ', '{OldValue:') |
      replace('\n', '') |
      replace('(into ) ', ',NewValue:') + '}') |
      to_json }}

The value_template works as expected and correctly extracts the state.

However I am stuck on getting the attributes to parse correctly. I am attempting to convert them to json so that they can be ingested by HA.

The json_attributes_template in my config above produces exactly the correct output when using the interactive template helper thingy in HA. However it does not seem to apply to attributes to the sensor.
I know that the format it produces is correct, because when I set the json_attributes_template to be that exact value, it parses correctly and HA recognises it.

I’m quite certain that it is the \n that is causing the issues, as my tests on input data without the \n work fine. Does anyone know how to combat this (as I do not have any control over the presence of the \n in the MQTT once this is all up and running.

It seems that including or excluding the final to_json has no bearing on the issue as it currently stands.

Thanks in advance!

Don’t know if this is the answer, but “proper” JSON has quotes in it, and it may be |from_json that you want.

This shows the template editor recognising the output as a dictionary object (showing single quotes in place of the double quotes I used and some spacing, evidencing that it’s not just a string). Try that and report back?

{{ (value |
      replace('(changed) ', '{"OldValue":"') |
      replace('\n', '"') |
      replace('(into ) ', ',"NewValue":"') + '"}') |
      from_json }}

I like your thinking!
But after giving it a try, still the same result :cold_sweat:

This works:

- name: Test
  state_topic: test/test
  qos: 2
  value_template: >-
    {{ value | regex_findall_index('(?<=\(into \) ).*') }}
  json_attributes_topic: test/test
  json_attributes_template: >-
    {% set numbers = value|regex_findall('([\d\-\.]+)') %}
    {{ {"OldValue":numbers[0],"NewValue":numbers[1]}|to_json }}
troon@pi:~$ mosquitto_pub -h 192.168.1.7 -t test/test -m "(changed) 20.00\n(into ) 17.80"


EDIT: updated the template regex_findall to include the minus sign to allow for negative numbers.

1 Like

It does!

Legend! :heart_eyes:

1 Like