@riogrande75 OK, BMS ist an und CRC nach CRC16/XMODEM berechnet: ^D054BMS0531,090,1,0011,00,0,0554,0544,1200,0,0,0470,200012354
Der WR verweigert weiterhin diesen Befehl.
CRC wird im infinipoll10k_bms.php berechnet.
Hier die relevanten Teile des Codes:
$bmscmd = shmop_read($sh_bms, 0, 56); // lese BMS Kommando von readmqttbms.php aus sharememobj $bmscrc = paddings(genCRC($bmscmd),4); // generiere CRC $bmscrc1 = substr($bmscrc,-4,2); // erzeuge crc hi-byte $bmscrc2 = substr($bmscrc,-2); // erzeuge crc lo-byte // füge alles zusammen und schicke es zum WR fwrite($fp,$bmscmd.chr(hexdec($bmscrc1)).chr(hexdec($bmscrc2)).chr(0x0d)); // Hier noch die genCRC Funktion function genCRC (&$ptr) { $crc_table = array( 0x0, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0xa50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0xc60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0xe70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0xa1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x2b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x8e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0xaf1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0xcc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0xed1, 0x1ef0); $crc = 0x0000; for ($i = 0; $i < strlen($ptr); $i++) $crc = $crc_table[(($crc>>8) ^ ord($ptr[$i]))] ^ (($crc<<8) & 0x00FFFF); return dechex($crc); }
24kWP an 2x FSP 10kW,Solax X3-G2 und AxpertMAXII 8000 mit 70kWh LiFePo4
123solar, meterN und EVSE-WiFi
Kein Support per PN
@riogrande75 OK, Danke dir.
Die CRC habe ich hier berechnet crccalc.com.
Kannst du bitte mal nachvollziehen, ob ich diese richtig berechnet habe oder mir von dir eine "fertige" Befehlszeile zur Verfügung stellen?
@riogrande75 OK, Hi und Lo sind werden gedreht. Wie in deinem ersten Beitrag fügst du hier auch "od" hinzu. Mit "od" konnte ich bisher nichts anfangen.
Kann ich dies einfach in ASCI umwandeln und dem String anhängen oder erst nach dem ich den Buffer erstellt habe?
Ich nehme immer diese Seite für sowas: crc-calculation
Wenn ich dort folgenden String (aus Trace von meiner Anlage) hernehme, dann bekomme ich die korrekte CRC 0xEE04
^D054BMS0525,000,1,0008,00,0,0555,0555,1500,0,0,0464,150
Auf der Leitung sieht das dann so aus (Wireshark, weil ich mit IP2Serial Wandler arbeite):
Der String von dir müsste als CRC 0x3210 haben:
24kWP an 2x FSP 10kW,Solax X3-G2 und AxpertMAXII 8000 mit 70kWh LiFePo4
123solar, meterN und EVSE-WiFi
Kein Support per PN
@riogrande75 Dann mache ich wohl tatsächlich etwas bei der Berechnung meiner CRC falsch.
Mir ist allerdings noch aufgefallen, dass du im Bild oben für MaxDisChgCurr 3 Stellen verwendest und im Skript 4. Welches ist denn richtiger?
Das Bild stammt noch aus der Zeit, wo ich das reverse-engineert habe. Baue den String so, wie ich ihn im letzten Post schicke. Und Achtung: Die CRC ist kein String (ASCII) sondern muss in HEX geschickt werden (siehe Wireshark Bild).
24kWP an 2x FSP 10kW,Solax X3-G2 und AxpertMAXII 8000 mit 70kWh LiFePo4
123solar, meterN und EVSE-WiFi
Kein Support per PN
^D054BMS0531,090,1,0011,00,0,0554,0544,1200,0,0,0470,2000 => CRC (HEX) = 71FD
Für mich sieht der Buffer nun korrekt aus (hi / lo vertauscht).
Nach wie vor wird der Befehl nicht vom WR akzeptiert.
Sorry, wenn ich hier so dämlich nachfrage. Ich bin etwas verwirrt. In deinem Bild generierst du den CRC EE04 (ASCII). Dies ist so auch im Wireshark zu sehen. Hier ist auch Hi und Lo nicht vertauscht. Zumindest interpretiere ich das so. Wo habe ich den Denkfehler?
Danke für deine Geduld!
Schicke mal ohne die 2 Bytes der CRC zu vertauschen, so wie ich das mache.
Außerdem sollte der letzte Wert 200 sein und nicht 2000 wie bei dir.
24kWP an 2x FSP 10kW,Solax X3-G2 und AxpertMAXII 8000 mit 70kWh LiFePo4
123solar, meterN und EVSE-WiFi
Kein Support per PN
@riogrande75 Sorry für die Verzögerung, war im Urlaub.
Ich habe nun sämtliche Varianten versucht. Letzte Stelle 4 oder 3 stellig. Jeweils die entsprechenden CRC dazu. Egal ob Hi/Lo vertauscht oder nicht. Egal ob HEX oder ASCII. Der WR möchte das Kommando nicht akzeptieren.
Ich habe auch immer mal wieder mit ^P005BATS abgefragt. Gleiches Resultat: "^D0520000,000,0,0000,00,0,0000,0000,0000,0,0,0000,0000g=".
Vllt als Anhaltspunkt: Hierbei ist mir aufgefallen, dass die Abfrage am letzter Stelle scheinbar jedes Mal eine 4te Stelle anstelle 3. zurückgibt. Ist dies nicht relevant für die Übergabe an den WR?
Tja, dann würde ich vorschlagen du lässt mal meine Scripte auf deinen WR los (z.b. aus einer LinuxVM raus).
Dann siehst du, ob es an den Befehlen liegt oder am WR.
Welche FW hat dein WR drauf? Evtl. kann man mit dem Disassambler nachsehen, ob da in dieser FW etwas geändert wurde.
24kWP an 2x FSP 10kW,Solax X3-G2 und AxpertMAXII 8000 mit 70kWh LiFePo4
123solar, meterN und EVSE-WiFi
Kein Support per PN
@riogrande75 Hola die Waldfee, es funktioniert!!!
Hab den WR komplett stromlos gemacht und es funktioniert!!! 🙂
@riogrande75 vielen vielen Dank für deine Geduld <3
Lösung für meinen Fall:
Abgesetzter Befehl: D054BMS0531,090,1,0011,00,0,0554,0544,1200,0,0,0470,200 (Incjet node).
CRC16 XModem Berechnung via NodeRed (Funktion = 0D wird innerhalb der Funktion hinzugefügt):
// Algoritmo para lanzar los comandos hacia Voltronics por puerto serie con CRC propietario // Algoritmo realizado por Tejota solar@tejota.net var topic = (msg.payload) + (" ") + (msg.topic); // Topic con el comando string y posible descripcion var comandobuffer = Buffer.from(msg.payload); // pasando a buffer el string del comando var crc = 0x0000; // inicio del crc for (tj = 0; tj < comandobuffer.length; tj++) // scaneo del buffer { const byte = comandobuffer[tj]; // analizando el byte para aplicarle el crc16xmodem tejota = (crc >>> 8) & 0xff; tejota ^= byte & 0xff; tejota ^= tejota >>> 4; crc = (crc << 8) & 0xffff; // Algoritmo crc ^= tejota; // crc16 xmodem tejota = (tejota << 5) & 0xffff; // sin tabla estatica crc ^= tejota; tejota = (tejota << 7) & 0xffff; crc ^= tejota; } // resultante crc numerico var crchexastring = crc.toString(16).padStart(4,'0'); // crc numerico a string hexa añadiendo ceros a izquierda si es preciso var crchexabuffer = Buffer.from(crchexastring, "hex"); // buffer del crchexa for (mdk=0; mdk < crchexabuffer.length; mdk++) // scaneo del buffer { if (crchexabuffer[mdk]==10 || crchexabuffer[mdk]==13 || crchexabuffer[mdk]==40) // Exceptuando estos bytes mdk { crchexabuffer[mdk]++; // se pone el byte siguiente si es alguno de las excepciones mdk } } const retornodecarro = Buffer.from("\r"); var crctotalbuffer = [comandobuffer, crchexabuffer, retornodecarro]; // construyendo el buffer final hacia el hibrido msg.payload = Buffer.concat(crctotalbuffer); msg.topic = topic; return msg;