华为云用户手册

  • encode接口说明 encode接口的入参是JSON格式的数据,是平台下发的命令或应答。 平台的下行报文可以分为两种情况: 平台对设备上报数据的应答(对应图中的消息②) 表2 平台收到设备的上报数据后对设备的应答encode接口的入参结构定义 字段名 类型 参数描述 是否必填 identifier String 设备在应用协议里的标识, 物联网平台 通过decode接口解析码流时获取该参数,通过encode接口编码时将该参数放入码流。 否 msgType String 固定值"cloudRsp",表示平台收到设备的数据后对设备的应答。 是 request byte[] 设备上报的数据。 是 errcode int 请求处理的结果码,物联网平台根据该参数判断命令下发的状态。 0表示成功,1表示失败。 是 hasMore int 表示平台是否还有后续消息下发,0表示没有,1表示有。 后续消息是指,平台还有待下发的消息,以hasMore字段告知设备不要休眠。hasMore字段仅在PSM模式下生效,且需要“下行消息指示”开启。 是 LwM2M协议的命令下发格式和MQTT协议的命令下发格式不一样 注:在cloudRsp场景下编解码插件检测工具显示返回null时,表示插件未定义上报数据的应答,设备侧不需要物联网平台给予响应。 示例: { "identifier": "123", "msgType": "cloudRsp", "request": [ 1, 2 ], "errcode": 0, "hasMore": 0 } 平台命令下发(对应图中的消息③) 表3 平台下发命令encode接口的入参结构定义 字段名 类型 参数描述 是否必填 identifier String 设备在应用协议里的标识,物联网平台通过decode接口解析码流时获取该参数,通过encode接口编码时将该参数放入码流。 否 msgType String 固定值"cloudReq",表示平台下发的请求。 是 serviceId String 服务的id。 是 cmd String 服务的命令名,参见产品模型的服务命令定义。 是 paras ObjectNode 命令的参数,具体字段由产品模型定义。 是 hasMore Int 表示平台是否还有后续命令下发,0表示没有,1表示有。 后续命令是指,平台还有待下发的消息,以hasMore字段告知设备不要休眠。hasMore字段仅在PSM模式下生效,且需要“下行消息指示”开启。 是 mid Int 2字节无符号的命令id,由物联网平台内部分配(范围1-65535)。 物联网平台在通过encode接口下发命令时,把物联网平台分配的mid放入码流,和命令一起下发给设备;设备在上报命令执行结果(deviceRsp)时,再将此mid返回物联网平台。否则物联网平台无法将下发命令和命令执行结果(deviceRsp)进行关联,也就无法根据命令执行结果(deviceRsp)更新命令下发的状态(成功或失败)。 是 示例: { "identifier": "123", "msgType": "cloudReq", "serviceId": "NBWaterMeterCommon", "mid": 2016, "cmd": "SET_TEMPERATURE_READ_PERIOD", "paras": { "value": 4 }, "hasMore": 0} }
  • decode接口说明 decode接口的入参binaryData为设备发过来的CoAP报文的payload部分。 设备的上行报文有两种情况需要插件处理(消息④是模组回复的协议ACK,无需插件处理): 设备上报数据(对应图中的消息①) 字段名 类型 是否必填 参数描述 identifier String 否 设备在应用协议里的标识,物联网平台通过decode接口解析码流时获取该参数,通过encode接口编码时将该参数放入码流。 msgType String 是 固定值"deviceReq",表示设备上报数据。 hasMore Int 否 表示设备是否还有后续数据上报,0表示没有,1表示有。 后续数据是指,设备上报的某条数据可能分成多次上报,在本次上报数据后,物联网平台以hasMore字段判定后续是否还有消息。hasMore字段仅在PSM模式下生效,当上报数据的hasMore字段为1时,物联网平台暂时不下发缓存命令,直到收到hasMore字段为0的上报数据,才下发缓存命令。如上报数据不携带hasMore字段,则物联网平台按照hasMore字段为0处理。 data ArrayNode 是 设备上报数据的内容。 表1 ArrayNode定义 字段名 类型 是否必填 参数描述 serviceId String 是 服务的id。 serviceData ObjectNode 是 一个服务的数据,具体字段在产品模型里定义。 eventTime String 否 设备采集数据时间(格式:yyyyMMddTHHmmssZ)。 如:20161219T114920Z。 示例: { "identifier": "123", "msgType": "deviceReq", "hasMore": 0, "data": [{ "serviceId": "NBWaterMeterCommon", "serviceData": { "meterId": "xxxx", "dailyActivityTime": 120, "flow": "565656", "cellId": "5656", "signalStrength": "99", "batteryVoltage": "3.5" }, "eventTime": "20160503T121540Z" }, { "serviceId": "waterMeter", "serviceData": { "internalTemperature": 256 }, "eventTime": "20160503T121540Z" }] } LwM2M协议的数据格式跟MQTT的数据格式不同。 设备对平台命令的应答(对应图中的消息⑤) 字段名 类型 参数描述 是否必填 identifier String 设备在应用协议里的标识,物联网平台通过decode接口解析码流时获取该参数,通过encode接口编码时将该参数放入码流。 否 msgType String 固定值"deviceRsp",表示设备的应答消息。 是 mid Int 2字节无符号的命令id。在设备需要返回命令执行结果(deviceRsp)时,用于将命令执行结果(deviceRsp)与对应的命令进行关联。 物联网平台在通过encode接口下发命令时,把物联网平台分配的mid放入码流,和命令一起下发给设备;设备在上报命令执行结果(deviceRsp)时,再将此mid返回给物联网平台。否则物联网平台无法将下发命令和命令执行结果(deviceRsp)进行关联,也就无法根据命令执行结果(deviceRsp)更新命令下发的状态(成功或失败)。 是 errcode Int 请求处理的结果码,物联网平台根据该参数判断命令下发的状态。 0表示成功,1表示失败。 是 body ObjectNode 命令的应答,具体字段由产品模型定义。 注:body体不是数组。 否 示例: { "identifier": "123", "msgType": "deviceRsp", "mid": 2016, "errcode": 0, "body": { "result": 0 } }
  • 如何开发网关 网关是一个特殊的设备,除具备一般设备功能之外,还具有子设备管理、子设备消息转发的功能。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.SUC CES S); 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的使用 在平台上为网关注册开户。 修改StringTcpServer的main函数,替换构造参数,然后运行该类。 1 2 3 simpleGateway = new SimpleGateway(new SubDevicesFilePersistence(), "ssl://iot-acc.cn-north-4.myhuaweicloud.com:8883", "5e06bfee334dd4f33759f5b3_demo", "mysecret"); 在平台上看到该网关在线后,添加子设备。 此时网关上日志打印: 2023-01-05 19:14:32 INFO SubDevicesFilePersistence:83 - add subdev: 456gefw3fh 运行TcpDevice类,建立连接后,输入子设备的nodeId。 此时网关设备日志打印: 2023-01-05 19:15:13 INFO StringTcpServer:118 - channelRead0/127.0.0.1:60535 msg :subdev2 2023-01-05 19:15:13 INFO SimpleGateway:68 - create new session okSession{nodeId='456gefw3fh', channel=[id: 0x42c9dc24, L:/127.0.0.1:8080 - R:/127.0.0.1:60535], deviceId='5e06bfee334dd4f337589c1de_subdev2'} 在平台上看到子设备上线。 子设备上报消息 查看日志看到上报成功 查看消息跟踪 在平台上找到网关,选择 设备详情-消息跟踪,打开消息跟踪。继续让子设备发送数据,等待片刻后看到消息跟踪:
  • 接收下发命令 在Demo中提供了接收平台下发命令的功能,在MQTT建链完成并成功订阅Topic后,可以在管理控制台设备详情中命令下发或使用应用侧Demo对该设备ID进行命令下发。下发成功后,在Demo中接收到平台下发给设备的命令。 例如下发参数名为smokeDetector: SILENCE,参数值为1的命令。 图6 命令下发 命令下发成功后,Demo收到平台下发的命令,浏览器调试界面的console栏显示如下: 图7 显示 由于是同步命令需要端侧回复响应可参考接口。
  • 导入代码样例 下载quickStart(websocket).zip样例,并解压。 修改Demo里的关键工程配置参数。其中MqttOverWebsocketDemo.html需要配置host地址、设备ID和设备密钥,用于启动Demo时连接平台。 host地址:即域名,请参考平台对接信息获取; 设备ID和设备密钥:在物联网平台注册设备或调用创建设备接口后获取。 var host = '****'; //IoT平台mqtt对接地址 var deviceId = '****'; //请填写在平台注册的设备ID var secret = '****'; //请填写在平台注册的设备密钥
  • 接收下发命令 在Demo中提供了接收平台下发命令的功能,在MQTT建链完成并成功订阅Topic后,可以在管理控制台设备详情中命令下发或使用应用侧Demo对该设备ID进行命令下发。下发成功后,在Demo中接收到平台下发给设备的命令。 例如下发参数名为smokeDetector: SILENCE,参数值为50的命令。 命令下发成功后,Demo收到的消息是50,命令运行主界面显示如下: 由于是同步命令需要端侧回复响应可参考接口。
  • JavaScript编解码插件模板 以下为JavaScript编解码插件的模板,开发者需要按照平台提供的模板,实现对应的接口。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /** * 设备上报数据到物联网平台时调用此接口进行解码, 将设备的原始数据解码为符合产品模型定义的JSON格式数据。 * 该接口名称和入参已经定义好,开发者只需要实现具体接口即可。 * @param byte[] payload 设备上报的原始码流 * @param string topic MQTT设备上报数据时的topic,非MQTT设备上报数据时不携带该参数 * @return string json 符合产品模型定义的JSON格式字符串 */ function decode(payload, topic) { var jsonObj = {}; return JSON.stringify(jsonObj); } /** * 物联网平台下发指令时,调用此接口进行编码, 将产品模型定义的JSON格式数据编码为设备的原始码流。 * 该接口名称和入参格式已经定义好,开发者只需要实现具体接口即可。 * @param string json 符合产品模型定义的JSON格式字符串 * @return byte[] payload 编码后的原始码流 */ function encode(json) { var payload = []; return payload; }
  • 设备发放流程中使用到的证书都有哪些,它们有何区别? 设备发放提供证书认证方式,证书认证为双向认证过程,涉及到设备发放(平台)和设备两端,过程如下图所示。 图1 设备发放流程 双向证书认证过程使用到了如下几类证书: 表1 证书类别 证书 说明 证书及其私钥持有者 签发者 服务端证书 步骤2中,设备发放设备侧将该证书返回设备。 设备发放设备侧持有 权威CA(服务端证书的CA证书)签发 服务端CA证书 步骤3中,客户端使用该服务端CA证书验证服务端证书,通常为权威CA证书,获取方式见MQTT CONNECT连接鉴权。 权威CA机构持有 权威CA机构签发 设备证书(客户端证书) 步骤4中,设备将该证书发送给设备发放设备侧。 设备 CA证书 CA证书(设备CA证书/客户端CA证书) 步骤5中,设备发放设备侧使用该CA证书验证来自设备的客户端证书。用户通过应用侧上传该证书到设备发放平台。 用户 通常为自签发 样例中各类证书常用文件名: 表2 证书常用文件名 证书 文件名 MQTT.fx中的字段名 服务端证书 - - 服务端CA证书 如下其中之一: GlobalSignRSAOVSSLCA2018.bks(android)GlobalSignRSAOVSSLCA2018.crt.pem(c或java)GlobalSignRSAOVSSLCA2018.jks(java) bsca.jks(java) bsrootcert.pem(c) CA File 设备证书(客户端证书) client.crt Client Certificate File 设备证书(客户端证书)私钥 client.key Client Key File CA证书(设备CA证书/客户端CA证书) server.crt - 双向认证,即双向证书认证,与单向认证中不同的是,不仅包含单向认证中的设备对平台的证书验证步骤,还包含了平台对设备的证书验证步骤。
  • 热门问题 设备管理服务和 设备接入服务 合一后的差异点是什么? 如何获取对接物联网平台的地址? 如何获取新域名和老域名接入的地址/证书? 新旧域名接入的鉴权方式有什么区别? 命令/属性下发总是超时? 应用侧如何获取appid和secret? Java SDK中有多个demo,该参考哪一个demo? C版 SDK中有多个demo,该参考哪一个demo? 如果是TCP协议,或者自定义协议如何接入平台? 设备显示上报数据成功,在控制台未看到数据? 应用服务器调用接口失败怎么处理? 应用服务器如何获取设备上报到物联网平台的数据? 如何制作订阅推送调测证书? 调用订阅接口时,回调地址如何获取? 订阅后消息推送失败如何处理? 物联网卡无法正常接入设备接入平台? 为何上报中文数据,平台会乱码呈现?
  • 数据上报失败如何处理? 若设备是使用接口注册的,请确认设备是否因为没在指定的timeout时间内上线而被物联网平台自动删除了。如果设备已被删除,请重新注册设备再尝试上报数据。 请检查使用接口注册设备时,填写的产品信息是否和产品模型一致。 请检查上报的数据名称是否和产品模型定义的服务属性一致。 确定以上都不存在问题时,请检查设备和物联网平台之间的网络链路是否畅通,设备是否正常运行。 若设备为NB-IoT设备,请再参考NB模组无法正常上报数据怎么办?进行排查。
  • 为何上报中文数据,平台会乱码呈现? 问题描述 使用MQTT.fx设备模拟器进行数据上报时,在json字符串中携带中文字符,如下图: 图4 MQTT.fx数据上报截图 上报至IoTDA平台后,会出现乱码情况,如下图: 图5 设备详情样例 可能原因 MQTT.fx设备模拟器不支持中文字符。 解决办法 与平台交互时,不使用中文字符。 请将上报数据中的中文字符进行Unicode编码处理。 替换第三方设备模拟器,推荐使用IoTDA自研的设备模拟器。
  • 命令下发失败如何处理? 问题描述 调用命令下发接口报错或调用接口成功但设备未收到命令。 可能原因 设备协议不支持。 设备订阅的下行topic不正确或者设备上行topic及消息体不正确。 解决方法 确认使用的接口是否支持设备协议(同步命令下发当前仅支持MQTT协议设备)。 同步命令下发操作步骤: 确认设备订阅下行topic是否正确(需订阅成功后才可调用接口,不订阅,设备收不到平台消息),详细请参考平台命令下发接口文档。 若设备有收到平台下发的消息,确认设备上行topic及消息体是否正确,且必须在收到平台消息20s内(消息接口不限定20s),通过上行topic向平台发送,否则接口报错(request_id为下行消息中携带)。 异步命令下发操作步骤: 确认是立即下发还是缓存下发(根据入参的send_strategy判断)。 立即下发:设备在线,调用接口后设备立即收到。 缓存下发:调用接口后,设备上报数据后收到。
  • 物联网平台的命令状态总共有几种? LWM2M/CoAP设备命令下发状态 物联网平台命令下发包含如下状态: 超期:表示命令在物联网平台缓存时间超期,未向设备下发。 成功:表示物联网平台已经将命令下发给设备,且收到设备上报的命令执行结果。 失败:表示编解码插件解析为空,或执行结果响应里面有“ERROR CODE”等。 超时:表示物联网平台等待ACK响应超时。 取消:表示应用侧已经取消命令下发。 等待:表示命令在物联网平台缓存,还未下发给设备。 已发送:表示物联网平台已经将命令下发给设备。 已送达:表示物联网平台已经将命令下发给设备,且收到设备返回的ACK消息。 各命令状态之间的转换如下图所示: 图6 命令状态转换图 MQTT设备下发消息状态 等待:MQTT设备不在线,物联网平台会将消息进行缓存,此时任务状态为“等待”状态。 超时:物联网平台缓存的PENDING状态的消息,如果1天之内还没有下发下去,物联网平台会将消息状态设置为"超时”。 已送达:物联网平台将消息发送给设备后,状态变为“已送达”。 失败:物联网平台发送消息给设备不成功,消息状态变为“失败”。 各消息状态之间的转换如下图所示: 图7 消息状态转换图
  • 物联网平台下发异步命令有重发机制吗? 物联网平台具备异步命令重发机制。异步命令发送后(可以在设备接入的命令详情中查看命令发送时间):如果物联网平台未收到设备返回的ACK,则在10s~15s后会进行第一次重传。如果物联网平台仍未收到设备返回的ACK,在20s~30s后进行第二次重传。如果物联网平台依旧未收到设备返回的ACK,在40s~60s进行第三次重传。如果物联网平台在80s~180s后还没收到设备返回的ACK,则命令状态变为超时。
  • 离线开发的插件通过了工具检测,上传到平台后,设备日志提示异常? 问题描述 离线开发的插件包已经通过了编解码插件检测工具检测后,上传平台后,设备日志提示异常。 图5 设备日志错误提示 可能原因 该异常是运行插件代码抛出的异常,一般是相关依赖没有引入或者代码逻辑有误,可根据日志中的Java异常提示进行处理。 解决方法 在离线插件关键代码处(例如decode函数入口处,出口处等)打印日志,并联系物联网平台支撑人员在后台获取日志,辅助定位问题。 图6 打印日志样例
  • 在线开发的插件部署失败如何处理? 问题描述 用户在插件开发界面开发好了编解码插件,点击部署按钮部署失败了 可能原因 如果插件下载成功,但是部署失败,则可能是网络问题导致 如果插件下载失败,则部署失败的原因如下: 同类消息的(例如:两种数据上报的消息)messageId的值设置重复或在消息中的位置不一致。 messageId的数据类型设置为非int型。 存在字段的默认值设置为非16进制数。 存在字段名字设置为java关键字,比如type、int等 解决方法 插件如果可以成功下载,但是部署失败,请检查网络状态,并重试。 如果插件下载失败,请排查插件定义是否符合规范。
  • 在线开发插件中地址域(messageId)如何使用? 当有相同类型的消息时(例如:两种数据上报的消息),需要添加地址域字段,用于区分不同的消息,且该字段在字段列表的位置必须一致。场景如下: 有两条及以上的数据上报消息或命令下发消息。 命令响应消息可看作一种数据上报消息,因此如果存在命令响应消息,则需要在数据上报消息中添加地址域。 数据上报响应消息可看作一种命令下发消息,因此如果存在数据上报响应消息,则需要在命令下发消息中添加地址域。
  • 在线开发的插件中如何实现命令下发响应? 设备在接收到命令后,可以上报两类消息:ACK和命令下发响应。ACK用于表示命令已经到达设备,命令下发响应用于表示设备执行命令的结果。如果需要设备在接到命令后,需要返回命令下发响应,则: 需要在数据上报消息和命令响应消息中均定义地址域字段(messageId),并且该字段在两种消息的字段列表中的位置必须相同,使编解码插件可以对数据上报消息和命令响应消息进行区分。 需要在命令下发消息和命令响应消息中定义响应标识字段(mid),并且该字段在两种消息的字段列表中的位置必须相同,使编解码插件可以将命令下发消息和对应的命令响应消息进行关联。
  • 安全&数据保护 已获国家安全等保2.0四级认证,通过ISO27001/ISO27017/ ISO27018/ CS A STAR国际安全认证,数据隐私保护遵从中国《个人信息保护法》、欧盟GDPR数据隐私保护要求,建立端到端可信的安全体系。 设备安全:提供一机一密的设备安全认证机制,防止设备非法接入,支持设备的安全检测。 信息传输安全:基于TLS、DTLS、DTLS+加密协议,提供安全的传输通道。 平台安全:基于华为云整体进行威胁防御,充分利用华为 云安全 服务/组件和华为的安全研究部门,建立安全分析、设计、编码、测试、安全攻防等一整套安全防御体系。 数据保护:满足中国《个人信息保护法》、欧盟GDPR数据隐私保护要求。
  • 业务迁移 设备有对接设备发放(设备适配了设备发放能力)。如果设备第一次发放成功接入后,根据业务需要重新接入到新的实例,可以通过再次发放动态修改接入地址。 本场景涉及的功能也适用于多个商用环境间的迁移。 设备没有对接设备发放。对于设备预置的是设备接入的地址,根据业务需要,需要更改设备的接入实例(比如共享实例往专享实例迁移,设备从测试环境往商用环境迁移),可以通过设备发放实现设备的业务迁移。 具体使用示例参考设备数据迁移。 本场景涉及的功能也适用于多个商用环境间的迁移。
  • 动态完成不同批次设备初始化配置 当不同型号的设备在首次连接设备接入时需要具备不同的初始化状态,可以通过设备发放完成不同批次设备初始化配置。 具体使用示例参考: MQTT 密钥设备使用静态策略发放示例 MQTT 密钥设备使用静态策略发放是设备预注册的场景,需要为每个设备预置初始化的值。 MQTT 注册组静态策略发放示例 MQTT 注册组静态策略发放是设备注册组的场景,只需要为注册组设置一个初始化的值,那么对应这个组的设备都可以收到下发的初始化配置。一般来说:设备初始化配置会配合注册组使用。
  • 设备发放业务流程 设备启动后,通过Bootstrap流程(设备出厂时预置设备发放平台地址作为引导服务器地址),引导物联网设备在初次上电时获得正确的目标物联网平台地址,继而完成设备与平台的建链过程。保证设备安全可靠的按业务目标上线,最大程度上减少人为干预的错误可能。 流程如下: 首先确认用户是否开通设备接入服务(物联网平台)。 在设备发放平台创建设备的发放清单(包括预注册设备以及添加发放策略)。 设备出厂时预置设备发放平台地址,设备上电后,设备发放服务通过使用标准 X.509证书验证或者根据设备秘钥验证设备的标识,把设备发放到对应的设备接入平台。 设备发放将设备接入平台连接信息返回给设备。 设备通过收到的设备接入平台连接信息连接到设备接入平台。 父主题: 设备发放
  • 和其他服务的关系 设备发放服务与其他服务的关系如表1所示。 表1 与其他服务的关系 交互功能 相关服务 位置 创建设备时,需要使用设备接入服务创建的产品 设备接入服务(IoT Device Access,IoTDA) 创建产品 创建自定义策略时需要使用函数 函数工作流 服务(FunctionGraph) 创建并初始化函数 创建证书策略使用云证书时,需要去 云证书管理服务 创建云证书 云证书管理 服务(Cloud Certificate Manager Service,CCM) 创建私有CA 父主题: 设备发放
  • 使用限制 设备发放服务具有以下使用限制。 对象 类别/描述 限制 设备 集成Agent Lite的设备(MQTT) 不支持 原生MQTT协议设备 支持,设备需要开发设备引导接口,具备设备发放能力。 集成LiteOS的设备(LwM2M) 支持 证书 数字证书保证系统内各服务及系统与外部通信的安全性,防止通信数据在传输过程被篡改造成安全风险。 100 策略 自定义策略最多可添加的实例数 10 静态策略最多可添加的实例数 20 证书策略最多可添加的实例数 20 父主题: 设备发放
  • 前提条件 已收到购买的智能企业网关设备。 已获取设备对应的ESN。 电子标签用来标识设备的硬件信息,包括序列号、生产日期、设备型号、硬件描述信息等。智能企业网关设备的电子标签存在新旧两种,对应设备序列号(ESN)的拼接规则也不同。 老款标签:仅包含SN编号,SN编号即为设备ESN。 新款标签:包含SN编号和PN编号,用户需要将PN编号和SN编号按照一定的组合规则拼接为设备ESN。 因此,在进行激活操作时,用户需要按照实际情况,输入正确的SN编号(必填)和PN编号(选填),系统将自动拼接出对应的设备ESN。
  • 典型组网 本节以企业分支访问华为云单个VPC场景为例,介绍IEG设备侧的典型组网。 表1 典型组网 组网场景 组网说明 组网图 组网配置 设备直挂LAN侧动态(DHCP)上云 适用于企业分支/门店等新建网络场景,IEG设备作为企业分支内网关使用,直接连接二层交换机。 IEG设备支持单机和双机部署,对于本地可靠性高的用户可以在站点部署双机。 单机直挂LAN侧动态(DHCP)上云 双机直挂LAN侧动态(DHCP)上云 设备直挂静态路由上云 适用于企业分支/门店等新建网络场景,IEG设备通过静态路由协议与三层交换机对接。 单机直挂静态路由上云 双机直挂静态路由上云 设备旁挂静态路由上云 适用于客户网络已部署并运行业务,在不改变现有组网情况下实现快速上云的场景。 IEG设备连接现有的路由器设备,采用静态路由对接,将需要访问华为云的流量引导到IEG设备侧,其他流量仍沿原有路径转发。 单机旁挂静态路由上云 双机旁挂静态路由上云 设备旁挂动态路由(OSPF)上云 适用于客户网络已部署并运行业务,在不改变现有组网情况下实现快速上云的场景。 IEG设备连接现有的路由器设备,且IEG设备、现有路由器分别启用OSPF协议,打通LAN侧网络,将需要访问华为云的流量引导到IEG设备侧,其他流量仍沿原有路径转发。 单机旁挂动态路由(OSPF)上云 双机旁挂动态路由(OSPF)上云 设备直挂客户端上云和上网 适用于企业分支/门店等新建网络场景,站点上网环境简单,PC直接连接IEG设备,同时访问云上服务和Internet服务。 单机直挂客户端上云和上网 设备LAN侧多个子网上云和上网 适用于企业分支/门店等新建网络场景,IEG设备LAN需要划分多个子网,且多子网可以同时访问云上服务和Internet服务。 单机直挂LAN侧多个子网上云和上网
  • 华为云DNS服务器地址 为了实现用户就近接入和最低延迟的解析,提升全球范围的DNS解析体验,华为云在全球多个区域的多个可用区部署了DNS服务器。其中,部分区域支持任播网络(Anycast)功能。 目前,已经部署了DNS服务器的可用区包括:北京、廊坊、上海、广州、深圳、贵阳、香港、泰国、新加坡、日本、德国、南非、智利、迪拜、巴西、墨西哥等。 当前,华为云云解析服务对用户提供解析服务的新的DNS服务器地址为: ns1.huaweicloud-dns.com:中国大陆各区域DNS服务器地址 ns1.huaweicloud-dns.cn:中国大陆各区域DNS服务器地址 ns1.huaweicloud-dns.net:除中国大陆之外国家或地区DNS服务器地址 ns1.huaweicloud-dns.org:除中国大陆之外国家或地区DNS服务器地址 通过DNS的控制台创建公网域名后,其默认生成的NS记录集的值即为上述四个DNS服务器地址。
  • DNS服务器地址设置步骤 在域名的“解析记录”页面,您可以通过修改域名NS类型的记录集值来设置DNS服务器地址。 进入公网域名列表页面。 在域名列表页面,单击域名名称,进入“解析记录”页面。 单击NS类型记录集“操作”列的“修改”,进入“修改记录集”页面。 图1 修改NS记录集 按照公网域名的DNS服务器地址设置建议,修改“修改记录集”页面的“值”。 单击“确定”,完成NS记录集的修改。 您之前通过华为云创建的公网域名,其NS地址设置为ns1.hwclouds-dns.com和ns1.hwclouds-dns.net。该地址是华为云DNS在历史版本中对用户提供解析服务的DNS服务器地址,仍然可用。 为了更好的提供解析服务,建议您设置为新的DNS服务器地址。
  • DNS服务器地址设置建议 由于中国大陆的国际出口带宽有限,用户在中国大陆和中国大陆之外国家或地区之间跨地区访问时,会出现网络时延增大的现象。 因此,对于公网域名的NS记录集设置,建议您: 如果您的网站用户主要集中在中国大陆,设置DNS服务器地址为:ns1.huaweicloud-dns.com、ns1.huaweicloud-dns.cn。 如果您的网站用户主要集中在中国大陆之外国家或地区,设置DNS服务器地址为:ns1.huaweicloud-dns.net、ns1.huaweicloud-dns.org。 如果您的网站用户遍布全球,同时设置上述四个DNS服务器地址。
  • 背景知识 URL转发分为URL显性转发和URL隐性转发。 URL显性转发 显性URL转发采用的是301(也称之为永久性转移)或302重定向技术(也称之为暂时性转移)。将域名解析到一个云服务器IP,在云服务器上配置了此域名和URL的跳转,本节介绍的Nginx实现URL转发即URL显性转发。 301永久性转移和302暂时性转移的状态码都表示重定向,当浏览器得到服务器返回的301或302状态码后会跳转到一个新的URL地址。但301表示旧地址的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址的资源还在(仍然可以访问),这个重定向只是临时地从旧地址跳转到新地址,搜索引擎会抓取新的内容而保存旧的网址。 URL隐性转发 隐性URL转发是用的是iframe框架技术。
共100000条