HTTP binding - openHAB 3 version

There usually ends up being use cases for both ways.

I would suggest a user option , perhaps per data channel
postUndefOnError=true
or something like, defaulting false.

An alternative might be dateTime channel(s) for
lastReadSuccess
lastReadError
which allows users to trap and manage errors for themselves in rules.

The config per channel might be an option. lastReadSuccess is difficult, because it could be that reading one channel is successfull (e.g. with one stateExtension) while another channel (with another stateExtension) always fails. The lastReadSuccess would not help here.

Really I was thinking this would be a built-in channel exposing something about the Thing. Itā€™s the Thing doing the HTTP work from the user viewpoint.

I see this binding does both read and write - so I suppose a better name might be more like
lastCommSuccess
lastCommError
or something if it covers both uses.

Maybe it is less useful these days where Thing status is more accessible from rules, if this Thing reflects its comms problems in its own statusā€¦

Hello @J-N-K

thank for creating this new OH2 binding, great job! :slight_smile:

Finally had time to test it.

I have one feature request:

In http1 binding you had the possibility to use up to 3 different urls.

In the new binding there are unfortunately only two:

Simple example: Switch

baseURL + stateExtension
baseURL + commandExtension

.

But there are the following cases possible and in http1 and you were able to do so:

URL1 = ON
URL2 = OFF
URL3 = state

e.g:

ON = 192.168.100.44:3000/on/3ef204
OFF = 192.168.100.44:3000/off/3ef204
state = 192.168.100.44:3000/state/3ef204
.

Example .items file:

Switch GHoma1	"G-Homa Socket 1"	{ http=">[ON:GET:http://192.168.100.44:3000/on/3ef204] >[OFF:GET:http://192.168.100.44:3000/off/3ef204] <[http://192.168.100.44:3000/state/3ef204:60000:MAP(onoff.map)]" } 

.
.

This would be in http2 binding:

baseURL = 192.168.100.44:3000
stateExtension = /state/3ef204
commandExtension = /on/3ef204 OR /off/3ef204
.

But I need one commandExtension for ON and another commandExtention for OFF.

Or can I use commandTransformation? How do I have to use it?
.
.

Second question:

How do I mix GET and POST commands?

e.g:

stateExtension = GET
commandExtension = POST or PUT

Thank you very much. :slight_smile:

I think that /%2$s/3ef204 as commanfExtension should work. You need to set onValue to on and offValue to off.

3 Likes

This is now working for commandExtension, thanks! :slight_smile:

But the state is ā€œonā€ or ā€œoffā€ with the quotation marks! Thatā€™s why I used MAP (see example above).

How to set the State Transformation?

image

.
.
.
EDIT: I now found out on my own! :slight_smile:

State Transformation: MAP:onoff.map

and the onoff.map must contain the following:

"on"=on
"off"=off

Now it works very well! Many thanks to @J-N-K !

.
.
P.S: A further running example of a State Transformation is e.g: JSONPATH:$.value

2 Likes

I tried another tricky transformation example that didnā€™t work. Hereā€™s the v1 item definition:
http="<[http://foscam:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=admin&pwd=password:10000:REGEX(.?(.?).*)]" }

That request returns a response like

<CGI_Result>
    <result>0</result>
    <IOAlarm>0</IOAlarm>
    <motionDetectAlarm>1</motionDetectAlarm>
    <soundAlarm>1</soundAlarm>
    <record>0</record>
    <sdState>0</sdState>
    <sdFreeSpace>0k</sdFreeSpace>
    <sdTotalSpace>0k</sdTotalSpace>
    <ntpState>1</ntpState>
    <ddnsState>0</ddnsState>
    <upnpState>2</upnpState>
    <isWifiConnected>1</isWifiConnected>
    <infraLedState>0</infraLedState>
</CGI_Result>

But no matter what I try all I always get is a server response </CGI_Result>-2</CGI_Result>

The debug output is mostly useless as it does not show the URL or headers going out, not even info like SSL or user auth, or responses coming back.

