スマートコスモの消費電力情報を、AiSEG2経由で収集する

IoT

家全体の消費電力に加えて、分電盤内の回路ごとに消費電力を収集できるスマートコスモ。本記事では、ECHONET Lite経由ではなく、AiSEG2経由で情報を収集する方法をまとめます。

最終的なコードを早く見たいという方は「まとめ」をご覧ください。

スポンサーリンク

AiSEG2? スマートコスモ?

AiSEG2は、Panasonic製のHEMSコントローラーです。ソーラーパネルや蓄電池などの電気設備とECHONET Liteプロトコルでお話をして、情報を可視化したり制御したりします。

スマートコスモは、同じくPanasonic製の分電盤です。HEMSに対応しているというのが特徴で、AiSEG2と有線LAN(ECHONET Liteプロトコル)あるいは特定小電力無線で接続し、住宅全体の電力量に加え、回路ごと(いわゆるブレーカーごとという理解でOK)の消費電力を報告してくれます。

スマートコスモの情報を取得したい

スマートコスモの情報を(ほぼ)リアルタイムのデータとして取得したい場合(そんな人は稀でしょうが)、ECHONET Liteでお話をしていればLAN経由で情報を取得できるのでしょうが、特定小電力でAiSEG2と直接接続されていると手が出せません。

我が家のケースでは、残念ながら特定小電力で接続されており、スマートコスモのLANポートには何も刺さっていない状態でした。スマートコスモとスイッチングハブまでは距離は遠くないものの、綺麗に収めるのはそれなりに面倒そうなので、代わりにAiSEG2に来ているデータをスクレイピングできないか探ることにしました。

スポンサーリンク

AiSEG2にブラウザでアクセスして観察する

AiSEG2はウェブインタフェースが備わっており、AiSEG2のディスプレイに表示される内容をそのまま見ることができます。

IPアドレスはAiSEG2の独自ルールで、XXX.XXX.XXX.216固定となっています(XXXは各LANの環境に応じて)。

http://XXX.XXX.XXX.216/ にアクセスすると、ユーザ名とパスワード(ユーザ名はaiseg、初期パスワードは説明書に記載)を求められ、入力すると初期画面が表示されます。我が家の場合は以下のような感じです。

家全体の情報を取得する

以下の情報は、我が家のAiSEG2 MKN716(セキスイハイム向けのMKN713)を使って得られた情報です。機種やソフトウェアバージョンによって異なることがあります。以下の情報やコード実行による不具合の責任はおいかねますので、あくまでご参考まで。

さて、ここからメニューでグラフを選んで使用電力量のページに飛ぶと、こんな感じです。

左上に表示されている14.166kWhを取得したいわけですが、ここでおもむろにHTMLソースを見てみましょう。

<div id="txt_val_inner">
    <div id="val_current">2023/09/10</div>
    <div id="txt_graph_kwh">
        <span id="val_kwh">14.166</span><span id="unit_kwh">kWh</span>
    </div>
</div>

なんか、こんなのが出てきます。idでval_kwhとなってるので、さくっと取得できますね。なお、URLはhttp://XXX.XXX.XXX.216/page/graph/52111 のようです。

Pythonでちょっと書いてみます。

import requests
from requests.auth import HTTPDigestAuth
from lxml import html

user="aiseg"
password="XXXXXXXXXX"
host="XXX.XXX.XXX.216"

# 今日の使用電力量
url="http://"+host+"/page/graph/52111"
response=requests.get(url, auth=HTTPDigestAuth(user,password))
root = html.fromstring(response.content)
print("使用電力量: " + root.xpath('//span[@id="val_kwh"]')[0].text + "kwh")

はい。

使用電力量: 14.166kwh

他にも、売買電量など取得できます。お試しください。

スポンサーリンク

回路ごとの消費電力量を取得する

先ほどの仕様電力量のページの右下にある回路ごとを選択し、その後の画面で左側のタブ詳細1を選択すると、以下の画面になります。

さらに、ここでヒートポンプなど特定回路のボタンを押すと、以下の画面になります。

これも同様にHTMLソースを見ると

<div id="txt_val_inner">
    <div id="val_current">2023/09/10</div>
    <div id="txt_graph_kwh">
        <span id="val_kwh">2.450</span><span id="unit_kwh">kWh/</span><span id="val_kwh">73</span><span
            id="unit_kwh">円</span>
    </div>
</div>

となっているのでこれまたval_kwhでparseすればいいのかと思ったのですが、どうやらURLが他の回路と同様のようです。

具体的には、

http://XXX.XXX.XXX.216/page/graph/584?data=eyJkYXkiOlsyMDIzLDksMTBdLCJiYWNrX3VybCI6Ii9wYWdlL2dyYXBoLzUyMTExIiwiYmFja191cmwyIjoiL3BhZ2UvZ3JhcGgvNTgyIiwidGVybSI6IjIwMjMvMDkvMTAiLCJ0ZXJtU3RyIjoiZGF5IiwiaWQiOiIxIiwiY2lyY3VpdGlkIjoiNDMifQ%3D%3D&request_by_form=1

となっており、dataの中身が怪しそうです。

最後の%3D%3DはURLエンコードでしょうが、その手前はなんでしょうかね。とりあえずbase64でデコードしてみると、こうなりました。

