E3DC with the new modbus binding

modbus
e3dc
Tags: #<Tag:0x00007f51eae338c8> #<Tag:0x00007f51eae334b8>

(Marco) #1

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. :slight_smile:

  • 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
Modbus%20Binding

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 :nerd_face:

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


(Ssalonen) #2

Excellent tutorial and nice that you shared this!

I hope this kind of work encourages experienced users/developers to contribute device specific bindings on top of the generic modbus binding, so it would reduce the burden for new users with similar devices. Similar to work tried here with sunspec inverters.

This was one of the main design drivers with the new binding, enable hopefully easy way to build device specific bindings.

Btw, installation guide for the binding with openHAB 2.3 is described here: Modbus addon not work at openhab2.3.0


(Frank) #3

I completed the installation of the modbus binding yesterday and got everything to work - including the addition of my E3DC Wallbox.
I have a question regarding the modbus registers for autarky and selfconsumption: When I compare the data displayed in Openhab with the data on the display of the E3DC system, it looks like the two values are interchanged, i.e. what should be autarky is actually the value for selfconsumption and vice versa.
Can you please have a look at this and clarify.
thanks.


(Marco) #4

@ffr thanks for the reply and heads up. Fixed the swaped values in the 1st post.
As you added the a wallbox, you might want to share that configuration here?!


(Frank) #5

@mal Great. :re the Wallbox config: I am only interested displaying the charging power and the PV-charging power in realtime, so uncommented the two things you already put in, created the resp. items and added them to the sitemap… so really pretty easy job based on your excellent work.
Some time in the future, I will start working on some charting, similar to what you show in your post.

I would really like to be able to control the E3DC system via Openhab at some point in time. Anyone of the experts interested in developing a binding for that, using the E3DC RSCP interface?


(Frank) #6

here is my next question: I have a ton of entries in the event log. How can I reduce that effectively? I tried to insert an entry for the modbus binding in the log-config file … but that did not work.
thanks for your help.


(Frank) #7

can anyone please help a newbe out here.
I tried to limit the amount of log entries coming from the E3DC Modbus by adding the following lines to the logging.cfg file, but it did not change the logging level at all :

Custom Log levels

Modbus

log4j2.logger.org_openhab_binding_modbus.name = org.openhab.binding.modbus

log4j2.logger.org_openhab_binding_modbus.level = WARN

log4j2.logger.org_openhab_io_transport_modbus.name = org.openhab.io.transport.modbus

log4j2.logger.org_openhab_io_transport_modbus.level = WARN


(Rossko57) #8

Perhaps that’s the part to fix. What kind of entries? (sample?)


(Frank) #9

all of the entries are “INFO” type entries, I guess … I like to change the logging level to “Warning”.

2018-11-02 16:15:09.921 [vent.ItemStateChangedEvent] - E3DC_Voltage_String2 changed from 518 to 521

2018-11-02 16:15:09.931 [vent.ItemStateChangedEvent] - E3DC_Current_String1 changed from 20 to 21


(Frank) #10

never mind … found a way to get this fixed with a filter added to the log config file
Filters in Log - Config File


(Rossko57) #11

Okeydoke; the logs come from OH Item updating, not Modbus particularly.

You could perhaps poll voltages less often (do you really care about small changes?) but even then I expect you want fairly frequent current polls.


(Alex) #12

Hi Marco,

thank you - so great that you wrote this tutorial.

Unfortunately my Things seems to get no Updates. I think i configured everything right, as my “E3DC Modbus TCP” shows the Status “online”. But all other Things show “Offline-Communication Error”

Do you know where to start my search? I use Openhab 2.4.
image

Thank you in advance
Alex


(Rossko57) #13

Have a look in openhab.log for modbus related messages.


(Rossko57) #14

Just for info - latest version of modbus binding includes a new feature, allowing you to greatly reduce Item updates when polling a value that doesn’t change.


(Stefan Hentschke) #15

Hi, I just went through your instructions step by step.
I would also like to have the graphic from the top of your description.
I have the whole thing installed on the Raspberry.
Can you help me?
What can I post here to make you transparent where my mistake lies?
Thank you.


(Juergen Meyer) #16

Danke für die Anleitung.
Ich hatte Openhab 2.3 mit funktionierendem Modus Bindung für E3DC. Nach der Aktualisierung auf Openhab 2.4 funktioniert es nicht mehr.

Mit dieser Anleitung hab ich das Modbus Binding für meine E3DC-Anlage wieder hingekriegt.

Lediglich der Wert für den Hausverbrauch wird nicht korrekt ausgelesen:

Thing data Consumption “E3DC Consumption” [ readStart=“71”, readValueType=“int32_swap”]

Number E3DC_Haus “E3DC Hausverbrauch” <poweroutlet> (E3DC) { channel=“modbus:data:e3dc:polling:Consumption:number” }

Ich hab Thing und Item schon gelöscht und neu angelegt. Lt. log wird der Wert einmalig ermittelt (aber mit nem falschen Wert) … dann erfolgt kein Update mehr.

Wie komm ich dem Fehler auf die Spur ?
Danke

Jürgen