要想通过物联网平台实现远程监控设备,那么就要建立监控端设备(比如手机)和被监控端设备的数据交互,在阿里云物联网平台完成这个交互功能的方法就是建立两个设备之间的数据流转,对于设备要流转的物模型数据,阿里云网站上已经有详细的示例介绍,但是对于设备上下线状态的数据流转,网站没有进行详细说明,本人经过摸索,整理成此文,予以记录。
目录
第一,在物联网平台创建虚拟设备
在物联网平台建立实际设备(监控设备和被监控设备)相对应的虚拟设备,获得ProductKey、DeviceName、DeviceSecret三要素。此步属于阿里云物联网平台基本操作,阿里云官方网站有详细说明,可以参考:
第二,将实际设备与虚拟设备连接
在实际设备接入程序内配置相应的虚拟设备三要素,完成实际设备与物联网平台的连接,注意:虚拟设备和实际设备只能一对一连接。阿里云已经有设备的接入程序例程,可以参考:
第三,设置数据流转
建立物联网平台内虚拟设备的数据流转,完成被监控实际设备数据上传到Iot虚拟设备->被监控虚拟设备数据流转到监控虚拟设备->监控虚拟设备数据下发到监控实际设备,完成实际设备之间的数据交互。
此步基本操作可以参考:
设置数据流转解析器又分为3步:配置数据源、配置数据目的、编写解析器脚本程序。这三步中编写脚本程序难度最大,最为关键。阿里云官网上脚本示例都是以物模型数据上报为例的,可以参考:
本文以被监控设备状态流转到监控设备为例,被监控虚拟设备名称:LZM1001,监控虚拟设备名称:LZM1002,这两台设备已经在物联网平台创建,并且已经与实际设备进行了连接。另外注意,阿里云物联网平台数据流转有新版和旧版,本文以新版为例。
数据流转设置的入口:物联网平台->规则引擎->云产品流转
1、在云产品页面,点“数据源”标签
2、点“创建数据源”按钮,给新的数据流转创建一个新的数据源,本例也就是被监控设备与虚拟设备LZM1001相连接的上下线状态
3、在数据源名称栏内取一个名字:本例取名为“设备LZM1001上下线状态” ,数据源描述可先不填。
4、点“确定”按钮,然后可以在数据源页面看到新创建的这条数据源。
5、点数据源“设备LZM1001上下线状态” 后边操作的“查看”,进入数据源详情界面,此时界面内还没有数据源。
6、在数据源详情界面,点“添加Topic”按钮,弹出“添加Topic”对话框。
7、第一个下拉列表框是Topic类型,选择“设备状态变化通知”。
8、第二个下拉列表框是产品名称,选择LZM1001所属的产品。
9、第三个是设备名称,选择“LZM1001”
10、然后点“确定”按钮。
此时可以看到数据源详情里已经有了一条数据源。
1、点“数据目的”按钮。
2、点“创建数据目的”按钮,弹出“创建数据目的”对话框。
3、数据目的名称栏内:本例取名“设备LZM1002接收上线线状态”。
4、选择操作下拉列表框选“发布到另一个Topic”。
5、产品下拉列表框选择LZM1002所属的产品。
6、点“确定”按钮,完成创建。
此时可以看到数据目的页面内,已经有了这条新建的数据目的,注意:要记住这条数据目的ID为1017,一会编写解析器脚本会用到。
1、点“解析器”标签,进入创建解析器页面。
2、点“创建解析器”按钮,弹出“创建解析器”对话框。
3、解析器名称栏,本例取名为“设备LZM1001状态发送到LZM1002”。
4、点“确定”按钮,完成创建。
5、在创建解析器页面可以看到这条新建的解析器,点操作栏“查看”,进入解析器详情页面,对解析器进行下一步操作。
6、在解析器详情页面点“数据源”标签,进入“关联数据源”页面。
7、点“关联数据源”按钮。
8、在“关联数据源”对话框,数据源下拉列表框内选择刚刚创建的数据源“设备LZM1001上下线状态”。
9、然后点“确定”按钮。
此时可以看到关联数据源页面内,已经有了一条数据源。
10、点“数据目的”标签。
11、在“数据目的”页面内,点“关联数据目的”按钮。
12、 在“关联数据目的”对话框内,在数据目的选择下拉列表框选择刚刚创建的数据目的“设备LZM1002接收上线线状态”。
13、点“确定”按钮,完成关联。
此时,在数据目的页面,可以看到有了这条数据目的,数据目的ID为1017。
14、点“解析器脚本”标签,进入“编辑脚本”界面。
15、在编辑框内,输入如下代码:
var data = payload("json"); var select = {}; select.put("deviceName", deviceName()); select.put("timestamp", timestamp()); select.put("status", data.status); writeIotTopic(1017, "/sys/gbsp*******/LZM1002/thing/service/property/set", select);16、点“保存”按钮。
17、点“发布”按钮。
18、点解析器“设备LZM1001状态发送到LZM1002”前的后退箭头,返回到“云产品流转”页面。
19、点击“设备LZM1001状态发送到LZM1002” 这条解析器后边的“启动”按钮,启动云产品流转解析器。
测试设备:LZM1001为一台真实设备,LZM1002用Android studio AVD代替。进行测试的结果如下:
当设备LZM上线时,LZM1002收到的消息中的msg即为数据流转的内容
devicename:LZM1001
timestamp:1661580931561
status:online
当设备LZM下线时,LZM1002收到的消息中的msg即为数据流转的内容
devicename:LZM1001
timestamp:1661590108538
status:offline
测试结果正确,配置成功!
下边对脚本的代码进行一下解释:
以下为阿里云上给出的脚本示例:
示例数据为上报的属性数据,输入数据如下:
{ "status":"offline", "iotId":"4z819VQHk6VSLmmBJfrf00107e****", "offlineReasonCode":427, "productKey":"al12345****", "deviceName":"deviceName1234", "time":"2018-08-31 15:32:28.205", "utcTime":"2018-08-31T07:32:28.205Z", "lastTime":"2018-08-31 15:32:28.195", "utcLastTime":"2018-08-31T07:32:28.195Z", "clientIp":"192.0.2.1" }
上下线的数据格式中,第1条即为上下线的status的键值对。
var data = payload("json");
var select = {};
select.put("deviceName", deviceName());
select.put("timestamp", timestamp());
select.put("status", data.status);
writeIotTopic(1017, "/sys/gbsp*******/LZM1002/thing/service/property/set", select);
(1)第1行代码:
var data = payload("json");本例脚本代码第一行与脚本示例第一句一致,将设备状态变化通知上报的数据用payload函数,转成json格式,并将此json格式数据赋值给变量data。payload函数详细解释如下表:
payload(textEncoding) 返回设备发布消息payload的转义数据。textEncoding表示payload的转义字符编码,取值如下:
- 不传入参数:默认按照UTF-8编码转换为字符串,即
payload()等价于payload('utf-8')。'json':将payload数据转换成Map格式变量。如果payload不是JSON格式,则返回异常。'binary':将payload数据转换成二进制变量进行透传。
(2)第2行代码:
var select = {};
构建一个名为select的map类型数据,map内存储的对象为键值对,第一列为键名,第二列为键值,select初始化为空。
(3)第3-6行代码:
select.put("deviceName", deviceName()); select.put("timestamp", timestamp()); select.put("status", data.status);
向select内填加三个键值对,分别为设备名deviceName、时间戳timestamp和状态status。
注意键值名为一个标志字段,带双引号,其后的键值是从设备状态变化时上传的消息数据中取出的,所以为一个变量。
devieName和timestamp为设备上下线数据具体内容json之外的部分,所以变量格式为函数形式: deviceName()和timestamp()。
而status是json数据的具体内容,所以格式为data.status,此处是关键!
- Map类型基本数据类型支持的函数。
表达式 说明 [Object] 获取指定键( Key)对应的Value。size() 获取Map数据中键值对数量。 containKey(String) 判断Map数据中是否包含指定的键。 keySet() 获取Map数据中键的集合,返回类型为Array。 remove(Object) 移除Map数据中指定键对应的键值对。 put(Object, Object) 在Map数据中添加键值对。 putAll(map) 在Map数据中批量添加一组Map数据。
(4)第6行:
writeIotTopic(1017, "/sys/gbsp*******/LZM1002/thing/service/property/set", select);
数据转发到另外一个Topic,所用的函数为writeIotTopic,此第一个变量为数据目的ID(此ID一般为某个产品,而不是具体的设备),第二个变量为转发目的的Topic(此变量确定为某个设备),第三个为转发的map格式的数据。
本例中:数据目的ID为1017,就是上文创建的数据目的编号。
Topic包含了产品名称:gbsp*******,设备名称:LZM1002,以及下发格式:set
要发送的数据就是2-5行代码创建的select。
writeIotTopic函数的具体说明如下:
| writeIotTopic(destinationId, topic, payload, deviceName) | 流转数据到另一个Topic。
开源MQTT托管形态的基础型实例下,仅支持创建一个产品,默认不支持跨产品流转。 | 数据转发到另一Topic |
此段脚本中用的函数具体见:函数列表 (aliyun.com)
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r
作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐
基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U
如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb