🏡

Nature Remo+AWS+LINE Notifyで緩やかな自宅監視(1)

2023/12/22に公開

家族がいると自宅の様子が気になる、けれども監視カメラを設置するのは家族のプライバシー的に行き過ぎた感あり、もう少し緩やかな監視ができないか?と考えた際、照度の変化に着目したソリューションを思いついた。
つまり、家族が帰宅して部屋の電気を付けた、外出のため消灯した、電気を消して寝静まったといった状態の遷移を「照度の変化」によって検知し、スマホに通知する、といった具合だ。

概要

Nature Remo 3は外出先からスマートフォンで家電を制御するためのスマートリモコン製品のひとつであるが、照度や温度センサーが取得した情報を Nature Remo Cloud API によりクラウドから取得できる、という大変素晴らしい特徴がある。
https://shop.nature.global/products/nature-remo-3

自宅に設置したNature Remoの照度を、AWSのLambda関数により一定時間毎に取得してDynamoDBに蓄積する。前回取得した照度と比べて急激な変化があった場合、LINE Notify APIを使用してスマホにピロリン♪と通知してみよう。

なお、Nature Remo 3の設置、WiFi経由でのインターネット接続、スマートフォンアプリとの連動などは一通り設定済みである前提とする。

Nature Remo Cloud API アクセストークンを発行

APIを使用するにあたり、まずはhome.nature.globalのサイトへログインし、「Generate access token」ボタンからOAuth2認証のためのアクセストークンを発行する。アクセストークンはこの後使用するため、安全な場所に保管しておく。

AWS Lambda 関数を作成

ここからはAWSコンソールにサインインして作業する。
まず初めに、新規のLambda関数を作成する。

  • 関数名: NatureRemo_Save
  • ランタイム: Node.js 20.x

続いて、先ほど作成したトークンを環境変数として設定しておく。
「Lambda > 関数 > NatureRemo_Save > 環境変数の編集」にて下記の通り設定する。

  • キー: NATURE_REMO_TOKEN
  • 値: Nature Remo Cloud APIのアクセストークン

Nature Remo Cloud APIのドキュメントに書いてある通り https://api.nature.global/1/devices のURLに対してAuthorizationヘッダーにトークンをセットしてリクエストすると、センサーが取得した最新の照度などがJSON形式で返ってくる。JSONはNatureアカウントに登録されたデバイスの個数分が配列となっており、各配列要素内で下記のようにして情報を取得できる。

  • name: 登録されたデバイス名
  • newest_events.il.val: 最新の照度の値
  • newest_events.te.val: 最新の温度の値

curlで試すとJSONが返るところまであっさり確認できたので、さっそくLambda関数の「index.mjs」を書いてみる。

index.mjs
import https from "https";

export const handler = (event) => {

  const url = "https://api.nature.global/1/devices";
  const options = {
    headers: { "Authorization": "Bearer " + process.env.NATURE_REMO_TOKEN }
  };
  
  https.get(url, options, (response) => {
    let data = "";
    response.on("data", (chunk) => { data += chunk; });
    response.on("end", () => {
      data = JSON.parse(data);
      console.log("name: " + data[0].name);
      console.log("il: " + data[0].newest_events.il.val);
      console.log("te: " + data[0].newest_events.te.val);
    });
  });
};

Deploy〜Testして、期待通り照度や温度が取得できた!

Function Logs
2023-12-21T15:59:21.272Z ... INFO name: Remo
2023-12-21T15:59:21.311Z ... INFO il : 106
2023-12-21T15:59:21.311Z ... INFO te : 20.4

DynamoDB テーブルを作成

AWSのDynamoDBコンソールから、照度データを保存するためのテーブルを新規に作成する。

  • テーブル名: NatureRemo_Records
  • パーティションキー: device(文字列)
  • ソートキー: timestamp(数値)

DynamoDBではTTLという便利な機能があり、テーブルの項目の特定の列に入れたUnix時間を超過すると自動で項目を削除してくれる。項目が単調増加により増えすぎるのを防ぐことが可能。

TTLの設定はちょっとわかりにくいところにあり、dynamoDBコンソールの「テーブル > 設定の更新 > NatureRemo_Save」テーブルを選択し、「アクション > TTLをオンにする」で設定画面が開くので、「TTL属性名: ttl」と設定する。

Lambda関数からdynamoDBへデータを保存する

データ保存処理を書く前に、Lambda関数からdynamoDBへアクセス可能にするためのロール設定を行う。ロール設定をうっかり忘れると、この後のテーブルへの項目追加処理でエラーとなってしまうので要注意。

NatureRemo_Save関数の「設定 > アクセス権限 > ロール名 NatureRemo_Save-role-...」をクリックすると、「IAM > ロール > NatureRemo_Save-role-...」のロール設定画面となるので、「許可ポリシー > 許可を追加」から「AmazonDynamoDBFullAccess」を追加する。

無事にロール設定が完了したら、Lambda関数の「index.mjs」のコードへ戻り、まずはdynamoDBへアクセスするためのモジュールをインポートしてDB接続用クライアントを生成する。

index.mjs
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
const db = new DynamoDBClient({ region: "ap-northeast-1" });

テーブルに項目を追加するためには PutItemCommand オブジェクトを生成して、DB接続用クライアントで send する。PutItemCommand の中身 Item には、文字列は { S: "foo" } 数値は { N: "123" } といったようにする必要があり、素人目にみてなんともイケていない仕様に感じるけど、こういうものなのか?ちなみに数年前に同じことをやったときの当時のAWS SDKでは、数値型のまま普通に突っ込めた。

index.mjs
    response.on("end", async () => {
      data = JSON.parse(data);
      const unixtime = Math.floor(Date.now() / 1000);
      const putCmd = new PutItemCommand({
        TableName: "NatureRemo_Records",
        Item: {
          device   : { S: data[0].name },
          il       : { N: data[0].newest_events.il.val.toString() },
          timestamp: { N: unixtime.toString() },
          ttl      : { N: (unixtime + 60*60*24*3).toString() }
        }
      });
      await db.send(putCmd);
    });

テスト実行し、コンソールに出力される項目追加の処理結果が「httpStatusCode: 200」となることを確認。また NatureRemo_Records テーブルの「項目の探索」でテーブルの中身を見て、お見事、テスト実行のたびに項目が追加されるようになった!

今日はここまで

だいぶ長くなりそうなので、今日はここまで。明日からは引き続きLambda関数の定期的な繰り返し実行、LINE Notify APIを使用した通知を実装する予定。

つづきの記事はこちら
Nature Remo+AWS+LINE Notifyで緩やかな自宅監視(2)

Discussion