Software developers absolutely love documentation. But unfortunately for me they hate writing it (and I know this, working fulltime as one of them...).
Last time I said that my goal for the past week was to write a small prototype for communicating with the REST API of OpenHAB, to prove that it works. Now the week is over, and apart from having learned too many things I have nothing that really works. Bummer
So OpenHAB has a REST API, and its documented in the wiki. It tells you how to access it, and how to navigate the structure of available resources. It also explains how to use server-push functionality - that allows to avoid polling. By using either WebSockets, streaming or long-polling the server can notify the client when something happens, instead of having the client polling every 5 seconds.
Here is where the documentation starts to get, lets say, difficult.
A first test
First it says that one subscribe to items, item groups, items states or complete pages. And it says to add a special header to tell OpenHAB which streaming connection to use. OK, so lets fire up curl and see what happen:
curl -v -H "X-Atmosphere-Transport: websocket" -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: raspi1" -H "Origin: http://raspi1" http://raspi1/rest/items/switch_Rocker_B
Now I tried to press the button on the rocker switch - I should see some events coming in. But whats happens is - nothing. Just a timeout after some minutes. Strange.
Trying this with 'long-polling' as transport (and omitting the WebSocket headers) just results in an empty response and a closed connection whenever the switch is pressed.
A hint can be fund in the documentation some paragraphs above - one needs to specify what format the response should have (application/json for example). Maybe its a good idea to document that its required instead of writing 'the response format can be changed by...'. Since the requests work fine in a browser and return XML its hard to find out that this header is needed...
Also, when using long-polling one gets back a complete page. Note that this differs from whats returned as a 'sitemap' resource. One sitemap can contain multiple pages (though the documentation is silent on how to do that, but its in the example).
Streaming kind of works
So when specifying 'streaming' as transport mode, and add a proper 'Accept' header, I get some response as expected:
curl -v -N -H "Accept: application/json" -H "X-Atmosphere-Transport: streaming" http://raspi1/rest/items/switch_Rocker_B
returns:
{"type":"SwitchItem","name":"switch_Rocker_B","state":"ON","link":"http://raspi1:80/rest/items/switch_Rocker_B"}
(but it does so three times in a row...)
Doing this with WebSockets still ends in a closed connection Istill don't know whether this has something do to with using curl as a client, or is it a problem in OpenHAB?
First steps on a Java client
Since OpenHAB uses the Atmosphere framework for all its REST stuff, it was kind of natural to go looking there for a Java 8and Android) client. Fortunately there both, combined in the 'wasync' library. There even is a nice example right on the first GitHub page. too bad that it does not even compile...
After correcting this (the API seems to have changed since the demo code was written) I can get a successful streaming (or long-polling) connection, and even receive some answers back. But both times the socket close with a timeout, and there is no automatic re-connect. I can increase the timeout, but if its large enough then the connection will stall (and not receive any events from the server).
Hell is other peoples source code
So where does this leave me? I know that the streaming and long-polling options work in principle. WebSockets don't seem to work reliably (and I guess this is why my Android tablet doesn't refresh state changes to the sensors immediately).
So it looks I need to write my own client, based on the base Java URL classes (or maybe I can at least re-use the code from underneath the Atmosphere client, which seems to use Netty as networking library).
Btw: there is only one thing software developers hate more than writing documentation: bugs.