ラズパイとAWS IoTを使った見守りシステム自作で学んだこと（２）見守りProjectの設計（名前の設定）


[ラズパイとAWS IoTを使った見守りシステム自作で学んだこと（１）概要の説明](https://qiita.com/nsaito9628/items/ff9743e471592f38a463)からの続きです。今回も概要説明の続きになります。

本稿では、この「見守りProject」の設計書を作ります。
大上段で設計と言いましたが大げさなものではなく
* Project
* モノ（ラズパイ）
* 録画したmp4をuploadするS3のBucket

の３種類、最大で６個の名前を決めて、加えてセンサーの1/0のタイプとイベント録画のトリガー方法を確認します。

これらをcliの対話実行でdeployに必要な設定ファイルと映像確認用ページのhtmlファイルを出力します。

以下、若干分かり難い説明になりますが、やることは**最大６個の名前とセンシングのタイプを決めて入力するだけ**です。

## Projectで使う名前を決める

[リポジトリー](https://github.com/nsaito9628/Monitoring-system-with-Raspberry-Pi-and-AWS)のProjectを実装するのに必要なパラメーター（名前）は次の３種類です。
* Project名
* モノの名前（ラズパイの名前）
* S3のBucket名

Defaultでは最小１個、最大４個のラズパイを設定できる仕様になっており、ラズパイを複数設置する場合はラズパイの数だけモノの名前を決める必要があります。

ラズパイ４台設置するプロジェクトでは下図のようになります。ここでは、MyLivingというProjectで4か所のネコbedを見守り、neko-mimamoriというS3Bucketを作るという例になります。
（下図のメモ用シートはリポジトリーの./xlsx/parameters setting.xlsxになります）

<img width= 1200 src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565396/b22cc596-f9fc-43f2-3377-a244143ad47a.png>

## リソース名

次に３種類の名前がリソースのどこに使われるか説明します。

#### ラズパイ
モノの名前：hostnameとして設定しますmqtt topicにも使います。

#### AWSリソース
1. Project名：各リソース名の先頭につけます、何のProjectのリソースなのか明示します。
1. モノの名前：IoT topic、IoT Rule、custom metricsの名前空間に使います。S3にホスティングする映像確認用web page Default originのキャプチャータイトルとタブ名にも使います。
1. S3のBucket名：録画したmp4のupload先、閲覧時のホスティング先にする新規Bucketの名前として使います

#### リソース命名規則
本Projectでは下図のような命名規則に「三種類の名前」を組み込んでリソースを識別します。

<img width= 1200 src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565396/d1e93de7-66ed-1610-613d-4fc78120b38c.png>


## 名前の対話入力

リポジトリーに用意してある./setparameter.pyをcloneしたリポジトリーのroot directoryから実行して[「Projectで使う名前を決める」](https://qiita.com/nsaito9628/items/da402829316549853d0f#project%E3%81%A7%E4%BD%BF%E3%81%86%E5%90%8D%E5%89%8D%E3%82%92%E6%B1%BA%E3%82%81%E3%82%8B)で決めた名前を入力します。

#### 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
```
全部で何台のラズパイを設置するか入力します。先の図の例に沿って４台とします。
```
>Input number of places you need to watch over (less than 4): 4
```
ラズパイの台数分、モノの名前とラズパイに接続するセンサーのタイプを聞いてきます。

センサータイプは焦電型人感センサーを使う場合は0、反射型障害センサーを使う場合は1を入力します。自分が使っているセンサーは[次稿(3)](https://qiita.com/nsaito9628/items/528ab7ccd0a62515463b)で説明します。
```
>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)](https://qiita.com/nsaito9628/items/db43b1e854a3cc95df1a)で説明します。

AWSリソースの構築では、aws cliでAWS IoT coreにラズパイを登録、ポリシー設定、証明書ダウンロードする為に必要な元情報としてiot_prov_configからモノの名前とAWSアカウントIDを参照します。[(4)](https://qiita.com/nsaito9628/items/2ff6ab6d471537270e68)で説明します。

```sh:iot_prov_config
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)](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/what-is-sam.html)という[Cloudformation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html)の拡張機能でAWSリソースをbuild/deployする為の設定ファイルになります。

このリポジトリーでは、本稿で説明した最大6個の名前をParametersとして設定することで任意のsam projectがdeploy出来ます。

set_parameters.pyでparameterを入力し終わるとまずtemplate_head.txtが出力されます。ここにはtemplate.yamlの先頭部分に記述されるSAMの定義とパラメーターset_parameters.pyで入力したparametersが記述されます。

```sh:template_head.txt
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)の定義が記述されています。以下はラズパイ１台のみで見守りシステムを構成する場合のyaml定義文になります。４台設置する場合はDashboard4つ分の定義文が格納されます。

```sh:template_dashboard.txt
  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)](https://qiita.com/nsaito9628/items/312112486ce61ba396ae)で詳細を説明します。

#### ./template/index.htmlと./template/PlaceX/placeX-x.html
1台目のラズパイ設定時のみ出力されます。

index.htmlは[（１）の成果物で紹介したこのpage](https://qiita.com/nsaito9628/items/ff9743e471592f38a463#%E6%98%A0%E5%83%8F%E7%A2%BA%E8%AA%8D%E7%94%A8web-page)を表示するhtmlファイルです。

モノの名前＝見守りする場所名なので写真の上に場所名のキャプチャーをつけます。ページのサブタイトルにも１つ目の場所と最後の場所をいれます。

```html:index.html
<!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に埋め込んで出力します。
<img width= 720 src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565396/7a06ce24-8697-87c1-0a09-bc0eba6d70b4.png>

場所の写真の右側に貼ったリンクから録画したmp4ファイルを別タブで表示しますが、別タブ表示用のhtmlファイルにも場所名を埋め込み同時に出力します。

以下は「１番目の場所」に設置するラズパイの「latest」を表示するhtmlファイルとpage外観です。
```html:./template/Place1/place1-1.html
<!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>
```
<img width= 720 src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565396/cac5730b-dd02-723d-64f4-eec5257abde1.png>

index.htmlとplaceX-x.htmlは[（９）](https://qiita.com/nsaito9628/items/73f8f2b175000db46ec2)で詳細を説明します。

## 次回
[（３）ラズパイ物理構成とパッケージ導入](https://qiita.com/nsaito9628/items/528ab7ccd0a62515463b)に続きます。


## 追記

#### 修正　2022.09.04
[リポジトリー修正箇所の解説を加筆修正しました。](https://github.com/nsaito9628/Monitoring-system-with-Raspberry-Pi-and-AWS/pull/11)
* 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定義を出力する](https://qiita.com/nsaito9628/items/da402829316549853d0f#templatetemplateyaml)仕様に変更した部分の説明を修正しました。