LoginSignup
7
14

LINEとラズパイで家の家電を操作する

Last updated at Posted at 2022-08-07

外出先からでもLINEを使って部屋の監視・コントロールができるスマートホームシステムを立ち上げた。

Screenshot_20220813-222203.jpg

このシステムでできること

  • LINEで部屋においた各種センサーの読み出し
  • 温湿度からエアコンのON/OFF自動制御
  • PCのON/OFF制御
  • PCのON/OFF状態の検出
  • 外出と帰宅の検出
  • 起床と就寝の検出
    など

システムの全体像

全体像としてはこんな感じ
基本的にスマートホーム系の操作をRaspberry Pi上で実行しているNode-REDに集約する思想で構築している
今回は黄色で着色した範囲の解説になる
2022-08-14_smarthome_systemchart.drawio.png

対象者

  • Switchbotとかアレクサというワードに興味があってちょっと使いこなしてみたい人
  • スマホからスマートホームしてみたい人
  • 家の家電を便利にしたい人
    など

前置き

前置きがいらない方は こちら から。

動機

1年前にSwitchBotを買ったところから我が家のスマートホーム化がスタートした。
エンジニアにとってはこれ以上ないおもちゃだが、いかんせんSwitchBotの標準アプリではできることが限られている。
Raspberry Piを買ってNode-REDフローを組んだり、Alexaとつなげたりしていたが
どうせなら家の外からも操作できるようにしてみたくなってきた。

全体構成図

最終的に出来上がったのはこういった構成。
どうしてわざわざGAS(Google Apps Script)を経由しているのか
どうしてSlackなんか動かしているのか。
「無料」と「セキュリティ」を両立したらこうなりました。
smarthome_arch.drawio.png

当初のもくろみ

最初に考えていたのはこんな構成。
LINEでテキストを飛ばせばそれがそのままラズパイに届く。
とってもかんたん。
そう思っていた時期がありました。えぇ。
主に以下の問題でこの構成に行き着きました。
smarthome_arch_pre.drawio.png

Webhookのエンドポイントはローカルに持ちたくない

Webhookのエンドポイントをローカル(RaspberryPi)に持つということは、すなわちHTTPポートを外部に公開して
世界中の誰からでもリクエストを受けられるようにするといこと。
セキュリティ的に怖いし、そもそもうちはDHCPのプロバイダで毎回アドレスが変わる。お金を払ってドメイン取得するのもイヤだ。
結果的にSlack Appを利用すればそのあたりが解決することがわかった。
Webhook RelayやPushBulletあたりも考えたが、こいつらは無料プランだとリクエストの上限が月100回くらいと少なく
今後のスケーラビリティも考えて見送った。
ちなみにSlackは1時間あたり30,000イベントまでOKらしい。
太っ腹すぎる。

LINEのAPIとSlackのAPIが噛み合わない

LINE側の用意しているメッセージのAPIと、Slackが受け付けているAPIの仕様が絶妙に噛み合わず
LINE → Slack という経路が直結できない。
LINEのWebhookを受けてSlackのAPIに変換する仕組みが必要だ。
AWSやIBM Cloud, Google Cloud Platformあたりが中継サーバーとして機能しそうだが
登録すると強制的にトライアル扱いになって、期間が終わるとデータが消えたりお金を請求されるようなことが書いてあった。
こんな小規模ホビー目的で使うにはトライアルはもったいないし、大したことしてないのに請求が来るのも残念すぎる。
結果的にGAS(Google Apps Script)ならなんとかしてくれそうなことがわかった。

本編

前置きが長くなりましたが、ここから。

LINE Developerの用意

登録

LINE Developer のフリープランで登録する。
右上のログインから自分のLINEアカウントで登録・ログインする。
qiita_fig1.png

プロバイダーの作成

プロバイダー > 作成 で新規プロバイダーを作成する
名前はなんでもいいと思う
qiita_bot_createprovider.png

Botの作成

作成したプロバイダーに移動 > 新規チャネル作成 > Messaging API をクリック
新規チャネル作成画面に移動するので必要事項を入力して 作成 をクリック
qiita_bot_create.png

