Solaredge omvormer levert incorrecte waarden bij uitlezen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Sirius.B
  • Registratie: Oktober 2020
  • Laatst online: 01-11-2020
Bij het uitlezen van een Solaredge omvormer heeft het register voor de totaal opgeleverde vermogen een incorrecte waarde. Met deze blog hoop ik te achterhalen hoe dat kan en hoop het te kunnen corrigeren.
Ook kan deze blog anderen helpen die met het zelfde onderwerp bezig zijn.

Ik heb een Solaredge SE3000H Omvormer. Enkel fase aansluiting.
De Solaredge wordt zeer bewust niet aan internet aangesloten. Dus GEEN App in de cloud. Ik heb een fysieke geijkte kWh meter en ik heb de Solaredge "SetApp". Dat is een App om het apparaat uit te kunnen lezen en instellingen aan te passen. Ik heb een Raspberry Pi3 met een CAN Hat RS485 printje er boven op. Ik lees de Solaredge uit via het RS485 interface. Wat ik wil is alle Solaredge registers uitlezen om zo zelf alle waarden weer te geven.

Verschil fysieke meting en aangegeven waarden

Er zit nu een verschil van 3 kWh tussen de waarde die de SetApp aangeeft en de kWh meter. Interessant.
De fysieke meter is 3 KWh lager. Dit kan niet verklaard worden met het gecumuleerde standby gebruik van de Solaredge 's nachts. Dit verbruik is 4W gedurende de hele nacht. Precies om die reden heb ik de kWh meter ook.

Uitlezen SolarEdge via RS485

Het is niet gelukt om de SolarEdge uit te lezen via Modbus. De Solaredge geeft geen reactie. Er is pas activiteit als ik met de SetApp het RS485 interface instel op Sunspec. Dit is een open protocol. Voor mijn doen is dat perfect. Er bestaan verschillende registers en die kun je uitlezen.
Als software om dat te doen gebruik ik Minimalmodbus onder Python. Zie specificatie hier
De specificatie wat in welk register zit kun je hier vinden.
In tussen ben ik er achter dat Solaredge zich niet exact aan de specificatie houd maar grotendeels klopt het. Ik heb dat opgelost door alle registers op te vragen en zo heb ik waarden terug gevonden.

Uitlezen doe ik zo;

Eerst verbinding maken met Minimalmodbus in RTU mode en dan

code:
1
regval = instrument.read_register(register,0)


0 is het ophalen van de waarde met 0 decimalen.
Op dat moment ben je er nog niet want er is ook nog een schaalfactor die je moet toepassen. Die SF staat meestal paar registers verder.

Voorbeeld:

Register: 40072 (I_AC_Current "AC Total Current value") waarde = 135
Register: 40075 waarde = 65534
Dit laatste is een signed interger die als een unsigned interger wordt opgehaald. Dit is echter geen probleem.
65534 - 65536 = -2. Het gaat om een schaalfactor van -2. Dit zet je zo om: register x 10 ^ SF = 135 x 0,01 = 1,35 Ampere. De waarden kloppen ook met wat de meter aangeeft. Dit gaat dus prima.


32 Bit waarden uitlezen

Het totaal opgeleverde vermogen kan een heel groot getal worden. Daarom is het opgeslagen als een 32 bits waarde. Het gebruikt 2 register posities en staat op register 40094 (register 40095 bestaat daarom dus niet) Naam: I_AC_Energy_WH "AC Lifetime Energy production".
De SF voor dit register staat in register: 40096.

Ophalen van 32 bit waarden gaat zo:

code:
1
regval = instrument.read_long(register, 3, signed=False, byteorder=0)


3 is een modbus functie code die 3 of 4 kan zijn. 4 werkt niet.
Zie Minimalmodbus spec boven voor details.


Tot zo ver het goede nieuws. Nu het probleem.
De waarde die uit dit register komt is heel groot en lijkt geen relatie te hebben met de echt opgeleverde kWh die ik gelukkig wel weet. Het is wel zo dat de waarde in register 40094 gestaagd aan het oplopen is.

Een paar voorbeelden.

Meter Meter W SetApp SetApp W Register 40094
---------------------------------------------------------------------------
250,7 250700 254,5 254500 3793616896
251,8 251800 255,61 255610 3866755072
251,9 251900 255,77 255770 3877109760

