Toon posts:

Goodwe 2500-xs uitlezen

Pagina: 1
Acties:

Vraag


  • FJR1300
  • Registratie: Juli 2001
  • Laatst online: 20-03 16:09

FJR1300

145 enthousiaste paardjes...

Topicstarter
Ik ben een aantal offertes aan het uitpluizen voor zonnepanelen en omvormers. In een aantal van deze offertes wordt de GoodWe 2500-xs omvormer aangeboden. Een van mijn wensen is het zelf kunnen uitlezen van opbrengst gegevens. En met zelf bedoel ik lokaal, met eigen apparatuur, direct uit de omvormer.

Mijn ervaring is dat partijen die offertes leveren, GEEN verstand hebben van zelf uitlezen... (somming verdenk ik er van dat ze er helemaal GEEN verstand van hebben maar dat terzijde). Ze vinden de vraag over zelf uitlezen maar raar, weten het niet en verwijzen naar de APP van de leverancier. Sommige beginnen nog over WiFi sticks en verliezen van garantie als je het anders doet... en dat is het moment dat ik de offerte aan de kant schuif.

Zelf uitlezen... Wel, de forums staan vol met mensen die dat doen. Waarom start je een nieuwe thread?
Nou... al die informatie is nogal gefragmenteerd en beantwoorden niet perse mijn vragen. Ik wil een aantal vragen stellen aan mensen die het betreffende apparaat hebben en de informatie zelf uitlezen. En wellicht dat de antwoorden ook anderen gaan helpen in de toekomst.

Mijn doel:
  1. Direct uitlezen van gegevens via RS485 nog even los van eventuele software zoals Domoticz, Home Assistant of eigen programmeersels.
  2. Duidelijk krijgen of elk in Nederland geleverd apparaat over de juiste aansluiting daarvoor beschikt, welke aansluiting dat is en welke pins de juiste gegevens opleveren.
Als je de user manual er bij pakt loop je tegen de eerste tegenstelling aan.



Het probleem begint bij aansluiting 3 en 4. In het eerste tabel wordt poort 3 als WiFi/LAN en poort 4 als CT/DRED/Remote Shutdown aangeduid terwijl in het 2e tabel poort 3 als gecombineerde RS485/USB poort wordt aangeduid... en poort 4 als WiFi/LAN poort.

Waarschijnlijk is de eerste tabel correct...

Kijkend naar de pinlayout van connector 4 (uit de eerste tabel) kom ik 2 mogelijkheden tegen. De eerste is het gebruik als CT/DRED/Remote Shutdown aansluiting (wat volgens de manual een Australisch/Nieuw Zeelands dingetje is). De tweede mogelijkheid is het leveren van output via RS485 gegevens waarbij er 2 poorten beschikbaar zijn.

Tabel 1:



Tabel 2:



Ik zie dat de benodigde pinnen voor RS485 een dubbele functie hebben... en dat levert vragen op.

Oke, en dan nu de directe vragen:
  1. Klopt het dat de eerste tabel uit het eerste plaatje de correcte versie is?
  2. Aannemende dat het antwoord bij vraag 1 JA is, heeft die betreffende connector 4 een dubbele functie en kan ik ergens kiezen welke van de 2 actief moet zijn? Of werkt het gewoon als je maar de juiste pins gebruikt?
  3. Kan ik er vanuit gaan dat elk apparaat de betreffende connector heeft en deze bruikbaar is (AAN staat)?
  4. Wordt er een geschikte connector meegeleverd met het apparaat waarmee ik mijn eigen apparatuur kan aansluiten?
Dus... eigenaren van een Goodwe 2500-xs die zelf gegevens uitlezen, kunnen jullie iets met de vragen en hebben jullie eventueel een plaatje/foto van jullie eigen uitlees hardware?

Uitlezen is meer smart dan installatie => schopje naar SH

[Voor 0% gewijzigd door septillion op 13-02-2023 21:02]

Alle reacties


  • DeHollander
  • Registratie: September 2012
  • Laatst online: 22:46
@FJR1300 ik denk dat de meeste van je vragen hier wel beantwoord worden.

Mijn setup: Omvormer 1: 12x330wp 3960wp ZO + 6x330wp 1980WP NW - Omvormer 2: 6x370wp 2220wp ZW Totaal 8160wp Locatie Zuid-Limburg Bunde


  • remco_k
  • Registratie: April 2002
  • Laatst online: 22:01

remco_k

