Http binding error with MAC address in URL - SOLVED

Trying to read a temperature from a RM2, RM Bridge, using the HTTP biding and JSONPATH transformation

My URL:
http://192.168.1.64:7474/b4:43:0d:38:e8:61/temperature

Gives this answer:
{“temperature”:30.700001,“code”:0,“msg”:“Refresh rm2 status success”}

So I have this item:
String tempRM {http="<[http://192.168.1.64:7474//b4:43:0d:38:e8:61/temperature:3000:JSONPATH($.temperature)]"}

But get this error:
2016-10-18 11:09:37.268 [INFO ] [runtime.busevents ] - tempRM state updated to Invalid request
2016-10-18 11:09:38.285 [WARN ] [g.openhab.io.net.http.HttpUtil] - Method failed: HTTP/1.1 400 Bad Request
2016-10-18 11:09:38.287 [WARN ] [transform.TransformationHelper] - Cannot get service reference for transformation service of type 0d:38:e8:61/temperature:3000:JSONPATH
2016-10-18 11:09:38.288 [WARN ] [.o.b.http.internal.HttpBinding] - couldn’t transform response because transformationService of type ‘0d:38:e8:61/temperature:3000:JSONPATH’ is unavailable

I believe the problem is with “:” of the mac address, but can´t get a way around it.

Could you URL encode each colon in the URL by replacing it with %3A, and see if the HTTP binding can then correctly parse the binding config string (and of course fetch the intended URL)?

New URL:
String tempRM {http="<[http://192.168.1.64%3A7474/b4%3A43%3A0d%3A38%3Ae8%3A61/temperature:3000:JSONPATH($.temperature)]"}

New error:
2016-10-18 12:48:47.520 [ERROR] [.service.AbstractActiveService] - Error while executing background thread HTTP Refresh Service
java.util.IllegalFormatConversionException: a != java.util.Date
at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302) ~[na:1.8.0_101]
at java.util.Formatter$FormatSpecifier.printFloat(Formatter.java:2806) ~[na:1.8.0_101]
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2753) ~[na:1.8.0_101]
at java.util.Formatter.format(Formatter.java:2520) ~[na:1.8.0_101]
at java.util.Formatter.format(Formatter.java:2455) ~[na:1.8.0_101]
at java.lang.String.format(String.java:2940) ~[na:1.8.0_101]
at org.openhab.binding.http.internal.HttpBinding.execute(HttpBinding.java:139) ~[na:na]
at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:156) ~[na:na]
at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:173) ~[na:na]

Thanks for the prompt reply

Yes, now the HTTP binding is trying to substitute in a replacement value here. Yuck.

I changed the 1.9.0-SNAPSHOT binding in July to allow you to turn off this string formatting feature for situations like this. Here is how to get past it:

If you are using a recent openHAB 2 beta, add format=false to http.cfg and restart the runtime.

If you are using openHAB 1.x, replace your org.openhab.binding.http-*.jar in the addons folder with this one, add http:format=false to openhab.cfg and restart the openHAB runtime.

I´m using OH 1.8.3, replaced and added, but now I have the error below. Just like to point out that I´m just a beginner and could be wrong in something else. Thanks

2016-10-18 13:34:06.547 [WARN ] [g.openhab.io.net.http.HttpUtil] - Method failed: HTTP/1.1 400 Bad Request
2016-10-18 13:34:06.561 [ERROR] [.service.AbstractActiveService] - Error while executing background thread HTTP Refresh Service
java.lang.IllegalArgumentException: Invalid container object
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:238) ~[na:na]
at com.jayway.jsonpath.internal.JsonReader.read(JsonReader.java:103) ~[na:na]
at com.jayway.jsonpath.internal.JsonReader.read(JsonReader.java:97) ~[na:na]
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:462) ~[na:na]
at org.openhab.core.transform.internal.service.JSonPathTransformationService.transform(JSonPathTransformationService.java:44) ~[na:na]
at org.openhab.binding.http.internal.HttpBinding.execute(HttpBinding.java:195) ~[na:na]
at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:156) ~[na:na]
at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:173) ~[na:na]

There was a problem even performing the HTTP GET (400 Bad Request), and this no doubt led to the failure to parse a JSON response. Maybe only replace the colons in the MAC address with %3A, leaving the port number with its preceding colon as normal. I wonder if the MAC address could be specified without colons? The API doc I found doesn’t say you can, but sometimes these things work! :smile:

