Skip to content

Master Slave Operation 1.0

Calin Crisan edited this page Nov 15, 2020 · 16 revisions

Masters And Slaves

A qToggle device may act as a master for other slave qToggle devices. The master controls these slave devices and allows accessing them through its own API functions. A slave device can act as a master for other devices. Complex chained master-slave configurations can be obtained in this way.

Special API functions are supported by the master for listing, adding and removing slaves.

Slave devices are identified on the master by their names. The master must be prepared for a slave to change its name at any time.

Authentication of all API requests from master to slaves must be done by supplying tokens computed using the device's admin username and its corresponding password.

Master Device Constraints

Master devices must expose the "master" flag via the flags device attribute.

Master devices must support real date/time.

HTTP Status Codes

When the master calls API functions on a slave, the following status codes must be used in case of communication errors:

  • 502 Bad Gateway

    This status is used to indicate an invalid response from the slave device. The following values are defined for the error field:

    • "invalid-device" - the device doesn't (properly) implement the qToggle API
    • "connection-refused" - connection refused on specified port
    • "unreachable" - the host/network is unreachable or any other network-related error
    • "other-error" - any other unexpected error; additional message field may provide more details
  • 503 Service Unavailable

    This status is used to indicate that the device is currently offline. The error field value must be "device-offline" (see Offline Devices).

  • 504 Gateway Timeout

    This status is used to indicate a timeout when communicating with the slave device. The error field value must be "device-timeout". The timeout used when waiting for the slave device's response is up to the implementation.

API Call Forwarding

All API requests made to master at locations starting with /devices/{name}/forward, with some exceptions listed below, must be synchronously forwarded to the device named name, to the corresponding API function path. In fact, the master should act as an HTTP proxy for the slave devices. For example, GET /device/mydev1/forward/device on master should be equivalent to a call to GET /device on the slave named mydev1.

For offline devices, requests to /devices/{name}/forward/device, /devices/{name}/forward/webhooks and /devices/{name}/forward/reverse must be intercepted by the master. In these cases, when receiving GET requests to these paths, the master must use cached values to provide a response to the consumer, if all cached field values are available. Upon receiving a PATCH request to these paths, the master must update the cached values accordingly and mark the changes for Offline Devices Provisioning.

Requests to unknown (unregistered) slave devices must be responded with a 404 Not Found and an error field set to "no-such-device".

Slave Ports

All ports from slave devices must be exposed directly by the master. Slave port identifiers exposed by the master must have the slave device name prepended to them, followed by a dot. For example, port gpio1 on slave device mydev1 would be exposed by the master under the id mydev1.gpio1. From the API point of view, the port should behave just like any regular port attached directly to the master.

After adding a slave to the master, all mechanisms on master must take the slave and its ports into account.

The master must keep a cache of all attributes of slave ports, including their values, so that they are available even when a slave device is offline.

Attributes

Slave port attributes must be made available on master. They must be kept synchronized between the master and the slave. The following attributes must however be treated separately:

id

The id attribute must be exposed by the master as indicated above.

tag

The tag attribute should never be synchronized with the slave. A master-only value should be kept for this attribute.

expression

The expression attribute must be handled separately, on master, as described in Expressions.

history_interval

The history_interval attribute must be handled separately, on master, as described in History.

history_retention

The history_retention attribute must be handled separately, on master, as described in History.

online

The online attribute must be exposed by master and must take into account the online status of the corresponding slave device. The value of the port attribute, as exposed by the master, must be:

  • false for:

    • a disabled port
    • a port whose value is expired
    • a port whose value never expires but belongs to an offline slave device
  • the value reported by the slave port itself, or true if the port itself does not expose the online attribute, in any other case

last_sync

The last_sync attribute must be exposed by master and represents the moment, expressed as seconds since Epoch, when the last value was received for the port; 0 should be used when this information is not available.

The master should not generate port-update events when last_sync changes, since the information can be deduced by the consumer from the value-change event.

This number attribute is not modifiable.

expires