een cassettebandje was genoeg

De Goodwe XS serie praat Modbus over UDP. Dan hoef je niet met RS485 te rotzooien. Dus gewoon Wifi of Ethernet module erin en klaar.

Voor Domoticz heb ik daar een plugin voor gemaakt.

En ja, klopt. Ik ben nog nooit een verkoper tegengekomen die goed voorbereid was voor- of ook maar antwoorden kon geven op dit soort vragen. Daar gebeurd het blijkbaar te weinig voor en is een ondergeschoven kindje.

[Voor 6% gewijzigd door remco_k op 13-02-2023 20:32]

Alles kan stuk.
Goedkoop Shoutcast stream hosting? Snel online, geen setup kosten. www.digiplay.nl


  • The Fatal
  • Registratie: Maart 2009
  • Laatst online: 21:12
heb zelf 3 GoodWe omvormers hangen van 3 verschillende leveranciers, die lees ik allemaal lokaal uit via een eigen gemaakt python scriptje.
Op alle 3 zit de standaard wifi module,
Enige is dat de juiste firmware er op moet staan, zo nee, dan berichtje sturen naar goodwe en ze updaten hem voor je.

heel basaal:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import json
import socket
import datetime
from enum import Enum


class GoodweStatus(Enum):
    Offline = -1
    Waiting = 0
    Online = 1
    Error = 2
    Checking = 3


def to_16_bit(buffer: [bytes], exp: int = -1, signed: bool = False) -> int:
    return round((int.from_bytes(bytes(buffer), byteorder='big', signed=signed)) * 10**exp, -exp);

class Goodwe:

    _port: int = 0
    _ip: str = ''

    def __init__(self, ip: str = '', port: int = 8899) -> None:
        if ip != '':
            self._ip = ip
        self._port = port

    @staticmethod
    def getCRC(payload: [bytes]) -> [bytes]:
        crc = 0xFFFF
        odd = False
    
        for i in range(0, len(payload)):
            crc ^= payload[i]

            for j in range(0, 8):
                odd = (crc & 0x0001) != 0
                crc >>= 1;
                if odd:
                    crc ^= 0xA001
        return crc.to_bytes(2, byteorder='little', signed=False)

    def getData(self, retries=3):
        while retries > 0:
            retries -= 1
            try:
                return self._getData(self._ip, self._port)
            except Exception as e:
                print(f'Retrying {retries}')
                if retries == 0:
                    defaultData = {
                        'voltage_dc_1': None, 
                        'current_dc_1': None, 
                        'voltage_ac_1': None, 
                        'current_ac_1': None, 
                        'frequency_ac_1': None, 
                        'power_ac': 0, 
                        'status': 'Offline',
                        #'yield_today': 0, 
                        'temperature': None, 
                        'power_dc_1': 0}
                    return defaultData
                pass
        #raise Exception('Could not get proper data after retrying')

    def _getData(self, ip, port):

        # get data from inverter
        cs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        cs.settimeout(1)
        msg = bytes(b'\x7f\x03\x75\x94\x00\x49\xd5\xc2')
        cs.sendto(msg, (ip, port))

        response = cs.recvfrom(1024)
        #print(f'Got response from server: {response}')

        # the first part is a list of bytes
        data = bytes(response[0])
        
        # check length of packet
        if len(data) != 153:
            raise Exception(f'Invalid data (unexpected length: {len(data)}')

        # check header
        header = data[0:2]
        if header != b'\xaa\x55':
            raise Exception(f'Invalid header: {header}')

        # check CRC
        receivedCRC = data[-2:]
        payload = data[2:151]
        calculatedCRC = self.getCRC(payload)
        if receivedCRC != calculatedCRC:
            raise Exception(f'comparing received {receivedCRC} {int.from_bytes(receivedCRC, "big")} to {calculatedCRC}')
            
        #print("###############################")
        #print(data)
        #print("###############################")
        
        date = datetime.datetime(
            year=data[5] + 2000, month = data[6], day=data[7],
            hour=data[8],minute=data[9], second=data[10])
        status = { -1 : 'Offline', 0 : 'Waiting', 1 : 'Online' , 2:'Error', 3:'Checking'}
        
        gw = {
            #'sample': date,
            'voltage_dc_1': to_16_bit(data[11:13]),
            'current_dc_1': to_16_bit(data[13:15]),
            'voltage_dc_2': to_16_bit(data[15:17]),
            'current_dc_2': to_16_bit(data[17:19]),
            #'voltage_dc_3': to_16_bit(data[19:21]),
            #'current_dc_3': to_16_bit(data[21:23]),
            #'voltage_dc_4': to_16_bit(data[23:25]),
            #'current_dc_4': to_16_bit(data[25:27]),

            'voltage_ac_1': to_16_bit(data[41:43]),
            #'voltage_ac_2': to_16_bit(data[43:45]),
            #'voltage_ac_3': to_16_bit(data[45:47]),
            'current_ac_1': to_16_bit(data[47:49]),
            #'current_ac_2': to_16_bit(data[49:51]),
            #'current_ac_3': to_16_bit(data[51:53]),
            'frequency_ac_1': to_16_bit(data[53:55], -2),
            #'frequency_ac_2': to_16_bit(data[55:57], -2),
            #'frequency_ac_3': to_16_bit(data[57:59], -2),
            'power_ac': to_16_bit(data[61:63], 0),
            #'status': str(GoodweStatus(int(to_16_bit(data[63:65], 0)))),
            'status': status.get(int(to_16_bit(data[63:65], 0))),

            'temperature': to_16_bit(data[87:89]),
            'yield_today': to_16_bit(data[93:95]),
            'yield_total': to_16_bit(data[95:99]),
            'working_hours': to_16_bit(data[101:103], 0)
        }

        if gw['yield_today'] > 6500:
            raise Exception(f'Yield today to high {gw["yield_today"]}')
        if gw['yield_total'] > 4000000:
            raise Exception(f'yield total too high {gw["yield_total"]}')

        # add DC power output if applicable
        for i in range(1,5):
            if gw[f'voltage_dc_1'] < 6553:
                gw[f'power_dc_1'] = gw[f'voltage_dc_1'] * gw[f'current_dc_1']
                gw[f'power_dc_1'] = round(gw[f'power_dc_1'],2)
            if gw[f'voltage_dc_2'] < 6553:
                gw[f'power_dc_2'] = gw[f'voltage_dc_2'] * gw[f'current_dc_2']
                gw[f'power_dc_2'] = round(gw[f'power_dc_2'],2)
        return gw

