瘦网虫 发表于 2013-8-5 15:11:20

乐联网功能介绍-控制设备

本帖最后由 瘦网虫 于 2014-12-24 09:27 编辑

最近陆陆续续很多人玩了乐联网的反向控制功能,实现了自己的反向控制函数的调用,而且可以通过网页控制自己的设备了。

于是很多人想更进一步,通过手机等设备来控制自己的设备。但是发现乐联网里面的“控制设备”这个功能不是那么好用。

这里简单介绍一下,并且附加一些arduino代码,供有兴趣的人参考。





同样是反向控制,但是,是有区别的。

它们在乐联网上的实现,也是所不同的。

对于“控制设备”,可以是个继电器、开关、调速器等,它需要向服务器(例如你的手机,或者网页)报告它所有设备的当前状态(通过响应“getAllSensors”命令),例如设备名,id,类型,当前状态等。在进行完“切换”操作后,还要再汇报一次自己的当前状态,已更新服务器端存储的信息。


/*
{\"method\":\"response\",\"result\":{\"successful\":true,\"message\":\"null\",\"data\":[{\"id\":\"POWER\",\"type\":\"jdq\",\"name\":\"POWER\",\"value\":\"1\",\"status\":\"ok\"}]}}&^!
你的控制开关叫 POWER,你就发上面的数据
服务器向你发getAllSensors你就返回上面的
*/


对于“执行命令”,就没有那么多讲究了。只要接收到服务器发来的命令,跟自己名字匹配上了,就执行就可以了。不需要向请求方发送自己的执行结果等。

下面结合个实例,让玩家可以简单的实现自己的“控制设备”,并且希望能有更深刻的理解:

首先你要有个乐联网的E-KIT,不好意思,嵌入广告了。
或者你可以用个arduino UNO+w5100搭一个平台也可以实现,最好是用arduino mega 2560+w5100来测试这个代码。
然后,你要有乐联网帐号什么的,这个不多说了。

然后下载https://github.com/lewei50/LeweiTcpClient/tree/LeweiTcpClientliteBeta,这个库支持了自定义的“控制设备”。
下面的代码里还用到了自己写的IRremoteLite库,在这里下载
https://github.com/yangbo1979/IRremoteLite
如果你不需要红外控制的话,可以自行删除对应的代码。我这里控制的是“格力”的挂机开关。
下面的代码里面用到了dht11传感器测温湿度,一个红外2极管发射红外指令。
接线如下:
DHT11 vcc pin->+5v
DHT11 data pin->d2(数字引脚2,从d0开始数,第三个孔)
DHT11 gnd pin->gnd
http://www.lewei50.com/userfiles/tutorial/1-3-1.JPG

红外接线:
GND->红外的瘦的那个针脚
D3->红外发射管里面那个碗状的针脚。

把下面的代码,改下userkey和gateway后刷入你的设备。


#include <SPI.h>
#include <Ethernet.h>
#include <LeweiTcpClient.h>//乐联网的类库
#include <EEPROM.h>
#include <IRremoteLite.h> //红外控制的自定义精简库
#include <dht11.h>
//#include <EthernetUdp.h>

#define LW_USERKEY "your api key here"//change your api key here,这里要改
#define LW_GATEWAY "01"//change your gateway number here,这里看着改

//unsigned int localPort = 9959;
// buffers for receiving and sending data
//char packetBuffer; //buffer to hold incoming packet,
//charReplyBuffer[] ="{\"deviceName\":\"01\",\"api\":\"http://tcp.lewei50.com:9965/?method=send&gatewayNo=01\",\"requestType\":\"get\"}";       // a string to send back
//EthernetUDP Udp;

dht11 DHT11;
#define DHT11PIN 2

IRsend irsend;

