As I Please

MTのいんすとーるの練習と、その他びぼうろく・・・

タグ「スマートメーター」が付けられているもの


スマートメーター HEMS デバイススキャン for python3

以前書いた、HEMS 機器からのデータの取り出し関連で、とても参考にさせてもらった スマートメーターの情報を最安ハードウェアで引っこ抜くをベースにプログラムを書いた。
このサンプルプログラムはpython2 でのプログラムだったので、今後のためにもpython3 用に書き直しておいたほうが良かったので、作成してみた。例示してあるプログラムはデバイスを探索してデータを取得するのだが、定期的にデータを取得して時系列データを作成するのであれば、デバイス探索は毎回繰り返さなくても良い(スマートメーターのサイトローカルのIPv6アドレスで特定できる)ので、(1)デバイスを探索し、アクセスするための諸元データを取得する。(2)データを定期的に取得する。の2つにわけてしまうほうが良さそうで、それを実施してみた。 まずは (1)の python3 に自分なりに書き換えたものを。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import serial
import time
# Bルート認証ID(東京電力パワーグリッドから郵送で送られてくる)
rbid  = "AAAABBBBCCCCDDDD"
# Bルート認証パスワード(東京電力パワーグリッドからメールで送られてくる)
rbpwd = "PASSWORDDDDDDD"
# シリアルポートデバイス名
#serialPortDev = 'COM3'  # Windows の場合
serialPortDev = '/dev/ttyUSB0'  # Linux(ラズパイなど)の場合
#serialPortDev = '/dev/cu.usbserial-A103BTPR'    # Mac の場合
#
ser = serial.Serial(serialPortDev, 115200)
#
wcom = "SKVER\r\n"
ser.write(str.encode(wcom))
print(ser.readline().decode('utf-8'), end="",flush=True) # エコーバック
print(ser.readline().decode('utf-8'), end="",flush=True) # バージョン
#
# Bルート認証パスワード設定
wcom = "SKSETPWD C " + rbpwd + "\r\n"
ser.write(str.encode(wcom))
ser.readline() # エコーバック
# Bルート認証ID設定
wcom = "SKSETRBID " + rbid + "\r\n"
ser.write(str.encode(wcom))
print(ser.readline().decode('utf-8'), end="",flush=True) # エコーバック
ser.readline()
print(ser.readline().decode('utf-8'), end="",flush=True) # OKが来るはず(チェック無し)
ser.readline()
scanDuration = 4;   # スキャン時間。サンプルでは6なんだけど、4でも行けるので。(ダメなら増やして再試行)
scanRes = {} # スキャン結果の入れ物
# スキャンのリトライループ(何か見つかるまで)
#while not scanRes.has_key("Channel") :  python2
while not 'Channel' in scanRes :
        # アクティブスキャン(IE あり)を行う
        # 時間かかります。10秒ぐらい?
        #ser.write(str.encode("SKSCAN 2 FFFFFFFF " + str(scanDuration) + "\r\n"))
        wcom = "SKSCAN 2 FFFFFFFF " + str(scanDuration) + "\r\n"
        ser.write(str.encode(wcom))
        # スキャン1回について、スキャン終了までのループ
        scanEnd = False
        while not scanEnd :
            line = ser.readline()
            print(line.decode(), end="",flush=True)
#
            line = line.decode()
            if line.startswith("EVENT 22") :
#                # スキャン終わったよ(見つかったかどうかは関係なく)
                scanEnd = True
            elif line.startswith("  ") :
                # スキャンして見つかったらスペース2個あけてデータがやってくる
                # 例
                #  Channel:39
                #  Channel Page:09
                #  Pan ID:FFFF
                #  Addr:FFFFFFFFFFFFFFFF
                #  LQI:A7
                #  PairID:FFFFFFFF
                cols = line.strip().split(':')
                scanRes[cols[0]] = cols[1]
        scanDuration+=1
        if 7 < scanDuration and not scanRes.has_key("Channel"):
            # 引数としては14まで指定できるが、7で失敗したらそれ以上は無駄っぽい
            print("スキャンリトライオーバー")
            sys.exit()  #### 糸冬了 ####