[Voor 0% gewijzigd door septillion op 13-02-2023 21:02]


  • FJR1300
  • Registratie: Juli 2001
  • Laatst online: 20-03 16:09

FJR1300

145 enthousiaste paardjes...

Topicstarter
DeHollander schreef op maandag 13 februari 2023 @ 18:44:
@FJR1300 ik denk dat de meeste van je vragen hier wel beantwoord worden.
Ja, daar had ik al eens zitten lezen maar dat begon al in 2017 met een ander model. Toch maar eens voor gaan zitten om het helemaal uit te pluizen ;)

  • FJR1300
  • Registratie: Juli 2001
  • Laatst online: 20-03 16:09

FJR1300

145 enthousiaste paardjes...

Topicstarter
remco_k schreef op maandag 13 februari 2023 @ 20:30:
De Goodwe XS serie praat Modbus over UDP. Dan hoef je niet met RS485 te rotzooien. Dus gewoon Wifi of Ethernet module erin en klaar.
mmm... oke, dat had ik al eens gezien maar dan komt er vaak ook een heel verhaal over welke firmware het wel en/of niet doet... Maar voor Modbus over UDP bestaat al een hoop software dus daar ga ik me eens in verdiepen.

  • FJR1300
  • Registratie: Juli 2001
  • Laatst online: 20-03 16:09

FJR1300

145 enthousiaste paardjes...

Topicstarter
The Fatal schreef op maandag 13 februari 2023 @ 20:46:
heb zelf 3 GoodWe omvormers hangen van 3 verschillende leveranciers, die lees ik allemaal lokaal uit via een eigen gemaakt python scriptje.
Op alle 3 zit de standaard wifi module,
Enige is dat de juiste firmware er op moet staan, zo nee, dan berichtje sturen naar goodwe en ze updaten hem voor je.
Oke, dus om de volgorde even goed op het vizier te hebben:
1. Wifi stick in de omvormer en gewoon een account aanmaken etc zodat goodwe eventueel kan updaten.
2. Na een mogelijke update de omvormer isoleren van het internet om 'spionnen' buiten te houden.
3. Met scriptjes data uitlezen rechtsteeks van de omvormer.

