REST API - vpjuslin/openhab GitHub Wiki
The REST API of openHAB serves different purposes. It can be used to integrate openHAB with other system as it allows read access to items and item states as well as status updates or the sending of commands for items. Furthermore, it gives access to the sitemaps, so that it is the interface to be used by remote user interfaces (e.g. fat clients or fully Javascript based web clients).
The REST API furthermore supports server-push, so you can subscribe yourself on change notification for certain resources. Find more about the server-push features in the "Server-Push" section below.
The uris of the REST API support different media types. This means that you can define the format of the response with an additional HTTP header like
Accept: application/xml
For each url, you will find the list of supported media types documented below.
If your client cannot correctly set the HTTP accept header, you also have the choice to append the query "?type=xml", "?type=json" or "?type=jsonp" to the URI to request a specific media type for the response.
Each resource that accepts application/x-javascript
as a media type returns JSONP results, which can be parameterized by appending ?jsoncallback=callback
to the URI, e.g.
http://localhost:8080/rest/items/Temperature_FF_Office?jsoncallback=callback
which yields the following response
callback({"type":"NumberItem","name":"Temperature_FF_Office","state":"Undefined","link":"http://localhost:8080/rest/items/Temperature_FF_Office"})
The parameter jsoncallback
is optional. If not provided, callback
will be used as a default.
The entry url for the REST API is the following:
http://localhost:8080/rest
Media types: application/xml, application/json, application/x-javascript
As a response, this will return links to the available resource collections:
<openhab>
<link type="items">http://localhost:8080/rest/items</link>
<link type="sitemaps">http://localhost:8080/rest/sitemaps</link>
</openhab>
The request
http://localhost:8080/rest/items
Media types: application/xml, application/json, application/x-javascript
returns a collection of all declared items like
<items>
<item>
<type>GroupItem</type>
<name>Temperature</name>
<state>20.145533363073167</state>
<link>http://localhost:8080/rest/items/Temperature</link>
</item>
<item>
<type>NumberItem</type>
<name>NoOfPairedDevices</name>
<state>1</state>
<link>http://localhost:8080/rest/items/NoOfPairedDevices</link>
</item>
<item>
<type>GroupItem</type>
<name>gFF</name>
<state>Undefined</state>
<link>http://localhost:8080/rest/items/gFF</link>
</item>
...
</items>
Single items can hence be accessed like
http://localhost:8080/rest/items/Temperature_FF_Office
Media types: application/xml, application/json, application/x-javascript
To directly access an item state, you can access
http://localhost:8080/rest/items/Temperature_FF_Office/state
which returns the state as a plain string.
Likewise, you can send a status update using the HTTP verb PUT to the same uri, passing the new state as a plain string argument in the body (encoding text/plain).
In order to send a command to an item, you would use the item uri (http://localhost:8080/rest/items/Temperature_FF_Office
) and send an HTTP POST with the according command in the request body as text/plain.
The request
http://localhost:8080/rest/sitemaps
Media types: application/xml, application/json, application/x-javascript
returns a collection of all declared sitemaps like
<sitemaps>
<sitemap>
<name>default</name>
<link>http://localhost:8080/rest/sitemaps/default</link>
</sitemap>
<sitemap>
<name>demo</name>
<link>http://localhost:8080/rest/sitemaps/demo</link>
</sitemap>
</sitemaps>
The content of a single sitemap is available at
The request
http://localhost:8080/rest/sitemaps/demo
Media types: application/xml, application/json, application/x-javascript
which returns a result like
<sitemap>
<name>demo</name>
<link>http://localhost:8080/rest/sitemaps/demo</link>
<homepage>
<id>demo</id>
<link>http://localhost:8080/rest/sitemaps/demo/demo</link>
<widget>
<type>Frame</type>
<label />
<icon>frame</icon>
<widget>
<type>Group</type>
<label>First Floor</label>
<icon>1stfloor</icon>
<item>
<type>GroupItem</type>
<name>gFF</name>
<state>Undefined</state>
<link>http://localhost:8080/rest/items/gFF</link>
</item>
<linkedPage>
<id>0000</id>
<link>http://localhost:8080/rest/sitemaps/demo/0000</link>
<widget>
<type>Group</type>
<label>Bathroom</label>
<icon>bath</icon>
<item>
<type>GroupItem</type>
<name>FF_Bath</name>
<state>Undefined</state>
<link>http://localhost:8080/rest/items/FF_Bath</link>
</item>
[...]
</widget>
</linkedPage>
</widget>
</widget>
</homepage>
</sitemap>
You can see that the sitemap information not only contains the static information that the user has provided in the sitemap file, but that it also holds derived data like icons and labels and dynamic group contents, where the groups structure is not explicitly defined in the sitemap.
Single pages can be accessed by adding a page id (as given in the sitemap response):
http://localhost:8080/rest/sitemaps/demo/FF_Bath
Media types: application/xml, application/json, application/x-javascript
which returns the widgets contained in this page:
<page>
<id>FF_Bath</id>
<link>http://localhost:8080/rest/sitemaps/demo/FF_Bath</link>
<widget>
<type>Switch</type>
<label>Ceiling</label>
<icon>switch</icon>
<item>
<type>SwitchItem</type>
<name>Light_FF_Bath_Ceiling</name>
<state>ON</state>
<link>http://localhost:8080/rest/items/Light_FF_Bath_Ceiling</link>
</item>
</widget>
[...]
<widget>
<type>Text</type>
<label>Bath [undefined]</label>
<icon>contact</icon>
<item>
<type>ContactItem</type>
<name>Window_FF_Bath</name>
<state>CLOSED</state>
<link>http://localhost:8080/rest/items/Window_FF_Bath</link>
</item>
</widget>
</page>
openHAB makes use of the Atmosphere framework for server-push functionality. By this, you automatically have the option to use long-polling, HTTP streaming or websockets, depending on what your client supports.
You can subscribe on the following resources:
- a single item (or item group)
- an item state
- a single page of a sitemap
Whenever the state of an item that is part of the resource changes, the resource will be returned just as on a regular request (i.e. exactly the same syntax). This is especially useful for sitemap pages as you can instantly refresh your UI whenever some state changes on the currently shown page.
To tell the openHAB server that you want to suspend the response (i.e. use server-push), you have to add the following header to your HTTP request: X-Atmosphere-Transport: websocket|long-polling|streaming
Moreover it's recommend to set a unique tracking Id for each client. X-Atmosphere-tracking-id: unique id With the aid the of the tracking id openHAB is able to reduce the network load. openHAB will detect if the actual message is equal to the previous one and will supress double broadcasts. The tracking header is also neccessary if you want to receive page-label and page-icon updates on streaming connections (see below).
Please note: for sitemap ressources we have different types of answers. This depends on the connection type.
"X-Atmosphere-Transport: long-polling" should be set as HTTP Header.
long-polling connections will always receive a complete page object. The answer is equal to normal REST api invocations as described above.
"X-Atmosphere-Transport: streaming" or "X-Atmosphere-Transport: websocket" should be set as HTTP Header.
HTTP streaming or websocket connections receive only updated objects from the openHAB server. The received update could either be a widget and / or a page object. If the page label or icon is not changed you will only receive a widget object, but if a label or icon is changed on the page you will additionally receive a page object. (For this feature the "X-Atmosphere-tracking-id" header is required)
a widget response looks like
<widgets>
<widget>
<widgetId>FF_Bath_0</widgetId>
<type>Switch</type>
<label>Ceiling</label>
<icon>switch-on</icon>
<item>
<type>SwitchItem</type>
<name>Light_FF_Bath_Ceiling</name>
<state>ON</state>
<link>http://localhost:8080/rest/items/Light_FF_Bath_Ceiling</link>
</item>
</widget>
</widgets>
in case the page label or icon changes you will also receive something like this:
<page>
<id>030001</id>
<title>No. of Active Heatings [(1)]</title>
<icon>heating-on</icon>
<link>http://localhost:8080/rest/sitemaps/demo/030001</link>
<parent>
<id>0300</id>
<title>Group Demo</title>
<icon>1stfloor</icon>
<link>http://localhost:8080/rest/sitemaps/demo/0300</link>
</parent>
</page>
That's all! The GreenT UI, the iOS client as well as HABDroid use this mechanism to update the pages.
Besides this, server-push can be very helpful for integration with other systems, if they are interested in state changes from openHAB - there is no need to do polling in such a case.
Checkout the atmosphere pages to learn more about client development: https://github.com/Atmosphere/atmosphere
See the following for code samples: https://github.com/openhab/openhab/wiki/Samples-REST