tobiasfaust / SolaxModbusGateway

Modbus RTU to MQTT Gateway
GNU General Public License v3.0
54 stars 17 forks source link

Solax X3-PRO-G2 #30

Closed wm1962 closed 4 months ago

wm1962 commented 10 months ago

Hallo Tobias, zunächst einmal mein Lob an deine tolle Software. Ich habe einen Solax X3-PRO-G2 und in der Modbus Config "Solax-MIC" eingestellt. Über die Com-Schnittstelle des ESP32 kommen folgende Meldungen

Request queue data to inverter 0x01 0x04 0x00 0x78 0x00 0x77 0x30 0x35 Read Data from Queue 0x01 0x84 0x02 0xC2 0xC1 Dataframe invalid

Scheinbar versteht der X3-PRO-G2 die Kommandos nicht. Kannst Du mir weiterhelfen?

Viele Grüße Wilfried

tobiasfaust commented 10 months ago

Hi Wilfried, erstmal die gute Nachricht: Die Verkabelung stimmt, die Anfrage kommt beim Inverter an und der Inverter antwortet korrekt :) Jetzt die schlechte Nachricht: Der Inverter versteht die Anfrage nicht und liefert einen korrekten Fehlercode mit (0x84). Soll heißen, das ModbusProtokoll ist abweichend. Bitte versuche mal als erstes auf "Solax X3" umzustellen da "Solax MIC" offensichtlich nicht zu deinem Solax X3-Pro-G2 passt. Der Invertertyp muss am Anfang immer korrekt eingestellt sein ;)

wm1962 commented 10 months ago

Hi Tobias, sorry, ich habe mich da verschrieben, ich hatte bereits "Solax X3" eingestellt.

tobiasfaust commented 10 months ago

Ok, die Antwort bleibt leider dieselbe. Dein Request aus dem ersten Post ist aber von MIC. Poste mal einen aktuellen Request. Du kannst versuchen die Invertertypen nacheinander durchzuprobieren ob irgendeiner annähernd passt. Besser wäre es die ModbusProtokoll Doku vom SolaxSupport sich schicken zu lassen. Die antworten auch relativ schnell. Dann kann man eine eigene Sektion für den PRO anlegen wenn diese total abweichend von einer der anderen ist.

wm1962 commented 10 months ago

ok, den Support habe ich soeben angeschrieben. Den aktuellem Request poste ich heute abend, da die Anlage nicht vor Ort ist. Kann ich eigentlich im Reiter "Raw Data" vorab etwas testen? Kannst du die Möglichkeiten dort noch etwas erklären? grafik

tobiasfaust commented 10 months ago

erst wenn korrekte Antworten kommen kann man auf der RAW Seite weiter arbeiten. Wie? Ist im Wiki unter Punkt "6. Advanced stuff" erklärt ;) Hoffentlich verständlich

wm1962 commented 9 months ago

Hi Tobias, nun habe ich über meinen Händler die Doku von Solax bekommen. Kannst du mir mir eine pn schreiben, dann kann ich die dir zukommen lassen.

kommando828 commented 9 months ago

You can add the PDF to a post by dragging it until its under the dotted line. Like so.

Solax Power X1-BOOST Single phase inverter Modbus-RTU comms protocolV1.0 - Public version.pdf

wm1962 commented 9 months ago

sorry, at the moment I'm not allowed to publish the document

kommando828 commented 9 months ago

So instead compare the file you have with the Tobias posted pdf's and see which has the closest match.

https://github.com/tobiasfaust/SolaxModbusGateway/tree/development/docs

Then select that inverter and try a test.

wm1962 commented 9 months ago

Hi Tobias, ich habe bei dem Dokument nun den Schutz entfernen können. Es sieht analog zur V1.9 aus, ich komme damit leider nicht klar. Kannst Du helfen?

Solax X3-PRO Modbus-Protokoll V2.7.pdf

tobiasfaust commented 9 months ago

Hi, wenn es wirklich dieses Dokument ist, stell mal den SOLAX MIC ein. Die Live-Register starten ab 0x400

