设备连接IoT云平台指南

一、简介

设备与IoT云间的通讯协议包含了MQTT,LwM2M/CoAP,HTTP/HTTP2,Modbus,OPC-UA,OPC-DA。而我们设备端与云端通讯主要用的协议是MQTT。那么设备端与IoT云间是如何创建通信的呢?以连接华为云IoT平台为例:开发者需先在华为云IoT平台上创建产品并注册对应的设备,华为云IoT平台会分配给设备一个设备ID,并允许开发者设置一个验证码,端侧设备需使用设备ID和验证码来确保安全可信的连接到华为云IoT平台。 连接华为云IoT平台后,设备端与华为云IoT平台主要有两种通信方式。当设备侧状态发生变化时,设备可以向IoT平台上传设备状态,手机侧APP通过中间服务器向IoT平台查询设备状态,IoT平台将最新的设备状态下发至手机,则此时手机APP显示的设备侧状态与设备侧实际状态完成同步(如下图6、7、8所示);用户操作手机APP时,手机APP通过中间服务器将用户命令发送给IoT平台,IoT平台将命令下发至设备侧,设备侧接收到命令后进行响应,则此时用户完成了一次对设备的控制(如下图9、10、11所示)。

本章将介绍:1.如何在华为云IoT后台配置一个设备。2.设备端该如何使用SDK提供的IoT云相关的API接口来连接华为云IoT平台以及如何与华为云IoT平台通信。以帮助读者搭建从设备到云端的双向通信。

二、具体步骤

1. 开发流程

开发者从获取硬件环境到设备连接到华为云IoT平台,可总结为下图所示流程:

2. 华为云IoT平台配置
1.登陆华为云IoT平台后台

登录华为云IOT平台,进入到华为IoTDA界面,登陆网址链接。

2.创建产品

点击左侧功能页面选择栏中的产品页面,进入平台产品功能页面。

点击页面右上角创建产品按钮,弹出创建产品窗口,根据提示填写对应信息。以风扇为例:

信息填写完成后可在产品信息列表中看到对应的产品信息

创建产品详细步骤参考

3.定义产品模型

点击产品信息中的查看选项,可以进入到产品详细信息界面,在模型定义选项卡中选择自定义模型(也可以上传之前定义好的模型)

创建模型后就可以根据需要新建相关的命令以及属性。

添加命令:

添加属性:

设备模型的详细操作参考

4.注册设备

点击左侧功能页面选择栏中的设备->所有设备页面。点击页面右上角的注册设备按钮弹出单设备注册窗口。填写设备注册信息并设定验证码,单击确定完成设备注册。注册完后会提示保存设备ID与验证码,该设备ID和验证码在设备端开发时需要用到。

保存的设备ID和验证码:

到此,IOT云平台配置完成。

3. 华为云IoT设备端SDK开发

华为云IoT平台的端侧SDK已经集成到我们的SDK云通信模块中,开发者基于我们的SDK云通信模块提供的接口就可以与华为云IoT平台进行通信了。

1.云通信模块对华为云SDK的封装

云通信模块封装的相关接口说明:

2.云通信模块运行流程图

3.云通信模块接口的使用方法
1.云通信模块初始化

在调用云通信模块其他接口前必须先成功调用CLOUD_init,以确保云通信模块的初始化。

// 云通信模块初始化
if (CLOUD_Init() != 0) {  return;
}
2.连接华为云IoT平台

在与华为云IoT平台通信前,需调用CLOUD_Connect连接华为云IoT平台。在对华为云IoT平台配置时,由平台分配的Device ID和验证码需传入此接口,用以确保安全可信的接入华为云IoT平台。

// 连接华为云IoT平台
nfcInfo.deviceID = "6150601d88056b027dd2ca47_Fan01";    // 云平台配置时分配的设备ID
nfcInfo.devicePWD = "12345678";     // 云平台配置时设置的验证码
if (CLOUD_Connect(nfcInfo.deviceID, nfcInfo.devicePWD, \    CONFIG_CLOUD_DEFAULT_SERVERIP, CONFIG_CLOUD_DEFAULT_SERVERPORT) != 0) {return;
}
3.设备状态数据打包

