Posted by & filed under diary.


最近、自宅にスマートメーターがつきました。

スマートメーターはBルートサービスと呼ばれるサービスに申し込むことで、Wi-SUN規格の通信で現在の指示数や取得時点の瞬間消費電力を取得することができます。

プロトコルはECHONET Lite。経産省推奨の日本のHEMS機器通信の標準プロトコルです。1

 

折角の機会なので、Bルートサービスに申し込んで、ついでに最近気になっていたESP8266やらAWSやらLINE BOT APIやらあれやこれやを詰め込んでみました。

 

概要

diagram

ざっくりとデータの流れを表してみたのが上の図です。

スマートメーターから取得したセンサ値はMQTT(MQ Telemetry Transport)プロトコルでMQTTブローカーサーバ(CloudMQTT)へ送られ、ブローカー経由でAmazon Kinesis Streamsに接続します。

Kinesisから入ったデータは永続化のためにLambdaによって逐次DynamoDBに突っ込まれます。

 

クライアント(PCブラウザ)は過去データをAmazon API Gateway経由でDynamoDBから取得し、グラフ描画します。また、同時にWebSocket経由でメッセージのSubscribeも行い、リアルタイムにデータを受信してグラフへ反映します。

また、LINE BOT APIのcallbackからも同様に、DynamoDBに突っ込まれている過去センサデータを参照できるようになっています。

 

とりあえずいろいろ詰め込んでみました感がハンパない(笑)

センサノードが数百~数千単位であるならまだしも、今回は1台(しかもデータ送出間隔1分)なので正直Kinesisはオーバースペックですが、使ってみたかったので組み込んでいます。

また、AWSには最近AWS IoTというズバリなサービスができていますが、AWS IoTは機器認証の為にTLSv1.2が必須であり、今回使用するマイコンモジュールESP8266では対応してなかったため、今回は使用していません。2

 

センサボード

ESP-WROOM-02スマートメータとMQTTブローカをつなぐGWの役割を果たすセンサボードはブレッドボード上で適当に自作しました.

コアには今回使ってみたかったものの一つ,ESP8266(ESP-WROOM-02)を使用しています.いつぞやかKickstarterで買ったOnion Omegaが日の目を見るタイミングかとも思ったのですが,後述のWi-SUNモジュール(BP35A1)と通信するためのUARTポートを引っ張りだすのが大変だったため諦めました.

 

主要な構成部品は以下.

  • ESP8266 (ESP-WROOM-02) – WiFiモジュール
  • BP35A1 – Wi-SUN通信モジュール
  • AM2320 – 温湿度センサ(オマケ)

あとはEPS8266とBP35A1は3.3V駆動なので,5Vから3.3Vを作っているぐらいで特に難しいことはやってません(できない).

 

EPS8266 (ESP-WROOM-02)

技適マーク付きのWiFiモジュールで,Arduinoと同じようにコーディングできるので非常に使い勝手よいです.しかも安い!

たった1000円でWiFiでネットに繋がるマイコンモジュールが手に入るようになるとは…

[データシート]

 

BP35A1

Wi-SUN対応の920MHz帯無線モジュールです.これ自体に32bitマイコンが搭載されており,物理層,データリンク層(IEEE802.15.4g/e)だけでなく,TCP/IP喋ったりPANAで認証するところまで面倒を見てくれます.開発者はアプリケーションレイヤしか気にする必要はなく,UART経由でMCUに命令を渡し,後はおまかせ.ただ,それ故にちょっと値が張ります.

これ単体だとブレッドボード上で使用できないので,純正の2.54mmピッチ変換基盤(BP35A7A)を咬ませています.

[データシート]

 

AM2320

これ一つで温度と湿度が計測できる,温湿度センサです.秋月で600円.I2Cで値を取得します.取得するのが電力だけなのも寂しいので(?)くっつけてみました.

[データシート]

 

ECHONET Lite

通信規格は以下で無償公開されており,誰にでも閲覧できます.

ECHONET Lite規格書 Ver.1.12(日本語版)

今回やりたいことは第2部を読めばだいたい内容が書いてあります.

ECHONET Liteでは接続機器の種類によって参照できるプロパティについても規定されており,それらは以下のドキュメントで調べることができ,スマートメータについては「3.3.25 低圧スマート電力量メータクラス規定」に記載があります,

