E3DC via Modbus TCP
I started using OH last year. Loved I PaperUI so far. Until the new Modbus binding came in… to much configuration. So I switched to config files, which I’d like to share with you.
This work is based on information of Modbus E3/DC photovoltaic system Uint8+Uint8 and Modbus openHAB2 binding available for alpha testing.
The new Modbus binding is included in the upcoming Openhab 2.4 (Snapshot). You can also install the binding manually in version 2.3.
some notes
-
The latest E3DC Modbus documentation can be loaded here
-
This configuration uses the E3/DC Simple-Mode - I have to investigate on the Sunspec-Mode yet
-
Didn’t configure any wallbox (due to the lack of), but I can assist you in configuration (and then update this thread)
-
Depending on you E3DC Model some values are not used
-
If you don’t use Openhabian, I assume you know how to access the needed directories. In this sample we edit in windows and write the files via Samba share to Openhabian on a raspberry
-
Thing and item names in english, item labels in german. personal preference.
-
This is not meant to be perfect comments and improvements are welcome!
what you will get using this tutorial
STEP 1 - The foundation
Activte ModbusTCP in your E3DC, which will make Modbus TCP available on port 502. (See manual, currently chapter 5.4.9 Smart-Funktionen > Smart Home > Modbus
)
STEP 2 - The binding
Openhab 2.4+
Install the Modbus binding
Openhab 2.3
Download the file org.openhab.binding.modbus-2.4.0-SNAPSHOT.jar and copy it to \\openhabianpi\openHAB-share\openhab2-addons
OpenHab will then automatically load the Binding. Updates go the same way: Download and overwrite the old file.
STEP 3 - The things
(yes, each data object is a thing). Place the file E3DC.things
with the following content in the configuration folder
(\\openhabianpi\openHAB-conf\things)
- Important: Replace 192.168.0.50 in
host="192.168.0.50"
with eiteher the ip address of your E3DC or a the DNS name. - I inverted Battery and External values. So everything that goes in the hous is a positive value. Everything that goes out (net or battery) is negative. personal preference. If you don’t want this, just drop the
,readTransform="JS(invertValue.js)"
- The polling cycle is set to 2 seconds (2000 miliseconds), which is sufficient for my needs:
refresh=2000
Bridge modbus:tcp:e3dc "E3DC Modbus TCP" [ host="192.168.0.50", port=502, id=1 ] {
Bridge poller polling "E3DC Modbus Poller" [ start=0, length=104, refresh=2000, type="holding" ] {
Thing data PV_Inverter "E3DC Inverter" [ readStart="67", readValueType="int32_swap"]
Thing data Battery "E3DC Battery" [ readStart="69", readValueType="int32_swap" ,readTransform="JS(invertValue.js)"]
Thing data Consumption "E3DC Consumption" [ readStart="71", readValueType="int32_swap"]
Thing data Grid "E3DC Grid" [ readStart="73", readValueType="int32_swap"]
Thing data External "E3DC External" [ readStart="75", readValueType="int32_swap" ,readTransform="JS(invertValue.js)"]
//Thing data Wallbox_Power "E3DC Wallbox" [ readStart="77", readValueType="int32_swap"]
//Thing data Wallbox_PV_Power "E3DC Wallbox PV" [ readStart="79", readValueType="int32_swap"]
Thing data SelfConsumption "E3DC SelfConsumption" [ readStart="81.0", readValueType="uint8"]
Thing data Autarky "E3DC Autarky" [ readStart="81.1", readValueType="uint8"]
Thing data SoC "E3DC Battery SoC" [ readStart="82", readValueType="uint16"]
Thing data Emergency_Power_Status "E3DC Emergency Power" [ readStart="83", readValueType="uint16"]
Thing data EMS_Charge_Lock "E3DC EMS charging locked" [ readStart="84.0", readValueType="bit"]
Thing data EMS_DisCharge_Lock "E3DC EMS discharging locked" [ readStart="84.1", readValueType="bit"]
Thing data EMS_Emergency_Power "E3DC EMS emergency enabled" [ readStart="84.2", readValueType="bit"]
Thing data EMS_Wather_Based "E3DC EMS weather based charging" [ readStart="84.3", readValueType="bit"]
Thing data EMS_Output_Cut "E3DC EMS output cut" [ readStart="84.4", readValueType="bit"]
Thing data EMS_Charge_Lock_Time "E3DC EMS charge lock time" [ readStart="84.5", readValueType="bit"]
Thing data EMS_DisCharge_Lock_Time "E3DC EMS discharge lock time" [ readStart="84.6", readValueType="bit"]
Thing data String1_Voltage "E3DC String 1 Voltage" [ readStart="95", readValueType="uint16"]
Thing data String2_Voltage "E3DC String 2 Voltage" [ readStart="96", readValueType="uint16"]
Thing data String3_Voltage "E3DC String 3 Voltage" [ readStart="97", readValueType="uint16"]
Thing data String1_Current "E3DC String 1 Current" [ readStart="98", readValueType="uint16"]
Thing data String2_Current "E3DC String 2 Current" [ readStart="99", readValueType="uint16"]
Thing data String3_Current "E3DC String 3 Current" [ readStart="100", readValueType="uint16"]
Thing data String1_Power "E3DC String 1 Power" [ readStart="101", readValueType="uint16"]
Thing data String2_Power "E3DC String 2 Power" [ readStart="102", readValueType="uint16"]
Thing data String3_Power "E3DC String 3 Power" [ readStart="103", readValueType="uint16"]
}
}
STEP 4 - The items
Save following as E3DC.items
into in the folder \\openhabianpi\openHAB-conf\items
Group E3DC
Number E3DC_PV "E3DC PV Leistung" <solarplant> (E3DC) { channel="modbus:data:e3dc:polling:PV_Inverter:number" }
Number E3DC_Battery "E3DC Batterieleistung" <battery> (E3DC) { channel="modbus:data:e3dc:polling:Battery:number" }
Number E3DC_Haus "E3DC Hausverbrauch" <poweroutlet> (E3DC) { channel="modbus:data:e3dc:polling:Consumption:number" }
Number E3DC_Netz "E3DC Netzleistung" <power> (E3DC) { channel="modbus:data:e3dc:polling:Grid:number" }
Number E3DC_Extern "E3DC externe Leistung" <solarplant> (E3DC) { channel="modbus:data:e3dc:polling:External:number" }
Number E3DC_String1 "E3DC String 1 Leistung" (E3DC) { channel="modbus:data:e3dc:polling:String1_Power:number" }
Number E3DC_String2 "E3DC String 2 Leistung" (E3DC) { channel="modbus:data:e3dc:polling:String2_Power:number" }
Number E3DC_String3 "E3DC String 3 Leistung" (E3DC) { channel="modbus:data:e3dc:polling:String3_Power:number" }
Number E3DC_Voltage_String1 "E3DC String 1 Spannung" (E3DC) { channel="modbus:data:e3dc:polling:String1_Voltage:number" }
Number E3DC_Voltage_String2 "E3DC String 2 Spannung" (E3DC) { channel="modbus:data:e3dc:polling:String2_Voltage:number" }
Number E3DC_Voltage_String3 "E3DC String 3 Spannung" (E3DC) { channel="modbus:data:e3dc:polling:String3_Voltage:number" }
Number E3DC_Current_String1 "E3DC String 1 Strom" (E3DC) { channel="modbus:data:e3dc:polling:String1_Current:number" }
Number E3DC_Current_String2 "E3DC String 2 Strom" (E3DC) { channel="modbus:data:e3dc:polling:String2_Current:number" }
Number E3DC_Current_String3 "E3DC String 3 Strom" (E3DC) { channel="modbus:data:e3dc:polling:String3_Current:number" }
Number E3DC_Autarkie "E3DC Autarkie" (E3DC) { channel="modbus:data:e3dc:polling:Autarky:number" }
Number E3DC_Eigen "E3DC Eigenverbrauch" (E3DC) { channel="modbus:data:e3dc:polling:SelfConsumption:number" }
Number E3DC_SOC "E3DC Ladestand" <batterylevel> (E3DC) { channel="modbus:data:e3dc:polling:SoC:number" }
Number E3DC_Notstrom "E3DC Notstrom Status" (E3DC) { channel="modbus:data:e3dc:polling:Emergency_Power_Status:number" }
Switch E3DC_Ladesperre "E3DC Ladesperre [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_Charge_Lock:number" }
Switch E3DC_Entladesperre "E3DC Entladesperre [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_DisCharge_Lock:number" }
Switch E3DC_Notstrom_aktiv "E3DC Notstrom möglich [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_Emergency_Power:number" }
Switch E3DC_Wetter_aktiv "E3DC Wetterregelung aktiv [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_Wather_Based:number" }
Switch E3DC_Abregelung "E3DC Abregelung [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_Output_Cut:number" }
Switch E3DC_Sperrzeit_Laden "E3DC Sperrzeit Laden [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_Charge_Lock_Time:number" }
Switch E3DC_Sperrzeit_Entladen "E3DC Sperrzeit Entladen [%s]" (E3DC) { channel="modbus:data:e3dc:polling:EMS_DisCharge_Lock_Time:number" }
}
STEP 5 - The function
Only if you want to invert battery and external.
Save following in directory with filename invertValue.js
Save following as invertValue.js
into in the folder \\openhabianpi\openHAB-conf\transform
(function(i) {
return (i * -1);
})(input)
STEP 6 - The map
Only if you want have the emergency power function installed.
To translate integer value states of the emergency power function we use a map.
Save following as e3dc-ems_de.map
in \\openhabianpi\openHAB-conf\transform
0=Nicht unterstützt
1=Aktiv
2=Nicht aktiv
3=Nicht verfügbar
4=Motorschalter steht falsch
or english as e3dc-ems_en.map
0=Not supported
1=Active
2=Inactive
3=n/a
4=Motor switch misaligned
STEP 7 - The sitemap
Save following as E3DC.sitemap
in \\openhabianpi\openHAB-conf\sitemaps
sitemap E3DC label="E3DC" {
Text item=E3DC_PV label="PV Produktion [%s W]" {
Frame label="String 1" {
Text item=E3DC_String1 label="Leistung 1 [%s W]"
Text item=E3DC_Voltage_String1 label="Spannung 1 [%s V]"
Text item=E3DC_Current_String1 label="Strom 1 [%s A]"
}
Frame label="String 2" {
Text item=E3DC_String2 label="Leistung 2 [%s W]"
Text item=E3DC_Voltage_String2 label="Spannung 2 [%s V]"
Text item=E3DC_Current_String2 label="Strom 2 [%s A]"
}
Frame label="String 3" {
Text item=E3DC_String3 label="Leistung 3 [%s W]"
Text item=E3DC_Voltage_String3 label="Spannung 3 [%s V]"
Text item=E3DC_Current_String3 label="Strom 3 [%s A]"
}
}
Text item=E3DC_Extern label="PV Produktion extern [%s W]"
Text item=E3DC_Battery label="Batterieleistung [%s W]"
Text item=E3DC_SOC label="Ladestand [%s %%]"
Text item=E3DC_Haus label="Hausverbrauch [%s W]"
Text item=E3DC_Netz label="Netzleistung [%s W]"
Text item=E3DC_Autarkie label="Autarkie [%s %%]"
Text item=E3DC_Eigen label="Eigenverbrauch [%s %%]"
Text item=E3DC_Notstrom label="E3DC Notstrom Status [MAP(e3dc-ems_de.map):%s]"
Switch item=E3DC_Ladesperre label="E3DC Ladesperre [%s]"
Switch item=E3DC_Entladesperre label="E3DC Entladesperre [%s]"
Switch item=E3DC_Notstrom_aktiv label="E3DC Notstrom möglich [%s]"
Switch item=E3DC_Wetter_aktiv label="E3DC Wetterregelung aktiv [%s]"
Switch item=E3DC_Abregelung label="E3DC Abregelung [%s]"
Switch item=E3DC_Sperrzeit_Laden label="E3DC Sperrzeit Laden [%s]"
Switch item=E3DC_Sperrzeit_Entladen label="E3DC Sperrzeit Entladen [%s]"
}
Thats it.
Step 8 - The chart
This is totally optional. But for me it’s the best part. Watching the curves influenced by the dish washer or dryer is better than netflix
If you use the persistance feature with Grafana you can get sth. like this:
which is more detailed than the graph E3DC offers
Hope I didn’t miss or mess up to much.
Bei Bedarf kann ich das auch nochmal (komplett) auf Deutsch runterschreiben