研究室の在室ボードを電子ペーパーで作ってみた

:::note info
※この記事は書きかけです。随時更新していきます。
:::

# 作ったもの
研究室の在室ボードの代わりに、こんなものを作ってみました。
表示は、5分ごとに切り替わります。

![6b7uWAzR6wn5riFM_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/159d7246-6aff-4802-9bed-cd7a83ec67a3.gif)



# 開発背景
　以前より、在室ボードはマグネットを使って手動で在室かどうかを表す方式をとっていました。下図のような表を印刷してドアに貼り付け、その上にマグネットを置くことで自分の在室状況を示す仕組みです。手軽に在室状況を把握できるので、多くの研究室で一般的かと思います。
 
 <img width="500" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/f0a19477-c3ed-3af7-821c-7b3cb276319d.jpeg">
 
　しかしながら，在室状況を変更するのを忘れてしまうことが頻発し，あまり役立たなくなってしまいました．そこで、自動で在室と不在が切り替わるような在室ボードの作成に至りました。

# 仕組み
　仕組みは至って単純で、Pingによる死活監視を使って在室状況を判断しています。
 
 ![システム概略図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/6a866b1b-eac4-74f1-68eb-c437ee07a0aa.png)
 
研究室内には、学生が自由に使えるWi-Fi環境が整っており、そのWi-Fiに学生のスマートフォンが接続されると、`Ping`が通るようになります．従って，WiFi圏外（研究室外）になれば当然Pingは通らなくなりますし，圏内になれば通るようになります．

この仕組みを使って、定期的に`Raspberry Pi`から予め指定された`IPアドレス`に対して`Ping`を送信、`Ping`が返ってきたら、`在室`、そうでなければ`不在`と判断するという仕掛けになっています。



## 外出と不在
　`Pingが通らない（不在と判断されるべき）`とき、すぐには`不在`とは表示されず、`外出`になるような工夫をしています。研究室の学生は、講義や図書館、お手洗いなどで一時的に不在になることもあるわけですから、すぐに帰宅になってしまうと困ります。
 
　そこで、在室確認時に直近の在室状況を`SQLite`を使って記録するとともに、書き換えの際は、過去のデータを参照して、不在の時間が一定以上の場合は、`帰宅`に変更するようにしています。

## 書き込みをしない判断
　これらの仕組みを備えたコードを定期実行するだけでも、在室ボードとしては十分な役割を果たします
 。しかしこのままでは、在室状況が前回の実行時と在室状況の変化がなく、書き換えの必要がなくても書き換え処理が行われてしまいます。
 　今回のシステムでは、在室状況の表示に電子ペーパーを使っているので、（消費電力や描画速度の観点からも）極力表示の書き換えは避けたいところです。
そこで、書き換えの必要があるときだけ、書き換えを行い、そうでなければ、書き換えを行わなない、という処理を加えてあります。

# 電子ペーパーと液晶ディスプレイの比較
電子ペーパーと液晶ディスプレイの違いを以下にまとめました。
||電子ペーパー|液晶ディスプレイ|
|---|:---:|:---------:|
|表示速度|遅い（最速でも1fps以下）|速い（60fps）|
|表示色|3色[^1]|$256^{3}$色以上|
|消費電力|小さい（書き換え時に消費）|大きい（常に消費）|
[^1]: 今回用いた電子ペーパーの例

電子ペーパーは液晶ディスプレイに比べ、表示色、表示速度の面で大きく引けをとっています。しかし、画面の書き換え時しか、電力を消費しないという面は大変魅力的です。

今回は、設置場所の都合上、コンセントから直接電源を取れる環境になく、バッテリーを電源に使用することになります。このような状況下では、消費電力が少ない電子ペーパーの方が使い勝手が良いので、こちらを使用することにしました。

また、電子ペーパーは「画面が書き換わる感じがしない（印刷物みたい）」な見た目が印象的です。

# コード
下記のGithubにコードを載せています。

## セットアップ
コードをダウンロードした後は，以下の作業が必要になります．