{"day":[2023,9,10],"back_url":"/page/graph/52111","back_url2":"/page/graph/582","term":"2023/09/10","termStr":"day","id":"1","circuitid":"43"}

あらー。

back_urlとかそこらへんは置いておいて、circuitidで回路を指定しているのでしょうね。ためしに、

{"circuitid":"43"}

だけエンコードして動作を試してみたところ、

1日前と比較などのボタンが見えませんが、アクセスした日の使用電力量は見えるみたいです。めでたい。

スポンサーリンク

回路名を取得する

回路名は、計測回路名称ページに一覧があります。

こいつもおもむろにHTMLソースを見ると、

<script type="text/javascript">window.onload = init({ "popupmsg": ... </script>

の中にJSONで名称が定義されているようです。JSONを切り出せばいろいろできそうです。回路ごとの電力量を収集する際に指定したcircuitidも取得できるので一括で収集できますね。

まとめ

このあたりのコードをまとめると、こんな感じです。

import requests
from requests.auth import HTTPDigestAuth
from lxml import html
import json
import base64

user="aiseg"
password="XXXXXXXXXX"
host="XXX.XXX.XXX.216"

# 今日の使用電力量
url="http://"+host+"/page/graph/52111"
response=requests.get(url, auth=HTTPDigestAuth(user,password))
root = html.fromstring(response.content)
print("使用電力量: " + root.xpath('//span[@id="val_kwh"]')[0].text + "kwh")

# 今日の買電量
url="http://"+host+"/page/graph/53111"
response=requests.get(url, auth=HTTPDigestAuth(user,password))
root = html.fromstring(response.content)
print("買電量: " + root.xpath('//span[@id="val_kwh"]')[0].text + "kwh")

# 今日の売電量
url="http://"+host+"/page/graph/54111"
response=requests.get(url, auth=HTTPDigestAuth(user,password))
root = html.fromstring(response.content)
print("売電量: " + root.xpath('//span[@id="val_kwh"]')[0].text + "kwh")

# 今日の発電量
url="http://"+host+"/page/graph/51111"
response=requests.get(url, auth=HTTPDigestAuth(user,password))
root = html.fromstring(response.content)
print("発電量: " + root.xpath('//span[@id="val_kwh"]')[0].text + "kwh")

# 計測回路ごとの使用電力量
url="http://"+host+"/page/setting/installation/734"
response=requests.get(url, auth=HTTPDigestAuth(user,password))
root = html.fromstring(response.content)
elements = root.xpath('//script[contains(text(), "window.onload")]')
for element in elements:
    index = element.text.index('(') + 1
    rindex = element.text.rindex(')')
    json_text = element.text[index:rindex]
    json_dict = json.loads(json_text)
    for circuit in json_dict['arrayCircuitNameList']:
        if (circuit['strBtnType'] == "1"):
            params_dict = {'circuitid':circuit['strId']}
            url="http://"+host+"/page/graph/584?data=" + base64.b64encode(json.dumps(params_dict).encode()).decode()
            response=requests.get(url, auth=HTTPDigestAuth(user,password))
            root = html.fromstring(response.content)
            print(circuit['strId'].rjust(2) + ": " + root.xpath('//span[@id="val_kwh"]')[0].text + "kwh" + " " + circuit['strCircuit'])

実行するとこんな感じになります。

使用電力量: 24.562kwh
買電量: 19.988kwh
売電量: 23.926kwh
発電量: 40.200kwh
 8: 0.000kwh 子供室(1)
 9: 0.000kwh 子供室(2)
10: 0.027kwh 通路吹抜
11: 0.051kwh W.I.Cトイレ(2)
12: 0.315kwh 書斎
13: 0.033kwh 主寝室
14: 1.917kwh キッチン
15: 0.004kwh ダイニング
16: 0.824kwh 畳スペース階段踊場
17: 1.051kwh リビング
18: 1.460kwh ファミリクローゼット
19: 0.047kwh ホールトイレ(1)SIC
20: 0.044kwh ランドリー
21: 0.047kwh バスコア洗面室
22: 0.000kwh 子供室(1)クーラー
23: 0.000kwh 子供室(2)クーラー
24: 0.193kwh 書斎クーラー
25: 1.962kwh 主寝室クーラー
26: 1.348kwh エアーファクトリー
27: 0.011kwh 家電用①
28: 0.000kwh 家電用②
29: 0.505kwh 家電用③
30: 0.007kwh 家電用④
31: 0.161kwh 家電用⑤
32: 0.000kwh キャビネット付
33: 0.894kwh 食洗機
34: 0.145kwh 洗濯機
35: 0.979kwh ライコンスイッチ
36: 0.000kwh 予備
37: 0.000kwh 予備
38: 0.000kwh 電気自動車用①
39: 0.000kwh 電気自動車用②
40: 0.000kwh 浴室乾燥機
41: 5.761kwh 快適エアリー
42: 0.682kwh IHヒーター
43: 2.450kwh ヒートポンプ
44: 0.000kwh 増回路スペース
45: 0.000kwh 増回路スペース
46: 0.000kwh 増回路スペース

実際には、例えばHome AssistantのScrapeなどから呼び出したりするでしょうが、まずはこんな感じで取得できるよということで。

ちなみに、Home Assistantで5分ごとに収集したデータを可視化したのが以下です。

別の機会に、Home Assistantへのデータ取り込みについても記事にします。

コメント

タイトルとURLをコピーしました