チャンネル名はなんでも良い
bluehamham.png

BotのIDの確認と友だち追加

Botの作成が完了するとチャネルの詳細を確認できる。
Messaging API設定 タブを押すと自分のBotのIDが確認できる
qiita_bot_ID.png

このIDでラインの友達検索をするとチャンネルが表示されるため友だちになっておく
qiita_bot_friend.png

ちなみにこのBotのアカウントは他人も登録することができるのでIDは公開しないように。

Webhookの有効化、デフォルトリプライの無効化

Webhookの設定とデフォルトリプライの設定を行う
今見ているLINE Developperではなく LINE Official Account Manager での設定となるので
下記のリンクをクリックする
qiita_bot_account_manager.png

クリックすると画面が遷移するので
リンク先の画面 > 左の応答設定 > 詳細設定

  • 応答メッセージ > オフ
  • Webhook > オン
    にする
    qiita_bot_account_setting.png

GAS(Google Apps Script)の用意

Googleアカウントの作成

さすがに持ってない人はいないと思うので割愛する。
特に特別なライセンスである必要はなく、Googleドライブが使えるアカウントならOK。

スクリプト作成画面に行く

正しい行き方がわからないが、GoogleDrive > 新規スプレッドシート >
スクリプト でこの画面へ行けた。
qiita_gas_open.png

プラスマークからスクリプトを選択する
qiita_gas_coding.png

スクリプトを作成する

下記のコードを入力する。
デフォルトで myFunction() が定義されているが、それは削除する

function doPost(e) {
  var ACCESS_TOKEN = 'このあと発行するLINE長期トークン';

  var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
  var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
  var url = 'https://api.line.me/v2/bot/message/reply';
  var response = UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': [{
        'type': 'text',
        'text': userMessage + 'ンゴ',
      }],
    }),
  });

    url = 'このあと発行するSlackのWebhookURL';
    UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json',
    },
    'method': 'post',
    'payload': JSON.stringify({
      'text': JSON.stringify({
          'message': userMessage,
          'replyToken': replyToken
      })
    }),
    });
  
  return response.getResponseCode();
}

2020年頃まで流行っていたLINE オウム返しBOTのコードのほとんどは
Google側のレスポンスの仕様が変わったため利用できない。
このGoogle側の仕様変更はセキュリティ観点だそうで、今後この方法も使えなくなる可能性がある。
とりあえず2024年2月現在は上記コードで正常に動作している。

デプロイする

Ctrl + s で変更を保存してから 画面右上のデプロイボタンを押す
下記のポイントに気をつけること

  • 種類の選択でウェブアプリを選択
  • アクセスできるユーザーが全員になっていること

安全ないアクセスになるため警告が出るが、URLを外部に公開しない前提 でOKとする
※デプロイするたびに新しいURLが発行されるので、LINEには最新のURLを入れる必要がある
qiita_gas_deploy.png
qiita_gas_deploy2.png

この画面が出てきたらひとまずOK。下のURLを使用するが、後でもう一度デプロイするのでこの時点では特にURLを控えなくて良い
qiita_gas_webhookURL.png

Slackの用意

Slackに登録する

もともと使ってる人はすっ飛ばしてください。
僕は会社がTeamsなのでここで初めて登録しました。

ワークスペースを作成する

自分しかいないワークスペースを作成する。
他の人もいても構わないが、その人からも家の家電が操作できてしまう。

チャンネルの作成

自分とSlack Appしか使わないチャンネルを作成する
ユーザーの追加は特に不要

プラベートチャンネルに設定した場合でも動く方法がわからないため、今回はワークスペースの公開チャンネルで作成する
qiita_slack_createchannel.png

Slack Appの作成

このサイトからSlackAppを作成する
From Scrachを選ぶ
qiita_slack_createapp.png

適当な名前をつけ、さっき作ったWorkSpaceを選ぶ
qiita_slack_createapp2.png

Incoming Webhooks をONにする

qiita_slack_incomingwebhook.png

