全球樂鑫科技代理商為您介紹ESP RainMaker功能擴展—服務 (Service),如果您一直關注樂鑫新聞和博客,應該對 ESP RainMaker 及其豐富的功能有所了解。若您對 ESP RainMaker 尚不了解,建議先點此了解相關信息,以便更好地理解本文內容。
全球樂鑫科技代理商ESP RainMaker 的重要特性之一是輕量化。它能夠充當 ESP 節點 (Node) 和移動端 App、Alexa、GVA(谷歌語音助手)等客戶端之間的“隧道”,所以具備極大的靈活性與可擴展性。ESP RainMaker 支持您創建任意設備,開發多種設備功能,并終通過移動端 App 實現設備控制。當然,我們預定義了一些默認類作為參考,您可以對其進行自定義更改,創建自己的設備和參數類型。
全球樂鑫科技代理商ESP RainMaker 節點 (Node) 所支持的功能是通過節點配置 (node configuration) 標記的,分為兩個部分:
.設備 (Device):指用戶可視化、可交互的功能,例如設備的開關及燈的亮度控制。
.服務 (Service):主要包括底層功能,例如恢復出廠設置、重啟設備、時區信息、定時等。
大多數 ESP RainMaker 開發者已在例程中了解并熟悉了設備 (Device) 的概念,而對服務 (Service) 較為陌生。它往往隱藏在 esp_rmaker_system_service_enable(),esp_rmaker_schedule_enable(),esp_rmaker_timezone_service_enable() 等 API 中,可以被移動端 App 調用。
服務 (Service) 的結構與設備 (Device) 類似,都由名稱 (name)、類型 (type) 和一系列的參數構成。因此,所有適用于設備 (Device) 的 API(包含固件 API 和云 API)也都適用于服務 (Service);同理,適用于設備 (Device) 的 GET /user/nodes?node_details=true,GET /user/nodes/config 和 GET/PUT /user/nodes/params API 也同樣適用于服務 (Service)。
我們預先定義了一些標準服務 (Service) 例程,您可以點此直接獲取。接下來,我們將進一步指導您如何添加自定義服務 (Service)。
定義用例
在創建服務 (Service) 之前,您需要先定義用例,以便于后續定義相應服務 (Service) 的參數。例如“診斷”服務 (Service),就可以讓開發者在移動端 App 開啟節點 (Node) 診斷功能并獲取診斷數據。
創建服務 (Service)
創建服務 (Service) 的基本代碼段包含以下 4 個部分:
.創建服務 (Service)
.注冊回調
.創建添加適用的參數
.將服務 (Service) 添加至節點 (Node)
/* Create the service using esp_rmaker_service_create(). However, note that a service uses esp_rmaker_device_t
* as the data type, since it is structurally same as a device.
*/
esp_rmaker_device_t *diag_service = esp_rmaker_service_create("Diagnostics","my.service.diag", NULL);
/* Register the write callback. Read callback would normally be NULL */
esp_rmaker_device_add_cb(diag_service, diag_write_cb, NULL);
/* Create and add paramaters of various types as applicable.
* Parameter types (like my.param.diag-trigger) are not mandatory, but useful to have.
*/
esp_rmaker_device_add_param(diag_service, esp_rmaker_param_create("Trigger", "my.param.diag-trigger", esp_rmaker_bool(false), PROP_FLAG_WRITE));
esp_rmaker_device_add_param(diag_service, esp_rmaker_param_create("Timestamp", "my.param.diag-timestamp", esp_rmaker_int(0), PROP_FLAG_READ));
esp_rmaker_device_add_param(diag_service, esp_rmaker_param_create("Data", "my.param.diag-data", esp_rmaker_obj("{}"), PROP_FLAG_READ));
/* Add the service to the node */
esp_rmaker_node_add_device(node, diag_service);
如果診斷參數的數量較少,我們可以分別定義整型/布爾型/浮點型/字符串類型的參數(如上述“Timestamp”)。但是如果參數數量較多,則推薦直接使用“對象 (Object)”類(如上述“Data”),然后在里面寫入所有的 JSON 參數對象。
注意,這里提到的參數并非必要參數,僅供參考。
由于本文展示的“診斷”服務 (Service) 參數類型較多,我們直接使用了對象 (Object) 類。該服務 (Service) 將在節點配置 (Node Configuration) 中顯示為服務數組 (Service Array)
同理,節點 (Node) 參數對象 (Object) 將如下所示:
{
“Diagnostics”:{
“Trigger”:false,
“Timestamp”:0,
“Data”:{}
}
}
處理服務回調 (Service Callback)
在上文的代碼中,我們已經將 diag_write_cb 定義為服務 (Service) 的寫回調函數。實現過程如下:
#include <json_generator.h>
static esp_err_t diag_write_cb(const esp_rmaker_device_t *device, const esp_rmaker_param_t *param,
const esp_rmaker_param_val_t val, void *priv_data, esp_rmaker_write_ctx_t *ctx)
{
/* This ctx check is just to find if the request was received via Cloud, Local network or Schedule.
* Having this is not required, but there could be some cases wherein specific operations may be allowed
* only via specific channels (like only Local network), where this would be useful.
*/
if (ctx) {
ESP_LOGI(TAG, "Received write request via : %s", esp_rmaker_device_cb_src_to_str(ctx->src));
}
/* Check if the write is on the "Trigger" parameter. We aren't really checking true/false as that
* is not much of a concern in this context. But you can add checks on the values too.
*/
if (strcmp(esp_rmaker_param_get_name(param), "Trigger") == 0) {
/* Here we start some dummy diagnostics and populate the appropriate values to be passed
* to "Timestamp" and "Data".
*/
ESP_LOGI(TAG, "Starting Diagnostics");
time_t current_timestamp = 0;
time(¤t_timestamp);
char buf[100] = {0};
json_gen_str_t jstr;
json_gen_str_start(&jstr, buf, sizeof(buf), NULL, NULL);
json_gen_start_object(&jstr);
json_gen_obj_set_bool(&jstr, "diag1", true);
json_gen_obj_set_int(&jstr, "diag2", 30);
json_gen_obj_set_float(&jstr, "diag3", 54.1643);
json_gen_obj_set_string(&jstr, "diag4", "diag");
json_gen_end_object(&jstr);
json_gen_str_end(&jstr);
/* The values are reported by updating appropriate parameters */
esp_rmaker_param_update_and_report(esp_rmaker_device_get_param_by_name(device, "Data"),
esp_rmaker_obj(buf));
esp_rmaker_param_update_and_report(esp_rmaker_device_get_param_by_name(device, "Timestamp"),
esp_rmaker_int((int)current_timestamp));
}
return ESP_OK;
}
可以看到,用單個參數對象上報 4 種不同類別、不同數據類型的參數是優于分別上報的,可以避免使節點配置過于臃腫的問題。需要說明的是,上面展示了在 ESP RainMaker 中對 JSON Generator 庫應用的方法作為示例,您完全可以選擇任何庫或函數來創建對象 (Object)。
對服務 (Service) 進行測試
在使用移動端 App 調用服務 (Service) 之前,建議您先通過 RainMaker CLI 對其進行測試。在完成 CLI 配置后,使用以下命令即可啟動診斷:
$ ./rainmaker.py setparams --data '{"Diagnostics":{"Trigger":true}}' <node_id>
設備收到命令后,會立即在串行控制臺上輸出如下結果:
I (74726) esp_rmaker_param: Received params: {"Diagnostics": {"Trigger": true}}
I (74726) app_main: Received write request via : Cloud
I (74726) app_main: Starting Diagnostics
I (74736) esp_rmaker_param: Reporting params: {"Diagnostics":{"Data":{"diag1":true,"diag2":30,"diag3":54.16430,"diag4":"diag"}}}
I (74746) esp_rmaker_param: Reporting params: {"Diagnostics":{"Timestamp":1639738352}}
接下來,您也可以使用命令查詢節點 (Node) 的參數:
$ ./rainmaker.py getparams <node_id>
并在控制臺上獲取結果:
{
“Diagnostics”:{
“Data”:{
“diag1”:true,
"diag2":30,
“diag3”:54.1643
},
“Trigger”:false,
“Timestamp”:1639738352
}
}
以上是全球樂鑫科技代理商ESP RainMaker 添加服務 (Service) 的基本流程。您無需在云后臺進行任何配置或更改,就可以輕松添加自定義功能,擁有極大的靈活性與可擴展性。
這里是一些可供參考的服務 (Service) 示例,您可以基于此熟悉并在自己的應用中添加自定義服務 (Service):
?OTA Using Params
?System Service
?Time Service
?Schedules
敬請關注全球樂鑫科技代理商飛??萍夹侣?,及時獲取 ESP RainMaker 的新動態。