SMA-Net Protokoll hacken (RS485,YASDI)

  • Klar ist der Post ärgerlich, weil hier ja schon längst das SMA Protokol aufgeklärt sein sollte.. Vielleicht kann ja jemand auf einen solchen Post verlinken...


    Möchte endlich mal mein Windows 7 Notebook durch Arduino.. ersetzen.
    Der Packetmonitor vom SunnyExplorer, die YASDI pdf Seite 40 und https://sites.google.com/site/terminalbpp/ lassen das Protokoll leicht zerlegen:


    SMANet ist also in https://de.wikipedia.org/wiki/…_Link_Control#Blockaufbau eingebettet.
    Wenn also ein Paket über die RS485 gesendet wird, fängt das immer an mit

    Code
    1. 7E FF 03 40 41


    und endet mit zB.

    Code
    1. F1 17 7E


    Wobei die F117 die Prüfsumme ist.


    Darin eingebettet kommen anfangs immer 7 byte:

    Code
    1. 00 00 02 00 00 00 0B


    16 bit Senderadresse, 16 bit Empfängeradresse, 8 bit "Control", 8 bit "PaketCounter", 8 bit "Command"
    Hier also ein Paket vom SunnexExplorer zum Wechselrichter 2.
    Es handelt sich offensichtlich um die Aufforderung zum Senden der aktuellen Daten.
    Als Inhalt dieser Anfrage werden nur 3 Bytes mitgeschickt:

    Code
    1. 0F 09 00


    Wenn man also vom Wechselrichter x die aktuellen Werte haben, so muss man nur mit 1200 Baud und 30 cent https://www.aliexpress.com/ite…essories/32848344535.html folgendes raus schicken:
    Wechselrichter 1:

    Code
    1. 7E FF 03 40 41
    2. 00 00 01 00 00 00 0B
    3. 0F 09 00
    4. 21 9D 7E


    Wobei die Antwort in zwei Paketen zu kommen scheint. Drum scheint der SunnyExplorer erst den Empfang des ersten Pakets zu bestätigen, woraufhin der WR das zweite Paket schickt. Das hat dann die ID 0 (PaketCounter) und drum weiß der SunnyExplorer dass alle Daten angekommen sind. Seltsam das das erste Paket manchmal 84 bytes lang ist, manchmal 85:



    Wie diese Daten zu entschlüsseln sind, sollte über den Sourcecode der YASDI API möglich sein.
    Wobei mir über mein Mini-Portal http://www.robosolar.de auch schon nur die aktuelle Einspeiseleistung reichen würde. Und die könnte ich mit den im SunnyExplorer angezeigten Werten auch noch hacken.


    Aber ich mach mir hier sicher gerade unnötig Arbeit, weil das bestimmt schon jemand anderes hier gemacht hat.
    Und da hier ja zu 99% immer nur Besserwisser ihr Bestes zum Besten geben, können die jetzt bitte links posten.


    das Roland, der geborene Verlierer
    und Dankeschön !

  • Jetzt wurschtel ich mich ein wenig durch die api https://www.sma.de/produkte/monitoring-control/yasdi.html durch


    core/smadata_layer.h


    damit kann ich noch nichts anfangen:


    Hier die Funktion aus core/defractionizer.c , welche die zwei empfangenen Pakete zu einem Ganzen zusammen baut:


    Die Rohdaten landen also in der struct TNetPacket aus core/netpacket.h

    Code
    1. struct TNetPacket
    2. {
    3. TMinNode Node; /* Zum Verketten von mehreren Puffern in einer Liste */
    4. TMinList( Fragments ); /* Liste der Pufferfragmente */
    5. TNetPacketRouteInfo RouteInfo; /* Routing infos for the packet */
    6. };


    include/lists.h

    Code
    1. typedef struct
    2. {
    3. TMinNode * Head; //Pointer to the first element of the list
    4. TMinNode * Tail; //always "NULL" (mark end of list , see AMIGA Lists)
    5. TMinNode * Tailprev; //Pointer to last element of the list
    6. T_MUTEX Mutex; //A Mutex for thread critical section...
    7. } TMinList;


    Damit bin ich aber immer noch nur bei den Roh-Daten.
    Wo daraus die expliziten Werte für Einspeiseleistung, etz. definiert werden, hab ich noch nicht gefunden.


    Ideen immer zu mir :-)
    Ausreden woanders hin :-(

  • Die YASDI umfasst SIEBEN Abstraktionsebenen. Von den Rohdaten bis zum P_ac Wert werden die Bytes also bis zu 7 mal in neue Form kopiert.



    Mir scheint also, die Rohdaten lassen sich keiner einzigen Struct zurodnen, die dann alle Parameter wie P_ac enthält.
    Stattdessen werden die Rohdaten auf "Channel" verteilt.
    master/netchannel.h


    Und auf der obersten Abstraktionsebene wird dann aus dem String "pac" der passende Channel gesucht, und der Wert ausgelesen:
    samples/sample1/sample1.c

    .


    Ich werde jetzt wohl mal einen ESP32 her nehmen und versuchen den Wechselrichtern die Rohdaten zu entlocken..
    Theoretisch könnte ich die yasdi.dll (91kB) und yasdimaster.dll (82 kB) auch für den ESP32 kompilieren. der ESP32 fasst ja 520 kB.


    Mit den 7 Abstraktionsebenen schieße ich aber ja mit Kanonen auf Spatzen. Da würde ich mehr Zeit mit debuggen der api vergeuden als wenn ich die Rohdaten hacke.


    Ideen immer zu mir.

    Einmal editiert, zuletzt von Elektron () aus folgendem Grund: edit

  • Bevor man die WR auffordert, ihre Werte zu schicken, muss man noch einen "CMD_SYN_ONLINE"(=0x0A) "broadcast"(=0x80) senden,

    Code
    1. 7E FF 03 40 41
    2. 00 00 00 00 80 00 0A
    3. FF 60 54 5B
    4. 73 B6 7E


    sonst antworten die WR danach nicht mit neuen Werten.


    Davor schickt der SunnyExplorer übrigens noch Bytes die offensichtlich nicht dem SMA-Net Protokoll angehören:

    Code
    1. 68 04 04 68
    2. 00 00 00 00 80 00 0A
    3. FF 60 54 5B
    4. 98 02 16


    Wahrscheinlich pingt er da weitere möglichen WR mit dem Sunny-Net Protokoll (siehe Seite 40. der obigen pdf).


    Hab jetzt einen Arduino Nano laufen (rs485 Ding brauchte 5V statt 3,3V), der die Rohdaten abrufen kann. Jetzt muss ich nur noch raus finden, welche 4 Bytes die Float-Zahl für P_ac darstellen.

  • Zitat von ManfredR

    SMAData(1) ist pupliziert von SMA und kann auch runtergeladen werden.


    Never change a running system. Wozu sollte ich meine 11 Jahre alten MiniCentral neue Firmware verpassen ?
    Aber danke für den Link. Die haben wohl ein paar Dinge übernommen:
    Seite 46:

    Code
    1. Bit FEDC BA98 7654 3210
    2. 0000 1001 0000 1111 = 090F (Hex) ⇒ Anforderung Momentanwerte Ein- gangssignale aller Signaltypen


    Das ist wahrscheinlich genau die Anforderung aus dem altenProtokoll

    Code
    1. 7E FF 03 40 41
    2. 00 00 02 00 00 00 0B
    3. 0F 09 00
    4. F1 17 7E


    Und ja auch schon gehackt:

    Code
    1. 4.3.2.1 Onlinedaten synchronisieren (CMD_SYN_ONLINE)
    2. Um eine zeitgleiche Erfassung von Onlinedaten zu gewährleisten, muss vor jedem
    3. Abfragezyklus ein Synchronisationsbefehl mit der aktuellen Zeit als Broadcastmeldung
    4. an alle Busteilnehmer gesendet werden.


    Diese 0F 09 00 ist also die "Übertragungsmaske" und die wird drum auch in der Antwort zu Beginn zurück gesendet. Neues wie altes Protokol. Die noch zu hackenden Rohdaten schlüsseln sich also schon mal so auf:

    Code
    1. Dateninhalt: Übertragungsmaske (3 Byte)
    2. Anzahl der Datensätze (word) (zu berechnen)
    3. Datensätze (nn Byte) (zu berechnen)


    Der Anfang der Rohdaten scheint mit dem alten Protokoll überein zu stimmen:

    Code
    1. 0F 09 00 übertragungsmaske
    2. 01 00 anzahl datensätze
    3. 19 61 54 5B unix time
    4. 01 00 00 00 zeitbasis


    Der Rest scheint mir aber anders festgelegt zu sein als auf Seite 50 des neuen Protokol. Zumal ich mehr Bytes zurück bekomme:


    Wär schön wenn jetzt auch jemand eine pdf zum SMA-Net Protokoll posten könnte.
    Ich hacke derweil weiter..

  • Ah nochmal Danke, der link war wohl schon die Referenz zum SMA-Net Protokoll.
    Und es wird doch eine große Struct übertragen:


    Wobei sie vielleicht durch die 3 Byte Maske verkleinert werden kann.


    Bevor man die empfangenen Rohdaten auf die struct casted muss man noch das "Bitstuffing" umkehren. Die Checksummen-Prüfung hab ich mir noch erspart, sollte sich aber auch leicht aus der YASDI source kopieren lassen.


    Manche Werte kann ich nicht sinnvoll zuordnen. Vielleicht hat hier noch jemand Ideen. Ich hab aber jetzt alles was ich brauche:


    das Roland

  • Was hast du eigentlich genau vor?


    Relevante Werte lassen sich prima mit PHPModbus auf dem NAS mit Cronjob oder anderen Modbusapplikationen über Python usw usf auf Raspi und (ich meine sogar)Arduino bei github als fertiges Paket laden und installieren.


    Die Varianten per Raspi lassen soweit ich weiss kürzere Intervalle als der Cronjob auf dem NAS zu


    Nun denne... wo soll es hin gehen?


    Grüsse
    Carsten

    7,28 kWp, 6000TL20, Ost mit 28 x ReneSola JC260M-24/Bb (02/2013)
    2,65 kWp, 2500TL21, West mit 10 x SolarWorld AG SW 265 mono (EU)
    6,48 kWp, SB5.0, W/NW mit 22 x SolarWorld AG SW 270 mono (EU)
    14,8 kWh Hoppecke Batterie mit SI 6H-11

  • Zitat von Carstene

    NAS mit Cronjob oder anderen Modbusapplikationen über Python usw usf


    Wer Linux (oder Python) NICHT für Scheiße hält hat vom Programmieren keine Ahnung..


    Bei mir geht es Richtung https://de.wikipedia.org/wiki/Long_Range_Wide_Area_Network
    Also zwei ESP32 mit Oled, Sd, Wifi, Bluetooth und eben LoRa für 35 Euro: http://www.aliexpress.com/item…-SD-Card/32847443952.html


    Und nebenbei wächst ein landesweites kostenloses IoT Funknetz..

  • Han isch auch nüscht :juggle::juggle:


    Et tut was es soll- frei nach dem Motto den Zufall durch den Irrtum ersetzen und als Erfolg verkaufen :mrgreen:


    Hast du mal im Haustechnikforum nachgelesen ?


    Da gibt es auch Protokollzerleger

    7,28 kWp, 6000TL20, Ost mit 28 x ReneSola JC260M-24/Bb (02/2013)
    2,65 kWp, 2500TL21, West mit 10 x SolarWorld AG SW 265 mono (EU)
    6,48 kWp, SB5.0, W/NW mit 22 x SolarWorld AG SW 270 mono (EU)
    14,8 kWh Hoppecke Batterie mit SI 6H-11