GitChat · 人工智能 | 用語音和天然語言控制智能家居——實例分享

GitChat 做者:晶晶郭
原文:用語音和天然語言控制智能家居——實例分享
關注公衆號:GitChat 技術雜談,一本正經的講技術html

前言

ZigBee做爲一種短距離、低功耗的無線通訊局域網協議,其優勢是超低功耗、安全性高和自組網,而且可容納多個設備,所以在智能家居控制中佔有很大的優點。前端

同時,隨着人工智能、語音識別、天然語義理解的發展,語音控制智能家居將成爲一種趨勢,這裏會以window java應用程序爲例,講解如何經過語音識別控制智能家居,並輸出ZigBee3.0協議,也很方便和ZigBee協調器進行對接,實現語音直接控制硬件。java

下面詳細介紹程序的功能和代碼實現,但願語音、語義理解從此能普遍的應用在家居等控制領域。git

代碼下載

語音和天然語言控制智能家居輸出Zibee3.0協議實例源碼程序員

注:下載代碼後請仔細閱讀說明文檔。web

APP 測試請查看第3節。windows

功能分析

APP 工做流程

APP的工做流程以下圖所示,圖中虛線框部分均由OLAMI開發平臺提供,後面會具體介紹OLAMI開發平臺的使用方法。api

其他部分由APP來完成數組

enter image description here

語音輸入安全

OLAMI的語音識別支持兩種格式:

WAV 格式的 PCM 錄音數據,單聲道(mono)、16K 採樣率(16 KHz Sample Rate)、16 bits 位深(Bit
Resolution)。

Speex 音頻壓縮,節省數據傳輸量,壓縮參數:Wideband 模式、Quality(壓縮比)= 十、單聲道(mono)、16K
採樣率(16 KHz Sample Rate)。

首先要確保硬件設備沒有問題,能夠進行正常的語音錄入。在電腦上安裝好麥克風以後,在「開始菜單」中輸入「錄音機」。

enter image description here

而後在彈出的錄音機中點擊「開始錄音」,使用話筒錄音後點擊「中止錄音」後會彈出保存錄音結果的對話框,保存,聽聽聲音正常便可。固然,也可使用QQ等第三方測試麥克風的軟件。

enter image description here

肯定硬件設備無誤以後,只要經過javax.sound.sampled.TargetDataLine調用windows錄音功能,錄下符合OLAMI語音識別接口的聲音數據便可,個人錄音方式是一邊錄音,同時將原始數據經過speex壓縮的方式post給 OLAMI 語音識別的API接口。不是保存爲wav文件以後再上傳,這樣可以提升語音識別的效率。

文字輸入

文字輸入即直接文本輸入,好比「打開空調」,「把彩燈調成紅色」。

處理NLI輸出

即根據OLAMI NLI的語義輸出結果決定如何操做設備,好比當輸入爲「打開燈」時,咱們能夠收到以下JSON數據:

{
        "data": {
            "asr": {
                "result": "打開燈",
                "speech_status": 0,
                "final": true,
                "status": 0
            },
            "seg": "打開 燈 ",
            "nli": [
                {
                    "desc_obj": {
                        "status": 0
                    },
                    "semantic": [
                        {
                            "app": "smarthome",
                            "input": "打開燈",
                            "slots": [
                                {
                                    "modifier": [
                                        "open"
                                    ],
                                    "name": "control_obj",
                                    "value": "燈"
                                }
                            ],
                            "modifier": [],
                            "customer": "593664ad84ae0a0a3feec056"
                        }
                    ],
                    "type": "smarthome"
                }
            ]
        },
        "status": "ok"
    }

slots中的「control_obj」即要操做的設備,上面的結果能夠看到須要操做的設備是"燈",動做爲"打開"。應用程序根據這兩個信息就能夠在本身的設備中尋找「燈」這個設備,併發出「打開」命令。

輸出ZigBee 3.0 協議

根據NLI的輸出咱們能夠斷定要控制的設備是燈,而燈的cluster咱們選擇了ZCL_CLUSTER_ID_GEN_ON_OFF, 根據這個cluster以及等的device ID等輸出命令便可。

鏈接硬件

這裏沒有提供驅動硬件的代碼,但基本流程就是,將ZigBee協調器的開發版經過串口和電腦相連,軟件發出的命令經串口發送給協調器,再由協調器控制ZigBee協議便可。

APP功能

enter image description here

文字輸入

經過設備選擇能夠切換不一樣的例句。同時,能夠在例句的框裏輸入其餘控制語句,按回車能夠重複輸入。好比:「請幫我打開燈」,「燈給我打開」,「開一下空調」,「空調的溫度提升一點」

enter image description here

語音輸入

點擊」開始錄音」,若是沒有點擊「中止錄音」,3秒以後會自動中止錄音。若是在這以前點擊了「中止錄音」,那麼會及時中止錄音,並進行語音識別。

識別後的文字會顯示在按鈕的上方,以下圖所示:

enter image description here

設備模擬

如上圖所示,應用程序中會模擬彩燈的顏色和空調的溫度、模式、風力,其原理就是根據輸出的Zigbee3.0協議進行顯示。

命令輸出

即輸出ZigBee3.0的協議。下面列出例子中的幾種設備的協議信息。

功能:僅支持打開和關閉

Device Dype: 0x100

命令:

Cluster ID: 0x0300

Cluster ID 的TI定義:ZCL_CLUSTER_ID_GEN_ON_OFF

actionID Action_frame(1 bit ) 參數組 說明
0x00 0x01 Off,關閉
0x01 0x01 On,打開

彩燈

功能:打開,關閉,顏色調節(例子僅支持紅、橙、黃、綠、青、藍、紫),氛圍調節,色調調節。好比運動氛圍、浪漫氛圍、冷色調、暖色調等。

Device Dype:0x0102

命令:

Cluster ID: 0x0006

Cluster ID 的TI定義:ZCL_CLUSTER_ID_GEN_ON_OFF

actionID Action_frame(1 bit ) 參數組 說明
0x00 0x01 Off,關閉
0x01 0x01 On,打開

Cluster ID: 0x0300

Cluster ID 的TI定義:ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL

actionID Action_frame(1 bit ) 參數組 說明
0x08 0x01 Attr1,Attr2 (均爲int16,即兩個字節,數據格式編號爲0x29 ) 設置彩燈的顏色,即R,G,B值。

第一個參數的高八位表示R值。

第一個參數的低八位表示G值。

第二個參數的高八位表示B值。

第二個參數的低八位無心義。

電視

功能:打開,關閉,提升下降音量,換臺。

Device Dype:0x0006

命令:

Cluster ID: 0x0006

Cluster ID 的TI定義:ZCL_CLUSTER_ID_GEN_ON_OFF

actionID Action_frame(1 bit ) 參數組 說明
0x00 0x01 Off,關閉
0x01 0x01 On,打開
0x05 0x01 提升音量
0x06 0x01 下降音量

Cluster ID: 0x0008

Cluster ID 的TI定義:ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL

actionID Action_frame(1bit ) 參數組 說明
0x00 0x01 1個字節,uint8 切換頻道
0x01 0x01 切換下個頻道
0x02 0x01 切換上個頻道

空調

功能:

開關功能,即打開和關閉空調。

切換模式,順序爲「自動-製冷-除溼-送風-加熱」模式按順序循環切換,但不支持某個模式的設置。

風力切換,切換順序爲「自動-低速-中低速-中速-中高速-高速-超強」。

其中,製冷和制熱模式支持上述7種風力切換。

送風和自動模式沒有「超強」風力

除溼無風力調節。

注意,僅支持切換,無風力設置。

升高溫度,切換一次,溫度上升一度,基礎範圍是16-30.

下降溫度,每切換一次,溫度降低一度,基礎範圍是16-30

狀態查詢,開關、溫度、風力、模式查詢。

Device Dype:0x0102

命令:

Cluster ID: 0x0300

Cluster ID 的TI定義:ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL

actionID Action_frame(1bit ) 參數組 說明
0x00 0x01 切換開關
0x01 0x01 切換模式
0x02 0x01 切換風速
0x03 0x01 Setup Button
0x04 0x01 Setdown Button

窗簾

功能:

打開,關閉,中止運行,指定窗簾運行的位置。

Device Dype: 0x202

命令:

Cluster ID: 0x102

Cluster ID 的TI定義:ZCL_CLUSTER_ID_CLOSURES_WINDOW_COVERING

actionID Action_frame(1bit ) 參數組 說明
0x00 0x01 打開
0x01 0x01 關閉
0x02 0x01 窗簾電機中止移動,並返回當前位置的百分比
0x04 0x01 窗簾號房間號,2bytes 設置窗簾號,房間號.其中高8位是房間號,低8位是窗簾號
0x05 0x01 百分比 單位百分比

其他設備和傳感器的ZigBee 輸出協議再也不一 一列出,能夠直接在APP中測試。

APP測試

代碼下載解壓以後,能夠在根目錄找到 smarthome.jar,在windows7 環境下雙擊便可以運行。

應用程序支持的語料除了選項裏的,其餘的類似說法也支持。

APP源碼解析

OLAMI語法加載

由於APP調用了OLAMI的天然語言理解接口,因此首先是必須先寫語法,來匹配智能家居控制語句。好比:「打開燈」,「幫我打開空調」,必須在完成語法以後,才能從OLAMI的接口中獲取NLI結果。語法相關定義和寫法等請參考博客:告訴你如何使用OLAMI天然語言理解開放平臺API製做本身的智能對話助手

若是你但願修改語法,添加更多的句子支持,必須將語法文件導入到歐拉蜜NLI系統。

下載包解壓以後,根目錄找到smarthome.osl,這個就是智能家居支持的語法。而後註冊並登陸歐拉蜜官網,在本身的帳號下找到「應用管理」,並進入NLI系統。以下圖所示。

enter image description here

接着新增模塊,並將智能家居語法smarthome.osl導入,以下圖所示,點擊「新建」並輸入APP的名字「smarthome」,這個名字必須與smarthome.osl的名字相同,不然導入時會報錯。固然也能夠修改,但同時要修改smarthome.ols中APP name相關字段。

enter image description here

模塊建立以後,選擇「上傳OSL文件」,而後選擇smarthome.osl並確認便可。上傳成功以後會進入該模塊內部,而後在例句庫中能夠看到不少智能家居控制的句子,同時也能夠查看Grammar,Rule等。至此OLAMI語法加載完畢。

enter image description here

獲取應用程序的APP KEY和APP Secreat

若是但願獲取句子解析後的結果,必須在歐拉蜜平臺中建立本身的應用程序,名字任意,個人叫「smarthome」。

回到「應用管理」界面-----建立應用程序。

應用程序建立成功以後,還須要把剛纔建立的smarthome 語法模塊添加到應用程序中,一個應用程序能夠支持多個語法模塊。

enter image description here

點擊圖中的「測試」,輸入「打開燈」,就能夠看到JSON格式的語義輸出結果了:

enter image description here

語法模塊配置好以後,點擊應用程序的」查看Key」的按鈕,能夠看到平臺分配的APP Key和APP Secret.

源碼分析

源碼工程是demosourcecode.jar,解壓以後,添加入Eclispe工程,個人開發環境是JDK1.8.

Eclipse Version: Mars.2 Release (4.5.2).

注意:導入工程後,若是出現文字報錯,請將默認編碼修改成UTF-8,方法 Project->Properties->Resource

代碼結構:

enter image description here

替換KEY

在smarthome packge中的NLIProcess.java中,替換以前建立語法應用時的APP Key和APP Secreat:

// * Replace your APP KEY with this variable.
           private static String appKey = "*****your APP Key******";
            
    // * Replace your APP SECRET with this variable.
            private static String appSecret = "****your APP Secret*****";

程序入口

程序入口爲smarthome packge下的window.java,能夠安裝windows Builder插件,直接操做界面。

smarthome packge:

smarthome包裏的源碼包括了APP應用的基本框架,其中:

window.java爲APP入口,即界面。

NLIProces.java表示處理來自OLAMI NLI接口的語義結果.

錄音處理爲:getSemanticBySpeech()

文字處理爲:getSemanticByText(String inputText)

windowVariable.java是window.java和NLIProces.java的數據傳遞媒介, window.java中會將
NLIProcess.java 須要的控件傳過去:

private void initialize() {
            nliwindowdata.setCmdTable(cmd_table);
            nliwindowdata.setcolortext(color_text);
            nliwindowdata.setAnswerText(answer_Text);
            nliwindowdata.setModetext(mode_text);
            nliwindowdata.setTempetext(tempe_text);
            nliwindowdata.setVoicetext(voice_text);
            nliwindowdata.setWindtext(wind_text);
            nliwindowdata.setisRed(isred);
            nliprocess.SetAnswerConfigCom(nliwindowdata);

smartHomeApp.java用來處理智能家居APP的語法解析和命令輸出。是NLIProces.java中其中一個小模塊。 你還能夠在NLI處理中添加其餘處理模塊,好比天氣查詢、詩歌背誦等等。目前NLIprocess.java中僅處理了smarthome相關的NLI輸出:

private void ProcessNLIResults(NLIResult[] nliResults) {
        // TODO Auto-generated method stub
        String  answer="對不起,你說的話我還不能理解";
        boolean isnormal=false;
        for(int i=0;i<nliResults.length;i++){
            NLIResult tempNlI=nliResults[i];
            //tempNlI.
            //voice_text
            if(tempNlI.getType()!=null&&tempNlI.getType().equals(nliDefinitions.smarthome_app)){

APPSlotEntry.java----處理NLI返回的JSON數據中slots相關信息

OutputMap.java------存放smartHomeApp.java返回給NLIProcess.java的輸出語句和命令。

Smarthome.definition packge

該包是智能家居處理中用到的定義和設備狀態解析。

Demo中模擬了燈,彩燈,電視,空調,傳感器等設備,初始化數據見smartHomeApp.java的InitDeviceData()。

全部設備信息經過ClientHomeAutomation.java解析並存儲。

//key is deviceID
        Map<String,HomeAutodeviceObjectNew> addedDeviceMapNew=new ConcurrentHashMap<String,HomeAutodeviceObjectNew>();

Smarthome.util

DataBuffer.java 和Microphone.java用來進行麥克風錄音;錄音格式按照歐拉蜜平臺的要求,參數爲16位深採樣率,16KHZ頻率,單聲道。

源碼爲

public Microphone() {
    
            this.sampleRate = 16000;
            this.bigEndian = false;
            this.signed = true;
    
            this.desiredFormat = new AudioFormat
                    (sampleRate, 16, 1, signed, bigEndian);
    
            //this.closeBetweenUtterances = closeBetweenUtterances;
            this.msecPerRead = 100;
            //this.keepDataReference = keepLastAudio;
            //this.stereoToMono = stereoToMono;
            //this.selectedChannel = selectedChannel;
            //this.selectedMixerIndex = selectedMixerIndex;
            this.audioBufferSize = 9600;
            
            recorderData = new DataBuffer();
        }

麥克風的錄音開始和中止經過線程監控完成。直到沒有聲音錄入時,錄音線程纔會觸發錄音中止機制,所以但願中止錄音時必須通Microphone.stopRecording()關閉錄音,程序才能中止錄音。

所以錄音時最好設置默認的錄音時長或者經過標誌來中止錄音,並調用Microphone.stopRecording(),我這裏的默認錄音時長爲3s.

代碼見NLIProcess.java的

//最多錄3秒數據,由於採樣頻率是16000點每秒,每一個點佔兩個字節。
        // readcount<=0表示錄音結束
         int num=0;
         int srcint=0;
        while(readcount > 0 ) 
        {           
            if(total_count >= 48000*2||needstop)
                break;
    
            num++;
            System.out.println("數據"+(num+1));
            total_count += readcount;
            System.out.println("單數"+readcount);
                 
            speechrecoginzer.appendAudioFramesData(databytes);
       
            readcount = mic.getData(databytes, 0, temsize);
        }
    
        mic.stopRecording();

WaveFileWriter.java能夠爲錄音數據添加wav頭。

和硬件設備對接

和硬件設備對接,須要串口或者USB等將輸出的ZigBee協議發給協調器,由協調器控制各智能設備作出反應。


實錄:《晶晶郭:用語音快速控制智能家居實戰解析》


彩蛋

重磅 Chat 分享:《一場 Chat 讓你搞清 BAT 程序員的技術職級》

分享人:
勝洪宇,一線互聯網公司前端技術組長,掘金簽約做者,前端博客博主,所講課程幫助超過20萬前端小夥伴學習。
Chat簡介:
不少程序員嚮往進入 BAT 這樣的大型互聯網公司,可是又不知道他們如何評定技術職級。

  • 阿里集團薪資職級如何劃分?讓你快速獲得馬雲的青睞。
  • 在百度明白這些,你將快速晉升。
  • 騰訊職級裏的小祕密,這樣工做你會更強。
    一場 Chat 讓你搞清 BAT 的技術評價體系,爲您進入超級互聯網公司指明技術方向,時刻作好準備!若是您但願您的技術團隊也像這些互聯網巨頭同樣強大,本場 Chat 我將幫您立刻模仿創建有效的技術職級體系。

想要免費參與本場 Chat ?很簡單,「GitChat技術雜談」公衆號後臺回覆「BAT」

這裏寫圖片描述

相關文章
相關標籤/搜索