Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
11.02.2020, 13:51
(This post was last modified: 11.02.2020, 13:51 by baggins.)
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?
Posts: 4643
Threads: 24
Joined: Aug 2017
Reputation:
207
You are reading one register here so delete the r2
------------------------------
Ctrl+F5
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(11.02.2020, 13:59)Daniel. Wrote: You are reading one register here so delete the r2
Result: nil...
Posts: 7758
Threads: 42
Joined: Jun 2015
Reputation:
447
mb:setslave() does nothing, try setting slave to 1: mb:setslave(1)
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(11.02.2020, 14:58)admin Wrote: mbetslave() does nothing, try setting slave to 1: mbetslave(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!
Posts: 4643
Threads: 24
Joined: Aug 2017
Reputation:
207
Yes you can start just with one register and this is the correct way of doing it
------------------------------
Ctrl+F5
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(11.02.2020, 15:47)Daniel. Wrote: Yes you can start just with one register and this is the correct way of doing it
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?
Posts: 4643
Threads: 24
Joined: Aug 2017
Reputation:
207
Add value_multiplier": 0.01
Add "datatype": "uint32" - it will automatically read 2 registers.
------------------------------
Ctrl+F5
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(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.
Posts: 4643
Threads: 24
Joined: Aug 2017
Reputation:
207
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.
------------------------------
Ctrl+F5
Posts: 7758
Threads: 42
Joined: Jun 2015
Reputation:
447
For scaling you can specify scaling register address.
From docs:
address_scale (Number)
- Address of register containing value scale value = value * 10 ^ scale
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(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...
Posts: 4643
Threads: 24
Joined: Aug 2017
Reputation:
207
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.
------------------------------
Ctrl+F5
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(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: 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...
Posts: 4643
Threads: 24
Joined: Aug 2017
Reputation:
207
How do you know it reads only one register? Maybe it need some read_swap. Check in manuals.
It still doesn't make sense
------------------------------
Ctrl+F5
Posts: 7758
Threads: 42
Joined: Jun 2015
Reputation:
447
Make sure that bus_datatype and object data type is the same. Otherwise data might not display correctly.
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(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
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.
Posts: 7758
Threads: 42
Joined: Jun 2015
Reputation:
447
Profile field key should be datatype not data_type
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
(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.
Posts: 184
Threads: 39
Joined: Sep 2015
Reputation:
4
@Daniel
In case you should still have some doubts about changing scale factors:
As you can see it really changes
|