自宅状況の見える化（M5Stack版）

# はじめに
- 2年ほど前に、[自宅状況の見える化](https://qiita.com/katsumin/items/b11da555daa506800933)という記事を投稿しています。
- 当該記事はRaspberryPi（実際は[NanoPi](http://nanopi.io/nanopi-neo2.html)を使用）ベースだったのですが、今年の１０連休を利用（完成はしなかったんですが）してM5Stackベースで作り直したので、そのご紹介記事となります。

---
# 装置の外観
![view.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166435/8a4b21b1-3fce-7ff5-938c-27b8516435b5.jpeg)

- 表示内容
    - IPアドレス（左上）
    - 現在日時（右上）
    - 上から順に
        - BME280センサーから取得した室温、湿度、気圧
        - スマートメーターから取得した瞬時電力、積算電力量（正方向、負方向）
        - エコキュートから取得した消費電力、タンク残量
        - ダイキンエアコンから取得した消費電力、室温、外気温

---
# M5Stack化のメリット・デメリット
- メリット
    - QVGAディスプレイによる視認が可能。
        - NanoPiには表示機能がない。
    - 電源ON/OFFのストレスがない。
        - NanoPiの場合、電源OFFの前にssh接続＆シャットダウンを行う必要がある。
- デメリット
    - Pythonに比べて、お手軽さがない。（MicroPythonというものがあるようですが、試したことがありません。）
    - Linuxによるマルチプロセスを期待できないので、一つのプログラム内で作り込む必要がある。
    - Linuxコマンドが使えない。（curlコマンドなど）

---
# プログラムソース、回路図など
- GitHub([HomeM5](https://github.com/katsumin/HomeM5))で公開しています。

---
# 機能説明
1. スマートメーター通信
    - 状態遷移
　　　　[![alt](http://www.plantuml.com/plantuml/png/TPB1IW917CRlynJB7WDVe4DuwL2GGdIB3k8kiP4ZkEjTTr2tahGEIXQLbDOX0n74RD67-JkpUl8LsjbfcytiiWpCx_j_t__RYPjMAcVbCwV8FrYwebAdmXezxtp8IXUgaZ8LpJ3JMOprjALh8GJs1zWz84z01hDHB-3CT0fZ0n-73BliUCCMhNIzUZbalWVzeI9s9ra32oEP1km1a7iW_lTiKIZEfkq0jVHSni0-Xz3Xnf4IoyMsVgLLDXLrSVl9nlLaGaNH6y66YJctczn90Ba3U-hRgEZdAhR2ySrv51U80wJD3rpYCbAYZtrQQz19CohNVBtSca-8alIzEXkNLII9m51qm65HZy0MXPRtq07x6SXDq8L3QqtU1U9yk9JKpbyTDde3KX4XbsxjVostbNrojMX-tYsolhrE9-7LYfRkbVToJITLEJo_viySRE_lHHgFwrZpd-4N)](http://www.plantuml.com/plantuml/png/TPB1IW917CRlynJB7WDVe4DuwL2GGdIB3k8kiP4ZkEjTTr2tahGEIXQLbDOX0n74RD67-JkpUl8LsjbfcytiiWpCx_j_t__RYPjMAcVbCwV8FrYwebAdmXezxtp8IXUgaZ8LpJ3JMOprjALh8GJs1zWz84z01hDHB-3CT0fZ0n-73BliUCCMhNIzUZbalWVzeI9s9ra32oEP1km1a7iW_lTiKIZEfkq0jVHSni0-Xz3Xnf4IoyMsVgLLDXLrSVl9nlLaGaNH6y66YJctczn90Ba3U-hRgEZdAhR2ySrv51U80wJD3rpYCbAYZtrQQz19CohNVBtSca-8alIzEXkNLII9m51qm65HZy0MXPRtq07x6SXDq8L3QqtU1U9yk9JKpbyTDde3KX4XbsxjVostbNrojMX-tYsolhrE9-7LYfRkbVToJITLEJo_viySRE_lHHgFwrZpd-4N)
    - 接続状態の動作
        - 約~~１０ms~~1msごとにスマートメーターからの受信がないかポーリングする。
            - EVENT２５受信の取りこぼしは、インターバルが長過ぎた（10msで100byteを超えるデータが受信バッファに溜まってしまう）ためと思われ、修正。（2019/6/23）
            - さらに、HardSerialの受信バッファサイズ（デフォルト256byte）を2048byteに拡張。（2019/6/23）

                ```cpp
  Serial2.setRxBufferSize(2048);
```

        - 受信電文により、処理を振り分ける。
            - データ受信（取得コマンド応答の瞬時電力値、３０分毎にスマートメーターから送られてくる積算電力量値）
            - イベント受信（EVENTxxは、[無線モジュール](https://www.rohm.co.jp/products/wireless-communication/specified-low-power-radio-modules/bp35c0-product)から送られてくる電文）
                - EVENT25…接続完了通知
                    - 取得コマンド送信可能状態になる。
                - EVENT26…切断要求通知
                    - 切断コマンド（TERM）送信後、接続処理を開始。
                - EVENT27…切断成功通知
                    - 切断コマンド（TERM）送信後、接続処理を開始。
                - EVENT28…タイムアウト通知（切断要求に対する応答がなかった）
                    - 切断コマンド（TERM）送信後、接続処理を開始。
                - EVENT29…無線送信禁止通知
                    - 取得コマンドの送信を止め、EVENT25の受信を待つ
            - 取得コマンド送信可能なら、約２分毎に瞬時電力取得コマンドをスマートメーターに送信する。
        - 切断要求のハンドリングは重要で、定期的にスマートメーターから送られてくるので、うまく再接続処理してやらないと、いつの間にか通信が止まっているという状況になってしまう。
            - NanoPi版で時々接続が切れてしまう事象があって、通信ログを追ったところ、1日に１回くらい切断要求が送られてきていたのを無視していた。
    - 無線送信禁止状態が解除されない場合がある(2019/6/12 追記)
        - EVENT29を受信した後のEVENT25が、時々受信できない。
            - そのため、取得コマンドを送れずに瞬時電力値が得られない。
            - スマートメーターとの接続は切れてないので、３０分ごとに送られてくる積算電力量は取得できる。
        - スマートメータからの受信をMicroSDカードにログを取るようにして稼働させてみたところ、下記の状態になっていることを確認できた。
            - 正常（EVENT29が来た後、数秒以内にEVENT25）

                ```
2019/06/10 18:06:08 EV29
2019/06/10 18:06:08 RXUDP
2019/06/10 18:06:09 RXUDP
2019/06/10 18:06:09 RXUDP
2019/06/10 18:06:09 RXUDP
2019/06/10 18:06:09 EV25
                ```
            - 異常（EVENT29が来た後、ずっとEVENT25が来ない）

                ```
2019/06/12 08:32:38 EV29
2019/06/12 08:32:42 RXUDP
2019/06/12 08:32:43 RXUDP
```

2. ネットワーク
    - 起動時にEthernetがLink状態ならEthernetモジュール（[WIZ850io](https://www.switch-science.com/catalog/3683/)）を使用し、それ以外はM5Stack内蔵のWiFiを使用。
    - Echonet通信とNTP取得では、EthernetUDP（または、WiFiUDP）を使用。
    - InfluxDB送信は、EthernetClient（または、WiFiClient）を使用。
1. BME280センサー
    - 起動直後は、気圧が異常な値（極端に小さい値）になることが多かったので、９００hPaを超えるまで繰り返し取得するように。
    - 約２分毎にライブラリ（[BME280_Light](https://github.com/EnviroMonitor/BME280_light?utm_source=platformio&utm_medium=piohome)）経由で計測値を取得。
1. Echonet通信（エコキュート、ダイキンエアコン）
    - 起動時に受信タスクを起動し、UDPポート３６１０でEchonetパケットの受信を待つ。
    - 約２分毎に取得要求コマンドを、エコキュートとダイキンエアコンに送信
1. NTP取得
    - 起動時にNTPサーバーに時刻取得を行う。
    - 以降は、millis()値を定期的に取得し、増分（ms）を加算していく。
    - 「NTP」ボタンが押されたら、NTPサーバーへの再取得を行う。
1. InfluxDB送信
    - 上記の各計測値（スマートメーターの瞬時電力、積算電力量、BME２８０センサー値、エコキュート値、ダイキンエアコン値）の取得タイミングで、InfluxDBサーバに計測値を送信する。

---
# 今回、ハマったところ
- InfluxDB送信で、NanoPi版ではcurlコマンドを使用していたので同様にしようと、[libcurl](https://curl.haxx.se/libcurl/)の導入を試みたりしました。（これだけで三日くらい費やしている。）
- ふと思い立って、誰かがライブラリを提供しているんじゃないかと検索したところ、[ESP8266_Influx_DB](https://github.com/tobiasschuerg/ESP8266_Influx_DB)に行き着きました。
    - コードを読んでHttpClientを使えば良いことがわかりました。
    - そのまま当該ライブラリを使ってもよかったんですが、なるべく有線LANでネットワーク接続したかったので、参考にして自作しています。