This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

SolarEdge inverter
#1
Hi,

I have a SolarEdge inverter which supports Modbus.

The Modbus data can be found here: https://www.solaredge.com/sites/default/...l-note.pdf



Before starting to assemble a profile for this, I wanted to check if I could connect to the device and do a simple operation.

I use a script that admin provided in another thread:




Code:
require('luamodbus')

mb = luamodbus.tcp()
mb:open('192.168.0.45', 1502)
res, err = mb:connect()

if res then
  log("connected!")
   mb:setslave()
  r1,r2 = mb:readregisters(40082)
  log(r1,r2)
else
  log('connect failed', err)
end

mb:close()



This is the result I get:





Code:
testing 11.02.2020 14:31:01
* arg: 1
  * nil
* arg: 2
  * string: Operation timed out
testing 11.02.2020 14:31:01
* string: connected!


I took some random address from the manual but no matter what addres I use, I get the same result.

I tried with both 40082 and 82 and also other combinations.

I also tried the script without the mb.setslave() statement; same resul

I can telnet to the device and it opens a connection but I have no idea what I could enter next to get some sort of response.

Am I overlooking something here?
Reply
#2
You are reading one register here so delete the r2
Reply
#3
(11.02.2020, 13:59)Daniel. Wrote: You are reading one register here so delete the r2

Result: nil...
Reply
#4
mb:setslave() does nothing, try setting slave to 1: mb:setslave(1)
Reply
#5
(11.02.2020, 14:58)admin Wrote: mbConfusedetslave() does nothing, try setting slave to 1: mbConfusedetslave(1)

Success!
It looks like I have to subtract 1 from the address in the manual. Also it makes no difference if I use 40072 (as stated in the manual) or 72...

Just for my understanding (as you can guess, I know absolutely nothing about Modbus..): I now need to make a profile, add the device, specify the group addresses and the rest will be taken care of by the LM?
Can I start with just a simple profile with one or two registers and expand later or does the profile needs to be complete to start with?

Thanks for your help!
Reply
#6
Yes you can start just with one register and this is the correct way of doing it Smile
Reply
#7
(11.02.2020, 15:47)Daniel. Wrote: Yes you can start just with one register and this is the correct way of doing it Smile




So I started with this simple profile:



Code:
{
"manufacturer": "SolarEdge",
  "description": "SE6000 inverter",
  "mapping": [
  { "name": "I_AC_VoltageAN", "bus_datatype": "uint16", "type": "register", "address": 40079},
  { "name": "I_AC_VoltageSF", "bus_datatype": "int16", "type": "register", "address": 40082},
  { "name": "I_AC_Power", "bus_datatype": "int16", "type": "register", "address": 40083},
  { "name": "I_AC_Power_SF", "bus_datatype": "int16", "type": "register", "address": 40084}
  ]
}




This works fine apart from one thing: the scaling factors ( I_AC_Voltage_SF and I_AC_Power_SF).



According the manual, to get the scaled values, the returned value should be mulitplied with 10^Scaling_Factor



The returned value for the voltage is 32767.

Now the values returned for the voltage are 10 times too high eg; 2378, so they should be mulitplied by 0.1, so I would expect the SF values to be -2 and not 32767

The SF for the Power switches between 32767 and 0 according to the amount of power generated (0 being correct).





Another problem is the following: there is one register (actually the most important one as it is the generated energy) that has datatype acc32. I understand that this means that the value is spread over 2 registers.



I did the test with the simple program and indeed I get the values of both registers and can then calculate the real value.



How do I implement this in the profile?
Reply
#8
Add value_multiplier": 0.01
Add "datatype": "uint32" - it will automatically read 2 registers.
Reply
#9
(12.02.2020, 13:02)Daniel. Wrote: Add value_multiplier": 0.01
Add "datatype": "uint32"  - it will automatically read 2 registers.
Adding datatype uint32 returns only the value of the first register...