The expires attribute must be exposed by master and represents the number of seconds after which a port value is considered expired. The special 0 value signifies that the port value never expires, and should be used as a default by the master.

The master must use last_sync in conjunction with expires to determine if a port value has expired or not. A port whose value has expired must have its online attribute set to false.

This number attribute is modifiable. Valid values go from 0 to 2147483647.

provisioning

The provisioning attribute must be exposed by master and represents the list of names of all port attributes (or value) that have been marked for provisioning (see Offline Devices Provisioning).

This list of string attribute is not modifiable.

Expressions

Setting a slave port-dependent value expression on a master port should work as expected, given that slave ports are treated by master as any other local port. Setting a master port-dependent value expression on a slave port must also be possible, but the expression itself must never be forwarded to the slave, but rather stored and processed on the master device, given that the slave has no knowledge of the master.

The master should keep track of both a master-side and a slave-side expression for each slave port that supports expressions. Both attributes could be set at the same time and they could (and most likely will) have different, unrelated expressions, one evaluated by the master and the other evaluated by the slave.

The slave-side expression attribute of the slave device, if present, must be exposed by master under the name device_expression. The master-side expression attribute of the slave device, if present, must be exposed by the master under the name expression.

Moreover, in order to support complex master-slave chainings, the master should prepend the string device_ to any additional slave attribute that starts with device_ and ends with _expression.

Transform expressions are transparent to the master-slave mechanism.

History

On master devices that support history, the master history mechanism must be completely independent of that present on the slave (if the latter is present, at all).

The master should keep track of both a master-side and a slave-side set of history attributes (history_interval and history_retention) for each port belonging to slaves that support history. The former set will control the history mechanism on master, while the latter will be used to allow control the history mechanism on the slave, directly via master (if slave supports history).

The slave-side set of history attributes of the slave device, if present, must be exposed by master using the device_ prefix (e.g. device_history_interval). The master-side history attributes of the slave device will simply have their unmodified name.

Moreover, in order to support complex master-slave chainings, the master should prepend the string device_ to any additional slave attribute that starts with device_ and ends with _history_interval or _history_retention.

Sequences

The sequences must be forwarded and executed directly on the slave device. There is no way for the master to know about the state of the sequences running on its slaves, therefore the slave ports should be treated all the time by the master as executing no current sequence.

If however the port in question has a master expression, the request must be rejected with 400 Bad Request and an error field set to "port-with-expression".

Slave Events

There are three ways in which the master can be notified about slave events:

  • the listening mechanism
  • device polling
  • webhooks

Regardless of the way events reach the master, they must be treated as any other locally generated event, with the except of a slave generated device-update event, which must be translated into a slave-device-update event.

For slave devices that support listening, when the listen slave parameter is true, the master must use a listening client to get informed of the slave events. When the poll_interval slave parameter is greater than 0, the master must use a polling client to get informed of the slave events.

The master device must cache slave device and port attributes, so that these details are available even when a slave is offline.

Device Polling

When polling is enabled (poll_interval is greater than 0), the master must call GET /device on the slave at fixed intervals, indicated by the poll_interval slave parameter, to detect attribute changes.

Similarly, the master must then call GET /ports on the slave at fixed intervals, indicated by the poll_interval slave parameter, to detect port changes.

The master must then locally generate events corresponding to any additions, removals and changes detected after polling.

Webhooks

Slaves can be configured to send events to the master by leveraging the webhooks functionality. The master should not attempt to automatically configure the webhooks mechanism on its slaves. It must however expect events to be pushed by slaves via HTTP requests at POST /devices/{name}/events. These events must be treated locally just like any other slave event.

The master must however ignore events transmitted via webhooks by slave devices that are disabled. It must also ignore events transmitted via webhooks by slave devices that are registered with listening or polling mechanisms enabled.

For each slave device that supports webhooks, the master must keep a local cache with its webhooks parameters. The master may regularly poll the slave device to update the local cache with the new parameters.

At the end of the Offline Devices Provisioning procedure, in the absence of any webhooks provisioning parameters, the master must query devices that support webhooks and update its local cached parameters.

