Node - Cloud communication
All the communication between the node and cloud happens over secure MQTT.
Security
TLS
The communication between node and the cloud is secured using TLS. It uses X.509 certificate based mutual authentication. The client key is generated on the node itself. It then generates a Certificate Signing Request (CSR) which is signed by a CA and given back to the node as a client certificate during the "Claiming" process.
MQTT Policies
The MQTT Policy for the node has been written such that a node can connect only if the client id matches the node id. Moreover, it can subscribe and publish only to topics with the prefix node/<node_id>/
Node Configuration
All the information pertaining to a node, like the node id, attributes, devices, params, etc. is combined into an object called the Node configuration. It is the first thing that is reported to ESP RainMaker Cloud as the node boots up. The same is reported as is to the clients like phone apps and CLI. The clients can parse and use it anyhow they want. You can add/edit this as per your requirements and handle appropriately in your clients.
The below is the node configuration that the ESP RainMaker firmware and Phone apps currently use.
Note: Entries in bold are mandatory. The strings in the parentheses indicate the corresponding key in the JSON representation and the data type.
- Node Id (node_id, String)
- Config Version (config_version, String)
- Information (info, Object)
- Name (name, String)
- FW Version (fw_version, String)
- Type (type, String)
- Node Attributes (attributes, Array of Objects)
- Name (name, String)
- Value (value, String)
- Devices (devices, Array of objects)
- Name (name, String)
- Type (type, String)
- Primary (primary, String)
- Device Attributes (attributes, Array of Objects)
- Name (name, String)
- Value (value, String)
- Params (params, Array of objects)
- Name (name, String)
- Data Type (data_type, String)
- Type (type, String)
- Properties (properties, Array of Strings)
- UI Type (ui_type, String)
- Bounds (bounds, Object)
- Minimum (min, Number)
- Maximum (max, Number)
- Step (step, Number)
MQTT
- Topic
node/<node_id>/config
- Operation:
PUBLISH
- Data:
Node configuration JSON object described below
- Eg. Sample node configuration
Node Parameters
All parameter changes are managed through specific node parameter topics
Initial Reporting
MQTT
- Topic
node/<node_id>/params/local/init
- Operation:
PUBLISH
- Data:
{"<device-name">:{"<param-name>":<value>,...},...}
- Example:
{
"Lightbulb": {
"name": "Bedroom Light",
"power": true,
"brightness": 55
}
}
Initial reporting is done every time the node boots up. Values of all the parameters of all the devices are reported in this.
Subsequent reporting
MQTT
- Topic
node/<node_id>/params/local
- Operation:
PUBLISH
- Data:
{"<device-name">:{"<param-name>":<value>,...},...}
- Example
{
"Lightbulb": {
"brightness": 75
}
}
Any subsequent changes on the node, either due to remote control or a local change is reported on this topic. Only the parameter that has changed is required in the payload
Remote Control
MQTT
- Topic
node/<node_id>/params/remote
- Operation:
SUBSCRIBE
- Data:
{"<device-name">:{"<param-name>":<value>,...},...}
- Example
{
"Lightbulb": {
"brightness": 100
}
}
A node must always stay subscribed to this topic, listening for updates triggered by the clients like phone apps or CLI. Any change in parameter values as per the updates must be reported back using the "Subsequent Reporting"
User-Node mapping
Before the devices under a node can be monitored and controlled remotely, the node should be first mapped to a user so that only that specific user can have permissions to access it. This happens in the background during the Wi-Fi provisioning stage. The node sends its node_id to the client and the client sends the user_id and secret_key to the node for mapping. Once connected to the RainMaker Cloud, the node sends the mapping request. Please check here for detailed workflow.
MQTT
- Topic
node/<node_id>/user/mapping
- Operation:
PUBLISH
- Data:
{"node_id":"<node_id>","user_id":"<user_id>","secret_key": "<secret_key>"}
- Example
{
"node_id": "112233AABBCC",
"user_id": "02e95749-8d9d-4b8e-972c-43325ad27c63",
"secret_key": "9140ef1d-72be-48d5-a6a1-455a27d77dee"
}
Appendix: Sample Node Configuration
Here is a sample node configuration with 2 devices
{
"node_id": "5d898491-a498-48ec-9476-a4e23519fe31",
"config_version": "2019-02-27",
"info": {
"name": "My_Bridge",
"fw_version": "1.0",
"type": "Bridge"
},
"attributes": [{
"name": "serial_num",
"value": "123abc"
}, {
"name": "model",
"value": "myBridge-2019"
}],
"devices": [{
"name": "Switch",
"primary": "power",
"params": [{
"name": "name",
"type": "esp.param.name",
"data_type": "string",
"properties": ["read", "write"]
}, {
"name": "power",
"data_type": "bool",
"properties": ["read", "write", "time_series"],
"ui_type": "esp.ui.toggle"
}]
}, {
"name": "Light",
"type": "esp.device.lightbulb",
"attributes": [{
"name": "serial_number",
"value": "012345"
}, {
"name": "mac",
"value": "xx:yy:zz:aa:bb:cc"
}],
"primary": "power",
"params": [{
"name": "name",
"type": "esp.param.name",
"data_type": "string",
"properties": ["read", "write"]
}, {
"name": "power",
"data_type": "bool",
"properties": ["read", "write", "time_series"],
"ui_type": "esp.ui.toggle"
}, {
"name": "brightness",
"data_type": "int",
"properties": ["read", "write"],
"bounds": {
"min": 0,
"max": 100
},
"ui_type": "esp.ui.slider"
}]
}]
}