智能家居入门DIY——【六、使用OneNet后台处理数据】
OneNet使用起来要比lewei50复杂一些,它没有前台需要自己开发。命令下发也和之前介绍的lewei50有一些区别,这里着重介绍一下使用MQTT协议来进行通讯。
一、准备
1、Esp8266开发板(+烧写器或者直接用WeMos D1 Wifi之类的就不要烧写器了)
2、Arduino IDE for VS
3、OneNet注册
二、OneNet配置
OneNet整体结构上与lewei50不同,它从产品开始下面可以有若干按APIKEY组织的设备群组(实名认证与否决定了能用多少产品和设备),每个设备下面可以有若干传感器和控制器(测试过程未发现个数限制)。而其中控制器状态是和传感器一起上传的,服务器下发的命令以Qos0进行,即不接收回复。更多的内容就请参考开发文档吧。
1、进入开发者中心创建产品

接入方式选择公开协议,设备接入协议选择MQTT。创建完成后,会得到一个APIKEY,这个APIKEY可以用于访问产品下的任何一个设备。当然,也可以创建一个新的APIKEY,然后设置该APIKEY关联的设备。
2、创建设备

其中设备名称和鉴权信息都是自定义,鉴权信息与设备ID是通用的,如果想要用MAC进行绑定那这里鉴权信息就填写设备的MAC地址,我就随便填了一个。当然这是与前台相关的内容,不在此讨论。
3、创建数据流模板

数据流名称最好简明,因为需要ESP8266处理的字符很多,而其资源也不是十分充裕。需要主意的是,每一个数据流就是一个传感器或控制器。即控制器也在这里创建。创建完成之后就可以把数据流和产品关联起来,为了直观观察,我们再在“应用管理”里面创建一个简单的应用:

选择这个开关控件,然后在右面除了关联设备数据流之外,设置一下开关开值和开关关值:

其默认值开为1,关为0。这里说明一下该参数在服务器下发命令时如何被解释(以图中的01和00为例):
把每个数字解释为1字节进行下发,所以上面00被接收到的是{0,0}这样的,它与0完全不同。而右面的按钮我设置的开关之分别为11、10,所以在后面的代码中前一字节被作为分组标志,后一字节被作为开关值。
三、编码
1、IDE和配置
与前一篇一样,这里使用Arduino IDE(实际上我用的是for vs,操作差不多,有代码提示而已)来进行编写。开发板选择NodeMCU1.0(ESP-12E Module),而不论使用的是WeMos D1 Wifi还是其他8针、IO全引出啥的(估计魔改串口4针的是玩不了的)。其他配置如下:

2、层次逻辑
a、Esp8266wifi.h负责连接WIFI
b、pubsubclient.h负责MQTT通讯(可变头和载体需要自定义,该库只负责Fixed header)
c、ArduinoJson.h负责构建载体中数据部分,具体格式请参考OneNet MQTT开发文档
d、eeprom.h负责将配置写到esp8266模块中和读取,这个的写操作与arduino开发板是不同的
3、主要代码示例
这里主要说一下MQTT部分,其他部分不再赘述。
a、pubsubclient总述:
WiFiClient wClient;
PubSubClient mClient(mServerAddress,mServerPort, mCallback,wClient);
其中,mCallback是一个回调函数,该函数用于处理服务器发来的消息,其签名如下:
void mCallback(char* topic, byte* payload, unsigned int length)
其中topic是话题,包含了topicName,Payload是实际下发的内容,例如上面的水泵开关开则有2字节:0 1。length指payload字节数。要处理的服务器数据就在该函数处理就可以了,但是最好别太长,否则影响数据的响应速度。
b、连接MQTT服务器
bool ConnectServer() {
    int waitConst = ;
    if (!mClient.connected()) {
        //id="设备id",user="产品id",pass="APIkey"
        mClient.connect(DeviceID, ProductID, APIKey);
        while (!mClient.connected() && waitConst<)
        {
            delay();
            waitConst++;
        }
        Serial.println((String)"ConnectServer " + mClient.connected());
    }
    return mClient.connected();// mClient.state() == MQTT_CONNECTED;
}
在Onenet开发者页面的说明后面有一段问答,其中明确说明了上面的参数如何传递,上面注释写的非常清楚了;当然也可以用前面提到的设备鉴权信息代替APIKEY字段作为password传入。
c、发布话题
bool PubTopic(String TopicName,String Json) {
    memset(msg_buf, , MQTT_MAX_PACKET_SIZE);        //清理MQTT消息缓存
    //设置可变头
    msg_buf[] = char(0x03);                        //包数据格式标志
    msg_buf[] = char(Json.length() >> );          //高位在后
    msg_buf[] = char(Json.length() & 0xff);        //低位在前
    //设置数据
    memcpy(msg_buf + , Json.c_str(), Json.length());
    mClient.publish(TopicName.c_str(), (uint8_t*)msg_buf, Json.length() + ); //设置发送长度以免中间的00使得自动判定长度出错。
}
可变头部分指明了使用哪种数据包格式,设置了Json数据长度。这一部分有若干种数据格式,具体参考开发文档,上面代码中使用的type3格式在说明文档中的说明如下:
数据类型3(type == 3)格式说明:
| Byte 1 | 数据点类型指示:type=3 // JSON格式2字符串 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 
| Byte 2 | //指示后面字符串长度 固定两字节长度高位字节,值为0x00 | ||||||||
| Byte 3 | 固定两字节长度低位字节,值为0x46 | ||||||||
| Byte 4 | 通用格式: { “datastream_id1”:”value1”, “datastream_id2”:”value2”, … } 示例: {“temperature”:22.5,”humidity”:”95.2%”} | ||||||||
| … … … … | |||||||||
| Byte n | 
看的时候无视这没头没尾的0x00、0x46吧。参考代码上面的代码就可以了。其中Json的构建在上一篇中已经说得非常清楚、十分深入了,完成这个代码构建是基础中的基础了,这里不再说明。
四、ESP8266的EEPROM
关于这个问题是看乐鑫的开发文档还是怎么的才能解决说起来没意义,上大家最喜欢的积木:
void SaveConfig(int cfgidx, String val) {
    //esp8266的EEPROM与Areduino的使用不同
    //1、申请操作缓存
    EEPROM.begin(eBlockSize);
    //2、写入数据
    for (int i = ; i < eBlockSize; i++) {
        EEPROM.write(cfgidx*eBlockSize + i, val[i]);
    }
    //3、保存数据更改
    EEPROM.commit();
}
好了,这篇就介绍到这里,也不把OneNet上面创建的这个设备的应用嵌入到这里了,愿意做的自己做一下就可以看到效果了。我这现在就几块开发板,USB已经插了一堆堆各种东西,不可能长期保持这东西在线的。
五、网络调试工具
这个不像之前的一些WIFI应用调试起来那么简单,有时候代码看着貌似都没问题就是不过,而服务器端没有提供底层的数据调试功能,一般的SOCKET调试工具也不提供MQTT服务器,自己架设一个也需要大篇幅的工作。所以具体WIFI发送了什么还是要一些其他工具。首先,得让数据从电脑上过去我们才有机会在电脑上下个钩子把数据呈现出来,于是我安了一个随身WIFI,设置好之后,让ESP8266连接它,至于用什么WIFI软件无所谓,根本别指望他们提供底层数据,也没指望去勾它们,那太麻烦了。开发一个新的东西也得不偿失,还是用专业工具吧,祭出神器winpcap就解决一切了。使用winpcap的网络封包工具很多,其中做的好的也不少,Ethereal就是其中一个,现在可能叫Wireshark。
智能家居入门DIY——【六、使用OneNet后台处理数据】的更多相关文章
- 智能家居入门DIY——【一、ESP8266之软串口HTTP请求】
		前段时间做了一个激光雕刻,玩的不亦乐乎.对Arduino大感兴趣,于是又入手一块20大洋版,配上买学习套件时的诸多零件——红外发射管.一体化红外接收头.DHT11温湿度传感器.ESP8266等,以及某 ... 
