华为云用户手册

  • 如何开发网关 网关是一个特殊的设备,除具备一般设备功能之外,还具有子设备管理、子设备消息转发的功能。SDK提供了AbstractGateway抽象类来简化网关的实现。该类提供了子设备管理功能,需要从平台获取子设备信息并保存(需要子类提供子设备持久化接口)、子设备下行消息转发功能(需要子类实现转发处理接口)、以及上报子设备列表、上报子设备属性、上报子设备状态、上报子设备消息等接口。 使用AbstractGateway类 继承该类,在构造函数里提供子设备信息持久化接口,实现其下行消息转发的抽象接口: 1 2 3 4 5 6 7 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 9 10 11 12 13 14 15 16 17 18 @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 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @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 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @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.SUCCESS); log.info("writeAndFlush " + propsSet); } 属性查询: 1 2 3 4 5 6 7 @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 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @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 9 10 11 12 13 14 15 16 17 18 @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(); } } 如果会话存在,则进行消息转发: 1 2 3 4 5 6 7 else { //如果需要上报属性则调用reportSubDeviceProperties DeviceMessage deviceMessage = new DeviceMessage(s); deviceMessage.setDeviceId(session.getDeviceId()); simpleGateway.reportSubDeviceMessage(deviceMessage, null); } 到这里,网关的关键代码介绍完了,其他的部分看源代码。整个demo是开源的,用户可以根据需要进行扩展。比如修改持久化方式、转发中增加消息格式的转换、实现其他子设备接入协议。 iot-gateway-demo的使用 创建子设备的产品,步骤可参考创建产品。 在创建的产品中定义模型,添加服务,服务ID为parameter。并且新增alarm和temperature两个属性,如下图所示 图8 模型定义-子设备产品 修改StringTcpServer的main函数,替换构造参数,然后运行该类。 1 2 3 simpleGateway = new SimpleGateway(new SubDevicesFilePersistence(), "ssl://iot-acc.cn-north-4.myhuaweicloud.com:8883", "5e06bfee334dd4f33759f5b3_demo", "mysecret"); 在平台上看到该网关在线后,添加子设备。 图9 设备-添加子设备 表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。 图10 子设备连接 此时网关设备日志打印: 2024-04-16 21:00:54 INFO StringTcpServer:196 - initChannel: /127.0.0.1:21889 2024-04-16 21:01:00 INFO StringTcpServer:137 - channelRead0 is /127.0.0.1:21889, the msg is subdev 2024-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'} 在平台上看到子设备上线。 图11 设备列表-设备在线 子设备上报消息 图12 子设备上报消息 查看日志看到上报成功 2024-04-16 21:02:36 INFO StringTcpServer:137 - channelRead0 is /127.0.0.1:21889, the msg is hello 2024-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"}]] 查看消息跟踪 在平台上找到网关,选择 设备详情-消息跟踪,打开消息跟踪。继续让子设备发送数据,等待片刻后看到消息跟踪: 图13 消息跟踪-直连设备
  • 准备工作 开发环境要求:已经安装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 不填写 产品描述 请根据实际情况填写。
  • 使用模拟器接入 下载模拟器(默认是64位操作系统),并启动模拟器,如下图: 界面展示 模拟器提供了界面显示,填写Server地址、设备ID、设备密钥。请根据实际创建的设备信息填写。 Server地址:即域名,参考平台对接信息获取; 设备ID和设备密钥:在这里获取。 不同的Server地址SSL加密接入时要与对应的证书文件匹配使用,证书获取请参考获取资源,需要替换certificate文件夹下的证书,如下图: 用户可以选择设备侧建链时是否为SSL加密,选择Qos方式是0还是1,当前不支持Qos2,可参考使用限制。 新建连接 设备或网关在接入物联网平台时首先需要和平台建立连接,从而将设备或网关与平台进行关联。开发者通过传入设备信息,将设备或网关连接到物联网平台。单击新建连接按钮,域名、设备ID和密钥正确的情况下,可以看到日志设备连接成功,可在平台查看设备状态,如下图: 图7 设备列表-设备在线 订阅Topic 订阅某topic的设备才能接收broker发布的关于该topic的消息,关于平台预置topic可参考Topic定义。 建链后,如果成功订阅Topic,主界面日志栏显示如下信息: 发布Topic 发布Topic是指设备主动向平台上报自己的属性或消息,详细见设备属性上报接口文档。 在模拟器中实现了上报Topic、属性上报功能。 发布Topic后,Demo界面显示如下: 设备上报属性成功后可在“设备详情”页面查看到上报的属性: 图8 查看上报数据-MQTT 接收下发命令 模拟器支持接收平台下发命令的功能,在MQTT建链完成并成功订阅Topic后,可以在控制台设备详情中对该设备进行同步命令下发。下发成功后,在MQTT的回调函数中接收到平台下发给设备的命令。 例如下发参数名为smokeDetector: SILENCE,参数值为50的命令。 图9 命令下发-同步命令下发 同步命令下发成功后,Demo界面显示如下:
  • 获取设备接入信息 在设备接入服务控制台获取设备接入平台所需的信息。 访问设备接入服务,单击“立即使用”进入设备接入控制台。 单击“立即使用”进入控制台,单击左侧导航栏的“总览”,点击“实例基本信息 - 接入信息”查看设备接入信息,记录域名和端口。 图1 总览-获取接入信息 针对不支持用域名接入的设备,通过在cmd命令框中执行“ping 域名”获取IP地址,用IP地址接入平台。由于IP地址不固定,您需要将IP地址做成可配置项。
  • 模拟数据上报及结果验证 使用MQTT模拟器连接到平台(模拟器使用请参考:使用MQTT.fx调测)。 使用模拟器进行消息上报,详情请参考:设备消息上报。 上报内容如下: { "id": "2", "device_id" : "6459f49b97bacf7a56439f97_321135434425", "report_time":"2023-10-24 19:39:42", "province":"guangzhou", "city": "guangdong", "daily_power_generation": 11, "total_power_generation": 22, "total_power": 324, "running_status": "OFFLINE" } 前往DWS控制台,查看是否收到转发的消息。 图18 查看DWS消息 前往Astro大屏服务查看监控视图。 图19 监控大屏数据
  • 配置DWS数据仓库服务 登录华为云官方网站,访问数据仓库服务。 单击“进入控制台”。 访问数据仓库服务控制台“集群管理”页面,选择购买的集群,若无集群,则参考购买集群,购买集群后,单击登录集群。 登录集群后,单击新建数据库,创建数据库。 图7 创建数据库 单击SQL查询, 进入SQL查询页面, 执行以下SQL语句创建数据表。 CREATE TABLE IF NOT EXISTS power_test_dws ( "id" BIGINT, "report_time" TIMESTAMP, "province" varchar(255), "city" varchar(255), "device_id" varchar(255) NOT NULL, "daily_power_generation" numeric(10,2), "total_power_generation" numeric(10,2), "total_power" numeric(10,1), "running_status" varchar(10), CONSTRAINT "device_uniqe" UNIQUE ("device_id", "report_time") ) WITH (ORIENTATION = COLUMN, PERIOD='15 days', storage_policy = 'LMT:180') PARTITION BY RANGE (report_time);
  • 配置Astro大屏服务 登录华为云官方网站,访问Astro大屏服务。 选择进入首页, 新建项目。 图13 新建项目 进入新建项目后,单击“新建页面”。单击“新建空白页”完成页面创建。 图14 新建空白页 可通过拖拉的方式,将组件中的元素拉到页面,从而完成页面设计。详情请参考开发页面。 图15 最终页面展示 设置数据源,选中一个视图组件,如图单击数据按钮。 图16 设置数据源 数据类型选择DWS,并配置DWS数据源,配置流程中通过sql语句查询DWS数据,并在组件预览中将查询出来的数据与组件的配置做映射。详情参考数据集管理。 图17 配置数据 参考上述步骤完成所有组件的配置。
  • 数据上报及验证数据是否转发成功 使用MQTT模拟器连接到平台(模拟器使用请参考:使用MQTT.fx调测)。 使用模拟器进行消息上报(参考:设备消息上报)。上报内容如下: { "id": "2", "device_id" : "6459f49b97bacf7a56439f97_321135434423", "report_time":"2023-10-19 19:39:42", "province":"guangzhou", "city": "shengzhen", "daily_power_generation": 32, "total_power_generation": 108, "total_power": 1023, "running_status": "ONLINE" } 前往Kafka控制台,查看是否收到转发的消息。 图6 查看Kafka消息
  • 前提条件 已注册华为官方账号。未注册可参考注册华为账户完成注册。 已完成实名制认证。未完成可在华为云上单击实名认证完成认证,否则会影响后续云服务的开通。 已开通设备接入服务。未开通则访问设备接入服务,单击“免费试用”或单击“价格计算器”购买并开通该服务。 已开通Kafka服务。未开通则访问Kafka服务,单击“立即购买”后开通该服务。 已开通数据湖探索服务。未开通则访问数据湖探索服务,单击“立即购买”后开通该服务。 已开通云数据仓库GaussDB(DWS)服务。未开通则访问云数据仓库GaussDB(DWS)服务,单击“购买”后开通该服务。 已开通Astro大屏服务, 未开通则访问Astro大屏应用,单击“立即使用”后开通该服务。
  • 权限配置 单击设备接入控制台页面右上角的账号,选择“统一身份验证”。 图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获取 上述步骤替换后,代码导入和修改完毕。
  • 前提条件 已开通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 文件加入相应的依赖项即可。
  • 导入测试计划 下载用于JMeter测试的测试计划。 打开JMeter,选择“Open”导入下载的测试计划。 在 JMeter左侧文件目录中单击 “User Defined Variables”,在“User Defined Variables”对话框中配置以下信息。 表4 参数说明 参数名 参数说明 server MQTT协议服务端地址。获取方式参考获取接入地址。 port MQTT协议端口,填写为8883。 productId 产品ID,创建产品时生成的产品ID。 password MQTT连接密码。为使用“HMACSHA256”算法以时间戳为密钥对secret进行加密后的值。secret为批量注册设备时填写的密钥。可以通过工具获取加密后的值。 timeStamp 为对password进行加密的时间戳。时间格式为YYYYMMDDHH。 图2 参考样例
  • 创建产品 登录管理控制台,单击左侧导航栏“产品”,单击页面左侧的“创建产品”。 根据页面提示填写参数,然后单击“确定”。 表2 参数说明 基本信息 所属资源空间 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下,下拉选择所属的资源空间。如无对应的资源空间,请先创建资源空间。 产品名称 自定义。支持字母、数字、下划线(_)、连字符(-)的字符组合。 协议类型 选择MQTT。 数据格式 选择JSON。 所属行业 请根据产品模型的所属行业填写。 设备类型 使用平台预置的产品模型,会自动关联设备类型,不需要再输入设备类型。 高级配置 产品ID 定制ProductID,用于唯一标识一个产品。如果携带此参数,平台将产品ID设置为该参数值;如果不携带此参数,产品ID在物联网平台创建产品后由平台分配获得。
  • 场景说明 随着物联网技术的发展,全球物联网设备连接规模与日俱增。大量设备接入和设备管理对网络带宽、通信协议以及平台服务架构都带来了很大挑战。IoT架构选型时,对平台进行性能测试显得尤为重要。本文介绍如何使用JMeter工具对平台的MQTT协议接入能力进行性能压测。 本文描述的测试方案如下: 测试场景: 模拟1万个设备同时在线,验证平台长连接的稳定性。 模拟设备每秒发起100次消息上报,验证平台消息处理能力。 测试环境: 压测目标平台:华为云设备接入服务低频单元S1(1万设备在线、200TPS消息上下行)。 压测执行机:Jmeter执行机1台,规格如下: 表1 压测执行机 实例类型 规格名称 vCPUs 内存 通用计算型s6 s6.xlarge.2 4vCPUs 8GiB 单台Jmeter执行机最多能模拟5万设备在线,如果需要模拟更高规格的在线设备数可以使用华为云的CPTS服务,部署多台Jmeter执行机,以满足规格测试的要求。
  • 验证操作 方法一: 您可以使用MQTT.fx模拟设备验证。 使用MQTT.fx模拟恒温空调,并连接到物联网平台。操作方法请参考在线开发MQTT协议的模拟智慧路灯。 选择“Subscribe”页签,输入订阅设备影子的topic=$oc/devices/{device_id}/sys/shadow/get/response/#,其中{device_id}与步骤6的设备ID保持一致,单击“Subscribe”按钮。 选择“Publish”页签,输入请求设备影子的Topic=$oc/devices/{device_id}/sys/shadow/get/request_id={request_id}。 输入一条获取设备影子的请求,单击“Publish”按钮。 示例: { "object_device_id": "40fe3542-f4cc-4b6a-98c3-61a49ba1acd4", "service_id": temperature" } 选择“Subscribe”页签,看到平台下发的设备影子数据。 方法二: 您可以使用配置设备接入服务时注册的真实设备接入平台,设备会收到平台下发的设备影子,修改空调的预设温度值。
  • 创建产品 某一类具有相同能力或特征的设备的集合称为一款产品。除了设备实体,产品还包含该类设备在物联网能力建设中产生的产品信息、产品模型(Profile)等资源。下面,我们按照R40的基本特征,在控制台上创建R40产品。 访问设备接入服务,单击“立即使用”进入设备接入控制台。 选择左侧导航栏的“产品”,然后单击左侧的“创建产品”,创建一个基于MQTT协议的产品,参考下表填写参数后,单击“确定”,完成产品的创建。 基本信息 所属资源空间 选择您需要归属到的资源空间 产品名称 自定义,如“R40” 协议类型 选择“MQTT” 数据格式 选择“JSON” 所属行业 无 设备类型 EnvironmentalMonitoringDevice 产品创建成功后,单击“查看详情”按钮进入产品界面,进行后面操作。
  • R40配置 在R40上需要对传感器的参数进行配置: 风速变速器相关配置: R40上电后,在自己的电脑上连接King开头的wifi,连上后在浏览器中输入地址192.168.3.1进入R40的配置界面。 输入用户名(默认为admin)和密码(默认无密码)后,单击“登录”按钮。 单击上方菜单栏“RTU I/O”,选中“模拟量接入”,进入模拟输入配置界面。 在AIN1输入一行(因为风速变速器选择的是该口)中,选择“电流4~20mA”(风速变送器的输出为该值)。并且按照传感器推荐的将最小值设置为0,最大值设置为30,单位设置为m/s。 设置完毕后,单击“保存并应用”。 通过旋转风速变送器的扇叶,然后刷新当前的配置页,可以看到“当前值”那一栏中有数据,说明已经能采集到传感器的数据。 气象多要素百叶箱相关配置: R40上电后,在自己的电脑上连接King开头的wifi,连上后在浏览器中输入地址192.168.3.1进入R40的配置界面。 输入用户名(默认为admin)和密码(默认无密码)后,单击“登录”按钮。 单击上方菜单栏“应用”,选择“Modbus”主站,进入Modbus主站配置页面。 在下方的框中填写“noise”,单击“添加”按钮。添加完成后,单击“编辑”按钮(“删除”按钮旁的那一个),进入传感器的配置界面。 在配置界面,将别名设置为“噪声监测”,从机地址设置为“2”,寄存器类型设置为“16位数据”,功能码设置为“03”,寄存器起始地址设置为“0”,数据个数设置为“1”,映射地址分配设置为“手动”,映射起始地址设置为“20004”,从机接口设置为“RS485”。 设置完毕后,单击“保存”。然后单击左下角的“返回至概况”。然后单击“保存并应用” 单击“noise”这一行的“查询”按钮,可以看到“数据值”,如果周围噪声发生改变,可以通过刷新按钮来查看值的变化。 从机地址、寄存器类型、功能码以及寄存器起始地址可以从气象多要素百叶箱的配置文件中获取到。 映射地址为R40的寄存器地址,建议改为手动,同时设置映射地址。因为该地址跟物模型中的属性是对应的,属性名称需要设置成“REG”+ 映射起始地址。这里设置20004是因为物模型中已经设置了REG20004的属性名。 从噪声查看页单击“返回至概况”,在Modbus设置界面下方的空白框处填写“lightIntensity”,单击“添加”按钮。添加完成后,单击“编辑”按钮(“删除”按钮旁的那一个),进入传感器的配置界面。 在配置界面,将别名设置为“光照强度”,从机地址设置为“5”,寄存器类型设置为“32位数据”,功能码设置为“03”,寄存器起始地址设置为“0”,数据个数设置为“1”,映射地址分配设置为“手动”,映射起始地址设置为“20130”,从机接口设置为“RS485”。 设置完毕后,单击“保存”。然后单击左下角的“返回至概况”。然后单击“保存并应用” 单击“lightIntensity”这一行的“查询”按钮,可以看到“数据值”,如果周围光照强度发生改变,可以通过刷新按钮来查看值的变化。 从机地址、寄存器类型、功能码以及寄存器起始地址可以从气象多要素百叶箱的配置文件中获取到。 映射地址为R40的寄存器地址,建议改为手动,同时设置映射地址。因为该地址跟物模型中的属性是对应的,属性名称需要设置成“REG”+ 映射起始地址。这里设置20130是因为物模型中已经设置了REG20130的属性名。 从光照强度查看页单击“返回至概况”,在Modbus设置界面下方的空白框处填写“shidu”,单击“添加”按钮。添加完成后,单击“编辑”按钮(“删除”按钮旁的那一个),进入传感器的配置界面。 在配置界面,将别名设置为“湿度”,从机地址设置为“1”,寄存器类型设置为“16位数据”,功能码设置为“03”,寄存器起始地址设置为“500”,数据个数设置为“1”,映射地址分配设置为“手动”,映射起始地址设置为“20015”,从机接口设置为“RS485”。 设置完毕后,单击“保存”。然后单击左下角的“返回至概况”。然后单击“保存并应用” 单击“shidu”这一行的“查询”按钮,可以看到“数据值”,如果周围光照强度发生改变,可以通过刷新按钮来查看值的变化。 从机地址、寄存器类型、功能码以及寄存器起始地址可以从气象多要素百叶箱的配置文件中获取到。 映射地址为R40的寄存器地址,建议改为手动,同时设置映射地址。因为该地址跟物模型中的属性是对应的,属性名称需要设置成“REG”+ 映射起始地址。这里设置20115是因为物模型中已经设置了REG20115的属性名。 从湿度强度查看页单击“返回至概况”,在Modbus设置界面下方的空白框处填写“wendu”,单击“添加”按钮。添加完成后,单击“编辑”按钮(“删除”按钮旁的那一个),进入传感器的配置界面。 在配置界面,将别名设置为“温度”,从机地址设置为“1”,寄存器类型设置为“16位数据”,功能码设置为“03”,寄存器起始地址设置为“501”,数据个数设置为“1”,映射地址分配设置为“手动”,映射起始地址设置为“20003”,从机接口设置为“RS485”。 设置完毕后,单击“保存”。然后单击左下角的“返回至概况”。然后单击“保存并应用” 单击“shidu”这一行的“查询”按钮,可以看到“数据值”,如果周围光照强度发生改变,可以通过刷新按钮来查看值的变化。 从机地址、寄存器类型、功能码以及寄存器起始地址可以从气象多要素百叶箱的配置文件中获取到。 映射地址为R40的寄存器地址,建议改为手动,同时设置映射地址。因为该地址跟物模型中的属性是对应的,属性名称需要设置成“REG”+ 映射起始地址。这里设置20003是因为物模型中已经设置了REG20003的属性名。 R40上报到平台的配置: 在上方的菜单栏中选择“云平台”,选择“华为云”。“认证方式”选择“设备密钥”,设备ID和密钥在iot平台注册所得,服务ID填写“basicData”,发布周期填写60。 配置完后,单击“保存并应用”。设置完毕后,R40会自动连上华为云iot平台,并且每隔60s报一次数据。
  • 控制台操作概览 在真实设备连接之前,需要在设备接入服务控制台创建产品、定义产品模型和注册设备。 创建产品:在物联网平台上规定好某一款产品的协议类型、数据格式、厂商名称、设备类型。此处我们需要按照R40的特征,在控制台创建R40的产品。 定义产品模型:产品模型是用来描述设备能力的文件,通过JSON的格式定义了设备的基本属性、上报数据和下发命令的消息格式。定义产品模型,即在物联网平台构建一款设备的抽象模型,使平台理解该款设备支持的属性信息,例如风速、光照强度、温湿度、噪声等。 注册设备:将R40设备注册到物联网平台。
  • 硬件连接 将风速变送器的棕色线和黑色线分别接到外部电源的正级和负极,将蓝色线和绿色线分别接入到R40的AIN1口和AGND口(见下图)。 图6 风速变送器连接R40 将气象多要素百叶箱的棕色线和黑色线分别接到电源的正极和负极,将黄色线和蓝色线分别接入到R40的485A口和485B口(见下图)。 图7 气象多要素百叶箱连接R40 将报警器的红色线和黑色线分别接到电源正极和R40的DO2口,将电源的负极接入到R40的DO1口(见下图)。 图8 报警器连接R40
  • 上传产品模型 产品模型是用来描述设备能力的文件,通过JSON的格式定义了设备的基本属性、上报数据和下发命令的消息格式。定义产品模型,即在物联网平台构建一款设备的抽象模型,使平台理解该款设备的功能。我们已提供开发好的产品模型,帮助您快速体验上云流程,如果您想体验产品模型的开发流程,可参考开发产品模型。 操作步骤: 在产品详情“模型定义”页面,单击“上传模型文件”。 在弹出的页面中,上传提供的产品模型(本示例的产品模型),然后单击“确认”。 图9 产品-上传模型文件
  • 场景说明 微型气象是不可预测的,基本上不能通过人工手段来分析其变化,因此必须运用新技术,对气象进行实时监测,以便采取相应的措施来避免或解决事故的发生。而常规气象环境数据采集容易造成数据损失、人力成本高、数据安全性差、可追踪性差等问题。为解决上述问题,可以通过网关将设备采集的数据上报到华为云IoT平台,实现对现场设备数据的实时监控,您可通过华为云IoT平台实时查看现场温度、湿度、光照、风速等环境数据,并对数据进行转储、分析等处理,同时也能通过IoT平台对设备进行控制。本文以金鸽的R40设备为例进行演示。
  • 设备简介 R40(如图2)负责将传感器的数据收集上来,上报到华为云IoT平台,同时负责将华为云IoT平台下发的控制信息下发给传感器。其中演示的传感器设备有如下三种: 1. 风速变送器(如图3)将采集到的风速通过电流信号输出给R40; 2. 气象多要素百叶箱(如图4)将采集到的噪声、光照、温湿度信息通过RS485口(Modbus协议)输出给R40。 3. 报警器(如图5)通过R40的DO口接收从华为云IoT下发给的控制信息。
  • 创建产品 登录管理控制台,单击左侧导航栏“产品”,单击页面左侧的“创建产品”。 根据页面提示填写参数,然后单击“确认”,完成产品的创建。 基本信息 所属资源空间 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下,下拉选择所属的资源空间。如无对应的资源空间,请先创建资源空间。 产品名称 为产品命名。产品名称在相同资源空间有唯一性。长度不超过64,只允许中文、字母、数字、以及_?'#().,&%@!-等字符的组合。 协议类型 选择MQTT。 数据格式 选择JSON。 所属行业 请根据实际情况选择。 设备类型 请根据实际情况选择。 高级配置 产品ID 定制ProductID,用于唯一标识一个产品。如果携带此参数,平台将产品ID设置为该参数值;如果不携带此参数,产品ID在物联网平台创建产品后由平台分配获得。 图3 创建产品-MQTT
  • 开发产品模型 找到新增的产品,单击“查看”进入产品界面。 在产品详情“模型定义”页面,直接上传模型文件BearPi_Agriculture.zip。 在产品列表中,单击对应的产品,进入产品详情页。您可以查看产品ID、产品名称、设备类型、数据格式、厂商名称、所属资源空间、协议类型等产品基本信息。 产品创建成功后,您可以单击“删除”删除不再使用的产品。删除产品后,该产品下的产品模型、编解码插件等资源将被清空,请谨慎操作。
  • 业务场景说明 自建MQTT Broker基于MQTT协议的上行数据和下行指令的业务定义如下: 表1 业务场景 业务场景 通信Topic 报文Payload 设备上报数据 /aircondition/data/up { "temperature": 26.0 } 服务端控制指令 /aircondition/cmd { "switch": "off" } 设备使用一机一密的认证方式。 设备通过Topic上报数据,通过消息流转功能将数据转发到后端服务。 服务端通过消息下发接口下发消息给设备。
  • 2.设备端域名切换 完成平台端配置后,需要进行设备端业务开发。完整的设备开发流程可参考设备侧开发。本章节以Paho-MQTT开源MQTT客户端为例,介绍在设备迁移场景下,设备侧如何在只修改接入地址的情况下,实现设备建立MQTT连接、Topc订阅、消息发布等功能。 //接入华为云IoT的域名,在控制台的"总览"界面的"平台接入地址"中获取“设备侧”的MQTTS接入地址。 String server = "ssl://******.st1.iotda-device.cn-north-4.myhuaweicloud.com:8883"; // Paho MQTT客户端。 MqttClient myMqttClient = new MqttClient(server, "myClientId", persistence); // Paho MQTT连接参数。 MqttConnectOptions connOpts = new MqttConnectOptions(); connOpts.setCleanSession(true); connOpts.setKeepAliveInterval(120); connOpts.setUserName("myUserName"); connOpts.setPassword("myPassword".toCharArray()); myMqttClient.connect(connOpts); System.out.println("Broker: " + broker + " Connected"); // Paho MQTT消息订阅。 myMqttClient.subscribe("/aircondition/cmd", new MyMessageListener()); // Paho MQTT发布消息。 String topic = "/aircondition/data/up"; String content = "{\"temperature\": 26.0 }"; MqttMessage message = new MqttMessage(content.getBytes()); message.setQos(0); myMqttClient.publish(topic, message);
共100000条