//use PROGMEM to defined the 'large' variables into flash,not using the ram
//开关格力空调的红外原始编码
PROGMEM unsigned int rawCodes_ac_open = {4397,4368,561,1578,560,537,557,1581,584,1582,584,486,558,537,584,1554,560,538,558,510,558,1607,557,513,585,511,556,1585,581,1583,583,486,557,1609,556,513,558,538,557,512,558,1607,558,1583,557,1608,558,1608,557,1580,559,1606,559,1581,556,1609,557,512,559,537,558,512,557,539,557,512,558,1607,558,1582,558,537,584,1555,558,1607,556,514,559,537,556,513,558,537,556,514,558,1606,559,511,583,513,558,1582,557,1608,558,1580,585,5154,4419,4347,584,1555,558,539,557,1581,584,1581,571,501,577,516,571,1568,557,541,581,487,557,1608,557,513,558,538,557,1582,583,1582,584,487,557,1608,557,511,611,486,558,510,558,1607,557,1609,556,1583,583,1582,583,1555,558,1607,558,1607,559,1582,557,537,585,486,558,510,558,540,558,509,557,1608,558,1608,557,512,559,1606,559,1581,558,537,581,490,558,510,587,511,557,511,559,1606,559,510,569,527,558,1582,560,1604,561,1605,561};
PROGMEM unsigned int rawCodes_ac_close ={4193,4096,595,1451,589,432,588,1453,589,1454,587,432,587,434,563,1475,591,433,564,458,586,1453,587,434,587,433,563,1476,590,1454,587,434,565,1475,566,456,563,1476,590,1453,587,1452,564,1477,566,457,585,1453,567,1477,587,1452,564,460,584,434,564,457,562,460,562,1475,587,434,588,433,562,1476,589,1455,563,1476,588,433,586,436,562,459,586,433,563,458,609,410,563,458,586,433,587,1454,587,1453,563,1477,564,1477,565,1476,581,4858,4237,4074,593,1453,562,460,563,1477,563,1477,565,458,587,434,584,1454,590,433,562,458,587,1453,588,436,584,436,562,1476,588,1453,590,434,562,1480,586,435,586,1453,565,1476,589,1453,589,1451,565,461,583,1453,589,1453,588,1454,564,457,587,434,587,433,587,435,561,1479,586,435,562,458,588,1452,590,1452,565,1476,564,458,587,436,584,433,562,458,588,432,562,461,585,434,584,435,589,1451,588,1453,588,1453,590,1453,590,1451,590};
//下面的地址什么的,根据需要自己改
byte mac[] = {0x74,0x69,0x69,0x2D,0x30,0x31};
IPAddress ip(192,168,1, 15);
IPAddress mydns(8,8,8,8);
IPAddress gw(192,168,1,1);
IPAddress subnet(255,255,255,0);

LeweiTcpClient *client;
long starttime;
int postInterval = 10000;//10秒更新一次温湿度
void setup()
{
Serial.begin(9600);
pinMode(3, OUTPUT);
starttime = millis();
//you can use 3 ways to init your network
//1.simplest
//client = new LeweiTcpClient(LW_USERKEY, LW_GATEWAY);
//2.set mac only
//client = new LeweiTcpClient(LW_USERKEY, LW_GATEWAY,mac);
//3.full setting for your network
//使用了自定义的ip地址来初始化乐联网的库
client = new LeweiTcpClient(LW_USERKEY, LW_GATEWAY,mac,ip,mydns,gw,subnet);
//Udp.begin(localPort);

//test1 is the function you write below to handle your program
//"testFunction" is the function name you set on website:http://www.lewei50.com/
//on "controll command manager" menu
//we test transfer 1-5 para from website(you defined on it) to your arduino
//enjoy it

//UserFunction ufChangeLed(changeLed,"changeLed");
//client->addUserFunction(ufChangeLed);
//这里是乐联网的“控制命令”的自定义
UserFunction uf1(openAc,"openMyAC");
client->addUserFunction(uf1);
UserFunction uf2 (closeAc,"closeMyAc");
client->addUserFunction(uf2);
//这里是乐联网的“控制设备”的自定义,设备的开始默认状态为开(1)
UserSwitch us1 (switchTest,"swTest",1);
client->addUserSwitch(us1);
//client->easySetupMode(true);
client->checkFreeMem();
}

void loop()
{
    client->keepOnline();
    if ((millis()-starttime) > postInterval)
    {
      sendDht11Value();
      starttime = millis();
    }
    /*
int packetSize = Udp.parsePacket();
if(packetSize)
{
   
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++)
    {
      Serial.print(remote, DEC);
      if (i < 3)
      {
      Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
}
*/
}