Socket Mode をONにする

左の Socket Mode をクリックし、Enable Socket Mode をONにする
qiita_slack_socketmode.png

Event Subscriptionsを設定する

左の Event Subscriptions をクリックし、Enable Events をONにする
Subscribe to bot events > Add Bot User Event をクリックし
message.channels を追加する
qiita_slack_eventsubscriptions.png

OAuthのスコープを確認する

左の OAuth & Permissions > Scopes に行き
channels:history と incoming-webhook が追加されていればアプリの設定は完了

qiita_slack_OAuth.png

App-Level Tokensを作成する

左のBasic Information > App-Level Tokens から Create token and Scopes を押す
Scopeは connections:write
qiita_slack_apptoken.png

qitta_slack_apptoken2.png
これがSlack→node-redの接続のためのTokenになる

  • アプリをチャンネルにインストールする
    Install App > Install to Workspace でワークスペースへインストールする
    さっきのチャンネルにインストールする

チャンネルにアプリを追加する

Slackのチャンネル画面に戻り、
チャンネル名を右クリック > チャンネル詳細を表示する > インテグレーション > App > アプリを追加する
で作成したアプリを追加する
qiita_slack_addapp.png

WebhookURLを控える

Incoming Webhook > Webhook URLs for Your Workspace でWebhookURLの確認する
後でGoogeleAppscriptに入力する
ワークスペースへアプリをインストールするたびに新しいURLが発行されるため、何度か行った人は複数のURLが発行されており、一番下が最新である。
URLにアプリのパーミッションが紐づいているので、誤ってURLを外部に公開した人はここでURLを無効にする必要がある。
qiita_slack_webhookURl.png

Node-REDの用意

まずはNode-REDの環境がまだ整っていない人は下記のURLを参考にしてブラウザでNode-REDが立ち上がるところまでいく
qiita_node-red_init.png

ブラウザでこの画面が表示されるところまで行く

Slackノードの導入

Slackのノードを使えるようにする。
Node-REDの画面 > 右上のハンバーガー > パレットの管理 > ノードを追加タブ
検索窓に「node-red-contrib-slack-socket」を入力 > ノードを追加 をクリック
ラズパイの場合激重なので、気長に待つ
qiita_node-red_install.png

インストールが成功すると左の一番下に Slack Listen のノードが追加される
qiita_node-red_install_complete.png

余談だがこのあたりのワードを検索すると出てくるSlackBotは使えない。
SlackBotが使用しているRTM(Real Time Messaging)というAPIが廃止になったためだ。
2021年11月現在、SlackはイベントベースでのAPIのみ受け付けている状況だ。

全体接続図

今回はサンプルで「こんにちは」というメッセージを送ったら「I'm fine, thank you. And you?」と返してくれるフローを作ってみる。
qiita_node-red_connect2.png

各ノードの設定

Slack Listen

ノードをパレット上にドラッグ > ノードをダブルクリック > Settingsの鉛筆マーク
名前とTokenを入力する
名前は何でもよく
Tokenは先ほど作成したSlack の App-level Tokenを入力する
qiita_node-red_slacklisten.png

jsonパーサ

qiita_node-red_json.png
プロパティは下記
payload.text

switchノード

qiita_node-red_switch.png
プロパティは下記
payload.text.message
How are you?

Changeノード

qitta_node-red_change.png
プロパティは下記
headers.Content-Type
application/json
headers.Authorization
Bearer LINE長期トークン
payload.messages[0].type
text
payload.messages[0].text
I'm fine, thank you. And you?
payload.replyToken
payload.text.replyToken

HTTPリクエストノード

qiita_node-red_http_request.png
https://api.line.me/v2/bot/message/broadcast

Debugノード

対象をmsgオブジェクト全体にしておくとあとでデバッグがやりやすい(個人的に)
debug_lineのノードのも同様
qiita_node-red_http_debug.png

各種トークンやWebhook URLの入力

