はじめに
こんにちは、プロトタイピングソリューションアーキテクトの市川です。
我が家ではネコを飼っているのですが、餌をあげればあげるほど食べてしまう食いしん坊なネコです。もっと欲しいと甘えてくるので、ついあげてしまった結果、余計なお肉がついてしまったようです。

ネコの体重変化をモニタリング
そんなこともあり、日頃から体重の変化をモニタリングできた方がいいなと思い、自作してみることにしました。
とはいえ、ネコは自分から体重計に乗ってくれるわけではないので、 1 日に数回必ずくるトイレの下に体重計を設置することで、自動的に計る仕組みにしました。
注意: 正しくネコの健康を管理したい場合は、商品化されているものを利用する方がより簡単に、正確な健康管理ができます。
トイレの下に置くとほとんど見えないですね (矢印のところ)。ネコもまさかトイレの度に体重が計られているなんて、これなら気づかれません。

自作する際の方針
自作するにあたって、以下の方針を考えました。
可愛いネコの様子も見たいので、動画を撮影して体重と一緒に撮影したい
なるべく少ない実装で済ませたい
独自の UI で一覧や動画再生を用意したくない
体重の計測ができたら、わかるようにしたい
トイレ掃除タイミングがわかりやすい
というわけで、 UI 側をどうするか検討したところ、使い方に合いそうなのが Slack だったので、アーキテクチャはこのような形になりました。

Slack 通知のイメージ
一通り完成すると、このようなメッセージが Slack に投稿されます。

ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
builders.flash メールメンバー登録
1. 利用するデバイス
このブログでは主に以下のデバイスを利用しています。(配線やコネクターは適宜用意してください)
センサーが接続できる GPIO が必要であり、動画の撮影用のカメラの接続ができ、開発に使う言語も慣れた Python が使えるということで、デバイスとしては Raspberry Pi 4 Model B メモリ 4G を採用しました。カメラには USB で接続できる ロジクールの Web カメラ を利用しています。
使用するセンサー
重さを計る時に使うセンサーは、ロードセルと呼ばれる物で、歪みによって変化する抵抗値によって得られる電気信号を AD コンバータモジュール (HX711) を利用して測定できます。今回は 5 kg を計測できるロードセルとモジュールのセットを 2 つ用意します (5 kg のロードセルを 2 つ使うこと 10 kg まで計測ができ、ネコの体重とトイレの重さを考えると今のところ十分)

センサーと Raspberry Pi のワイヤリング
センサーと Raspberry Pi のワイヤリングはこのようになっています。

センサーのイメージ

ロードセル
ロードセルは歪むことで重さを計ることができますので、板の間に固定します。今回はベースにアルミの板を使い、上部には中が見えるように 5 mm 厚のアクリル板を使用しています。