Wenn es nichts hilft, dann bitte folgende Schritte nacheinander. Nach jedem Schritt bitte prüfen ob es schon funktioniert.

  1. 9600 Baud einstellen
  2. Firmwareupdate Wechselrichter, du brauchst bestenfalls die ARM Version 1.22 mit ProtokollVersion V2.7
  3. in der register.h, section "Solax MIC" den RequestLiveData anpassen auf:

"RequestLiveData": [ ["#ClientID", "0x04", "0x04", "0x00", "0x00", "0x16"] ],

  1. wenn 2 hilft, dann schrittweise die 0x16 (in Hex!) erhöhen bis der Fehler wieder kommt.
wm1962 commented 9 months ago

Hi Tobias, ich habs heute nachmittag hinbekommen mit den Live-Registern ab 0x400 und ID-Registern ab 0x300 und es kommen tatsächlich Daten. Zumindest mal die Seriennummer, die anderen Werte kommen auch, passen mit der Doku von Solax jedoch nicht überein. Da muß ich morgen nochmals testen. Aktuell hat sich der WR abgeschaltet. Ich melde mich wieder. Vielen Dank soweit 👍

tobiasfaust commented 9 months ago

Super, mach mal ein Firmwareupdate. Die Doku muss ja mit dem Stand der Firmware des WR zusammenpassen ;)

tobiasfaust commented 9 months ago

gibt es etwas Neues?

wm1962 commented 9 months ago

Ich habe die Daten soweit eingepflegt. Beim Tages- und Gesamtertrag habe ich jedoch noch Probleme die Werte richtig zu interpretieren/darzustellen. Da muß ich noch etwas testen.

Noch eine Frage: wie funktioniert das mit dem "set-Befehl" und kann man neben der "InverterSN" weitere ID-Datas auf der webgui page darstellen?

tobiasfaust commented 9 months ago

Welche WR-Settings hatten denn am besten gepasst? Oder musstest du eine neue Sektion bauen? Wenn du fertig bist nehme ich die JSON Änderung gerne an um sie ins Repo einchecken zu können

Zur Frage mit dem set Befehl: Ich habe hier die Vorbereitungen im Code eingebaut, aber ohne Tests da ich selbst keine set´s absetze. Zu den ID-Data: Aktuell können ohne Codeänderung keine weiteren ID-Daten angezeigt werden. Da müsste ich erst noch ran.

wm1962 commented 9 months ago

Hallo Tobias, ich habe nun die richtige Darstellung für die noch offenen Werte gefunden. Anbei die Datei mit dem Teil der Register-Daten für den Solax-X3-PRO. Solax-X3-PRO.txt

Grüße Wilfried

wm1962 commented 9 months ago

Zur Frage mit dem set Befehl: Ich habe hier die Vorbereitungen im Code eingebaut, aber ohne Tests da ich selbst keine set´s absetze.

Ich sollte beim meinem Solax die Ausgangsleistung setzen können, kannst Du mir das mit dem set Befehl etwas näher erläutern?

tobiasfaust commented 9 months ago

Hi, Als erstes musst du das korrekte Register kennen was du setzen willst. Als absoluter erster Versuch ist auch hier das Example ein guter Start. Einfach die zu setzende registergruppe an einen schreibbefehl anpassen, genaueres findest du nur in deiner Modbus Doku.

Problem ist, das Solax nur ungern die Dokumente mit der Auflistung der schreibregister rausrückt.

MagicSven81 commented 8 months ago

Hier der Code für den X3 Pro G2:

