Smart Home vs GoodWe
In the post, we will demonstrate step by step how to communicate directly with the Goodwe inverter in a smart home setup and obtain real-time information (unlike the SEMS portal). This information is essential if we want to react to current parameters in a smart home, such as activating additional cooling or controlling a socket with a load.
Hardware
Pi-Home - if you don't have it, see the section How To
Software
OpenHAB 3
Procedure:
1) We will connect via SSH to the Raspberry and verify if we have the pip3 manager for Python libraries installed:
sudo apt install python3-pip
then we will install the goodwe library:
sudo pip3 install goodwe
2) We will navigate to the scripts directory for OpenHAB, create a file named "goodwejson.py," and test the communication:
cd /etc/openhab/scripts
sudo nano goodwejson.py
Insert the following content here, replacing the IP address marked in red with your actual GoodWe inverter's IP address:
import asyncio
import goodwe
asyncdef get_runtime_data():
ip_address = '192.168.1.100'
sensors = [
"ppv", # PV total power (W)
"ppv1", # PV1 power (W)
"ppv2", # PV2 power (W)
"temperature", # Inverter Temp Radiator
"temperature_air", # Inverter Temp Air
"battery_temperature", # battery temperature
"pbattery1", # battery power (W) + = charging, - = discharging
"battery_mode", # 1=standby, 2=discharge, 3=charge
"battery_soc", # battery state of charge (%)
"active_power", # grid power (W): - = buy, + = sell
"grid_in_out", # 1=sell or export, 2=buy or import
"house_consumption", # own consumption (W)
"e_day", # today's PV energy production (kWh)
"e_total", # total PV energy production (kWh)
"meter_e_total_exp", # total sold (exported) energy (kWh)
"meter_e_total_imp" # total bought or imported energy (kWh)
]
inverter = await goodwe.connect(ip_address)
runtime_data = await inverter.read_runtime_data()
print(f'{{')
for sensor in inverter.sensors():
if sensor.id_ in runtime_data:
if sensor.id_ in sensors:
print(f'"{sensor.id_}": {runtime_data[sensor.id_]},')
print(f'"end": 0')
print(f"}}")
asyncio.run(get_runtime_data())
save by pressing the CTRL+O keyboard shortcut, confirm with Enter, and exit the nano editor by pressing CTRL+X.
Test if the script fetches current data, for example:
python3 goodwejson.py
3) Create another script in the same folder, named goodwe.sh:
sudo nano goodwe.sh
and paste following content:
#!/bin/bash
RESULT=$(python3 /etc/openhab/scripts/goodwejson.py)
echo"$RESULT"| tr '\n'' '
Save using the keyboard shortcut CTRL+O, confirm with Enter, and exit the nano editor (CTRL+X)
Let's also run a command regarding the permission settings for the file:
sudo chmod 744 goodwe.sh
and add it to the exec.whitelist file to allow execution:
sudo nano /etc/openhab/misc/exec.misc
It should contain the following:
# For security reasons, all commands used by the exec binding or transformation need to be whitelisted.
# Each command needs to be listed on a separate line below.
bash /etc/openhab/scripts/goodwe.sh
Save using the keyboard shortcut CTRL+O, confirm with Enter, and exit the nano editor (CTRL+X).
4) Let's create a .things file for OpenHAB, where we define the script and execution frequency (according to forum information, do not go below 30 seconds, as it might block your SEMS portal)
sudo nano /etc/openhab/things/exec.things
Insert the following content:
exec:command:goodwe_json [command="bash /etc/openhab/scripts/goodwe.sh", interval=30, timeout=10, autorun=false]
Save using the keyboard shortcut CTRL+O, confirm with Enter, and exit the nano editor (CTRL+X).
5) Define the .items file for OpenHAB - definition of custom objects
sudo nano /etc/openhab/items/goode.items
Insert the following content:
String ZP_JSON_Out "[%s]" {channel="exec:command:goodwe_json:output"}
Number:Energy zpPv "zpPv [%.0f W]" <energy>
Number:Energy zpPv1 "zpPv [%.0f W]" <energy>
Number:Energy zpPv2 "zpPv [%.0f W]" <energy>
Number:Energy zpIRad "zpPv [%.1f °C]" <energy>
Number:Energy zpIAir "zpPv [%.1f ˚C]" <energy>
Number:Energy zpBatteryTemp "zpPv [%.1f °C]" <energy>
Number:Energy zpBattery "zpBattery [%.0f W]" <battery>
Number zpBatteryStatus "zpBatteryStatus [%d]" <battery>
Number zpSoc "zpSoc [%d %]" <battery>
Number:Energy zpActivePower "zpActivePower [%.0f W]" <energy>
Number zpGridStatus "zpGridStatus [%d]"
Number:Energy zpConsumption "zpConsumption [%.0f W]" <energy>
Number:Energy zpEday "zpEday [%.1f kWh]" <energy>
Number:Energy zpEtotal "zpEtotal [%.0f kWh]" <energy>
Number:Energy zpEtotalExp "zpEtotalExp [%.0f kWh]" <energy>
Number:Energy zpEtotalImp "zpEtotalImp [%.0f kWh]" <energy>
Save using the keyboard shortcut CTRL+O, confirm with Enter, and exit the nano editor (CTRL+X).
6) Finally, we define the .rules file for OpenHAB - value transformations
sudo nano /etc/openhab/rules/goode.rules
Insert the following content:
rule "ZP JSON transform"
when
Item ZP_JSON_Out changed
then
val Pv = transform("JSONPATH","$.ppv",ZP_JSON_Out.state.toString)
val Pv1 = transform("JSONPATH","$.ppv1",ZP_JSON_Out.state.toString)
val Pv2 = transform("JSONPATH","$.ppv2",ZP_JSON_Out.state.toString)
val InvRadTemp = transform("JSONPATH","$.temperature",ZP_JSON_Out.state.toString)
val InvAirTemp = transform("JSONPATH","$.temperature_air",ZP_JSON_Out.state.toString)
val BatteryTemp = transform("JSONPATH","$.battery_temperature",ZP_JSON_Out.state.toString)
val Battery = transform("JSONPATH","$.pbattery1",ZP_JSON_Out.state.toString)
val BatteryStatus = transform("JSONPATH","$.battery_mode",ZP_JSON_Out.state.toString)
val Soc = transform("JSONPATH","$.battery_soc",ZP_JSON_Out.state.toString)
val ActivePower = transform("JSONPATH","$.active_power",ZP_JSON_Out.state.toString)
val GridStatus = transform("JSONPATH","$.grid_in_out",ZP_JSON_Out.state.toString)
val Consumption = transform("JSONPATH","$.house_consumption",ZP_JSON_Out.state.toString)
val Eday = transform("JSONPATH","$.e_day",ZP_JSON_Out.state.toString)
val Etotal = transform("JSONPATH","$.e_total",ZP_JSON_Out.state.toString)
val EtotalExp = transform("JSONPATH","$.meter_e_total_exp",ZP_JSON_Out.state.toString)
val EtotalImp = transform("JSONPATH","$.meter_e_total_imp",ZP_JSON_Out.state.toString)
zpPv.postUpdate(Pv)
zpPv1.postUpdate(Pv1)
zpPv2.postUpdate(Pv2)
zpIRad.postUpdate(InvRadTemp)
zpIAir.postUpdate(InvAirTemp)
zpBatteryTemp.postUpdate(BatteryTemp)
zpBattery.postUpdate(Battery)
zpBatteryStatus.postUpdate(BatteryStatus)
zpSoc.postUpdate(Soc)
zpActivePower.postUpdate(ActivePower)
zpGridStatus.postUpdate(GridStatus)
zpConsumption.postUpdate(Consumption)
zpEday.postUpdate(Eday)
zpEtotal.postUpdate(Etotal)
zpEtotalExp.postUpdate(EtotalExp)
zpEtotalImp.postUpdate(EtotalImp)
end
Save using the keyboard shortcut CTRL+O, confirm with Enter, and exit the nano editor (CTRL+X).
Done. Now, take a look at OpenHAB under Items, and the information should be displayed and updated for you. You can download the Widget from this thread: https://community.openhab.org/t/animated-energy-widget/133510 and insert your GoodWe values there.
Examples of dashboards with installed PV systems:
Add comment