### ① 動作に必要なファイルのダウンロード
このソースコードの動作には，Githubに上がっているものに加え，waveshare社公式の電子ペーパーライブラリと，日本語フォントファイルの追加ダウンロードが必要になります．

Githubにこれらのファイルをそのまま上げても良いかと思ったのですが，再配布に該当するため（ライセンスを確認していないため），ご自身でのダウンロードをお願いいたします．

動作に必要なファイルは以下にリンクを貼っておきますので，ダウンロードしたファイルをGithubリポジトリの直下においてください．


### ② ``config.yaml``ファイルの書き換え
 在室ボードに表示する名前および，それに対応したIPアドレスを指定する必要があります．
 ``config.yaml``を開き，サンプルファイルに倣って編集してください．

#### 各項目の説明
|変数|説明|
|----|----|
|name|在室ボードに表示する名前|
|ip  |在室状況を確認するターゲットのIPアドレス|
|lookbackDuration|何分間の不在まで退出中と表示するかを決める変数|
|offset|表示する表の全体的なオフセット|
|scale| 在室状況の表示サイズ|

### ③ cronを用いた定期実行
cronを用いて定期実行を行う設定を行います。
以下のコマンドを打ち込み、cronの編集ファイルを開いてください

```cronの編集.bash
crontab -e
```
開いたら、以下のテキストを追記してください。

```
 python [StatusBoardディレクトリの絶対パス]/main.py
```

これで5分おきに``main.py``が実行され、Ping疎通が行われるようになりました。

### ④　ボックスの表示位置を変更する（オプション）
人数が多い（少ない）場合、一人一人の在室状況の表示の大きさを変更したいという場合もあるかと思います。現在のプログラムでは、大きさに合わせて表示位置等を自動変更する機能はないので、そのへんは自分でやってください。

#### 大きさの変更
大きさを変更する場合は、**``config.yaml``を開き、``scale``の値を変更**してください。
``1``がデフォルトで、それ以上値を大きくすれば、表示サイズは大きくなりますし、小さくすればその分小さくなります。

#### 表示位置の調整
``main.py``を開き、126行目を参照すると以下のようになっているはずです。

```main.py
# テーブルの作成
canvas.create(list(DisplayContent.items())[:5], (config['offset']['x'],config['offset']['y']))
canvas.create(list(DisplayContent.items())[5:], (config['offset']['x']+380,config['offset']['y']))
```

この2行でE-paperに表示するデータを描画しています。

はじめの1行で表示列の左側を、次の2行で表示列の右側を表示しているのですが、この``DisplayContent``の第一引数で渡している配列の長さを変更すると，一列に表示する在室状況の数が変わります．

従って例えば，10人分の在室状況を6人と4人の2列で表示したい場合，次のようにします．
```main.py
canvas.create(list(DisplayContent.items())[:6], (config['offset']['x'],config['offset']['y']))
canvas.create(list(DisplayContent.items())[:4], (config['offset']['x']+380,config['offset']['y']))
```

# 余談
以前の手動の在室ボードに代わり、今回制作した電子ペーパーを使ったことで、狙い通り在室状況の変更し忘れはなくなり、研究室の人々は在室ボードを変更する手間がなくなりました。

しかし、iPhone等の一部の機種ではスリープにしておくと勝手に``Ping``を受けつけなくなる仕様の端末もあるようで、そうした端末では研究室のWi-Fiに接続されているはずなのにPingが通らず在室にならないといった事象も見られました。

仕様と言われてしまえば、これはもうどうすることもできませんし、Ping疎通で在室確認するシステム自体を大きく変えなければこの問題は解決しそうにないので、無視することに。

また今回は、電子ペーパーの低消費電力仕様を活かした、モバイルバッテリー駆動にするはずでした。がしかし、Raspberry Piの電力消費量が予想以上よりも大きく、モバイルバッテリーが1日持たないということが判明し、結局コンセントから電気を供給する仕様になりましたとさ。