これを実行すると次のような結果が出てくる。
raspberrypi:~/smartmeter3# ./test-bs_scan.py
SKVER
EVER 1.2.8
SKSETPWD C PASSWORDDDDDDD
SKSETRBID AAAABBBBCCCCDDDD
SKSCAN 2 FFFFFFFF 4
OK
EVENT 20 FE80:0000:0000:0000:1234:5678:9ABC:DEF0
EPANDESC
  Channel:33
  Channel Page:09
  Pan ID:24EF
  Addr:00FFEEDDCCBBAA99
  LQI:32
  PairID:12345678
EVENT 22 FE80:0000:0000:0000:1234:5678:9ABC:DEF0
Addr は64bit、これを IPv6のリンクローカルアドレスに変換するには SKLL64 コマンドを使う、ようだが 単純に、MACアドレス 48bit を、EUI-64で変換する場合の、'FF:FE'の挿入をやめただけのよう。先頭の7bit目を反転させて、後半64bit の IPv6 アドレスにしてしまえば良いみたい。例の 'Addr:00FFEEDDCCBBAA99' なら、IPv6アドレスは 'FE80:0000:0000:0000:02FF:EEDD:CCBB:AA99' になる、と思われる。
これで取得できた Channel, Channel Page, Pan ID,PairID, 生成した IPv6アドレスを利用して定期的なデータ取得 scriptを動かす。

スマートメーター HEMS デバイススキャン for python3

以前書いた、HEMS 機器からのデータの取り出し関連で、とても参考にさせてもらった スマートメーターの情報を最安ハードウェアで引っこ抜くをベースにプログラムを書いた。
このサンプルプログラムはpython2 でのプログラムだったので、今後のためにもpython3 用に書き直しておいたほうが良かったので、作成してみた。例示してあるプログラムはデバイスを探索してデータを取得するのだが、定期的にデータを取得して時系列データを作成するのであれば、デバイス探索は毎回繰り返さなくても良い(スマートメーターのサイトローカルのIPv6アドレスで特定できる)ので、(1)デバイスを探索し、アクセスするための諸元データを取得する。(2)データを定期的に取得する。の2つにわけてしまうほうが良さそうで、それを実施してみた。 まずは (1)の python3 に自分なりに書き換えたものを。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import serial
import time
# Bルート認証ID(東京電力パワーグリッドから郵送で送られてくる)
rbid  = "AAAABBBBCCCCDDDD"
# Bルート認証パスワード(東京電力パワーグリッドからメールで送られてくる)
rbpwd = "PASSWORDDDDDDD"
# シリアルポートデバイス名
#serialPortDev = 'COM3'  # Windows の場合
serialPortDev = '/dev/ttyUSB0'  # Linux(ラズパイなど)の場合
#serialPortDev = '/dev/cu.usbserial-A103BTPR'    # Mac の場合
#
ser = serial.Serial(serialPortDev, 115200)
#
wcom = "SKVER\r\n"
ser.write(str.encode(wcom))
print(ser.readline().decode('utf-8'), end="",flush=True) # エコーバック
print(ser.readline().decode('utf-8'), end="",flush=True) # バージョン
#
# Bルート認証パスワード設定
wcom = "SKSETPWD C " + rbpwd + "\r\n"
ser.write(str.encode(wcom))
ser.readline() # エコーバック
# Bルート認証ID設定
wcom = "SKSETRBID " + rbid + "\r\n"
ser.write(str.encode(wcom))
print(ser.readline().decode('utf-8'), end="",flush=True) # エコーバック
ser.readline()
print(ser.readline().decode('utf-8'), end="",flush=True) # OKが来るはず(チェック無し)
ser.readline()
scanDuration = 4;   # スキャン時間。サンプルでは6なんだけど、4でも行けるので。(ダメなら増やして再試行)
scanRes = {} # スキャン結果の入れ物
# スキャンのリトライループ(何か見つかるまで)
#while not scanRes.has_key("Channel") :  python2
while not 'Channel' in scanRes :
        # アクティブスキャン(IE あり)を行う
        # 時間かかります。10秒ぐらい?
        #ser.write(str.encode("SKSCAN 2 FFFFFFFF " + str(scanDuration) + "\r\n"))
        wcom = "SKSCAN 2 FFFFFFFF " + str(scanDuration) + "\r\n"
        ser.write(str.encode(wcom))
        # スキャン1回について、スキャン終了までのループ
        scanEnd = False
        while not scanEnd :
            line = ser.readline()
            print(line.decode(), end="",flush=True)