Reverse API Calls

For each slave device that supports reverse API calls, the master must keep a local cache with its reverse API calls parameters. The master may regularly poll the slave device to update the local cache with the new parameters.

At the end of the Offline Devices Provisioning procedure, in the absence of any reverse API calls provisioning parameters, the master must query devices that support reverse API calls and update its local cached parameters.

Disabled Devices

A slave device can be explicitly disabled and reenabled afterwards using the PATCH /devices/{name} API function. The enabled parameter of a slave device indicates whether the slave device is active on the master or not.

The internal mechanisms of the master should treat inactive slaves just as if they weren't present at all. No requests should be forwarded to disabled slaves; instead, the request should be responded with 404 Not Found and an error field set to "no-such-device". When it comes to ports, enabling and disabling a slave device should have the same effect as adding and removing it.

Offline Devices

The master should keep an internal online state for each of its registered slaves. It should continuously monitor its slaves and update the internal online state accordingly, triggering the corresponding events.

For slaves with listening enabled, the master must use the listening mechanism to detect offline devices: a slave device not responding correctly to a listen request within the established listen timeout (plus a guard interval left to the implementation) is considered offline.

For slaves with polling enabled, the master must use the Device Polling mechanism to detect offline devices: a slave device not responding correctly to a polling request within a timeout interval (left to the implementation) is considered offline.

Permanently Offline Devices

If both listening and polling are disabled, the device is considered permanently offline. Devices that are permanently offline usually employ the Webhooks mechanism to send events to the master, whenever they need to. Permanently offline devices must however be reachable at least when they are added to the master.

Offline Devices Provisioning

The master must implement a way to provision offline devices with new values for:

  • device attributes
  • webhooks parameters (for devices that implement webhooks)
  • reverse API calls parameters (for devices that implement reverse API calls)
  • port attributes
  • port values

Internal provisioning flags should be used to mark device/port attributes, port values or any other parameters that have been changed via master during the offline period.

As soon as the device gets back online, the master must immediately provision it with the new values, issuing corresponding requests to the device. For Permanently Offline Devices, as soon as the master receives a request to POST /devices/{name}/events from the offline slave, it can assume the device is reachable for a limited period of time; the master must then immediately provision it with the new values, issuing corresponding requests to the device with the updated values.

In case of slave API call errors, the master may employ a retry mechanism. The provisioning flags should be cleared when the master succeeds pushing the provisioning values to the slave, or upon reaching a certain number of retries.

When receiving events carrying new attribute values or port values from a slave, values associated locally with a provisioning flag that is set must be ignored by the master.

The provisioning field of a slave device contains the list of all device attributes that are marked for provisioning. In addition to the attributes, the presence of values "webhooks" and "reverse" indicate the provisioning status of webhooks and reverse API call parameters, respectively.

An additional provisioning attribute must be exposed by each slave port through master. The attribute is a list of strings containing the name of each port attribute that has been marked for provisioning. In addition to the attributes, the presence of "value" indicates the provisioning status of the port value.

Device Names

Slave devices are uniquely identified on master by their name. The master must not have two or more devices with the same name, at the same time. The master must also not have a slave with the same name as its own.

When adding a new slave, the master must first fetch its attributes and refuse the addition if the name conditions above are not met.

Upon receiving events from an existing slave, the master must check for name changes. If the name has been changed, it must update all internal references to the device's name (e.g. port identifiers, persisted data). If however, the new name is a duplicate, the slave must be disabled.

Slave Parameters

A slave device is defined on the master by the following parameters:

  • name - the device name (a reported by the slave device)
  • scheme determines the transport protocol used and can be either http or https; for devices that don't support SSL, the only accepted value should be http
  • host is the client's host (HTTP server in this case); this can be either an IP address or a DNS domain name
  • port - is the client's TCP port
  • path - the base path at which the qToggle API functions are available (without any trailing slash)
  • admin_password - the admin access level password admin (recommended to be kept as a sha256 hash)
  • poll_interval - the polling interval, in seconds (see Device Polling). Valid values range from 0 to 86400. 0 signifies that polling is disabled
  • listen - whether to enable the listening mechanism for this device or not

