2
2

More than 1 year has passed since last update.

ESP32をAlexaでLチカする(1):これから作るものと環境セットアップ

Last updated at Posted at 2021-12-15

ESP32をAlexaでLチカします。
ESP32をAlexaのスマートホーム化することで、声で操作もできますし、AndroidやiPhoneアプリにインストールしたAlexaアプリでも、ESP32や周辺デバイスを操作したり状態を確認することができるようになります。

以下のことができるようにします。
・ESP32に接続したENVユニットで、温度を取得して表示します。
・ESP32に搭載されている加速度センサを取得して表示します。
・ESP32に接続したガスセンサユニットで、二酸化炭素濃度を取得して表示します。
・ESP32に接続したRGB LEDユニットをカラー照明として操作します。
・ESP32に接続したサーボハットを回転操作します。
・ESP32に搭載されているLEDをスイッチとして操作します。
・ESP32のサイドボタンの押下状態を取得して表示します。
・ESP32のメインボタンをドアベルとして押下したことをAlexaに通知してもらいます。

何を言っているかわかりにくいかもしれませんが、あとで示すAlexaアプリの画面を見るとわかるかと思います。

全体構成は以下のようになっています。

image.png

いくつか補足します。
・Alexaスマートホーム化するには、Alexaサーバと連携するためにAWS Lambdaにロジックを実装する必要があります。ですが、そこでデバッグするのは面倒なので、イントラネットに立ち上げたNode.jsサーバに転送して処理しています。
・Alexaスマートホーム化するには、OpenID Connectによるユーザ認証が必要です。自分でサーバを立ち上げたりAWS Cognitoを使うのでもよいですが、今回はLINEサーバを使わせていただきました。
・ESP32のLチカは、ESP32とMQTTを介して連携します。(ESP32をWebAPIサーバにもできたのですが、使っているとリブートが発生したりと不安定だったので止めました。)
・Node.jsサーバとMQTTの間に中継サーバを立てて、REST API呼び出しとMQTT Publish/Subscribeを中継するようにしました。それにより、Node.jsサーバはREST API呼び出しでよくてMQTTを意識する必要がなくなるのと、中継サーバは汎用的なので他用途でも使えます。

ただし、大事なのはalexa→AWS Lambda→Node.jsサーバ の部分なので、以降ではこの部分を説明します。特に、Node.jsの部分が大事です。

ソースコードもろもろはGitHubに上げておきました。

poruruba/AlexaSmartHome_Test

第二回の投稿はこちら
 ・ESP32をAlexaでLチカする(2):Alexa Smart Homeを実装する

ESP32の接続構成

今回はESP32として、M5StickCを使います。
さらに、スマートホームっぽくするため、いくつかM5ユニットを追加しています。

image.png

M5StickCに搭載されているデバイスと、Grove端子にI2Cハブを介して3つのI2Cデバイスを接続しています。また、GPIO端子にも(排他ですが)2つのデバイス接続を試します。

いい機会なので、各デバイスのスペックをまとめておきます。

・M5StickC
https://www.switch-science.com/catalog/6350/

・ボタンA(メインボタン)
GPIO37

・ボタンB(サイドボタン)
GPIO39

・Wire
SDA:GPIO32、SCL:GPIO33

・Wire1
SDA:GPIO21、SCL:GPIO22

・LED
GPIO10

・加速度センサ
I2C
MPU6886 アドレス:0x68
接続先:Wire1

・Ledc(PWM)
GPIO26
※Servo Hat接続時

・環境センサユニット
https://www.switch-science.com/catalog/5690/
I2C
DHT12(温湿度) アドレス:0x5C
BMP280(気圧) アドレス:0x76
接続先:Wire

・ガスセンサユニット
https://www.switch-science.com/catalog/6619/
I2C
SGP30 アドレス:0x58
接続先:Wire

・Digital Ligth Sensor
https://www.switch-science.com/catalog/1174/
I2C
TSL2561 アドレス:0x29
接続先:Wire

・Servo Hat
https://www.switch-science.com/catalog/6076/
ES9251II
GPIO26にPWMで接続
※RGB LEDユニットと排他

・RGB LEDユニット
https://www.switch-science.com/catalog/6550/
SK6812
GPIO026にGPIOで接続
※Servo Hatと排他

Alexaアプリでの見え方

構築完了後は、Alexaアプリで以下のように見えるようになります。そう、これが目標です。

ボタンBの押下状態。サイドボタンを押していると、表示がオフに切り替わります。
image.png

ボタンA押下時に反応するドアベル。この画面はあじけないですが、「ドアベル押下をアナウンス」をOnにしてからボタンAを押すと、Echo等のスマートスピーカが「ドアベルのところに誰かいます」としゃべります!
image.png