在业务处理任务中,开发者需按照在华为云IoT平台后台申请的产品属性的格式,将设备当前状态上报至华为云IoT平台。以风扇为例,在定义产品模型时,定义如下属性:

则,设备端对应上报数据的格式为:

{"service_id":"SmartFan",   // 产品服务ID,固定"data":{"FanStatus":"ON",        // 当前状态,类型string, 取值为“ON”(打开)、“OFF”(关闭)"SpeedLevel": 1,          // 当前设置风速风速(int 类型), 取值1-4}
}

其中FanStatus的ON与OFF,SpeedLevel的取值要反应端侧设备的实际状态。

为方便开发者,在云通信模块中,针对JSON格式数据的打包过程封装了IoTProfilePackage函数。在该函数中,通过IotProfileService、IotProfileKV两个结构体,分别将开发者在云平台中申请的不同ServiceID级别数据和属性级别数据组织了起来。

typedef struct {void                 *nxt;   ///< ponit to the next keychar                 *key;IotProfileDataType    type;void                 *value;
}IotProfileKV;

typedef struct {void *nxt;char *serviceID; ///< the service id in the profile, which could not be NULLchar *eventTime; ///< eventtime, which could be NULL means use the platform timeIotProfileKV *propertyLst; ///< the property in the profile, which could not be NULL
} IotProfileService;

开发者仅需将在华为云IoT平台上配置的产品模型数据按照提供的两个结构体组织起来传入IoTProfilePackage函数,该函数便直接返回了上报的JSON数据。

IotProfileService  service;    // 定义ServiceID级别数据,该处对应云平台配置的SmartFan服务下的数据
IotProfileKV  kvFanSpeedLevel;   // 定义属性级别数据,该处对应云平台配置的属性SpeedLevel信息
IotProfileKV  kvMainFanStatus;   // 定义属性级别数据,该处对应云平台配置的属性FanStatus信息/* package the data */service.eventTime = NULL;service.serviceID = "SmartFan";     // 对应云平台配置的服务IDservice.propertyLst = &kvMainFanStatus;    // 在SmartFan服务下添加属性信息service.nxt = NULL;    // 该产品上报数据中仅存在SmartFan一种服务,所以next指针为空kvMainFanStatus.key = "FanStatus";    // 对应云平台配置的属性名称kvMainFanStatus.value = mainFanStatus ? "ON" : "OFF";    // FanStatus的ON,OFF取值由设备实际                                                           // 状态mainFanStatus决定。kvMainFanStatus.type = IOT_PROFILE_KEY_DATATYPE_STRING;    // 对应云平台配置的数据类型kvMainFanStatus.nxt = &kvFanSpeedLevel;     // 继续添加SmartFan服务下的另一属性。kvFanSpeedLevel.key = "SpeedLevel";     // 对应云平台配置的服务IDkvFanSpeedLevel.value = &speedLevel;    // speedLevel的取值由设备实际状态speedLevel决定。kvFanSpeedLevel.type = IOT_PROFILE_KEY_DATATYPE_INT;    // 对应云平台配置的数据类型kvFanSpeedLevel.nxt = NULL;   // SmartFan服务下没有其它属性了,next置为null。 jsonString = IoTProfilePackage(&service);  //打包本地数据,函数返回打包好的数据
4.设备状态数据上报

将端侧设备的实际状态打包成JSON格式的上报数据后,便可调用CLOUD_ReportMsg函数,将数据上报至华为IoT云平台。

if ( NULL != jsonString) {    // jsonString为打包好的上报数据RaiseLog(LOG_LEVEL_INFO, "jsonString:%s", jsonString);ret = CLOUD_ReportMsg(jsonString);free(jsonString);
} else {RaiseLog(LOG_LEVEL_ERR, "format the report message error");
}
5.设备端通知数据上报

