云服务器内容精选
-
创建产品 为了方便体验,我们提供了一个烟感的产品模型,烟感会上报烟雾值、温度、湿度、烟雾报警、还支持响铃报警命令。以烟感例,体验消息上报、属性上报等功能。 访问 设备接入服务 ,单击“管理控制台”进入设备接入控制台,选择您的实例,单击实例卡片进入。查看MQ TTS 设备接入 域名 ,保存该地址。 单击左侧导航栏“产品”,单击页面左侧的“创建产品”。 根据页面提示填写参数,然后单击“确定”完成产品的创建。 基本信息 所属资源空间 平台自动将新创建的产品归属在默认资源空间下。如需归属在其他资源空间下,下拉选择所属的资源空间。如无对应的资源空间,请先创建资源空间。 产品名称 自定义。支持字母、数字、下划线(_)、连字符(-)的字符组合。 协议类型 选择“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证书。
-
如何开发网关 网关是一个特殊的设备,除具备一般设备功能之外,还具有子设备管理、子设备消息转发的功能。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'} 在平台上看到子设备上线。 子设备上报消息 查看日志看到上报成功 查看消息跟踪 在平台上找到网关,选择 设备详情-消息跟踪,打开消息跟踪。继续让子设备发送数据,等待片刻后看到消息跟踪:
-
IoT Device SDK Tiny使用指南(C) IoT Device SDK Tiny是部署在具备广域网能力、对功耗/存储/计算资源有苛刻限制的终端设备上的轻量级互联互通中间件,您只需调用API接口,便可实现设备快速接入到 物联网平台 以及数据上报和命令接收等功能。相关集成指导请参见端云互通组件开发指南。 IoT Device SDK Tiny可以运行于无linux操作系统的设备,也可以被模组集成,但是不提供网关服务。 父主题: 设备侧SDK
更多精彩内容
CDN加速
GaussDB
文字转换成语音
免费的服务器
如何创建网站
域名网站购买
私有云桌面
云主机哪个好
域名怎么备案
手机云电脑
SSL证书申请
云点播服务器
免费OCR是什么
电脑云桌面
域名备案怎么弄
语音转文字
文字图片识别
云桌面是什么
网址安全检测
网站建设搭建
国外CDN加速
SSL免费证书申请
短信批量发送
图片OCR识别
云数据库MySQL
个人域名购买
录音转文字
扫描图片识别文字
OCR图片识别
行驶证识别
虚拟电话号码
电话呼叫中心软件
怎么制作一个网站
Email注册网站
华为VNC
图像文字识别
企业网站制作
个人网站搭建
华为云计算
免费租用云托管
云桌面云服务器
ocr文字识别免费版
HTTPS证书申请
图片文字识别转换
国外域名注册商
使用免费虚拟主机
云电脑主机多少钱
鲲鹏云手机
短信验证码平台
OCR图片文字识别
SSL证书是什么
申请企业邮箱步骤
免费的企业用邮箱
云免流搭建教程
域名价格