133
人物
【自定義開發】基於網關局域網通信協議二次開發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