I have a rest sensor reading from a camera. It is creating the json as a state
In the template editor I can see the value:
{% set my_test_json = states('sensor.motion_test') %}
{{ my_test_json }}
Which returns:
[
{
"cmd" : "GetMdState",
"code" : 0,
"value" : {
"state" : 0
}
}
]
I just don’t seem to be able to extract the state…
tom_l
October 13, 2019, 6:44am
2
How about this in the restful sensor config:
value_template: '{{ value_json.value.state }}'
Error rendering template: UndefinedError: ‘str object’ has no attribute ‘value’
tom_l
October 13, 2019, 6:48am
4
I wonder if it is because ‘value’ is a reserved word.
Try:
value_template: '{{ value_json.[2].[0] }}'
same error.
You can use
{% set my_test_json = [ { “cmd” : “GetMdState”, “code” : 0, “value” : { “state” : 0 } } ] %}
{{ my_test_json.[2].[0] }}
is you want to try a few things.
1 Like
tom_l
October 13, 2019, 7:04am
6
Got it.
{{ my_test_json.0.value.state }}
It was the top level list ‘[…]’ stuffing it up.
1 Like
f’k me! I swear I have been screwing around for f’king HOURS
1 Like
tom_l
October 13, 2019, 7:06am
8
Always handy to have an extra pair of eyes. This place is great for that.
1 Like
Also tried removing the [ and ] with replace but doesn’t work. Also tried string…
nope.
This is eerily familiar:
I Think I need some help from the python gurus on here.
I’ve been trying for a couple of days now to figure out why what I’m trying to do isn’t working and I’m obviously missing something.
I would like to take the output of a custom component that creates an attribute and parse the result to extract certain keys.
I’ve copied the text of the attribute exactly as it is into the template editor and I can dig into it and get out exactly what I want. So that’s all good.
But when I use the same sy…
The string is coming from here:
- platform: rest
resource: http://192.168.1.44/api.cgi?cmd=GetMdState&user=admin&password=xxxxx
name: motion_test
@pnbruckner @petro feel free to weigh in.
tom_l
October 13, 2019, 8:15am
11
Try this:
{{ states('sensor.motion.test') |regex_findall_index('\d', index=1) }}
petro
(Petro)
October 13, 2019, 12:06pm
12
Tom’s solution will always get the 2nd digit, I.E. The digit after the word state. If the shape of the object changes, that won’t work. If you wan’t to ensure that you always get the state…
{% set value = my_test_json | regex_findall_index('\"state\" : \d+', index=0) %}
{{ value.split(':')[-1].strip() }}
This is finding the first instance of the phrase "state" : <number>
. Then, we split the returned value on the colon. Select the last value (the number), and remove the extra white space.
EDIT: This of course assumes that the state is a string. If you change your rest sensor… you can have it just plop out that value.
- platform: rest
resource: http://192.168.1.44/api.cgi?cmd=GetMdState&user=admin&password=xxxxx
name: motion_test
value_template: "{{ value_json[0].value.state }}"
json_attributes:
- 0
This should put the whole object as a 0 attribute. Don’t know if that portion will work, never tried it. If it does work, your attributes will be accessible as json object too.
Last EDIT: I think we need a PR that depreciates json_attributes and replaces it with json_attributes_template, like MQTT sensors. There are too many of these topics that return a list of objects and that would require a template to extract.
1 Like
Thanks @petro
Is there a way I can make the rest sensor write the whole text string like a normal rest sensor rather than just that one attribute?
petro
(Petro)
October 14, 2019, 12:43am
14
don’t think so, that’s why we need an update to json_attributes as a template.
What I don’t understand… in Tom’s example he used index 1 and you use index 0 - this is very fuzzy… both work but I’m not 100% sure I understand why… (well I’m 100% sure I don’t understand actually)
What if I wanted the value of the cmd or code?
tom_l
October 14, 2019, 1:05am
16
Because my expression was very sloppy and returned 2 results. Petro’s regex is more exact and will only return one result.
hmm… ok… what if I want the value of “cmd” - even from the docs I don’t understand what the regex_findall_index is doing
123
(Taras)
October 14, 2019, 1:27am
18
FWIW, you can use a capturing group within the regex pattern to pluck out the desired value directly.
{{ my_test_json | regex_findall_index('\"state\" : (\d+)') }}
The regex pattern is:
\"
escape the meaning of a double-quote and match it
state
match the literal word state
\"
escape the meaning of a double-quote and match it
:
match literal space followed by a colon followed by another space
(\d+)
everything matched within the parentheses will be captured. The pattern within the parentheses will match one or more digits.
So if fed a string like this:
blablabla"state" : 12345abcdefg
it will return 12345
When given your example, it returns 0
as shown in the following screenshot from regex101.com
1 Like
so \d+ means it’s looking for digits? what if I wanted text? like the value of “cmd”?
just saw your edit… I’ll play on that site there! thanks.
123
(Taras)
October 14, 2019, 1:37am
20
DavidFW1960:
like the value of “cmd”?
{{ my_test_json | regex_findall_index(\"cmd\" : \"(\w+)\"') }}
1 Like