Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
16
Help us understand the problem. What is going on with this article?
@poruruba

ESP32をAlexa Gadgets Toolkitデバイスにしよう

Alaxaには、Alexa Gadgets Toolkit という、Echoデバイス(スマートスピーカ)と連携できるAlaxa Gadgetを作れるSDKがあります。

Alexa Gadgets Toolkit
 https://developer.amazon.com/ja-JP/docs/alexa/alexa-gadgets-toolkit/understand-alexa-gadgets-toolkit.html

Webでは、ラズパイを使った例が複数あったのですが、BLEのプロトコルも提示されているので、ESP32で実現しようと思います。

Alexa Gadgetsデバイスになれば、いろんなことができるのですが、まずは単純なところから。
今回は、「アレクサ、今何時?」といつもの問いかけをしている間、勝手にLEDが点灯するようなAlexa Gadgetsを作ってみたいと思います。
本来であれば、AlexaのスキルからAlexa Gadgetsデバイスに指示を出したり、Alexa Gadgetsからスキルにイベントを伝達できたりするのですが、それは次回で。

ESP32として、M5StickCを使いました。
開発環境は、PlatfomIOです。おそらくArduinoIDEでも大丈夫だと思います。

Alexa Gadgetsは、一般には以下のような流れです。

image.png

今回はこのうち以下の流れだけです。(これ以外は、次回の投稿にあります。)
Alexa Gadgets Toolkitに定義済みの、wakeword(アレクサ、という呼びかけ)をひっかけて、LED点灯するところまでです。

image.png

いつもの通り、Arduinoのコードは以下のGitHubに登録しておきました。

poruruba/AlexaGadget
 https://github.com/poruruba/AlexaGadget

※ソースコードの解説やカスタムスキル対応は次回の記事で。以下、続編
 ESP32をAlexa Gadgets Toolkitデバイスにしよう:ソースコード解説
 ESP32をAlexa Gadgets Toolkitデバイスにしよう:カスタムスキル→Alexa Gadgetデバイスへの通知
 ESP32をAlexa Gadgets Toolkitデバイスにしよう: Alexa Gadgetデバイス→カスタムスキルへの通知

Alexa Gadgetsデバイスの登録

まず最初に、Alexa Gadgetsデバイスの情報を登録して、IDを払い出します。
登録は、Alexa音声サービス開発者コンソールから行います。

Alexa音声サービス開発者コンソール
 https://developer.amazon.com/alexa/console/avs/home

image.png

製品 をクリックしたのち、「新しい商品を追加」をクリックします。

製品名等を登録します。何でも良いですが、とりあえず適当に以下で入力してみましょう。

・製品名:M5StickC
・製品ID:M5StickC
・製品タイプ:Alexaガジェット
・商品カテゴリ:コミュニケーションまたは通知の端末
・製品概要:テスト用
・この製品を商品として配信する予定ですか?:いいえ

登録が完了すると、「Amazon ID」と「Alexaガジェットのシークレット」が払い出されます。

ちょっと、フライングですが、以下にあるPythonコードを実行しておきます。

maketoken.py
import hashlib
def generate_token(device_id, device_token):
    hash_object = ( hashlib.sha256(bytes(device_id, 'utf-8') + bytes(device_token, 'utf-8')) )
    hex_dig = hash_object.hexdigest()
    return bytes(hex_dig, 'utf-8')

token = generate_token("【Amazon ID】", "【Alexaガジェットのシークレット】")
print(token)

【Amazon ID】と【Alexaガジェットのシークレット】のところを置き換えてください。

〉python maketoken.py
b’XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX’

ここで生成されたのがデバイストークンで、あとで使います。

これで、準備OKです。

プロトコルバッファのコンパイル

EchoデバイスとはBLEで通信するのですが、通信プロトコルは、proto3と呼ばれるProtocolBufferという形式でバイナリ化されて送信されてきます。
Echoデバイスと通信するパラメータは、このproto3の形式で定義されており、その定義ファイルをダウンロードします。

Alexa Gadgets Embedded Sample Code
 https://github.com/alexa/Alexa-Gadgets-Embedded-Sample-Code

proto3の形式で送られてくるバイナリをデコードしたり、バイナリにエンコードしたりするエンコーダを作成します。

以下の手順に従います。

まずnanopbダウンロードします。
 https://jpa.kapsi.fi/nanopb/download/

ここで注意が必要です。必ず、v0.3系を選んでください。v0.4系では動きません。私はこれではまりました。。。本日時点では、v0.3.9.6が最後でした。

nanopb-0.3.9.6-windows-x86.zip をダウンロードしておきます。
また生成するエンコーダはWindowsではなくESP32で動かすので、nanopb-0.3.9.6.tar.gz もダウンロードしておきます。

展開後、以下のフォルダに移動します。
C:\XXXX\Alexa-Gadgets-Embedded-Sample-Code-master\ConnectionHelpers\BLE\Handshake

