messyなkitchenなブログ

ただひたすらに散らかった台所や人生やその他を晒す。

MENU

自宅消費電力の可視化作戦

電気代が、こわい。
✗✗✗の次に、こわい。

まずは使っている電力の、見える化からはじめよう。

電力会社への申し込み

Bルートサービス を申し込みます。
Bルートというのは、スマートメーターとの通信経路(ざっくり)。
スマートメーターというのは、各家庭の電力計です。 昔ながらの電力計から 最近のスマートな電力計に、だいたいの家では置き換わっているっぽい。

んで、Bルートという通信経路を使えるようにしてもらうように、電力会社にお願いするわけです。
うちの場合、申し込みしてから 1週間くらいで通知が来ました。
この通知で提供される、ID と パスワード をこのあと使うことになります。

通信デバイスの入手

スマートメーターが Bルートで通信する電波の規格が存在し、これを使って通信する機械が必要になります。

Wi-SUN ていう無線規格 ... スマートメーター関係で使われているだけなんだろうなきっと。

今回は UDG-1-WSNE ってUSB接続のデバイスを入手できました(中古)。

プログラムの作成

Raspberry Pi Zero2W で動作する pythonコードを作ります。
python のバージョンは 3.9
ちなみに UDGなんとかは、USB端子で接続するだけで ラズパイOS で認識しました。

ネットで検索していろいろかき集めてくっつけて動くように手直ししたコードがこちらです。

▶ power_consumption_monitoring.py(クリックすると展開されます)

from time import sleep
import serial
from datetime import datetime

# シリアルポートデバイス名
serialPortDev = '/dev/tty.usbmodemXXXXX'    # Mac の場合
serialPortDev = '/dev/ttyACM0'              # Raspberry pi の場合

Broute_pw = {もらったパスワード}
Broute_id = {もらったID}
Channel = {取得したチャネル}
PanId = {取得したPanID}
Address = {取得したアドレス}

# シリアルポート初期化
ser = serial.Serial(serialPortDev, 115200)

# Bルート認証パスワード設定
ser.write(str.encode('SKSETPWD C ' + Broute_pw + '\r\n'))
print(ser.readline().decode(encoding='utf-8'), end='')  # OK:成功

# Bルート認証ID設定
ser.write(str.encode('SKSETRBID ' + Broute_id + '\r\n'))
print(ser.readline().decode(encoding='utf-8'), end='')  # OK:成功

# Channel設定
ser.write(str.encode('SKSREG S2 ' + Channel + '\r\n'))
print(ser.readline().decode(encoding='utf-8'), end='')  # OK:成功

# PanID設定
print('PanID設定')
ser.write(str.encode('SKSREG S3 ' + PanId + '\r\n'))
print(ser.readline().decode(encoding='utf-8'), end='')  # OK:成功

# PANA 接続シーケンス
ser.write(str.encode('SKJOIN ' + Address + '\r\n'))
print(ser.readline().decode(encoding='utf-8'), end='')  # OK:成功

# 瞬時電力計測値取得コマンドフレーム
echonetLiteFrame = b'\x10\x81\x00\x01\x05\xFF\x01\x02\x88\x01\x62\x01\xE7\x00'

# コマンド送信・データ受信・解析処理の繰り返し
while True:
    # コマンド送信
    command = 'SKSENDTO 1 {0} 0E1A 1 0 {1:04X} '.format(Address, len(echonetLiteFrame))
    ser.write(str.encode(command) + echonetLiteFrame)

    # コマンド受信
    ser.readline()  # EVENT 21
    ser.readline()  # OK:成功

    # 返信データ取得
    data = ser.readline().decode(encoding='utf-8')

    # 返信データが得られるまで読み捨てる
    while not data.startswith('ERXUDP'):
        data = ser.readline().decode(encoding='utf-8')

    # 応答が得られたかどうかを示すフラグ boolean
    isResponse = False

    # データチェック
    cols = data.strip().split(' ')
    res = cols[9]   # UDP受信データ部分
    SEOJ = res[8:14]
    ESV = res[20:22]
    if SEOJ == '028801' and ESV == '72':
        # スマートメーター(028801)から来た応答(72) の場合
        isResponse = True
        EPC = res[24:24 + 2]
        if EPC == "E7":
            # 瞬時電力計測値(E7) の場合
            hexPower = data[-8:]  # 最後の4バイト=瞬時電力計測値
            intPower = int(hexPower, 16)
            print(u'瞬時電力計測値:{0}[W]'.format(intPower))

    if isResponse:
        sleep(30)   # 応答が得られた場合は 30秒待つ
    else:
        sleep(1)    # 応答が得られなかった場合はすぐに次のコマンド送信になるよう 1秒だけ待つ

{もらったパスワード} {もらったID} は、Bルートサービスを申し込んだときに入手したものです。
{取得したチャネル} {取得したPanID} {取得したアドレス} は、スマートメーターと通信をやり取りして得られる値です。 このコードとは別に、事前に入手しました(元気があればその内容を追記します)。

実行結果

こんな具合に、約 30秒間隔で 電力の計測値を見ることができました。

実行結果(初期化中にわかりやすいようprintを追加しています)

まとめ

消費電力の現在の値を見ることができるようになりました。
今後は次の計画で考えています。

  1. 積算電力を得る
  2. グラフなどで視覚的にわかりやすくする
  3. サイネージっぽいデバイスでいつでも見える化

更新 2024-02-02

古いスマホ + ウェブサービス (Ambient) で、消費電力モニター を作ってみました。

  • 更新頻度は 30秒間に1回
  • スマホのせいかブラウザのせいかサービスのせいか、ときどき更新されない時がある

これで常に電気使用量にビクビク怯えながら生活できるぞ!