#
            line = line.decode()
            if line.startswith("EVENT 22") :
#                # スキャン終わったよ(見つかったかどうかは関係なく)
                scanEnd = True
            elif line.startswith("  ") :
                # スキャンして見つかったらスペース2個あけてデータがやってくる
                # 例
                #  Channel:39
                #  Channel Page:09
                #  Pan ID:FFFF
                #  Addr:FFFFFFFFFFFFFFFF
                #  LQI:A7
                #  PairID:FFFFFFFF
                cols = line.strip().split(':')
                scanRes[cols[0]] = cols[1]
        scanDuration+=1
        if 7 < scanDuration and not scanRes.has_key("Channel"):
            # 引数としては14まで指定できるが、7で失敗したらそれ以上は無駄っぽい
            print("スキャンリトライオーバー")
            sys.exit()  #### 糸冬了 ####
これを実行すると次のような結果が出てくる。
raspberrypi:~/smartmeter3# ./test-bs_scan.py
SKVER
EVER 1.2.8
SKSETPWD C PASSWORDDDDDDD
SKSETRBID AAAABBBBCCCCDDDD
SKSCAN 2 FFFFFFFF 4
OK
EVENT 20 FE80:0000:0000:0000:1234:5678:9ABC:DEF0
EPANDESC
  Channel:33
  Channel Page:09
  Pan ID:24EF
  Addr:00FFEEDDCCBBAA99
  LQI:32
  PairID:12345678
EVENT 22 FE80:0000:0000:0000:1234:5678:9ABC:DEF0
Addr は64bit、これを IPv6のリンクローカルアドレスに変換するには SKLL64 コマンドを使う、ようだが 単純に、MACアドレス 48bit を、EUI-64で変換する場合の、'FF:FE'の挿入をやめただけのよう。先頭の7bit目を反転させて、後半64bit の IPv6 アドレスにしてしまえば良いみたい。例の 'Addr:00FFEEDDCCBBAA99' なら、IPv6アドレスは 'FE80:0000:0000:0000:02FF:EEDD:CCBB:AA99' になる、と思われる。
これで取得できた Channel, Channel Page, Pan ID,PairID, 生成した IPv6アドレスを利用して定期的なデータ取得 scriptを動かす。

HEMS 機器オブジェクトスーパークラス

電力スマートメーターは「住宅・設備関連機器クラスグループ」の「低圧スマート電力量メータクラス」だそうで、クラスグループ"0x02",クラスコード "0x88" になる。その他に取れるデータが無いかと見てみたら、一番上位の「機器オブジェクトスーパークラス」のデータにGetできるものがあるようなので、とりあえず見てみた。

