【自定义开发】基于网关局域网通信协议二次开发PHP版
【前言】
之前看到小米网关有局域网通信协议,找到了相关api文档,基于此,想更加个性化智能家庭,所以根据api二次开发些小功能,比如可以推送到微信,发送短信等等。
本篇分享不会有很多具体的实现方法,只是一些基本操作,之前我搜了不少时间,发现其实没人分享具体的代码,所以想写篇文章分享一些。本次代码采用的是php语言,抛砖引玉,希望大神们多多指点。
放上github地址,暂时先【回复可见】几天,希望能留几天首页让更多的人看到:
以下内容被隐藏,回复本帖后可见
【正文】
下面开始正式分享:
1.首先,你要会看官方的api文档,具体地址为:
https://forrestfung.gitbooks.io/lumi-gateway-local-api/content/
根据官方说法:网页版的文档不是最新的,所以自行下载最新版的api文档,自行在文章末尾下载。
2.有了api文档之后,那么就可以自行开发了,本次使用的是php语言,如果没有相关基础,可以去学一下,入门不是很难。
我为什么用php呢?
①目前靠这个吃饭;②我有其他开发的功能,可以方便的把小米网关接入我已经开发好了的系统中;③php是最好的语言(无奈脸)
3.回归正题,说下具体的代码,再强调一点,只说基础操作,不说具体业务逻辑
在写代码之前,一定要先打开网关的局域网通信功能,这样才能进入开发,具体方法,论坛多的是。
3.1接受小米网关报文
打开局域网通信功能之后,网关每10秒就会发送一次报文到网络,告诉网络中所有人:“我在正常工作”,那么我们首先要怎么接收到这个消息呢,看下面代码:
function listenGateway()
{
set_time_limit(0);
ob_implicit_flush();
//创建socket绑定ip
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);//创建socket,模式为upd
socket_bind($socket, '0.0.0.0', 9898);绑定ip及端口,照抄就行,不用修改,9898端口是网关提供的
以下内容被隐藏,回复本帖后可见
//接收数据
while (true) {
//显示收到的结果
$port = 0;
$from = "";
socket_recvfrom($socket, $recvStr, 1024, 0, $from, $port);
"time:" . date("Y-m-d H:i:s") . "\r\n";
"from:" . $from . "\r\n";
"recvStr:" . $recvStr . "\r\n";
"\r\n";
}
socket_close($socket);
}
把上面代码复制到php文件中,然后再命令行下面执行就可以了,这样,就能在命令行看到网关发过来的信息了。
3.2获取相关设备的信息
上一段代码可以让我们被动获取到网关信息,那么如何主动获取相关信息了,请看代码
$sendMsg = "{'cmd':'whois'}";//查询网络中所有网关的信息,本命令需要使用组播方式发送出去
readGateway($sendMsg, 1);//获取信息
/**
* 读取网关命令
* @param string $cmd json格式
* @param int $isGroup 是否组播0不是1是
*/
function readGateway($cmd, $isGroup = 0)
{
//创建socket
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
以下内容被隐藏,回复本帖后可见
//显示收到的结果
$port = 0;
$from = "";
socket_recvfrom($socket, $recvStr, 1024, 0, $from, $port);
"time:" . date("Y-m-d H:i:s") . "\r\n";
"from:" . $from . "\r\n";
"recvStr:" . $recvStr . "\r\n";
"\r\n";
socket_close($socket);
}
以上代码可以获取网关列表了,那么具体获取某个设备的命令代码呢?如下:
$sendMsg = '{"cmd" : "get_id_list"}';//读取子设备列表,不用在组播
readGateway($sendMsg);
更多的命令请自行参考api文档吧~
3.3操作相关设备
上面的代码可以让我们获取相关设备的代码,接下来我们要操作设备了,网关操作设备需要有一个key,首先说说这个key怎么生成。根据api文档,网关每10秒发送一次信息,其中有一个属性是token,然后用这个token通过一系列算法获取key,但是,这个token每次都是不一样的,所以我们要想获取token,有2种方法:1把每次网关送来的token存起来,用的时候取最新的出来,2先查询一次子设备列表,返回的信息中也会有token,然后用这个token去生成key。目前我用的是第二种方法。具体代码如下:
$sendMsg = '{"cmd":"read","sid":"123456"}';//获取具体设备信息,sid为上面一条命令获取到的结果,请根据实际情况填写
readGateway($sendMsg);
一定要注意,那个sid是通过前面监听网关信息获取到的
有了token,那么接下来实现获取key的方法,具体代码如下:
以下内容被隐藏,回复本帖后可见
有了key,那么就可以实现对设备的操作,以下是对无线开关的操作示例
$writeCmd = [
"cmd" => "write",
"model" => "switch",
"sid" => "123456789",//sid需要具体自己填写
"short_id" => "66666",//short_id也是要自己填写
"data" => [
"key" => $key,//之前生成的key
"status" => "click"],//事件
];
//创建socket
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
//发送命令
socket_sendto($socket, $cmd, strlen($cmd), 0, $this->gateWayIp, $this->gatewayPort);
//显示收到的结果
$port = 0;
$from = "";
socket_recvfrom($socket, $recvStr, 1024, 0, $from, $port);
"time:" . date("Y-m-d H:i:s") . "\r\n";
"from:" . $from . "\r\n";
"recvStr:" . $recvStr . "\r\n";
"\r\n";
socket_close($socket);
以上就是全部的代码片段了,那么如何实现和微信、发短信之类的互动呢。。自行开发其他功能调用。
希望这些对大家有所帮助,也希望小米越来越好!有什么不懂的可以私信我~
最后更新:2017-08-24 11:18:24