"Solax-X3-PRO": {
    "config": {
        "RequestLiveData": [
            ["#ClientID", "0x04", "0x04", "0x00", "0x00", "0x40"],
            ["#ClientID", "0x04", "0x07", "0x00", "0x00", "0x0A"]
        ],
        "RequestIdData": ["#ClientID", "0x03", "0x03", "0x00", "0x00", "0x54"],
        "ClientIdPos": 0,
        "LiveDataFunctionCodePos": 1,
        "LiveDataFunctionCode": "0x04",
        "IdDataFunctionCodePos": 1,
        "IdDataFunctionCode": "0x03",
        "LiveDataStartsAtPos": 3,
        "IdDataStartsAtPos": 3,
        "LiveDataErrorPos": 1,
        "LiveDataErrorCode": "0x84",
        "IdDataErrorPos": 1,
        "IdDataErrorCode": "0x83",
        "LiveDataSuccessPos": 1,
        "LiveDataSuccessCode": "0x04",
        "IdDataSuccessPos": 1,
        "IdDataSuccessCode": "0x03"
    },
    "data": {
        "livedata": [
            {
                "position": [3, 4],
                "name": "PvVoltage1",
                "realname": "Pv Voltage 1",
                "datatype": "float",
                "factor": 0.1,
                "unit": "V"
            },
            {
                "position": [5, 6],
                "name": "PvVoltage2",
                "realname": "PV Voltage 2",
                "datatype": "float",
                "factor": 0.1,
                "unit": "V"
            },
            {
                "position": [85, 86],
                "name": "PvVoltage3",
                "realname": "PV Voltage 3",
                "datatype": "float",
                "factor": 0.1,
                "unit": "V"
            },
            {
                "position": [7, 8],
                "name": "PvCurrent1",
                "realname": "PV Current 1",
                "datatype": "float",
                "factor": 0.1,
                "unit": "A"
            },
            {
                "position": [9, 10],
                "name": "PvCurrent2",
                "realname": "PV Current 2",
                "datatype": "float",
                "factor": 0.1,
                "unit": "A"
            },
            {
                "position": [87, 88],
                "name": "PvCurrent3",
                "realname": "PV Current 3",
                "datatype": "float",
                "factor": 0.1,
                "unit": "A"
            },
            {
                "position": [31, 32],
                "name": "PAC",
                "realname": "P-AC",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [33, 34],
                "name": "RunMode",
                "realname": "Inverter Status",
                "datatype": "integer",
                "mapping": [[0,"WaitMode"],[1,"CheckMode"],[2,"NormalMode"],[3,"FaultMode"],[4,"PermanentFaultMode"]]
            },
            {
                "position": [41, 42],
                "name": "Total Power DC",
                "realname": "P-DC",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [43, 44],
                "name": "PDC1",
                "realname": "P-DC1",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [45, 46],
                "name": "PDC2",
                "realname": "P-DC2",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [89, 90],
                "name": "PDC3",
                "realname": "P-DC3",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [11, 12],
                "name": "GridVoltage_R",
                "realname": "Grid Voltage L1",
                "datatype": "float",
                "factor": 0.1,
                "unit": "V"
            },
            {
                "position": [13, 14],
                "name": "GridVoltage_S",
                "realname": "Grid Voltage L2",
                "datatype": "float",
                "factor": 0.1,
                "unit": "V"
            },
            {
                "position": [15, 16],
                "name": "GridVoltage_T",
                "realname": "Grid Voltage L3",
                "datatype": "float",
                "factor": 0.1,
                "unit": "V"
            },
            {
                "position": [17, 18],
                "name": "GridFrequency_R",
                "realname": "Grid Frequency L1",
                "datatype": "float",
                "factor": 0.01,
                "unit": "Hz"
            },
            {
                "position": [19, 20],
                "name": "GridFrequency_S",
                "realname": "Grid Frequency L2",
                "datatype": "float",
                "factor": 0.01,
                "unit": "Hz"
            },
            {
                "position": [21, 22],
                "name": "GridFrequency_T",
                "realname": "Grid Frequency L3",
                "datatype": "float",
                "factor": 0.01,
                "unit": "Hz"
            },
            {
                "position": [23, 24],
                "name": "GridOutputCurrent_R",
                "realname": "Grid Current L1",
                "datatype": "float",
                "factor": 0.1,
                "unit": "A"
            },
            {
                "position": [25, 26],
                "name": "GridOutputCurrent_S",
                "realname": "Grid Current L2",
                "datatype": "float",
                "factor": 0.1,
                "unit": "A"
            },
            {
                "position": [27, 28],
                "name": "GridOutputCurrent_T",
                "realname": "Grid Current L3",
                "datatype": "float",
                "factor": 0.1,
                "unit": "A"
            },
            {
                "position": [29, 30],
                "name": "InverterTemperature",
                "realname": "Inverter Temperature",
                "datatype": "integer",
                "unit": "°C"
            },
            {
                "position": [91, 92],
                "name": "MainboardTemperature",
                "realname": "Mainboard Temperature",
                "datatype": "integer",
                "unit": "°C"
            },
            {
                "position": [75,76,73,74],
                "name": "YieldTotal",
                "realname": "Gesamtertrag",
                "datatype": "integer",
                "factor": 0.1,
                "unit": "kWh"
            },
            {
                "position": [79,80,77,78],
                "name": "YieldToday",
                "realname": "Tagesertrag",
                "datatype": "integer",
                "factor": 0.1,
                "unit": "kWh"
            },
            {
                "position": [123,124,121,122],
                "name": "GridPower",
                "realname": "GridPower",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [127,128,125,126],
                "name": "FeedInEnergy",
                "realname": "Feed In Energy",
                "datatype": "integer",
                "factor": 0.01,
                "unit": "kWh"
            },
            {
                "position": [131,132,129,130],
                "name": "ConsumeEnergy",
                "realname": "Consume Energy",
                "datatype": "integer",
                "factor": 0.01,
                "unit": "kWh"
            },
            {
                "position": [129,130,131,132],
                "name": "ConsumeEnergy2",
                "realname": "Consume Energy2",
                "datatype": "integer",
                "factor": 0.01,
                "unit": "kWh"
            },
            {
                "position": [133,134],
                "name": "PowerRef",
                "realname": "PowerRef",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [137,138,135,136],
                "name": "PowerToEV",
                "realname": "PowerToEV",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [139,140],
                "name": "PVRef",
                "realname": "PV Ref",
                "datatype": "integer",
                "unit": " "
            },
            {
                "position": [143,144,141,142],
                "name": "FeedInPowerR",
                "realname": "FeedInPowerL1",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [147,148,145,146],
                "name": "FeedInPowerS",
                "realname": "FeedInPowerL2",
                "datatype": "integer",
                "unit": "W"
            },
            {
                "position": [151,152,149,150],
                "name": "FeedInPowerT",
                "realname": "FeedInPowerL3",
                "datatype": "integer",
                "unit": "W"
            }
        ],
        "id": [
                {
                "position": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
                "name": "InverterSN",
                "realname": "Inverter SerialNumber",
                "datatype": "string"
            },
            {
                "position": [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
                "name": "FactoryName",
                "realname": "Factory Name",
                "datatype": "string"
            },
            {
                "position": [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42],
                "name": "ModuleName",
                "realname": "Module Name",
                "datatype": "string"
            },
            {
                "position": [43, 44, 45, 46, 47, 48],
                "name": "FirmwareVersion",
                "realname": "Firmware Version",
                "datatype": "string"
            },
            {
                "position": [159],
                "name": "Safty",
                "realname": "Safty",
                "datatype": "integer"
            },
            {
                "position": [160],
                "name": "MachineType",
                "realname": "Machine Type",
                "datatype": "integer"
            },
            {
                "position": [161],
                "name": "Power Ratio",
                "realname": "Percent of Powerlimits",
                "datatype": "integer",
                "factor": 0.01,
                "unit": "%"
            },
            {
                "position": [162],
                "name": "MpptScanMode",
                "realname": "MpptScanMode",
                "datatype": "integer"
            }
        ]
    }
},
wm1962 commented 8 months ago

@MagicSven81 Hast du zufällig schon mal probiert in die Single-Write-Register ab 0x600 etwas zuschreiben?

Ich versuche in das Register 0x60F (PowerLimitsPercent) zu schreiben, schreibe daher zuerst in 0x600 das Unlock-Passwort (2014 - dezimal), was positiv quittiert wird 0x02 0x06 0x06 0x00 0x00 0x00 0x89 0x71 - antwort: 0x02 0x06 0x06 0x00 0x00 0x00 0x89 0x71

Danach schreibe ich in den Wert 0x64 (100 - dezimal) ins Register 0x60F und bekomme jedoch eine negative Quittierung 0x02 0x06 0x06 0x0F 0x00 0x64 0xB8 0x99 - antwort: 0x02 0x86 0x06 0x32 0x62

Gruß Wilfried