Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| sandbox:api [2023/02/10 23:13] – [JavaScript Example] davel17 | sandbox:api [2025/02/18 20:36] (current) – created - external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Indigo Web Server Design Notes 2022.2 ====== | ||
| + | |||
| + | In Indigo v2022.2, we’re completely redesigning the web server plugin (commonly referred to as IWS). The major components of the new web server are: | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | We’re introducing two new APIs: | ||
| + | |||
| + | - Websocket API – (which the new Indigo Touch Web UI will use), and | ||
| + | - HTTP API – will share as much of the messaging construction with the websocket interface as is practical. | ||
| + | |||
| + | Both of these APIs are authenticated with HTTP Digest and API Keys (either as a query string or an Authorization header which is preferable) depending on how the user configures it in the Start Local Server dialog. We’re **deprecating HTTP Basic authentication**. This version of the plugin will support all the necessary endpoints for Indigo Touch as outlined below. | ||
| + | |||
| + | We also intend to **deprecate** the [[https:// | ||
| + | |||
| + | ===== Python vs JavaScript ===== | ||
| + | |||
| + | In these APIs, we’re using JSON (JavaScript Object Notation) as the message format for communicating between the Websocket and HTTP APIs and IWS. In JavaScript, an “object” definition looks (almost) exactly like a Python dictionary (and vice versa). So we may refer to an object or dictionary (dict): for the purposes of this document, they refer to the same JSON construct. A simple example, we may call this an object or a dict: | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | We expect that there will be both Python and JavaScript users integrating our APIs, so we wanted to explicitly call this out. As a primarily Python organization, | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | // These comments can not be in the actual JSON payload and should be removed. | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Python developers will notice the use of '' | ||
| + | |||
| + | ^Python^JSON Equivalent^ | ||
| + | |True |true | | ||
| + | |False |false | ||
| + | |float |Number | ||
| + | |int | ||
| + | |None |null | | ||
| + | |dict |Object | ||
| + | |list |Array | ||
| + | |tuple |Array | ||
| + | |||
| + | ===== Versioning ===== | ||
| + | |||
| + | Starting with Indigo 2022.2, we’re implementing an API versioning scheme. For the original URLs, we’ll implement these for Indigo Touch older than 3.0 (or maybe 2023.1 or whatever): | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Moving forward, all APIs will be versioned under the following scheme: | ||
| + | |||
| + | * '' | ||
| + | |||
| + | ===== API Command Summary ===== | ||
| + | |||
| + | ==== Websocket API V2 ==== | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | ==== HTTP API V2 ==== | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | ==== Control Page HTML rendering ==== | ||
| + | |||
| + | * '' | ||
| + | |||
| + | One exception is '' | ||
| + | |||
| + | ===== Websocket API v2 ===== | ||
| + | |||
| + | This is the API for websockets in the web server in Indigo v2022.2. Websockets are bidirectional TCP connections, | ||
| + | |||
| + | There are 5 websocket feeds that work over local IP or via the reflector: | ||
| + | |||
| + | * device-feed '' | ||
| + | * action-feed '' | ||
| + | * variable-feed '' | ||
| + | * page-feed '' | ||
| + | * log-feed '' | ||
| + | |||
| + | Each feed (except log-feed) will send the following server CRUD messages: | ||
| + | |||
| + | * **add** (when a new Indigo object is added) | ||
| + | * **refresh** (this message will return the entire Indigo object collection or a single Indigo object if one was requested) | ||
| + | * **update** (when an Indigo object changes) | ||
| + | * **delete** (when the Indigo object is deleted) | ||
| + | |||
| + | When a websocket connection is made, the client will receive two **refresh** messages: one with the entire collection of Indigo objects and the other with the entire collection of Indigo folders corresponding to the feed (device folders in the device-feed, | ||
| + | |||
| + | At any time, the client can request a refresh, and Indigo will return the entire object hierarchy again (or the specific object) in a refresh message. If an '' | ||
| + | |||
| + | The log-feed is different in that it will only send **add** messages with the appropriate log event object defined below. | ||
| + | |||
| + | ==== JavaScript Example ==== | ||
| + | |||
| + | For JavaScript developers, the following functions are examples of how to use the '' | ||
| + | |||
| + | <code javascript> | ||
| + | /** | ||
| + | * This function will return the color of the border that we draw around event | ||
| + | * log entries based on the typeVal of the message (see the EventTypes | ||
| + | * enumeration for details). | ||
| + | * | ||
| + | * @param le - the log event object | ||
| + | * */ | ||
| + | function getBorderColor(le) { | ||
| + | let eType = le.typeVal; | ||
| + | if (eType === EventTypes.Error || eType === EventTypes.Error_Client) { | ||
| + | return ' | ||
| + | } else if (eType === EventTypes.Warning || eType === EventTypes.Warning_Client) { | ||
| + | return ' | ||
| + | } else if ( | ||
| + | eType === EventTypes.Debug_Client || | ||
| + | eType === EventTypes.Debug_Plugin || | ||
| + | eType === EventTypes.Debug_Server) | ||
| + | { | ||
| + | return ' | ||
| + | } else { | ||
| + | return theme.colors[" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * This function will determine the color of the message or the color of the type | ||
| + | * string in log view. | ||
| + | * | ||
| + | * @param le - the log event object | ||
| + | * @param part - return the color for this part of the message (primarily the message | ||
| + | | ||
| + | */ | ||
| + | function getTextColor(le, | ||
| + | let eType = le.typeVal; | ||
| + | if (eType === EventTypes.Error || eType === EventTypes.Error_Client) { | ||
| + | return ' | ||
| + | } else if (eType === EventTypes.Warning || eType === EventTypes.Warning_Client) { | ||
| + | return ' | ||
| + | } else if ( | ||
| + | eType === EventTypes.Debug_Client || | ||
| + | eType === EventTypes.Debug_Plugin || | ||
| + | eType === EventTypes.Debug_Server) | ||
| + | { | ||
| + | return ' | ||
| + | } else { | ||
| + | if (part === " | ||
| + | return theme.colors.secondary; | ||
| + | } else { | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Messages from clients to the server are specific to the feed type and are described below. | ||
| + | |||
| + | ===== HTTP API v2 ===== | ||
| + | |||
| + | Messages sent to the HTTP API are formatted in exactly the same way as those used with the websockets API. | ||
| + | |||
| + | ==== Python API Command Example ==== | ||
| + | |||
| + | For Python developers, here is a sample script that sends a device toggle request to the HTTP API: | ||
| + | |||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | API_KEY = " | ||
| + | COMMAND_URL = " | ||
| + | |||
| + | headers = {" | ||
| + | |||
| + | toggle_message_target_id = 1198679701 | ||
| + | toggle_message = { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | print(f" | ||
| + | reply = requests.post(url=COMMAND_URL, | ||
| + | print(f" | ||
| + | print(f" | ||
| + | </ | ||
| + | |||
| + | ===== API Object Types ===== | ||
| + | |||
| + | ==== Folder Objects ==== | ||
| + | |||
| + | First, every object type (except logs) may have folders. This is an example of a folder object. It is the same for any folder in any feed ('' | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Folder messages work in any of the websockets (except the log-feed websocket). The following are messages that you’ll receive from the server. | ||
| + | |||
| + | === Example add folder message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example update folder message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example delete folder message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh folder server message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh all folders server message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Device Feed ===== | ||
| + | |||
| + | We’re using the '' | ||
| + | |||
| + | < | ||
| + | ws:// | ||
| + | wss:// | ||
| + | http:// | ||
| + | http:// | ||
| + | </ | ||
| + | |||
| + | ==== Server messages ==== | ||
| + | |||
| + | You’ll receive full device JSON objects which will represent an Indigo device. Each device will be slightly different based on the device class and the definition (if a custom device). See the Indigo Object Model docs for device details. | ||
| + | |||
| + | === Example device object (dictionary in Python) === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Here are some examples of the server messages that clients will receive on the device feed. | ||
| + | |||
| + | === Example add device message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example update device message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Device patch objects are created via the [[https:// | ||
| + | |||
| + | === Example delete device message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh a single device message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh all devices message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Client messages ==== | ||
| + | |||
| + | Messages sent from clients to the server. This will most often be commands to control a device, but there are a few other commands (refresh). | ||
| + | |||
| + | === Device refresh messages === | ||
| + | |||
| + | These messages are sent to the server to refresh a single device, the entire device list, a single device folder, or the entire device folder list. | ||
| + | |||
| + | === refresh device object(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | // Specify the object type | ||
| + | " | ||
| + | // Specifying an objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified object. If no id is specified, the whole object list will be | ||
| + | // returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === refresh device folder(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | // Specifying a objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified folder. If no folder is specified, the whole folder | ||
| + | // list will be returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Device command messages ==== | ||
| + | |||
| + | === indigo.device === | ||
| + | |||
| + | These commands can be used on any Indigo device type - it can be considered the “base” class for messages | ||
| + | |||
| + | **status request** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | // Note, this won't necessarily cause a device update message - if the device | ||
| + | // didn't have any changes after the status request, there will be no updates | ||
| + | // to the device in the server, so no update message will be received. | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **toggle** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **turn off** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **turn on** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **lock** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **unlock** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === indigo.dimmer === | ||
| + | |||
| + | **brighten** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **dim** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set brightness** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set brightness** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === indigo.iodevice === | ||
| + | |||
| + | **set binary output** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === indigo.sensor === | ||
| + | |||
| + | **set on state** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === indigo.speedcontrol === | ||
| + | |||
| + | **decrease speed index** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **increase speed index** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set speed index** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set speed level** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === indigo.sprinkler === | ||
| + | |||
| + | **next zone** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **previous zone** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **pause schedule** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **resume schedule** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **run schedule** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **stop schedule** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set active zone** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === indigo.thermostat === | ||
| + | |||
| + | **decrease heat setpoint** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **increase heat setpoint** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | %%**%%set heat setpoint | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **decrease cool setpoint** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **increase cool setpoint** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set cool setpoint** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set hvac mode** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **set fan mode** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Variable Feed ===== | ||
| + | |||
| + | We implemented the '' | ||
| + | |||
| + | < | ||
| + | ws:// | ||
| + | wss:// | ||
| + | http:// | ||
| + | http:// | ||
| + | </ | ||
| + | |||
| + | ==== Server messages ==== | ||
| + | |||
| + | You’ll receive full variable JSON objects which will represent an Indigo variable. | ||
| + | |||
| + | === Example variable object (dictionary in Python) === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Here are some examples of the server messages that clients will receive on the variable feed. | ||
| + | |||
| + | === Example add variable message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example update variable message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Variable patch objects are created via the [[https:// | ||
| + | |||
| + | === Example delete variable message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh a single variable message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh all variables message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Client messages ==== | ||
| + | |||
| + | Messages sent from clients to the server. This will most often be commands to update a variable, but there are a few other commands (refresh). | ||
| + | |||
| + | ==== Refresh messages ==== | ||
| + | |||
| + | These messages are sent to the server to refresh a single variable, the entire variable list, a single variable folder, or the entire variable folder list. | ||
| + | |||
| + | === refresh variable object(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | // Specify the object type | ||
| + | " | ||
| + | // Specifying an objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified object. If no id is specified, the whole object list will be | ||
| + | // returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === refresh variable folder(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | // Specifying a objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified folder. If no folder is specified, the whole folder | ||
| + | // list will be returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Variable command messages ==== | ||
| + | |||
| + | This is the only command message you can send to the variable feed. | ||
| + | |||
| + | === updateValue === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | // Note, values passed in the parameter dictionary must be strings. You can | ||
| + | // pass in an empty string ("" | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Action Group Feed ===== | ||
| + | |||
| + | We implemented the '' | ||
| + | |||
| + | < | ||
| + | ws:// | ||
| + | wss:// | ||
| + | http:// | ||
| + | http:// | ||
| + | </ | ||
| + | |||
| + | ==== Server messages ==== | ||
| + | |||
| + | You’ll receive full variable JSON objects which will represent an Indigo action group. | ||
| + | |||
| + | === Example action group object (dictionary in Python) === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | }, | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Here are some examples of the server messages that clients will receive on the action feed. | ||
| + | |||
| + | === Example add action group message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example update action group message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Variable patch objects are created via the [[https:// | ||
| + | |||
| + | === Example delete action group message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh a single action group message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh all action groups message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Client messages ==== | ||
| + | |||
| + | Messages sent from clients to the server. This will most often be commands to execute an action group, but there are a few other commands (refresh). | ||
| + | |||
| + | ==== Refresh messages ==== | ||
| + | |||
| + | These messages are sent to the server to refresh a single action group, the entire action group list, a single action group folder, or the entire action group folder list. | ||
| + | |||
| + | === refresh action group object(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | // Specify the object type | ||
| + | " | ||
| + | // Specifying an objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified object. If no id is specified, the whole object list will be | ||
| + | // returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === refresh action group folder(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | // Specifying a objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified folder. If no folder is specified, the whole folder | ||
| + | // list will be returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Action Group command messages ==== | ||
| + | |||
| + | There is only one command message you can send to the action feed. | ||
| + | |||
| + | === execute === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Control Page Feed ===== | ||
| + | |||
| + | We implemented the '' | ||
| + | |||
| + | < | ||
| + | ws:// | ||
| + | wss:// | ||
| + | http:// | ||
| + | http:// | ||
| + | </ | ||
| + | |||
| + | ==== Server messages ==== | ||
| + | |||
| + | You’ll receive full variable JSON objects which will represent an Indigo control page. | ||
| + | |||
| + | === Example variable object (dictionary in Python) === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Here are some examples of the server messages that clients will receive on the variable feed. | ||
| + | |||
| + | === Example add page message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example update page message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Page patch objects are created via the [[https:// | ||
| + | |||
| + | === Example delete page message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh a single page message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Example refresh all pages message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Client messages ==== | ||
| + | |||
| + | Messages sent from clients to the server. This consists only of refresh requests since there are no other actions that can be taken on control pages. | ||
| + | |||
| + | ==== Refresh messages ==== | ||
| + | |||
| + | These messages are sent to the server to refresh a single page, the entire page list, a single page folder, or the entire page folder list. | ||
| + | |||
| + | === refresh page object(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | // Specify the object type | ||
| + | " | ||
| + | // Specifying an objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified object. If no id is specified, the whole object list will be | ||
| + | // returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === refresh variable folder(s) client message === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | // Specifying a objectId is optional. If it's included the server will send a refresh | ||
| + | // message for the specified folder. If no folder is specified, the whole folder | ||
| + | // list will be returned | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Log Feed ===== | ||
| + | |||
| + | We convert the event Indigo dictionary into a python dictionary in the '' | ||
| + | |||
| + | < | ||
| + | ws:// | ||
| + | wss:// | ||
| + | </ | ||
| + | |||
| + | ==== Server messages ==== | ||
| + | |||
| + | You’ll receive full variable JSON objects which will represent an Indigo log entry. | ||
| + | |||
| + | === Example log object (dictionary in Python) === | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | When you first open a websocket connection to the log feed, you’ll immediately receive the last 25 event log entries (individually) and any further event log entries as long as the connection is open. You only need one handler for messages coming from the log feed since they will always be objects as described above (the '' | ||
| + | |||
| + | Note that '' | ||
| + | |||
| + | <code python> | ||
| + | export enum EventTypes { | ||
| + | Application = 0, | ||
| + | Error, | ||
| + | Error_Client, | ||
| + | Warning, | ||
| + | Warning_Client, | ||
| + | Debug_Server, | ||
| + | Debug_Client, | ||
| + | Debug_Plugin, | ||
| + | Custom, | ||
| + | LastBaseEnumItem | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | You can use the values above to help determine any kind of decoration you want to use when displaying or otherwise interpreting the log event. | ||
| + | |||
| + | ===== Error Messaging ===== | ||
| + | |||
| + | Error messages will be returned to API clients in the event that something didn’t go as planned. The structure of messages returned will depend on what went wrong and how the message was sent. **Note that folder messages are added to the feed by the server; there are no folder endpoints to manage folders from a client at this time.** | ||
| + | |||
| + | A generic example message is provided in JSON format: | ||
| + | |||
| + | == Generic Error Message == | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | where the value of the JSON name (or key) '' | ||
| + | |||
| + | == Example API Call == | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | You will receive the following error response: | ||
| + | |||
| + | == Resulting Error Message == | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | }, | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | The '' | ||
| + | |||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | |||
| + | based on the '' | ||
| + | |||
| + | === Invalid JSON === | ||
| + | |||
| + | One other type of error that you may receive would be if you POST a string (or something else, like XML, etc.) that’s not JSON. This will result in the following message return: | ||
| + | |||
| + | == Example Invalid JSON Message == | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | We will just return the entire request body since it isn’t valid JSON and we don’t know what else to do with it. | ||