-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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 websocket-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 ****")
wget --user=myusername --password=mypassword http://192.168.1.1:8080/CMD?My_Switch=OFF
When running OH2, the CMD path is now classicui/CMD and requires the Classic UI to be installed:
wget --user=myusername --password=mypassword http://192.168.1.1:8080/classicui/CMD?My_Switch=OFF
ℹ Please find all documentation for openHAB 2 under http://docs.openhab.org.
The wiki pages here contain (outdated) documentation for the older openHAB 1.x version. Please be aware that a lot of core details changed with openHAB 2.0 and this wiki as well as all tutorials found for openHAB 1.x might be misleading. Check http://docs.openhab.org for more details and consult the community forum for all remaining questions.
- Classic UI
- iOS Client
- Android Client
- Windows Phone Client
- GreenT UI
- CometVisu
- Kodi
- Chrome Extension
- Alfred Workflow
- Cosm Persistence
- db4o Persistence
- Amazon DynamoDB Persistence
- Exec Persistence
- Google Calendar Presence Simulator
- 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
- DD-WRT Binding
- Denon Binding
- digitalSTROM Binding
- DIY on XBee 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
- Expire Binding
- Fatek PLC 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
- Horizon Mediabox Binding
- HTTP Binding
- IEC 62056-21 Binding
- IHC / ELKO Binding
- ImperiHome Binding
- Insteon Hub Binding
- Insteon PLM Binding
- IPX800 Binding
- IRtrans Binding
- jointSPACE-Binding
- KM200 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
- MCP23017 I/O Expander Binding
- MCP3424 ADC 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
- PowerDog Local API 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
- Siemens Logo! 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
- UPB 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
- Osram Lightify
- Rainforest EAGLE Energy Access Gateway
- Roku Integration
- ROS Robot Operating System
- Slack
- Telldus Tellstick
- Zoneminder
- Wink Hub (rooted)
- Wink Monitoring
- openHAB Cloud Connector
- Google Calendar Scheduler
- 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