Backup & Restore

To restore slave devices on a master device, the consumer should use the PUT /devices API call to this end.

With regards to the GET /backup/endpoints API call, a master device must not list the /devices endpoint as an extra endpoint to be backed up. The consumer of a master device should identify that it talks to a master device by the presence of the "master" device flag and decide whether it wants to also backup/restore the slave devices or not.

Restoring /devices must take place before /ports, given that the ports backup section may contain master-specific attributes corresponding to slave ports. To that end, the order used for PUT /devices should be 15.

When it comes to PUT /ports, dealing with local ports (those that live on master) must be done as indicated by the qToggle API specifications. However, ports that reside on slaves must be treated differently: the master must not forward any of their attributes to the corresponding slaves. Instead, attributes that live on master (such as expression) must be restored as indicated in the request, while purely remote attributes should be ignored. A restore operation on master should never attempt to update values on slave ports.

History

Event Types

slave-device-update

A slave-device-update event is triggered by the master whenever:

  • the slave parameters kept by the master are changed
  • the device online status changes as described in Offline Devices
  • the attributes of a slave device are updated

This event must however not be triggered when a slave device is renamed. Instead, the slave-device-remove event must be triggered for the device with the old name, followed by a slave-device-add event, with the new name.

The master should also avoid triggering this event when last_sync is updated.

This event has the same parameters as an element of the list returned by the GET /devices API function call.

This event type requires admin access level.

slave-device-add

A slave-device-add event is triggered by the master when a new slave device has been added using POST /devices. This event might be triggered by a master device at startup, when loading slaves; for slaves that are already known to a consumer, the consumer should handle slave-device-add events just like a slave-device-update event.

This event has the same parameters as an element of the list returned by the GET /devices API function call.

This event type requires admin access level.

slave-device-remove

A slave-device-remove event is triggered by the master when a slave device has been removed using DELETE /devices/{name}. This event has the following parameters:

{
    "name": string
}

This event type requires admin access level.

API Functions

All valid API requests made to URIs starting with /devices/{name}/forward must be forwarded synchronously to the slave device with the given name. The response must be relayed back to the consumer.

GET /devices

Returns the list of slave devices registered to this master device.

This API function requires admin access level.

Response has the following body:

[
    {
        "name": string,
        "enabled": boolean,
        "scheme": string,
        "host": string,
        "port": number,
        "path": string,
        "admin_password_hash": string,
        "poll_interval": number,
        "listen_enabled": boolean,
        "online": boolean,
        "last_sync": number,
        "provisioning": string[]
        "attrs": {...}
     },
     ...
]

Each record in the list represents a slave device.

  • online represents the online state of the slave device (see Offline Devices)
  • last_sync represents the moment, expressed as seconds since Epoch, of the last successful communication with the slave device; if no communication has been done, this must be 0
  • provisioning - is a list of attribute names and other parameters that are marked for provisioning (see Offline Devices Provisioning)
  • attrs represents the cached slave device attributes, as returned by the GET /device API call
  • admin_password_hash represents the sha256 lowercase hex digest of the device's admin password

For the rest of the fields, see Parameters.

The response body may contain JSON References.

Example:

Consumer's request:

GET /devices HTTP/1.1
Host: device.example.com
Connection: close
Cache-Control: no-cache
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJhZG1pbiIsImlhdCI6MTUxNjIzOTAyMiwib3JpIjoiY29uc3VtZXIiLCJpc3MiOiJxVG9nZ2xlIn0.-Ckcvq_Gk6RsW3pa-diWWiqQ4za0MCNGCXvdio1MK5Y

Device's response:

HTTP/1.1 200 OK
Connection: close
Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
Content-Length: n

