首先看效果(不太清晰)
视频演示效果
其次我讲一下大概的实现过程:前端用uniapp,(后来软工学长告诉我如果不是跨端开发的话完全可以不用uniapp,如果你要开发微信小程序就用微信开发者工具,如果你要开发移动端app就用安卓studio,因为我是自己琢磨的,当时只知道uniapp),和物联网平台通信用到了后端,以python的flask框架写的后端代码,发送命令后ESP32接收报文,解析并作出相应操作(本文是点灯,如果有其它外设可以扩展功能),同时上报设置属性到物联网平台。
具体流程如下:
1.后端代码编写
要下载阿里云物联网的pythonSDK,python的web框架——flask框架(因为我不太懂前端,因此用的是python,如果熟悉前端的话可以用node.js),这样的话我们就可以编写后端代码,用于和阿里云服务器平台通信了
后端功能代码示例如图所示,我截取的是检查设备是否在线函数:
其实后端功能代码我们完全可以通过阿里云平台的API调试来剪取,具体获取方法如图:
然后就可以查看你需要的实例代码了,截取相应部分到你的代码文件里
这样的话你就可以在你的相应文件里调试了,但是这时物联网平台的物模型属性值并不会改变,因为没有设备端上报。
2.编写前端接口
如图所示:
这里的url必须是你的后端代码设置的ip地址加上你对应功能函数的路由,上文我的chekline函数路由设置的Checkline,因此我这里写的就是/Checkline,同时method也要对照你功能函数写的。res其实就是后端函数的返回值,前端利用后端的返回值就牵扯到JSON数据的解析,我就不过多解释。
3.设备端ESP32的程序编写:
其实这里又分了几步
①订阅主题
阿里云物联网平台提供了很多主题
我们这里只会用两个,一个是属性上报中的设备属性上报,用于设备的上报属性到物联网平台,另一个是属性设置,用于设备订阅主题,接收应用端发送的命令
这里我们就根据这里的主题名订阅主题,我ESP32的IDF代码如下:
void mqtt_start() //连接MQTT服务器
{
esp_mqtt_client_config_t mqtt_cfg = {
.host = CONFIG_BROKER_URL,
.port = 1883,
.client_id = "<your clientid>", //这些数据都可以在阿里云物联网平台看到
.username = "<your username>",
.password = "<your password>",
.user_context = NULL,
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
}
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) //事件处理回调函数
{
int msg_id;
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
switch (event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGW(TAG, "Connectted successfully!");
ESP_LOGW(TAG, "Subscribing topic....");
msg_id = esp_mqtt_client_subscribe(client, "<your topic>", 0); //这里就是订阅主题函数
ESP_LOGW(TAG, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGW(TAG, "Disconnectted...");
esp_mqtt_client_reconnect(client);
break;
case MQTT_EVENT_ERROR:
ESP_LOGW(TAG, "Error...");
esp_mqtt_client_reconnect(client);
break;
case MQTT_EVENT_DATA:
ESP_LOGW(TAG, "MQTT_EVENT_DATA");
parse_info(event->data); //调用解析函数
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGW(TAG, "Subscribed successfully!");
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGW(TAG, "Published successfully!");
break;
default:
break;
}
}
②解析JSON数据
这里用到了ESP32的cJSON库,贴出我的代码,但是具体的物模型属性需要根据自己的进行修改
void parse_info(char *data)
{
cJSON *root = cJSON_Parse(data);
if (root == NULL)
{
ESP_LOGE(TAG, "JSON parsing failed!");
return;
}
cJSON *paramsObj = cJSON_GetObjectItem(root, "params");
if (paramsObj == NULL || !cJSON_IsObject(paramsObj))
{
ESP_LOGE(TAG, "Invalid params object!");
cJSON_Delete(root);
return;
}
// 获取temperature的值
cJSON *Item = cJSON_GetObjectItem(paramsObj, "temperature");
if (Item != NULL && cJSON_IsNumber(Item))
{
temperature = Item->valueint;
ESP_LOGW(TAG, "Temperature: %u", temperature);
}
// 获取airmode的值
Item = cJSON_GetObjectItem(paramsObj, "air_mode");
if (Item != NULL && cJSON_IsNumber(Item))
{
air_mode = Item->valueint;
ESP_LOGW(TAG, "Airmode: %u", air_mode);
}
// 获取灯的值
Item = cJSON_GetObjectItem(paramsObj, "LED_state");
if (Item != NULL && cJSON_IsNumber(Item))
{
light_state = Item->valueint;
ESP_LOGW(TAG, "LED_state: %u", light_state);
}
}
③设备做出响应
这样的话我们的动作状态的全局变量就相应的修改成了前端APP发来的理想值,可以通过轮询来检查这些数据的改变,同时检查到了改变的变量并会相应执行这样的动作,例如开灯啊,检查室内温度啊等等这样操作其实我们写起来都很容易,我就不具体贴出代码了。
④设备上报属性值
如果我们在执行操作过程中出现错误,打个比方,我们执行了开灯操作,但传感器检测到并没有开灯,这时我们就可以选择不上报属性,这样的话APP端询问物联网平台属性,如果没有改变则一直发命令等等,这些都是我的想法,我本身工程并没有搞得这么复杂。
一般来说执行操作是没有问题的,这样我们就需要把属性值上报给物联网平台。
我把这个函数贴出来:
esp_mqtt_client_publish(client, topic, "{\"params\":{\"<your property1>\":<value>,}}", strlen("{\"params\":{\"<your property2>\":<value>,}}"), 0, 0);
事实上,你这里会需要用到字符串剪切方法,因为你上报的数据一定是一串字符串,而C语言的快速字符串剪切有一个函数就是sprintf函数。
具体我也贴出我的代码:
char data[50];
sprintf(data, "{\"params\":{\"<property1>\":%u,\"<property2>\":%d}}",<property1val>, <property2val>);
esp_mqtt_client_publish(client, topic, data, strlen(data), 0, 0);
4.总结
这样的话,整个三端互通就完成了,你既可以在物联网平台监控属性,也可以在前端APP控制设备。目前我的项目存在的局限就是你的后端代码运行在电脑上的话,你的电脑必须一直在运行这个python文件才能与前端APP正常交接,而且是局域网IP,这要求你的设备和后端和前端必须在一个局域网内。这是存在的一个局限,但是其实可以买一个公网IP用于后端(记得学长是这么跟我说的)。
其实,我讲的很大概,因为主要是思路嘛,我是主要搞嵌入式的,对这个感兴趣才来搞着玩的。也没有前辈,网上资料也很少,我问客服(这里点名表扬阿里云的服务很好)和自己琢磨花费了大约一个月时间才搞懂,所以我觉得思路搞懂了,这些流程具体操作起来就很快了。