APPENDIX ECHONET機器オブジェクト詳細規定

いろんなオブジェクトが規定されていて,眺めていると結構夢が広がる.(この規格が普及すれば,だが…)

 

スケッチ

基本的には先人さんのコードを流用させていただいています.

スマートメーターからリアルタイムに消費電力を取得する – Okiraku Programming

ただし,ESP8266向けに以下のあたりを変更しています.

  • BP35A1との通信はSoftwareSerialではなく,Serial (HardwareSerial) を使用するように変更
  • SerialをBP35A1で使ってしまうので,デバッグ出力をSerial1 に変更
  • setup() で電源投入時のままBP35A1と通信しようとすると,なぜか ER09(UART 入力エラーが発生した)が帰ってきてしまうため,初回通信前にBP35A1のRESETポートをGNDに落としてリセットをかけるように変更
  • たまにSerial.read()でノイズを受信してしまい,読み込み待ちで15分ぐらい使ってしまう時があったのでタイムアウト処理周りを書き換え

また,流用元は7seg出力でしたが,今回はMQTTブローカーへPublishするのでその辺りも書き換えています.

 

データ伝送・処理部

消費電力(や温湿度)が取得できたらそれを他のクライアントからアクセスできるようにPublishしてやります.プロトコルはIBM発のMQTT.Pub/Subに必要なブローカーサーバーにはCloudMQTTを使用します.

 

MQTT (MQ Telemetry Transport)

日本語版Wikipediaだと何故かMessage Queue Telemetry Transportの略と書かれていますが,Queueの機能はついていないためおそらく誤りで,英語版Wikipediaだとそのような記載はありません.

IBM WebSphere MQ(IBM MQ)のプロダクトラインの1つとして開発されたのが始まりらしい.

Historically, the ‘MQ’ in ‘MQTT’ came from IBM’s MQ message queuing product line. However, queuing per se is not required to be supported as a standard feature in all situations.

IBM謹製だからか,この手のプロトコルには珍しく日本語の公式仕様書が提供されているのも特徴で,とっつきやすい.

MQ Telemetry Transport (MQTT) V3.1 プロトコル仕様

 

CloudMQTT

MQTTブローカーサーバのSaaSの一つ.無料で,遊ぶ分には十分な機能を利用できます.

日本発のMQTTブローカーサーバサービスとして「sango」がありますが,こちらは無料アカウントでは平文でしか利用できなかったため利用せず.

Amazon Kinesisとの連携機能があり,Kinesis書込可のロールを付与したIAMアカウントをWebコンソールから登録するだけで,受信したメッセージをそのままKinesisに横流ししてくれます.(もちろん無料)

 

Amazon Kinesis Streams

ストリーミングデータを扱うためのAWSサービスで,複数ソースから送られてくるストリーミングデータを順序性を担保した状態でまとめてキューイング,読み出しできます.

処理性能はシャードと呼ばれる単位で制御することが可能ですが,1シャードあたりの処理性能は,書込1MB/sec,読込2MB/sec,1,000 PUT req/secとなっており,今回の用途としては明らかにオーバースペックです(笑)

何しろソースは1つしかなく,そもそもCloudMQTTの無料アカウントでは,スループットが10 Kbit/sに制限されています.

 

Kinesisで受信したデータをDynamoDBに突っ込むLambdaコードは以下.Kinesis用のblueprintにDynamoDBへ挿入するコードを追加しただけです.

 

クライアント(グラフ出力)

graph viewメインどころでもないので頑張らず,D3.jsのプラグインであるC3.jsを使って出しているだけです.

気が向いたらCubism.js版も作ってみたい.

document.load 時にAPI Gateway経由で直近のデータを取得してプロット,同時にWebSocketでCloudMQTTに接続して最新データを受信する都度挿入していく作りです.

 

DynamoDBから過去データを読みだして返すLambdaコードは以下.

引数として limit ぐらいは取るべきなんだろうけど,とりあえず動けば良いので全データ垂れ流し状態です.

 

LINE BOT API

もりだくさん過ぎたため,別記事で…(書くかどうか微妙)

  1. 研究で触っていたので懐かしい… []
  2. 消費電力を気にするようなセンサモジュールは何かしらGWを介してデータを送るしかなさそう? []