本章节以嵌入式芯片设备采用Websocket协议接入本IOT中继平台为例程。设备采用Websocket协议接入本IOT中继平台,实现从接入设备上报物模型属性数据。 设备侧根据业务需要周期性调用此接口向平台上报设备属性数据,例如:间隔10分钟上报设备温度、湿度等,本IOT平台websocket协议接入只支持上报物模型属性数据。
针对嵌入式设备, 上报设备属性数据报文由json字符串组成,数据报文对json字符串base64加密传输(本例程以stm32f403开发版+lwip+freeRTOS接入为例)。
服务器地址:ws://192.168.0.105:18080( IOT中继宝盒IOT设备接口–配置说明中显示的连接地址和端口)
用户名: 134xxxxxxxx(IOT中继宝盒IOT设备接入–设备接入配置 填写的连接账号)
密码:XXXXXX(IOT中继宝盒IOT设备接入–设备接入配置 填写的连接口令)
设备连接KEY: NDQwODAwMDAwMDExMTEwMDAwMjEsMTM0MzcxNTY1NjksMTIzNDU2(IOT设备接入key格式为:设备ID+逗号+连接用户名+逗号+连接密码 拼接的字符串BASE64 加密生成 )
设备连接请求地址: ws://192.168.0.105:18080/websocket/NDQwODAwMDAwMDExMTEwMDAwMjEsMTM0MzcxNTY1NjksMTIzNDU2
上报报文请求地址:ws://192.168.0.105:18080/websocket/NDQwODAwMDAwMDExMTEwMDAwMjEsMTM0MzcxNTY1NjksMTIzNDU2
上报报文为json格式字符串:
加密前报文上报属性数据json字符串内容:
{
"secrecetKey": "44080000001111000021,134xxxxxxxx,xxxxxx" , // 设备ID+逗号+连接用户名+逗号+连接密码 拼接的字符串
"secrecetBody": [ // 设备上报物模型属性数据
{"propertiesId": "P_1704161791995", "dataValue": "20" },
{"propertiesId": "P_1704161977952", "dataValue": "42"},
...... ]
}JSON字段参数说明:
| secrecetKey | 设备连接KEY: 设备ID+逗号+连接用户名+逗号+连接密码 拼接的字符串 “44080000001111000021” 为接入设备ID标识; "134xxxxxxxx“为在设备接入配置里面配置的此设备的接入账号; ”xxxxxx"为在设备接入配置里面配置的此设备的接入口令。 |
|---|---|
| secrecetBody | 上报设备属性数据集合标识 |
| propertiesId | 上报设备属性数据ID标识,为设备物模型配置的属性ID标识 如上例 “P_1704161791995” 、 “P_1704161977952” |
| dataValue | 上报设备属性数据值,dataValue 为属性值标识 上例 “20” 、 “42” 上报设备属性数据值 |
加密后的报文上报属性数据json字符串内容:
eyJzZWNyZWNldEtleSI6IjQ0MDgwMDAwMDAxMTExMDAwMDIxLDEzNDM3MTU2NTY5LHh4eHh4eCIsInNlY3JlY2V0Qm9keSI6W3sicHJvcGVydGllc0lkIjoiUF8xNzA0MTYxNzkxOTk1IiwiZGF0YVZhbHVlIjoiMjAifSx7InByb3BlcnRpZXNJZCI6IlBfMTcwNDE2MTk3Nzk1MiIsImRhdGFWYWx1ZSI6IjQyIn1dfQ==
websocket.h文件中定义:
#define SERVER_IP "192.168.0.105" //本IOT中继平台设备接入配置的IOT平台连接IP #define SERVER_PORT 18080 //本IOT中继平台设备接入配置的IOT平台连接端口 #define SERVER_PATH "/websocket/" //在本IOT中继平台设备接入配置的websocket协议访问地址 #define AUTH_KEY "44080000001111000021,134xxxxxxxx,xxxxxx" //发送的设备认证KEY 由设备ID+逗号+连接用户名+逗号+连接密码 拼接而成
参数说明:
| 参数 | 说明 |
|---|---|
| SERVER_IP | 本IOT中继平台设备接入配置的IOT平台连接IP |
| SERVER_PORT | 本IOT中继平台设备接入配置的IOT平台连接端口 |
| SERVER_PATH | 在本IOT中继平台设备接入配置的websocket协议访问地址 |
| AUTH_KEY | 设备连接KEY: 设备ID+逗号+连接用户名+逗号+连接密码 拼接的字符串 “44080000001111000021” 为接入设备ID标识; "134xxxxxxxx"为在设备接入配置里面配置的此设备的接入账号; "xxxxxx"为在设备接入配置里面配置的此设备的接入口令。 |
/*******************************************************************************
* @file websocket协议上报设备属性或设备事件数据 Template ../main.c
* @author txb0727
* @version V1.0.0
* @date 2023-12-10
* @brief Main program body
******************************************************************************
* @attention
* 本范例用于嵌入式开发版采用websocket协议上报设备属性数据,仅供参考
* 本范例硬件为stm32f407开发板,采用lwip通讯
*
* <h2><center>© COPYRIGHT 2023 txb0727.</center></h2>
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "client.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include <lwip/sockets.h>
/**************************** 任务句柄 ********************************/
/*
* 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
* 这个句柄可以为NULL。
*/
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t UploadData_Task_Handle = NULL;/* 上报数据任务句柄 */
/**************************************************************************
* 函数声明
**************************************************************************/
static void UploadData_Task(void* pvParameters);/* UploadData_Task 任务实现 */
extern void TCPIP_Init(void);
static void AppTaskCreate(void){
BaseType_t xReturn = pdPASS;
taskENTER_CRITICAL();
xReturn = xTaskCreate(
(TaskFunction_t) UploadData_Task,
(const char*) "UploadData_Task",
(uint32_t) 800,
(void*) NULL,
(UBaseType_t) 1,
(TaskHandle_t*) &UploadData_Task_Handle
);
if (pdPASS == xReturn)
printf("Ping_Task created successfully \r\n");
else
printf("Ping_Task created failed \r\n");
vTaskDelete(AppTaskCreate_Handle);
taskEXIT_CRITICAL();
}
/*****************************************************************
* @brief 主函数
* @param 无
* @retval 无
* @note 第一步:开发板硬件初始化
第二步:创建APP应用任务
第三步:启动FreeRTOS,开始多任务调度
****************************************************************/
int main(void)
{
BaseType_t xReturn = pdPASS;
/* 开发板硬件初始化 */
BSP_Init();
TCPIP_Init();
// 创建任务
xReturn = xTaskCreate(
(TaskFunction_t) AppTaskCreate,
(const char*) "AppTaskCreate",
(uint32_t) 128,
(void*) NULL,
(UBaseType_t) 3,
(TaskHandle_t*) &AppTaskCreate_Handle
);
if (xReturn == pdPASS)
vTaskStartScheduler(); // 启动调度器
while(1);
}
/**********************************************************************
* @ 函数名 : uploadData_Task
* @ 功能说明: uploadData_Task 任务主体
* @ 参数 :
* @ 返回值 : 无
********************************************************************/
static void UploadData_Task(void* parameter)
{
while (1)
{
//调用上报物模型属性数据方法
uploadBussinessData();
printf("UploadData_Task min free stack size is %d \r\n",(int32_t)uxTaskGetStackHighWaterMark(NULL));
vTaskDelay(60*1000);/* 延时60秒,实际根据业务需要修改上报业务数据频率 */
}
}
/********************************END OF FILE****************************/#include "client.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/api.h"
#include <lwip/sockets.h>
#include "websocket.h"
/*******************
* 上报物模型属性数据方法
* 上报物模型属性数据,上报报文为json格式字符串(样例):
* {"secrecetKey":"44080000001111000021,13437156569,xxxxxx","secrecetBody":[{"propertiesId":"P_1704161791995","dataValue":"20"},{"propertiesId":"P_1704161977952","dataValue":"42"}]}
* 参数说明:
* secrecetKey为设备连接KEY标识,固定值;
* "44080000001111000021,13437156569,xxxxxx"为其值,由设备ID+逗号+连接用户名+逗号+连接密码 拼接而成;
* 44080000001111000021为在本IOT平台配置的接入设备ID,13437156569为设备配置的连接账号,xxxxxx 为连接密码;
* secrecetBody 为上报设备属性数据集合标识,固定值;
* propertiesId 为设备物模型配置的属性ID标识,固定值;
* "P_1704161791995"、"P_1704161977952" 为在IOT平台物模型属性配置的属性ID的值;
* dataValue 为设备物模型属性数据值标识,固定值;
* "20"、"42" 为上报属性数据实际值,例如"20"代表温度,"42"代表湿度数值, 在本程序中通常调用gpio获取替换,在此演示范例代码中写虚拟数据
* **********************************************************/
void uploadBussinessData(void )
{
ip4_addr_t ipaddr;
IP4_ADDR(&ipaddr,DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);
int port = SERVER_PORT;
char ip[32] = SERVER_IP;
char path[64] = SERVER_PATH;
char secrecetUploadData[200];//报文数据
int fd;
//用本进程pid作为唯一标识
int pid = 1;
printf("client ws://%s:%d%spid/%d \r\n", ip, port, path, pid);
//3秒超时连接服务器
//同时大量接入时,服务器不能及时响应,可以加大超时时间
fd = ws_requestServer(ip, port, path, 0);
printf("连接服务器fd: %d \r\n",fd);
if(fd<=0){
vTaskDelay(10*1000);
// return -1;
}
if(fd>0){
// printf("上报数据fd: %d >>> %s\r\n",fd,path);
char send_buff[512]; //发送数据
memset(send_buff,0,sizeof(send_buff));
memset(secrecetUploadData,0,sizeof(secrecetUploadData));
/**************************************************************************************************************************
* 此处拼接上报报文内容
* 上报报文为json格式字符串(样例):
* {"secrecetKey":"44080000001111000021,13437156569,xxxxxx","secrecetBody":[{"propertiesId":"P_1704161791995","dataValue":"20"},{"propertiesId":"P_1704161977952","dataValue":"42"}]}
* 参数说明:
* secrecetKey为设备连接KEY标识,固定值;
* "44080000001111000021,13437156569,xxxxxx"为其值,由设备ID+逗号+连接用户名+逗号+连接密码 拼接而成;
* 44080000001111000021为在本IOT平台配置的接入设备ID,13437156569为设备配置的连接账号,xxxxxx 为连接密码;
* secrecetBody 为上报设备属性数据集合标识,固定值;
* propertiesId 为设备物模型配置的属性ID标识,固定值;
* "P_1704161791995"、"P_1704161977952" 为在IOT平台物模型属性配置的属性ID的值;
* dataValue 为设备物模型属性数据值标识,固定值;
* "20"、"42" 为上报属性数据实际值,例如"20"代表温度,"42"代表湿度数值, 在本程序中通常调用gpio获取替换,在此演示范例代码中写虚拟数据
* ***********************************************************************************************************************/
char *uploadData="[{\"propertiesId\":\"P_1704161791995\",\"dataValue\":\"20\"},{\"propertiesId\":\"P_1704161977952\",\"dataValue\":\"42\"}]";
// 拼接上报数据
snprintf(secrecetUploadData, sizeof(secrecetUploadData), "{\"secrecetKey\":\"%s\",\"secrecetBody\":%s}",AUTH_KEY,uploadData);
// printf("secrecetUploadData: %s\r\n",secrecetUploadData);
//对拼接的上报报文为json格式字符串base64加密
wss_base64_encode((const uint8_t*)secrecetUploadData, send_buff, strlen(secrecetUploadData));
// printf("send_buff: %s\r\n",send_buff);
//发送加密后的报文
int ret = ws_send(fd, send_buff, strlen(send_buff), true, WDT_TXTDATA);
// delay_us(1000);
vTaskDelay(1000);
free(send_buff);
free(secrecetUploadData);
free(uploadData);
close(fd);
printf("client(%d): close\r\n", pid);
}
vTaskDelay(10*1000);
} Websocket协议接入STM例程打包源码进入IOT中继宝盒主操作界面打开“IOT设备接口”窗口,选择对应的设备–设备接入端接口中对应的协议接入样例中下载。
长按关注宜联科技公众号