[
    {
        "name": "kitchen_device",
        "enabled": true,
        "scheme": "http",
        "host": "192.168.1.4",
        "port": 80,
        "path": "/",
        "admin_password_hash": "6cad63595165fc39c9a3c715b874d406758bccb91e98106db8cd21da3150f658",
        "poll_interval": 0,
        "listen_enabled": true,
        "online": true,
        "last_sync": 1524599833,
        "provisioning": ["frequency", "webhooks"],
        "attrs": {
            "name": "kitchen_device",
            "description": "Kitchen Device",
            "version": "3.14.15f",
            "api_version": "1.0",
            "flags": ["firmware", "listen", "webhooks", "reverse", "ssl"],
            "frequency": "40",
            "sleep_timeout": "300",
            "definitions": {
                "frequency": {
                    "description": "The operating frequency of the device",
                    "type": "number",
                    "modifiable": true,
                    "unit": "MHz",
                    "choices": [
                        "20",
                        "40",
                        "80"
                    ]
                },
                "sleep_timeout": {
                    "description": "Interval of inactivity after which device enters sleep mode",
                    "type": "number",
                    "modifiable": true,
                    "unit": "seconds",
                    "min": 1,
                    "max": 3600,
                    "integer": true
                }
            }
        }
    },
    {
        "name": "garage_device",
        "enabled": true,
        "scheme": "http",
        "host": "192.168.1.9",
        "port": 8080,
        "path": "/qtoggle",
        "admin_password_hash": "6cad63595165fc39c9a3c715b874d406758bccb91e98106db8cd21da3150f658",
        "poll_interval": 3600,
        "listen_enabled": false,
        "online": false,
        "last_sync": 0,
        "provisioning": [],
        "attrs": {
            "name": "garage_device",
            "description": "Garage Device",
            "version": "3.14.16g",
            "api_version": "1.0",
            "flags": ["firmware", "listen", "webhooks", "reverse", "ssl"],
            "frequency": "80",
            "sleep_timeout": "300",
            "definitions": {
                "frequency": {
                    "description": "The operating frequency of the device",
                    "type": "number",
                    "modifiable": true,
                    "unit": "MHz",
                    "choices": [
                        "20",
                        "40",
                        "80"
                    ]
                },
                "sleep_timeout": {
                    "description": "Interval of inactivity after which device enters sleep mode",
                    "type": "number",
                    "modifiable": true,
                    "unit": "seconds",
                    "min": 1,
                    "max": 3600,
                    "integer": true
                }
            }
        }
    }
]

PUT /devices

Replaces the entire slave devices configuration, removing and adding devices as necessary.

This API function requires admin access level.

Request has the same body format as the one returned by GET /devices.

The master must begin by removing all slave devices. Then, for each element in the list of devices, which is a dictionary with slave device parameters, the master must add the corresponding slave device, similarly to what a POST /devices API call would do.

The master must silently ignore any field in the dictionary that is not used when adding a device; these include at least: online, last_sync, provisioning and attrs; enabled field should be honored. However, any error when creating a slave device (including missing fields) must immediately stop the processing of the request and must result in a corresponding error response.

Event generation should be suspended during the processing of this request. Instead, a full-update event should be generated at the end of the request, to inform consumers about the changes.

The master may attempt to add multiple slave devices concurrently, instead of waiting for the response of each one, thus reducing the total amount of time needed for the entire request.

The master should wait for all enabled (and non-permanently offline) slave devices to come online before responding to this request.

Response has no body.

Particular status codes: the possible status codes in case of an error are, with few exceptions, the status codes of POST /devices combined with those of PATCH /devices/{name}. In case of error, the additional index field indicates the 0-based position inside the request list that caused the error.

Example:

Consumer's request:

PUT /device HTTP/1.1
Host: device.example.com
Connection: close
Cache-Control: no-cache
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJhZG1pbiIsImlhdCI6MTUxNjIzOTAyMiwib3JpIjoiY29uc3VtZXIiLCJpc3MiOiJxVG9nZ2xlIn0.-Ckcvq_Gk6RsW3pa-diWWiqQ4za0MCNGCXvdio1MK5Y
Content-Type: application/json; charset=utf-8
Content-Length: n

