Go言語でスマートメーターから電力量取得してみる

なんか最近電気代高くなってきたのでスマートメーターから電力量を取得してみた。
いまどきアプリとかで電気代見ることできるのであんまりやる意味はないと思う・・・
リアルタイム性と瞬時電力量が取れるのが一番のメリットだと思うがNeture Remote Lite Eを使えばUIもいい感じで表示されるし値段もそんな変わらないのでそっち買うのがおすすめ。

準備するもの

  • BP35A1
    • Wi-SUNモジュール
  • BP35A7A
    • ピッチ変換アダプタ
  • BP35A7-accessories
    • ピンヘッダー
  • USBシリアル変換
    • なんか家にあったやつを使った
  • BルートのIDとパスワード

Wi-SUN系のものはコアスタッフってところで買った。
トータルで1万円ぐらいだった。

ドキュメント

参考にした記事

BP35A1のセットアップ

cuコマンドでシリアル通信を行う。
sudo cu -l cu.usbserial-AI06IYRS -s 115200

デフォルト設定だとスマートメータからデータがバイナリで表示されるので16進数に変更しておく
WOPT 1

瞬時電力量の取得方法

送信コマンドの組み立て方

ミドルウェア仕様書のとおりにECHONETLiteデータフレームを組み立てていく。

  • EHD1
    • 0x10
    • ECHONET Lite規格
  • EHD2
    • 0x81
    • 形式1
  • TID
    • 0x01
    • 2Byteであればなんでもいいが今回は0x01で固定している
  • SEOJ
    • 0x05FF01
    • 送信元
    • コントローラークラス規定
  • DEOJ
    • 0x028801
    • 送信先
    • 低圧スマート電力メータクラス規定
  • ESV
    • 0x62
    • 読み出し要求
  • OPC
  • 0x01
  • 1プロパティしか読み込まないため
  • EPC
    • 0xE7
    • 瞬時電力計測値
  • PDC
    • 0x00
    • 読み出し要求の場合は0x00
  • EDT
    • PDCが0の場合はたぶんいらない

こららを全部結合すると\x10\x81\x00\x01\x05\xFF\x01\x02\x88\x01\x62\x01\xE7\x00になるのでSKSENDTOで送信する。

受信データ読み方

瞬時電力量のコマンドを送信すると以下みたいなERXUDPから始まるデータのレスポンスがくる。

ERXUDP FE80:0000:0000:0000:0280:xxxx:xxxx:xxxx FE80:0000:0000:0000:021D:xxxx:xxxx:xxxxx 0E1A 0E1A 008087003010D9C1 1 0012 1081000102880105FF017201E704000000DE

空白区切りの最後の部分が瞬時電力計測値が含まれているデータ(ECHONETLiteデータフレーム)である。
DEOJまでは送信元と受信元が逆になったぐらい違いしかない。

  • ESV
    • `0x72
    • 応答
  • OPC
  • 0x01
  • 要求時と同じ値
  • EPC
    • 0xE7
    • 要求時と同じ値
  • PDC
    • 0x04
    • EDTのサイズ
  • EDT
    • 0x000000DE
    • 16 * 13 + 14 = 222W

ソースコード

Goで書いてみたが、結構長くなったのでGithubのリンク貼っておく。積算電力量も取得できるようにしている。

github.com

エラーハンドリングは結構適当なので長時間動かす時は手加えないといけない。

serial通信のパッケージにgo-serialを使ってみたが、タイムアウトを設定してもエラーが返ってこないのでio.ReadLine()で読み込もうとすると永遠にブロックされてしまう。
issueは上がっているが破壊的変更なのでv2がでるまで改善されてないみたいなので、自分でそこの部分は実装した。
このパッケージでラップすればいけるみたいなコメントもみた。