Parse sensor state as json

Hello everyone,
i have an Aqara Smart Pet Feeder C1, connected over Zigbee2Mqtt

Zigbee2Mqtt provides a ‘schedule’ sensor with following state:
[{'days': 'everyday', 'hour': 7, 'minute': 30, 'size': 2}, {'days': 'everyday', 'hour': 13, 'minute': 30, 'size': 1}, {'days': 'everyday', 'hour': 20, 'minute': 0, 'size': 2}]

The amount of elements in array can vary depending on program.
It looks ugly when shown in a card, so i wanted to somehow parse it and print in a better readable form:

{% set jsn = states('sensor.catfeeder_schedule') %}

{% for i in range(jsn | length) %}
   {{ jsn[i]['days'] }}, {{ jsn[i]['hour'] }}
{% endfor %}

But the problem is ‘jsn’ is a string, and jsn | length is not 3 but somewhat 170+ (amount of characters in a string). I tried to use
{% set jsn = states('sensor.catfeeder_schedule') | to_json%}
but it doesn’t work either.

Is there any way to convert string to json object? or maybe just better way to get it like
everyday at 7 30, size 2
everyday at 13 30, size 2

Your code worked fine for me:

Probably because you declare your variable as json array, and states(‘’) returns a string. I also tried it like you, it works. But as soon as ‘states’ is used it doesn’t work anymore.
My output looks like this:

,

,

,

repeated 170+ times :slight_smile:

Right so the first thing - is are you absolutely certain that the state is actually the full json? because states have a maximum length of 250. My suspicion is that the JSON is being truncated to fit in the state limit of the sensor.

JSON should be stored as an attribute in a sensor, not as a state.

I suspect that if you paste {{ states('sensor.catfeeder_schedule') }} into template editor, you will see the JSON is not complete.

1 Like

I know it should be “from_json” instead of “to_json”, but I’m noodling on it now to see. All variants of converting a string from JSON are saying the JSON is invalid, but it isn’t.

Yep, i am sure it is a full JSON at this point.
It also has around 170 characters so it is not truncated.
And yes, of course i printed it when debugging :slight_smile:

I don’t know why zigbee2mqtt provides this info like state, but probably i can not change it that easy, default behaviour.

So probably this sensor doesn’t make much sense if json could be truncated to 250…

I’d just create a template sensor, using that zigbee2mqtt sensor’s topic as an mqtt trigger.
Give it a state of anything from OK, to the time.
Then store the entire JSON string as an attribute under the key schedule.

template:
  trigger:
    - platform: mqtt
      topic: /path/to/thesensor
  sensor:
    - name: Cat Feeding Schedule
      state: "OK"
      attributes:
        schedule: "{{ trigger.payload_json }}"

Something like that.

1 Like

I didn’t even know there was a Zigbee cat feeder out there, I just ordered one to see how it works on ZHA versus the mqtt packet.

I’ve re-read this multiple times now, just to be sure I am not missing something.
…erm…
Unless I’m missing something… a Zigbee cat feeder (or any device), wouldn’t be talking to the ZWave JS server…

Did you mean ZHA?

LOL, yes I did mean ZHA :slight_smile:

1 Like

Try this:

{% set jsn = "[{'days': 'everyday', 'hour': 7, 'minute': 30, 'size': 2}, {'days': 'everyday', 'hour': 13, 'minute': 30, 'size': 1}, {'days': 'everyday', 'hour': 20, 'minute': 0, 'size': 2}]" | replace('\'', '"') | from_json  %}

{% for i in range(jsn | length) %}
   {{ jsn[i]['days'] }}, {{ jsn[i]['hour'] }}
{% endfor %}

image

The JSON is actually malformed with single quotes instead of double quotes.

2 Likes

Good catch, the posted JSON does not parse on any online JSON parser. But

[{"days": "everyday", "hour": 7, "minute": 30, "size": 2}, {"days": "everyday", "hour": 13, "minute": 30, "size": 1}, {"days": "everyday", "hour": 20, "minute": 0, "size": 2}]

Does parse fine.

Like I said, I had to noodle on that for a while and it suddenly dawned on me that you had single quotes in your string.

Thanks! Now it works! :+1:

1 Like