I had tried changing the colons only in the MAC but got the same answer/error. I was about to send the API you found, so you can see if I´m making any other mistake, maybe due JOSNP being some how a bit different. Not home now to try the MAC without colons, but I had done that before when trying to call the URL from the browser and it did not work, but I will give it a try any way in my .item file. Thanks

First try this URL:

http://192.168.1.64:7474/b4%3A43%3A0d%3A38%3Ae8%3A61/temperature

before trying other things.

One “last resort” option I just thought of is to instead write a rule that runs at your desired update frequency and calls the sendHttpPostRequest(url, contentType, content) action, and then the transform(type, function, value) action to extract the temperature using the JSONPATH transform. Something like:

rule GetTemperature
when
  Time Cron "3 * * * * *"
then
  val req  = "{\"api_id\":10011,\"command\":\"temperature\",\"mac\":\"b4:43:0d:38:e8:61\"}"
  val json = sendHttpPostRequest("http://192.168.1.64:7474/", "application/json", req)
  val temp = transform("JSONPATH", "$.temperature", json)
  MyTempItem.postUpdate(temp)
end

item:

Number MyTempItem "amb. temp [%.1f ºC]"

Tried the URL, got the same result in OH. If I use anything other than the fist URL on a browser all I get is "Invalid request"
Tried the rule but with no luck either, even changer api_id to 1011, as I found that error on the API documentation. Here I have no feedback from the terminal.
The shortcut URL that I use also has an erro on documentation, on page 7 it´s not specified that you need the MAC, but you do.

One approach to finding the right details is to perform the HTTP request using the curl command at a command line, and then “translating” that to what the binding or rule must do. You can perform HTTP GETs and POSTs with curl. I would Google examples of using curl, type man curl at a Linux prompt, etc.

Using Curl from my Raspberry terminal I get the same thing I get from a browser

pi@OpenHab:~ $ curl http://192.168.1.64:7474/b4:43:0d:38:e8:61/temperature
{“temperature”:31,“code”:0,“msg”:“Refresh rm2 status success”}

Is that what I was supposed to do. Thanks for bearing with me.

OK, then this rule ought to work:


rule GetTemperature
when
  Time Cron "0/3 * * * * *"
then
  val json = sendHttpGetRequest("http://192.168.1.64:7474/b4:43:0d:38:e8:61/temperature")
  val temp = transform("JSONPATH", "$.temperature", json)
  MyTempItem.postUpdate(temp)
end

Note: every 3 seconds might be too often for what you need and lead to unnecessary load.

Watou,

I tried that when you sent the first rule, but just in case I updated with this new one, but still not getting any response, nothing is showing on the terminal either. Is it possible that the http binding is reading the colons of the MAC and “thinking” that there is a transformation rule as it does when it is a “item”? We already saw that the API can´t decode the URL with “%3A” as a colon. Should I try to use the exec binding? Thanks

No, the rule approach does not use the HTTP binding at all. The built-in sendHttpGetRequest and transform actions are independent of any binding. Could you change the cron expression to “* 0/2 * * * *” (every two minutes) and add

logInfo("GetTemperature","rule triggered")

to the body of the rule, just to see if it’s running?

You could of course try the exec binding and call curl, but that’s a lot more overhead than should be needed!

Solved

The rule was good from the start, the problem was the cron expression, when I was changing it with the terminal open, I got this msg:

2016-10-19 13:21:59.142 [ERROR] [.r.i.engine.RuleTriggerManager] - Cannot create timer for rule ‘GetTemperature’: CronExpression ‘* 0/5 * * * *’ is invalid,.

So all I did was change the last digit to “?” so now I have “* 0/2 * * * ?” and now everything works great.

Before that I tried to use the Exec binding as a “item” {exec="<[curl -s http://192.168.1.64:7474/b4:43:0d:38:e8:61/temperature:60000:JSONPATH($.temperature)]"} , but it turns out to have the same transformation colon issue and I got this error:

2016-10-19 12:59:21.083 [ERROR] [.service.AbstractActiveService] - Error while executing background thread Exec Refresh Service
java.lang.IllegalArgumentException: given transformation function ‘0d:38:e8:61/temperature:60000’ does not follow the expected pattern ‘()’

Many thanks to you Watou, really appreciated all the help.

1 Like

Very happy you got it working! Now to re-think the HTTP binding for openHAB 2, so issues like these go away (channel configuration, possibly). Thanks for reporting how you got it going! - John