ZABBIXで太陽光発電システム(JH-RWL3)をモニタリングする


 前回、初めての検針結果を貼ってみたが、月に1回の検針結果だけで売電量などが分かるのはあまり効率もよくない。電力モニタ JH-RWL3 でも確認はできるが、粒度は 1 時間単位とそんなに細かくはない。

 ただ、JH-RWL3 には lighttpd による Web サーバ機能があり、LAN 越しにもアクセスすることができる。そのため、ZABBIX で 30 秒ごとにデータを取得するようにしてみた。

 JH-WRL3 のトップページには消費電力量、発電量、売電量が表示されている。売電量 = 発電量 – 消費電力量なので、とりあえずは消費電力量と発電量を取りたい。そこで HTML ソースを確認してみると、いわゆる <table> コーディングで

<table border="0" cellpadding="0" cellspacing="0" width="230" summary="消費">
<tr>
<td rowspan="2" width="107"><img src="aicon02.gif" width="90" height="90" alt="消費マーク"></td>
<td height="50" colspan="2"><img src="topttl02.gif" width="123" height="50" alt="消費マーク"></td>
</tr>
<tr><td align="right" width="95"><span class="data_top">
<!-- ここから消費量表示 -->0.61<!-- ここまで消費量表示 --></span></td>
<td align="right" width="28"><img src="kw.gif" width="28" height="32" alt="kW"></td>
</tr>
</table>

<!-- 売買センサーがある場合はここまで出力する -->
<!-- 売買センサーが無い場合はここから出力する -->

<!-- 売買センサーが無い場合はここまで出力する -->

</td>
<td width="303" align="center" valign="middle" height="170" background="topback02.jpg">
<table border="0" cellpadding="0" cellspacing="0" width="230" summary="発電">
<tr>
<td rowspan="2" width="107"><img src="aicon01.gif" width="90" height="90" alt="発電マーク"></td>
<td height="50" colspan="2"><img src="topttl01.gif" width="123" height="50" alt="発電マーク"></td>
</tr>
<tr><td align="right" width="95"><span class="data_top">
<!-- ここから発電量表示 -->2.50<!-- ここまで発電量表示 --></span></td>
<td align="right" width="28"><img src="kw.gif" width="28" height="32" alt="kW"></td>
</tr>
</table>

となっている。つまり、単純に正規表現で

 /<!-- ここから発電量表示 -->([0-9\.]+)<!-- ここまで発電量表示 -->/

と書くだけで発電量を取得できることになる。あとは HTTP クライアントで HTML を持ってくれば必要なデータはいつでも取れることになる。

 そこで、今回は Ruby で書いてみた。エラー処理周りについては、今回はプライベートなものなのであまり考えないようにしておくことにする。まず、HTTP 周りは net-http で

require 'net/http'
require 'nkf'

def http (url)
  url = URI.parse(url)
  response = Net::HTTP.start(url.host, url.port) do |http|
    http.get(url.path)
  end
  response.code == '200' ? NKF.nkf('--utf8 -d', response.body) : nil
rescue
  nil
end

といった感じになる。出力される HTML は ShiftJIS なので、UTF-8 に文字コード変換している。

 次にパースする部分だが、今回は消費電力量と発電量でフォーマットがほぼ変わらないのので、同時に取得してハッシュで返す形式にする。

def parse (source)
  status = {}
  {
    '消費量' => 'consumed',
    '発電量' => 'generated'
  }.each do |target, key|
    if source =~ /<!-- ここから#{target}表示 -->([0-9\.]+)<!-- ここまで#{target}表示 -->/
      status[key] = $1.to_f
    end
  end
  status
end

 あとはこれを組み合わせて、消費電力量または発電量を標準出力に書き出すようにすればいい。今回は割と書き捨てっぽく、コマンドライン引数でハッシュのキーを渡し、それに対応する値を出力するようにした。ZABBIX で問題なく稼働させられればいいので、例外処理はほぼ行なっていない。

source = http('http://192.168.1.7/pc/')
if source.nil?
  puts "0.0"
else
  data = parse()
  puts data[ARGV[0]].to_f
end

 これで読み出しスクリプト側は完成したので、zabbix_agentd.conf を修正して ZABBIX エージェントからコマンドを実行し、値を取得できるようにする。

UserParameter=env.photovoltaic.consumed,/usr/bin/ruby /path/to/update_solar_status.rb consumed
UserParameter=env.photovoltaic.status,/usr/bin/ruby /path/to/update_solar_status.rb status

 ZABBIX エージェントを再起動すれば、ZABBIX エージェント経由で消費電力量と発電量を記録できるようになる。あとは ZABBIX 側で設定すれば、各種監視やグラフ化が可能となる。

ZABBIXでグラフ化した消費電力量と発電量
ZABBIXでグラフ化した消費電力量と発電量

 今回は ZABBIX でデータを蓄積しているが、これにより、太陽光発電が正常稼動しているかを ZABBIX で監視することも可能となる。一般家庭では待機電力や冷蔵庫などがあり、通常は消費電力が 0kWh になることはほぼあり得ない。そのため、消費電力が 0kWh になれば何かしら問題が発生していることがわかる。

 これ以外にも、連系運転中は必ず「現在の状況」が「連系運転中」「連系準備中」「自動停止中」のどれかになる。「現在の状況」を正規表現で取得し、この3パターンに一致するか否かで太陽光発電システムが正常かどうしているかを判定することも可能となる。

 当然ながら、ZABBIX にこだわらなくても RRDTool や自前実装なども可能となる。我が家では他に、東京電力との契約形態を変更するかの判断材料として、「今日の実績」を1時間おき、毎時 59 分に取得し、1時間あたりの消費電力量と発電量を保存するようにしている。JR-WRL3 側の仕様にほぼ変更はないことから、一度データを取得できれば後はロングスパンで色々と有用なデータの蓄積が可能となる。太陽光発電システム導入の際は、ぜひこういった遊べる要素も考慮に入れることをおすすめしておきたい。