2. 環境の構築
今回は AWS Cloud Development Kit (AWS CDK) のサンプルソース を用意していますので、ダウンロードして利用するとクラウド側に必要な設定が準備できます。
サンプルのデプロイの前にいくつか準備が必要ですので、まずは準備を行います。説明のコマンドは、Linux ベースでの説明となっています。また、AWS Lambda 関数 は Arm アーキテクチャを指定しているため、Ubuntu 20.04、 Armアーキテクチャの Amazon EC2 インスタンス (t4g.medium) を起動し、作業を進めるとトラブルが起きずに進められると思います。
また、AWS のリソースを操作する際にはクレデンシャル情報が必要となります。十分な権限を持つクレデンシャルを用意し、環境変数へ設定してください。
クレデンシャル情報を取得
コマンド
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_DEFAULT_REGION=ap-northeast-1DEFAULT_REGION=ap-northeast-1
2-1. Slackのアプリケーションを登録
今回は動画を投稿したいため、incomming web hook ではなく、ファイルアップロード用の API を利用します。この API を利用するためには、 Slack にアプリケーションを登録し token の発行が必要です。そのための作業は Slack の 公式のドキュメント を参考に進めてください。アプリケーションに必要となる権限は以下の 2 つでした。
- Bot Token Scopes の files:write
- User Token Scopes の files:write
アプリケーションを作成したら Bot User OAUth Token の値をメモしておきます。
次に、通知先のチャンネルを作成し Channel ID をメモしておきます。
2-2. AWS Systems Manager の Parameter Store の登録
作成した Slack の情報をソースコードにハードコードするのは良くないので、 Parameter Store に保存し、Lambda が利用するときに参照するようにします。以下の aws cli コマンドで Slack の情報を Parameter Store へ登録してください。your channel id と your token は実際の値に置き換えてください。
Slack の情報を Parameter Store へ登録
コマンド
aws ssm put-parameter \
--name "/NekoSensor/NotifyToken" \
--type "SecureString" \
--value "{\"channel\":\"your channel id\",\"token\":\"your token\"}"
2-3. AWS Cloud Development Kit (AWS CDK) のデプロイ
AWS CDK は使い慣れたプログラミング言語で記述することで AWS のリソースを柔軟に管理・構築することができるツールです。 AWS CDK をあまり利用したことがない場合は、以下の AWS Blackbelt Online セミナーを見ることをお勧めします。
バージョン情報
AWS CDK は複数の言語に対応していますが、このサンプルでは Typescript を利用して記述しています。今回のサンプルは以下のバージョンの環境で作成しています。
node --version
v20.10.0
npm --version
10.2.3
python3 --version
Python 3.9.6
ライブラリをインストール
ここからは、サンプルソースを AWS CDK の実行できる環境にダウンロードし、デプロイを行います。 まずは、AWS CDK スタックで必要となるライブラリをインストールします。
cd path/to/unziped-folder
npm install
ブートストラップ
対象のリージョンで初めて AWS CDK を利用する場合は、ブートストラップが必要になりますので、以下のコマンドを実行します。CDK がインストールされていない場合は、リンクを参考 にセットアップしてください。
cdk bootstrap
デプロイ
以下のコマンドで、デプロイを行います。途中で Do you wish to deploy these changes (y/n)? と聞かれたら y を入力してください。Lambda layer のビルドで Docker を必要とします。Error: spawnSync docker ENOENT というエラーが表示されたら、Docker のインストールを行ってください。
cdk deploy
出力ログ
デプロイが完了すると以下のような出力があります。これらの値は、後の作業で必要になりますので、メモしてください。(AWS CloudFormation のマネージメントコンソールで NekoScaleStack の Output でも確認することができます)
Outputs:
NekoScaleStack.GreengrassCredentialEndpointXXXXXX = <AWS IoT Core のクレデンシャルエンドポイント>
NekoScaleStack.GreengrassGreengrassComponentBucketNameXXXXXX = <AWS IoT Greengrass のコンポーネントを保持する Amazon S3 バケット>
NekoScaleStack.GreengrassGreengrassTokenExchangeRoleXXXXXX = <AWS IoT Greengrass が利用する Token Exchange Service が利用する Role>
NekoScaleStack.GreengrassRecordDataBucketNameXXXXXX = <動画がアップロードされる Amazon S3 バケット>
NekoScaleStack.GreengrassRoleAliasXXXXXX = ScaleGgTesRoleAlias
3. AWS IoT Greengrass の準備
AWS IoT Greengrass の準備を始める前に、Raspberry Pi に SSH で入り、以下の作業を行います。OS のセットアップなどは、公式のドキュメント を参考に進めてください。
Raspberry Pi の情報
今回テストで利用した Raspberry Pi の情報は以下となります。
uname -a
Linux raspberrypi 6.1.0-rpi7-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.63-1+rpt1 (2023-11-24) aarch64 GNU/Linux
Java のインストール
AWS IoT Greengrass の実行には Java を必要とします。また、コンポーネントの利用するライブラリのインストールで pip コマンドを必要としますので、以下の手順でインストールします。
sudo apt update
sudo apt install software-properties-common python3-pip
wget -O- https://apt.corretto.aws/corretto.key | sudo apt-key add -
sudo add-apt-repository 'deb https://apt.corretto.aws stable main'
sudo apt update
sudo apt install -y java-11-amazon-corretto-jdk
AWS IoT Greengrass のインストーラーを取得
AWS IoT Greengrass のインストーラーを取得します。
curl -s https://d2s8p88vqu9w66.cloudfront.net/releases/greengrass-nucleus-latest.zip > greengrass-nucleus-latest.zip && unzip greengrass-nucleus-latest.zip -d GreengrassInstaller
インストールを実行
--tes-role-name には AWS CDK のデプロイ後の表示された値を指定して、インストールを実行します。(実行する前に環境変数に十分な権限を持つ AWS のクレデンシャルを指定してください)
sudo -E java -Droot="/greengrass/v2" \
-Dlog.store=FILE -jar ./GreengrassInstaller/lib/Greengrass.jar \
--aws-region ap-northeast-1 \
--thing-name NekoScale \
--thing-group-name NekoScaleGroup \
--tes-role-name <AWS CDK デプロイ時に表示された NekoScaleStack.GreengrassGreengrassTokenExchangeRoleXXXXXX> \
--tes-role-alias-name ScaleGgTesRoleAlias \
--component-default-user ggc_user:ggc_group \
--provision true --setup-system-service true
起動確認
以下のコマンドでログが確認できますので、正しく起動していることを確認しましょう。
sudo tail -f /greengrass/v2/logs/greengrass.log
4. コンポーネントのデプロイ
ここまでの作業でクラウド側とデバイスの準備ができました。サンプルソースにはコンポーネントのサンプルも含まれていますので、ここではコンポーネントの登録とデプロイについて紹介します。
4-1. GDK のセットアップ
コンポーネントは GDK を用いて作成されています。GDK コマンドを利用できるよう予め GDK のセットアップが必要です。下記のコマンドを用いて サンプルソースがあるローカル PC (または EC2 インスタンス) に GDK をセットアップしてください。
GDK のインストール
コマンド
python3 -m pip install git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git
バージョン確認
バージョンを確認します。
gdk --version
gdk 1.6.2
4-2. コンポーネントの登録
コンポーネントのディレクトリに移動し、まずはビルドを行います。コードの変更を行った場合は、クラウドに登録する前に必ずビルドを行います。(実行する前に環境変数に十分な権限を持つ AWS のクレデンシャルを指定してください)
cd gdk/NekoScale
gdk component build
コンポーネントを登録
コンポーネントを登録します。オプションの --bucket には、AWS CDK デプロイ時に表示された値を指定します。
gdk component publish --bucket <CDKデプロイ時に表示された NekoScaleStack.GreengrassGreengrassComponentBucketName の値>
コンポーネントの登録確認
正常に終了したら、 AWS IoT Greengrass の マネジメントコンソール を開き、コンポーネントが登録されていることを確認します。

