ラズパイとAWS IoTを使った見守りシステム自作で学んだこと(1)概要の説明からの続きです。今回も概要説明の続きになります。
本稿では、この「見守りProject」の設計書を作ります。
大上段で設計と言いましたが大げさなものではなく
- Project
- モノ(ラズパイ)
- 録画したmp4をuploadするS3のBucket
の3種類、最大で6個の名前を決めて、加えてセンサーの1/0のタイプとイベント録画のトリガー方法を確認します。
これらをcliの対話実行でdeployに必要な設定ファイルと映像確認用ページのhtmlファイルを出力します。
以下、若干分かり難い説明になりますが、やることは最大6個の名前とセンシングのタイプを決めて入力するだけです。
Projectで使う名前を決める
リポジトリーのProjectを実装するのに必要なパラメーター(名前)は次の3種類です。
- Project名
- モノの名前(ラズパイの名前)
- S3のBucket名
Defaultでは最小1個、最大4個のラズパイを設定できる仕様になっており、ラズパイを複数設置する場合はラズパイの数だけモノの名前を決める必要があります。
ラズパイ4台設置するプロジェクトでは下図のようになります。ここでは、MyLivingというProjectで4か所のネコbedを見守り、neko-mimamoriというS3Bucketを作るという例になります。
(下図のメモ用シートはリポジトリーの./xlsx/parameters setting.xlsxになります)
リソース名
次に3種類の名前がリソースのどこに使われるか説明します。
ラズパイ
モノの名前:hostnameとして設定しますmqtt topicにも使います。
AWSリソース
- Project名:各リソース名の先頭につけます、何のProjectのリソースなのか明示します。
- モノの名前:IoT topic、IoT Rule、custom metricsの名前空間に使います。S3にホスティングする映像確認用web page Default originのキャプチャータイトルとタブ名にも使います。
- S3のBucket名:録画したmp4のupload先、閲覧時のホスティング先にする新規Bucketの名前として使います
リソース命名規則
本Projectでは下図のような命名規則に「三種類の名前」を組み込んでリソースを識別します。
名前の対話入力
リポジトリーに用意してある./setparameter.pyをcloneしたリポジトリーのroot directoryから実行して「Projectで使う名前を決める」で決めた名前を入力します。
1台目のラズパイでの設定
1台目のラズパイの設定時には、設置するラズパイ全数の情報を入力します。
最初に何番目のラズパイか聞いてくるので1を入力します。
python set_parameters.py
>What number is this place to set RaspberryPi and cam (Allowed values are 1, 2, 3 or 4): 1
次にProject名を入力します。
>Input project name e.g., room name such as 'MyLiving': MyLiving
全部で何台のラズパイを設置するか入力します。先の図の例に沿って4台とします。
>Input number of places you need to watch over (less than 4): 4
ラズパイの台数分、モノの名前とラズパイに接続するセンサーのタイプを聞いてきます。
センサータイプは焦電型人感センサーを使う場合は0、反射型障害センサーを使う場合は1を入力します。自分が使っているセンサーは次稿(3)で説明します。
>Input for Place No.1
>Input place name: CatBed1
>Input sensor type if normal close is '0' else normal open is '1': 1
>Input for Place No.2
>Input place name: CatBed2
>Input sensor type if normal close is '0' else normal open is '1': 1
>Input for Place No.3
>Input place name: CatBed3
>Input sensor type if normal close is '0' else normal open is '1': 0
>Input for Place No.4
>Input place name: CatBed4
>Input sensor type if normal close is '0' else normal open is '1': 1
イベント録画のトリガータイプを入力します。センサー(焦電型または反射型)をトリガーにする場合は0、カメラ映像による動体検知をトリガーにする場合は1を入力します。
>Input trigger type if to use sensor is '0' else motion detection is '1': 1
S3Bucket名を入力します。S3Bucket名は全世界のAWS regionでuniqueである必要があるのでProject名-日付等、予め被らなさそうな名前を付けることをお勧めします。
>Input S3 bucket name to upload mp4 files: neko-mimamori
最後にAWSアカウントIDを入力します。アカウントIDは12桁の数字です。IoT policyをResource縛りにする為に使います。
>Input your AWS account Id : ${your AWS account id}
2台目以降のラズパイでの設定
設置するラズパイのみの情報を入力します。以下は4台目のラズパイの入力例です。
python set_parameters.py
>What number is this place to set RaspberryPi and cam (Allowed values are 1, 2, 3 or 4): 4
>Input for Place No.4
>Input place name: CatBed4
>Input sensor type if normal close is '0' else normal open is '1': 1
>Input trigger type if to use sensor is '0' else motion detection is '1': 1
>Input S3 bucket name to upload mp4 files: neko-mimamori
>Input your AWS account Id : ${your AWS account id}
設定ファイルの出力
set_parameters.pyでパラメーターの対話入力が終了すると、バックグラウンドではリソースをdeployする為に必要な2つの設定ファイルが出力されます。
./src/cert/iot_prov_config
全てのラズパイ設定時に出力されます。
ラズパイ環境の構築で、Python code実行に必要な環境変数の元データとしてiot_prov_configからmqtt topic、S3Bucket名、センサータイプ、トリガータイプを参照します。(5)で説明します。
AWSリソースの構築では、aws cliでAWS IoT coreにラズパイを登録、ポリシー設定、証明書ダウンロードする為に必要な元情報としてiot_prov_configからモノの名前とAWSアカウントIDを参照します。(4)で説明します。
THING_NAME=CatBed1
TOPIC_DETECT=CatBed1/count
S3BUCKET=mimamori-20220817
AWS_AccountId=${your AWS account id}
SENSOR_NO=1
PREFIX_IN=Place1
TRIGGER_SELECT=1
./template/template.yaml
1台目のラズパイ設定時のみ出力されます。
AWSリソース構築でモノの登録以外のすべてのリソース構築に使います。template.yamlはAWS Serverless Application Model(SAM)というCloudformationの拡張機能でAWSリソースをbuild/deployする為の設定ファイルになります。
このリポジトリーでは、本稿で説明した最大6個の名前をParametersとして設定することで任意のsam projectがdeploy出来ます。
set_parameters.pyでparameterを入力し終わるとまずtemplate_head.txtが出力されます。ここにはtemplate.yamlの先頭部分に記述されるSAMの定義とパラメーターset_parameters.pyで入力したparametersが記述されます。
AWSTemplateFormatVersion: '2010-09-09'
Transform:
- AWS::Serverless-2016-10-31
- Count
Description: >
SAM Template for Watch-Over-Dashboard-and-Cam deployment
Globals:
Function:
Runtime: python3.9
Timeout: 15
MemorySize: 128
Architectures:
- arm64
####################################
Parameters:
############Customizable############
ProjectName:
Type: String
Default: MyLiving
Place:
Type: String
Default: CatBedNo1,CatBedNo2,CatBedNo3,CatBedNo4
NumPlace:
Type: Number
Default: 4
OrgBucketName:
Type: String
Default: neko-mimamori
NameTag:
Type: String
Default: MyLiving
############# Fixed #############
EventPrefix:
Type: String
Default: 'emr'
#################################
####################################
Resources:
####################################
次にtemplate_dashboard.txtが出力されます。設置されるラズパイの数に応じた表示ダッシュボード(CloudWatch Dashboard)の定義が記述されています。以下はラズパイ1台のみで見守りシステムを構成する場合のyaml定義文になります。4台設置する場合はDashboard4つ分の定義文が格納されます。
CloudWatchDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: MyLivingDashboard
DashboardBody: |
{
"widgets": [
{
"height": 6,
"width": 12,
"y": 0,
"x": 0,
"type": "metric",
"properties": {
"metrics": [
[
"CatBedNo1/count",
"detect_count"
]
],
"view": "timeSeries",
"stacked": false,
"region": "ap-northeast-1",
"title": "CatBedNo1",
"period": 60,
"stat": "Sum"
}
}
]
}
./templateを見ていただくと分かりますが、ParametersとDashborad以外のFixされたyaml部分を予めtemplate_body.txtとして用意しています。
set_parameters.pyを実行するとtemplate_head.txtとtemplate_dashboard.txtを一旦出力し、続いてtemplate_head.txt、template_dashboard.txt、template_body.txtの順に連結してtemplate.yamlを出力します。
SAMとtemplate.yamlは(8)で詳細を説明します。
./template/index.htmlと./template/PlaceX/placeX-x.html
1台目のラズパイ設定時のみ出力されます。
index.htmlは(1)の成果物で紹介したこのpageを表示するhtmlファイルです。
モノの名前=見守りする場所名なので写真の上に場所名のキャプチャーをつけます。ページのサブタイトルにも1つ目の場所と最後の場所をいれます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Place Watching Over Site</title>
<meta name="viewport" content="width=device-width">
<link href="https://fonts.googleapis.com/earlyaccess/nicomoji.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=M+PLUS+Rounded+1c" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header>
<h1>My Place Watching Over Site</h1>
</header>
<section class="information">
<h1>Event records catbed1 to catbed4</h1>
</section>
</div> <div class="box1">
<div class="section2">
<h2>catbed1</h2>
<img src="img/place1.jpg" width="500">
<ol>
<li><a href="Place1/place1-1.html" target="_blank">latest</a></li>
<li><a href="Place1/place1-2.html" target="_blank">1 time ago</a></li>
・
・
・
<li><a href="Place1/place1-12.html" target="_blank">11 times ago</a></li>
</ol>
</div>
</div>
ブラウザで見ると下図の赤線部分をindex.htmlに埋め込んで出力します。
場所の写真の右側に貼ったリンクから録画したmp4ファイルを別タブで表示しますが、別タブ表示用のhtmlファイルにも場所名を埋め込み同時に出力します。
以下は「1番目の場所」に設置するラズパイの「latest」を表示するhtmlファイルとpage外観です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>catbed1</title>
</head>
<body>
<h1>catbed1 latest</h1>
<video src="01.mp4" autoplay muted loop playsinline controls width=1024 height=768></video>
</body>
index.htmlとplaceX-x.htmlは(9)で詳細を説明します。
次回
(3)ラズパイ物理構成とパッケージ導入に続きます。
追記
修正 2022.09.04
- set_parameters.py実行時にモノの名前を反映させたhtmlファイルを自動生成する仕様に変更した部分の解説を追記しました。
- set_parameters.pyの対話入力項目にイベント録画のトリガーを追加した部分の解説を追記しました。
修正 2022.10.25
IoT policyをResourceとtopicで制限した際にAWSアカウントIDの入力項を追加しました。
修正 2022.10.26
set_parameters.pyでCloudWatch Dashboardのyaml定義を出力する仕様に変更した部分の説明を修正しました。