Skip to content
This repository has been archived by the owner on May 17, 2021. It is now read-only.

http binding / JSONPATH array access with filter #4768

Closed
kohlsalem opened this issue Nov 11, 2016 · 7 comments
Closed

http binding / JSONPATH array access with filter #4768

kohlsalem opened this issue Nov 11, 2016 · 7 comments

Comments

@kohlsalem
Copy link

kohlsalem commented Nov 11, 2016

Dear OH Team, Dear @watou,

after trying out my things (Rademacher homepilot blinds) using the patch #4759 i found an issue which is most likely bound to JSONPATH itself or the way it is called.

I run basically OH2; 3 days old snapshot.

Http bindings work fine, principally. Exept this one.

If adress a list like:

Number testval "door [%d]" {http="<[http://homepilot/deviceajax.do?devices=1:4000:JSONPATH($.devices[0].position)]"}

everything works perfectly fine. However, i need to select the correct device by its ID.

Number testval "door [%d]" {http="<[http://homepilot/deviceajax.do?devices=1:4000:JSONPATH($.devices[?(@.did==10006)].position)]"}

it does not bring a result back. if i test it on http://jsonpath.com/ with the actual json, both retrive the same value. ('0' => "57" or whatever the position is).

If i switch debugging log on, i can see that filtercondition matches. BUt as i sait, no result.

I read, OH2 uses a newer JSONPATH version. Since a filter could theoretically deliver several results, i suspect JSONPATH 2.x to have a different handling of the return value than the old versions did.

I assume, every array access with filter instead of index will cause this. If needed i can provide as well the json...

Thanks
Michael

@watou
Copy link
Contributor

watou commented Nov 12, 2016

You are correct that the JSONPATH transformation can output different results in OH2 versus OH1. My recollection is that the newer JSONPATH can sometimes return an array, so your number might come back [57] in OH2 whereas it came back as 57 in OH1. [57] is of course not acceptable input to create a state suitable for a Number.

Here are things you could try to diagnose:

  1. Temporarily change your item type to String from Number to see what the result is.
  2. Use the test JAR from HTTP Binding - Status update for dimmers #4759 or the latest JAR and enable DEBUG logging for the binding. It should log cases where the transformed response is not suitable for creating a State to post to the item.

If the JSONPATH transformation is working but producing an unparseable result, you might have to switch to the JS (JavaScript) transformation.

Please close this issue if you don't find an openHAB bug. If it's a lack of proper documentation about the differences between OH1 and OH2, please suggest edits to this file.

@kohlsalem
Copy link
Author

kohlsalem commented Nov 12, 2016

Hi,

first try: Changing to String gives no change there: the number is given on direct indexing, a "-" on filtered Index.

If openhab would return [100], i think i should be able to index that with:

$.devices[?(@.did==10006)][0].position) or $.devices[?(@.did==10006)].position), both does not return anything.

so i enabled the filter and switched debug on. i found:

11:28:04.032 [INFO ] [marthome.event.ItemStateChangedEvent] - testval changed from 0 to [0]

so, assumption is right.

Yes, i could swith to JS - but that would be in result an change to the worse from the OH1 to the OH2 features.

I would see 2 questions:

  • Why cant i dereference that resulting array? Fair, thats a jsonpath question :-) .

but the other is:

  • http binding can generally not handle arrays returning. Why does it not just grab into it, and using the first value?

Best
Michael

@watou
Copy link
Contributor

watou commented Nov 12, 2016

Yes, i could switch to JS - but that would be in result an change to the worse from the OH1 to the OH2 features.

I would argue that whatever is the correct result from JsonPath is what ESH/OH2 should return, even if it's inconvenient in some cases. The question would then be: Was OH1 wrong or is OH2 wrong (or, unlikely, both)? I think OH1 was wrong and OH2 is right, but it would require some research to find the definitive answer.

The JS version would look something like:

var data = eval("(" + input + ")");
result = data.devices[0].position;

Why does it not just grab into it, and using the first value?

Because that would be a special case that could break other, perfectly valid expectations of what the transformation should return. The "spec" for what the transformation returns should be exactly the JsonPath spec, IMHO.

@kohlsalem
Copy link
Author

Assuming, that OH1 used JSONPATH <2 and OH2 JSONPATH >2 (i think i read that), I'd say:

JSONPATH 2 is doing correct. A Filter to an Array is an Array. How could the fact, that "sometimes" only one value is filtered, change that array to a single value.

But w/o debugging, i noticed that the jsonpath.com does not return arrays, but a list of results.

Without looking at the actual interface of the library i can not say what's true or wrong there, but it looks like the "List of Value" in V1, where you just grabbed the first, changed to List of values with only one entry - an array.

So i suspect a different interpretation of the results on the interface of JSONPATH. If this is true, it is worth to either argure with openpath team to keep the interfacing behavior consistent or to adapt callers behavior.

(Disclaimer: I have most likely to change to JS anyway, I'm discussing just to have a chance to find the "right" solution here :-) )

Question: Is there any case right now in OH1/OH2, where http binding does something meaningful out of an Array? Regardless if it is with one or two values? If yes - everything is ok. If no - picking the first value out of an array result can be seen as a convenience feature... "nothing to loose"...

Independent of this discussion i'll ask a question @ JP2 to gen an opinion there,

Best
Michael

@kohlsalem
Copy link
Author

kohlsalem commented Nov 12, 2016

Have a look at json-path/JsonPath#272
someone has same issues...

@watou
Copy link
Contributor

watou commented Nov 12, 2016

Question: Is there any case right now in OH1/OH2, where http binding does something meaningful out of an Array? Regardless if it is with one or two values?

It certainly seems less usable in the context of openHAB transformations, I'll give you that. There might be current openHAB users who are implementing a rule with a proxy item to strip off the [ and ], so changing the implementation of the JSONPATH transformation to insert special-case handling would both screw them up, and create a more complicated-to-explain behavior that would have to be maintained ongoing.

Somewhere back in github history I was making similar points about changes from OH1 to OH2 behavior, but documenting it got lost in the shuffle. Please feel free to submit a suggested change to migration.md to document the difference in behavior between OH1 and OH2 -- you would probably save others from the same unpleasant realization down the line!

In my opinion the ultimate arbiter are the implementers of JsonPath, as they attempt to conform to a documented specification. If they change the implementation to address json-path/JsonPath#272, then I think it would then make sense to update the implementation used in openHAB, even though this would again shift the goalposts.

@kohlsalem
Copy link
Author

Agreed and closed here....

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants