Modbus binding with Sunny Boy SMA inverter

There sure are some problems… I cant compress all of them for some strange reason…(even in small groups)
I just tried making a group of these registers.

	Bridge poller power_a [ start=30773, length=18, refresh=5000, type="input" ] {
	    
	       Thing data power_west       [ readStart="30773", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data active_power     [ readStart="30775", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data power_L1         [ readStart="30777", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data power_L2         [ readStart="30779", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data power_L3         [ readStart="30781", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data volt_G1          [ readStart="30783", readValueType="int32" ]
	       Thing data volt_G2          [ readStart="30785", readValueType="int32" ]
	       Thing data volt_G3          [ readStart="30787", readValueType="int32" ]

  	 }

But it seems like I cant get the length right. It should be 18, but then I get an error. If I use 16 or 14, I get an error on register 30773, (something about lenght beeing 12, which makes no sense.).
So there do seem to be some issues with this. But only for some registers it seem. Its pretty weird!

This is what happens when I set the lenght to 18.

2020-01-23 22:13:49.936 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_total:active_power' changed from UNINITIALIZED to UNINITIALIZED (HANDLER_MISSING_ERROR)
2020-01-23 22:13:49.941 [hingStatusInfoChangedEvent] - 'modbus:poller:inverter1:power_total' changed from ONLINE to UNINITIALIZED

2020-01-23 22:13:49.958 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Unregistering regular poll task BasicPollTaskImpl@1b7e002[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@741c24[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30773,length=4,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@18d32a6[address=10.4.28.248,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@446f2c0a] (interrupting if necessary)
2020-01-23 22:13:49.960 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Poll task BasicPollTaskImpl@1b7e002[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@741c24[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30773,length=4,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@18d32a6[address=10.4.28.248,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@446f2c0a] canceled

2020-01-23 22:13:49.963 [hingStatusInfoChangedEvent] - 'modbus:poller:inverter1:power_total' changed from UNINITIALIZED to OFFLINE
2020-01-23 22:13:49.970 [hingStatusInfoChangedEvent] - 'modbus:poller:inverter1:power_total' changed from OFFLINE to UNINITIALIZED (HANDLER_MISSING_ERROR)

2020-01-23 22:13:50.484 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Unregistering regular poll task BasicPollTaskImpl@b36977[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@3ac4f9[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30773,length=16,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@18d32a6[address=10.4.28.248,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@fe896427] (interrupting if necessary)
2020-01-23 22:13:50.486 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Poll task BasicPollTaskImpl@b36977[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@3ac4f9[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30773,length=16,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@18d32a6[address=10.4.28.248,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@fe896427] canceled

2020-01-23 22:13:50.490 [hingStatusInfoChangedEvent] - 'modbus:poller:inverter1:power_a' changed from ONLINE to OFFLINE
2020-01-23 22:13:50.493 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_west' changed from ONLINE to OFFLINE (BRIDGE_OFFLINE): Poller modbus:poller:inverter1:power_a 'Regular Poll' has no poll task
2020-01-23 22:13:50.498 [me.event.ThingUpdatedEvent] - Thing 'modbus:poller:inverter1:power_a' has been updated.
2020-01-23 22:13:50.515 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:active_power' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.531 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:active_power' changed from INITIALIZING to ONLINE
2020-01-23 22:13:50.558 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_L1' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.571 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_L1' changed from INITIALIZING to ONLINE
2020-01-23 22:13:50.597 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_L2' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.620 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_L2' changed from INITIALIZING to ONLINE
2020-01-23 22:13:50.640 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_L3' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.661 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:power_L3' changed from INITIALIZING to ONLINE
2020-01-23 22:13:50.689 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:volt_G1' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.703 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:volt_G1' changed from INITIALIZING to ONLINE
2020-01-23 22:13:50.719 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:volt_G2' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.735 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:volt_G2' changed from INITIALIZING to ONLINE
2020-01-23 22:13:50.751 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:volt_G3' changed from UNINITIALIZED to INITIALIZING
2020-01-23 22:13:50.767 [hingStatusInfoChangedEvent] - 'modbus:data:inverter1:power_a:volt_G3' changed from INITIALIZING to ONLINE

I´m working on it :smiley:

Yes, there is some config idiot proofing, example -

Bridge poller xxx [ start=100, length=10, ....
	       Thing data zzz  [ readStart="120",

is going to error because 120 does not lie within the 100-110 polled block.

I would suggest try length 20, you had an earlier example of that working.

Remember when editing poller things in flight with a less than very latest binding version, there can be confusion with cached settings. Restart the binding if in doubt.

Yes, I just restarted OH, and things seems to went online just fine.
This is my main inverter (the Tri Power). It is dark outside right now (22:41 o´clock) so I cant really tell untill tomorrow if its actually working.

(Note!! Restart of binding is a highly bad idea, when running a serial modbus as well… My Nilan setup (serial RTU) went bananas when I restarted the binding only. So I had to restart OH insted. Damn how I hate this serial/USB/Linux shi*** ).

@rossko57
What are the different readValueType formats.
In thedoc of the registers for my inverter, I see U32, U64, S32 and STR32, S16.
In the modbus doc I dont see S32, STR32 and S16.
What are these type?

Bit value type must be used with coils and discrete inputs. With registers all value types are applicable. 
Valid values are: 
"int64", "int64_swap", "uint64", "uint64_swap", "float32", "float32_swap", "int32", "int32_swap", "uint32", "uint32_swap", "int16", "uint16", "int8", "uint8", or "bit".

In my original setup (original copied from Nana) I had uint32 readValueType in some data, even though the SMA modbus register says format int32
Is it a typo/mistake/anything? It doesnt seem to do any harm though.
I have changed it to int32 in my new setup. Still no harm done, (I hope).

As before, Modbus protocol only knows 16-bit registers. (and the on/off types)

There are established conventions to fit on top of that. For example, make an effectively 32-bit register by sticking two 16-bit registers together end to end. There’s now a choice, do you stick them together as A + B or B + A? There’s no rules about this. There’s no rules about what to name it. This is the origin of what openHAB calls _swap (or not).

Looking at the openHAB names, example int16 and uint16.
It’s pretty common to treat a 16-bit register as representing an integer number, 16 bits can then be interpreted as decimal 0 - 65535. That’s uint16, where the U is for Unsigned. Signed?
There’s a very common computing convention to allow negative numbers in binary registers called “twos complement”. This allows our 16 bits to represent decimal integers -32768 to +32767. That’s int16.
It so happens that the 16-bit patterns for values 0 to 32767 are exactly the same in int16 and uint16 - so often you cannot tell the difference even if you guess wrong.

Remember all that comes over Modbus is 16-bit registers, this is all about interpretation. Which means the slave designers decide what they mean, we have to guess or read the docs. What the slave designer might call the various possibilities, we don’t know. You might now guess what the U and S are about in the SMA docs, though.

There are reasonably well established general computing conventions to represent floating point numbers - like 3.1417 - in 32 or 64-bit registers. In particular an IEE standard is very common, and so openHAB provides dataTypes for that.

STR is a good one. I’m guessing it might be String.
It’s possible to pack encoded characters or suchlike into those universal 16-bit registers. You might do that in two 8-bit characters, again we have the A+B or B+A problem, this time internal to the register. You also have to know what character encoding they use - ascii, unicode, blah?
String over Modbus is fairly unusual and unwieldy, and given the large number of variations openHAB presently has no decode for this. You can make your own with transformations, or exploit the uint8 form and use rules to decode.

All of which means … I can’t tell you what SMA means by it.

1 Like

Hmm… So:
int16 is for negative to positive number (ie -32768 til +32767)
uint16 is for positive number only (ie 0 - 65535)…
Which means, if a register can never return a negative value, it will be an uint16? But if it can return an negative value it will be an int16 ?

I know there are alot of guessing going on here. But I´m also trying to understand, so I at least have a fair chance to guess right :slight_smile:

I think you´re right about the STR32 beeing a string. It seems to be use for IP, DNS, MAC adresses ect.

Here are some examples from the modbus registers of my main inverter:

Modbus register address	Short description / Enumerators	         Unit	Format	Type	Access
30513	                Total yield                  	         Wh	    U64	    FIX0	RO
30529	                Total yield                              Wh	    U32	    FIX0	RO
30773	                DC power input [1]           	         W	    S32	    FIX0	RO
31017	                Current speedwire IP address	                STR32	UTF8	RO
41029	                X value 1, conf. of grid integr. char. 1        S32	    FIX3	RW

Seems logic… except:
I still dont get the difference between S32 and U32.
and
Why the heck is there a Total yield in both U64 format and U32 format?

Also notice a funny thing I just have to show:

30539	                Daily yield	                             MWh	U32    FIX0	RO

How many 6000Watt inverters are capable pf producing MWh pr day?? :laughing:
(I know why they have this option… Its just funny to see from its description)

All you get over Modbus is 16 bits. All registers look alike.

1000000000110101 might mean 32821 as a uint16 type, or it might mean -32715 as an int16 type, or it might mean “€5” as string characters, or it might be part of a 32-bit value and be useless on its own,

Any register can represent a negative value, or string characters, or screen pixels, or blah. It’s entirely up to the slave designers whim.
You have to guess or find out what meaning they placed upon it, so that you can apply the same meaning at your end.

Having discussed Signed and Unsigned numbers, what do you think SMA might mean by S32 and U32?

int16 = Signed
uint16 = Unsigned
S32 = Signed
U32 = Unsigned
STR32 = String (most probably).

Got it :slight_smile:

Hi,
I was reading many articles regarding modbus and sma tripower. I’m not able to get it to work. When I use separate modbus poll utility I can read some data.
My setup is very simple and added the openhab.log and events.log snapshot.
I hope someone can read the logfiles and explain what is wrong.

things
Bridge modbus:tcp:tripower "SMA Sunny Tripower 5000TL-20" @ "Zolder" [ host="192.168.100.85", port=502, id=3, connectMaxTries=3 ] {
        Bridge poller SMA_Poller_30813_10 "SMA_Poller_30813_10" [ start=30813, length=10, refresh=2000, type="input" ] {
        Thing data 30813_2 "SMA_Input_30813_2" [ readStart="30813", readValueType="int32"]
          }    
}
items
Number          SMAInput308132Number             "Value as number"       (gEV)   {channel="modbus:data:tripower:SMA_Poller_30813_10:30813_2:number"}

openhab.log
2020-04-29 13:51:29.679 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Unregistering regular poll task BasicPollTaskImpl@69ff5a7b[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@6738a934[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30813,length=10,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@6307310b[address=192.168.100.85,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@f99b7510] (interrupting if necessary)

2020-04-29 13:51:29.679 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Poll task BasicPollTaskImpl@69ff5a7b[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@6738a934[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30813,length=10,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@6307310b[address=192.168.100.85,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@f99b7510] canceled

2020-04-29 13:51:29.682 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Unregistering regular poll task BasicPollTaskImpl@54d46a09[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@5a139ee3[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30813,length=10,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@5e2c0179[address=192.168.100.85,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@f99b7510] (interrupting if necessary)

2020-04-29 13:51:29.682 [INFO ] [rt.modbus.internal.ModbusManagerImpl] - Poll task BasicPollTaskImpl@54d46a09[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@5a139ee3[slaveId=3,functionCode=READ_INPUT_REGISTERS,start=30813,length=10,maxTries=3],endpoint=ModbusTCPSlaveEndpoint@5e2c0179[address=192.168.100.85,port=502],callback=org.openhab.binding.modbus.internal.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@f99b7510] canceled

2020-04-29 13:51:30.002 [INFO ] [smarthome.model.script.default.rules] - SMA gegevens: NULL SMAInput308132LastReadSuccess (Type=DateTimeItem, State=NULL, Label=Last successful read, Category=null, Groups=[gEV]) SMAInput308132LastReadError (Type=DateTimeItem, State=NULL, Label=Last erroring read, Category=null, Groups=[gEV])

2020-04-29 13:51:35.002 [INFO ] [smarthome.model.script.default.rules] - SMA gegevens: NULL SMAInput308132LastReadSuccess (Type=DateTimeItem, State=NULL, Label=Last successful read, Category=null, Groups=[gEV]) SMAInput308132LastReadError (Type=DateTimeItem, State=NULL, Label=Last erroring read, Category=null, Groups=[gEV])

2020-04-29 13:51:40.003 [INFO ] [smarthome.model.script.default.rules] - SMA gegevens: NULL SMAInput308132LastReadSuccess (Type=DateTimeItem, State=NULL, Label=Last successful read, Category=null, Groups=[gEV]) SMAInput308132LastReadError (Type=DateTimeItem, State=NULL, Label=Last erroring read, Category=null, Groups=[gEV])

events.log
2020-04-29 13:51:25.390 [vent.ItemStateChangedEvent] - zwave_serial_zstick_667e6ce2_serial_sof changed from 45015 to 45016

2020-04-29 13:51:29.678 [hingStatusInfoChangedEvent] - 'modbus:tcp:tripower' changed from ONLINE to OFFLINE

2020-04-29 13:51:29.679 [hingStatusInfoChangedEvent] - 'modbus:tcp:tripower' changed from OFFLINE to ONLINE

2020-04-29 13:51:29.680 [me.event.ThingUpdatedEvent] - Thing 'modbus:tcp:tripower' has been updated.

2020-04-29 13:51:29.681 [hingStatusInfoChangedEvent] - 'modbus:poller:tripower:SMA_Poller_30813_10' changed from ONLINE to OFFLINE

2020-04-29 13:51:29.681 [hingStatusInfoChangedEvent] - 'modbus:poller:tripower:SMA_Poller_30813_10' changed from OFFLINE to ONLINE

2020-04-29 13:51:29.683 [hingStatusInfoChangedEvent] - 'modbus:poller:tripower:SMA_Poller_30813_10' changed from ONLINE to OFFLINE

2020-04-29 13:51:29.684 [hingStatusInfoChangedEvent] - 'modbus:data:tripower:SMA_Poller_30813_10:30813_2' changed from ONLINE to OFFLINE (BRIDGE_OFFLINE): Poller modbus:poller:tripower:SMA_Poller_30813_10 'SMA_Poller_30813_10' has no poll task

2020-04-29 13:51:29.685 [hingStatusInfoChangedEvent] - 'modbus:poller:tripower:SMA_Poller_30813_10' changed from OFFLINE to ONLINE

2020-04-29 13:51:29.685 [hingStatusInfoChangedEvent] - 'modbus:data:tripower:SMA_Poller_30813_10:30813_2' changed from OFFLINE (BRIDGE_OFFLINE): Poller modbus:poller:tripower:SMA_Poller_30813_10 'SMA_Poller_30813_10' has no poll task to ONLINE

Can’t help with that but the SunSpec binding has become available now, and if I’m not mistaken SMA supports that. So maybe it does what you want.

I have yet to figure out what exactly is the difference between modbus and SunSpec, except its same. :slight_smile:

I doubt using SunSpec binding will solve his issue.

Thanks Markus. This doesn’t help I expect because it still requires modbus.

I dont see anything wrong in your setup. But I wonder if you´re having a network issue somehow. It seems like its the Bridge going on/off all the time.
It may require you to activate the trace log to see more.

Maybe @rossko57 got an idea of this one.

Not much more to be seen, yet. If you’ve been editing your Things, I would recommend a binding restart at least.

Hi Rossko57, Thanks not sure how to do a binding restart but it triggered me to uninstall the binding and reinstall it. Afterwards the value was shown perfectly. Thanks. I’m still learning but making progress. Next job is adding a database in graphical representation.

Hi @Kim_Andersen,
May I ask you to share your final config files for the SMA Sunny Boy setup? (Things, Items, Transform & Sitemap) This would be very useful for future openhab users :slight_smile:
Thank you

Sure. I´ll upload them later (tonight) as I´m at work right now.

Hi @Kim_Andersen
I have 2 SMA Sunny Boy (2500HF and 3000HF) with standard communication module Bluetooth, what communication / interface module do you have to get the Modbus data?

Not sure whether this will help but I’ll try to give my 50 ct…

Concerning modbus an sunspec I read some questions before: modbus is a protocol. Sunspec uses modbus protocol. The sunspec modbus profile defines specific registers and data types for measurements or parameters. Some of them are read only, some of them can also be written. Take care, not all of them are meant to be changed but only to be set once. Changing them continuously will destroy flash memory. SMA has documented this well.

At least in some SMA devices Modbus TCP is not activated by default. For Sunny Boy Tripower as well as for Sunny Boy Storage you’ll have to enable “Modbus TCP Server” to use it with openHAB.

When you try to read out sunspec modbus values you have to take care of the registers adresses, theres an offset. SMA:

To read or to write Modbus registers in each case use register numbers reduced by the
offset of 1. Example: Modbus register address = Modbus register number in SunSpec
Modbus profile – offset = 40001 - 1 = 40000.

Not all SMA devices serve all values.

SMA Documentation:
https://www.sma.de/fileadmin/content/landingpages/pl/FAQ/SunSpec_Modbus-TI-en-15.pdf

This is my setup for my SMA devices:
Main Inverter - Sunny Tripower 6000 TL-20
Batery inverter: Sunnyboy storage 2.5 10.

My .things setup (Sunny Tripower)

Bridge modbus:tcp:inverter1 [ host="10.4.28.248", port=502, id=3, connectMaxTries=3] {

// SMA Inverter Device Type
	Bridge poller DevType              [ start=30053, length=4, refresh=5000, type="input" ] {
	    	Thing data type            [ readStart="30053", readValueType="uint32" ] 
  	 }

// SMA Inverter Status
	Bridge poller SMA_Status           [ start=30201, length=36, refresh=6000, type="input" ] {
               Thing data status           [ readStart="30201", readValueType="int32" ]
               Thing data Grid_Contactor   [ readStart="30217", readValueType="int32" ]

               Thing data Max_Power        [ readStart="30231", readValueType="int32" ]
               Thing data Set_Max_Power    [ readStart="30233", readValueType="int32" ]

  	 }

// SMA Inverter Yield
	Bridge poller Yield                [ start=30517, length=16, refresh=5000, type="input" ] {
               Thing data Day_Yield        [ readStart="30517", readValueType="int64", readTransform="JS(divide1000.js)" ]
               Thing data Total_Yield      [ readStart="30529", readValueType="int32", readTransform="JS(divide1000.js)" ]
   	 }

// SMA Inverter Power Section West & Total
	Bridge poller power_a              [ start=30769, length=20, refresh=5000, type="input" ] {
	       Thing data current_input    [ readStart="30769", readValueType="int32", readTransform="JS(smalimit1000.js)" ]
	       Thing data voltage_input    [ readStart="30771", readValueType="int32", readTransform="JS(smalimit100.js)" ]
	       Thing data power_west       [ readStart="30773", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data active_power     [ readStart="30775", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data power_L1         [ readStart="30777", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data power_L2         [ readStart="30779", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data power_L3         [ readStart="30781", readValueType="int32", readTransform="JS(smalimit.js)" ]
	       Thing data volt_G1          [ readStart="30783", readValueType="uint32", readTransform="JS(divide100.js)" ]
	       Thing data volt_G2          [ readStart="30785", readValueType="uint32", readTransform="JS(divide100.js)" ]
	       Thing data volt_G3          [ readStart="30787", readValueType="uint32", readTransform="JS(divide100.js)" ]
  	 }

// SMA Inverter Power Section East
	Bridge poller power_b              [ start=30957, length=8, refresh=5000, type="input" ] {
               Thing data currentB_input   [ readStart="30957", readValueType="int32", readTransform="JS(smalimit1000.js)" ]
	       Thing data voltageB_input   [ readStart="30959", readValueType="int32", readTransform="JS(smalimit100.js)" ]
	       Thing data power_east       [ readStart="30961", readValueType="int32", readTransform="JS(smalimit.js)" ] 
   	 }


// SMA Inverter Operation
	Bridge poller SMA_Status_Operate   [ start=40029, length=4, refresh=5000, type="holding" ] {
	       Thing data operatestatus    [ readStart="40029", readValueType="uint32" ]
   	 }
}

My .things setup (Sunnyboy storage)

Bridge modbus:tcp:inverter2 [ host="10.4.28.197", port=502, id=3, connectMaxTries=3] {


// SMA SunnyBoy Storage 2.5
	Bridge poller device_typ [ start=30053, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data device_typ [ readStart="30053", readValueType="int32"]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Condition
	Bridge poller status [ start=30201, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data status [ readStart="30201", readValueType="int32"]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 GridRelay on/off
	Bridge poller GridRelay [ start=30217, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data GridRelay [ readStart="30217", readValueType="int32"]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Total Yield.
	Bridge poller TotalYield [ start=30529, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data TotalYield [ readStart="30529", readValueType="int32", readTransform="JS(divide1000.js)" ]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Daily Yield
	Bridge poller DayYield [ start=30535, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data DayYield [ readStart="30535", readValueType="int32", readTransform="JS(divide1000.js)" ]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Power
	Bridge poller Power [ start=30775, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data Power   [ readStart="30775", readValueType="int32" ]
	    	 Thing data PowerL1 [ readStart="30777", readValueType="int32" ]

  	 }

// SMA SunnyBoy Storage 2.5 Grid Voltage L1
	Bridge poller GVoltageL1 [ start=30783, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data GVoltageL1 [ readStart="30783", readValueType="int32", readTransform="JS(divide100.js)" ]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Current battery state of charge
	Bridge poller CurrentBatStatCharge [ start=30845, length=4, refresh=5000, type="input" ] {
	    
	    Thing data CurrentBatStatCharge [ readStart="30845", readValueType="int32" ]
	    Thing data CurrentBatcapacity   [ readStart="30847", readValueType="int32" ]
  	 }


// SMA SunnyBoy Storage 2.5 PowerDrawn
	Bridge poller PowerDrawn [ start=30865, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data PowerDrawn      [ readStart="30865", readValueType="int32" ]
	    	 Thing data PowerGridFeedIn [ readStart="30867", readValueType="int32" ]
	   	 
  	 }


// SMA SunnyBoy Storage 2.5 Battery oper. status
	Bridge poller BatteryStatus [ start=30955, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data BatteryStatus [ readStart="30955", readValueType="int32" ]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Status battery application area:
	Bridge poller BatteryAppArea [ start=31057, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data BatteryAppArea [ readStart="31057", readValueType="int32" ]
	   	 
  	 }


// SMA SunnyBoy Storage 2.5
	Bridge poller PowerDrawnGridL1 [ start=31259, length=16, refresh=5000, type="input" ] {
                 Thing data PowerGridFeedL1  [ readStart="31259", readValueType="int32" ]
                 Thing data PowerGridFeedL2  [ readStart="31261", readValueType="int32" ] 
                 Thing data PowerGridFeedL3  [ readStart="31263", readValueType="int32" ]      
	    	 Thing data PowerDrawnGridL1 [ readStart="31265", readValueType="int32" ]
	    	 Thing data PowerDrawnGridL2 [ readStart="31267", readValueType="int32" ]
	    	 Thing data PowerDrawnGridL3 [ readStart="31269", readValueType="int32" ]
  	 }

// SMA SunnyBoy Storage 2.5 Present battery charge
	Bridge poller PresBatCharge [ start=31393, length=4, refresh=5000, type="input" ] {
	    
	    	 Thing data PresBatCharge     [ readStart="31393", readValueType="int32" ]
	    	 Thing data PresBattDischarge [ readStart="31395", readValueType="int32" ]
	   	 
  	 }

// SMA SunnyBoy Storage 2.5 Present battery charge/discharge Wh
	Bridge poller PresBattDischargeWh [ start=31397, length=8, refresh=5000, type="input" ] {
	    
	    Thing data PresBattchargeWh    [ readStart="31397", readValueType="int64", readTransform="JS(divide1000.js)" ]
            Thing data PresBattDischargeWh [ readStart="31401", readValueType="int64", readTransform="JS(divide1000.js)" ]
  	 }


// SMA SunnyBoy Storage 2.5 Battery nominal capacity
	Bridge poller BattNormCap [ start=40187, length=2, refresh=10000, type="input" ] {
                  Thing data BattNorminalcapac [ readStart="40187", readValueType="int32" ]
	   	 
  	 }
}

My .items setup (for both):

// Inverter 1 TriPower 6000
Number inverter1DevType               "Inverter Type [MAP(SMA.map):%s]"                 <solarinverter>                 {channel="modbus:data:inverter1:DevType:type:number"}

Number inverter1Status	              "Device Status [MAP(SMA.map):%s]" 	        <switch>                        {channel="modbus:data:inverter1:SMA_Status:status:number"}
Switch inverterGridContactor          "Grid contactor [MAP(SMA.map):%s]"                <cu_switch>                     {channel="modbus:data:inverter1:SMA_Status:Grid_Contactor:switch"}

Number inverter1MaxPower              "Max Power [%s W]" 	                        <Energy>                        {channel="modbus:data:inverter1:SMA_Status:Max_Power:number"}
Number inverter1SetMaxPower           "Max Power Set [%s W]" 	                        <Energy>                        {channel="modbus:data:inverter1:SMA_Status:Set_Max_Power:number"}

Number inverter1DaylyYield            "Inverter Dayly Yield [%s kWh]"                   <line>                          {channel="modbus:data:inverter1:Yield:Day_Yield:number"}
Number inverter1TotalYield            "Inverter Total Yield [%s kWh]"                   <line>                          {channel="modbus:data:inverter1:Yield:Total_Yield:number"}

Number inverter1DC1Cur_input          "Current input [%s A]"                            <solarpanel>                    {channel="modbus:data:inverter1:power_a:current_input:number"}
Number inverter1DC1Volt_input         "Voltgae input [%s V]"                            <solarpanel>                    {channel="modbus:data:inverter1:power_a:voltage_input:number"}
Number inverter1PowerA                "Panel SydVest [%s W]"                            <solarpanel>                    {channel="modbus:data:inverter1:power_a:power_west:number"}
Number inverter1ActivePower           "Active Power [%s W]"                             <solarpanel>	    (PV)        {channel="modbus:data:inverter1:power_a:active_power:number"}
Number inverter1PowerL1               "Active Power L1 [%s W]"                          <solarpanel>	    (PV)        {channel="modbus:data:inverter1:power_a:power_L1:number"}
Number inverter1PowerL2               "Active Power L2 [%s W]"                          <solarpanel>	    (PV)        {channel="modbus:data:inverter1:power_a:power_L2:number"}
Number inverter1PowerL3               "Active Power L3 [%s W]"                          <solarpanel>	    (PV)        {channel="modbus:data:inverter1:power_a:power_L3:number"}
Number inverter1_voltG1               "Grid voltage phase L1 [%s V]"                    <solarpanel>                    {channel="modbus:data:inverter1:power_a:volt_G1:number"}
Number inverter1_voltG2               "Grid voltage phase L2 [%s V]"                    <solarpanel>                    {channel="modbus:data:inverter1:power_a:volt_G2:number"}
Number inverter1_voltG3               "Grid voltage phase L3 [%s V]"                    <solarpanel>                    {channel="modbus:data:inverter1:power_a:volt_G3:number"}

Number inverter1DC2Cur_input          "Current input B [%s A]"                          <solarpanel>                    {channel="modbus:data:inverter1:power_b:currentB_input:number"}
Number inverter1DC2Volt_input         "Voltgae input B [%s V]"                          <solarpanel>                    {channel="modbus:data:inverter1:power_b:voltageB_input:number"}
Number inverter1PowerB                "Panel SydØst [%s W]"                             <solarpanel>                    {channel="modbus:data:inverter1:power_b:power_east:number"}
Number inverter1OpMode                "Operation Mode [MAP(SMA.map):%s]" 	        <text>                          {channel="modbus:data:inverter1:SMA_Status_Operate:operatestatus:number"}




// Inverter 2 SunnyBoy Storage 2.5
String inverter2DevType               "Inverter type [MAP(SMA.map):%s]"                 <solarinverter>                 {channel="modbus:data:inverter2:device_typ:device_typ:string"}
String inverter2Status                "Device Status [MAP(SMA.map):%s]" 	        <switch>                        {channel="modbus:data:inverter2:status:status:string"}
Switch inverter2GridRelay             "Grid Relay [%s]"                                 <cu_switch>                     {channel="modbus:data:inverter2:GridRelay:GridRelay:switch"}
String inverter2TotalYield            "Total Yield [%s Wh]" 	                        <line>                          {channel="modbus:data:inverter2:TotalYield:TotalYield:string"}
String inverter2DayYield              "Dayli Yield [%s Wh]" 	                        <line>                          {channel="modbus:data:inverter2:DayYield:DayYield:string"}
String inverter2Power                 "Power [%s W]" 	                                <Energy>                        {channel="modbus:data:inverter2:Power:Power:string"}
String inverter2PowerL1               "Power L1 [%s W]" 	                        <Energy>                        {channel="modbus:data:inverter2:Power:PowerL1:string"}
String inverter2GVoltageL1            "Grid Voltage L1 [%s V]" 	                                                        {channel="modbus:data:inverter2:GVoltageL1:GVoltageL1:string"}

Number inverter2BatStateCharge        "Current Battery State Charge [%s %%]"            <batterylevel>     (PV)         {channel="modbus:data:inverter2:CurrentBatStatCharge:CurrentBatStatCharge:number"}
Number inverter2BatCapacity           "Current Battery Capacity [%s %%]"                <status>                        {channel="modbus:data:inverter2:CurrentBatStatCharge:CurrentBatcapacity:number"}

Number inverter2PowerDrawn            "Power Drawn [%s W]"                              <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawn:PowerDrawn:number"}
Number inverter2PowerGridFeedIn       "Power Grid Feed-in [%s W]"                       <cu_grid>                       {channel="modbus:data:inverter2:PowerDrawn:PowerGridFeedIn:number"}

Number inverter2BatteryStatus         "Battery status [MAP(SMA.map):%s]"                <switch>                        {channel="modbus:data:inverter2:BatteryStatus:BatteryStatus:number"}
Number inverter2BatAppArea            "Battery Application Area [MAP(SMA.map):%s]"      <text>                          {channel="modbus:data:inverter2:BatteryAppArea:BatteryAppArea:number"}

Number inverter2PowGridFeedL1         "Power Feedin Grid L1 [%s W]"                     <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawnGridL1:PowerGridFeedL1:number"}
Number inverter2PowGridFeedL2         "Power Feedin Grid L2 [%s W]"                     <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawnGridL1:PowerGridFeedL2:number"}
Number inverter2PowGridFeedL3         "Power Feedin Grid L3 [%s W]"                     <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawnGridL1:PowerGridFeedL3:number"}
Number inverter2PowDraGridL1          "Power drawn from Grid L1 [%s W]"                 <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawnGridL1:PowerDrawnGridL1:number"}
Number inverter2PowDraGridL2          "Power drawn from Grid L2 [%s W]"                 <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawnGridL1:PowerDrawnGridL2:number"}
Number inverter2PowDraGridL3          "Power drawn from Grid L3 [%s W]"                 <cu_grid>          (PV)         {channel="modbus:data:inverter2:PowerDrawnGridL1:PowerDrawnGridL3:number"}

Number inverter2PreBatCharge          "Present Battery Charge [%s W]"                   <batterylevel>     (PV)         {channel="modbus:data:inverter2:PresBatCharge:PresBatCharge:number"}
Number inverter2PreBatDischarge       "Present Battery Discharge [%s W]"                <batterylevel>     (PV)         {channel="modbus:data:inverter2:PresBatCharge:PresBattDischarge:number"}

Number inverter2BatNormCapac          "Battery Norminal Capacity [%s Wh]"               <text>                          {channel="modbus:data:inverter2:BattNormCap:BattNorminalcapac:number"}

And the .sitemap setup:

sitemap inverters label="Invertere"
{
	Frame label="SMA Inverter 1" {
          Text  item=inverter1Status
          Text  item=inverter1DevType
          Text  item=inverterGridContactor
          Text  item=inverter1OpMode
          Text  item=inverter1MaxPower
          Text  item=inverter1SetMaxPower
       }


	Frame label="Paneler" {
         Text item=inverter1PowerA {
          Text  item=inverter1DC1Volt_input
          Text  item=inverter1DC1Cur_input
          Text  item=inverter1PowerA

       }

        Text item=inverter1PowerB {
          Text  item=inverter1DC2Volt_input
          Text  item=inverter1DC2Cur_input
          Text  item=inverter1PowerB

       }
          Text  item=inverter1ActivePower label="Total Watt"
          Text  item=inverter2BatStateCharge
          Text  item=inverter2PreBatCharge
          Text  item=inverter2PreBatDischarge

}

	Frame label="Yield" {
          Text  item=inverter1DaylyYield
          Text  item=inverter1TotalYield
       }

	Frame label="Grid voltage & Power" {
          Text  item=inverter1_voltG1
          Text  item=inverter1PowerL1
          Text  item=inverter1_voltG2
          Text  item=inverter1PowerL2
          Text  item=inverter1_voltG3
          Text  item=inverter1PowerL3

	}

	Frame label="SMA Inverter 2" {
          Text  item=inverter2Status
          Text  item=inverter2DevType
          Text  item=inverter2Power
          Text  item=inverter2PowerL1
          Text  item=inverter2GVoltageL1
          Text  item=inverter2GridRelay
          Text  item=inverter2DayYield
          Text  item=inverter2TotalYield

	}

        Frame label="PowerDrawn/Feed-in" {
          Text  item=inverter2PowerDrawn
          Text  item=inverter2PowerGridFeedIn
          Text  item=inverter2PowDraGridL1
          Text  item=inverter2PowGridFeedL1
          Text  item=inverter2PowDraGridL2
          Text  item=inverter2PowGridFeedL2
          Text  item=inverter2PowDraGridL3
          Text  item=inverter2PowGridFeedL3

// 	Image refresh=10000 url="http://10.4.28.3:3000/render/d-solo/5098Wzrik/solcelleanlaeg?refresh=30s&orgId=1&from=now-12h&to=now&panelId=6&width=1000&height=500"
// 	Image refresh=10000 url="http://10.4.28.3:3000/render/d-solo/5098Wzrik/solcelleanlaeg?refresh=30s&orgId=1&from=now-12h&to=now&panelId=8&width=1000&height=500"

        }

	Frame label="LG Chem Resu10 Battery" {
          Text  item=inverter2BatteryStatus
          Text  item=inverter2BatAppArea
          Text  item=inverter2BatCapacity
          Text  item=inverter2BatNormCapac
          Text  item=inverter2BatStateCharge
          Text  item=none
          Text  item=inverter2PreBatCharge
          Text  item=inverter2PreBatDischarge
	}
}

Hope it will do.

1 Like