プロパティ名称 EPC 取得データ 内容 備考
動作状態 0x80 30 ON
設置場所 0x81 61 庭・外周 場所番号 01
規格Version情報 0x82 00004600 Release F (?)
識別番号 0x83 ESV=52,読み出し応答不可
瞬時消費電力計測値 0x84 ESV=52,読み出し応答不可
積算消費電力計測値 0x85 ESV=52,読み出し応答不可
メーカ異常コード 0x86 ESV=52,読み出し応答不可
電流制限設定 0x87 ESV=52,読み出し応答不可
異常発生状態 0x88 42 異常発生無
異常内容 0x89 ESV=52,読み出し応答不可
メーカコード 0x8A 000016
事業場コード 0x8B ESV=52,読み出し応答不可
商品コード 0x8C ESV=52,読み出し応答不可
製造番号 0x8D 313233343536373839300000 1234567890
製造年月日 0x8E ESV=52,読み出し応答不可
節電動作設定 0x8F ESV=52,読み出し応答不可
遠隔操作設定 0x93 ESV=52,読み出し応答不可
現在時刻設定 0x97 0C35 12時41分
現在年月日設定 0x98 07E20803 2018年8月3日
電力制限設定 0x99 ESV=52,読み出し応答不可
積算運転時間 0x9A ESV=52,読み出し応答不可

意味があるデータは製造番号くらいで、ほぼ読み出し応答不可が帰ってきた。

excel 2 table にはここを利用

HEMS 機器オブジェクトスーパークラス

電力スマートメーターは「住宅・設備関連機器クラスグループ」の「低圧スマート電力量メータクラス」だそうで、クラスグループ"0x02",クラスコード "0x88" になる。その他に取れるデータが無いかと見てみたら、一番上位の「機器オブジェクトスーパークラス」のデータにGetできるものがあるようなので、とりあえず見てみた。

プロパティ名称 EPC 取得データ 内容 備考
動作状態 0x80 30 ON
設置場所 0x81 61 庭・外周 場所番号 01
規格Version情報 0x82 00004600 Release F (?)
識別番号 0x83 ESV=52,読み出し応答不可
瞬時消費電力計測値 0x84 ESV=52,読み出し応答不可
積算消費電力計測値 0x85 ESV=52,読み出し応答不可
メーカ異常コード 0x86 ESV=52,読み出し応答不可
電流制限設定 0x87 ESV=52,読み出し応答不可
異常発生状態 0x88 42 異常発生無
異常内容 0x89 ESV=52,読み出し応答不可
メーカコード 0x8A 000016
事業場コード 0x8B ESV=52,読み出し応答不可
商品コード 0x8C ESV=52,読み出し応答不可
製造番号 0x8D 313233343536373839300000 1234567890
製造年月日 0x8E ESV=52,読み出し応答不可
節電動作設定 0x8F ESV=52,読み出し応答不可
遠隔操作設定 0x93 ESV=52,読み出し応答不可
現在時刻設定 0x97 0C35 12時41分
現在年月日設定 0x98 07E20803 2018年8月3日
電力制限設定 0x99 ESV=52,読み出し応答不可
積算運転時間 0x9A ESV=52,読み出し応答不可

意味があるデータは製造番号くらいで、ほぼ読み出し応答不可が帰ってきた。

excel 2 table にはここを利用

HEMS スマートメーターからの出力

電灯契約を変えたことで、スマートメータに取り替えられた。
東電にBルートサービスを申し込んで、自宅raspberry pi3に テセラ・テクノロジーのRL7023 Stick-D/IPS を刺して計測し、グラフ化することを目標としてみる。
ほぼ、

スマートメーターの情報を最安ハードウェアで引っこ抜くを大変に参考にさせてもらった。

ECHONETの機器オブジェクト詳細規定の「低圧スマート電力量メータクラス規定」のところを読む。

https://echonet.jp/wp/wp-content/uploads/pdf/General/Standard/Release/Release_H_jp/Appendix_H.pdf