在一些场景下,设备端有一些自定义的通知信息需要通知到用户。此类信息仅需透传至手机应用侧即可而不需要华为云IoT平台对数据进行解析。像燃气报警装置的报警信息、甲醛监测装置的报警信息等都属于设备端通知数据的上报,此时开发者可以调用CLOUD_ReportNotification进行此类数据的上报。该函数入参中第一项定义了通知信息的种类,第二、三项分别为通知信息的中、英文字符串。

typedef enum {NOTIFY_TYPE_NORMAL = 0,NOTIFY_TYPE_SECONDARY,NOTIFY_TYPE_URGENT,NOTIFY_TYPE_LAST
} NOTIFY_TYPE;int CLOUD_ReportNotification(int type, const char *enString, const char *chString);

以燃气报警设备为例,当设备端检测到燃气浓度超标时,则调用如下接口将通知数据进行上报:

CLOUD_ReportNotification(NOTIFY_TYPE_URGENT, "Gas warning", "可燃气体警告");
6.云端命令的下发与解析

为将云端下行数据通知到用户,在云通信模块中声明了CLOUD_CommandCallBack函数:

该函数需由开发者进行实现,当云端有下行数据发送至端侧设备时,云通信模块会通过调用此函数将数据传输给开发者,再由开发者对此数据进行解析。具体实现是:调用此函数时将云端下行数据的指针传入函数,开发者在函数内部实现对下行数据的解析。以风扇为例,在定义产品模型时,定义如下命令:

则云端下发命令格式为:

 {"service_id":"SmartFan",       // 产品服务ID,固定"command_name":"SetFanStatus", // 开关命令名字,固定"paras":{"FanStatus":"ON",           // 命令参数,控制风扇开关,类型(string),选项为ON(打开)/OFF(关闭)"SpeedLevel":1,              // 命令参数,风扇挡位(int 类型), 1 - 4   1:风速最小}
}

则在函数中对其进行解析:

// 按照cJSON结构体的结构序列化整个数据包
if ((objRoot = cJSON_Parse(jsonString)) == NULL) {    RaiseLog(LOG_LEVEL_ERR, "could not parse the payload\r\n");goto EXIT_JSONPARSE;
}
// 查找 command_name对象
if ((objCmdName = cJSON_GetObjectItem(objRoot, "command_name")) == NULL) {    RaiseLog(LOG_LEVEL_ERR, "%s:could not get the cmd name from json\r\n");goto EXIT_CMDOBJ;
}
// 在command_name对象查找SetFanStatus字符串,若查找到则调用DealSetFanStatus进行解析
if (0 == strcmp(cJSON_GetStringValue(objCmdName), "SetFanStatus")) {ret = DealSetFanStatus(objRoot);
} 

经过层层解析,最终解出对应的命令,并设置到端侧设备:

// 查找数据中FanStatus对象
if ((objPara = cJSON_GetObjectItem(objCmd, "FanStatus")) == NULL) {RaiseLog(LOG_LEVEL_ERR, "cJSON_GetObjectItem LampStatus failed!\n");return -1;
}
// 解析数据中FanStatus的键值ON或OFF并设置到端侧设备
if (0 == strcmp(cJSON_GetStringValue(objPara), "ON")) {setFanParam->status = CN_BOARD_SWITCH_ON;
}
else {setFanParam->status = CN_BOARD_SWITCH_OFF;
}
// 查找数据中SpeedLevel对象并在验证SpeedLevel的键值后设置到端侧设备。
if ((objPara = cJSON_GetObjectItem(objCmd, "SpeedLevel")) != NULL) {setFanParam->speedLevel = cJSON_GetNumberValue(objPara);if (setFanParam->speedLevel < 1) {setFanParam->speedLevel = 1;} else if (setFanParam->speedLevel >= 4) {setFanParam->speedLevel = 4;}
} 

本节仅以SetFanStatus命令为例,其他命令类似不再重述。

7.断开华为云IoT平台连接

开发者可在网络异常或其它需要断开与云端连接的场景下,调用如下接口断开与云端连接。

int CLOUD_Disconnect(void);
8.云通信模块逆初始化

在断开与云端的连接后需调用如下接口,以释放资源。

