天天看點

把arduino以簡單的方式接入Amazon Alexa實作語音控制

本文隻是提供一個簡單的思路,以一種比較簡單的方式把自己使用arduino制作的硬體連接配接到Amazon Alexa中,可以使用Amazon Echo等裝置控制它。

原文位址:http://blog.csdn.net/luhanglei/article/details/54289986

效果:http://weibo.com/tv/v/EpwDW1ktb?fid=1034:35b0913deed1b50f38fbad52f4c03382

大體的原理如圖所示

把arduino以簡單的方式接入Amazon Alexa實作語音控制

我選擇java做伺服器語言,完整開發需要了解并實作oauth的過程、servlet或jsp、socket通信

1.硬體環境:首先需要配置Amazon Echo,按照說明書配置好即可,不過多描述。

2.雲伺服器:準備好一個雲伺服器,必須要有一個固定的端口号給server socket(主要是讓arduino跟自己的伺服器同步資料用,如果有更好的解決方案,請忽視)。我采用的是bae和它的擴充服務中的port服務,因為用起來比較熟悉。如果會node.js或者python,也可以直接使用亞馬遜的AWS Lambda。

注意申請完port之後要把port和你的bae應用綁定起來,就是把port映射到你bae應用的某一個端口上。

3.亞馬遜的配置:注冊skill

到亞馬遜開發者網站的Alexa管理頁面,選擇Alexa Skills Kit,然後建立一個Skill

①選Custom Interaction Model,并填寫插件的名字。選智能家居後面的部分步驟會比選普通插件麻煩,如果想嘗試的朋友也可以嘗試直接使用智能家居的選項。

把arduino以簡單的方式接入Amazon Alexa實作語音控制
把arduino以簡單的方式接入Amazon Alexa實作語音控制
把arduino以簡單的方式接入Amazon Alexa實作語音控制

填好後選擇next

②填寫你要用到的密碼的相關資訊(JSON格式)

Intent Schema,可以了解為定義一下你指令中可能出現的一些東西,比如裝置、動作

以下是亞馬遜提供的Intent Schema的執行個體

{
  "intents": [
    {//以上為固定格式
      "intent": "GetHoroscope",//intent的名字,在下方指令定義中,針對這個intent的指令必須以引号中的字元開頭
      "slots": [
        {
          "name": "Sign",//slot的名字,比如你要操作好幾個裝置,這裡可以是裝置
          "type": "LIST_OF_SIGNS"//slot對應的type,在下方的輸入框中會進行定義,比如定義的type是機器,那麼type可以在下方的定義中可以包含燈、插座等
        },
        {
          "name": "Date",
          "type": "AMAZON.DATE"//亞馬遜也給出了一些預設的type,如果需要可以檢視,因為我控制的是淨化器,沒有用到
        }
      ]
    },
    {
      "intent": "GetLuckyNumbers"
    }
  ]
}           

假如我需要從空氣淨化器讀取我家裡的空氣品質,那我隻需要把Intent Schema定義成下面的樣子

{"intents":[{
    "intent":"air",//intent會被發送到自己的伺服器,告訴自己是要擷取空氣品質
    "slots":[{
      "name":"quality",//給關鍵詞定義名字為品質
      "type":"QUALITY"//slot的類型為QUALITY,至于關鍵詞到底有什麼,會在Slot type中定義    
}]
  }
]
}           

Slot Type

某個類别的關鍵詞定義在一起友善識别

比如:在machine中定義light和switch等詞語,這裡的詞語不再是一個類别的名稱,而是你指令中确切會出現的詞語。特别注意,最後亞馬遜發送給我們伺服器的消息隻包含了指令的intent的名字、slot的名字和type中具體的密碼詞,不會包含type的名字。

還是以擷取空氣品質為例:

要在QUALITY這個type中加入air quality、dust、PM2.5等詞語,關鍵詞之間換行分割即可。

Sample Utterances

這一步是要給出指令的範例,還是拿空氣品質舉例

air How is the {quality} in the house