void sendDht11Value()
{
//read DHT11 sensor
      int chk = DHT11.read(DHT11PIN);
      switch (chk)
      {
      case DHTLIB_OK:
//                  Serial.println("OK");
                  
                  //Serial.print("*** start data collection ");
                  //Serial.println(DHT11.temperature);
                  
//                  client->sendSensorValue("tcp1","20");
                  client->sendSensorValue("temperature",(String)DHT11.temperature);
                  client->sendSensorValue("humidity",(String)DHT11.humidity);
                  
                  client->checkFreeMem();
                  break;
                  
//      case DHTLIB_ERROR_CHECKSUM:
//                  Serial.println("Checksum error");
//                  break;
//      case DHTLIB_ERROR_TIMEOUT:
//                  Serial.println("Time out error");
//                  break;
//      default:
//                  Serial.println("Unknown error");
//                  break;
                  
      }
   
}

//function functionIWrote use 1 parameter,on the website,it point to "p1"
void changeLed(char * p1)
{
client->setRevCtrlMsg("true","ok");
Serial.println(p1);
}


//function without parameter
void openAc(char* p1)
{
client->setRevCtrlMsg("true","o");
client->checkFreeMem();
irsend.sendRaw(rawCodes_ac_open,200, 38);
}

void closeAc(char* p1)
{
client->setRevCtrlMsg("true","c");
client->checkFreeMem();
irsend.sendRaw(rawCodes_ac_close,200, 38);   
}

void switchTest(char* p1)
{
Serial.println("switch test");
client->setRevCtrlMsg("true","switch changed");
/*
if(String(p1).equals("1"))
{
    openAc("1");
}
else
{
    closeAc("0");
}
*/
client->checkFreeMem();
}



代码的62、63行指定了网页中你设定的“控制设备”的名字,默认为“开”。

UserSwitch us1 (switchTest,"swTest",1);
client->addUserSwitch(us1);

网页里是这么设置的


刷入代码后,通过网页应该可以控制你的“控制设备”了。
通过手机控制的话,需要从github下载最新的手机端软件:
https://github.com/lewei50/LeweiApp/
下载bin目录下的LoginActivity.apk


上面代码实现的功能是发布你的温度到乐联网,并且可以控制空调开关。

我的截屏中的其它控制设备的联合使用效果见下面的视频:
http://player.youku.com/player.php/sid/XNTg3Mjk3MTU2/v.swf
Enjoy it~

yuefengkai 发表于 2013-8-5 15:17:07

传说中的沙发。。。谢谢胖网虫{:soso_e113:} {:soso_e113:}

俯首观天 发表于 2013-8-5 20:21:04

又有大作发布,来晚了

疯子。 发表于 2013-8-6 02:04:49

为拍这个视频浪费了不少电。。。

问题不大 发表于 2013-8-13 21:03:03

又有大作发布

迷你强 发表于 2013-8-15 21:42:51

:o高级啊

万马奔腾 发表于 2013-8-16 22:03:18

顶 这个能否实现用手机的APP控制继电器的开关啊~

ntwhq 发表于 2013-11-7 15:56:11

请问对应下面这段程序在物联网上是否是要作相应的设置?怎么设置(最好给你一下设置界面)?谢谢!
“这里是乐联网的“控制命令”的自定义
UserFunction uf1(openAc,"openMyAC");
client->addUserFunction(uf1);
UserFunction uf2 (closeAc,"closeMyAc");
client->addUserFunction(uf2); ”

瘦网虫 发表于 2013-11-8 14:52:51

本帖最后由 瘦网虫 于 2013-11-8 14:57 编辑

ntwhq 发表于 2013-11-7 15:56 static/image/common/back.gif
请问对应下面这段程序在物联网上是否是要作相应的设置?怎么设置(最好给你一下设置界面)?谢谢!
“这里 ...

UserFunction uf1(openAc,"openMyAC");
这句话是设置一个对应关系,
前面的openAc是个函数名,在程序里面你能搜到这个代码段,函数功能就是为了开空调(囧),
后面的"openMyAC"是你在网站上设置的函数名称,是给你自己看的。


通过这个库可以把你的arduino设备和乐联网保持一个连接,arduino端负责解析openAc这一段,网站那边负责解析openMyAC这一段,通过这个影射关系,你就可以轻松控制你的arduino了。

不过这个帖子目的是演示下面这段代码。呵呵。
UserSwitch us1 (switchTest,"swTest",1);
client->addUserSwitch(us1);