Digital Ligth Sensorで輝度表示。周りの明るさのレベルに応じて明るさのパーセント表示が変わります。
image.png

環境センサユニットで温度表示
image.png

LEDの点灯状態。M5StickCのLEDを点灯・消灯できます。
image.png

加速度センサとガスセンサの二酸化炭素濃度の表示。M5StickCを傾けると加速度の数値が変わります。
image.png

RGB LEDユニットでカラー照明。RGB LEDの色変えることができます。
image.png

Servo Hatで回転角度を操作。ゲージを操作すると、M5StickCに接続したサーボが回転します。
image.png

スマートホームスキルを登録

それでは、まずはスマートホームスキルの準備から始めます。
Alexa developer Consoleにスマートホームスキルを登録します。

Alexa developer Console

image.png

「スキルの作成」ボタンを押下します。

image.png

スキルに追加するモデルは「スマートホーム」を選択し、スキルのバックエンドリソースをホスティングする方法は、ユーザ定義のプロビジョニングのみ選択できます。

次の画面で連携するAWS Lambdaの設定をします。

image.png

ちょっとここで、ブラウザの別タブを開いて、Lambdaの設定をします。スキルIDはLambda設定で使うので覚えておきます。

AWSのLambdaの画面において、右上のリージョンを「オレゴン」にします。

image.png

「関数の作成」ボタンを押下して、関数を追加します。

image.png

転送しかしないので、ランタイムは何でもよく、Node.js 14.xを選択しました。
それでは、ロジックを実装していきます。実装は以下のみです。転送しかしていないので。。。

AlexaSmartHome_Test\Node.js\AlexaSmartHome\api\controllers\alexahome_forwarder\index.js
'use strict';

const { URL, URLSearchParams } = require('url');
const fetch = require('node-fetch');
const Headers = fetch.Headers;

exports.handler = async (event, context, callback) =>{
    console.log(JSON.stringify(event));
    console.log(context);

    var response = await do_post(process.env.FORWARD_URL, {
        event: event,
        context: context
    });
    console.log(JSON.stringify(response.body));
    callback(null, response.body);
}

function do_post(url, body) {
  const headers = new Headers({ "Content-Type": "application/json" });

  return fetch(url, {
      method: 'POST',
      body: JSON.stringify(body),
      headers: headers
    })
    .then((response) => {
      if (!response.ok)
        throw 'status is not 200';
      return response.json();
    });
}

ただし、npmモジュール「node-fetch」を使っていますので、以下の通りにZIP化してアップロードします。

# mkdir alexahome_forwarder
# cd alexahome_forwarder
# npm init -y
# vi index.js
# zip index.zip .

出来上がったZIPファイルをAWS Lambdaにアップロードします。

image.png

環境変数に以下を指定します。

 キー名:FORWARD_URL
 値:https://【転送先のドメイン名】/alexahome-forward

image.png

次に、トリガを追加から、Alexa Smart Homeを選択し、先ほど覚えたスキルIDをアプリケーションIDのところに指定します。

image.png

これで完成ですが、Alexa側にも設定が必要で、AWS Lambdaの関数のARNをメモっておきます。もう一度以下の画面に戻って、極東のチェックをオンにして、デフォルトのエンドポイントと極東のエンドポイントに、AWS Lambdaの関数のARNを指定して、保存ボタンを押下します。

image.png

次に、アカウントリンクを選択します。
このうち、Alexaのリダイレクト先のURLが3つほど表示されています。認証サーバとして利用するLINEサーバに設定が必要なので、メモっておきます。

 https://pitangui.amazon.com/api/skill/link/XXXXXXXXXXXXXX
 https://alexa.amazon.co.jp/api/skill/link/XXXXXXXXXXXXXX
 https://layla.amazon.com/api/skill/link/XXXXXXXXXXXXXX

image.png

LINEにOpenID Connect設定

ブラウザから、LINEデベロッパーコンソールを開きます。

LINEデベロッパーコンソール

image.png

プロバイダを選択します。プロバイダを作成していなければ作成します。
以下のプロバイダの設定画面で、新規チャネルを作成します。

image.png

作成するのは、LINEログインです。すでに作成済みであれば、それでよいです。

image.png

登録されるといろいろ情報が表示されます。

image.png

使うのは、以下です。
・チャネルID
・チャネルシークレット

チャネル基本設定のタブにあります。
また、LINEログイン設定のタブにあるコールバックURLに、Alexa Developer ConsoleでメモったAlexaのリダイレクト先のURLを指定します。

image.png

Alexa develper consoleにLINEサーバを設定する

以下の画面に戻って入力します。

image.png