Adding "value_multiplier": 0.1 to an int16? What datatype would the group address have to be?
Also, this would always multiply with 0.1 whereas in reality this scale factor changes in function of the returned value of the value register.
Reply
#10
datatype uint32 does read 2 registers only make sure that bus_datatype is same size or bigger.
You need a float object 2byte float would do but you can also use 4byte float.
Value multiplier is constant, it never change.
Reply
#11
For scaling you can specify scaling register address.
From docs:
address_scale (Number)
- Address of register containing value scale value = value * 10 ^ scale
Reply
#12
(12.02.2020, 13:58)Daniel. Wrote: datatype uint32 does read 2 registers only make sure that bus_datatype is same size or bigger.
You need a float object 2byte float would do but you can also use 4byte float. 
Value multiplier is constant, it never change.

When I change the bus datatype to a 4 byte float, I cannot link this register to it (the group address does not show up in the drop down box because the datatype is different from uint32...)

I understand that the value_multiplier is constant, but that is a problem because the scaling factor is not constant, it changes with the value in the data register..., So to calculate the real value of the data I need both...
Reply
#13
Just create new object. If you make 4byte bus data_type then LM object must have the same.
I did a lot of modbus integration and scaling factor was never dynamic, this wouldn't make sense at all.
Reply
#14
(12.02.2020, 14:28)Daniel. Wrote: Just create new object. If you make 4byte bus data_type then LM object must have the same.
I did  a lot of modbus integration and scaling factor was never dynamic, this wouldn't make sense at all.

Initially I misunderstood, but I think I got it right this time. Unfortunately I still only get the value of the first register.
This is the profile as it is at the moment:
Code:
{
"manufacturer": "SolarEdge",
  "description": "SE6000 inverter",
  "mapping": [
  { "name": "I_AC_VoltageAN", "bus_datatype": "uint16", "type": "register", "address": 40079, "value_multiplier": 0.1},
  { "name": "I_AC_VoltageSF", "bus_datatype": "int16", "type": "register", "address": 40082},
  { "name": "I_AC_Power", "bus_datatype": "int16", "type": "register", "address": 40083},
  { "name": "I_AC_Power_SF", "bus_datatype": "int16", "type": "register", "address": 40084},
  { "name": "I_AC_Energy_WH", "bus_datatype": "float32", "data_type": "uint32", "type": "register", "address": 40093},
  { "name": "I_AC_Energy_WH_SF", "bus_datatype": "int16", "type": "register", "address": 40095}
  ]
}

The object's datatype is 4 byte floating point and I still only get the value of the first register.
As to the scaling factor: there always has to be a first time:  Wink I can see the scaling factor changing whenever the value of the data register reaches a certain value. The SF object switches between 32767 and 0...
Reply
#15
How do you know it reads only one register? Maybe it need some read_swap. Check in manuals.
It still doesn't make sense Smile
Reply
#16
Make sure that bus_datatype and object data type is the same. Otherwise data might not display correctly.
Reply
#17
(12.02.2020, 16:22)Daniel. Wrote: How do you know it reads only one register? Maybe it need some read_swap. Check in manuals.
It still doesn't make sense Smile

Well, If I read the registers at 40093 with the test program, at the moment it returns 2 and 2968. If I use those values to calculate the energy, that seems to be OK.
The Modbus object returns only 2 which is the value of the first register. Earlier today the values were 1 and  somewhere in the 60000. At that time the Modbus result was 1. Once the second register hits 65536, it is set to 0 and the first register becomes 2.
I can't find anything in the manual about this.

I found another document which states:

SunSpec register order for 32-bit Integer and Floating Point values is HI-LO, therefore, the 16-bit Modbus register at the address given in the Modbus map below is the HI register, and the next consecutive 16-bit Modbus register is the LO register.
Reply
#18
Profile field key should be datatype not data_type
Reply
#19
(12.02.2020, 17:01)admin Wrote: Profile field key should be datatype not data_type

A sharp eye as always admin!
After correcting this all seems to be fine!

Thanks to Daniel and yourself for helping me in this.
Cheers.
Reply
#20
@Daniel
In case you should still have some doubts about changing scale factors:

   

   

As you can see it really changes Wink
Reply


Forum Jump: