閱讀133 返回首頁    go 人物


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

  上一篇:go 米家定位權限問題
  下一篇:go 智能設備比較多,修改WIFI密碼好麻煩