int CLOUD_Deinit(void);

三、总结

本章介绍了如何将一个具有网络功能的设备连接到华为云IoT平台上。在华为云IoT平台后台上配置一个设备,端侧SDK使用云通信模块接口实现连云、上报数据、接收和解析下发数据。读者还需参考设备如何接入互联网、手机应用侧开发等相关文档以更好地了解由手机应用、IoT云、端侧设备构成的整个系统的运作方式。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot集成EasyExcel 3.x:高效实现Excel数据的优雅导入与导出

目录 介绍 快速开始 引入依赖 简单导出 定义实体类 自定义转换器 定义接口 测试接口 复杂导出 自定义注解 定义实体类 数据映射与平铺 自定义单元格合并策略 定义接口 测试接口 一对多导出 自定义单元格合并策略 测试数据 简单导入 定义接口 测试接口 参…

供应链系统搭建|主流电商平台商品采集|一键搬家|订单物流回传API接口

搭建供应链系统时&#xff0c;您可能需要与电商平台进行集成&#xff0c;以实现订单管理、库存同步、物流跟踪等功能。以下是一些常见的电商接口&#xff0c;可以帮助您构建供应链系统&#xff1a; 1. **淘宝开放平台接口**&#xff1a;淘宝开放平台提供了丰富的接口&#xff…

ssh-key关于authorized_keys电脑与linux互相认证

思路&#xff1a; 在A上生成公钥私钥。将公钥拷贝给server B&#xff0c;要重命名成authorized_keys(从英文名就知道含义了)Server A向Server B发送一个连接请求。Server B得到Server A的信息后&#xff0c;在authorized_key中查找&#xff0c;如果有相应的用户名和IP&#xf…

ubuntu 查询mysql的用户名和密码 ubuntu查看username

ubuntu 查询mysql的用户名和密码 ubuntu查看username 文章标签mysqlUbuntu用户名文章分类MySQL数据库 一.基本命令 1.查看Ubuntu版本 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.5 LTS Release: 16.04 Coden…

Java数据结构-堆和优先级队列

目录 1. 相关概念2. PriorityQueue的实现2.0 搭建整体框架2.1 堆的创建和调整2.2 插入元素2.3 出堆顶元素 3. 全部代码&#xff08;包含大根堆和小根堆&#xff09;4. PriorityQueue的使用5. Top-K问题 之前我们学习的二叉树的存储方式是链式存储&#xff0c;&#xff08;不清楚…

java的各种锁

我们先来看看有什么锁 一、java锁 1、乐观锁 乐观锁 是一种乐观思想 &#xff0c;假定当前环境是读多写少&#xff0c;遇到并发写的概率比较低&#xff0c;读数 据时认为别的线程不会正在进行修改&#xff08;所以没有上锁&#xff09;。写数据时&#xff0c;判断当前 与期望…

算法打卡day48|动态规划篇16| Leetcode 583. 两个字符串的删除操作、72. 编辑距离

算法题 Leetcode 583. 两个字符串的删除操作 题目链接:583. 两个字符串的删除操作 大佬视频讲解&#xff1a;583. 两个字符串的删除操作视频讲解 个人思路 本题和115.不同的子序列相比&#xff0c;变为了两个字符串都可以删除&#xff0c;整体思路是不变的&#xff0c;依旧…

vue3中web前端JS动画案例(二)多物体运动-多值运动

<script setup> import { ref, onMounted, watch } from vue // ----------------------- 01 js 动画介绍--------------------- // 1、匀速运动 // 2、缓动运动&#xff08;常见&#xff09; // 3、透明度运动 // 4、多物体运动 // 5、多值动画// 6、自己的动画框架 // …

在PostgreSQL中如何实现递归查询,例如使用WITH RECURSIVE构建层次结构数据?

文章目录 解决方案使用WITH RECURSIVE进行递归查询示例代码 总结 在PostgreSQL中&#xff0c;递归查询是一种非常强大的工具&#xff0c;它可以用来查询具有层次结构或树形结构的数据。例如&#xff0c;你可能会在员工-经理关系、目录结构或组织结构图中遇到这样的数据。为了处…