Prima. Snap ik. Even kijkend naar je code: Ik zie port 8899. Is dat modbus? Ik meende gezien te hebben dat modbus tcp 502 is en udp 4800... of is 8899 de Goodwe implementatie daarvan?

  • remco_k
  • Registratie: April 2002
  • Laatst online: 22:01

remco_k

een cassettebandje was genoeg

8899 is modbus over udp bij Goodwe omvormers.
Je moet daar de juiste relatief nieuwe firmware voor hebben en omdat je je omvormer nog krijgen moet, zou dat geen enkel probleem moeten zijn.
Mijn omvormer, ook XS serie, deed het out of de box. De bijbehorende wifi stick is alleen een super brak ding. Maar daar is, geloof ik, verandering in gekomen in de tussentijd.

Wat je gebruikt om modbus viahet netwerk uit te lezen is een keuze (mijn Domoticz krijgt elke seconde realtime data van mijn SolarEdge en Goodwe omvormers, beide Modbus over het netwerk).
Ik zou het als ik jouw was in ieder geval via deze route doen en er even mee spelen wat voor jouw de beste client is.

[Voor 30% gewijzigd door remco_k op 14-02-2023 19:24]

Alles kan stuk.
Goedkoop Shoutcast stream hosting? Snel online, geen setup kosten. www.digiplay.nl


  • The Fatal
  • Registratie: Maart 2009
  • Laatst online: 21:12
FJR1300 schreef op dinsdag 14 februari 2023 @ 15:24:
[...]


Oke, dus om de volgorde even goed op het vizier te hebben:
1. Wifi stick in de omvormer en gewoon een account aanmaken etc zodat goodwe eventueel kan updaten.
2. Na een mogelijke update de omvormer isoleren van het internet om 'spionnen' buiten te houden.
3. Met scriptjes data uitlezen rechtsteeks van de omvormer.

Prima. Snap ik. Even kijkend naar je code: Ik zie port 8899. Is dat modbus? Ik meende gezien te hebben dat modbus tcp 502 is en udp 4800... of is 8899 de Goodwe implementatie daarvan?
Dat is voor zo ver ik weet de lokale poort. Ik roep het aan op lokaal ip+poort.

Je volgorde lijkt juist. Heb het zelf niet zo getest. Maar heb een apart VLAN. Dat standaard niet naar mijn interne netwerk kan. Behalve als de verbinding vanuit mijn interne netwerk word opgezet. Daarnaast staat ook cliënt isolation aan op het aparte vlan.
Met deze opzet kunnen ze wel “het internet op” voor secundaire logging etc maar slangetje goed is niet op het interne netwerk.

Ps: boven genoemd script word door een ander run script aangeroepen met een call van lokaal ip adres etc en daarna op MQTT gegooid.
Mijn coding skills zijn niet het beste maar werkt al meer dan een jaar dikke prima.

[Voor 9% gewijzigd door The Fatal op 14-02-2023 21:48]


  • FJR1300
  • Registratie: Juli 2001
  • Laatst online: 20-03 16:09

FJR1300

145 enthousiaste paardjes...

Topicstarter
remco_k schreef op dinsdag 14 februari 2023 @ 19:20:
Ik zou het als ik jouw was in ieder geval via deze route doen en er even mee spelen wat voor jouw de beste client is.
Jou domoticz plugin en het script van The Final hebben in ieder geval voldoende inspiratie gegeven om met deze netwerk route te beginnen. Het plan is vooralsnog om met jullie code voorbeelden iets te gaan integreren in mijn bestaande Python programmatuur.

Spelen met een RS485 to TTL converter kan altijd nog... doet me weer een beetje denken aan de oude tijd... seriële poorten, (4 draads)modems, leased lines... :)

  • FJR1300
  • Registratie: Juli 2001
  • Laatst online: 20-03 16:09

FJR1300

145 enthousiaste paardjes...

Topicstarter
The Fatal schreef op dinsdag 14 februari 2023 @ 21:45:
... Maar heb een apart VLAN. Dat standaard niet naar mijn interne netwerk kan. Behalve als de verbinding vanuit mijn interne netwerk word opgezet. Daarnaast staat ook cliënt isolation aan op het aparte vlan.
Ja, ik heb mijn IOT spul ook op een apart VLAN achter een firewall en een apart SSID van het WiFi. Daarmee kan ik heel selectief bepalen wat waarheen kan. Van mijn eigen brouwsels weet ik wel wat het gaat doen maar hardware en software van een ander... better safe than sorry.

Volgende item op de lijst: Leveranciers lastigvallen over levertijden :)
Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee