標籤:oid 控制 應用 gravity -o split 資料 csdn patch
前言
HomeKit是蘋果發布的智能家居平台。通過HomeKit組件,使用者可以通過iphone、iPad和ipod Touch來控制智能燈泡,風扇、空調等支援HomeKit的智能家居,尤其是可以通過Siri進行語音控制。
但是通過Siri進行語音控制有個很大的問題,就是Siri支援的語料無法進行自由的擴充,沒辦法添加更多的說法。而Olami SDK則可以通過OSL(OLAMI 文法描述語言 OLAMI Syntax Language,簡稱:OSL)自由的進行擴充,對智能對話的能力擴充變得非常容易通過。Olami的伺服器對輸入的語料進行語義的解析,獲得想要的控制結果。這樣就可以自己對語料和說法進行擴充,豐富了操作的功能。
準備工作
HomeKit關於智慧型裝置的一些基本概念和模擬器的安裝
由於市面上支援HomeKit的裝置不多也比較昂貴,蘋果貼心的提供了一個HomeKit模擬器來協助程式員進行HomeKit裝置的開發。這個Demo是類比一個智能空調,功能是通過語音控制空調的開關和調節溫度。
HomeKit模擬器預設不是安裝的,要去下載安裝
在Taget->Capabilities->HomeKit一項中可以下載,見
安裝好以後,就可以開啟使用了。見
在Homekit中有幾個概念,在這裡簡單的介紹一下APP裡用到的,網上有比較詳細的介紹,也可以參考我轉載的這篇博文:
http://blog.csdn.net/dfman1978/article/details/72179458
HomeKit允許使用者添加多個home,但是使用的時候只能有一個home,稱為primaryHome。每個Home可以有多個room.智慧型裝置稱為Accessory屬於home,但是每個Accessory可以配個一個room。如果沒有指定room,則預設分配給roomForEntireHome返回的預設room.每個Accessory可以有多個Service,每個Service可以有多個特性(HMCharacteristic)。有的特性是唯讀,例如空調當前的溫度;有的特性是可讀可寫的,例如空調的開關。APP就是通過控制這些特性的值來控制智慧型裝置的。
在程式中添加了一個Accessory,名稱起為空白調。然後給它添加了兩個Service:一個是Switch 開關,一個是Temperature 控制空調的溫度。通過APP,可是實現空調的開關和溫度的調節。
- Olami 智慧型裝置的文法規則的編寫和配置
使用者的說的話, APP怎麼知道說的是什麼意思,怎麼去理解呢?這就涉及到了OSL文法描述語言。想要使用Olami平台提供的語音和語義理解API,首先要根據OLAMI 文法描述語言(OLAMI Syntax Language,簡稱:OSL)的規則編寫一套文法。OSL的簡介如下網址有詳細的介紹https://cn.olami.ai/wiki/?mp=osl&content=osl1.html
通過Olami平台提供的NLI 自然語言語義互動系統,可以學習到如何為自己應用的業務編寫一套文法規則。
自然語言語義互動(Natural Language Interaction, 簡稱:NLI)管理系統是一套線上語義解析管理工具,NLI 系統採用 OLAMI 文法描述語言(OLAMI Syntax Language,簡稱:OSL)取代複雜的編碼編程,讓即便沒有軟體研發背景的使用者也能輕鬆快速的維護包含語義擴充及答案的智能對話流。
在如下網址可以瞭解到更加詳細的內容
https://cn.olami.ai/wiki/?mp=nli&content=nli1.html
方便的是Olami平台已經對很多領域方面的提供了一些寫好的文法規則,這些在Olami中稱為模組。其中關於智慧型裝置已經寫好,下面就一步一步配置一下。
首先要去Olami的平台註冊一下,註冊後進入到這個介面
點擊“建立應用”轉到下面這個頁面
填寫 應用程式名稱,應用描述,應用介紹以後,就可以建立了。回到上一個頁面,就可以看到建立的應用了。
點擊”進入NLI系統”就可以進入模組頁面
在官網已經內建了很多領域的grammar.在模組頁面大家點擊“匯入”按鈕,查看已有領域的模組
選擇一個要使用的,例如我要匯入”smarthome”這個模組,先選擇它,點擊“匯入” 按鈕
然後進入 smarthome模組,就可以看到例句了
但是這個時候還是不能使用,需要先進行發布。點擊頁面上方的”發布”按鈕,進入發佈頁面
點擊“發布”按鈕,發布成功
最後還要回到“我的應用程式”介面,點擊”配置NLI模組”按鈕,讓自己建立的應用和模組關聯起來
這樣smarthome的文法檔案就配置好了,就可以使用了。
代碼的實現
1.擷取home和Accessory的對象
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.accessories = [NSMutableArray array]; if (self.homeManager && self.homeManager.primaryHome) { for (HMAccessory *accessory in self.homeManager.primaryHome.accessories) { [self.accessories insertObject:accessory atIndex:0]; accessory.delegate = self; [self.tableView reloadData]; } } if (_currentHome) { _currentHomeLabel.text = [NSString stringWithFormat:@"當前Home:%@", _currentHome.name]; }}
在ViewWillAppear的時候來擷取當前Home的對象和名字,還有Accessory的對象,並儲存起來,用一個tableView來顯示是程式剛啟動的時候的介面,這個時候因為沒有添加Home,所以什麼都沒有
點擊“添加Home”按鈕彈出一個對話方塊,可以填入一個Home的名稱。對應的代碼
- (IBAction)addHomeBtnClicked:(id)sender
下一步就是添加Accessory,在代碼裡沒有做這一步。是通過iOS提供的“家庭”APP來添加智能空調的。
點擊“家庭”App,彈出頁面
點擊“開始使用”,彈出
點擊“添加配件”,App會自動搜尋剛才在模擬器添加的那個空調,按照提示一步一步添加,最後顯示空調的兩個Service:Switch和Temperature
在回到APP,這個時候APP,就會顯示出搜尋到的Accessory:空調
點擊“空調”,進入語音控制頁面
在這個頁面中,上面的TableView顯示了空調的一些屬性。
下面的TextView用來顯示ASR的一些結果
圓形按鈕用來錄音
2..去網址https://cn.olami.ai/wiki/?mp=sdk&content=sdk_and_sample.html下載Olami SDK.包括兩個檔案,其中的一個是Olami的靜態函數庫,一個是其標頭檔
第一步是初始化Olami的語音辨識對象,並設定代理
olamiRecognizer= [[OlamiRecognizer alloc] init];olamiRecognizer.delegate = self;
3.調用setAuthorization函數進行授權
[olamiRecognizer setAuthorization:@"d13bbcbef2a4460dbf19ced850eb5d83" api:@"asr" appSecret:@"3b08b349c0924a79869153bea334dd86" cusid:OLACUSID];
這個函數的參數的說明在OlamiRecognizer中有說明,也可以去線上API說明去查看
https://cn.olami.ai/wiki/?mp=sdk&content=sdk/ios/reference.html
參數就是剛才建立應用的時候獲得的。
4.設定語系
[olamiRecognizer setLocalization:LANGUAGE_SIMPLIFIED_CHINESE];
在進行錄音之前必須要先進行設定,否則會得不到結果。目前只支援簡體中文(LANGUAGE_SIMPLIFIED_CHINESE)
4.開始錄音
調用 start()介面開始進行錄音
[olamiRecognizer start];
5.得到錄音的文字和語義,並對其進行處理
通過調用stop()函數或者自動停止,都會獲得錄音的文字和對其進行的語義分析的結果
實現OlamiRecognizerDelegate onResult函數可以獲得結果,其結果以一個json字串的形式回調過來,對這個字串進行解析,就可以獲得想要的數字。例如對著話筒說”開啟空調”,得到的結果如下
{ "data": { "asr": { "result": "開啟空調", "speech_status": 0, "final": true, "status": 0 }, "nli": [ { "desc_obj": { "status": 0 }, "semantic": [ { "app": "smarthome", "input": "開啟空調", "slots": [ { "name": "device", "value": "空調" } ], "modifier": [ "open" ], "customer": "58df685e84ae11f0bb7b4893" } ], "type": "smarthome" } ] }, "status": "ok"}
這個是根據OSL文法描述語言定義的一套規則,返回的結果。這個結果的說明在 https://cn.olami.ai/wiki/?mp=api_nlu&content=api_nlu3.html 這個網址上有說明。
6.獲得所有Accessory的對象
for(HMService *service in _accessory.services) { [_serviceDic setObject:service forKey:service.name]; NSLog(@"service.name is %@",service.name); }
儲存在一個Dictionary中,服務的名稱是key,對象的指標是Value
7.onResult 函數的說明
在整個程式中,最主要的一個函數就是onResult函數,這個函數就是對傳過來的結果進行處理。在這個函數中,調用了三個函數,分別來處理josn格式中的三個比較重要的節點
- (void)processASR:(NSDictionary*)asrDic
這個用來處理ASR節點,獲得語音辨識的結果,如果沒有結果,則彈出一個對話方塊進行提示
- (void)processSemantic:(NSDictionary*)semanticDic
這個用來處理Semantic節點,這個節點中包含了slot的值和modifier的值。OSL 文法描述語言中的 slot 可理解為語義中的變數,用於傳遞、提取資訊,是代碼處理的資料的來源。對於本程式來說,就是進行控制空調的各種動作,例如開,關。還有就是調節的溫度值。關於slot的值可以參考 https://cn.olami.ai/wiki/?mp=osl&content=osl_slot.html,這裡有詳細說明
- (void)processModify:(NSString*) str
這個用來處理語音和語義的結果。這個函數主要是處理json字串中的modifier節點。modifier 文法描述規則是 OSL 文法描述語言中,除了 slot 以外的另一種內建的資訊傳遞機制,一般用來表示語義目的,也可以理解為對於語義的一種注釋方式,以便讓應用程式的開發人員得知 grammar 所代表的相應意圖。詳細說明參考
https://cn.olami.ai/wiki/?mp=osl&content=osl_regex.html#11,通過modifier,我們才能知道程式的意圖是什嗎?例如是想開啟、關閉空調。還是調節溫度
在代碼中我們處理了三個modifier:”open”、”close” 和”control_temperature”.然後根據slot的值進行進行進一步處理。
拿其中處理“關閉”空調的動作來做說明
if ([str isEqualToString:@"close"]){//關閉空調 HMService *tmpService = _serviceDic[@"Switch"]; HMCharacteristic *characteristic = tmpService.characteristics[1]; if ([characteristic.characteristicType isEqualToString:HMCharacteristicTypeTargetLockMechanismState] || [characteristic.characteristicType isEqualToString:HMCharacteristicTypePowerState] || [characteristic.characteristicType isEqualToString:HMCharacteristicTypeObstructionDetected]) { [characteristic writeValue:@NO completionHandler:^(NSError *error){ if(error == nil) { dispatch_async(dispatch_get_main_queue(), ^ { _asrTextView.text = @"空調已關閉"; }); } else { NSLog(@"error in writing characterstic: %@", error); _asrTextView.text = @"空調關閉失敗,請重試!"; } }]; } }
如果modifier等於”close”,那麼說明這是一個Switch服務的屬性。通過“Switch”獲得Service的指標,然後獲得Switch的屬性。然後通過
- (void)writeValue:(nullable id)value completionHandler:(void (^)(NSError * __nullable error))completion;
函數來修改這個屬性的值。因為是關閉空調,所以直接寫入@NO就可以了
因為這個函數是非同步返回的,返回的時候不一定操作成功,所以要對返回結果進行一下處理。
代碼下載
代碼可以到GitHub上下載
https://github.com/lym-ay/SmartHome
使用Olami SDK 語音控制一個支援HomeKit的智能家居的iOS程式