Scenes
In the context of IoT in general and ESP RainMaker in particular, a "scene" refers to a group of parameters set to specific values, where one or more devices may span across multiple nodes. For example, an "evening" scene may turn on all the lights and adjust them to a warm color. A "night" scene may turn off all the lights, activate the bedside lamp at minimal brightness, and switching on the fan or AC.
Note that the scene is a static entity, and some operation is required to activate a scene, be it via phone apps, voice assistants, or a predefined schedule.
In line with the rest of the ESP RainMaker features, scenes are 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 so, let's first understand the specifications.
You may also directly jump to Usage.
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
.
Add a New Scene
A new scene can be added by passing a value like this in setparams
:
{
"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. The ID 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, or 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. For example, for turning on the light, it will be
"Light": {"power": true}
.
Once the scene is added successfully, a get on params will report a similar value like below:
{
"Scenes": {
"Scenes": [{
"name": "Evening",
"id": "8D36",
"info": "My Test Scene",
"action": {
"Light": {
"Power": true
}
}
}]
}
}
Note: When you add or update scenes, a single entry is sent in the scenes array. However, when you query scenes, 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 should 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.
For instance, if the 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}}
, not just "action":{"Light": {"Brightness":100}}
.
Remove
To remove an existing scene, you just need to pass its ID and "operation": "remove"
. See the example below.
{
"Scenes": {
"Scenes": [{
"id": "8D36",
"operation": "remove"
}]
}
}
Activate
To activate a scene, you just need to pass its ID and "operation": "activate"
. See the example below.
{
"Scenes": {
"Scenes": [{
"id": "8D36",
"operation": "activate"
}]
}
}
Note: This can also be used as the action for adding a schedule.
Deactivate
As the name suggests, this is opposite operation of activation, but the payload will be similar, just with "operation": "deactivate"
. See the example below.
{
"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 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 behavior. 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 described above, scene information is maintained by nodes, instead of 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. During 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 devices 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 with RainMaker Alexa Skill or Google Actions enabled.