【連載記事】Azureを使って一人暮らしの父を見守る(2)Logic AppsとLINE連携偏

2020年8月12日

はじめに

一人暮らしの父(80歳Over)を見守るため、Webカメラで動体監視を行い、毎日リビングで過ごしているかを見守るシステムを構築します。

何本かに記事を分けて構築を進めたいと思いますが、最終的には以下の構成になりそうです。

今回の記事では黄色の範囲について説明しています。

本エントリでは、Azure Logic AppsとLINEとの連携にスポットを当てています。
WebカメラとAzure Logic Appsとの連携については「(1)WebカメラとLogic Appsの連携偏」を参照ください。
より実用的な構成にする最終話は「(3)Logic Appsのタイマーで定期チェック偏」を参照下さい。

必要なものなど

前回のエントリでWebカメラの動体検知の設定と、Azure Logic Appsの基本設定は済んでいるので、今回は以下の準備をします。

  • LINE DevelopersのアカウントでMessaging APIの準備
  • Logic AppsにてWeb Hookの応答と、自律メッセージの送信

LINE Developersの準備

LINE Developersのサイトにアクセスして、自身のLINEアカウントでログインをして、開発者登録を行います。
フリープランのままでも、月間1,000通のメッセージ送信が行えるそうなので今回の検証や用途であれば全く問題なさそうです。

プロバイダー登録

サイトにログイン完了後、コンソールのメニューから「プロバイダー」を選択して、新規作成します。
(画面では既にpersonalというプロバイダーが作成済みです)

作成画面で任意の名称を設定して作成します。

チャネル作成

作成したプロバイダーを選択後、チャネル設定画面から「新規チャネル作成」を選択します。
(画面では既にcamera motionというチャネルが作成済みです)

チャネルの種類は「Messaging API」を選択します。

チャネルの設定

作成したチャネルを選択して、「チャネル基本設定」を開きます。

ちょっとうろ覚えなのですが、「チャネルシークレット」の発行を行っておく必要があります。

「Messaging API設定」タブに移動します。

Webhook URLにAzure Logic Apps側のURLを指定します。Webhook URLにAzure Logic Apps側のURLを指定します。前回のエントリで作成したLogic Appsの「HTTP要求の受信時」にあるHTTP POSTのURLです。

LINEでこのBotをフレンド登録したときに、デフォルトの応答メッセージ、あいさつメッセージが送信されるのですが、今回は不要なので無効化します。

最後に表示される「チャネルアクセストークン」はこのあとLogic Appsにて指定するので控えておきます。

Logic Appsの準備

前回作成したLogic Appsを少し手直しして、以下の構成にしています。

(1)URLリクエストの取得と現在日時を取得

前回エントリの再掲になりますが、HTTP要求受信時のJSONスキーマはLINEから送られるメッセージを解析できるように、以下の設定をしています。

{
    "properties": {
        "events": {
            "items": {
                "properties": {
                    "message": {
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "text": {
                                "type": "string"
                            },
                            "type": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "replyToken": {
                        "type": "string"
                    },
                    "source": {
                        "properties": {
                            "type": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "timestamp": {
                        "type": "integer"
                    },
                    "type": {
                        "type": "string"
                    }
                },
                "required": [
                    "replyToken",
                    "type",
                    "timestamp",
                    "source",
                    "message"
                ],
                "type": "object"
            },
            "type": "array"
        }
    },
    "type": "object"
}

後は現在日時を取得して、それをJSTに変換しているくらいでしょうか。
変数の初期化は後で利用する前回モーション検知してから何秒経過したかを保存するために使います。

(2)Webカメラからのモーション検知受信時

前の条件で、HTTPリクエストのevents.typeが「motion」の場合は、Webカメラ(Synology NAS)からの通知であると判断しています。(LINEからはこの値にmotionは設定されてこない前提)

この場合は、現在日時をAzure Table Storageに保存後(前回エントリ参照)に、HTTPリクエストにてLINEのMessaging APIに対して、broadcast指定でチャネルに登録しているユーザ全てのLINE端末にメッセージを送信しています。

方法は「POST」、URIには「https://api.line.me/v2/bot/message/broadcast」を指定します。

ヘッダーに「Authorization」には「Bearer <先に控えたトークン文字列」を追加、
「Content-Type」には「application/json」を追加します。

本文には以下の形式でLINEに送るメッセージ本文をtext指定で設定します。

{
    "messages": [
        {
            "text": "@{body('changetimezone')}に動体検知しました",
            "type": "text"
        }
    ]
}

(3)LINEからのメッセージに返信する

前回のエントリでAzure Table Storageから最終モーション日時を取得してきましたが、これをJSON形式で判別できるようにします。

「JSONの解析」アクションでは以下のスキーマを設定して、Azure Table Storageからの応答の中身を見られるようにしました。

{
    "properties": {
        "odata.metadata": {
            "type": "string"
        },
        "value": {
            "items": {
                "properties": {
                    "datetime": {
                        "type": "string"
                    },
                    "odata.etag": {
                        "type": "string"
                    }
                },
                "required": [
                    "odata.etag",
                    "datetime"
                ],
                "type": "object"
            },
            "type": "array"
        }
    },
    "type": "object"
}

経過時間の計算はこれがベストなのかはわかりませんが、式を以下のようにして前回日時と現在時刻との差を取り、秒に変換しています。

div(sub(ticks(actionBody('changetimezone')),ticks(items('For_each_2')?['datetime'])),10000000)

最後にHTTPリクエストにてLINEのMessaging APIに対して、返信するユーザ指定でLINE端末にメッセージを送信しています。

方法は「POST」、URIには「https://api.line.me/v2/bot/message/push」を指定します。

ヘッダーに「Authorization」には「Bearer <先に控えたトークン文字列」を追加、
「Content-Type」には「application/json」を追加します。

本文には以下の形式でLINEに送るメッセージ本文をtext指定で設定します。

{
    "messages": [
        {
            "text": "前回動体検知してから @{variables('経過時間')}秒経過しています",
            "type": "text"
        }
    ],
    "to": "@{items('For_each')?['source']?['userId']}"
}

動作確認

カメラの前で飛んだり跳ねたりして、動体検知が行われてそのたびにLINEにメッセージが届きます。

Logic Appsの実行履歴も成功していますね。

続いて、LINEに適当なメッセージを投稿して、BOT(Logic Apps)からの返信を確認します。

こちらもちゃんと動いているようです。

おわりに

今回はLINEとAzure Logic Appsとの連携がメインでしたが、前回のエントリであるWebカメラとの連携と組み合わせることで、とりあえず動体検知時に即時LINEで通知が受けられるようになりました。

また、前回動体検知してからの経過時間も取得できるようになりました。

今回はここまでです、次回の最終章ではもうすこし実用的な設定を行ってひとまず完成させたいと思います。
(今のままでは終日動体検知する度に通知が飛んできてしまう)

参考になれば幸いです。