瘦网虫 发表于 2013-11-8 14:55:30

万马奔腾 发表于 2013-8-16 22:03 static/image/common/back.gif
顶 这个能否实现用手机的APP控制继电器的开关啊~

可以的。。函数作什么用完全取决于你自己,这个实质上是给你一个通道。

ntwhq 发表于 2013-11-9 11:36:07

本帖最后由 ntwhq 于 2013-11-9 11:48 编辑

瘦网虫 发表于 2013-11-8 14:52 static/image/common/back.gif
UserFunction uf1(openAc,"openMyAC");
这句话是设置一个对应关系,
前面的openAc是个函数名,在程 ...

谢谢赐教!我现在还是连不成功(同样设备arduino+w5100在Yeelink上能实现远程控制,说明设备和我的网络环境没有问题),不知道问题出在哪儿?您帮看一下,相关信息如下:
网关设置:


设备设置:


点击“控制设置”后对话框:


点击“切换”后对话框:


手机登录乐联网后也找不到设备:


再请教两个问题:
1、Yeelink网设备不接时也能正常发送命令,设备接上后就能再执行,乐联网是否设备没有正常工作,就出现找不到设备的接示?即出现上面的相关提示说明我的设备没有正常工作,而不是网站设置上的问题?
2、按照您说的:
“不过这个帖子目的是演示下面这段代码。呵呵。
UserSwitch us1 (switchTest,"swTest",1);
client->addUserSwitch(us1);”
这里openMyAC和closeMyAc这两个方法在网站是否就不要设置了,我只有一个网关,只能设置两个中的一个,不设置这两个不影响您说的测试吧?

对于乐联网反向控制的设置,没有找到一个比较完整的教程,您能否推荐一个,比如点亮一个二极管,第一关过了以后学习就方便了。
再次谢谢!

ntwhq 发表于 2013-11-12 14:20:01

本帖最后由 ntwhq 于 2013-11-12 14:33 编辑

谢谢楼主点评回复.
       我的arduino设备本地地址:192.168.1.15是可以ping通的,您说的“设置成固定ip地址试试看”,现在arduino设备IP地址是固定的,如果指外网IP地址固定不大可能,即使在单位出口是固定IP地址,但在内网使用还要做net转换,显然不方便。网站的API地址填http://tcp.lewei50.com:9965/?method=send&gatewayNo=01应该没问题吧?
       看了你推荐的帖子 :http://www.lewei50.com/dev/doc/142 不明白远程控制LED开关为什么要设置成测量设备,为什么不用控制设备?我试了,在网站是可能控制的,但用手机就无法控制了。
       再次谢谢!

瘦网虫 发表于 2013-11-13 09:59:23

远程控制led可以用测量设备也可以用控制设备,乐联网对这两种都支持,但是实现方式不一样而已。
控制“测量设备”的方式是通过设置“智能物联”里面的“控制命令管理“来实现的,需要你自己在你的arduino端写点代码;
控制”控制设备“的方式是在你的arduino端必须要实现乐联网规定的"getAllSensors”方法来实时回报你的控制设备状态(这个方法我在库里面帮你实现了)。
手机客户端目前不支持读取网站上设置的“自定义函数”,所以,手机端想远程控制你的设备,就需要把你的设备设置为“控制设备”。
这就是2者的区别。你需要深入测试使用后才能体会。:dizzy:

ntwhq 发表于 2013-11-13 15:22:49

瘦网虫 发表于 2013-11-13 09:59 static/image/common/back.gif
远程控制led可以用测量设备也可以用控制设备,乐联网对这两种都支持,但是实现方式不一样而已。
控制“测量 ...

谢谢指点,我以后再慢慢学习体会。

ntwhq 发表于 2013-11-19 10:38:31

本帖最后由 ntwhq 于 2013-11-19 11:57 编辑

      程序经过修改,已经能反向控制继电器了,用乐联网上的“切换”按钮控制完全正常,手机上也能看到可控设备列表并进行反向控制了,但每切换一下都要弹出下面的对话框:



   然后要重新登录才能继续控制。是不是乐联网手机app软件有问题?我用的版本是20130116:beta0.2 。
页: [1] 2
查看完整版本: 乐联网功能介绍-控制设备