Scenes
In the context of IoT in general and ESP RainMaker in particular, a Scene is a group of parameters with specific values, for one or more devices (optionally) spanning across multiple nodes. As an example, an "Evening" scene may turn on all the lights and set them to a warm colour. A "Night" scene may turn off all the lights, turn on a bedside lamp set to minimal brightness and turn on the fan/ac.
Note that scene is a static entity and some operation would be required to activate a scene, be it via phone apps, voice assistants or via a schedule.
In line with the rest of the ESP RainMaker features, scenes have been implemented completely on the node side in the form of a "service". The cloud backend just acts as a conduit between the node and the clients (like Phone apps).
The entire complexity of the scenes feature is hidden beneath a simple C API and also abstracted out by the phone apps. Even then, let's first understand the specifications.
You may also skip directly to Usage if you want.
Specifications
The scenes service consists of a single parameter which is an array of objects. It shows up in the node configuration as this:
"services": [{
"name": "Scenes",
"params": [{
"bounds": {
"max": 10
},
"data_type": "array",
"name": "Scenes",
"properties": [
"read",
"write"
],
"type": "esp.param.scenes"
}],
"type": "esp.service.scenes",
"attributes": [{
"name": "deactivation_support",
"value": "no"
}]
}]
The scenes parameter is an empty array by default. The "max" bound indicates the maximum number of scenes a node can have. Deactivation support will be disabled by default, but can be enabled using CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT
.
Adding a new scene
A new scene can be added by passing a value like this in set-param
{
"Scenes": {
"Scenes": [{
"name": "Evening",
"id": "8D36",
"info": "My Test Scene",
"operation": "add",
"action": {
"Light": {
"Power": true
}
}
}]
}
}
- name: A user friendly name for the scene.
- id: A unique ID for the scene. (This needs to be unique only for the given user not universally unique). This should be generated by the client while adding a scene, and then used for any further operations. A shorter id is desirable.
- info (Optional): Additional info or description as per the clients' requirements.
- flags (Optional): General purpose flags which can be used as per the clients' requirements.
- operation: The operation to be performed. Possible values are add, remove, edit, activate and deactivate.
- action: The actual action to be performed when the scene is activated. The value of this object will be same as what you pass while setting the params. Eg. For turning on Light, it will be
"Light": {"power": true}
.
Once the scene is added successfully, a get on params will the report a similar value like below:
{
"Scenes": {
"Scenes": [{
"name": "Evening",
"id": "8D36",
"info": "My Test Scene",
"action": {
"Light": {
"Power": true
}
}
}]
}
}
Note: While adding or updating scenes, a single entry is sent in the scenes array. However, when queried, the node will return information of all the scenes in the array.
Other operations
Edit
Value passed for editing the scene will be similar to that passed for adding. The ID should match an existing scene and the "operation" value will be "edit". You can either send the entire object or only the elements that have changed (name or action). However the objects in these keys cannot be partial.
Eg. If current action is "action":{"Light": {"Power": true, "Brightness":90}}
, and you need to change brightness to 100, you should pass "action":{"Light": {"Power": true, "Brightness":100}}
and not just "action":{"Light": {"Brightness":100}}
Remove
For removing an existing scene you just need to pass its ID and "operation": "remove"
.
Eg.
{
"Scenes": {
"Scenes": [{
"id": "8D36",
"operation": "remove"
}]
}
}
Activate
To activate a scene, you just need to pass its ID and "operation": "activate"
.
Eg.
{
"Scenes": {
"Scenes": [{
"id": "8D36",
"operation": "activate"
}]
}
}
Note: This can also be used as an "action" while adding a schedule.
Deactivate
As the name suggests, this is opposite of activate, and the payload will be similar, just with "operation": "deactivate"
.
Eg.
{
"Scenes": {
"Scenes": [{
"id": "8D36",
"operation": "deactivate"
}]
}
}
Note that deactivation won't be supported by default in the firmware. Please see Usage section for additional information.
Usage
Firmware
The ESP RainMaker exposes a single API to enable scenes
esp_err_t esp_rmaker_scenes_enable(void);
This API should be called after
esp_rmaker_node_init()
but beforeesp_rmaker_start()
.
The maximum number of scenes supported can be configured by using the CONFIG_ESP_RMAKER_SCENES_MAX_SCENES
config option (idf.py menuconfig -> ESP RainMaker Config -> ESP RainMaker Scenes -> Maximum scenes
).
Deactivation support can be enabled by setting CONFIG_ESP_RMAKER_SCENES_DEACTIVATE_SUPPORT=y
. This is kept disabled by default because deactivating a scene would require saving the previous values of params and then restoring them to those values, which could be complex and can also lead to inconsistent behaviour. The RainMaker core does not do this even if the support is enabled. It will just invoke the appropriate service write callback whenever a deactivation request is received. Saving/restoring the values will have to be managed by the application registered callback.
Whenever a scene "activation" request is received, the corresponding service write callback would be invoked with esp_rmaker_req_src_t
set to ESP_RMAKER_REQ_SRC_SCENE_ACTIVATE
. For "deactivation", the callback would be invoked with ESP_RMAKER_REQ_SRC_SCENE_DEACTIVATE
Phone Apps
The latest Android and iOS apps have support for scenes. You may directly check this feature in the apps.
Scenes across nodes
As we have seen, scenes information is maintained by the nodes, and not by the cloud backend. However, it is a common requirement to have multiple nodes as part of a single scene. For such scenes, the client uses the same scene ID across multiple nodes. Even while querying, it looks for common scene IDs across all the nodes and shows them together. A sample payload for creating a scene across multiple nodes is as shown below:
POST on {{base_url}}/v1/user/nodes/params
with payload:
[{
"node_id": "<nodeid_1>",
"payload": {
"Scenes": {
"Scenes": [{
"name": "Night1",
"operation": "add",
"id": "1112",
"action": {
"Light": {
"Power": true,
"Hue": 280
}
}
}]
}
}
}, {
"node_id": "<nodeid_2>",
"payload": {
"Scenes": {
"Scenes": [{
"name": "Night1",
"operation": "add",
"id": "1112",
"action": {
"Switch": {
"Power": true
}
}
}]
}
}
}]
Scenes with 3P Integrations
Even though the ESP RainMaker backend acts like a conduit between device and clients, scenes are treated differently. The backend parses the scene information so that it can be reported to Alexa and Google Voice Assistant (GVA) in a format they can understand. So, any scenes created in RainMaker get exported to Alexa and GVA if the RainMaker skill/actions are enabled.