其中air是intent的名字,空格後是指令,{quality}是一個通配符,是slot的名字,Alexa會把它比對到上一步定義的air quality、dust、PM2.5等詞語中。

③把自己的伺服器關聯到Alexa,讓Alexa知道把消息傳遞到哪。

把arduino以簡單的方式接入Amazon Alexa實作語音控制
把arduino以簡單的方式接入Amazon Alexa實作語音控制

圖檔上方要填寫的位址就是當Alexa收到我們的指令之後,把json post的目的位址。

下半部分為使用者綁定相關設定。因為牽扯到智能家居控制,是以最好選擇綁定賬戶,可以在我們自己的伺服器上區分使用者是誰。

grant type選擇 implicit grant比較簡單,就是很常見的oauth的認證方式,隻不過這次我們的角色變成了token的頒發方,Alexa引導使用者來擷取token。當第一次打開插件的時候,Alexa APP會把使用者引向我們填寫的Authorization URL,由我們進行認證,在認證完成後,按照要求重定向到圖中所示的Redirect url中,完成賬戶的綁定。

認證完成後,我們讓使用者重定向的位址類似于:

https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=AAAAAAAAAAAAAA#state=xyz&access_token=2YotnFZFEjr1zCsicMWpAA&token_type=Bearer           

其中#之前的是亞馬遜給我們的重定向位址,後面的參數需要我們添加上。 state 是在亞馬遜請求Authorization URL的時候,會帶過來的一個參數,此處需要傳回去。 access_token 就是我們給予使用者的令牌。 token_type是固定值,Bearer 。

此外網頁中其他的資料分别是:client-id,輸入的數值會在亞馬遜請求的時候發送給我們用于識别。scope是Alexa需要請求的權限,也是我們自己定義的,我瞎填的。

④SSL Certificate

這一步是亞馬遜要求我們的伺服器必須是有效的sll證書的。因為我是用的是bae,是以直接選My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority即可,bae是支援https的,應該所有的二級域名都有證書。

⑤測試

前面都按步驟設定好的話,就可以打開測試了。打開測試以後,可以在網頁下方的Service Simulator輸入文字指令檢視自己伺服器的傳回結果是不是正确。也可以在Alexa APP中的skill中的your skills中看到自己的skill了!

到這裡,亞馬遜的配置就完成了。

ARDUINO連接配接到伺服器

我用的是esp-13的wifi闆,使用arduino uno的軟序列槽連接配接。連接配接到伺服器的方式比較簡單,在esp-13的配置界面裡把模式改成client,然後把在bae申請到的port的ip和端口号填進去就行了。

【此處有坑】我申請的時候port的端口号總是在30000多,esp-13的送出總顯示非法數值。解決方法是:除了端口号之外,其他東西照常填,端口号瞎填一個30015以下的數字。送出。然後重新整理一下,把esp的配置界面儲存下來,用文本編輯軟體打開,把javascript中進行端口号合法性檢查函數的傳回值直接改為永遠是true。然後把post配置資訊的相對位址改成以ip開頭的絕對位址進行送出,就可以正常使用了。

arduino和伺服器之間就可以通過socket進行資料交換了。

伺服器的幾個接口

1.oauth授權的頁面,alexa的app打開這個頁面,确定使用者身份後按規定跳轉回指定的redirect url。

2.Alexa發來的資訊互動

發來的資訊的樣式可以在test中看到

回複的格式為:

{
  "version": "1.0",
  "response": {
    "outputSpeech": {"type":"PlainText","text":"Text to speak back to the user."},//text中是語音回複的内容
    "card": {//顯示在Alexa APP中的内容
      "type": "Simple",
      "title": "Example of the Card Title",
      "content": "Example of card content. This card has just plain text content.\nThe content is formatted with line breaks to improve readability."
    }
  }
}           

3.一個server socket,跟arduino通信

大體過程就是這樣,如果有什麼需要補充的歡迎在評論中提出,如有錯誤歡迎批評指正。

繼續閱讀