All debug level log shows is

2020-07-10 17:09:30.119 [DEBUG] [.transform.SingleValueTransformation] - Transformation ChannelStateTransformation{pattern='.*?<motionDetectAlarm>(.*?)</motionDetectAlarm>.*', serviceName='REGEX'} returned empty result when applied to <CGI_Result>
    <result>-2</result>
</CGI_Result>
.

I was able to confirm this is what the server returns using wireshark, but for sure I need to be able to see that in the OH log to be able to make good use of it.

@mstormi

If I follow the logic of MAP and JSONPATH it should be as follows:

Binding MAP JSONPATH REGEX
http1 MAP(onoff.map) JSONPATH($.value) REGEX(. ?(. ?).*)
http2 MAP:onoff.map JSONPATH:$.value REGEX:. ?(. ?).*

.
Did you also try REGEX:. ?(. ?).*

I have updated the link above. If you set org.openhab.binding.http.internal.http to TRACE youā€™ll see the URL when requesting and the responses received.

Dowloaded it but did that change anything about http logging ?
Thatā€™s not really useful yet. Would need to see Headers, body and reponse code of the request

2020-07-10 20:24:04.590 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Sending 'http://foscam:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState' to 'HttpRequest[GET /cgi-bin/CGIProxy.fcgi HTTP/1.1]@13442bb'
2020-07-10 20:24:04.639 [TRACE] [ttp.internal.http.RefreshingUrlCache] - RefreshingUrlCache for 'http://foscam:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState' received 'org.openhab.binding.http.internal.http.Content@66d12b'

Iā€˜ll see how I can improve that.

Please check if the updated jar works for you.

It does, thanks.
It helped me find my own error now that I see the 200 response.
Turned out it was the request I didnā€™t copy properly. That device needs to have http://host/yaddayadda&usr=username&pwd=password rather than basic auth.

Whatā€™s left is that apparently I must be having another HTTP thing active (resulting from first tests yesterday ?) as I keep seeing both URLs below (the difference is the additional ā€˜/ā€™). I donā€™t find that 2nd one in the list of smarthome:things though - is it something your binding does ? (although I donā€™t think so as it has a different request interval).

But that reminds me of this: if Iā€™m not mistaken, you add State and Command URL Extension to Base URL but insert a fixed ā€˜/ā€™, correct?
Then please remove that fixed ā€˜/ā€™ insertion as the requirement could as well be to continue the URL with ? or & like in my test case.

2020-07-11 17:29:48.576 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Requesting refresh from 'http://foscam:88/cgi-bin/CGIProxy.fcgi?/cmd=getDevState' with timeout 3000ms
2020-07-11 17:29:48.579 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Sending 'http://foscam:88/cgi-bin/CGIProxy.fcgi?/cmd=getDevState' to 'HttpRequest[GET /cgi-bin/CGIProxy.fcgi HTTP/1.1]@5f3465'
2020-07-11 17:29:50.176 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Requesting refresh from 'http://foscam:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=admin&pwd=password' with timeout 1000ms
2020-07-11 17:29:50.178 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Sending to 'http://foscam:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=admin&pwd=password': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.20.v20190813, Authorization: Basic YWRtaW46Y1ROVzBUcGU=}, Content = {null}
2020-07-11 17:29:50.418 [TRACE] [p.internal.http.HttpResponseListener] - Received from 'http://foscam:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=admin&pwd=password': Code = {200}, Headers = {Content-Type: text/plain, Transfer-Encoding: chunked, Date: Sat, 11 Jul 2020 15:29:47 GMT, Server: lighttpd/1.4.35}, Content = {<CGI_Result>
    <result>0</result>
    <IOAlarm>0</IOAlarm>
    <motionDetectAlarm>1</motionDetectAlarm>
    <soundAlarm>1</soundAlarm>
    <record>0</record>
    <sdState>0</sdState>
    <sdFreeSpace>0k</sdFreeSpace>
    <sdTotalSpace>0k</sdTotalSpace>
    <ntpState>1</ntpState>
    <ddnsState>0</ddnsState>
    <upnpState>2</upnpState>
    <isWifiConnected>1</isWifiConnected>
    <infraLedState>0</infraLedState>
</CGI_Result>
}

