太陽光発電のダッシュボード(EPEVERチャージコントローラー、RaspberryPi)備忘録
今回は太陽電池でバッテリーを充電する装置「チャージコントローラー」についてです。
このページではRaspberryPi(ラズパイ)を使って、EPEVERのチャージコントローラーから発電・充電の情報を読み取り、ダッシュボードに表示する方法をまとめます。
- チャージコントローラーの簡単な説明
- 今回の環境、機材
- ラズパイのセットアップ
- チャージコントローラーのデータ読み取り
- データのダッシュボード表示
チャージコントローラーの簡単な説明
チャージコントローラーは、太陽電池で発電した電力をバッテリーに充電する装置です。太陽電池をキャンピングカーに載せたり、災害時の非常電源として設置する様な場合には、チャージコントローラーが必要です。
チャージコントローラーの主な機能は2つあります。
- 太陽電池の電力をバッテリーへ充電する
- 太陽電池から効率良く電力を取り出す
【バッテリーへ充電する】
太陽電池をバッテリーに繋ぐだけでは、ほとんど充電されません。バッテリーの種類、定格、充電状態に合わせて、充電電圧を調整する必要があります。充電電圧を調整しないとバッテリーの寿命が短くなったり、最悪ではバッテリーが破損してしまいます。
【効率良く電力を取り出す】
太陽電池で発電された電力を効率良く取り出す為に、発電量に応じて取り出す電圧・電流をリアルタイムで調整する必要があります。今回のチャージコントローラーはMPPT方式で効率90%以上を達成しているようです。
下の記事のように、チャージコントローラーとバッテリーが1つになっている一体型の製品もあります。
家庭で使う場合には、一体型の方が使い勝手が良いかもしれません。
今回の環境、機材
- Raspberry Pi 3 Model B
- Raspberry Pi OS Lite (Released: 2021-05-07)
- Python 3.7.3
- チャージコントローラー: Epever TRACER6415AN
- USB通信ケーブル(Modbus RS485): Epever CC-USB-RS485-150U
- 全体の構成:
余談ですが、チャージコントローラーの各種設定には公式から提供されているWindows版ツールを利用する方が断然お勧めです(Charge Controller V1.95)。Android版アプリは使いずらかったです。
ラズパイのセットアップ
USB通信ケーブルをラズパイと接続すると、動作しないドライバーが有効になってしまいます。ドライバーが通信ケーブルのチップと合ってないようです。
幸いなことに動作するドライバーがgithubで公開されているので、手動でインストールします。
ドライバーのインストール
# git/kernel-headersをインストール
$ sudo apt update
...
$ sudo apt install git raspberrypi-kernel-headers
...
# ドライバーのソースを取得
$ git clone https://github.com/kasbert/epsolar-tracer
...
# ドライバーのコンパイル、インストール
$ cd ./epsolar-tracer/xr_usb_serial_common-1a
$ make
...
$ sudo make modules_install
...
DEPMOD 5.10.52-v7+
Warning: modules_install: missing 'System.map' file. Skipping depmod.
make[1]: Leaving directory '/usr/src/linux-headers-5.10.52-v7+'
# depmodの手動実行
$ cd /lib/modules/<KernelVer>/ # <- 今回のKernelVerは"5.10.52-v7+"
$ sudo depmod
# ドライバーのロード設定、動作しないドライバーをブラックリストへ
$ echo "xr_usb_serial_common" | sudo tee /etc/modules-load.d/xr_usb_serial_common.conf
$ echo "blacklist cdc-acm" | sudo tee /etc/modprobe.d/blacklist-cdc-acm.conf
$ sudo reboot
(ラズパイを再起動します)
新しいドライバーが有効になっている事を確認
下のコマンドで"ttyXRUSB0"が表示されると、新しいドライバーでUSB通信ケーブルが動作しています。
$ ls -l /dev/tty*
...
crw-rw---- 1 root dialout 266, 0 Aug 21 06:16 /dev/ttyXRUSB0
動作しないドライバーが有効になっている場合は、"/dev/ttyACM0"が表示されます。
チャージコントローラーのデータ読み取り
通信ケーブルが使えるようになったので、データの読み取り先(レジスタのアドレス)を知らないといけません。このアドレスについてもPDFファイルでデータが公開されていました。
レジスタリスト(Read onlyの一部)
# アドレス | 説明 | 単位 |
| 0x3100 | 太陽電池の電圧 | V *100 |
| 0x3101 | 太陽電池の電流 | I *100 |
| 0x3102 | 太陽電池の電力 | W *100 |
| 0x3104 | バッテリーの電圧 | V *100 |
| 0x3105 | バッテリーの電流 | I *100 |
| 0x3106 | バッテリーの電力 | W *100 |
| 0x310C | 負荷の電圧 | V *100 |
| 0x310D | 負荷の電流 | I *100 |
| 0x310E | 負荷の電力 | W *100 |
| 0x3110 | バッテリーの温度 | ℃ *100 |
| 0x3111 | 装置内部の温度 | ℃ *100 |
Pythonスクリプト(データ読み取り、表示)
今回は、電圧、電流、温度をpythonスクリプトで読み取ります。
$ pip3 install pymodbus
(RS485 ModBusモジュールのインストール)
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
import pymodbus
reg_base = 0x3100
reg_max = 18
# read data
client = ModbusClient(method = 'rtu', port = '/dev/ttyXRUSB0', baudrate = 115200)
client.connect()
try:
result = client.read_input_registers(reg_base, reg_max, unit=1)
except pymodbus.exceptions.ConnectionException:
print('Read error')
exit()
client.close()
# print data
print("Photovoltaics voltage [V]", float(result.registers[0] / 100.0))
print("Photovoltaics current [A]", float(result.registers[1] / 100.0))
print("Battery voltage [V]", float(result.registers[4] / 100.0))
print("Battery current [A]", float(result.registers[5] / 100.0))
print("Battery temperature [deg]", float(result.registers[16] / 100.0))
print("Equipment temperature [deg]", float(result.registers[17] / 100.0))
"reg_max"を範囲外の大きな値に指定すると、スクリプトがエラーになってしまいます。機種によって読み取れるデータの種類、数が変わるようです。
スクリプトの実行結果は下のようになります。
Photovoltaics voltage [V] 84.3
Photovoltaics current [A] 0.29
Battery voltage [V] 27.7
Battery current [A] 0.92
Battery temperature [deg] 23.84
Equipment temperature [deg] 27.7
データのダッシュボード表示
以前の記事の通りに作業をして、チャージコントローラーのデータをダッシュボードに表示してみました。
データ取得スクリプト
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
import pymodbus
import influxdb
from datetime import datetime
from time import sleep
reg_base = 0x3100
reg_max = 28
influx = influxdb.InfluxDBClient(
host='localhost',
port=8086,
database='epever'
)
def get_data():
# read data
client = ModbusClient(method = 'rtu', port = '/dev/ttyXRUSB0', baudrate = 115200)
client.connect()
try:
result = client.read_input_registers(reg_base, reg_max, unit=1)
json_point = [{
'measurement': "pv_data",
'tags': {'chargecontroller': "tracer6415an"},
'fields': {
'pv_v': float(result.registers[0] / 100.0),
'pv_i': float(result.registers[1] / 100.0),
'bat_v': float(result.registers[4] / 100.0),
'bat_i': float(result.registers[5] / 100.0),
'bat_t': float(result.registers[16] / 100.0),
'cc_t': float(result.registers[17] / 100.0)
}
}]
#print(json_point)
influx.write_points(json_point)
except pymodbus.exceptions.ConnectionException:
print('Read error')
client.close()
while( True ):
now_time = datetime.now() # time control
if (now_time.second > 30):
get_data()
sleep(30)
sleep(1)
ダッシュボードに表示(Grafana)
読み取った電圧と電流から電力のグラフを表示してみました。データを計算してグラフにする方法は以前の記事に追記します。
この日はフルパワーで発電しているように見えたのですが、グラフにしてみると電力がものすごくギザギザしてました。チャージコントローラーが故障していないか後で調べてみます。
おわりに
今回はドライバーのインストールに手こずりましたが何とかできました。
最近は趣味で調べた事を、記録代わりに記事にしてます。調べた事をかたちにすると、後で自分でも見やすいので良いですね。