プロパティ名称 EPC 取得データ 内容 備考
動作状態 0x80 30 ON
係数 0xD3 00000001 1 0.1Kwh
積算電力量有効桁数 0xD7 06 6桁
積算電力量計測値
(正方向計測値)
0xE0 00003354 1314.0 (kWh)
積算電力量単位 0xE1 01 0.1 kWh
積算電力量計測値履歴1
(正方向計測値)
0xE2 (194 byte= 48 data) FFFFFFFE (初期設定)
積算電力量計測値
(逆方向計測値)
0xE3 00000015 2.1 kWh
積算電力量計測値履歴1
(逆方向計測値)
0xE4 (0xC2=194 byte = 48data) FFFFFFFE (初期設定)
積算履歴収集日1 0xE5 FF 設定無 (初期値)
瞬時電力計測値 0xE7 0000073C 1852 W
瞬時電流計測値 0xE8 0046006E R相 7.0(A) T相11.0(A)
定時積算電力量計測値
(正方向計測値)
0xEA 07E2071D17000000003354 2018年07月29日
23時00分00秒
1314.0 (kWh)
定時積算電力量計測値
(逆方向計測値)
0xEB 07E2071D17000000000015 2018年07月29日
23時00分00秒
2.1 (kWh)
積算電力量計測値履歴2
(正方向、逆方向計測値)
0xEC FFFFFFFFFFFF01F
FFFFFFEFFFFFFFE
(初期値)
積算履歴収集日2 0xED FFFFFFFFFFFF01 (初期値)

電子レンジを使っているときだったのでちょっと電力量が高いかも。

電力量単位が 0.1kWh、有効桁数が6桁あたりは見落としがちだった。

とりあえずグラフ化するのは、積算電力量、瞬時電力、瞬時電流あたりか?発電・売電はしていないので、逆方向は必要ないと思うが一応モニタしておくか。

HEMS スマートメーターからの出力

電灯契約を変えたことで、スマートメータに取り替えられた。
東電にBルートサービスを申し込んで、自宅raspberry pi3に テセラ・テクノロジーのRL7023 Stick-D/IPS を刺して計測し、グラフ化することを目標としてみる。
ほぼ、

スマートメーターの情報を最安ハードウェアで引っこ抜くを大変に参考にさせてもらった。

ECHONETの機器オブジェクト詳細規定の「低圧スマート電力量メータクラス規定」のところを読む。

https://echonet.jp/wp/wp-content/uploads/pdf/General/Standard/Release/Release_H_jp/Appendix_H.pdf

プロパティ名称 EPC 取得データ 内容 備考
動作状態 0x80 30 ON
係数 0xD3 00000001 1 0.1Kwh
積算電力量有効桁数 0xD7 06 6桁
積算電力量計測値
(正方向計測値)
0xE0 00003354 1314.0 (kWh)
積算電力量単位 0xE1 01 0.1 kWh
積算電力量計測値履歴1
(正方向計測値)
0xE2 (194 byte= 48 data) FFFFFFFE (初期設定)
積算電力量計測値
(逆方向計測値)
0xE3 00000015 2.1 kWh
積算電力量計測値履歴1
(逆方向計測値)
0xE4 (0xC2=194 byte = 48data) FFFFFFFE (初期設定)
積算履歴収集日1 0xE5 FF 設定無 (初期値)
瞬時電力計測値 0xE7 0000073C 1852 W
瞬時電流計測値 0xE8 0046006E R相 7.0(A) T相11.0(A)
定時積算電力量計測値
(正方向計測値)
0xEA 07E2071D17000000003354 2018年07月29日
23時00分00秒
1314.0 (kWh)
定時積算電力量計測値
(逆方向計測値)
0xEB 07E2071D17000000000015 2018年07月29日
23時00分00秒
2.1 (kWh)
積算電力量計測値履歴2
(正方向、逆方向計測値)
0xEC FFFFFFFFFFFF01F
FFFFFFEFFFFFFFE
(初期値)
積算履歴収集日2 0xED FFFFFFFFFFFF01 (初期値)

電子レンジを使っているときだったのでちょっと電力量が高いかも。

電力量単位が 0.1kWh、有効桁数が6桁あたりは見落としがちだった。

とりあえずグラフ化するのは、積算電力量、瞬時電力、瞬時電流あたりか?発電・売電はしていないので、逆方向は必要ないと思うが一応モニタしておくか。