I would like to fill an Item Number from a JSON return. When saving my item, I get no errors. Also, my JSONPATH is valid against online test tools. JSONPATH is installed via Paperui.
Item:
Number Hue_Brightness_Woonkamer "Brightness [%s]" (gWoonkamer) { http="<[http://192.168.1.203/api/<myapiusername>:10000:JSONPATH($.groups[?(@.name=='Woonkamer')].action.bri)]" }
The return (on test tools):
[
123
]
I get no errors in openhab.log, am I doing something wrong?
I didn’t thought that was relevant because my JSONPATH is valid. I wil post it below.
As described, I get no errors in openhab.log. Are there perhaps any debugs I can enable regarding JSONPATH and/or HTTP get?
I’ve changed it to decimal and floaingpoint, it doenst seem to make a difference. I would expect an update in the servicebus once the value is changed.
@bastiaan_van_h sorry did not read it properly, thought you wrote i get an error.
Does one of those work? So does the http binding return something?
When you use this, at least something should apear int the log when Hue_Brightness_Woonkamer changes. I changed it to a string for testing and removed the json querry.
rule "Milight_ID1_G1_HubStates"
when
Item Milight_ID1_G1_EspMilightHub changed
then
var sJSONBLOB = Milight_ID1_G1_EspMilightHub.state.toString
var sMODE = transform("JSONPATH","$.bulb_mode", sJSONBLOB)
var sSTATE= transform("JSONPATH","$.state", sJSONBLOB)
var sLEVEL= transform("JSONPATH","$.level", sJSONBLOB)
var Number iLEVEL= Integer::parseInt(sLEVEL).intValue //convert the string to an int.
if(Milight_ID1_G1_State.state!=sSTATE)
Milight_ID1_G1_State.postUpdate(sSTATE)
if(sMODE=="white") // Code to handle a white JSON blob
{
var sCTEMP=transform("JSONPATH","$.color_temp", sJSONBLOB)
var iTempScaled=(((Integer::parseInt(sCTEMP)/2.17)-171)*-1).intValue //Dirty but seems to work. Converts string to int and scale range.
Milight_ID1_G1_CTemp.postUpdate(iTempScaled) //send CT to globe
Milight_ID1_G1_Brightness.postUpdate(iLEVEL) //send new brightness to globe
}
else if(sMODE=="color") // Code to handle a colour JSON blob
{
var String sHUE = transform("JSONPATH","$.hue", sJSONBLOB)
var String sSATURATION = transform("JSONPATH","$.saturation", sJSONBLOB)
Milight_ID1_G1_Brightness.postUpdate(iLEVEL) //update main dimmer item
Milight_ID1_G1_Hue.postUpdate(sHUE+","+sSATURATION+","+sLEVEL) //update color item
}
end
Thank you @bweekers for this, I did not have the HTTP binding installed. Despite I used it in my item without HTTP binding installed, I did not generate any error. After installing I now get returns.
After digging, I found out that the search part of my JSONPATH query does not work in Openhab.
Does not work:
$.groups[?(@.name=='Woonkamer')].action.bri
Does work:
$.groups.1.action.bri
I would like to include a search, because when in the future I can have more groups. Any idea why my search query isn’t working in Openhab?
You are using an indefinite path in your JSONPATH, which will return a List, not a string. Indefinite paths can’t be used in JSONPATH for Items/Labels, and take special handling in rules.
There was a relatively recent ESH PR to resolve an issue that has made its way into the OH snapshot build, where the first element of the List would be returned, if there is only one element in it. There are some unfortunate side affects to this that I am hoping will be addressed.
To resolve your issue, you could update OH to the snapshot, or use a JS transform to parse the JSON.
I think a query will always return as an array. And an Array can not be parsed to a Number.
Try to change your Item to a string. There should be a string in the Item.state which looks like [123]
One solution would be to use a rule and a proxy item, or use a javascript transformation and do the jsonpath query there, strip of the bracket and return the value.
Number Hue_Brightness_Woonkamer "Brightness [%s]" (gWoonkamer) { http="<[http://192.168.1.203/api/<myapiusername>:10000:JS(jsonpathQuery.js)]" }
/etc/openhab2/transform/jsonpathQuery.js
not sure what to put here
But also there seems to be an issue with the jsonpath transformation when used in rules.
rule "test"
when
Item Test_1 changed
then
var test = "{
\"groups\":{
\"1\":{
\"name\":\"Woonkamer\",
\"action\":{
\"bri\":123
}}}}"
var String test1 = transform( "JSONPATH",
"$.groups.1.action.bri",
test )
var String test2 = transform( "JSONPATH",
"$.groups[?(@.name=='Woonkamer')].action.bri",
test )
logInfo("Test", test.toString )
logInfo("Test 2", test1.toString )
logInfo("Test 3", test2.toString )
end
[INFO ] [smarthome.event.ItemStateChangedEvent] - Test_1 changed from ON to OFF
[INFO ] [g.eclipse.smarthome.model.script.Test] - {
"groups":{
"1":{
"name":"Woonkamer",
"action":{
"bri":123
}}}}
[INFO ] [eclipse.smarthome.model.script.Test 2] - 123
[INFO ] [eclipse.smarthome.model.script.Test 3] - []
But whats the difference and why does the first one not work.
So Basically it returns [123] which is expected but also does not solve the problem at hand of @bastiaan_van_h.
rule "test"
when
Item Test_1 changed
then
// filter applied on proxy item
var test1= transform( "JSONPATH",
"$..[?(@.name=='Woonkamer')].action.bri",
Test_1 )
logInfo("Test ", test1.substring(1, test2.length-1) )
// Strip off the brackets and
// Post result to Number Item
Test_2.postUpdate( test2.substring(1, test2.length-1) )
end
The way I understand it, $.groups[?(@.name=='Woonkamer')].action.bri searches the children of groups, and there is no child of “groups” with key “name”. But $.groups.1[?(@.name=='Woonkamer')].action.bri has a child with key “name”, so it is found. The deep scan (recursive descent) searches the whole tree, so also finds “name”.
Correct. His issue should be solved by what I posted earlier. I just saw your reply and thought I’d try to help. You hadn’t found an issue with using the JSONPATH transformation in rules… the expression you were using just wasn’t returning a result. But read through the issue I linked… as written, there are definitely some things that can be improved!
Jayway (used by OH) is a Java port of Goessner, so there could be differences. There could also be differences in the versions. Sorry… nothing definitive.
Hello @Josar and @5iver, thank you both for your analysis.
So my JSONPATH query returns a list, and that’s why it isn’t catched by OH. I will perform the rule tests @Josar proposed and will come back with the result.