・Web認証画面のURL:https://access.line.me/oauth2/v2.1/authorize
・アクセストークンのURL:https://api.line.me/oauth2/v2.1/token
・ユーザーのクライアントID:LINEのチャネルID
・ユーザーのシークレット:チャネルシークレット
・ユーザーの認可スキーム:HTTP Basic認証
・スコープ:openid profile email(任意)

ドメインリストとデフォルトのアクセストークンの有効期限は空白でよいです。

次に、アクセス権限を選択し、Alexaイベントを送る、のスイッチをOnにします。
また、AlexaクライアントIDとAlexaクライアントシークレットは後で使うので覚えておきます。

image.png

一応これで、設定はできました。

ベータテスト公開設定

AlexaアプリやEchoなどの本物のデバイスで試行で試すには、まずベータテスト公開設定の状態にしておく必要があります。
公開タブを選択します。

image.png

いろいろ入力項目がありますが、ベータテストをするには、以下の項目を適当に埋めます。
・公開名
・説明
・詳細な説明
・サンプルフレーズ
・小さなスキルアイコン
・大きなスキルアイコン
・カテゴリ
・プライバシポリシURL
・プライバシとコンプライアンス
・テストの手順

最後に、検証タブにおいて、実行ボタンを押下して以下のように検証OKとなればよいです。

image.png

ベータテストは、公開タブの公開範囲にあるベータテストで設定します。

image.png

ベータテスタとして、テスト対象のAlexaアプリやEchoスマートスピーカの設定に使ったAmazonアカウントのメールアドレスを指定します。(これが違っていると、いつまでたっても、Alexaアプリから今回作成したスマートホームスキルが選択肢に出てきません)

Amazonアカウントのメールアドレスを追加すると、本人にメールが届きます。
メールが届いた後の操作は、Node.jsサーバのセットアップが終わった後にします。

ちなみに、ベータテストは、公開から3か月間有効のようです。
それ以上続けたい場合は、再度ベータテスト公開するか、製品化することになるかと思います。

MQTTブローカのセットアップ

以下を参考に立ち上げます。手抜きですみません。

AWS IoTにMosquittoをブリッジにしてつなぐ

M5StickCのセットアップ

Arduinoフォルダに一式あります。PlatformIOで作成していますので、Visual Studio Codeから書き込みます。

以下の部分を書き換えます。

mqttApi.cpp
・const char *MQTT_BROKER_URL = "【MQTTブローカのドメイン名】"; // MQTTブローカのドメイン名

main.cpp
・const char *wifi_ssid = "【WiFiアクセスポイントのSSID 】"; // WiFiアクセスポイントのSSID
・const char *wifi_password = "【WiFiアクセスポイントのパスワード】"; // WiFiアクセスポイントのパスワード

・const char *MQTT_PUBLISH_PUSH_TOPIC = "esp32_webapi_push"; // MQTTトピック名
・const char *MQTT_PUBLISH_PUSH_URL = "https://【中継サーバのドメイン名】/alexahome-push"; //中継サーバのURL(Push用)

Node.jsサーバのセットアップ

Node.jsフォルダに一式あります。
Node.jsサーバと中継サーバの両方を実装してあります。

# cd node.js/AlexaSmartHome
# npm install
# mkdir data
# mkdir data/alexa_smarthome/
# vi .env
# node app.js

.envファイルには以下を記載します。

AlexaSmartHome_Test\Node.js\AlexaSmartHome\.env
PORT=【HTTPポート番号】
MQTT_BROKER_URL=mqtt://【MQTTブローカのホスト名】:1883

HTTPではなくHTTPSの場合は、certフォルダを作成してHTTP証明書を配置し、.envファイルには以下を記載します。

AlexaSmartHome_Test\Node.js\AlexaSmartHome\.env
SPORT=【HTTPSポート番号】

エンドポイント・トピック名情報

Node.jsサーバのエンドポイント

/alexahome-forward:AWS Lambdaからの転送を受け取ります。
/alexahome-push:ESP32側からの通知を受け取ります。

中継サーバのエンドポイント
/mqttapi/*:Node.jsサーバからESP32を操作するためのリクエストを受け取ります。

MQTTトピック名
 mqttapi/XXX.XXX.XXX.XXX:中継サーバからのリクエストをESP32が受け付けます。XXXXはESP32のIPアドレスです。
 esp32_webapi_notify:ESP32へのリクエストに対する応答を受け取ります。
 esp32_webapi_push:ボタン押下など、ESP32で発生したリクエストを中継サーバが受け取ります。

次回

今回はここまで。
セットアップのところはかなり速足でしたが、大事な部分は次回のNode.jsサーバの実装部分です。その中のESP32との連携部分は環境に合わせて作り替えればよいので、今回のセットアップ部分はあまり気にしなくてもよいかな。

こちらもご参考まで
 スマートホームスキルを作る(2):いよいよスマートホームスキルを作成する

以上

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2