1 Like

@J-N-K

Same here. I also need no fixed slash / at the end of baseURL or beginning of Extension. Many extensions will begin with ? or &.

I have the changed the concatenation logic. It now first checks if either the last character of the baseURL or the first character of the extension is ?, / or & and adds the / only if nothing is present. jar updated

2 Likes

What seems not to be working yet is updating the item.

Iā€™ve filled State Transformation with a REGEX to extract a value from one of the lines in the HTTP reponse body above: REGEX:.*?<motionDetectAlarm>(.*?)</motionDetectAlarm>.*

ā€¦ but I donā€™t see the linked item update and no hint in the internal.http trace.

I enabled debug logging on org.openhab.transform.regex and it says it is to execute the transformation, but the output isnā€™t shown in log and the item isnā€™t updated.

2020-07-11 18:39:33.930 [DEBUG] [.internal.RegExTransformationService] - about to transform '<CGI_Result>
    <result>0</result>
    <IOAlarm>0</IOAlarm>
    <motionDetectAlarm>1</motionDetectAlarm>
    <soundAlarm>1</soundAlarm>
    <record>0</record>
    <sdState>0</sdState>
    <sdFreeSpace>0k</sdFreeSpace>
    <sdTotalSpace>0k</sdTotalSpace>
    <ntpState>1</ntpState>
    <ddnsState>0</ddnsState>
    <upnpState>2</upnpState>
    <isWifiConnected>1</isWifiConnected>
    <infraLedState>0</infraLedState>
</CGI_Result>

I tried both, Number and String items but no luck.
Any idea how to debug that further ?

Works perfectly for me:

18:41:41.804 [TRACE] [http.internal.http.RefreshingUrlCache] - Requesting refresh from 'https://janessa.me/esh/test.xml' with timeout 3000ms
18:41:41.806 [TRACE] [http.internal.http.RefreshingUrlCache] - Sending to 'https://janessa.me/esh/test.xml': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.20.v20190813, X-Token: mytoken}, Content = {null}
18:41:41.813 [TRACE] [tp.internal.http.HttpResponseListener] - Received from 'https://janessa.me/esh/test.xml': Code = {200}, Headers = {Server: nginx/1.10.3, Date: Sat, 11 Jul 2020 16:41:35 GMT, Content-Type: text/xml, Content-Length: 445, Last-Modified: Sat, 11 Jul 2020 16:37:03 GMT, Connection: keep-alive, ETag: "5f09eaaf-1bd", Accept-Ranges: bytes}, Content = {<CGI_Result>
    <result>0</result>
    <IOAlarm>0</IOAlarm>
    <motionDetectAlarm>1</motionDetectAlarm>
    <soundAlarm>1</soundAlarm>
    <record>0</record>
    <sdState>0</sdState>
    <sdFreeSpace>0k</sdFreeSpace>
    <sdTotalSpace>0k</sdTotalSpace>
    <ntpState>1</ntpState>
    <ddnsState>0</ddnsState>
    <upnpState>2</upnpState>
    <isWifiConnected>1</isWifiConnected>
    <infraLedState>0</infraLedState>
</CGI_Result>}
18:41:41.859 [INFO ] [smarthome.event.ItemStateChangedEvent] - HTTPURLThing_n1 changed from NULL to 1

Did you install the regex transformation?

I have been using that with the v1 binding and my log above (ā€œabout to transformā€) shows itā€™s applied, doesnā€™t it.
Do I need to use a Number or a String item ?

I used a number item and pasted your transformation in the stateTransformation.

Alright, it was my own silly fault. It has been working all the time but the value didnā€™t change so the item didnā€™t.
Everything alright with your binding - thanks.

1 Like