角度を変えるサーボモータにirMagician(赤外線モジュール)をつけ、それをラズパイに接続します。
で、Alexaから自宅のラズパイ上に用意したBottle(HTTPサーバ)にHTTPを飛ばし、それをトリガにirMagicianとサーボモータを動かすことで、自宅照明のON/OFFをAlexa経由でやっちゃおう、というのが今回の趣旨です。
なのでAlexaスキルを作ります。
過去に調べた感じでは、IFTTTのWebhookと連携させないと実現できないような記事ばっかりだったので、面倒だな…と思ってましたが、どうやらAlexaスキルはPython(lambda)で作れるらしいと知ったので、今回はそれでやっています。
今回は自作スキルをベータテスト扱いで使うことになるので、使用期限は3ヶ月です。
スキルは基本的に全ユーザに公開する形になるので、特定のユーザに提供したいといった場合は、ベータテストで提供するか、Alexa for Business?を利用しなければいけない模様。
3ヶ月後に何をすればまた有効化できるのか(スキルを作り直す必要があるのか)はまた確認します。
追記:スキルを作り直す必要はないようですが、ベータテスト設定を再度実施する必要があるようです。
irMagicianとサーボモータの操作については以下のとこらへんで書いているため、そちらを参考にどうぞ。
一応、一番最後にBottleで動くソースとサーボモータ+irMagicianのソースを書いときます。
engetu21.hatenablog.com
engetu21.hatenablog.com
自宅サーバへのHTTPの引き込みは、ルータでポートを開けるか、以下のSSHポートフォワーディングで実現する必要があります。
engetu21.hatenablog.com
2.ソースの変更
コードエディタタブを押下し、「lambda_function.py」のソースを変更します。

import requests
url = 'http://XXXXXXXXXXXXXX'
class LaunchRequestHandler(AbstractRequestHandler):
"""Handler for Skill Launch."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return ask_utils.is_request_type("LaunchRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# speak_output = "Welcome, you can say Hello or Help. Which would you like to try?"
response = requests.get(url)
return (
handler_input.response_builder
#.speak(speak_output)
.speak(response.text)
#.ask(speak_output)
.response
)・変更点
1.import requests を追加
2.url = ''でHTTPを飛ばしたいURLを変数に設定
3.speak_output変数の定義部分をコメントアウト
4.response = requests.get(url) を追加
5..speak(speak_output) をコメントアウト
6..speak(response.text) を追加
7..ask(speak_output) をコメントアウト
どうやら「.speak」に設定した文言をAlexaはしゃべってくれるようなので、
ここにHTTPレスポンスでもらったメッセージを指定することで、それをしゃべらせるようにします。
変更が完了したところで、右上の「デプロイ」を押下。
4.Bottleで動くHTTPサーバのソースとirMagician+サーボモータのソース
書いておかないと自分が困りそうな気がしてきたので記載しておきます。
以下、Bottleで動作するHTTPサーバのソース。
from bottle import route, run, template
import subprocess
@route('/youshitu_on')
def youshitu_on():
subprocess.call("/home/pi/kadensousa/shells/youshitu_light_on.sh", shell=True)
response = f'洋室の照明をつけました'
return response
@route('/youshitu_off')
def youshitu_off():
subprocess.call("/home/pi/kadensousa/shells/youshitu_light_off.sh", shell=True)
response = f'洋室の照明を消しました'
return response
@route('/washitu_on')
def washitu_on():
subprocess.call("/home/pi/kadensousa/shells/washitu_light_on.sh", shell=True)
response = f'和室の照明をつけました'
return response
@route('/washitu_off')
def washitu_off():
subprocess.call("/home/pi/kadensousa/shells/washitu_light_off.sh", shell=True)
response = f'和室の照明を消しました'
return response
run(host='0.0.0.0', port=50001)
上記で作ったPythonを自動起動させるために、以下のようにShellファイルを作成します。
$ vi /home/pi/site/start_syomei.sh
#!/bin/bash
nohup python3 /home/pi/site/syomei.py &
exit 0
systemdで動かす設定ファイルを作成します。
$ sudo vi /lib/systemd/system/start_syomei.service
[Unit]
Description=python program
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/home/pi/site/start_syomei.sh
Restart=no
User=pi
[Install]
WantedBy=multi-user.target
以下のコマンドで自動化。
$ sudo systemctl enable start_syomei.service
スタートは以下。
$ sudo systemctl enable start_syomei.service
以下はPythonで作ったHTTPサーバから呼び出されるShellの中身。
このプログラムでサーボモータが動き、赤外線が発信されます。
#!/bin/bash
echo 0=50 > /dev/servoblaster
python /home/pi/kadensousa/irmcli/irmcli.py -p -f /home/pi/kadensousa/irmcli/light_on.json
sleep 1
echo 0=70 > /dev/servoblaster
何でPythonとShellでごっちゃになってんの?って話ですが、最初にそういう風に作った(作ってしまった)ため、
いまさら全部Pythonで統一も面倒だなぁ。とか、そういう理由というだけです。
基本的にPython内でsubprocessで書けばShellで用意する必要はないはずです。