A villanyszámlánk csökkentése érdekében kiépítettünk egy szigetüzemű napelemes rendszert, ennek a központi egysége egy PowMr 5600W All In One hibrid inverter.
PowMr 5600W All In One hibrid inverter
Tiszta szinuszos napelemes hibrid inverter, 48V DC, 220V/230V AC, 5600W-os névleges teljesítmény beépített 80A MPPT töltésvezérlő egyesítve az inverterben.
A hibrid inverter LCD kijelzővel rendelkezik, amely valós időben mutatja a rendszeradatokat és az üzemállapotot.
Alkalmas 48 V-os ólom-savas vagy lítium akkumulátorhoz.
hirdetés
A napelemes rendszerünk lehető legjobb kihasználásához szükségünk van az inverter monitorozására. Tudnunk kell, hogy mennyi áramot termel a napelem, vagy mennyi energiát tárol az akkumulátorcsomag.
A PowMr 5600W All In One hibrid inverter rendelkezik egy USB portal is, én oda csatlakoztattam egy Raspberry Pi 3 modellt, de erre a feladatra tökéletes lehet egy kedvező árú Raspberry pi zero is.
A Raspberry Pi-n futó Python script segítségével kiolvassuk az adatokat az inverterből és továbbitjuk az iobrokeren futó mqtt szerverre.
A PowMr is mint sok hasonló inverter (pl: ESUN, Deye, stb.) SRNE Modbus-RTU kommunikációs protokollt használ.
Hogy python script komunikáljon az inverterrel, szükségünk van a MinimalModbus könyvtárra. Ezt a python csomagtelepítőjével könnyedén megtehetjük. Ha még nincs telepítve, telepítsük a pip csomagtelepítőt, majd telepítsük a MinimalModbus könyvtárat.
sudo apt-get update
sudo apt-get install python3-pip
pip3 install -U minimalmodbus
A minimalmodbus használatához a python scriptünkben elöször importáljuk a könyvtárat.
#!/usr/bin/python3
import minimalmodbus
...
Majd létrehozunk egy példányt és megadjuk a beállításokat.
...
# minimalmodbus.Instrument(port, slave_address, mode)
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1, 'rtu')
instrument.serial.baudrate = 9600
instrument.serial.bytesize = 8
instrument.serial.parity = 'N'
instrument.serial.stoppbits = 1
instrument.serial.timeout = 0.2
instrument.mode = minimalmodbus.MODE_RTU
instrument.clear_buffers_before_each_transaction = True
Az inverter regisztereit a read_register függvénnyel tudjuk kiolvasni.
# read_register(registeraddress, number_of_decimals, functioncode)
battery_remaining = instrument.read_register(0x100, 1, 3)*10
12V 100Ah LiFePO4 Lithium Akku
1280Wh, 100A BMS, akár 15000 töltési ciklus.
Jó választás naplemes rendszerekhez is.
hirdetés
Az mqtt szerverrel való kommunikációhoz a paho-mqtt könyvtárat fogjuk használni. Ha meg nem tettük meg, telepítsük az alábbi módon.
pip3 install paho-mqtt
Importáljuk a paho-mqtt könyvtárat is.
#!/usr/bin/python3
import minimalmodbus
from paho.mqtt import client as mqtt_client
...
Csatlakozási adatok megadása az mqtt szerverhez.
...
broker = '192.168.1.180'
port = 1883
username = ''
password = ''
client_id = 'PowMr-client'
...
Szükségünk van egy függvényre a csatlakozáshoz az mqtt szerverhez.
def connect_mqtt():
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to ioBroker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
Az MQTT-üzenetek közzétételéhez is kell egy függvény.
def publish(client, topic, payload):
result = client.publish(topic, payload)
status = result[0]
if status == 0:
print(f"Send `{payload}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
Végül a run függvény. Csatlakozunk az mqtt szerverhez, kiolvassuk az inverterből a kívánt adatokat és elküldjük az mqtt szerverre.
def run():
client = connect_mqtt()
client.loop_start()
while(1):
try:
battery_remaining = instrument.read_register(0x100, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/parameters/battery_remaining", battery_remaining)
except:
print("Failed to read the battery_remaining")
Ezekre esetleg szükség lehet:
hirdetés
Hozzuk létre az inverter.py fájlt.
nano inverter.py
Majd másoljuk be az alábbi kódot.
#!/usr/bin/python3
import time
import subprocess
import minimalmodbus
from paho.mqtt import client as mqtt_client
delay = 1
broker = '192.168.1.180'
port = 1883
username = ''
password = ''
client_id = 'PowMr-client'
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1, 'rtu')
instrument.serial.baudrate = 9600
instrument.serial.bytesize = 8
instrument.serial.parity = 'N'
instrument.serial.stoppbits = 1
instrument.clear_buffers_before_each_transaction = True
instrument.serial.timeout = 0.2
instrument.mode = minimalmodbus.MODE_RTU
def connect_mqtt():
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to ioBroker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client, topic, payload):
result = client.publish(topic, payload)
status = result[0]
if status == 0:
print(f"Send `{payload}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
def run():
client = connect_mqtt()
client.loop_start()
while(1):
try:
battery_remaining = instrument.read_register(0x100, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/parameters/battery_remaining", battery_remaining)
except:
print("Failed to read the battery_remaining")
time.sleep(delay)
try:
battery_voltage = instrument.read_register(0x101, 1, 3)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/battery_voltage", battery_voltage)
except:
print("Failed to read the battery_voltage")
time.sleep(delay)
try:
battery_current = instrument.read_register(0x102, 1, 3, True)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/battery_current", battery_current)
except:
print("Failed to read the battery_current")
time.sleep(delay)
try:
pv_power = instrument.read_register(0x109, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/parameters/pv_power", pv_power)
except:
print("Failed to read the pv_power")
time.sleep(delay)
try:
pv_voltage = instrument.read_register(0x107, 1, 3)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/pv_voltage", pv_voltage)
except:
print("Failed to read the pv_voltage")
time.sleep(delay)
try:
pv_current = instrument.read_register(0x108, 1, 3)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/pv_current", pv_current)
except:
print("Failed to read the pv_current")
time.sleep(delay)
try:
battery_charge_status = instrument.read_register(0x10B, 1, 3)*10
if battery_charge_status == 0: batt_charge_status = "0 - Töltés kikapcsolva"
elif battery_charge_status == 1: batt_charge_status = "1 - Gyorstöltés"
elif battery_charge_status == 2: batt_charge_status = "2 - Állandó feszültségű töltés"
elif battery_charge_status == 3: batt_charge_status = "3 ---"
elif battery_charge_status == 4: batt_charge_status = "4 - Lebegő töltés"
elif battery_charge_status == 5: batt_charge_status = "5 ---"
elif battery_charge_status == 6: batt_charge_status = "6 - Li akkumulátor aktiválása"
elif battery_charge_status == 7: batt_charge_status = "7 ---"
publish(client,"Photovoltaik-Anlage/Inverter/parameters/battery_charge_status", batt_charge_status)
except:
print("Failed to read the battery_charge_status")
time.sleep(delay)
try:
inverter_current_status = instrument.read_register(0x210, 1, 3)*10
if inverter_current_status == 0: inverter_status = "0 - Bekapcsolási késleltetés"
elif inverter_current_status == 1: inverter_status = "1 - Várakozás"
elif inverter_current_status == 2: inverter_status = "2 - Inicializálás"
elif inverter_current_status == 3: inverter_status = "3 - Lágy indítás"
elif inverter_current_status == 4: inverter_status = "4 - Működés hálózatról"
elif inverter_current_status == 5: inverter_status = "5 - Inverteres működés"
elif inverter_current_status == 6: inverter_status = "6 - Inverter a hálózatra"
elif inverter_current_status == 7: inverter_status = "7 - Hálózat az inverterhez"
elif inverter_current_status == 8: inverter_status = "8 - Akkumulátor aktiválva"
elif inverter_current_status == 9: inverter_status = "9 - Felhasználó általi leállítás"
elif inverter_current_status == 10: inverter_status = "10 - Hiba"
publish(client,"Photovoltaik-Anlage/Inverter/parameters/inverter_status", inverter_status)
except:
print("Failed to read the inverter_status")
time.sleep(delay)
try:
load_current = instrument.read_register(0x219, 1, 3)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/load_current", load_current)
except:
print("Failed to read the load_current")
time.sleep(delay)
try:
loadpower = instrument.read_register(0x21B, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/parameters/load_power_W", loadpower)
except:
print("Failed to read the load_power_W")
time.sleep(delay)
try:
mains_charging_current = instrument.read_register(0x21E, 1, 3)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/mains_charging_current", mains_charging_current)
except:
print("Failed to read the mains_charging_current")
time.sleep(delay)
try:
load_rate = instrument.read_register(0x21F, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/parameters/load_rate", load_rate)
except:
print("Failed to read the load_rate")
time.sleep(delay)
try:
temp_dcdc = instrument.read_register(0x220, 1, 3, True)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/temp_dcdc", temp_dcdc)
except:
print("Failed to read the temp_dcdc")
time.sleep(delay)
try:
temp_dcac = instrument.read_register(0x221, 1, 3, True)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/temp_dcac", temp_dcac)
except:
print("Failed to read the temp_dcac")
time.sleep(delay)
try:
temp_trans = instrument.read_register(0x222, 1, 3, True)
publish(client,"Photovoltaik-Anlage/Inverter/parameters/temp_transformer", temp_trans)
except:
print("Failed to read the temp_transformer")
time.sleep(delay)
# fault codes
try:
current_fault_code_1 = instrument.read_register(0x204, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/fault_codes/current_fault_code_1", current_fault_code_1)
except:
print("Failed to read the current_fault_code_1")
time.sleep(delay)
try:
current_fault_code_2 = instrument.read_register(0x205, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/fault_codes/current_fault_code_2", current_fault_code_2)
except:
print("Failed to read the current_fault_code_2")
time.sleep(delay)
try:
current_fault_code_3 = instrument.read_register(0x206, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/fault_codes/current_fault_code_3", current_fault_code_3)
except:
print("Failed to read the current_fault_code_3")
time.sleep(delay)
try:
current_fault_code_4 = instrument.read_register(0x207, 1, 3)*10
publish(client,"Photovoltaik-Anlage/Inverter/fault_codes/current_fault_code_4", current_fault_code_4)
except:
print("Failed to read the current_fault_code_4")
time.sleep(delay)
instrument.serial.close()
if __name__ == '__main__':
run()
Ha kész a fájlunk, mentsük el. Most el kell érni, hogy automatikusan elinduljon a rendszer indításakor. Ehez egy újabb fájlra van szükségünk.
sudo nano /etc/systemd/system/inverter.service
A fájlba másoljuk be az alábbi pár sort. Ne felejtsük el fájl elérési útját helyesen megadni!
[Unit]
Description=inverter-service
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=idle
User=username
ExecStartPre=/bin/sleep 30
ExecStart=/usr/bin/python3 /home/pi/inverter.py
Restart=always
[Install]
WantedBy=multi-user.target
Állítsuk be a jogosultságokat az alábbiak szerint.
sudo chmod 644 /etc/systemd/system/inverter.service
Indítsuk újra a systemctl háttérszolgáltatást.
sudo systemctl daemon-reload
Engedélyezzük az inverter.service szolgáltatást.
sudo systemctl enable inverter.service
Igy már minden rendszerindításkor futni fog az inverter.py és a kiolvasott adatokat elküldi az mqtt szervernek.
hirdetés
Az SRNE modbus protokollról és egyes regiszterekről az alábbi pdf dokumentumban találhatunk bövebb információt. Ennek segítségével egyéni igényeinknek megfelelően alakíthatjuk az inverter.py fájlt.