- 智能家居入门DIY——【五、执行命令】
		前面几篇介绍了ESP8266使用AT命令来连接WIFI实现一系列功能.这一篇介绍一下使用Wemos D1 Wifi来进行开发,当然也可以用常见的8针ESP8266来完成(只是需要按网上的方法将Ardu ... 
- 智能家居入门DIY——【七、添加一个LCD12864吧】
		今天加了一个LCD12864,IC看说明上是ST7567,结果一顿U8g2,发现两个问题: 1.买的时候不知道是卖家写的我理解错了还是怎么了,反正是不出汉字的. 2.U8g2太大了…………占了uno的 ... 
- 智能家居入门DIY——【四、组合】
		前面几篇介绍了一些传感器和代码,这篇介绍一下把它们组合起来.之所以单独列出这部分,原因在于组合更多功能的时候发现使用软串口库驱动ESP8266时由于内存过小导致发送失败甚至整个系统无法工作的情况.所以 ... 
- 智能家居入门DIY——【三、GP2Y10之颗粒物传感器】
		这个传感器接线算比较简单的,程序也不麻烦.不过这东西是颗粒物传感器吧,不是神马PM2.5(总悬浮颗粒物),不是神马PM10(可吸入颗粒物).插个螺丝刀进去度数也是变的,不是说的很清楚原理是反光嘛……… ... 
- 智能家居入门DIY——【二、LD3320之语音识别】
		前一篇说了一下只有RX,TX,VCC,GND的WIFI模块软串口通讯:在实现了远程观察数据,类似的就可以实现远程控制.接下来说一下近距离控制,很多情况下应用语音识别技术无疑比掏出手机操作要更人性化一些 ... 
- springboot2.0入门(六)-- ymal语法、数据校验
		一.基本使用 1.ymal语法是一种更符合人类命名习惯的语法: # 1. 一个家庭有爸爸.妈妈.孩子. # 2. 这个家庭有一个名字(family-name)叫做“happy family” # 3. ... 
- DIY智能家居——零基础入门篇
		概要 本文主要根据笔者从零开始接触硬件,以小白视角开启IoT探索,根据相关资料DIY一个温湿度传感器.后经过探索发现新大陆--Home Assistant&Homebridge,最终实现了一个 ... 
- 入门智能家居,从 IFTTT 到 HomeKit 自动化(二)
		入门智能家居,从 IFTTT 到 HomeKit 自动化(二) 目录 0. HomeKit.HomeBridge.HomeAssistant 分别是什么?关系是什么? 1. 开始前的准备 2. 整 ... 
随机推荐
- nvm命令行操作命令
			1,nvm nvm list 是查找本电脑上所有的node版本 - nvm list 查看已经安装的版本 - nvm list installed 查看已经安装的版本 - nvm list avail ... 
- 解决数据库里表字段带下划线,实体类转小驼峰,Mapper的映射问题
			mybatis中mapUnderscoreToCamelCase的使用 mybatis-config.xml配置: <?xml version="1.0" encoding= ... 
- Maven .m2文件夹创建
			settings.xml存在于两个地方: 1.安装的地方:$M2_HOME/conf/settings.xml 2.用户的目录:${user.home}/.m2/settings.xml 前者又被叫做 ... 
- javascript debugger
			打开调试工具,刷新,可以看到脚本被暂停 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ... 
- vapply
			尽管 sapply 非常方便和智能,但有时智能可能隐藏着风险.假如我们有一个数字列表:x <- list(c(1, 2), c(2, 3), c(1, 3))如果我们想得到一个向量,其中每个元素 ... 
- spark + cassandra +postgres +codis 大数据方案
			1.环境: 1.1.cassandra 集群: 用于日志数据存储 1.2.spark集群: 用户后期的实时计算及批处理 1.3.codis 集群: 用于缓存一些基本数据如IP归属地,IP经纬度等,当日 ... 
- Java IO流-序列化流和反序列化流
			2017-11-05 20:42:06 序列化流:把对象按照流的方式存入文本文件或者在网络中传输. 对象 -- 流数据(ObjectOutputStream) 反序列化流:把文本文件中的流对象数据或者 ... 
- uva10655矩阵快速幂
			a^(n+2)+b^(n+2)=(a+b)*(a^(n+1)+b^(n+1))-a*b*(a^n+b^n) 坑爹的题目关系式都推出来了居然还是wa了..... 不能只看p,q=0就退出,因为a,b不一 ... 
- java反射教程
			什么是反射,为什么它是有用的,以及如何使用它? 1.什么是反射? “反射通常是JVM中运行的程序需要检测和修改运行时程序的行为的一种能力.”这个概念通常与内省(Introspection)混淆.以下是 ... 
- ps怎么替换颜色
			1.图像--->>调整--->>替换颜色 
