はじめに
こんにちは。TIG/DXユニット所属の宮永です。
本記事はPython連載第3回目の投稿です。よろしくお願いします。
突然ですが、私は以前以下2つの記事をこの技術ブログに投稿しました。
上記の記事ではAWS IoTと温湿度センサーを使用して「温湿度マイスターbot」を作成する内容を紹介しています。
記事では温度と湿度、不快指数を定期投稿するbotの作成を目指してハンズオンを進める構成となっています。
MQTTを使用して、室内温度を定点観測するだけならば以上の記事で十分ですが、ここまで作成してふと思いました。
「室内温度を知りたいのに2時間も待てない」
上記の記事では、定期的にworkerを実行する構成としたため、能動的に温度や湿度を知ることができないのです。
ということで、本記事ではAlexaとMQTT、そしてPythonを使って以上の悩みを解決する記事を書きました。前記事に続いてハンズオン形式で記載したので手元にRaspberrypiを添えながら読み進めてほしいです。
また、本章で使用するスクリプトは以下で公開しています。参考にしてください。
本記事で作成するもの
本記事と以下2つの記事
に取り組むことで以下の動画のようにリアルタイムで室内の不快指数を知ることができるようになります。
システム構成
で作成したシステム構成に修正を加えます。
RaspberrypiでAWS IoTをSubscribeしておきます。(PublishとSubscribeについては前回記事に記載しているのでご参照ください)
AWS IoTからMQTTでコマンドを送信し、Subscriberではコマンド受信をトリガーとしてローカルのワーカーを起動するという構成になっています。AWS IoTのPublishのタイミングはAlexa Home Skillをトリガーとしています。
開発環境
開発はWindows10環境、WSL2上で行いました。標準モジュール以外で使用したものを以下に列挙します。(※前回記事との差分です)
ハードウェア
- Amazon Echo Dot第3世代
ソフトウェア
- Python 3.8.10
- thorsten-gehrig/alexa-remote-control: control Amazon Alexa from command Line (set volume, select station from tunein or pandora)
- Alexa Smart Home Skill
- AWS Lambda
実装
以下の手順で実装します。
- PythonでSubscribe、AWS IoTからPublishする
- AWS LambdaからAWS IoT経由でPublishする
- Alexa Home Skillでスキルを作成する
- Alexa Home SkillとAWS Lambda、 AWS IoTを連携する
- Alexa Home Skillを開発する
- Alexaアプリと連携する
- ローカルのスクリプトを実行し、Alexaをしゃべらせる
まずは、PythonのMQTTモジュールであるeclipse/paho.mqtt.python: paho.mqtt.pythonに触ってAWS IoTからのテスト送信をSubscribeしましょう。
1. PythonでSubscribe、AWS IoTからPublishする
PythonでAWS IoTをSubscribeします。使用するPythonモジュールはeclipse/paho.mqtt.python: paho.mqtt.pythonです。
モジュールの使い方はREADMEに記載されています。Getting Startedをコピー&ペーストしたものが以下のスクリプトです。
import paho.mqtt.client |
適切にSubscribeできているのかAWS IoTのMQTT test clientで確かめます。
上記Pythonスクリプトを実行した状態でAWS IoTコンソールから「トピックをサブスクライブする」でtopic/to/subscribe
をサブスクライブした後に「トピックを公開する」でメッセージペイロードを発行してください。下図の様に「”AWS IoTコンソールからの挨拶”」を受信できていれば成功です。
2. AWS LambdaからAWS IoT経由でPublishする
次に、AWS LambdaからAWS IoT経由でメッセージをPublishしましょう。
ここで1点注意点があります。AWS Lambdaのリージョンは「オレゴン」としてください。これは後の工程でAlexa Home Skillと連携するためです。AWS IoTのリージョンは「東京」のままで大丈夫です。
大事なことなのでもう一度言います。
「AWS Lambdaのリージョンは「オレゴン」としてください」
まずはLambdaに設定するIAMロールを作成します。
コンソールからポリシーを新規作成してください。
ポリシーの作成
JSON タブを選択して以下を入力してください。
{ |
上記の設定でAWS IoTでのPublishの権限のみが付与されます。適当なポリシー名を設定しましょう。タグは選択しなくて問題ありません。
次に上記で作成したポリシーを付与するIAMロールを作成します。ユースケースは「Lambda」を選択してください。「権限の設定」ページで作成したポリシーを検索、付与します。ここでもタグの設定ページがありますが、入力はしなくても問題ありません。
以上の設定を行うことでAWS Lambda作成時に「既存のロール」から作成したロールを付与することが可能となります。(今回は「my」という名前のロールを作成しています。)
AWS Lambdaの作成
以下の様スクリプトをlambda_function.pyに張り付けてください。Lambdaのリージョンが「オレゴン」iot = boto3.client('iot-data','ap-northeast-1')
の設定に東京(‘ap-northeast-1’)が選択されていることに注意してください。AWS IoTが「オレゴン」で設定されている場合は’ap-northeast-1’は不要です。
# coding: utf-8 |
上記スクリプトを実行して下図の様に「AWS Lambdaからの挨拶」が表示されていれば成功です。
次の章でAlexa Home Skillを作成します。
3. Alexa Home Skillでスキルを作成する
Alexa Home Skillを作成する前にAmazon Developerアカウントを作成します。Amazon DeveloperアカウントやAlexa Developerコンソールを使用した経験がある方も本章の内容確認は必ず行ってください。特に、amazon.comでの購入経験がある方は要注意です。ここで手順を誤ってしまうと無限に時間を溶かします。
(私は溶かしました)。
泥沼の中から私を救ってくれた記事はこちらです。
結論から申し上げると、amazon.comのアカウントをお持ちの方(過去にamazon.comでの購入経験がある方)はパスワードをamazon.jpとは異なるパスワードで設定してください。
その上で、Amazon開発者ポータルから普段amazon.jpで使用しているアカウントでログインしてください。(正確には使用するAmazon Echo Dotに紐づいているアカウントです。)
それでは、スキルを作成します。Alexa>スキル開発>開発者コンソールよりスキル作成画面に遷移してください。Amazon Alexa Console - Amazon Alexa Official Site
本記事では、alexa-dht22
というスキルを作成しました。
スキル作成画面では以下の項目を選択してください。「スマートホーム」「ユーザー定義のプロビジョニング」です。
スキルの作成は以上で完了です。次にAlexa Home SkillとAWS Lambdaの連携を行います。
4. Alexa Home SkillとAWS Lambda、 AWS IoTを連携する
本章で説明する内容は以下のWikiに記載されています。不明瞭なことがある場合は参照してください。
まずはセキュリティプロファイルを作成します。Amazon開発者ポータル>Login with Amazonでセキュリティプロファイルを新規作成してください。
今回はalexa-dht22
という名称で作成しています。
作成が完了するとクライアントIDとクライアントシークレットの2つが発行されます。
この2つは後程使用するので、手元にメモしておきましょう。
ここで一度Alexa Developerコンソールに戻って設定を行います。
以下、Wikiに記載されている手順です。
- Lambda ARN default = enter your Lambda ARN noted from the previous step
- Authorization URI = https://www.amazon.com/ap/oa
- Client ID = your client ID from LWA noted in a previous step
- Scope: profile (click Add Scope first to add)
- Access Token URI: https://api.amazon.com/auth/o2/token
- Client Secret: your client secret from LWA noted in a previous step
- Client Authentication Scheme: HTTP Basic (Recommended)
- Click Save
作成したスキルを選択後「スマートホーム」という画面でLambad関数のArnを設定します。
次に以下の項目を設定してください。項目 | 設定内容 |
---|---|
Web認証画面のURI | https://www.amazon.com/ap/oa |
アクセストークンのURI | https://api.amazon.com/auth/o2/token |
ユーザーのクライアントID | セキュリティプロファイル作成時に発行されたID |
ユーザーのシークレット | セキュリティプロファイル作成時に発行されたシークレット |
ユーザーの認可スキーム | HTTP Basic認証 |
スコープ | profile |
Alexaのリダイレクト先のURLには3つのURLが記載されていると思います。
こちらは後の工程で使用するため、手元にメモしておきます(保存後に確認することもできます)。
次にAmazon開発者ポータルにて先ほどの3つのURLを設定します。
「許可された返信URL」に先ほどメモしたURLを1つずつ登録します。
次が最後の設定項目です。Alexa Developerコンソールのスマートホーム画面にてスキルIDをコピーしてください。こちらをAWS Lambdaのトリガーに設定することで連携の完了です。
先ほど作成したLambad関数でトリガーを設定します。
「アプリケーションID」の部分に先ほどメモした「スキルID」を設定すれば完了です。5. Alexa Home Skillを開発する
スクラッチで開発するのは大変ですので、こちらのリポジトリを転用します。
実装はこちらの公式サイトを参考にさせていただきました。
今回は”Smart Switch”を使用します。
編集するのはlambda.pyのみです。
上記のリポジトリを編集したコードを
で公開しているので参考にしてください。
サンプルコードのSAMPLE_APPLIANCESを以下に置き換えてください。
SAMPLE_APPLIANCES = [ |
サンプルコードでは「スマートスイッチ」「スマート温度計」「スマート鍵」など各種機能があらかじめ設定されているため、残していると今回作成したスキルを見失ってしまいます。消してしまいましょう。
ここでmodelName
にはSmart Switch
を指定します。Smart Switch
はサンプルコードでロジックに組み込まれた文字列であるため、変更はしないでください。friendlyName
やfriendlyDescription
はAlexaアプリ上での表示名です。自由に変更して構いません。
また、アプリ上での画面は温度計の表示したいため、get_display_categories_from_v2_appliance(appliance)
に変更を加えました。
UIを温度計にする場合はdisplayCategories
をTHERMOSTAT
を指定してください。
def get_display_categories_from_v2_appliance(appliance): |
最後にRaspberryPiに向けてMQTTでPublishを行うために以下の関数を追加します。
import boto3 |
send_command()
の実行はdef handle_non_discovery_v3(request)
の末尾に仕込みます。もし、ON
とOFF
で操作を変えたい場合は関数内のif文にロジックを記載してください。今回はトリガーとしてのみAlexaを使用するため、関数末尾に記載しています。
ここまで変更ができたら関数をデプロイしましょう。
サンプルコードのPythonディレクトリをzip化してAWS Lambdaにアップロードしてください。この時handler関数の設定はlambda.lambda_handler
としてください。
6. Alexaアプリと連携する
Alexaアプリを起動し、「デバイス>スマートホームスキル」と進むと先ほど作成したスキルが表示されます。スキルを有効化し、デバイスの探索を行ってください。Lambad関数が正しく記述できている場合はデバイスの探索が無事完了し、「温湿度マイスター」が登録されているはずです。
それでは最後にAlexaアプリ上で「その他>定型アクション」より、「アレクサ、不快指数は?」という呼びかけをトリガーとして「温湿度マイスターを起動する」アクションを作成します。
続く章ではローカルで実行するワーカーの実装を行います。
7. ローカルのスクリプトを実行し、Alexaをしゃべらせる
本章のスクリプトは以下で公開していますので、参考にしてください。
orangekame3/py-subscriber
あと少しで完成です。ローカルのスクリプトを実行するためにAWS IoTをSubscribeします。
import paho.mqtt.client |
AWS LambdaからPublishされたメッセージを受信した際に
で作成した
「温湿度マイスターbot」のワーカーを起動しています。worker()の戻り値は温湿度情報の最新値および不快指数です。
workerはplot.pyにて以下の様に定義されています。
from slack_sdk.web import WebClient |
alexaの音声操作にはこちらのシェルスクリプトを使用しています。
使い方についてはこちらの日本語の記事で詳細に紹介されています。
リポジトリからローカルにクローンをし、アカウントのセットアップ後すぐに使うことができます。
例えば、
./alexa_remote_control.sh -e "speak:おはよう" |
などを実行することで自分のEcho端末を自由に喋らせることができます。
それではmain.py
を実行してAWS IoTをSubscribeしましょう。
Alexaに話しかける
それではAlexaに話しかけましょう。
「Alexa 、不快指数は?」
どうでしょうか、Alexaは不快指数を教えてくれたでしょうか。
温湿度センサーを用いたデータの取得、MQTTによるDynamoDBへのデータ連携、Alexaを使ったデバイス操作などを行ってきましたが、能動的に動作するプロダクトはこれまでとは違った喜びがありますね。
Alexa周りはまだまだ分からないことばかりですが、これを機に学習してみようと思います。