华为云用户手册

  • 模拟数据上报及结果验证 在设备接入控制台“设备-所有设备-设备列表”中,单击创建的设备标识码进入设备详情,在“消息跟踪”页签中,单击“启动消息跟踪”,开启消息跟踪。 图24 消息跟踪-启动消息跟踪 使用MQTT模拟器连接到平台(模拟器使用请参考:使用MQTT.fx进行消息收发)。 使用模拟器进行消息上报,详情请参考:设备消息上报。 Topic: $oc/devices/{device_id}/sys/messages/up数据格式:{ "age": "34", "profession": "blue-collar", "maritalStatus": "single", "educationalStatus": "tertiary", "realEstateSituation": "no", "loanStatus": "tertiary"} 在设备详情中,查看消息跟踪,是否收到消息上报,并转发至FunctionGraph。 图25 消息跟踪-消息上报流转至FunctionGraph 查看HTTP服务器是否收到预测结果。 图26 查看消息
  • 前提条件 已注册华为官方账号。未注册可参考注册华为账户完成注册。 已完成实名制认证。未完成可在华为云上单击实名认证完成认证,否则会影响后续云服务的开通。 已开通 设备接入服务 。未开通则访问设备接入服务,单击“免费试用”或单击“价格计算器”购买并开通该服务。 已开通FunctionGraph服务。未开通则访问FunctionGraph服务,单击“立即使用”后开通该服务。 已开通ModelArts服务。未开通则访问 AI开发平台 ,单击“控制台”后进入该服务。 自建一个HTTP服务器,并提供POST接口用来接收推送的数据(本示例默认用户已经搭建好相应的服务器与接口,不再展示如何搭建HTTP服务器指导)。
  • 示例场景 在本示例中,我们实现以下场景: 设备上报银行客户特征信息, 物联网平台 将数据转发至FunctionGraph,由FunctionGraph转发至ModelArts进行AI分析,最终将分析的结果转发至HTTP服务器中。 操作步骤如下: 创建并发布ModelArts模型。 配置FunctionGraph函数。 创建MQTT协议产品,并创建设备。 数据转发规则配置,将数据流转至FunctionGraph。 模拟数据上报及结果验证,查看HTTP服务器是否收到AI分析后的消息。 图1 场景说明
  • 概述 在物联网解决方案中,针对庞大的数据进行自动学习时,需要对海量数据进行标注、训练,按照传统的方式进行标注、训练不仅耗时耗力,而且对资源消耗也非常巨大。华为云物联网平台可以通过规则引擎,将获取的海量数据流转到华为云其他云服务,从而实现将海量数据通过 函数工作流 (FunctionGraph)进行预处理,再将清洗后的数据流入AI开发平台(ModelArts)进行AI分析,并将分析结果统一转发至HTTP服务器中。
  • 场景说明 平台支持基于WebSocket的MQTT协议,使基于浏览器的应用程序或者小程序可以快速接入到物联网平台。本文以“智慧路灯”为示例,通过微信小程序模拟设备,带您体验设备通过MQTT over WebSocket协议连接到物联网平台、上报数据和接收命令的全过程。 假设: 路灯设备上报一条包含光照强度(luminance)的消息;路灯支持远程控制开关状态的命令(switch),路灯上报的数据格式为JSON格式。
  • 创建产品 产品是设备的合集,您可以将相同能力或特征的设备归属在同一个产品下。 登录管理控制台,单击左侧导航栏“产品”,单击页面左侧的“创建产品”。 根据页面提示填写参数,然后单击“立即创建”。 基本信息 所属资源空间 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下,下拉选择所属的资源空间。如无对应的资源空间,请先创建资源空间。 产品名称 自定义,如Streetlight。支持字母、数字、下划线(_)、连字符(-)的字符组合。 协议类型 选择MQTT。 数据格式 选择JSON。 设备类型选择 选择自定义类型 设备类型 Streetlight
  • 开发产品模型 找到创建产品章节新增的产品,单击产品进入产品界面。 在产品详情“基本信息”页面,单击“自定义模型”,配置产品的服务。 添加服务“BasicData”。 在“添加服务”页面,填写“服务ID”、“服务类型”和“服务描述”,单击“确定”。 “服务ID”:BasicData “服务类型”:建议和服务ID保持一致 “服务描述”:上报路灯数据 在“BasicData”的下拉菜单下单击“添加属性”,填写相关信息后,单击“确定”。 “属性名称”:luminance “数据类型”:int(整型) “访问权限”:可读、可写 “取值范围”:0~65535 “步长”:0 “单位”:不填写 添加服务类型“LightControl”。 在“基本信息”下单击“添加服务”,填写“服务ID”、“服务类型”和“服务描述”,单击“确定”。 “服务ID”:LightControl “服务类型”:建议和服务ID保持一致 “服务描述”:路灯开关控制 在“LightControl”的下拉菜单下单击“添加命令”,输入命令名称“Switch”。 在“新增命令”页面,单击“新增输入参数”,填写相关信息后,单击“确定”。 图1 新增命令参数-value
  • 使用微信小程序接入 下载微信小程序示例工程。 下载并安装微信 开发者工具 ,使用微信开发者工具打开微信小程序示例工程,如下图所示。 图3 微信小程序示例工程 小程序提供了界面显示,填写Server地址、设备ID、设备密钥。请根据实际创建的设备信息填写。 Server地址:即服务器 域名 ,参考平台对接信息获取“MQTT over WebSocket”协议对应的域名; 基础版实例“MQTT over WebSocket”协议对应的域名为:iot-mqtts.cn-north-4.myhuaweicloud.com 设备ID和设备密钥:在这里获取。 微信小程序连接到物联网平台 开发者通过传入设备信息,将设备连接到物联网平台。 真机调测时请在微信开发者工具-详情-本地设置-不校验合法域名,将其取消勾选,再在微信公众平台-小程序管理员界面-开发管理-服务器域名中添加socket合法域名('wss://'+MQTT接入地址)。 图4 连接到平台 单击连接到平台按钮,在域名、设备ID和密钥正确的情况下,可以看到日志设备连接成功,可在平台查看设备状态,如下图: 图5 设备列表-设备在线 发布Topic 发布Topic是指设备主动向平台上报自己的属性或消息,详细见设备属性上报接口文档。 在微信小程序中实现了上报属性数据的功能。 发布Topic后,Demo界面显示如下: 图6 上报数据 设备上报属性成功后可在设备详情页面查看到上报的属性: 图7 查看上报数据-MQTT 订阅Topic 订阅某topic的设备才能接收平台发布的关于该topic的消息,关于平台预置topic可参考Topic定义。 建链后,如果成功订阅Topic,主界面日志栏显示如下信息: 图8 订阅topic界面 接收下发命令 小程序支持接收平台下发命令的功能,在MQTT建链完成并成功订阅Topic后,可以在控制台设备详情中对该设备进行同步命令下发。下发成功后,在MQTT的回调函数中接收到平台下发给设备的命令。 例如下发参数名为LightControl: Switch,参数值为ON的命令。 图9 命令下发-MQTT 同步命令下发成功后,Demo界面显示如下 图10 接收命令界面
  • 1.设备接入地址切换 IoT场景设备量大,设备能力弱。IoT的迁移需尽量减少对设备侧的改动。华为云IoT提供多种技术方案来解决这个问题。 对于自建IoT平台设备,设备连接平台使用的是原有IoT平台域名,则设备侧可以不用做任何修改,将域名通过DNS解析到华为云IoT平台接入地址即可完成迁移。 对于存量第三方平台的设备,如果设备支持修改接入平台地址,则可以将设备侧地址切换为华为云IoT平台接入地址完成迁移。 对于设备能力比较强,可以进行OTA升级的设备,华为云提供Device SDK支持设备通过OTA完成接入地址切换。
  • 前提条件 已注册华为官方账号。未注册可参考注册华为账户注册华为账户完成注册。 已完成实名制认证。未完成可在华为云上单击实名认证完成认证,否则会影响后续云服务的开通。 已开通设备接入服务。未开通则访问设备接入服务,单击“免费试用”或单击“价格计算器”购买并开通该服务。 已开通 AOM 服务。访问AOM服务,单击“AOM2.0控制台”,单击“免费开通服务并授权”开通该服务。 已开通DMS Kafka服务。未开通则访问DMS Kafka服务,单击“立即购买”后开通该服务。
  • 2.设备接入鉴权适配 当前各个云厂商都会定义自己的鉴权方式,导致设备迁移时,需要在设备端做各种适配。华为云IoT在平台端提供多种鉴权能力,把鉴权适配的动作移到云端,减少设备改动带来的风险。 自定义鉴权:针对存量设备设备鉴权参数无法修改的场景,平台提供自定义鉴权能力,支持在平台自定义配置设备的鉴权逻辑,实现设备鉴权方式免改动接入华为云IoT。 系统鉴权:华为云Device SDK提供了系统默认的鉴权能力,对于支持修改代码的设备,可以集成SDK通过轻量化改动就可以实现设备的接入。 对于存量设备信息的迁移,华为云也提供了多种迁移能力满足不同的应用场景: 设备迁移服务:华为云IoTDA提供自动化,高效的迁移能力,支持第三方云平台的存量产品和设备信息全量同步到华为云IoT,实现设备信息无感自动迁移。迁移流程如下: 图2 设备迁移 设备自注册:通过在自定义鉴权中开启自注册功能,支持设备在连接到平台时自动注册设备到平台,而不需要提前进行设备的迁移。 批量注册设备:通过华为云提供的SDK调用创建设备接口,进行批量的设备注册。
  • 场景示例—智能家居煤气检测联动 场景简介:煤气检测器发现煤气浓度超标时,自动关联无线推窗器把窗户打开,起到通风的作用。 该场景主要描述的是设备可以通过MQTT协议与物联网平台进行交互,用户可以在控制台或通过应用侧接口创建设备联动规则,把设备上报的属性转发,通过物联网平台规则引擎转变成命令下发给其他指定设备。 核心知识点:产品模型、属性上报、命令下发、MQTT协议、设备联动规则。 最佳实践参考:煤气浓度过高自动打开推窗器。
  • 场景示例—智能网关 场景简介:已对接存量设备的网关,不用迁移就可以实现对既有设备和新设备的兼容控制。 该场景主要描述的是设备可以通过MQTT协议与物联网平台进行交互,用户可以在控制台产品详情中自定义Topic,通过应用侧接口或控制台创建数据转发规则,把设备上报的消息转发给其他华为云服务,供应用侧用户主动去消费。 核心知识点:产品模型、消息上报、消息下发、MQTT协议、数据转发规则、自定义Topic。 最佳实践参考:使用自定义Topic管理室内空调
  • 场景示例—恒温空调 场景简介:通过恒温控制系统,不论空调是否开机,都可以调整空调默认温度,待空调上电开机后,自动按默认温度调节。 该场景主要描述的是应用侧或控制台可以给离线设备下发缓存命令,待设备上线后执行,控制台通过设备影子配置属性,待设备上线后上报的属性不匹配的话,会自动下发属性修改的指令,直至修改成功。 核心知识点:产品模型、编辑码插件、设备影子、属性上报、属性修改。 最佳实践参考:预置设备影子自动调节空调温度。
  • 前提条件 已开通IoTDA的“华南-广州-华南友好环境”。 进入“IoTDA华南-广州-华南友好环境”控制台,选择左侧导航栏“设备发放”服务,开通设备发放服务。 图3 华南-广州-华南友好环境控制台 图4 授权开通 图5 授权成功 安装IntelliJ IDEA 访问IntelliJ IDEA官网,选择合适系统的版本下载。(本文以windows 64-bit系统IntelliJ IDEA 2019.2.3 Ultimate为例)。 图6 IntelliJ IDEA官网 下载完成后,运行安装文件,根据界面提示安装。 安装Maven软件,通过 Maven 安装项目依赖是使用 Java SDK 的推荐方法,首先您需要下载并安装 Maven ,安装完成后您只需在 Java 项目的 pom.xml 文件加入相应的依赖项即可。
  • 权限配置 单击设备接入控制台页面右上角的账号,选择“统一身份验证”。 图10 统一身份认证 进入统一身份认证服务页面后,单击左侧“委托”,然后在右上角的输入框中输入“iotps”,再单击iotps这个委托名称右侧的“授权”按钮。 图11 创建委托授权 进入授权页面后,在右上角的输入框中“iotda”,然后选择“IoTDA FullAccess”,再单击“下一步”。 图12 选择策略 跳转到如下页面后,直接单击右下角的“确定”即可。 图13 设置最小授权范围
  • 开始批量自注册引导 上述内容修改完后,可以运行iot-device-e2e-demo下的 BootstrapCertAuthRegisterGroup.java类,右键单击运行后,SDK会自动开始批量自注册过程。当前默认自注册大约1000设备,大约10TPS。 由于mqtt链接比较耗资源,大家可以把jvm最大内存调大一些。 1、单击IDEA菜单栏上方的“RUN”-“Edit Configurations” 2、单击“Modify options”-“Add VM options” 3、在下图的框中输入“-Xmx4096m” 4、运行程序,如下图所示: 图14 批量自注册
  • 结果验证 在自动开始批量自注册之后,用户可以在IDEA的控制台看到自注册的日志。 图15 自注册日志 用户可以在设备接入控制台看到已发放的设备数目。 图16 查看已发放的设备数目列表 用户可以通过右上角的“所有状态”来过滤“在线”的设备,可以看到在线设备数一直在增长。 图17 设备在线状态 用户可以回到设备发放控制台,看到SDK默认创建好的证书策略。 图18 设备发放证书策略 用户可以看到SDK默认创建的注册组。 图19 注册组列表 单击上图中的“注册组”名称,可以看到注册组里设备发放状态。 图20 设备发放状态
  • 导入批量自注册样例代码 下载JAVA批量自注册样例文档。 解压后选择样例代码主目录下的pom.xml文件,并用IDEA开发者工具打开后,可以看到工程目录如下: 图7 工程目录 修改AKSK.properties中的ak/sk参数,scopeId参数,accesspointid参数 用户可以在此处获取ak/sk。 scopeId可以在此处获取。 图8 获取注册组scopeId accesspointid可以在IoTDA的“华南-广州-友好用户环境”的总览界面获取到。 图9 accesspointid获取 上述步骤替换后,代码导入和修改完毕。
  • 验证操作 您可以使用配置设备接入服务时注册的真实设备接入平台,上报“temperature”大于80的数据。 您也可以使用模拟器模拟设备订阅Topic: “$oc/devices/{device_id}/sys/properties/report”(其中{deviceId}需要替换成实际设备ID)后,上报“temperature”大于80的数据,操作方法请参考在线开发MQTT协议的模拟智慧路灯。 您还可以使用虚拟设备进行在线调试,上报“temperature”大于80的数据。 期望结果: 若您使用真实设备上报数据,设备会收到一条“power”取值为“OFF”的“ON_OFF”命令。 若您使用模拟器上报数据,可在“Subscribe”页签查看到平台下发的“power”取值为“OFF”的“ON_OFF”命令。
  • SDK概述 物联网平台提供应用侧SDK和设备侧SDK,方便设备通过集成SDK接入到平台,应用通过调用物联网平台的API,实现安全接入、设备管理、数据采集、命令下发等业务场景。 资源包名 描述 下载路径 应用侧开发 Java SDK Java SDK提供Java方法调用应用侧API与平台通信。使用指南可以参考Java SDK使用指南。 Java SDK 应用侧开发 .NET SDK .NET SDK提供.NET方法调用应用侧API与平台通信。使用指南可以参考.NET SDK使用指南。 .NET SDK 应用侧开发 Python SDK Python SDK提供Python方法调用应用侧API与平台通信。使用指南可以参考Python SDK使用指南。 Python SDK 应用侧开发 Go SDK Go SDK提供Go方法调用应用侧API与平台通信。使用指南可以参考Go SDK使用指南。 Go SDK 应用侧开发 Node.js SDK Node.js SDK提供Node.js方法调用应用侧API与平台通信。使用指南可以参考Node.js SDK使用指南。 Node.js SDK 应用侧开发 PHP SDK PHP SDK提供PHP方法调用应用侧API与平台通信。使用指南可以参考PHP SDK使用指南。 PHP SDK 设备侧IoT Device SDK(Java) 设备可以通过集成IoT Device SDK(Java)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device SDK使用指南(Java)。 IoT Device SDK(Java) 设备侧IoT Device SDK(C) 设备可以通过集成IoT Device SDK(C)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device SDK(C)使用指南。 IoT Device SDK(C) 设备侧IoT Device SDK(C#) 设备可以通过集成IoT Device SDK(C#)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device SDK(C#)使用指南。 IoT Device SDK(C#) 设备侧IoT Device SDK(Android) 设备可以通过集成IoT Device SDK(Android)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device SDK(Android)使用指南。 IoT Device SDK(Android) 设备侧IoT Device SDK(Go社区版) 设备可以通过集成IoT Device SDK(Go社区版)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device SDK(Go社区版)使用指南。 IoT Device SDK(Go社区版) 设备侧IoT Device SDK Tiny(C) 设备可以通过集成IoT Device SDK Tiny (C)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device Tiny SDK(C)使用指南。 IoT Device SDK Tiny (C) 设备侧IoT Device SDK (ArkTS) 设备可以通过集成IoT Device SDK (ArkTS)接入物联网平台, Demo提供了调用SDK接口的样例代码。使用指导请参考 IoT Device SDK(ArkTS)使用指南 IoT Device SDK(ArkTS)
  • 创建产品 为了方便体验,我们提供了一个烟感的产品模型,烟感会上报烟雾值、温度、湿度、烟雾报警、还支持响铃报警命令。以烟感例,体验消息上报、属性上报等功能。 访问设备接入服务,单击“管理控制台”进入设备接入控制台,选择您的实例,单击实例卡片进入。查看MQ TTS 设备接入域名,保存该地址。 单击左侧导航栏“产品”,单击页面左侧的“创建产品”。 根据页面提示填写参数,然后单击“确定”完成产品的创建。 基本信息 所属资源空间 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下,下拉选择所属的资源空间。如无对应的资源空间,请先创建资源空间。 产品名称 自定义。支持字母、数字、下划线(_)、连字符(-)的字符组合。 协议类型 选择“MQTT”。 数据格式 选择“JSON”。 设备类型选择 选择”自定义类型” 设备类型 填写“smokeDetector” 高级配置 产品ID 不填写 产品描述 请根据实际情况填写。
  • 版本说明 表1 Python版本说明 版本 变更类型 说明 1.2.0 新增功能 增加规则引擎、设备发放功能、自定义断线重连功能、升级组件版本。 1.1.4 新增功能 OTA升级支持网关模式 1.1.3 功能增强 更新服务端ca证书 1.1.2 新增功能 增加micropython支持和对应demo,从OBS下载OTA,以及说明文档。 1.1.1 新增功能 提供对接华为云IoT物联网平台能力,方便用户实现安全接入、设备管理、数据采集、命令下发等业务场景。
  • 使用说明 已安装Python 3.11.4 已安装第三方类库paho-mqtt:2.0.0 (必需) 已安装第三方类库schedule: 1.2.2 (必需) 已安装第三方类库apscheduler: 3.10.4 (必需) 已安装第三方类库requests: 2.32.2 (可选,在网关与子设备管理demo演示中使用) 已安装第三方类库tornado: 6.3.3 (可选,在网关与子设备管理demo演示中使用)
  • 设备初始化 创建设备时,需要写入在注册设备时获取的设备ID、密码,以及1中获取的设备对接信息,注意格式为ssl://域名信息:端口号 或 ssl://IP地址:端口号 123456 // 获取证书路径:加载iot平台的ca证书,进行服务端校验,使用sdk默认的ca.jks即可。 URL resource = MessageSample.class.getClassLoader().getResource("ca.jks"); File file = new File(resource.getPath()); //例如在iot-device-demo文件 MessageSample.java中修改以下参数 IoTDevice device = new IoTDevice("ssl://域名信息:8883", "5e06bfee334dd4f33759f5b3_demo", "mysecret", file); 所有涉及设备ID和密码的文件均需要修改成对应的信息。 建立连接。调用init接口,该接口是阻塞调用,如果建立连接成功会返回0。 123 if (device.init() != 0) { return; } 如果连接成功就会打印: 1 2023-07-17 17:22:59 INFO MqttConnection:105 - Mqtt client connected. address :ssl://域名信息:8883 创建设备并连接成功后,可以开始使用设备进行通信。调用IoT Device 的getClient接口获取设备客户端,客户端提供了消息、属性、命令等通讯接口。
  • 如何开发网关 网关是一个特殊的设备,除具备一般设备功能之外,还具有子设备管理、子设备消息转发的功能。SDK提供了AbstractGateway抽象类来简化网关的实现。该类提供了子设备管理功能,需要从平台获取子设备信息并保存(需要子类提供子设备持久化接口)、子设备下行消息转发功能(需要子类实现转发处理接口)、以及上报子设备列表、上报子设备属性、上报子设备状态、上报子设备消息等接口。 使用AbstractGateway类 继承该类,在构造函数里提供子设备信息持久化接口,实现其下行消息转发的抽象接口: 1234567 public abstract void onSubdevCommand(String requestId, Command command); public abstract void onSubdevPropertiesSet(String requestId, PropsSet propsSet); public abstract void onSubdevPropertiesGet(String requestId, PropsGet propsGet); public abstract void onSubdevMessage(DeviceMessage message); iot-gateway-demo代码介绍 工程iot-gateway-demo基于AbstractGateway实现了一个简单的网关,它提供tcp设备接入能力。关键类: SimpleGateway:继承自AbstractGateway,实现子设备管理和下行消息转发 StringTcpServer:基于netty实现一个TCP server,本例中子设备采用TCP协议,并且首条消息为鉴权消息 SubDevicesFilePersistence:子设备信息持久化,采用json文件来保存子设备信息,并在内存中做了缓存 Session:设备会话类,保存了设备id和TCP的channel的对应关系 SimpleGateway类 添加或删除子设备处理 添加子设备:AbstractGateway的onAddSubDevices接口已经完成了子设备信息的保存。我们不需要再增加额外处理,因此SimpleGateway不需要重写onAddSubDevices接口 删除子设备:我们不仅需要修改持久化信息,还需要断开当前子设备的连接。所以我们重写了onDeleteSubDevices接口,增加了拆链处理,然后调用父类的onDeleteSubDevices。 1 2 3 4 5 6 7 8 9101112131415161718 @Override public int onDeleteSubDevices(SubDevicesInfo subDevicesInfo) { for (DeviceInfo subdevice : subDevicesInfo.getDevices()) { Session session = nodeIdToSesseionMap.get(subdevice.getNodeId()); if (session != null) { if (session.getChannel() != null) { session.getChannel().close(); channelIdToSessionMap.remove(session.getChannel().id().asLongText()); nodeIdToSesseionMap.remove(session.getNodeId()); } } } return super.onDeleteSubDevices(subDevicesInfo); } 下行消息处理 网关收到平台下行消息时,需要转发给子设备。平台下行消息分为三种:设备消息、属性读写、命令。 设备消息:这里我们需要根据deviceId获取nodeId,从而获取session,从session里获取channel,就可以往channel发送消息。在转发消息时,可以根据需要进行一定的转换处理。 1 2 3 4 5 6 7 8 910111213141516171819202122232425 @Override public void onSubdevMessage(DeviceMessage message) { //平台接口带的都是deviceId,deviceId是由nodeId和productId拼装生成的,即 //deviceId = productId_nodeId String nodeId = IotUtil.getNodeIdFromDeviceId(message.getDeviceId()); if (nodeId == null) { return; } //通过nodeId获取session,进一步获取channel Session session = nodeIdToSesseionMap.get(nodeId); if (session == null) { log.error("subdev is not connected " + nodeId); return; } if (session.getChannel() == null){ log.error("channel is null " + nodeId); return; } //直接把消息转发给子设备 session.getChannel().writeAndFlush(message.getContent()); log.info("writeAndFlush " + message); } 属性读写: 属性读写包括属性设置和属性查询。 属性设置: 1 2 3 4 5 6 7 8 91011121314151617181920212223242526 @Override public void onSubdevPropertiesSet(String requestId, PropsSet propsSet) { if (propsSet.getDeviceId() == null) { return; } String nodeId = IotUtil.getNodeIdFromDeviceId(propsSet.getDeviceId()); if (nodeId == null) { return; } Session session = nodeIdToSesseionMap.get(nodeId); if (session == null) { return; } //这里我们直接把对象转成string发给子设备,实际场景中可能需要进行一定的编解码转换 session.getChannel().writeAndFlush(JsonUtil.convertObject2String(propsSet)); //为了简化处理,我们在这里直接回响应。更合理做法是在子设备处理完后再回响应 getClient().respondPropsSet(requestId, IotResult.SUC CES S); log.info("writeAndFlush " + propsSet); } 属性查询: 1234567 @Override public void onSubdevPropertiesGet(String requestId, PropsGet propsGet) { //不建议平台直接读子设备的属性,这里直接返回失败 log.error("not supporte onSubdevPropertiesGet"); deviceClient.respondPropsSet(requestId, IotResult.FAIL); } 命令:处理流程和消息类似,实际场景中可能需要不同的编解码转换。 1 2 3 4 5 6 7 8 9101112131415161718192021222324 @Override public void onSubdevCommand(String requestId, Command command) { if (command.getDeviceId() == null) { return; } String nodeId = IotUtil.getNodeIdFromDeviceId(command.getDeviceId()); if (nodeId == null) { return; } Session session = nodeIdToSesseionMap.get(nodeId); if (session == null) { return; } //这里我们直接把command对象转成string发给子设备,实际场景中可能需要进行一定的编解码转换 session.getChannel().writeAndFlush(JsonUtil.convertObject2String(command)); //为了简化处理,我们在这里直接回命令响应。更合理做法是在子设备处理完后再回响应 getClient().respondCommand(requestId, new CommandRsp(0)); log.info("writeAndFlush " + command); } 上行消息处理 上行处理在StringTcpServer的channelRead0接口里。如果会话不存在,需要先创建会话: 如果子设备信息不存在,这里会创建会话失败,直接拒绝连接 1 2 3 4 5 6 7 8 9101112131415161718 @Override protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception { Channel incoming = ctx.channel(); log.info("channelRead0" + incoming.remoteAddress() + " msg :" + s); //如果是首条消息,创建session//如果是首条消息,创建session Session session = simpleGateway.getSessionByChannel(incoming.id().asLongText()); if (session == null) { String nodeId = s; session = simpleGateway.createSession(nodeId, incoming); //创建会话失败,拒绝连接 if (session == null) { log.info("close channel"); ctx.close(); } } 如果会话存在,则进行消息转发: 1234567 else { //如果需要上报属性则调用reportSubDeviceProperties DeviceMessage deviceMessage = new DeviceMessage(s); deviceMessage.setDeviceId(session.getDeviceId()); simpleGateway.reportSubDeviceMessage(deviceMessage, null); } 到这里,网关的关键代码介绍完了,其他的部分看源代码。整个demo是开源的,用户可以根据需要进行扩展。比如修改持久化方式、转发中增加消息格式的转换、实现其他子设备接入协议。 iot-gateway-demo的使用 创建子设备的产品,步骤可参考创建产品。 在创建的产品中定义模型,添加服务,服务ID为parameter。并且新增alarm和temperature两个属性,如下图所示 图9 模型定义-子设备产品 修改StringTcpServer的main函数,替换构造参数,然后运行该类。 123 simpleGateway = new SimpleGateway(new SubDevicesFilePersistence(), "ssl://iot-acc.cn-north-4.myhuaweicloud.com:8883", "5e06bfee334dd4f33759f5b3_demo", "mysecret"); 在平台上看到该网关在线后,添加子设备。 图10 设备-添加子设备 表1 子设备参数 参数名称 参数描述 所属产品 子设备所属的产品,选择步骤1创建的产品。 设备名称 即device_name,可自定义,如subdev_name 设备标识码 即node_id,填写subdev。 设备ID 即devicee_id,可不填写,自动生成。 此时网关上日志打印: 2024-04-16 21:00:01 INFO SubDevicesFilePersistence:112 - add subdev, the nodeId is subdev 运行TcpDevice类,建立连接后,输入步骤3中注册的子设备的nodeId,如subdev。 图11 子设备连接 此时网关设备日志打印: 2024-04-16 21:00:54 INFO StringTcpServer:196 - initChannel: /127.0.0.1:218892024-04-16 21:01:00 INFO StringTcpServer:137 - channelRead0 is /127.0.0.1:21889, the msg is subdev2024-04-16 21:01:00 INFO SimpleGateway:100 - create new session ok, the session is Session{nodeId='subdev', channel=[id: 0xf9b89f78, L:/127.0.0.1:8080 - R:/127.0.0.1:21889], deviceId='subdev_deviceId'} 在平台上看到子设备上线。 图12 设备列表-设备在线 子设备上报消息 图13 子设备上报消息 查看日志看到上报成功 2024-04-16 21:02:36 INFO StringTcpServer:137 - channelRead0 is /127.0.0.1:21889, the msg is hello2024-04-16 21:02:36 INFO MqttConnection:299 - publish message topic is $oc/devices/5e06bfee334dd4f33759f5b3_demo/sys/messages/up, msg = {"name":null,"id":null,"content":"hello","object_device_id":"subdev_deviceId"]2024-04-16 21:02:36 INFO MqttConnection:299 - publish message topic is $oc/devices/5e06bfee334dd4f33759f5b3_demo/sys/gateway/sub_devices/properties/report, msg = {"devices":[{"services":[{"properties":{"temprature":2,"alarm":1},"service_id":"parameter","event_time":null}],"device_id":"subdev_deviceId"}]] 查看消息跟踪 在平台上找到网关,选择 设备详情-消息跟踪,打开消息跟踪。继续让子设备发送数据,等待片刻后看到消息跟踪: 图14 消息跟踪-直连设备
  • 准备工作 开发环境要求:已经安装JDK(版本1.8以上)和maven 访问SDK下载页面,下载SDK,整个工程包含以下子工程: iot-device-sdk-java:sdk代码 iot-device-demo:普通直连设备的demo代码 iot-gateway-demo:网关设备的demo代码 iot-bridge-sdk:网桥的sdk代码 iot-bridge-demo:网桥的demo代码,用来演示如何将tcp设备桥接到平台 iot-bridge-sample-tcp-protocol:子设备使用tcp协议链接网桥的样例 iot-device-code-generator:设备代码生成器,可以根据产品模型自动生成设备代码 编译安装:进入到SDK根目录,执行mvn install
  • 创建产品 为了方便体验,我们提供了一个烟感的产品模型,烟感会上报烟雾值、温度、湿度、烟雾报警、还支持响铃报警命令。以烟感例,体验消息上报、属性上报等功能。 访问设备接入服务,单击“管理控制台”进入设备接入控制台,选择您的实例,单击实例卡片进入。查看MQTTS设备接入域名,保存该地址。 单击左侧导航栏“产品”,单击页面左侧的“创建产品”。 根据页面提示填写参数,然后单击“确定”完成产品的创建。 基本信息 所属资源空间 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下,下拉选择所属的资源空间。如无对应的资源空间,请先创建资源空间。 产品名称 自定义。支持字母、数字、下划线(_)、连字符(-)的字符组合。 协议类型 选择“MQTT”。 数据格式 选择“JSON”。 设备类型选择 选择”自定义类型” 设备类型 填写“smokeDetector” 高级配置 产品ID 不填写 产品描述 请根据实际情况填写。
  • 版本更新说明 表1 C#语言SDK版本更新说明 版本号 变更类型 功能描述说明 1.3.4 功能增强 优化日志打印; oc开头SubscribeTopic返回topic; demo优化; 网关接口bug修复; 升级目标框架; 其它优化。 1.3.3 新增功能 OTA升级支持网关模式 1.3.2 功能增强 更新服务器ca证书 1.3.1 修复 修复空指针异常,MQTT对象未释放等问题。 1.3.0 新功能 支持通过OBS升级软固件包 1.2.0 新功能 增加泛协议功能 1.1.1 功能增强 添加网关删除子设备功能,完善中英文描述。 1.1.0 新功能 新增网关与物模型功能 1.0.0 第一次发布 提供基础的设备接入能力,sdk预置了设备接入地址及华为IoTDA平台配套的CA证书。
  • 发布记录 表1 SDK C发布 版本号 变更时间 更新说明 1.2.0 功能增强 新增SDK测试代码及Demo,优化代码使用。 1.1.5 功能增强 更新OTA升级传输格式 1.1.4 功能增强 修复远程登录报文上报超时问题 1.1.3 功能增强 更新conf\rootcert.pem证书 1.1.2 新功能 增加规则引擎、M2M、gn编译文件、异常检测、日志打印时间戳、MQTT_DEBUG、国密算法、远程配置、端 云安全 通信(软总线)功能 1.1.1 新功能 新增SSH远程运维功能 1.1.0 新功能 增加MQTT5.0功能,优化代码,修复内存溢出问题 1.0.1 功能增强 增加mqtts不校验平台公钥场景、TLS版本为V1.2、增加消息存储样例等场景 0.9.0 新功能 增加网关更新子设备状态接口 0.8.0 功能增强 更换新的接入域名(iot-mqtts.cn-north-4.myhuaweicloud.com)和根证书。 如果设备使用老域名(iot-acc.cn-north-4.myhuaweicloud.com)接入,请使用 v0.5.0版本的SDK 0.5.0 功能增强 sdk预置了设备接入地址及华为物联网平台配套的CA证书,支持对接华为云物联网平台。
共99315条