4-3. コンポーネントのデプロイ
AWS IoT Greengrass では、今回のように独自で作成したコンポーネントだけではなく、 AWS で用意しているよく利用されるユースケースに便利な機能を持つコンポーネントも提供しています。サンプルのコンポーネントでは、 Stream Manager という AWS のいくつか (AWS IoT Analytics, AWS SiteWise, Amazon S3) のサービスへデータをエクスポートしてくれるコンポーネントを利用しています。
コンポーネントのデプロイは、 Greengrass Deployments の画面から行います。左のメニューで「Deployments」を選択し、「Create」ボタンから進みます。

対象の指定

コンポーネントの選択
My components では登録した com.example.NekoScale にチェックをつけます。
Public componentsでは、クラウド側でログが確認できるように aws.greengrass.LogManager も選択していますが、こちらは選択しなくても良いです。(クラウドのアップロードを有効にすると、その分コストがかかります)
「Next」で次に進みます。

個別設定
「Configure components」の画面では、コンポーネントに対して個別の設定を行います。
編集するコンポーネントを選択し「Configure components」ボタンを選択します。

S3 バケットを指定
サンプルのコンポーネントでは、撮影した動画のアップロード先の S3 バケットを指定する必要があるため、以下の画面のように JSON で設定値を指定します。
設定したら「Confirm」で保存します。
{ "S3BucketName": "AWS CDK デプロイ後に表示された `NekoScaleStack.GreengrassRecordDataBucketName の値" }

ログを Amazon CloudWatch Logs にアップロード
aws.greengrass.LogManager も選択していた場合は、同じようにコンポーネントの設定を開き以下の JSON を指定すると、AWS IoT Greengrass のログと、サンプルのコンポーネントのログを Amazon CloudWatch Logs にアップロードしてくれます。
{
"logsUploaderConfiguration": {
"systemLogsConfiguration": {
"uploadToCloudWatch": "true",
"minimumLogLevel": "INFO",
"diskSpaceLimit": "10",
"diskSpaceLimitUnit": "MB",
"deleteLogFileAfterCloudUpload": "false"
},
"componentLogsConfigurationMap": {
"com.example.NekoScale": {
"minimumLogLevel": "INFO",
"diskSpaceLimit": "20",
"diskSpaceLimitUnit": "MB",
"deleteLogFileAfterCloudUpload": "false"
}
}
},
"periodicUploadIntervalSec": "300",
"deprecatedVersionSupport": "false"
}
デプロイ完了
Configure advanced settings は「Next」で進み、Review の画面で確認したら「Deploy」ボタンを選択してデプロイを行います。
デプロイが完了すると、画面のように Successed が表示されます。

実際のデモ
以上で、一通りの準備が完了しました。あとは、実際にネコがトイレで用を足すと、 Slack のチャンネルに以下のように通知してきます。
準備ができましたので、あとはネコがトイレに来るのを待つだけです。Slack への投稿イメージは冒頭で紹介し多様なものですが、このような動画が添付されます。トイレの様子が見えて可愛いですね。
体重の推移
また、アーキテクチャ図にある Amazon CloudWatch では何をしているかというと、計測した体重をカスタムメトリックスとして登録しています。CDK ではそのメトリックスを使ってダッシュボードも作成しているので、体重の推移も確認することができます。

5. まとめ
いかがでしたでしょうか ? これで安心して可愛いネコの健康をチェックしつつ、おやつをあげたいと思います。
今回のサンプルではまだ間違いなく体重を計るコードには詰めきれておらず、誤検出や重さが違うなど改善点はまだまだありそうです。以下に重さの変化を図にしてみましたが、結構考えることが多いですね。
これらの点が改善できると、ウ⚪︎チの重さがわかったり、より精度の高い体重計が作れると思います。また、ロードセルを 100 kg ぐらい計測できるタイプに変えれは、自分用のスマート体重計も作れますね。人間の場合は、乗った後にそれほど動き回らないので、判定処理をもっとスッキリさせることができそうです。
皆様も是非チャレンジしていただければと思います。

筆者プロフィール
アマゾン ウェブ サービス ジャパン合同会社
AWS Prototyping Team シニア プロトタイピング ソリューションアーキテクト
2018年 に AWS へ入社し、主にIoTに関連するプロトタイピングを提供しています。Web サービスから家のデッキ作りまで、モノを作るという事であれば何でも好きな DIY おじさんです。ここ数年の趣味はバイクでツーリングに行ったりキャンプに行くことです。

Did you find what you were looking for today?
Let us know so we can improve the quality of the content on our pages