目的
この記事を読んでいる皆さんのオフィスでは、下記のようなことはありませんか。
- 会議室を予約しようとしたらもう埋まっている
- トイレに行ったら個室が満室だった
これを受けて、会議室の数を増やせ!
トイレの数を増やせ!
と不満の声を上げること簡単です。しかし、実際に部屋数を増やそうとするとオフィス改築となるため、中々難しいものがあると思います。予約システムを導入していても、もしカラ予約があった場合に正確な利用実態データは分かりませんよね。
そこで、ドア開閉センサを利用して、実際の利用データを収集しましょう。この記事では、ドア開閉センサの作り方と、収集したドア開閉データを可視化するアプリケーションの構成方法をご紹介します。
(2019/4/16 追記)
TWELITE DIPではなく、TWELITE PALを利用したこちらの記事もご参照ください。
システムの利用イメージ
-
空室確認機能
空室状況をほぼリアルタイム(今回の設定では最大1分の遅延)で確認できるようにします。新幹線のトイレマークのやつを、オフィスにも導入するようなイメージです。
-
過去データ分析機能
過去を遡って利用状況を確認できるように可視化します。オフィス管理者が、今後の空室利用の改善を検討することに向けた機能です。
では、早速作ってみましょう。
アーキテクチャ構成
下図に全体のアーキテクチャ構成を示します。図中の上部がソフトウェア構成で、下部がハードウェア構成です。可視化アプリ・DBは、下図ではクラウド上の仮想マシン(AWS EC2など)に構築する想定としていますが、オンプレミスのサーバ上に構築しても問題ありません。
ソフトウェア構成
-
Raspbian (センサデータ中継器のLinux OS)
- Raspberry Pi標準のLinux OS
- センサデータを受信できて、Pythonを動作できれば他のOSでも可
-
Python (センサデータ中継用スクリプト)
- ここでは、自製スクリプトのmonostick_to_influxdb.pyを利用
- 中継器のOS上で動作し、MONOSTICKの受信データを外部のinfluxDBに転送する
-
InfluxDB (時系列DB)
- センサデータとの相性が良いNoSQL
- 一般的なRDB(PostgreSQLやMySQL等)でもよいか、InfluxDBには下記のような利点がある
- 時系列に最適化された索引(TSI | Time Series Index)が自動生成されるため、時系列分析を高速実行可能。
- スキーマが柔軟。後から列項目を追加する場合でも、テーブル定義の再作成が不要。
- HTTP APIによりデータ参照・更新が可能で、SQLを記述する必要がない。
- 参考: InfluxDBについて最初に知るべき10のこと
-
Grafana (可視化アプリ)
- かっこいいダッシュボードを簡単に作成できる多機能なデータ可視化ツール
- 時系列DBであるInfluxDBとの相性が良い
ハードウェア構成
-
無線ドア開閉センサ
-
モノワイヤレス TWELITE DIP
- センサ入力値をIEEE 802.15.4(Zigbeeの基礎規格)で無線通信する高機能モジュール
-
リードスイッチ
- 磁石式スイッチ。磁石の近接状態によりONまたはOFFになる。
- 3Vコイン電池
- CR2032を利用
-
モノワイヤレス TWELITE DIP
-
中継器
-
Raspberry Pi
- 安価・小型・軽量でかっこいいPC
- いらなくなったノートPC等でも代用可能
-
モノワイヤレス MONOSTICK
- USB接続可能なTWELITE DIPとして利用
- ここでは、ドア開閉センサのTWELITE DIPのデータを受信するために利用
- インターネット接続
- SORACOMを利用すると面白いかもしれないが、今回は有線LANを利用する。
-
Raspberry Pi
ドア開閉センサの作製
この章の内容の大部分について、下記ページを参考にしています。
部品・工具類一覧
ドア開閉センサの作製に必要な部品と工具類を下記に示します。一覧表内のリンク先の製品は一例です。
部品・用具 | 説明 |
---|---|
TWELITE DIP | 無線モジュール |
TWELITE R | TWE-LITE DIPへの設定書き込み用機器。PCとの接続のために、Micro-B USBコネクタも別途必要。 |
リードスイッチ | 磁石式のON/OFFスイッチ |
コイン電池 | 電池ホルダーと、3Vコイン電池(CR2032) |
抵抗器 | 大きな抵抗値の抵抗(1MΩ抵抗など)。省電力性の考慮のため、TWELITE DIPに外部プルアップ回路を組み込む場合は必要。 |
はんだ付け基盤・用具 | ユニバーサル基盤、28ピンのICソケット(TWE-LITE DIP取付用)、はんだごて、こて台、はんだ、ワイヤストリッパ、ニッパ、線材など |
回路検証用の部品 | ブレッドボード、ジャンパーコード、LEDなど |
プラケース | 丁度いい大きさのかっこいいプラスチックケース(なかなかいいのが見つからない...) |
センサを固定するもの | 今回は両面テープを利用 |
TWELITE DIPの設定
IEEE 802.15.4規格の無線モジュールであるTWE-Lite DIPの設定を行います。
TWELITE DIPには複数のアプリ(ファームウェア)が用意されていますが、今回は標準インストールの「TWELITE標準アプリ」を利用します。TWELITE標準アプリを利用する場合は、基本的にはTWE-Lite DIPへのファームウェアの書き込み作業は不要です。
- その他のアプリ
より省電力性に優れた「無線タグアプリ」もあり、実機で色々と触ってみたのですが...。定期的にデータ送信するオプション設定ができなくて、公式ファームウェアに手を加えるほどの元気もなく諦めました。今後のアップデート等でできるようになったりしないかな。
TWELITE Rの利用
- TWELITE Rを下記ページの写真ように接続します。
- 接続の向きに注意
- 逆向きに取り付けると、回路がショート(?)してTWE-LITE DIP側の回路が大きく発熱します。私は一度やらかして壊しました。
- MONOWIRELESSのロゴを見ながら、上下の向きが合うように取り付けるのがコツだと思いました。
TeraTermを利用した設定
TWE-LITE DIPを接続したTWELITE Rに、別に用意したマイクロUSBケーブルを差してPCにUSB接続します。
PCにはTeraTermをインストールして、TWE-LITE DIPに接続して設定します。
-
TeraTermの設定
- ボーレートを115200 bpsに設定します(デフォルトでは異なる値のため変更が必要)
- Teratermのメニューバー > 設定 > シリアルポート > ボーレート を115200に変更
- パリティ なし, データビット 8bit, ストップビット 1bit, フロー制御 なし
-
インタラクティブモード(設定画面)に入る
- TeraTerm上で「+」キーを3回押下すると、設定画面に入れる。
- 入れない場合、ボーレート設定やTWE-LITEのインストールアプリを確認する。
-
アプリケーションIDの設定
- アプリケーションIDはTWE-LITEの設定項目の一つ。TWE-LITEでは、この値が同一のTWE-LITEモジュール同士でしか通信できない。
- 設定する際は、0x00010001 - 0x7FFFFFFE の中から任意の値を選ぶ。
-
論理デバイスIDの設定
- 今回は、可視化アプリ側での無線モジュールの識別にTWE-LITE DIPのシリアル番号を利用する予定のため、論理デバイスIDは設定不要。
-
データ送信間隔の設定
- データ送信間隔を10秒以上に設定するには、mode7の子機間欠モードを利用する。
- データ送信間隔を長く設定することで、省電力性が向上する。
-
オプションビットの設定
- もし、省電力性の観点(後述)から内部プルアップを停止する場合は
00000800
を設定する。 - 今回は試作のため、内部プルアップをそのまま利用し、オプションビットは使用しない。
- もし、省電力性の観点(後述)から内部プルアップを停止する場合は
-
最終設定画面
下記は、アプリケーションIDを0x11aaa000
、データ送信間隔を60秒(1分)に設定する例です。
--- CONFIG/MONO WIRELESS TWELITE APP V1-08-2/SID=0x8102****/LID=0x78 ---
a: set Application ID (0x11aaa000)*
i: set Device ID (--)
c: set Channels (18)
x: set Tx Power (03)
t: set mode4 sleep dur (1000ms)
y: set mode7 sleep dur (60s)*
f: set mode3 fps (32)
z: set PWM HZ (1000,1000,1000,1000)
o: set Option Bits (0x00000000)
b: set UART baud (38400)
p: set UART parity (N)
---
S: save Configuration
R: reset to Defaults
以上で、TWE-LITE DIPの設定は完了です。
回路作成とはんだ付け
ドア開閉センサの回路を作成し、基盤にはんだ付けして固定します。
回路の確認
まずは回路を確認します。TWELITE標準アプリのピン配置表は下図のようになっています。
今回は下記のピン番号を接続します。
説明 | 信号名 | ピン | 接続先 |
---|---|---|---|
電源 | VCC | 28 | HIGH |
電源グランド | GND | 14 (1でも可) | LOW |
モード設定ビット1 | M1 | 13 | LOW |
モード設定ビット2 | M2 | 26 | LOW |
モード設定ビット3 | M3 | 27 | LOW |
デジタル入力1 | D1 | 15 | LOW(リードスイッチ) |
はんだ付けする前に、ブレッドボード等で回路が正しいかを確認してください。
はんだ付けの例
はんだ付けの結果を晒します。左図は部品面(表面)、右図は回路面(裏面)の左右反転したものです。
はんだブリッジをさせている箇所がありいい加減ですが、とりあえずこれで動きました。こうして作成したドア開閉センサを、両面テープ等でドアに取り付けます。剥き出しの基盤が気になる場合は、プラケースに入れるなどしてなんとかします。
中継器の準備
センサの通信を受信して、HTTPでDBサーバに送信する中継器を準備します。
具体的には、主にRaspBerry PiとMONOSTICKの設定を行い、Pythonスクリプトを実行して疎通確認します。
部品一覧
中継器として準備する部品を下記に示します。一覧表内のリンク先の製品は一例です。
部品・用具 | 説明 |
---|---|
RaspBerry Pi 一式 | RaspBerry Pi本体の他に、マイクロSDカード、ACアダプタ、RaspBerry Pi専用ケース、KVM(キーボード、モニタ、マウス)が必要。 |
MONOSTICK | TWE-LITE DIPの無線通信を受信するデバイス。設置性の観点から、短いUSB延長ケーブルもあるといいかも。 |
外部接続回線 | DBサーバにHTTP接続するための回線。 |
RaspBerry Piの利用
RaspBian Lite OSをインストールします。また、RaspBian LiteにはデフォルトではPython2しかインストールされていないので、Python3をインストールします。設定方法については、外部リンクに丸投げします。
MONOSTICKの設定
TWELITE DIPと同様に、TeraTermからインタラクティブモードに入って設定し、アプリケーションIDをTWELITE DIPと同一値にします。MONOSTICKにはUSB端子が付いているため、設定のためにTWELITE Rを利用する必要はありません。
- 最終設定画面
--- CONFIG/MONO WIRELESS TWELITE APP V1-08-2/SID=0x810e****/LID=0x00 ---
a: set Application ID (0x11aaa000)*
i: set Device ID (121=0x79)
c: set Channels (18)
x: set Tx Power (03)
t: set mode4 sleep dur (1000ms)
y: set mode7 sleep dur (10s)
f: set mode3 fps (32)
z: set PWM HZ (1000,1000,1000,1000)
o: set Option Bits (0x00000020)
b: set UART baud (38400)
p: set UART parity (N)
---
S: save Configuration
R: reset to Defaults
HTTP送信スクリプトの準備
MONOSTICKで受信したセンサデータをHTTPでDBサーバに送信するために、自製Pythonスクリプトを中継器のRaspBian OS上で実行します。このスクリプトを実行した状態で、MONOSTICKがTWELITE DIPからのデータを受け取りHTTP送信に成功すると、下記のように出力されます
> python3 monostick_to_influxdb.py
open serial port: /dev/ttyUSB0
waiting sensor data to receive ...
row binary data : b':7F8115019F810E2A54000002000B431D00004B293A10F320'
source device logical id : 0x7f (127 in decimal)
packet id (generated from app id) : 0x15 (21 in decimal)
source device physical id : 0x810e2a54 (2165189204 in decimal)
Link Quality Indicator (LQI) : 159 (very good) / -42.85 [dbm]
source voltage value : 2883 [mV]
digital input 1 : 0 (off)
digital input 1 change status : 0 (off)
curl -i -XPOST 'http://xxx.xxx.xxx.xxx:8086/write?db=magnetic_door_sensor' --data-binary 'meeting_rooms,logical_device_id=127,packet_id=21,physical_device_id=xxxxxxxxxx LQI=159,mV=2883,is_closed=0,relay_count=0'
HTTP post request for influxDB:
http://xxx.xxx.xxx.xxx:8086/write?db=magnetic_door_sensor --data-binary meeting_rooms,logical_device_id=127,packet_id=21,physical_device_id=xxxxxxxxxx LQI=159,mV=2883,is_closed=0,relay_count=0
HTTP status code: 204 (succeeded)
具体的なデータとしては、主に下記パラメータ値がHTTP送信されます。なお、タイムスタンプ値はデータ登録時にInfluxdbで自動生成されます。
パラメータ | 説明 |
---|---|
is_closed | D1ピンのON/OFF状態。ドア開閉状況を示す |
physical_device_id | TWELITEのシリアルID。センサ識別用に利用 |
LQI | TWELITEの通信品質(詳細) |
mV | 電源電圧(mV単位) |
可視化アプリ・DBサーバの設定
収集したドア開閉データを可視化するDB・アプリを、InfluxDB + Grafanaを利用して準備します。InfluxDBとGrafanaについて、それぞれの設定方法を記載します。
InfluxDB(時系列DB)の設定
センサデータを蓄積するデータベース用に、InfluxDBをインストールします。ここでは、Ubuntu Linux OSにインストールする想定とします。
インストール
公式ドキュメントにOS環境別のインストール手順があります。下記はUbuntu環境でのコマンド実行例です。
# ダウンロードとインストール
user@ubuntu:~$ curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
OK
user@ubuntu:~$ source /etc/lsb-release
user@ubuntu:~$ echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
user@ubuntu:~$ sudo apt-get update && sudo apt-get install influxdb
# 起動
user@ubuntu:~$ sudo systemctl unmask influxdb.service
user@ubuntu:~$ sudo systemctl start influxdb
# 起動確認
user@ubuntu:~$ sudo systemctl status influxdb
influxdbの初期設定
任意の名前のデータベースを事前に作成しておきます。下記はコマンド実行例です。
# influxdbのコンソールを起動
user@ubuntu:~$ influx -precision rfc3339
# センサデータ保持用のDB作成
> CREATE DATABASE magnetic_door_sensor
# DB確認
> show databases
name: databases
name
----
_internal
magnetic_door_sensor
magnetic_door_sensor
という名前のデータベースを作成しました。次に、このデータベースにテストデータを挿入します。INSERT文も利用可能ですが、下記コマンド例ではcurlコマンドを用いて、HTTP API経由でデータを挿入します。
# HTTP APIでinfluxDBにテストデータを挿入。
# curl -i -XPOST 'http://[ホスト名]:[ポート番号]/write?db=[データベース名]' --data-binary '[テーブル名],[検索項目値] [データ値]'
user@ubuntu:~$ curl -i -XPOST 'http://localhost:8086/write?db=magnetic_door_sensor' --data-binary 'meeting_rooms,logical_device_id=127,packet_id=21,physical_device_id=123456789 LQI=159,mV=2883,is_closed=0,relay_count=0'
挿入したテストデータを確認します。下記コマンドでは、SQLのSELECT文を発行して確認しています。
# データベースを指定してinfluxdbのコンソールを起動。
user@ubuntu:~$ influx -precision rfc3339 -database magnetic_door_sensor
# テーブル一覧表示
> show measurements
name: measurements
name
----
meeting_rooms
# テーブルデータ確認
> SELECT * FROM meeting_rooms;
name: meeting_rooms
time LQI is_closed logical_device_id mV packet_id physical_device_id relay_count
---- --- --------- ----------------- -- --------- ------------------ -----------
2018-12-16T16:28:17.05671729Z 159 0 127 2883 21 123456789 0
期待通りのデータが挿入されていて、時刻(time列)も自動生成されていることが確認できます。以上で、InfluxDBの準備は完了です。
Grafana(可視化アプリ)の設定
InfluxDBに保存したデータを可視化して、Webブラウザ上から確認・分析できるようにするためのアプリとしてGrafanaを導入します。Ubuntu Linux OSにインストールする想定とします。
インストール
Grafana公式ドキュメントに手順があります。下記はコマンド実行例です。
# ダウンロードとインストール
user@ubuntu:~$ echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
user@ubuntu:~$ curl https://packages.grafana.com/gpg.key | sudo apt-key add -
user@ubuntu:~$ sudo apt-get update
user@ubuntu:~$ sudo apt-get install grafana
# サービス起動
user@ubuntu:~$ sudo systemctl daemon-reload
user@ubuntu:~$ sudo systemctl start grafana-server
user@ubuntu:~$ sudo systemctl status grafana-server
# 自動起動設定の追加
user@ubuntu:~$ sudo systemctl enable grafana-server.service
Grafanaのパラメータファイルが/etc/grafana/grafana.ini
に生成されているので、設定などを変更する場合はこのファイルを書き換えてGrafanaサービスを再起動します。Grafanaはデフォルト設定では3000番ポートでアクセスできるので、Webブラウザからhttp://[サーバURL]:3000
に接続してGrafanaのログイン画面が表示されればOKです。
デフォルト設定では、ログイン画面の「username/password」に「admin/admin」を入力すると、管理者アカウントでGrafanaにログインできます。なお、もし80番ポートでアクセスしたい場合は、下記コマンドのように、OS側のポートフォワーディング設定を追加するなどします。
# Linux OSのポートフォワーディング設定を追加 (80番 -> 3000番)
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000
InfluxDBとの接続
Grafanaの管理画面から、先ほど設定したInfluxDBをデータソースに追加します。管理画面にログインしたら、ホーム画面のAdd data source
をクリックして、表示される接続先DBの一覧からInfluxDB
を選択すると下記のような設定画面が表示されます。
図中の赤枠の部分を適当に入力します。今回はGrafanaとInfluxDBを同一サーバに同居させているため、URLにはhttp://localhost:8086
を入力し、InfluxDBのデータベース名には以前の手順で作成したDB名のmagnetic_door_sensor
を入力します。最後にSave & Test
をクリックしてData source is working
と画面上に表示されれば、InfluxDBへの接続は無事完了です。
###ダッシュボードの作成
Grafanaの管理画面から、下記の3つのダッシュボードを作成します。ややコツが要りますが、画面上の操作のみでインタラクティブなグラフ表示画面を作成できます。
- 空室確認用ダッシュボード
- リアルタイムのドア開閉状態を確認するための画面
図中の設定項目以外にも、Optionsタブから色々な表示設定ができます。
※この画像では、テーブル名はmeeting_rooms
ではなくdefault_room
に、シリアルID(センサ個体識別用)の列名はphysical_device_id
ではなくEndDeviceId
になっています。なお、図中のシリアルIDは架空の値です。
これで、この記事の最初にあった「システムの利用イメージ」にある図のような画面を見ることができるようになります。
さいごに
本記事で解説した内容を全て繋げて上手く動いたら、システムの完成です。電子工作からDB・アプリまで分野が跨っていますが、身近なテーマだと思いますし、一つ一つの技術自体はそれほど難しいわけではないと思っています。最後に、現状の課題と思っていることについて述べます。
- 省電力性
- 今回は内部プルアップをそのまま利用してドア開閉センサを作成したが、約3か月ほどで電池が切れてしまった。実用のためには、省電力性を考慮した設計のため、例えば外部プルアップ回路を組み込む等の工夫が必要かもしれない。
- プルアップは回路の電圧入力をHighで安定させるための仕組みで、TWELITE DIPの入力ピン(DIO)には内部プルアップ(約50kΩ)がデフォルトで実装されている。このプルアップを利用せずに、より抵抗値が高い抵抗(1MΩなど)で外部的にプルアップ回路を実装すると、センサの省電力性が向上するらしい。
- 内部プルアップは、TWE-LITE DIPのインタラクティブモードのオプションビットの設定で停止できる。
- 運用体制
- 電池切れたら誰が交換するのか。故障等の問題や技術追随の必要性が出た場合に、対応できる人がいるのか。
- 一人ではやりきれないので、真面目にやる場合は運用体制を考える必要がある。
- セキュリティ
- 今回の内容では機微データは一切利用していないはずだが、それでも関係者への説明は難しい。
- ドア開閉のON/OFFデータが漏洩しても、セキュリティ上の問題が発生しないことを説得する必要がある。
- かっこいいケース
- このままではドア開閉センサの基盤が剥き出しなので、見た目が悪い。
- 小さくて設置性と安定性が良いケース等はないかな...。3Dプリンタ等で自作するしかないのかも?
もうちょっと工夫できれば、オフィス内の会議室やトイレ不足は、今後は簡単に把握できるようになるのではと思います。