[
    {
        "enabled": true,
        "scheme": "http",
        "host": "192.168.1.4",
        "port": 80,
        "path": "/",
        "admin_password_hash": "6cad63595165fc39c9a3c715b874d406758bccb91e98106db8cd21da3150f658",
        "poll_interval": 0,
        "listen_enabled": true
    },
    {
        "enabled": true,
        "scheme": "http",
        "host": "192.168.1.9",
        "port": 8080,
        "path": "/qtoggle",
        "admin_password_hash": "6cad63595165fc39c9a3c715b874d406758bccb91e98106db8cd21da3150f658",
        "poll_interval": 3600,
        "listen_enabled": false
    }
]

Device's response:

HTTP/1.1 204 No Content
Connection: close

POST /devices

Adds a new slave device to this master device.

A request to GET /device must be issued by the master on the new slave device to test the connectivity and to retrieve the device attributes.

The slave device must be reachable when added to the master. The device must always be added as enabled.

This API function requires admin access level.

Request has the following body:

{
    "scheme": string,
    "host": string,
    "port": 8080,
    "path": string,
    "admin_password": string,
    "poll_interval": number,
    "listen_enabled": boolean
}

Fields poll_interval and listen_enabled are optional. If not supplied, the master must check the slave device flags attribute and, if slave device indicates listening support, the master must enable the listening mechanism; otherwise, it should enable polling with a default interval of choice.

For more details on the meaning of each field, see Parameters.

Response has the same body as one of the list elements in the response of the GET /devices API function call, representing the attributes of the newly added device.

The response body may contain JSON References.

Particular status codes:

  • 400 Bad Request - error field values:
    • "duplicate-device" - a device with this name or these parameters already exists
    • "forbidden" - authentication/authorization problems
    • "no-listen-support" - listen_enabled was set to true but device does not support listening
    • "listening-and-polling" - both listening and polling are enabled (poll_interval is greater than 0 and listen_enabled is true)
    • "invalid-field" - one of the fields is invalid; additional field field indicates the name of the field:
      • "scheme" - the given scheme is not supported
      • "host" - the given host is not a valid hostname, domain name or IP address
      • "port" - the given port is not a number between 1 and 65535
      • "poll_interval" - poll_interval is not an integer between 0 and 86400

Example:

Consumer's request:

POST /devices HTTP/1.1
Host: device.example.com
Connection: close
Cache-Control: no-cache
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJhZG1pbiIsImlhdCI6MTUxNjIzOTAyMiwib3JpIjoiY29uc3VtZXIiLCJpc3MiOiJxVG9nZ2xlIn0.-Ckcvq_Gk6RsW3pa-diWWiqQ4za0MCNGCXvdio1MK5Y
Content-Type: application/json; charset=utf-8
Content-Length: n

{
    "scheme": "http",
    "host": "192.168.1.4",
    "port": 80,
    "path": "/",
    "admin_password": "test1234",
    "poll_interval": 60,
    "listen_enabled": false
}

Device's response:

HTTP/1.1 201 Created
Connection: close
Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
Content-Length: n

{
    "name": "kitchen_device",
    "enabled": true,
    "scheme": "http",
    "host": "192.168.1.4",
    "port": 80,
    "path": "/",
    "admin_password_hash": "937e8d5fbb48bd4949536cd65b8d35c426b80d2f830c5c308e2cdec422ae2244",
    "poll_interval": 0,
    "listen_enabled": true,
    "online": true,
    "last_sync": 1524599833,
    "attrs": {
        "name": "kitchen_device",
        "description": "Kitchen Device",
        "version": "3.14.15f",
        "api_version": "1.0",
        "flags": ["firmware", "listen", "webhooks", "reverse", "ssl"],
        "frequency": "40",
        "sleep_timeout": "300",
        "definitions": {
            "frequency": {
                "description": "The operating frequency of the device",
                "type": "number",
                "modifiable": true,
                "unit": "MHz",
                "choices": [
                    "20",
                    "40",
                    "80"
                ]
            },
            "sleep_timeout": {
                "description": "Interval of inactivity after which device enters sleep mode",
                "type": "number",
                "modifiable": true,
                "unit": "seconds",
                "min": 1,
                "max": 3600,
                "integer": true
            }
        }
    }
}

