Eric 发表于 2014-11-14 16:10:22

Machtalk物联网平台控制开关量、数字量及监测环境温度

本帖最后由 Eric 于 2014-11-14 18:11 编辑

感谢dfrobot提供的wido wifi模块,还是比较容易上手的。通过这篇案例向大家介绍machtalk平台做为云平台如果存储展示采集数据,并向大家介绍如何通过socket长连接的方式上传数据、控制开关量及控制数字量。相信很多人现在都了解如何通过云平台上传数据以及http方式控制开关量,但却不知道如何通过云平台控制模拟量。首先说一下通过http方式控制开关量,这是采用轮询的方式查询云平台的数据来控制设备的开关量,有个缺点它并不是实时的,而且云平台并不知道是否真正的已经控制设备。Machtalk云平台采用socket长连接的方式,让服务器和设备之间通过心跳保持连接,这样云平台就可以知道设备是否在线,并且通过信息反馈的方式通知云平台在线设备是否真正得到了控制,只有设备真正得到了控制,云平台才会显示控制后的界面。另外Machtalk云平台采用的是服务器集群,这样避免了所有设备只连接一台服务器,服务器压力过大的危险。设备连接machtalk云平台需要先连接登录服务器,由登录服务器通过负载均衡分配给设备一个connect服务器的IP和端口,然后设备再去连接connect服务器,这样避免服务器压力过大而崩溃。进入主题,文档将详细介如何使用wido wifi模块(当然也可以采用其他硬件产品)上传数据、控制开关量及控制模拟量,为电子产品爱好者、开发者及做智能家居、可穿戴产品、家电产品的朋友提供一份参考。文档分为以下几个部分讲诉1、硬件准备连接 2、machtalk物联网平台配置 3、软件编程 4、物联网平台数据展示。一、硬件准备连接1、wido模块(由dfrobot提供,非常感谢哦)2、数据线(安卓手机上的数据线一根 也是dfrobot提供的)3、模拟量传感器一个,LM35 (5V GND OUT)分别与wido模块的5V GND A(0)连接。4、继电器(用于控制插座、灯开关)5、舵机(用于控制数字量)二、Machtalk物联网平台配置1、注册帐号访问注册地址:http://www.machtalk.net/user/registIndex 如下图,填写必填信息file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg   注册后会有一个邮箱激活的信息,到注册邮箱激活就可以了。里面有一些machtalk平台的基本信息,还有一个技术交流群号300250166。2、设备添加登录machtalk平台,进入用户中心,在这里会看到自己的基本信息。
file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg点击左边的“设备”,会进入到设备列表,如下图所示:
file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg 在这个地方可以看到自己帐号上的所有设备,点击 “增加设备”进入添加设备页面:
file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg其中有两项非常重要:值类型和值ID, 会在编程中用到。值类型是指你的数据是哪种类型的数据(1数值类, 2 开关类,3 GPS类,4 泛型类)值ID是指你这个设备中的第几个值。要记住这两个哦,编程中会用到。设备ID、值和值类型ID位置可以看下面的URL:/v1.0/device/device_id/device_value_id/device_value_type_id/datapoints/add还有一项PIN码也非常重要,是你这个设备的密码,在编程中会用到,是系统自动生成的。
也可以添加动作、添加触发器,它的作用是当采集的数据值超出你设定的范围值就会向你的邮箱发邮件报警等。三、软件编程1、首先下载wido使用库,以及一个json解析库,放置\Arduino\libraries库文件夹里。2、下载已经写好的wido2machtalk456程序,修改自己帐号设备ID、值ID、值类型ID以及pin码(这是这个设备的密码,是自动生成的)。3、程序流程:(1)Wido模块连接自己家的无线路由器:file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg(2)连接登录服务器并发送登录操作消息格式:{   "cmd": "login",    "mid":"1",//递增,记录在会话session中   "type":"1",//用户1、设备2   "usr": "liupeizhi", //用户代表用户名,设备代表设备ID   "pwd": "dc483e80a7a0bd9ef71d8cf973673924"//MD5加密后的密码,用户代表密码,设备代表设备PIN}

staticunsigned long RetryMillis = 0;charstrmid;char strtemp; // lian jie ip delay(5000);if(!WidoClient.connected() &&millis() - RetryMillis > TCP_TIMEOUT){    RetryMillis = millis();    WidoClient.close();    ip =Wido.IP2U32(60,211,253,162);    WidoClient = Wido.connectTCP(ip,7779);         } //fa song deng lu cao zuo delay(1000);WidoClient.fastrprintln(F("{\"cmd\":\"login\",\"mid\":\"1\",\"type\":2,\"usr\":\"87e4f47cc03347ee8382b24dfb1516c9\",\"pwd\":\"4a71754c408fd009b522acd57f1dc39c\"}"));

返回信息:登录成功则返回:server->user/dev{   "cmd": "resp",    "success": 1,    "mid": "222",    "apikey": "ssssss", //用户APIKey   "ip": "192.168.0.1", //连接服务器IP   "port": 6666//服务器端口}
登录失败返回:{"cmd":"resp","success":0,"errorcode":"10000","mid":"ddd222"}

(3)接收登录服务器发送的信息并解析接收的json
   recv();   JsonParser<32> parser;   JsonHashTable hashTable =parser.parseHashTable(json);   hashTable.success();
    char* ipok =hashTable.getString("ip");    uint8_t a,b,c,d;   sscanf(ipok,"%d.%d.%d.%d",&a,&b,&c,&d); ip =Wido.IP2U32(a,b,c,d);
    char*port=hashTable.getString("port");    uint16_t portok=atoi(port);    WidoClient.close();
void recv(){ unsigned long rTimer = millis(); while(millis() - rTimer < 2000) {while (WidoClient.connected() &&WidoClient.available())   {      char c = WidoClient.read();      if(c =='{')      Response=true;      else if(c =='}')      {      Response=false;      Response+=c;      }      if (Response)      returnvalue +=c;         } }    if (returnvalue.length() !=0){             int i;       Serial.print(returnvalue);    for(i=0;i<returnvalue.length();i++)    json=returnvalue;    json='\0';    returnvalue="";    } }



(4)连接connect服务器和端口,并发送连接信息
    WidoClient = Wido.connectTCP(ip,portok);       delay(1000);// que ren lian jie   WidoClient.fastrprint(F("{\"cmd\":\"connect\",\"mid\":\""));    mid+=1;    itoa(mid,strmid,10);     WidoClient.fastrprint(strmid);   WidoClient.fastrprintln(F("\",\"usr\":\"87e4f47cc03347ee8382b24dfb1516c9\",\"type\":2,\"encode\":\"\"}"));

(5)接收云平台connect服务器发来的消息并向服务器发送心跳消息
if(WidoClient.available())   {      char c = WidoClient.read();      if(c=='{')      Response=true;      else if(c =='}')      {      Response=false;      returnvalue+=c;      }      if (Response)      returnvalue +=c;                     }           if(millis()-lasttime>10000)      {      lasttime=millis();         WidoClient.fastrprintln("{1}");      }
(6)操作设备云平台操作设备时接收到的消息格式消息内容:{   "cmd": "opt",    "mid": "ddd222",    "to": "c95808d07d83430d919b3766cafc3ff3",    "from": "username", //服务端拼加,根据sessionID确认from   "dvid": 5,    "value": "commandvaluestr"}
返回信息:操作设备成功,设备向服务器发送以下内容:{   "cmd": "post",    "from": "c95808d07d83430d919b3766cafc3ff3",    "values": [      {            "dvid": “5”,             "value":"commandvaluestr"      }   ], "needack": 1,mid":"ddd222"//需要一个mid来确定是哪条消息}
解析云服务器发来的操作消息,并控制设备
if(returnvalue.length()!=0&&Response==false)   {            Serial.println(returnvalue);             int i;         //jie xi      for(i=0;i<returnvalue.length();i++)      json=returnvalue;      json='\0';      returnvalue="";          JsonParser<32> parser;      JsonHashTable hashTable =parser.parseHashTable(json);      hashTable.success();       char* scmd =hashTable.getString("cmd");      char* smid =hashTable.getString("mid");      char* svalue =hashTable.getString("value");         char* sdvid=hashTable.getString("dvid");      if(strcmp(scmd,"opt")==0)      {          WidoClient.fastrprint(F("{\"cmd\":\"post\",\"from\":\"87e4f47cc03347ee8382b24dfb1516c9\",\"values\":[{\"dvid\":"));         WidoClient.fastrprint(sdvid);          WidoClient.fastrprint(F(",\"value\":\""));         WidoClient.fastrprint(svalue);          WidoClient.fastrprint(F("\"}],\"needack\":1,\"mid\":\""));         WidoClient.fastrprint(smid);          WidoClient.fastrprintln(F("\"}"));                   }   }
(7)数据上传消息内容:{   "cmd": "post",    "from": "c95808d07d83430d919b3766cafc3ff3",    "values": [      {            "dvid": “5”,             "value":"commandvaluestr"      }   ], "needack": 1,“mid”:”123”}
返回消息:成功返回:{"cmd":"resp","success":1,“mid”:”123”}
失败返回:{"cmd":"resp","success":0,"errorcode":"10000",“mid”:”123”}


if(millis()-sensorstamp>10000)   {      sensorstamp=millis();      int reading = analogRead(0);      WidoClient.fastrprint(F("{\"cmd\":\"post\",\"from\":\"87e4f47cc03347ee8382b24dfb1516c9\",\"values\":[{\"dvid\":1,\"value\":\""));      itoa(reading,strtemp,10);       WidoClient.fastrprint(strtemp);       WidoClient.fastrprint(F("\"}],\"needack\":1,\"mid\":\""));      mid+=1;         itoa(mid,strmid,10);       WidoClient.fastrprint(strmid);      WidoClient.fastrprintln(F("\"}"));   }            

以上介绍完了machtalk定义的socket交互协议的消息内容,以及如果通过wido模块编码,会把源码及所使用到的库附在附件中,用户只要把使用库放在arduino的库文件中,并下载已经写好的代码,把代码中的ID替换成自己ID就可以实现设备控制了。四、数据展示OK 大功告成了查看数据结果吧http://machtalk.net/device/dataview/87e4f47cc03347ee8382b24dfb1516c9此图用于显示历史数据。
file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg此数据是有点乱,是因为采集口没有放传感器,放个传感器就OK啦。这是控制界面的图:
file:///C:/Users/Eric/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg通过这个界面可以控制开关量以及模拟量数据,还能实时显示温度值。



Ricky 发表于 2014-12-7 23:53:54

这个有人尝试过吗?
页: [1]
查看完整版本: Machtalk物联网平台控制开关量、数字量及监测环境温度