-
Notifications
You must be signed in to change notification settings - Fork 0
Samples REST
Examples for accessing REST API
This page has samples in multiple languages for utilizing the three main REST interfaces for Items in OpenHAB:
-
Send Command - This will send a command to an item to tell it to take some action (e.g. turn on light).
-
Send Status - This is to indicate that the status of an item has changed (e.g. window is now open).
-
Get Status - Gets the current status of an item. (This can also be used to continuously get updates as shown in the Python section).
There is also a sitemap interface.
Accessing REST API via jquery (tested with jquery 2.0 and Chrome v26.0
Get state of an item:
function getState()
{
var request = $.ajax
({
type : "GET",
url : "http://192.168.100.21:8080/rest/items/MyLight/state"
});
request.done( function(data)
{
console.log( "Success: Status=" + data );
});
request.fail( function(jqXHR, textStatus )
{
console.log( "Failure: " + textStatus );
});
}
Set state of an item:
function setState( txtNewState )
{
var request = $.ajax
({
type : "PUT",
url : "http://192.168.100.21:8080/rest/items/MyLight/state",
data : txtNewState,
headers : { "Content-Type": "text/plain" }
});
request.done( function(data)
{
console.log( "Success" );
});
request.fail( function(jqXHR, textStatus )
{
console.log( "Failure: " + textStatus );
});
}
Send command to an item:
function sendCommand( txtCommand )
{
var request = $.ajax
({
type : "POST",
url : "http://192.168.100.21:8080/rest/items/MyLight",
data : txtCommand,
headers : { 'Content-Type': 'text/plain' }
});
request.done( function(data)
{
console.log( "Success: Status=" + data );
});
request.fail( function(jqXHR, textStatus )
{
console.log( "Failure: " + textStatus );
});
}
Accessing REST API via cURL. cURL is useful on shell scripts (Win/Linux/OS X) or e.g. on Automator (OS X).
Get state of an item:
curl http://192.168.100.21:8080/rest/items/MyLight/state
Set state of an item:
curl --header "Content-Type: text/plain" --request PUT --data "OFF" http://192.168.100.21:8080/rest/items/MyLight/state
Send command to an item:
curl --header "Content-Type: text/plain" --request POST --data "ON" http://192.168.100.21:8080/rest/items/MyLight
Accessing REST API via PHP. Simple PHP function to post a command to a switch using the REST interface.
Send command to an item:
function sendCommand($item, $data) {
$url = "http://192.168.1.121:8080/rest/items/" . $item;
$options = array(
'http' => array(
'header' => "Content-type: text/plain\r\n",
'method' => 'POST',
'content' => $data //http_build_query($data),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return $result;
}
Example function use:
sendCommand("doorbellSwitch", "ON");
If the post was successful the function will return the state you set, EG above returns "ON"
Accessing REST API via Python. Note that the rget status interface is set up to continuously receive updates rather than just getting a one time response. This is done with the "polling header" and the last section decodes the JSON response.
Send command to an item
def post_command(self, key, value):
""" Post a command to OpenHAB - key is item, value is command """
url = 'http://%s:%s/rest/items/%s'%(self.openhab_host,
self.openhab_port, key)
req = requests.post(url, data=value,
headers=self.basic_header())
if req.status_code != requests.codes.ok:
req.raise_for_status()
Set state of an item
def put_status(self, key, value):
""" Put a status update to OpenHAB key is item, value is state """
url = 'http://%s:%s/rest/items/%s/state'%(self.openhab_host,
self.openhab_port, key)
req = requests.put(url, data=value, headers=self.basic_header())
if req.status_code != requests.codes.ok:
req.raise_for_status()
Get state updates of an item (using long-polling)
def get_status(self, name):
""" Request updates for any item in group NAME from OpenHAB.
Long-polling will not respond until item updates.
"""
# When an item in Group NAME changes we will get all items in the group
# and need to determine which has changed
url = 'http://%s:%s/rest/items/%s'%(self.openhab_host,
self.openhab_port, name)
payload = {'type': 'json'}
try:
req = requests.get(url, params=payload,
headers=self.polling_header())
if req.status_code != requests.codes.ok:
req.raise_for_status()
# Try to parse JSON response
# At top level, there is type, name, state, link and members array
members = req.json()["members"]
for member in members:
# Each member has a type, name, state and link
name = member["name"]
state = member["state"]
do_publish = True
# Pub unless we had key before and it hasn't changed
if name in self.prev_state_dict:
if self.prev_state_dict[name] == state:
do_publish = False
self.prev_state_dict[name] = state
if do_publish:
self.publish(name, state)
HTTP Header definitions
def polling_header(self):
""" Header for OpenHAB REST request - polling """
self.auth = base64.encodestring('%s:%s'
%(self.username, self.password)
).replace('\n', '')
return {
"Authorization" : "Basic %s" % self.cmd.auth,
"X-Atmosphere-Transport" : "long-polling",
"X-Atmosphere-tracking-id" : self.atmos_id,
"X-Atmosphere-Framework" : "1.0",
"Accept" : "application/json"}
def basic_header(self):
""" Header for OpenHAB REST request - standard """
self.auth = base64.encodestring('%s:%s'
%(self.username, self.password)
).replace('\n', '')
return {
"Authorization" : "Basic %s" %self.auth,
"Content-type": "text/plain"}
Get state updates of an item (using streaming) NOTE: this is a class method, not a stand alone example
def get_status_stream(self, item):
"""
Request updates for any item in item from OpenHAB.
streaming will not respond until item updates. Can also use
Sitemap page id (eg /rest/sitemaps/name/0000) as long as it
contains items (not just groups of groups)
auto reconnects while parent.connected is true.
This is meant to be run as a thread
"""
connect = 0 #just keep track of number of disconnects/reconnects
url = 'http://%s:%s%s'%(self.openhab_host,self.openhab_port, item)
payload = {'type': 'json'}
while self.parent.connected:
if connect == 0:
log.info("Starting streaming connection for %s" % url)
else:
log.info("Restarting (#%d) streaming connection after disconnect for %s" % (connect, url))
try:
req = requests.get(url, params=payload, timeout=(310.0, 310), #timeout is (connect timeout, read timeout) note! read timeout is 310 as openhab timeout is 300
headers=self.polling_header(), stream=True)
if req.status_code != requests.codes.ok:
log.error("bad status code")
req.raise_for_status()
except requests.exceptions.ReadTimeout, e: #see except UnboundLocalError: below for explanation of this
if not self.parent.connected: # if we are not connected - time out and close thread, else retry connection.
log.error("Read timeout, exit: %s" % e)
break
except (requests.exceptions.HTTPError, requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError) as e:
log.error("Error, exit: %s" % e.message)
break
#log.debug("received response headers %s" % req.headers)
log.info("Data Received, streaming connection for %s" % url)
connect += 1
try:
while self.parent.connected:
message = ''
content = {}
for char in req.iter_content(): #read content 1 character at a time
try:
if char:
#log.debug(char)
message += char
content = json.loads(message)
break
except ValueError: #keep reading until json.loads returns a value
pass
#log.debug(content)
if len(content) == 0:
raise requests.exceptions.ConnectTimeout("Streaming connection dropped")
members = self.extract_content(content)
self.publish_list(members)
except UnboundLocalError: #needed because streaming on single item does not time out normally - so thread hangs.
pass
except (timeout, requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError) as e:
log.info("Socket/Read timeout: %s" % e.message)
except Exception, e:
log.error("Stream Unknown Error: %s, %s" % (e, e.message))
log.error("logging handled exception - see below")
log.exception(e)
log.info("Disconnected, exiting streaming connection for %s" % url)
if item in self.streaming_threads:
del(self.streaming_threads[item])
log.debug("removed %s from streaming_threads" % item)
def polling_header(self):
""" Header for OpenHAB REST request - streaming """
self.auth = base64.encodestring('%s:%s'
%(self.username, self.password)
).replace('\n', '')
return {
#"Authorization" : "Basic %s" % self.auth,
"X-Atmosphere-Transport" : "streaming",
#"X-Atmosphere-tracking-id" : self.atmos_id,
"Accept" : "application/json"}
def basic_header(self):
""" Header for OpenHAB REST request - standard """
self.auth = base64.encodestring('%s:%s'
%(self.username, self.password)
).replace('\n', '')
return {
#"Authorization" : "Basic %s" %self.auth,
"Content-type": "text/plain"}
def extract_content(self, content):
""" extract the "members" or "items" from content, and make a list """
# sitemap items have "id" and "widget" keys. "widget is a list of "item" dicts. no "type" key.
# items items have a "type" key which is something like "ColorItem", "DimmerItem" and so on, then "name" and "state". they are dicts
# items groups have a "type" "GroupItem", then "name" and "state" (of the group) "members" is a list of item dicts as above
if "type" in content: #items response
if content["type"] == "GroupItem":
# At top level (for GroupItem), there is type, name, state, link and members list
members = content["members"] #list of member items
elif content["type"] == "item":
members = content["item"] #its a single item dict *not sure this is a thing*
else:
members = content #its a single item dict
elif "widget" in content: #sitemap response
members = content["widget"]["item"] #widget is a list of items, (could be GroupItems) these are dicts
elif "item" in content:
members = content["item"] #its a single item dict
else:
members = content #don't know...
#log.debug(members)
if isinstance(members, dict): #if it's a dict not a list
members = [members] #make it a list (otherwise it's already a list of items...)
return members
Get state updates of an item/page (using websockets) you can decode the data in the same way as the above example
#!/usr/bin/env python
import websocket #need to run pip install websockets-client to get this module
class WSClient():
def __init__(self):
websocket.enableTrace(False) #True for debugging
def connect(self, url):
print("connecting to %s" % url)
self.ws = websocket.WebSocketApp(url,
on_message = self.on_message,
on_error = self.on_error,
on_close = self.on_close)
self.ws.on_open = self.on_open
self.ws.run_forever()
def on_message(self, ws, message):
print("Received:")
print(message)
def on_error(self, ws, error):
print(error)
def on_close(self, ws):
print("connection closed")
def on_open(self, ws):
print("connected")
def close(self, ws):
ws.close()
if __name__ == "__main__":
try:
client = WSClient()
client.connect("ws://192.168.100.119:8009/rest/sitemaps/nicks/Lights?Accept=application/json")
#client.connect("ws://192.168.100.119:8009/rest/items/landingMain?Accept=application/json")
#client.connect("ws://192.168.100.119:8009/rest/items/sensortag1IRAmbientTemp?Accept=application/json")
except (KeyboardInterrupt, SystemExit):
print("System exit Received - Exiting program")
client.close()
print(" **** Program Ended ****")
###Linux / OS X
###Windows
- Cosm Persistence
- db4o 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
- 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
- Comfo Air Binding
- Config Admin Binding
- CUL Binding
- 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
- FS20 Binding
- Global Cache 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
- Modbus TCP Binding
- MPD Binding
- MQTT Binding
- MQTTitude 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 Bindung
- panStamp Binding
- Philips Hue Binding
- Piface Binding
- pilight Binding
- Pioneer-AVR-Binding
- Plex Binding
- Plugwise Binding
- PLCBus Binding
- Primare Binding
- Pulseaudio Binding
- RFXCOM Binding
- RWE Smarthome Binding
- Sager WeatherCaster Binding
- Samsung AC Binding
- Samsung TV Binding
- Serial Binding
- Sallegra Binding
- Satel Alarm Binding
- Sinthesi Sapp Binding
- Snmp Binding
- Somfy URTSI II Binding
- Sonos Binding
- Squeezebox Binding
- Swegon ventilation Binding
- System Info Binding
- TA CMI Binding
- TCP/UDP Binding
- Tellstick Binding
- TinkerForge Binding
- Tivo 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
- Google Calendar
- Linux Media Players
- 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.
- Comfo Air Binding
- Ecobee Examples
- Nest Examples
- Rollershutter Bindings
- Squeezebox
- WAC Binding
- WebSolarLog
- Alarm Clock
- Convert Farenheit to Celcius
- 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