既にこれまでの手順で入力したものも含めて、改めてここで各種サービスの連携をする。
ここで発行するURLやトークンはすべてプライベートなものなので、自分以外の人に公開しないようにすること。
誤って公開してしまった場合、トークンは再生成することで他のものが無効になる。
WebhookURLは無効にしない限り有効のままなので、無効化の手続きを行う必要がある。

LINEトークンの取得と入力

LINE Developpers > Messaging API設定 から
チャンネルアクセストークン(長期) の発行ボタンを押す
qiita_bot_token.png

Node-REDのcahngeノードのAuthentication部分に入力する
qitta_node-red_change.png
+
GASの青色部分にも入力する
qitta_gas_token.png.png

  • Slack App-levelトークン
    Slack AppのApp LevelTokenは
    qitta_slack_apptoken2.png

    Node-REDのここに入れる
    qiita_node-red_slacklisten.png

  • Slack Webhook URL
    左の Install App > Webhook URLTs for Your Workdspace
    からWebhook URLをコピーする
    複数ある場合は一番下が最新のURLになる。
    qiita_slack_webhookURl.png

    GASの赤色部分に入力する
    qitta_gas_token.png.png

  • GAS Webhook URL
    GASをデプロイしたときに発行されるURLをコピーする
    デプロイするたびにURLが変わるので注意
    qiita_gas_webhookURL.png

    LINE Developerのここに入れる
    このURLはデプロイごとに変わるので、
    コード修正してデプロイし直したら毎回入れ直すこと
    qiita_line_webhookURL.png

動作テスト

ここまできたら動作テストをする
完璧にできていれば一発で通るが、そんなにうまくいくことはないので
疎通箇所を確認しながら頭から読み直してほしい。
qiita_verify.png

LINE → GAS のテスト

自分のLINEアカウントからメッセージを送って「こんにちは+ンゴ」が返ってきたら成功

GAS → Slackのテスト

送ったメッセージが入ったテキストがSlackのチャンネルに投稿されていれば成功
qiita_verify_gas.png

Slack → Node-REDのテスト

Debugノードに反応があれば成功
qiita_verify_node-red.png

Node-RED → LINEのテスト

LINEからの「こんにちは」+ンゴのあとに、"I'm fine, thank you. And you?" が返ってきたら成功

ここまでできたら通信はバッチリなので、
あとはNode-REDで好きな機能を各々実装していってほしい。

応用

LINEの応用

リッチメニューの作成

よくある公式アカウントのあれ
簡易的なものならブラウザでとても簡単に作成ができる
LINEすごい
https://manager.line.biz/
qiita_line_richmenu.png

Node-REDの応用

SwitchBotのBLEで部屋の状況の監視

SwitchbotのBluetoothのAPIはここで公開されている
https://github.com/OpenWonderLabs/SwitchBotAPI-BLE
お部屋の温度湿度、照明の有無あたりが取得できると、カビが生えそうな湿度になったら外出先からでも部屋の除湿をONにしたり、電気やパソコンの消し忘れを外出先から解決することができる
qiita_line_room.png

SwitchBotでカーテンを閉める

HTTP系のAPIはここで公開されている
カーテンの開け締め、スイッチのON/OFF等の操作ができる
リクエスト数には上限があるので注意すること
https://github.com/OpenWonderLabs/SwitchBotAPI

Alexaにしゃべらせる

いくつか方法はあるが、この記事がとても参考になった。
特に追加でライブラリを入れる必要もない
https://qiita.com/shge/items/169de61c8f246d26c110

さいごに

初めてのQiita記事なので読みづらさはご容赦いただきたい。
LINEからスマートホームする手段が体系立てて掲載されている場所がなく今回まとめてみた。
応用編の解説は要望が多ければ掲載しようと思うので、記事を気に入っていただければ反応をいただきたい。

個人向けのフリーのWebhookエンドポイントサービス(+Node-REDのレシーバー)があるとここまで苦労しなかったので
誰か作ってくれるといいなぁ。
Webhook Relayのフリーアカウントみたいな、リクエスト数が月上限150とかだと
正直デバッグのリクエストだけで上限振り切りそうです。

7
14
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
7
14