[SOLVED] JSONPATH expression with String variable in the filter part

Hi all,. I’am trying to write a rule to sort out my temp sensor in my home and push these values to an Item.
But i’m getting an error in the JSONPATH expression that it can’t execute the filter.

I start with these json strings
MQTT_SENSOR is the incomming json data
jsonLiveSensors is a harcode json string with information about the Sensors that are in the Items.

MQTT_SENSOR== '{"Time":"2017-10-03T21:29:18", "DS18x20":{"DS1":{"Type":"DS18B20", "Address":"28FF4CBFA41604C4", "Temperature":25.44}, "DS2":{"Type":"DS18B20", "Address":"28FF1E7FA116035D", "Temperature":30.37}, "DS3":{"Type":"DS18B20", "Address":"28FF1597A41604CE", "Temperature":23.25}}, "DHT22":{"Temperature":33.20, "Humidity":28.40}, "TempUnit":"C"}'

var String jsonLiveSensors = ' {"DS18x20":[ {"Address":"28FF4CBFA41604C4","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp1","subject":"Temperatuur bovenin midden"}, {"Address":"28FF1E7FA116035D","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp2","subject":"Temperatuur bovenop achter"},{"Address":"28FF1597A41604CE","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp3","subject":"Temperatuur voorin midden"}]}'

and this is the rules part.

 	var String rData = MQTT_SENSOR.state.toString	//Recieved Data
	var String rSensors = transform("JSONPATH", "$.DS18x20..Address", rData) // Recieved Sensors Addresses
	var rSensorsArr = rSensors.substring(1,rSensors.indexOf(']')).split(",")
	for (String i: rSensorsArr) {
		if (jsonLiveSensors.indexOf(i)>0 ){ //Check if ID is active
			logInfo("MQTT_SENSOR","Address:" + i + " OKE!")
			vName = transform("JSONPATH", "$.DS18x20.[?(@.Address==' + i + ')].Name", jsonLiveSensors)
			vName = vName.substring(1,vName.indexOf(']'))
			logInfo("MQTT_SENSOR","Variable Name:" + vName)
			
			tVal = transform("JSONPATH", "$.DS18x20..[?(@.Address=='"+i+"')].Temperature", rData)
			vVal = new Double(tVal.substring(1,tVal.indexOf(']')))
			logInfo("MQTT_SENSOR","Variable Value:" + vVal)

			if(gTemperature.members.filter[k|k.name==vName].size > 0){
				var vItem = gTemperature.members.filter[k|k.name==vName].head
				vItem.sendCommand(vVal);
				logInfo("MQTT_SENSOR","SendCommand Update:"+vName)
			}else{
				logInfo("MQTT_SENSOR","SendCommand Fail:"+vName)
			}
		}else{
			logInfo("MQTT_SENSOR","Address:" + i + " NOT found")
		}
     }

And when i run this and set the correct karaf debug log setting get these errors:

2017-10-05 00:10:32.835 [DEBUG] [ternal.JSonPathTransformationService] - about to transform '{"Time":"2017-10-04T23:10:31", "DS18x20":{"DS1":{"Type":"DS18B20", "Address":"28FF4CBFA41604C4", "Temperature":24.81}, "DS2":{"Type":"DS18B20", "Address":"28FF1E7FA116035D", "Temperature":29.94}, "DS3":{"Type":"DS18B20", "Address":"28FF1597A41604CE", "Temperature":25.31}}, "DHT22":{"Temperature":32.70, "Humidity":29.30}, "TempUnit":"C"}' by the function '$.DS18x20..Address'
2017-10-05 00:10:32.838 [DEBUG] [ternal.JSonPathTransformationService] - transformation resulted in '["28FF4CBFA41604C4","28FF1E7FA116035D","28FF1597A41604CE"]'
2017-10-05 00:10:32.845 [INFO ] [e.smarthome.model.script.MQTT_SENSOR] - Address:"28FF4CBFA41604C4" OKE!
2017-10-05 00:10:32.870 [DEBUG] [ternal.JSonPathTransformationService] - about to transform '{"DS18x20":[
 	{"Address":"28FF4CBFA41604C4","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp1","subject":"Temperatuur bovenin midden"},
 	{"Address":"28FF1E7FA116035D","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp2","subject":"Temperatuur bovenop achter"},
 	{"Address":"28FF1597A41604CE","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp3","subject":"Temperatuur voorin midden"}
 	]}' by the function '$.DS18x20.[?(@.Address=="28FF4CBFA41604C4")].Name'
