M5 Stick C+を使用して可視化してみた 〜インフラ構築編 (Macbook)〜

# はじめに
照度センサーを使用して、光が当たっている時間を測定するIoT機器を作成しようと思います。
用途としては、部屋の電気がどのくらい使われているのかを実測したり、製造設備の[シグナルタワー(積層信号灯)](https://www.patlite.co.jp/product/detail0000000700.html)の点灯状態を取得したりする等を想定しております。

## 本記事の概要
IoTシステム作成のためには、二つの入れ物が必要になります。
1. 値に保管して、各ユーザが内容を取り出すための入れ物であるDatabaseです。
1. データベースに入れる前に、センサーデータをプールしておくための入れ物であるMQTT Brokerです。

本記事では、IoTプログラムを作成する前に、この二つの準備を行うための手順を記載しようと思います。
ここで注意ですが、【まずはさくっと作ってみる】という趣旨なので深い部分(特にセキュリティに関わる内容)は盛り込みません。この部分はご注意ください。

## 想定読者
- IoTをやってみたいと思っているがインフラ関係の知識がない方

## 検証した環境
- Macbook Pro (Apple Silicon)
- Homebrew
- PostgreSQL 14
- Mosquitto


# データベース構築
PostgreSQLを使用します。PostgreSQLはフリーのRDBMS (Relational DataBase Management System)です。RDBMSは簡単にいうとデータベースを管理するソフトです。このソフトの中でDatabaseを作成します。
ただ、Databaseの話になる前に一度どんなものを作った方がよいかの確認をしようと思います。

## テーブル設計 (どんな情報を送りたいか)
データベースに入れたい内容を考えてみましょう。データベースに期待することは、**時系列で照度センサーの生のセンサー値を格納する**ことですが、それ以外にも重要なものは存在します。それぞれどういったものが必要であるかを洗い出しましょう。

### センサー値について
今回使用するセンサーは、[M5Stack用光センサユニット [U021]](https://shop.m5stack.com/products/light-sensor-unit)を使用します。

https://shop.m5stack.com/products/light-sensor-unit

この中にフォトレジスターが内蔵されており、その信号をLM393(Dual Differential Comparators)で増幅しています。ただ、LM393を[テキサスインスツルメンツさんの資料](https://www.ti.com/jp/lit/ds/symlink/lm393.pdf)で確認してみたのですが、アウトプットに関する内容を理解できませんでした... 結果だけを見ると0〜4000程度のレンジの自然数が返ってきていました。
以上より、**センサー値は整数型で最大5000までを格納可能**にします。
なお、大きい値の場合は照度が低く、小さい値の場合は照度が高くなっています。


### 日時について
データがいつ取得したものか分かるように日時を格納したいです。どのくらいの粒度というと、計測する時間間隔に依存します。今回は1分間ごとの計測ですので、測定時刻の秒単位が取得できれば大丈夫です。
以上より、**日時を秒レベルで取得する**ことにします。


### 場所について
場所を表すにはいろいろなパターンが考えられます。一つは名前であったり、緯度経度のような座標データであったり、住所であったり。また、これらを別の箇所(テーブル)に入れて参照する形式も考えられます。今回は、リビングだったりキッチンという名前で設定します。今回の用途では30文字もあれば十分足りると思うので、最大30文字とします。
以上より、**場所はテキスト型のデータを格納する**ことにします。


## Databaseインストール
Homebrewを使用してPostgreSQLをインストールします。
まずはHomebrewがインストールされていることを確認します。(brewコマンドが使えること)
インストールされていない方は下記コマンドでインストールしてください。([公式ページ参照](https://brew.sh/ja/) )
```bash
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
% (echo; echo 'eval "$(opt/homebrew/bin/brew shellenv"') >> /Users/mio/.zprofile
```

次にPostgreSQLのインストールをします。下記コマンドを入力してください。
```zsh
% brew install postgresql@14
```
記憶なくてすいませんが、続けてDBの初期化が必要と言われたら下記を入力してください。
・・・先日のMacbook購入での初期設定で操作後スクショを撮ったのですが、自動でやってくれていたようなターミナルの出力がありましたので多分不要と思います。ちなみに、ソースで入れた場合はこの作業必須です。
```zsh
% initdb --locale=C -E UTF-8 /opt/homebrew/var/postgresql@14
```
なお、初期化されている場合に上記を入力しても、エラーが返ってくるだけなので問題なかったと思います。過去に間違ってやってしまったら、ディレクトリ内が空ではないので初期化できません、とエラーが出た記憶があります。(この部分も曖昧ですいません)

バージョン指定しましたが、今回の内容では特殊なことを行っていないので14より新しければ問題ないです。


## データベース作成
下記コマンドでDatabaseを作成します。名前は【iot_db】とします。
```zsh
% createdb -U (macのユーザ名) --encoding=UTF-8 --locale=ja_JP.UTF-8 --template=template0 iot_db
```

## テーブル作成
先程決めたデータの内容を使用してテーブルを作成します。
テーブルというのはエクセルのシートのようなものです。Databaseのテーブルは、エクセルと異なり、それぞれのテーブルで参照しあったり、結合したりできます。ただし、今回の内容ではそのような構造を入れてはおりません。

まずはターミナルからSQLというデータベース用のプログラミング言語が入力できる環境に移動します。下記コマンドを入力してください。

```zsh
% psql -U (macのユーザ名) -d iot_db
```
ここでエラーになる場合は、psqlというコマンドのパスが通っていない可能性がありますので、パスを確認してください。

次に環境の移動が終了したら、下記コマンドを入力してください。エラーが出なければテーブルが作成されているはずです。

```sql
> CREATE TABLE IF NOT EXISTS
  signal_light_table
  (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    location VARCHAR(30),
    sensor_value INTEGER,
    create_timestamp TIMESTAMP
  )
;
```

テーブルが作成されたことを下記のコマンドで確認してみましょう。
```sql
> \dl
```

以上でセンサーデータを格納する入れ物であるデータベースの設定が終わりました。
長かったですね、お疲れ様です。


# MQTT Broker構築
ここではMQTT Brokerをインストールし、設定します。MQTT Brokerも複数あるようですが、ここでは[Eclipse Mosquitto](https://mosquitto.org/)を使用します。

## MQTT Brokerとは

### MQTTとは
MQTTとは、通信プロトコルの一つです。通信プロトコルとして有名なものはHTTPやHTTPSがあります。
MQTTの特徴は軽量であることです。他のプロトコルに比べて送信データが小さくなります。これによって通信料の削減ができるというものです。

## MQTT Brokerのインストール
ここでもHomebrewを使用します。下記コマンドを入力してください。
```bash
% brew install mosquitto
```
## 設定ファイル
インストールが終了すると設定ファイルが作成されます。【/opt/homebrew/etc/mosquitto/mosquitto.conf】にあるので、こちらを任意のエディタで編集します。
次の3つの設定が存在すれば使用可能です。私はコメントアウトと追記で有効化しました。
```
listener 1883
allow_anonymous true
max_queued_messages 1000
```
繰り返しになりますが、今回はセキュリティを気にせずに設定しているのでこのまま本番環境適用は危険です。ご注意ください。
![設定ファイル編集1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/4b76f881-4897-37f3-65bd-780de1bb9c18.png)
![設定ファイル編集2.5_設定間違い.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/9c138613-9059-2af9-c660-41818279debe.png)
![設定ファイル編集3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/664aa18e-ab7d-7612-a1bd-16329b17d1b7.png)


## 起動
設定ファイルを書き終えたらサービスとして起動します。
```zsh
% brew services start mosquitto
```

## 疎通テスト
ターミナルを二つ起動します。
片側のターミナル(下記グラフでは右側)で下記のコマンドを入力しておきます。
```zsh
% mosquitto_sub -t test
```

もう片方のターミナル(下記グラフでは左側)で下記のコマンドを入力します。
```zsh
% mosquitto_pub -t test -m Hello_World
```

はじめのターミナルで、【Hello_World】と表示されたら成功です。

![pub-subテスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671049/2ac2741a-97f2-bf95-6ea4-1938800a12ac.png)



# 参考資料
## PostgreSQL
- [Homebrew HP内のPostgreSQLページ](https://formulae.brew.sh/formula/postgresql@14)
- [公式 ソースコードからのインストール手順](https://www.postgresql.jp/document/14/html/installation.html)
- [Let's Postgres](https://lets.postgresql.jp/map/install)
- [PostgreSQL独自コマンドおよびSQLについて](https://www.postgresql.jp/document/14/html/reference.html)
## Mosquitto
- [Eclipse Mosquitto公式ページ](https://mosquitto.org/)
- [AWSのMQTT解説記事](https://aws.amazon.com/jp/what-is/mqtt/)
- [IBMのMQTT解説記事](https://www.ibm.com/docs/ja/ibm-mq/8.0?topic=telemetry-mqtt-protocol)

# 最後に
PostgreSQLとMosquittoというIoTで使用する基本の道具を準備することができました。次回は実際にデータを貯めて表示を行います。
なお、今回は検証用にまずは入れてみる、という趣旨のものです。この2つには数々の設定があります。パフォーマンスやセキュリティに関わるものもありますので、ある程度学習が進んだ後に公式マニュアル等を用いて学習し直すことをおすすめします。