compile_nanos.batを開き、以下の部分PROTO_COMPILE_PATHをnanopbのWindows版の実行ファイルのある場所に変更します。

set PROTO_COMPILE_PATH=C:\XXXX\nanopb-0.3.9.6-windows-x86\nanopb-0.3.9.6-windows-x86\generator-bin\

そして、そのバッチファイルがあるフォルダで、実行します。
そうすると、*.pb.c*.pb.hのファイルが出来上がっているはずです。

次に、こっちのフォルダに移動します。
C:\XXXX\Alexa-Gadgets-Embedded-Sample-Code-master\AlexaGadgetsProtobuf\examples

同様に、compile_nanos.bat の中のPROTO_COMPILE_PATHを修正します。
バッチファイルを実行する前に、するべきことがあります。
以下の4つのファイルの中で、namespaceという変数を定義しているところがあります。

・directiveHeader.options/.proto
・eventHeader.options/.proto

この部分をnamespaccに変更します。c言語としてコンパイルする分には問題ないのですが、C++としてコンパイルするときに予約語であるためエラーとなってしまうためです。回避方法がわからなかったため、暫定策として上記のように名前を変更しました。
バイナリ変換時には、変数名は関係ないので大丈夫です。

例:

変更前
    string namespace = 1;
変更後
    string namespacc = 1;

それでは、さきほどのバッチファイルがあるフォルダで実行します。そうすると、たくさんのファイルが出来上がります。
*.pb.c*.pb.hというのができているかと思います。

これで準備OKです。

PlatformIOのプロジェクト作成

とりあえず、プロジェクト名に「AlexaGadget」として、Boardに「M5Stick-C」、Frameworkに「Arduino」を選択し、プロジェクトを作成します。

あと、ROM書き込みやモニタしやすくするために、以下のようにポート番号を指定すると楽です。ポート番号は適宜変えてください。

platformio.ini
[env:m5stick-c]
platform = espressif32
board = m5stick-c
framework = arduino
upload_port = COM6
monitor_port = COM6

次に、先ほど作った2つのフォルダにあるファイル「*.pb.c/*.pb.h」をコピーしてきます。main.cppがある\srcフォルダが良いです。加えて、
C:\XXXX\Alexa-Gadgets-Embedded-Sample-Code-master\ConnectionHelpers\BLE\Handshakeにある、common.hもコピーしておきます。

次に、nanopb-0.3.9.6.tar.gz を展開して出てくる以下のファイルもコピーしてきます。

・pb.h
・pb_common.c/.h
・pb_decode.c/.h
・pb_encode.c/.h

あと、pb.hの以下の部分のコメントアウトを外してください。

pb.h
#define PB_FIELD_16BIT 1

最後に、main.cppを以下に置き換えます。

ソースが長くなってしまったので、GitHubを見てください。
 https://github.com/poruruba/AlexaGadget/blob/master/AlexaGadget/src/main.cpp

以下の部分は、これまで出てきたかと思いますので、それぞれに合わせて書き換えてください。
【AmazonID】
【Alexaガジェットのシークレット】
【製品ID】
【デバイストークン】

以下は、お使いになるESP32に合わせてください。
【ESP32のBLEのMacAddress】

以下の部分は補足します。

【ガジェットの識別子】
 以下に記載がありますが、endpointIdの部分です。とりあえず、” G090RD108032071X”とでもしておきましょうか。

以下の文字列は何でも良いです。
【ファームウェアバージョン】
【モデル名】

上記をPlatformIOでコンパイルし、ESP32に書き込みます。
リブートがかかると、シリアルに「setup」という文字が表示されれば起動が完了です。

動作確認

それでは、動かしてみましょう。
AndroidなどにAlexaアプリがインストールされている前提です。

起動後、左上のメニューボタンを押して、設定を選択します。

image.png

次に「デバイスの設定」を選択します。

image.png

そうすると、Echoデバイスが一覧で表示されているかと思いますので、つなげたいEchoデバイスを選択します。
それでは、Alexa Gadgetデバイスを登録しましょう。
それには、「AlexaGadgetをペアリング」を選択します。

image.png

そうすると、BLEスキャンが始まり、「M5StickC」というのが見つかるはずです。
それを選択します。

image.png

めでたく、登録が完了です。

image.png

Echoデバイスに問いかけてみる

おもむろに、Echoデバイスに、「アレクサ、今何時」と聞いてみましょう。
アレクサに話しかけている間、M5StickCのLEDが点灯しているのではないでしょうか。

終わりに

ここまで来るのに疲れました。。。。
Arduinoのコードの解説は次回の記事でしたいと思います。

以下、参考にさせていただきました。
 Alexaのカスタムスキルがガジェットと連携! 〜Alexa Gadgets Toolkit の Custom Interfaces を試す〜

以上

16
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
16
Help us understand the problem. What is going on with this article?