MybatisPlus 逻辑删除

目录 一、配置MybatisPlus 二、添加注解 三、调用MybatisPlus的删除方法 四、测试结果 一、配置MybatisPlus # mybatis-plus mybatis-plus:# 全局配置global-config:db-config:# 全局逻辑删除的字段名logic-delete-field: deleted# 逻辑已删除值(默认为 d)logic-delete-va…

为什么科拓停车选择OceanBase来构建智慧停车SaaS应用

本文来自OceanBase的客户——拓客停车的实践分享 科拓停车简介与业务背景 作为智慧停车行业的佼佼者&#xff0c;科拓停车致力于提供全方位的智慧停车解决方案。服务涵盖车场运营管理、互联网智慧停车平台以及停车场增值服务等。通过不断研发创新&#xff0c;打造出了多样化的…

Linux的主机状态

查看系统资源占用 可以通过top命令查看CPU、内存使用情况&#xff0c;类似Windows的任务管理器 默认每5秒刷新一次&#xff0c;语法&#xff1a;直接输入top即可&#xff0c;按q或ctrl c退出 第一行&#xff1a; top&#xff1a;命令名称&#xff0c;14:39:58&#xf…

Sentinel 流控注解使用

大概原理&#xff1a;通过反射解析注解 SentinelResource信息完成调用&#xff0c;处理方法&#xff0c;类似AOP编程 处理方法的返回类型要保持一致&#xff0c;参数和顺序保持一致&#xff0c; 可以在参数列表最后加 com.alibaba.csp.sentinel.slots.block.BlockException; …

什么是时间序列分析

时间序列分析是现代计量经济学的重要内容&#xff0c;广泛应用于经济、商业、社会问题研究中&#xff0c;在指标预测中具有重要地位&#xff0c;是研究统计指标动态特征和周期特征及相关关系的重要方法。 一、基本概念 经济社会现象随着时间的推移留下运行轨迹&#xff0c;按…

现代农业AI智能化升级之路:机器学习在现代农业领域的现状与未来发展

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

学习笔记-数据结构-线性表(2024-04-18)- 单向链表选择排序

试以单向链表为存储结构实现简单选择排序的算法。 实现递增排序&#xff0c;首先选择一个元素作为第一个比较值&#xff0c;遍历其他所有的元素&#xff0c;如果发现其他元素中有比它小的元素&#xff0c;则交换两个元素&#xff0c;这样每一趟都能找到符合要求的最小值 正经…

展开说说:Android Fragment完全解析-卷一

1、是什么 Fragment 中文意思是碎片&#xff0c;Android 3.0推出的一个系统组件&#xff0c;主打一个在应用界面中可模块化又可重复使用。 Fragment 它很独立&#xff0c;它可以定义和管理自己的布局&#xff0c;具有自己的生命周期&#xff0c;并且可以处理自己的输入事件。…

4.18学习总结

多线程补充 等待唤醒机制 现在有两条线程在运行&#xff0c;其中一条线程可以创造一个特殊的数据供另一条线程使用&#xff0c;但这个数据的创建也有要求&#xff1a;在同一时间只允许有一个这样的特殊数据&#xff0c;那么我们要怎样去完成呢&#xff1f;如果用普通的多线程…

解决Error in writing header file of the driver

在源代码里面更新了一批常规的内容&#xff0c;编译的时候遇到一个error&#xff0c;一大片都是红的。XXX是项目名称。 Description Resource Path Location Type Generator: ERROR: Error in writing header file of the driver XXX Cpu Processor Expert Problem 表面意思是…

【学习】Jmeter、postman、python如何与数据库相互配合

在当今数字化时代&#xff0c;数据库已经成为我们日常生活中不可或缺的一部分。无论是购物、社交还是工作&#xff0c;数据库都在默默地为我们提供着高效、稳定的服务。而在众多的技术工具中&#xff0c;Jmeter、Postman和Python成为了操作数据库的三大主流技术。今天&#xff…