Je ziet zo al dat de achterste register waarden niet zomaar een schaalfactor zit.
Tussen de bovenste regels zit volgens de SetApp 1110 W verschil. In register waarde een verschil van 73138176. Dat zijn ca 65890 punten per Watt. Je kunt natuurlijk ook een factor uitrekenen tussen SetApp en register. 3793616896 / 254500 = 14906,156762279.
Maar daarmee kom je niet naar de laatste register waarde: 14906,156762279 * 255770 = 3812547715.
Dat klopt dus niet met de werkelijke waarde...
Er zit dus niet zomaar een factor of verschil tussen.

Als laatste heb ik de byte order van 0 naar 1 aangepast. Dan is de gelezen waarde heel laag. Bijvoorbeeld 36066. De scale factor in register 40096 is helemaal een ramp. Deze waarde zou een relatief costante factor moeten zijn maar de waarde varieert heel erg. Daar kan ik helemaal niets mee.

Ik weet dus even niet meer verder.
Wie helpt me verder?

[ Voor 0% gewijzigd door Sirius.B op 25-10-2020 14:06 . Reden: tabel ]


Acties:
  • +1 Henk 'm!

  • Xiphalon
  • Registratie: Juni 2001
  • Laatst online: 12:14
De solaredge meet volgens mij de DC opbrengst, het verlies in de omzetting moet er dus nog vanaf. Mijn AC stroom meting zit ook een paar procent lager dan wat de solaredge aangeeft. Ik lees dus maar de stroommeter uit :)

Lees je ook de volgende registers uit? Daar zit een scale-factor in:
40094 2 I_AC_Energy_WH acc32 WattHours AC Lifetime Energy production
40096 1 I_AC_Energy_WH_SF uint16 Scale factor

je hebt dus 40094 en 40095 nodig om de waarde te berekenen, en dan de scale factor eroverheen.
Scale Factors
Value = “Value” * 10^ Value_SF for example:
For “Value” = 2071 and “Value_SF” = -2 Value = 2071*10^-2 = 20.71
For “Value” = 2071 and “Value_SF” = 2 Value = 2071*10^2 = 207100
wellicht ter overvloedde, 40095 is dus de MSB, dus ([waarde 40095] shl 16) + [waarde 40094] is de 32bit waarde.

Acties:
  • 0 Henk 'm!

  • Sirius.B
  • Registratie: Oktober 2020
  • Laatst online: 01-11-2020
Met "read_long" haal je in een keer beide registers op. Dus 32 bit in een keer. Alleen register 40094 uitlezen met "read_register" werkt op zich maar je hebt dus maar een halve waarde. 40095 met "read_register" uitlezen werkt niet. Je krijgt gewoon geen waarde in dat geval.

Ik vertrouw er op dat read_long werkt, anders hadden meer mensen een probleem. Misschien dat Solaredge iets geks doet. Ik zit te puzzelen...

3793616896(decimaal) = [ 1110 0010 0001 1110 ] [ 0000 0000 0000 0000 ]
Daarbij valt op dat het LSB gedeelte rechts verdacht leeg is.
Je zegt dat het MSB in register 40095 zit. Als ik de waarden omdraai krijg je
[ 0000 0000 0000 0000 ] [ 1110 0010 0001 1110 ]
Decimaal is dat 57886. Dat komt niet overeen met 254500 W die op dat moment weergegeven had moeten worden...

Zou Solaredge een bit shift doen?

Acties:
  • +1 Henk 'm!

  • Xiphalon
  • Registratie: Juni 2001
  • Laatst online: 12:14
Nee een scale factor. De bits die je leest stellen niets voor zonder ook de scalefactor te vermelden

lijkt me sterk dat het getal binair met een 1 begint.

Als ik de bytes omdraai komt er iets van 7600 uit. hmm.

Oja: de implementatie van mijn modbusstroomlezer heeft de registers 1 locatie opgeschoven zitten. Register 1 heeft locatie 0

Even snel die van mij uitgelezen:
0000 0001 0001 1110
1101 0001 1010 0000

Als ik dat in de rekenmachine stop, komt er 18.796.960 uit, dat lijkt te kloppen. Dus dat zou beweren dat de specs niet kloppen :p

Omdat ik het toch in code heb:
Afbeeldingslocatie: https://tweakers.net/i/n0w-8XpaVatXALQ4M7rnKvw65io=/full-fit-in/4000x4000/filters:no_upscale():fill(white):strip_exif()/f/image/smbdUefp05YA7mYiJnJPIBQ0.png?f=user_large

Opletten dus dat de (negative) short niet omgekat wordt naar een int met allemaal aangevulde enen :)

