摘要:初学阿里云IoT Studio时,常遇到“数据格式验证出错”的错误,有很多同学不知道怎么处理,本文向大家介绍一下解决方法。

目录
1.问题描述
2.原因分析
3.解决方法
1.问题描述
我们学习阿里云物联网,一般都是从一个简单的智能灯开始做的。
智能灯涉及到硬件、网络、云平台,甚至是手机APP等多方面的知识。
任何一个环节出问题,都可能导致想实现的功能得不到实现,想看到的结果看不到。
不过别担心,我的文章为大家详细介绍了如何实现一个机遇阿里云物联网平台和arduino d1模块的智能灯。
详细链接是:
从arduino板开始做到阿里云app控制--WeMos D1或ESP8266连接阿里云文章合集及源代码
从arduino入门阿里云物联网平台非常适合,硬件成本低,编程简单,云平台的知识一点都不少学。许多同学已经成功实现了自己的智能灯。
近期给我留言的同学,可以分为2类:
第一类是想学习使用android studio来制作自己的APP,摆脱第三方平台的束缚,代价是需要更多的知识积累才行。
第二类是学习阿里云原生的IoT Studio,使用平台提供的无代码工具生成专业的物联网网络应用和移动应用,代价是需要自己的域名和公网IP。
其中,提出第二类问题的同学,又在入门IoT Studio的时候,遇到了一些基本的问题。这些问题只靠看阿里云官方文档是解决不了的。这些问题中,最多的就是“数据格式验证出错”问题。
我们一般是设计一个按钮(用来控制),一个指示灯(用来显示)。

可是当实际设计的时候,却发现,按钮数据源配置完成,验证数据格式的时候,提示错误。

错误提示如下:“数据格式验证出错”。设备模拟数据的数据格式不满足【组件】的数据格式要求,【组件】要求数据必须为【布尔】格式类型,请参考以下数据结构。

我们反复检查,无论是产品,还是设备,属性中的“主灯开关”的确是布尔型没有错误。

那么发生这个问题的原因是什么呢?
2.原因分析
原因是因为设备没有向云平台报送过属性。
仔细看一下设备数据源配置完之后的界面,就发现按钮上方显示一个红色的提示字符串
“该设备未上报过属性数据,你可以通过“在线模拟”模拟设备数据,并通过“推送”来上报”。

这是为什么呢?
是因为设备没有上报过属性!提示就是答案!
可是我们明明编写了智能灯的响应程序了啊,云平台下发的指令我们已经做出响应了啊,云平台让我们关闭就关闭,让我们打开就打开。
问题还真的在这个地方。
因为根据mqtt通信协议,IoT Studio的控件向外publish一个topic之后,订阅这个topic的物联网设备会收到属性改变的指令,然后做出硬件上的改变。
但这个通信过程还没有结束,因为IoT Studio的控件不知道硬件是否真的已经做出有效的反应了。因此硬件需要向云平台的topic也publish一个当前的状态,告诉平台属性变化成功。
当云平台订阅了这个topic之后,收到这个指令,就明白当前的状态是什么,然后就将按钮控件的状态“显示”为指定的状态。
没错,就是“显示”。也就是说,云平台控件同时兼顾着两个功能:publish和subscribe。
如果没有收到反馈,它就不知道怎么样显示自己的状态了,就会报错。
我们通过日志来观察。
如果没有返回值,那么通过IOT Studio 会导致关不掉,或者开不开。

日志如下图所示,只会显示服务调用的内容。

如果为代码添加返回值,也就是做出响应之后,返回当前的状态的话。

日志是这样子的,除了物模型服务调用,还有物模型和物模型消息两种日志。按钮也能够正常操作了。

知道了问题的症结,那么解决方法也就很容易理解了。
3.解决方法
大家做的硬件可能五花八门,但是问题解决方法大体上是一致的,
解决方法:就是做出硬件响应之后,要向云平台publish当前的状态。
下面以我的文章中提到的硬件和软件为例,具体可以参考文章:
从arduino板开始做到阿里云app控制--WeMos D1或ESP8266连接阿里云文章合集及源代码
硬件使用的是arduino d1模块

源代码用的是文章中的源代码。

如果我们要让设备向云平台publish属性改变,应该做出一定的修改。
void powerCallback(JsonVariant p)
{int PowerSwitch = p["LightSwitch"];if (PowerSwitch == 1){//看是否会响应云平台的内容Serial.println("Switch=1 ");digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage levelAliyunIoTSDK::send("LightSwitch", 1);}else{//是否会响应平台的内容Serial.println("Switch=0");digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGHAliyunIoTSDK::send("LightSwitch", 0);}
}
这样就实现了对硬件操作之后,再向云平台publish的操作。当云平台的topic做出改变之后,就可以显示正确的状态了。
效果如下图,首先在IoT Studio的编辑界面,按钮上方的红色提示文字消失了。其次是实际运行这个页面之后,能够正常控制LED灯的开关了。
