HTTP binding - openHAB 3 version

Hi

Great binding. I just have one issue.
I can read the values for 3 channels via GET method, but I need also a GET Method to set a switch item to ON & OFF.

here is the output when I set it via curl:

# curl -i -H "Accept: application/json" -H "Content-Type: application/json" -H "Token:SECRET" 'http://10.0.1.27/relay?state=1'
HTTP/1.1 200 OK
Pragma: no-cache
Cache-Control: no-store, no-cache
Content-Type: text/plain
Content-Length: 0
Connection: close

In the old binding, I defined the item that way:
ON:GET:http://10.0.1.27/relay?state=1{Token=SECRET}
OFF:GET:http://10.0.1.27/relay?state=0{Token=SECRET}

When I configure the channel that way, I get an exception in openhab.log.

2020-07-22 16:26:43.165 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.thingUpdated()' on 'org.openhab.binding.http.internal.HttpThingHandler@1ad26566': String index out of range: 0
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at java.lang.String.charAt(String.java:658) ~[?:1.8.0_252]
	at org.openhab.binding.http.internal.HttpThingHandler.concatenateUrlParts(HttpThingHandler.java:308) ~[?:?]
	at org.openhab.binding.http.internal.HttpThingHandler.createChannel(HttpThingHandler.java:191) ~[?:?]
	at java.util.ArrayList.forEach(ArrayList.java:1257) ~[?:1.8.0_252]
	at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1082) ~[?:1.8.0_252]
	at org.openhab.binding.http.internal.HttpThingHandler.initialize(HttpThingHandler.java:161) ~[?:?]
	at org.eclipse.smarthome.core.thing.binding.BaseThingHandler.thingUpdated(BaseThingHandler.java:166) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_252]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_252]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_252]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_252]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
	at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_252]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_252]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_252]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_252]

regards
Remo

@HaKuNa

I would also try MAP transformation with e.g. onoff.map

Content of onoff.map:

1=on
0=off

.
And your URL Definition should be:
.

This was the right direction, thanks.

my map file:

true=1
false=0

and the channel definition:

1 Like

Thanks for your snapshot. The missing part actually was that I need to use %2$s for the state argument. @J-N-K if I didnā€™t overlook it thatā€™s not documented ?

It in documentation at the bottom. See here.

That doesnā€™t seem to work properly yet.
On my last example (to read and write the channel), State URL Extension was ignored.
And when Iā€™ve set it to empty (but readwrite mode), I got an exception on saving saying

2020-07-22 22:31:15.968 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.thingUpdated()' on 'org.openhab.binding.http.internal.HttpThingHandler@163344': String index out of range: 0
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
        at java.lang.StringLatin1.charAt(StringLatin1.java:47) ~[?:?]
        at java.lang.String.charAt(String.java:693) ~[?:?]
        at org.openhab.binding.http.internal.HttpThingHandler.concatenateUrlParts(HttpThingHandler.java:308) ~[?:?]
        at org.openhab.binding.http.internal.HttpThingHandler.createChannel(HttpThingHandler.java:191) ~[?:?]

With another thing which has no Command Extension, State Extension is working, but apparently not together with Command Extensions.

Actually those docs say %2$ but I had to use %2$s like in @Celaeno1ā€™s example.

[quote=ā€œmstormi, post:67, topic:101851, full:trueā€]

Well, thatā€˜s not exactly true.

l. 101 states that the ā€žformat needs to be appended ā€ž and l. 106 shows exactly %2$s. But probably this needs to be reworded to be more clear.

I took the string from your README.md (as most people will simply do rather than read java docs) so please fix it there

Thatā€˜s in the readme. Anyway, it should be made more clear.

just to mention where I found the information:
-> It is explained under ā€œURL Formattingā€ here https://github.com/J-N-K/openhab-addons/tree/http/bundles/org.openhab.binding.http

http://www.domain.org/home/lights/23871/?status=%2$s&date=%1$tY-%1$tm-%1$td

Thereā€™s 2 occurences. The one in the URL you refer to is correct.
But thereā€™s another one 4 lines up which is bad which is what I took.

Did you see about the state extension not being honored ? (6 posts up)

Itā€™s here:
After the parameter reference the format needs to be appended

I guess @mstormi means this sentence in documentation:

After concatenation of the baseURL and the commandExtension (if provided) the URL is formatted using the java.util.Formatter.

.
It better should be:
.

After concatenation of the baseURL and the commandExtension or the stateExtension (if provided) the URL is formatted using the java.util.Formatter.

I have fixed the exception and made the documentation a little bit more explicit.The link above is updated. Be careful if you drop the .jar in your addons folder: Itā€™s now 2.5.8 instead of 2.5.7, so the old version will not be overwritten.

1 Like

Thanks, itā€™s working as expected now. Hereā€™s my promised complex example for your docs:

My ā€˜Dreamboxā€™ TV receiver has an HTTP API. The hostname is dm900.
On requesting /web/powerstate, it returns an XML

<e2powerstate>
<e2instandby>false</e2instandby>
</e2powerstate>

meaning it is currently not in standby thus ON. A POST request /web/powerstate?newstate=5 will instruct it to switch OFF and newstate=4 means to switch ON.


The state transformation REGEX fully reads REGEX:.*?<e2instandby>(.*?)</e2instandby>.* and returns what is between <e2instandby> and </e2instandby>, i.e. false or true.
dreambox.map for the command transformation is

true=5
false=4
NULL=no data
-=no data

Very unlike the HTTPv1 binding, the item definition is only a very simple channel reference
Switch Dreambox "Dreambox [%s]" { channel="http:url:<thing ID>:<channel ID>" }

1 Like

:smiley: Thatā€™s exactly my suggestion I made here:

1 Like

In the readme it says:

`mode` `READWRITE` Mode this channel is allowed to operate. `READ` means receive state, `WRITE` means send commands.

In the code it is actually:

<option value="READWRITE">Read/Write</option>
<option value="READONLY">Read Only</option>
<option value="WRITEONLY">Write Only</option>
2 Likes

Exellent work!!
This will be the binding to integrate all those proprietary smart/cloud devices.
But Iā€™m stuck with authentication on my Air-Heatpump.
Does the method for URL need to be Post?
Cause REGEX canā€™t find matches, because itā€™s only loading the loginpage.

If your device requires authentication, you need to define this on the thing (user/pwd or token in the http header). This depends on the device you want to connect.