Laatste edit:
@Sirius.B samenvatting: je leest registers 1 scheef uit (want in code beginnen ze met 40000, niet 40001. Kan je checken met 40002/40003 daar moet een 1 in staan.

[ Voor 110% gewijzigd door Xiphalon op 25-10-2020 22:05 ]


Acties:
  • 0 Henk 'm!

  • Sirius.B
  • Registratie: Oktober 2020
  • Laatst online: 01-11-2020
Bedankt voor de waardevolle input. Je bent goed bezig zeg!

Ik was bang dat ik niet de juiste registers aan het uitlezen was lees ik alles voor de zekerheid uit.
De waarden die ik vind moet ik ook kunnen matchen met waarden dit ik ken.
Op 40094 staat "AC Lifetime Energy production" (32 bit) en op 40096 de scale factor.
Daar ben ik wel zeker van en klopt ook met de spec:

Zie: Sunspec


Afbeeldingslocatie: https://tweakers.net/i/EEIvBODD0xjJyj4V97zYHdNwlIg=/full-fit-in/4000x4000/filters:no_upscale():fill(white):strip_exif()/f/image/8rbHcgTVfvhNL2lYay7zMSFP.png?f=user_large

Python code
32 bit register 40094:

code:
1
regval = instrument.read_long(register, 3, signed=False, byteorder=0)


16 bit register 40096:

code:
1
sf = instrument.read_register(register, 0)

dus uitlezen met 0 decimalen.


Dit zijn voorbeelden van wat er in de registers staat:

tijd:16:45
40094=3874750464
40096=7678

tijd:16:57
40094=3877109760
40096=4793

tijd:17:16
40094=3880255488
40096=3295

tijd:19:03 (het is donker buiten)
40094=3883139072
40096=3295

tijd:19:07
40094=3883139072
40096=3295


De waarde van 40094 loopt op maar zie ik niet in relatie staan tot het opgewekte vermogen.
Ik verwacht een waarde zou iets tussen 250 260 kW moeten zijn.
Van de scale factor snap ik niets. Dat zou, -1, -2 moeten zijn (gelezen als 65535, 65534)
De scale factor lees ik voor de andere waarden uit. Dat gebeurt in dezelfde lus en alle andere waarden kloppen.

3883139072 =

1110 0111 0111 0100
0000 0000 0000 0000

Het tweede register is blijkbaar leeg en dat is verdacht.

1110 0111 0111 0100 = 59252

Het probleem zit denk ik in het uitlezen.
Dit is de spec van Minimalmodbus https://minimalmodbus.rea...s/test_minimalmodbus.html

Ahhhhh wanhoop. Ik weet het niet meer....
Het enige wat ik nog niet geprobeerd heb is gewoon 32 losse bits uit te lezen en dan te kijken wat er staat.

Alle suggesties zijn meer dan welkom.

Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 08:36
Als ik de register map in de spec bekijk, begint deze met 40001. De Python library neemt je register nummer letterlijk over.
Er staat ook:
The base Register Common Block is set to 40001 (MODBUS PLC address [base 1]) or 40000 (MODBUS Protocol Address [base 0]).
Kan het zijn dat je een off by one in je registeradres hebt? Prebeer eens te verifieren met een register dat je absoluut kunt controleren, bv vanaf 40005(1 -base) zou er "SolarEdge" moeten staan.

Ik vermoed dat als je nu 40094 uitleest je in werkelijkheid 40095 krijgt

[ Voor 8% gewijzigd door farlane op 30-10-2020 13:56 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • +1 Henk 'm!

  • Xiphalon
  • Registratie: Juni 2001
  • Laatst online: 12:14
Tja dat probeer ik @Sirius.B ook duidelijk te maken.

Register 40001 in de sunspec is register 40000 voor de python modbuslib.


@Sirius.B lees register 40002 en 40003 eens uit?

[ Voor 5% gewijzigd door Xiphalon op 30-10-2020 14:34 ]


Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 08:36
Xiphalon schreef op vrijdag 30 oktober 2020 @ 14:33:
Tja dat probeer ik @Sirius.B ook duidelijk te maken.

Register 40001 in de sunspec is register 40000 voor de python modbuslib.

@Sirius.B lees register 40002 en 40003 eens uit?
Het is moet ik zeggen een bekend verchijnsel: Modicon heeft in hun wijsheid die off by one (over de lijn is het nl wel 0-based) er gedesigned:
The Read Holding Registers request packet specifies a start register and a number
of registers to read. The start register is numbered from zero (40001 = zero, 40002 =
one, etc.).
Die 40000 is ook een mooi verzinsel, want er bestaan ook regions voor input (register offset 30000) en coils. Op de lijn werken alle register nummers echter 0-based, en geregeld liggen alle regions (input registers, holding registers en coils) over elkaar heen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • +1 Henk 'm!

  • Sirius.B
  • Registratie: Oktober 2020
  • Laatst online: 01-11-2020
Jongens, ik heb goed nieuws. Ik kan alles per afzonderlijk register uitlezen. Dus ik lees een hele reeks uit.
Dit is wat er staat:
40000=21365
SunSpec_ID : 40001=28243
40002=1
SunSpec_DID : 40003=65
SunSpec_Lenght : 40004=21359
Manufacturer : 40005=27745
40006=29253
Waarde "65" herken ik. Dat is zou eigenlijk de block lengte moeten zijn in register 40004.
Ik moet alles een register lager uitlezen.

Nu het uitlezen van de 32 bits registers
40000 + 40001 =1400204883 > 0x/53756E53 > "SunS" Klopt
40001 + 40002 =1850933249 ... klopt niet

Manufacturer normaal op 40005
40004 + 40005 =1399811169 > 0x/536F6C61 > "Sola" Klopt
de rest komt natuurlijk daarna.

verder 16 bit uitlezen
40068=1 (klopt : modbus unit ID)
40069=101 (klopt: single phase)
AC total current 40071=880
AC total current 40072=880
AC total current SF 40075 =65534 > -2 signed int
Stroom = 8,8 Ampere en dat klopt met de waarde van de meter

Nu de totaal opgeleverde stroom (32 bit)
Life time energy production : 40093 = 274763

Klopt redelijk met de 271 kW/h die op de meter staat.

Nu nog de Scale factor vinden. In de spec staat die op 400096. Dus die verwacht ik nu op 40095.
400095=0
400096=4501
400097=65533 > SF -3
Het past dus niet met de logica van 1 verschuiven maar het is wel de juiste SF waarde. Misschien heeft dit er mee te maken dat dit een 32 bits register is. Als ik in mijn programma 400097 als SF register ingeef dan komt er dit uit: 275,414 kW/h
Dat klopt redelijk met de waarde op de meter. Ik weet dat er een verschil van 3 kW/h is.

Gevonden!
Super bedankt voor de tips!!!

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 08:36
Sirius.B schreef op zaterdag 31 oktober 2020 @ 13:40:
Het past dus niet met de logica van 1 verschuiven maar het is wel de juiste SF waarde. Misschien heeft dit er mee te maken dat dit een 32 bits register is. Als ik in mijn programma 400097 als SF register ingeef dan komt er dit uit: 275,414 kW/h
Dat klopt redelijk met de waarde op de meter. Ik weet dat er een verschil van 3 kW/h is.
Die snap ik niet helemaal : de registers 40096 t/m 40109 zijn allemaal 16 bits units, dus waarom denk je dat dat met 32 bits units te maken heeft?

Iig mooi dat het werkt nu ;)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Sirius.B
  • Registratie: Oktober 2020
  • Laatst online: 01-11-2020
Toch nog een aanvulling.

Ik kon de juiste scale factor voor de energie productie niet vinden. Dat zag je boven al een beetje aankomen. De scale factor van "Life time energy production" heet: I_AC_Energy_WH_SF. Die staat 1 register verder dan de "Life time energy production", namelijk op 40096 volgens spec. In mijn geval lees ik dus 40095 uit. Het probleem is dat daar een 0 staat .... De opgeleverde energie wordt daardoor vermenigvuldigd met 0.
Ik had even de SF uit reg 40098 (ik lees uit 40097) gebruikt. Die is -3 en dat is juist. Deze SF hoort echter bij DC current. Toen de omvormer wat minder stroom begon te produceren werd ik er al snel aan herinnerd dat dit niet juist was....

Dit was zowel een denkfout als een programmeerfout. De totaal aantal geproduceerde energie is in Watt en niet in kW. Een waarde van 0 is dus 10^0 = 1. Ik had 0 geïnterpreteerd als: er is niets. Dat klopt dus niet.
Nu gaat het dus goed.

Maar het blijf oppassen met de waarden die je uitleest.
De zon is op dit moment allang onder, en mijn omvormer staat op standby.
De meeste waarden zijn 0.
Maar niet "DC current" reg 40096=65535. Dat klopt natuurlijk niet.
De SF = 32768 (int) SF = -32768 (signed int)
10^-32768 = heeeeeeeel klein. Ik doe een afronding naar 2 decimalen dus daar komt gewoon 0 uit.

Mocht ik nog aparte dingen tegen komen dan zal ik het laten weten.
Ter lering en vermaak.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 08:36
Het zou handig zijn om de registernummering uit de spec aan te houden, en niet die van je Modbus library .... om verwarring te voorkomen :P

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1