-
Notifications
You must be signed in to change notification settings - Fork 0
REST API
The REST API of openHAB serves different purposes. It can be used to integrate openHAB with other systems 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 interface is very fast, so it is good for real time interaction with openHAB, especially from 3rd party user interfaces such as iRule, openremote or Home Remote (iOS app with apple watch and voice interface).
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.
See the following for code samples: Samples-REST
There are times where the security settings of openHAB requires entry of a username and password but the program making the REST call does not directly support a username and password. This can be handled by supplying the username and password as part of the url using the following pattern:
http://username:password@host:port/rest
This also works with my.openhab.
If your username or password contains non-alpha numeric characters you may have to escape those characters. For example, my.openhab uses your email address as the username so the "@" and "." may need to be escaped. See the following for a reference showing the escape codes for all characters: http://www.w3schools.com/tags/ref_urlencode.asp
In the case of an email, the "@" should be replaced with "%40" and the "." replaced with "%2E".
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.
It's also possible to send a status update using a HTTP GET request (http://localhost:8080/CMD?Temperature_FF_Office=12.3
). This way it's actually possible to send status updates simply through a web browser address bar.
Note: Openhab only supports status updates for the current timestamp. You can record "The value is 5, now". You cannot record "The value was 5, at 6am yesterday" to the API as yet.
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) - NOTE: this is the page id, not the group name or name entry. In the example above the page id is 0000:
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 - this happens to works as there is also a page id FF_Bath. In practice it depends on how your sitemap is defined, in many cases there is a sitemap page that corresponds to a group name, but we are getting the sitemap page id, not the group.:
<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
- all items (rest/items)
- an item group
- an item state
- a single page of a sitemap
Whilst you can subscribe to these things, you do not get notifications on most of them. For example, when using streaming on items (/rest/items/item_name), you can only get responses from a single item (nothing else works, and I've tried), or sitemap pages (/rest/sitemaps/name/page_id). You do not get notifications from all items, item groups, or item states.
The behavior with sitemap pages is that you will only get notification on items that change, in the form of a widget response. This means that if you subscribe to a sitemap page that does not have any items defined (such as a group of groups, or a frame containing only groups) you will not receive any notifications.
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 receive notifications (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 (but read the NOTE).
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 suppress double broadcasts (no I don't know what this means, but I'm leaving it in). The tracking header is also necessary if you want to receive page-label and page-icon updates on streaming connections (see below).
NOTE: In practice this is much trickier than it sounds. You can subscribe to any sitemaps page that you want (as explained previously, items only works for specific items), but many sitemaps pages do not produce widget responses, in which case you will only receive page-label and icon updates. This is a json example of a page update, on a subscription to a sitemaps page called "Lights", with tracking id enabled:
{"widget":{"widgetId":"Lights_18","type":"Slider","label":"Landing [44%]","icon":"slider-40","switchSupport":"true","sendFrequency":"0","item":{"type":"DimmerItem","name":"landingMain","state":"44","link":"http://192.168.100.119:80/rest/items/landingMain"}}}
{"id":"Lights","title":"Lights","icon":"group","link":"http://192.168.100.119:80/rest/sitemaps/nicks/Lights","leaf":"false"}
Without the tracking id, you just get the "widget" entry. The tracking id can be any string (not just numbers), but "0" is a special case, it means "send me back a tracking id to use in the future", so if you use "0" as your tracking id, the first response will be a new tracking id. I would just use "1234" or some other random number.
You can safely leave out the tracking id header entry altogether, streaming works fine without it.
In addition, you must specify the data type that you wish to receive, either json or xml (you must include this in the headers - http://xxxxxxx?type=json/xml does not work):
Accept: application/json
If you don't include this, you'll see messages like:
15:38:26.773 WARN o.a.cpr.DefaultBroadcaster[:533] - This message Entry{message=Temperature_Heru_Outdoor (Type=NumberItem, State=6.9), multipleAtmoResources=null, future=org.atmosphere.cpr.BroadcasterFuture@52b0a53d} will be lost
In the log. This means you haven't defined what kind of response is expected.
NOTE: With websockets, you can't include headers in the normal way (the Java API doesn't accept normal headers), you have to attach them as a querystring, so the url would look like:
ws://192.168.100.119:8009/rest/sitemaps/nicks/Lights?Accept=application/json
or
http://192.168.100.119:8009/rest/sitemaps/nicks/Lights?Accept=application/json
Depending on what client you are using. I have this working without sending the X-Atmosphere-Transport: websocket header using python websockets-client.
While registering for changes to all items you will receive every item update which occurs in the openHAB bus. Each response will look like a response from /rest/items/. This method is designed for small devices, which does not have enough resources to create a websocket connection to every single item separately. NOTE: This does not seem to work as you can only subscribe to specific items, not groups.
When streaming a connection, openHAB automatically times out the connection after 5 minutes, so you have to reconnect to continue to receive notifications.
Please note: for sitemap resources 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.
This means that if you subscribe to a sitemap page, if anything changes on the page, you receive the entire page, and it is up to you to figure out what changed on it.
"X-Atmosphere-Transport: streaming" or "X-Atmosphere-Transport: websocket" should be set as HTTP Header. Also for websockets, in addition you need to include the normal HTTP websocket upgrade request headers. Most clients take care of this for you if you specify a websockets connection, but see the NOTE above for the data type requirement.
HTTP streaming or websocket connections receive only updated objects from the openHAB server. The received update could either be a widget 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.
If you are accessing the REST interface from another client (such as a python script), you can use python requests as shown in the Samples-REST (Note: the example shows long polling to get updates - I don't recommend this, streaming works better. I will try to update the examples), but this will block on responses, so each subscription should be run in it's own thread.
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
In order to access historical data you need to install HABmin. Afterwards check how to use its REST Persistance API in the according documentation.
###Windows
###FreeBSD
- Classic UI
- iOS Client
- Android Client
- Windows Phone Client
- GreenT UI
- CometVisu
- Kodi
- Slack
- Chrome Extension
- Cosm Persistence
- db4o Persistence
- Amazon DynamoDB Persistence
- Exec Persistence
- InfluxDB Persistence
- JDBC Persistence
- JPA Persistence
- Logging Persistence
- mapdb Persistence
- MongoDB Persistence
- MQTT Persistence
- my.openHAB Persistence
- MySQL Persistence
- rrd4j Persistence
- Sen.Se Persistence
- SiteWhere Persistence
- AKM868 Binding
- AlarmDecoder Binding
- Anel Binding
- Arduino SmartHome Souliss Binding
- Asterisk Binding
- Astro Binding
- Autelis Pool Control Binding
- BenQ Projector Binding
- Bluetooth Binding
- Bticino Binding
- CalDAV Binding
- Chamberlain MyQ Binding
- Comfo Air Binding
- Config Admin Binding
- CUL Transport
- CUL Intertechno Binding
- CUPS Binding
- DAIKIN Binding
- Davis Binding
- Denon Binding
- digitalSTROM Binding
- DMX512 Binding
- DSC Alarm Binding
- DSMR Binding
- eBUS Binding
- Ecobee Binding
- EDS OWSever Binding
- eKey Binding
- Energenie Binding
- EnOcean Binding
- Enphase Energy Binding
- Epson Projector Binding
- Exec Binding
- Freebox Binding
- Freeswitch Binding
- Frontier Silicon Radio Binding
- Fritz AHA Binding
- Fritz!Box Binding
- FritzBox-TR064-Binding
- FS20 Binding
- Garadget Binding
- Global Caché IR Binding
- GPIO Binding
- HAI/Leviton OmniLink Binding
- HDAnywhere Binding
- Heatmiser Binding
- Homematic / Homegear Binding
- HTTP Binding
- IEC 62056-21 Binding
- IHC / ELKO Binding
- ImperiHome Binding
- Insteon Hub Binding
- Insteon PLM Binding
- IPX800 Binding
- IRtrans Binding
- jointSPACE-Binding
- KNX Binding
- Koubachi Binding
- LCN Binding
- LightwaveRF Binding
- Leviton/HAI Omnilink Binding
- Lg TV Binding
- Logitech Harmony Hub
- MailControl Binding
- MAX!Cube-Binding
- MAX! CUL Binding
- MiLight Binding
- MiOS Binding
- Mochad X10 Binding
- Modbus Binding
- MPD Binding
- MQTT Binding
- MQTTitude binding
- MystromEcoPower Binding
- Neohub Binding
- Nest Binding
- Netatmo Binding
- Network Health Binding
- Network UPS Tools Binding
- Nibe Heatpump Binding
- Nikobus Binding
- Novelan/Luxtronic Heatpump Binding
- NTP Binding
- One-Wire Binding
- Onkyo AV Receiver Binding
- Open Energy Monitor Binding
- OpenPaths presence detection binding
- OpenSprinkler Binding
- OSGi Configuration Admin Binding
- Panasonic TV Binding
- panStamp Binding
- Philips Hue Binding
- Picnet Binding
- Piface Binding
- PiXtend Binding
- pilight Binding
- Pioneer-AVR-Binding
- Plex Binding
- Plugwise Binding
- PLCBus Binding
- Powermax alarm Binding
- Primare Binding
- Pulseaudio Binding
- Raspberry Pi RC Switch Binding
- RFXCOM Binding
- RWE Smarthome Binding
- Sager WeatherCaster Binding
- Samsung AC Binding
- Samsung TV Binding
- Serial Binding
- Sallegra Binding
- Satel Alarm Binding
- SimpleBinary Binding
- Sinthesi Sapp Binding
- Smarthomatic Binding
- Snmp Binding
- Somfy URTSI II Binding
- Sonance Binding
- Sonos Binding
- Souliss Binding
- Squeezebox Binding
- Stiebel Eltron Heatpump
- Swegon ventilation Binding
- System Info Binding
- TA CMI Binding
- TCP/UDP Binding
- Tellstick Binding
- TinkerForge Binding
- Tivo Binding
- UCProjects.eu Relay Board Binding
- VDR Binding
- Velleman-K8055-Binding
- Wago Binding
- Wake-on-LAN Binding
- Waterkotte EcoTouch Heatpump Binding
- Weather Binding
- Wemo Binding
- Withings Binding
- XBMC Binding
- xPL Binding
- Yamahareceiver Binding
- Zibase Binding
- Z-Wave Binding
- Asterisk
- DoorBird
- FIND
- Foscam IP Cameras
- LG Hombot
- Worx Landroid
- Heatmiser PRT Thermostat
- Google Calendar
- Linux Media Players
- Rainforest EAGLE Energy Access Gateway
- Roku Integration
- ROS Robot Operating System
- Telldus Tellstick
- Zoneminder
- Wink Hub (rooted)
- Wink Monitoring
- Transformations
- XSLT
- JSON
- REST-API
- Security
- Service Discovery
- Voice Control
- BritishGasHive-Using-Ruby
- Dropbox Bundle
A good source of inspiration and tips from users gathered over the years. Be aware that things may have changed since they were written and some examples might not work correctly.
Please update the wiki if you do come across any out of date information.
- Rollershutter Bindings
- Squeezebox
- WAC Binding
- WebSolarLog
- Alarm Clock
- Convert Fahrenheit to Celsius
- The mother of all lighting rules
- Reusable Rules via Functions
- Combining different Items
- Items, Rules and more Examples of a SmartHome
- Google Map
- Controlling openHAB with Android
- Usecase examples
- B-Control Manager
- Spell checking for foreign languages
- Flic via Tasker
- Chromecast via castnow
- Speedtest.net integration