2017-10-05 00:10:32.901 [ERROR] [ore.transform.actions.Transformation] - Error executing the transformation 'JSONPATH': An error occurred while transforming JSON expression.
2017-10-05 00:10:32.905 [INFO ] [e.smarthome.model.script.MQTT_SENSOR] - Variable Name:"DS18x20":[
  	{"Address":"28FF4CBFA41604C4","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp1","subject":"Temperatuur bovenin midden"},
 	{"Address":"28FF1E7FA116035D","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp2","subject":"Temperatuur bovenop achter"},
 	{"Address":"28FF1597A41604CE","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp3","subject":"Temperatuur voorin midden"}
 	

I have tracked the problem to the "+ i + " this translates into double quoted String “28FF4CBFA41604C4” and this doesn’t work with the JSONPATH transform. But i can’t find a way to parse the i-variable as an single quotes String ‘28FF4CBFA41604C4’ then the JSONPATH expression filter works fine.

Does anyone have an idea or workaround of this?
Is this a bug in the transform binding or in the JSONPATH github project itself?

When checking the syntax of the json filter with https://jsonpath.curiousconcept.com/ single or double quotes have the same result but not in Openhab 2.1

Shouldn’t that line have this instead?:

"$.DS18x20.[?(@.Address=='" + i + "')].Name"

HI @namraccr

I tried that … and that translates to that the transformation is empty. Because the String is now single and double quoted.

2017-10-05 00:53:06.288 [INFO ] [e.smarthome.model.script.MQTT_SENSOR] - Address:"28FF4CBFA41604C4" OKE!
2017-10-05 00:53:06.292 [DEBUG] [ternal.JSonPathTransformationService] - about to transform '{"DS18x20":[
 	{"Address":"28FF4CBFA41604C4","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp1","subject":"Temperatuur bovenin midden"},
 	{"Address":"28FF1E7FA116035D","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp2","subject":"Temperatuur bovenop achter"},
 	{"Address":"28FF1597A41604CE","Type":"DS18x20","Correction":0,"Name":"PC_kast_temp3","subject":"Temperatuur voorin midden"}
 	]}' by the function '$.DS18x20.[?(@.Address=='"28FF4CBFA41604C4"')].Name'
2017-10-05 00:53:06.295 [DEBUG] [ternal.JSonPathTransformationService] - transformation resulted in '[]'

The timing of your post is uncanny.

This other thread had me really confused and I’ve played with JSONPATH now for hours and have finally seen the issue that was being reported, and you are experiencing exactly the same issue. There are many other ways to do what you are looking to do, but with a few changes I think it will work as you have it.

  1. Are vName and tVal global variables? If not, you’re missing the declarations.
  2. You’ll need the double quotes as @namraccr suggested.
  3. The values you are getting returned by JSONPATH have double quotes in them, so that needs to be taken into account when you are using the values in the filter expression. I’m still testing some things, but I believe a PR for the documentation needs to be made for this behavior.

Try this out and see if it works for you:

val String rData = MQTT_SENSOR.state.toString	//Recieved Data
val String rSensors = transform("JSONPATH", "$.DS18x20..Address", rData) // Recieved Sensors Addresses
val String[] rSensorsArr = rSensors.substring(1,rSensors.indexOf(']')).split(",")
for (String item: rSensorsArr) {
    val String i = item.replace('"','')
    if (jsonLiveSensors.contains(i) ) { //Check if ID is active
        logInfo("MQTT_SENSOR","Address:" + i + " OKE!")
        val String vName = transform("JSONPATH", "$.DS18x20.[?(@.Address=="' + i + '")].Name", jsonLiveSensors)
        //vName = vName.substring(1,vName.indexOf(']'))
        logInfo("MQTT_SENSOR","Variable Name:" + vName)
        val String tVal = transform("JSONPATH", "$.DS18x20..[?(@.Address=='"+i+"')].Temperature", rData)
        //vVal = new Double(tVal.substring(1,tVal.indexOf(']')))
        logInfo("MQTT_SENSOR","Variable Value:" + vVal)
        if(gTemperature.members.filter[k|k.name==vName].size > 0){
            val vItem = gTemperature.members.filter[k|k.name==vName].head
            vItem.sendCommand(vVal);
            logInfo("MQTT_SENSOR","SendCommand Update:"+vName)
        }else{
            logInfo("MQTT_SENSOR","SendCommand Fail:"+vName)
        }
    }else{
        logInfo("MQTT_SENSOR","Address:" + i + " NOT found")
    }
}

Hi @5iver, I just, 5minutes ago, found out that indeed the double quotes are not that of displaying a string though loginfo. But they are part of the String inside the variable that is returned by the JSON transform. :unamused:
So you’re correct that pealing of the double quotes is needed.

Getting up to speed with this language is a bit of a struggle.

Thanks for you’re help … I’ll close this topic