PATCH /devices/{name}

Updates a slave device on this master device.

This API function requires admin access level.

Request has the following body:

{
    "enabled": boolean,
    "poll_interval": number,
    "listen_enabled": boolean
}

All fields are optional. It is an error to have both polling and listen enabled.

For more details on the meaning of each field, see Parameters.

Response has no body.

Particular status codes:

  • 400 Bad Request - error field values:
    • "invalid-field" - one of the fields is invalid; additional field field indicates the name of the field:
      • "poll_interval" - poll_interval is not an integer between 0 and 86400
    • "no-listen-support" - listen_enabled was set to true but device does not support listening
    • "listening-and-polling" - both listening and polling are enabled (poll_interval is greater than 0 and listen_enabled is true)
  • 404 Not Found - error field values:
    • "no-such-device" - a slave device with the given name is not present on this master

Example:

Consumer's request:

PATCH /devices/kitchen_device HTTP/1.1
Host: device.example.com
Connection: close
Cache-Control: no-cache
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJhZG1pbiIsImlhdCI6MTUxNjIzOTAyMiwib3JpIjoiY29uc3VtZXIiLCJpc3MiOiJxVG9nZ2xlIn0.-Ckcvq_Gk6RsW3pa-diWWiqQ4za0MCNGCXvdio1MK5Y
Content-Type: application/json; charset=utf-8
Content-Length: n

{
    "enabled": true
}

Device's response:

HTTP/1.1 204 No Content
Connection: close

DELETE /devices/{name}

Removes a slave device from this master device.

This API function requires admin access level.

Path has the following arguments:

  • name specifies the name of the slave device to be removed

Request has no body.

Response has no body.

Particular status codes:

  • 404 Not Found - error field values:
    • "no-such-device" - a slave device with the given name is not present on this master

Example:

Consumer's request:

DELETE /devices/kitchen_device HTTP/1.1
Host: device.example.com
Connection: close
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJhZG1pbiIsImlhdCI6MTUxNjIzOTAyMiwib3JpIjoiY29uc3VtZXIiLCJpc3MiOiJxVG9nZ2xlIn0.-Ckcvq_Gk6RsW3pa-diWWiqQ4za0MCNGCXvdio1MK5Y

Device's response:

HTTP/1.1 204 No Content
Connection: close

POST /devices/{name}/events

Receives a slave event and treats it locally. This API call is intended to be used with slave device webhooks.

Validation of the authentication token for this API function must be made by computing the signature using the slave's admin_password; the expected ori claim must be "device" and the usr claim must be ignored.

The response to this API call should not contain any authentication token.

Path has the following arguments:

  • name specifies the name of the slave device sending events

Request has the following body:

{
    "type": string,
    "params": any
}

Fields type and params represent the type and the parameters of the event.

The request body may contain JSON References.

Response has no body.

Particular status codes:

  • 400 Bad Request - error field values:
    • "polling-enabled" - device has polling enabled
    • "listening-enabled" - device has listening enabled
  • 404 Not Found - error field values:
    • "no-such-device" - a slave device with the given name is not present on this master or is disabled

Example:

Consumer's request:

POST /devices/kitchen_device/events HTTP/1.1
Host: device.example.com
Connection: close
Cache-Control: no-cache
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJhZG1pbiIsImlhdCI6MTUxNjIzOTAyMiwib3JpIjoiY29uc3VtZXIiLCJpc3MiOiJxVG9nZ2xlIn0.-Ckcvq_Gk6RsW3pa-diWWiqQ4za0MCNGCXvdio1MK5Y
Content-Type: application/json; charset=utf-8
Content-Length: n

{
    "type": "value-change",
    "params": {
        "id": "gpio0",
        "value": true
    }
}

Device's response:

HTTP/1.1 204 No Content
Connection: close