|
Controller 2.0 API Documentation
The following document describes the Controller 2.0 API.
By default the response format is XML, you can also use JSON. You needn't to specify Accept type in HTTP header, if you want to use JSON, see how to Use JSONP format in this document.
(1) Request panel identity list (since M6)
- Output: xml format or json format data
- Sample Response:
- content-type:application/xml:
<?xml version="1.0" encoding="UTF-8"?>
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.openremote.org/panel.xsd">
<panel id="1" name="father's iPhone"/>
<panel id="141" name="mother's iPad"/>
<panel id="263" name="my iPod touch"/>
</openremote>
- content-type:application/json:
 | Note
you should use the name attribute to request panel UI layout.
the name attribute is the logical identity and easier for user to remember and input. |
- Errors:
- Error Code:426, panel.xml not found Error.
- Error Code:427, Invalid panel.xml Error.
(2) Request panel UI layout by logical identity (since M6)
- Parameters: panel_logical_identity
- Sample Request Url(require URL percent escape):
- Output: xml format or json format data
- Sample Response:
- content-type:application/xml:
<?xml version="1.0" encoding="UTF-8"?>
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.openremote.org/panel.xsd">
<tabbar>
<item name="Livingroom">
<navigate toGroup="142" />
<image src="light1274952251695.png" />
</item>
<item name="Aircondition">
<navigate toGroup="142" toScreen="228" />
<image src="aircondition1274952362228.png" />
</item>
<item name="TV">
<navigate toGroup="142" toScreen="237" />
<image src="tvitem1274952294708.png" />
</item>
<item name="Bedroom">
<navigate toGroup="173" />
<image src="togroup1274952414154.png" />
</item>
<item name="Setting">
<navigate to="setting" />
<image src="setting1274952617279.png" />
</item>
<item name="Logout">
<navigate to="logout" />
<image src="logout1274952557426.png" />
</item>
<item name="Login">
<navigate to="login" />
<image src="login1274952785498.png" />
</item>
<item name="Back">
<image src="back1274952817159.png" />
</item>
</tabbar>
<screens>
<screen id="211" name="Light" inverseScreenId="218">
<background fillScreen="true">
<image src="lightbackground1274950957643.png" />
</background>
<absolute left="43" top="108" width="86" height="52">
<button id="212" name="turn on" hasControlCommand="true" />
</absolute>
<absolute left="175" top="108" width="95" height="52">
<button id="213" name="turn off" hasControlCommand="true" />
</absolute>
<absolute left="127" top="174" width="185" height="54">
<label id="214" fontSize="14" color="#0000FF" text="light status">
<link type="sensor" ref="570">
<state name="off" value="light is off" />
<state name="on" value="light is on" />
</link>
</label>
</absolute>
<absolute left="195" top="240" width="50" height="50">
<switch id="215">
<link type="sensor" ref="570">
<state name="on" value="power.png" />
<state name="off" value="infrared.png" />
</link>
</switch>
</absolute>
<absolute left="117" top="16" width="66" height="81">
<image id="216" src="OpenRemote.Logo.30x32.png">
<link type="sensor" ref="570">
<state name="off" value="lightbulboff1274951408852.png" />
<state name="on" value="lightbulb1274951401848.png" />
</link>
<include type="label" ref="214" />
</image>
</absolute>
</screen>
<screen id="218" name="Light" landscape="true" inverseScreenId="211">
<background relative="TOP">
<image src="500X3001274943015264.png" />
</background>
<absolute left="184" top="112" width="84" height="82">
<image id="219" src="OpenRemote.Logo.30x32.png">
<link type="sensor" ref="570">
<state name="off" value="lightbulboff1274951484491.png" />
<state name="on" value="lightbulb1274951481080.png" />
</link>
</image>
</absolute>
<absolute left="126" top="22" width="212" height="52">
<label id="220" fontSize="14" color="#FF6600" text="light state">
<link type="sensor" ref="570">
<state name="off" value="OFF" />
<state name="on" value="ON" />
</link>
</label>
</absolute>
<absolute left="143" top="209" width="150" height="50">
<label id="324" fontSize="14" color="#FFFFFF" text="Test gesture" />
</absolute>
<gesture id="221" hasControlCommand="true" type="swipe-bottom-to-top" />
<gesture id="222" hasControlCommand="true" type="swipe-top-to-bottom" />
<gesture id="223" hasControlCommand="true" type="swipe-left-to-right" />
<gesture id="224" hasControlCommand="true" type="swipe-right-to-left" />
</screen>
<screen id="228" name="Aircondition">
<background fillScreen="true">
<image src="air1274951021940.png" />
</background>
<absolute left="139" top="32" width="110" height="52">
<label id="229" fontSize="14" color="#3366FF" text="value">
<link type="sensor" ref="568" />
</label>
</absolute>
<absolute left="59" top="86" width="198" height="44">
<slider id="230" vertical="false" passive="false">
<link type="sensor" ref="568" />
<min value="0" />
<max value="100" />
</slider>
</absolute>
<absolute left="267" top="178" width="44" height="198">
<slider id="231" thumbImage="vthumb1274939161708.png" vertical="true" passive="false">
<link type="sensor" ref="568" />
<min value="0" image="vmin1274939127956.png" trackImage="vminTrack1274939151356.png" />
<max value="100" image="vmax1274939183784.png" trackImage="vmaxTrack1274939173529.png" />
</slider>
</absolute>
<absolute left="59" top="130" width="198" height="44">
<slider id="232" thumbImage="thumbImage1274939361119.png" vertical="false" passive="false">
<link type="sensor" ref="568" />
<min value="0" image="low1274939314970.png" trackImage="red1274939338142.png" />
<max value="100" image="high1274939397163.png" trackImage="green1274939382473.png" />
</slider>
</absolute>
<absolute left="39" top="31" width="130" height="52">
<label id="233" fontSize="14" color="#FF6600" text="temperature:" />
</absolute>
</screen>
<screen id="237" name="TV">
<background fillScreen="true">
<image src="tvbackground1274951037399.png" />
</background>
<absolute left="15" top="10" width="287" height="54">
<label id="238" fontSize="14" color="#000000" text="Test grid layout, Not send commnad" />
</absolute>
<grid left="51" top="65" width="210" height="200" rows="4" cols="3">
<cell x="0" y="0" rowspan="1" colspan="1">
<button id="239" name="On" />
</cell>
<cell x="2" y="0" rowspan="1" colspan="1">
<button id="240" name="Off" />
</cell>
<cell x="1" y="0" rowspan="1" colspan="1">
<button id="241" name="Mute" />
</cell>
<cell x="0" y="2" rowspan="1" colspan="1">
<button id="242" name="Vol-" />
</cell>
<cell x="2" y="2" rowspan="1" colspan="1">
<button id="243" name="Vol+" />
</cell>
<cell x="1" y="1" rowspan="1" colspan="1">
<button id="244" name="Ch+" />
</cell>
<cell x="1" y="3" rowspan="1" colspan="1">
<button id="245" name="Ch-" />
</cell>
<cell x="1" y="2" rowspan="1" colspan="1">
<button id="246" name="Menu" />
</cell>
</grid>
</screen>
<screen id="250" name="Navigate_Buttons">
<background fillScreen="true">
<image src="yesanpoh1274939752102.jpg" />
</background>
<absolute left="15" top="242" width="26" height="25">
<image id="251" src="turtle1274939826027.png" />
</absolute>
<grid left="110" top="262" width="200" height="150" rows="3" cols="4">
<cell x="0" y="0" rowspan="1" colspan="2">
<button id="252" name="Login">
<navigate to="login" />
</button>
</cell>
<cell x="2" y="0" rowspan="1" colspan="2">
<button id="253" name="Logout">
<navigate to="logout" />
</button>
</cell>
<cell x="0" y="1" rowspan="1" colspan="2">
<button id="254" name="Setting">
<navigate to="setting" />
</button>
</cell>
<cell x="2" y="1" rowspan="1" colspan="2">
<button id="255" name="Back">
<navigate to="back" />
</button>
</cell>
</grid>
</screen>
</screens>
<groups>
<group id="142" name="Livingroom">
<include type="screen" ref="211" />
<include type="screen" ref="218" />
<include type="screen" ref="228" />
<include type="screen" ref="237" />
</group>
<group id="173" name="Bedroom">
<include type="screen" ref="250" />
</group>
</groups>
</openremote>
- content-type:application/json:
{
"tabbar": {"item": [
{
"@name": "Livingroom",
"navigate": {"@toGroup": "142"},
"image": {"@src": "light1274952251695.png"}
},
{
"@name": "Aircondition",
"navigate": {
"@toGroup": "142",
"@toScreen": "228"
},
"image": {"@src": "aircondition1274952362228.png"}
},
{
"@name": "TV",
"navigate": {
"@toGroup": "142",
"@toScreen": "237"
},
"image": {"@src": "tvitem1274952294708.png"}
},
{
"@name": "Bedroom",
"navigate": {"@toGroup": "173"},
"image": {"@src": "togroup1274952414154.png"}
},
{
"@name": "Setting",
"navigate": {"@to": "setting"},
"image": {"@src": "setting1274952617279.png"}
},
{
"@name": "Logout",
"navigate": {"@to": "logout"},
"image": {"@src": "logout1274952557426.png"}
},
{
"@name": "Login",
"navigate": {"@to": "login"},
"image": {"@src": "login1274952785498.png"}
},
{
"@name": "Back",
"image": {"@src": "back1274952817159.png"}
}
]},
"screens": {"screen": [
{
"@id": "211",
"@name": "Light",
"@inverseScreenId": "218",
"background": {
"@fillScreen": "true",
"image": {"@src": "lightbackground1274950957643.png"}
},
"absolute": [
{
"@left": "43",
"@top": "108",
"@width": "86",
"@height": "52",
"button": {
"@id": "212",
"@name": "turn on",
"@hasControlCommand": "true"
}
},
{
"@left": "175",
"@top": "108",
"@width": "95",
"@height": "52",
"button": {
"@id": "213",
"@name": "turn off",
"@hasControlCommand": "true"
}
},
{
"@left": "127",
"@top": "174",
"@width": "185",
"@height": "54",
"label": {
"@id": "214",
"@fontSize": "14",
"@color": "#0000FF",
"@text": "light status",
"link": {
"@ref": "570",
"state": [
{
"@name": "off",
"@value": "light is off"
},
{
"@name": "on",
"@value": "light is on"
}
]
}
}
},
{
"@left": "195",
"@top": "240",
"@width": "50",
"@height": "50",
"switch": {
"@id": "215",
"link": {
"@ref": "570",
"state": [
{
"@name": "on",
"@value": "power.png"
},
{
"@name": "off",
"@value": "infrared.png"
}
]
}
}
},
{
"@left": "117",
"@top": "16",
"@width": "66",
"@height": "81",
"image": {
"@id": "216",
"@src": "OpenRemote.Logo.30x32.png",
"link": {
"@ref": "570",
"state": [
{
"@name": "off",
"@value": "lightbulboff1274951408852.png"
},
{
"@name": "on",
"@value": "lightbulb1274951401848.png"
}
]
},
"include": {"@ref": "214"}
}
}
]
},
{
"@id": "218",
"@name": "Light",
"@landscape": "true",
"@inverseScreenId": "211",
"background": {
"@relative": "TOP",
"image": {"@src": "500X3001274943015264.png"}
},
"absolute": [
{
"@left": "184",
"@top": "112",
"@width": "84",
"@height": "82",
"image": {
"@id": "219",
"@src": "OpenRemote.Logo.30x32.png",
"link": {
"@ref": "570",
"state": [
{
"@name": "off",
"@value": "lightbulboff1274951484491.png"
},
{
"@name": "on",
"@value": "lightbulb1274951481080.png"
}
]
}
}
},
{
"@left": "126",
"@top": "22",
"@width": "212",
"@height": "52",
"label": {
"@id": "220",
"@fontSize": "14",
"@color": "#FF6600",
"@text": "light state",
"link": {
"@ref": "570",
"state": [
{
"@name": "off",
"@value": "OFF"
},
{
"@name": "on",
"@value": "ON"
}
]
}
}
},
{
"@left": "143",
"@top": "209",
"@width": "150",
"@height": "50",
"label": {
"@id": "324",
"@fontSize": "14",
"@color": "#FFFFFF",
"@text": "Test gesture"
}
}
],
"gesture": [
{
"@id": "221",
"@hasControlCommand": "true"
},
{
"@id": "222",
"@hasControlCommand": "true"
},
{
"@id": "223",
"@hasControlCommand": "true"
},
{
"@id": "224",
"@hasControlCommand": "true"
}
]
},
{
"@id": "228",
"@name": "Aircondition",
"background": {
"@fillScreen": "true",
"image": {"@src": "air1274951021940.png"}
},
"absolute": [
{
"@left": "139",
"@top": "32",
"@width": "110",
"@height": "52",
"label": {
"@id": "229",
"@fontSize": "14",
"@color": "#3366FF",
"@text": "value",
"link": {"@ref": "568"}
}
},
{
"@left": "59",
"@top": "86",
"@width": "198",
"@height": "44",
"slider": {
"@id": "230",
"@vertical": "false",
"@passive": "false",
"link": {"@ref": "568"},
"min": {"@value": "0"},
"max": {"@value": "100"}
}
},
{
"@left": "267",
"@top": "178",
"@width": "44",
"@height": "198",
"slider": {
"@id": "231",
"@thumbImage": "vthumb1274939161708.png",
"@vertical": "true",
"@passive": "false",
"link": {"@ref": "568"},
"min": {
"@value": "0",
"@image": "vmin1274939127956.png",
"@trackImage": "vminTrack1274939151356.png"
},
"max": {
"@value": "100",
"@image": "vmax1274939183784.png",
"@trackImage": "vmaxTrack1274939173529.png"
}
}
},
{
"@left": "59",
"@top": "130",
"@width": "198",
"@height": "44",
"slider": {
"@id": "232",
"@thumbImage": "thumbImage1274939361119.png",
"@vertical": "false",
"@passive": "false",
"link": {"@ref": "568"},
"min": {
"@value": "0",
"@image": "low1274939314970.png",
"@trackImage": "red1274939338142.png"
},
"max": {
"@value": "100",
"@image": "high1274939397163.png",
"@trackImage": "green1274939382473.png"
}
}
},
{
"@left": "39",
"@top": "31",
"@width": "130",
"@height": "52",
"label": {
"@id": "233",
"@fontSize": "14",
"@color": "#FF6600",
"@text": "temperature:"
}
}
]
},
{
"@id": "237",
"@name": "TV",
"background": {
"@fillScreen": "true",
"image": {"@src": "tvbackground1274951037399.png"}
},
"absolute": {
"@left": "15",
"@top": "10",
"@width": "287",
"@height": "54",
"label": {
"@id": "238",
"@fontSize": "14",
"@color": "#000000",
"@text": "Test grid layout, Not send commnad"
}
},
"grid": {
"@left": "51",
"@top": "65",
"@width": "210",
"@height": "200",
"@rows": "4",
"@cols": "3",
"cell": [
{
"@x": "0",
"@y": "0",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "239",
"@name": "On"
}
},
{
"@x": "2",
"@y": "0",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "240",
"@name": "Off"
}
},
{
"@x": "1",
"@y": "0",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "241",
"@name": "Mute"
}
},
{
"@x": "0",
"@y": "2",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "242",
"@name": "Vol-"
}
},
{
"@x": "2",
"@y": "2",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "243",
"@name": "Vol+"
}
},
{
"@x": "1",
"@y": "1",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "244",
"@name": "Ch+"
}
},
{
"@x": "1",
"@y": "3",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "245",
"@name": "Ch-"
}
},
{
"@x": "1",
"@y": "2",
"@rowspan": "1",
"@colspan": "1",
"button": {
"@id": "246",
"@name": "Menu"
}
}
]
}
},
{
"@id": "250",
"@name": "Navigate_Buttons",
"background": {
"@fillScreen": "true",
"image": {"@src": "yesanpoh1274939752102.jpg"}
},
"absolute": {
"@left": "15",
"@top": "242",
"@width": "26",
"@height": "25",
"image": {
"@id": "251",
"@src": "turtle1274939826027.png"
}
},
"grid": {
"@left": "110",
"@top": "262",
"@width": "200",
"@height": "150",
"@rows": "3",
"@cols": "4",
"cell": [
{
"@x": "0",
"@y": "0",
"@rowspan": "1",
"@colspan": "2",
"button": {
"@id": "252",
"@name": "Login",
"navigate": {"@to": "login"}
}
},
{
"@x": "2",
"@y": "0",
"@rowspan": "1",
"@colspan": "2",
"button": {
"@id": "253",
"@name": "Logout",
"navigate": {"@to": "logout"}
}
},
{
"@x": "0",
"@y": "1",
"@rowspan": "1",
"@colspan": "2",
"button": {
"@id": "254",
"@name": "Setting",
"navigate": {"@to": "setting"}
}
},
{
"@x": "2",
"@y": "1",
"@rowspan": "1",
"@colspan": "2",
"button": {
"@id": "255",
"@name": "Back",
"navigate": {"@to": "back"}
}
}
]
}
}
]},
"groups": {"group": [
{
"@id": "142",
"@name": "Livingroom",
"include": [
{"@ref": "211"},
{"@ref": "218"},
{"@ref": "228"},
{"@ref": "237"}
]
},
{
"@id": "173",
"@name": "Bedroom",
"include": {"@ref": "250"}
}
]}
}
- Errors:
- Error Code:426, panel.xml not found Error.
- Error Code:427, Invalid panel.xml Error.
- Error Code:428, No such panel identity Error.
(3) Send a control command (since M6)
- Parameters:
- control_id : control id
- command_param :
- Switch: ON/OFF
- Slider: some integer or float, e.g. 27
- Button: click
- Gesture: swipe
- Output: HTTP response code.
- Errors:
- Error Code:418, Command Build Error. Happens when a Command can't be built from a DOM Element.
- Error Code:419, No Such Component Error.
- Error Code:420, No Such Command Builder Error.
- Error Code:422, controller.xml Not Found Error.
- Error Code:423, No Such Command Error.
- Error Code:424, Invalid controller.xml Error.
- Error Code:429, Invalid XML element Error.
(4) Sensor Status request (since M6)
- Desc: This service will return sensor current status immediately.
- Parameters: sensor_id list
- Output: xml format or json format data.
- Sample Response:
- content-type:application/xml:
<?xml version="1.0" encoding="UTF-8"?>
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.openremote.org/panel.xsd">
<status id="1">on</status>
<status id="2">off</status>
</openremote>
- content-type:application/json:
- Errors:
- Error Code:418, Command Build Error. Happens when a Command can't be built from a DOM Element.
- Error Code:419, No Such Component Error.
- Error Code:420, No Such Command Builder Error.
- Error Code:422, controller.xml Not Found Error.
- Error Code:423, No Such Command Error.
- Error Code:424, Invalid controller.xml Error.
- Error Code:429, Invalid XML element Error.
(5) Sensor Polling request (since M6)
- Desc: This service is used for listening and will hang up on server side, only return new status until the status of any sensor in sensor_id list is changed, or return 504 response code if no change occurs within 50 seconds. if you only need the current status, please call (4) Sensor Status request.
- Parameters: device_id(The unique id of device, used to track session to avoid missing change detection when refreshing polling after timeout), sensor_id list.
- Output: xml format or json format data.
- Sample Response:
if no status change occurs:
otherwise:
- content-type:application/xml:
<?xml version="1.0" encoding="UTF-8"?>
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.openremote.org/panel.xsd">
<status id="1">on</status>
<status id="2">off</status>
</openremote>
- content-type:application/json:
- Errors:
- Error Code:418, Command Build Error. Happens when a Command can't be built from a DOM Element.
- Error Code:419, No Such Component Error.
- Error Code:420, No Such Command Builder Error.
- Error Code:422, controller.xml Not Found Error.
- Error Code:423, No Such Command Error.
- Error Code:424, Invalid controller.xml Error.
- Error Code:429, Invalid XML element Error.
(6) Fail-over(Round-Robin) Group member RESTful service (since M6)
- Desc: This service will return all fail-over group members' url of current Controller.
- Output: xml format or json format data.
- Sample Response:
- content-type:application/xml:
<?xml version="1.0" encoding="UTF-8"?>
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<servers>
<server url="http://10.10.10.104:8080/controller" />
<server url="http://10.10.10.106:8080/controller" />
</servers>
</openremote>
- content-type:application/json:
- Errors:
- Error Code:450, Failed to start tcp server.
- Error Code:451, Failed to start udp server.
- Error Code:452, Failed to establish udp client.
- Error Code:453, Invalid groupmember service url.
How to get image URL
Image file name can be used to get image from URL by adding the resources/ prefix.
for example, if an image is named Picture21273208346008.png, you can get it by accessing http://0.0.0.0:8080/controller/resources/Picture21273208346008.png
Use JSONP format
JSON-P is a method of wrapping the JSON output of API calls to allow other developers to call cross site. To use JSON-P, developer should include a 'callback' as request parameter like this: http://localhost:8080/controller/rest/panels?callback=aaa
then response will be :
We provide JSON format by converting XML into JSON, some simple rules are used when converting REST XML into JSON objects, see http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html
Dynamic parameter value as command input
When it comes to generic protocol definitions (TCP/IP, Telnet connectors, etc.) in Building Modeler, we provide a way to pass command parameters.
Put ${param} literal somewhere in the command input (Building Modeler), when the string to send over TCP/IP is parsed in protocol handler (Controller), ${param} will be replaced with the command param value got from REST call.
So take slider for example:
(1) /rest/control/{slider_id}/128
with TCP/IP command mapping:
(2) 'SEND ${param}'
Will be parsed to"
(3) 'SEND 128'
XML Failure Responses
By default You can check response code for failure if you don't use JSON. When response code is not 200, that means a failure.
In addition to the response code, you can get the error message from the returned XML:
<?xml version="1.0" encoding="UTF-8"?>
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openremote.org http://www.openremote.org/schemas/controller.xsd">
<error>
<code>428</code>
<message>No such Panel :NAME = demo</message>
</error>
</openremote>
JSON Failure Responses
JSON API doesn't use response code because of JSONP error handling (sometimes ignores a timeout and doesn't fire the error event).
So JSON failure response code is also 200.
Sample response:
From JavaScript, you can check error attribute for failure, and then read the error from error.code and error.message.
|
|
|
|
|