SDM630 + EW11 ab und zu 0 Readings
Moderator: Ulrich
-
- Beiträge: 167
- Registriert: Mo 16. Jan 2023, 20:43
- Hat sich bedankt: 16 Mal
- Danksagung erhalten: 25 Mal
Re: SDM630 + EW11 ab und zu 0 Readings
Wie wärs, das Ganze auch als code zu posten?
Raspi 3B, Hybrid Must PV18-3024 VHM, Hoymiles HM-800 , Nachteinspeisung, Flex-BKW, AhoyDTU, Smart Meter DTSU666-H, DIY Akku 6,7 KWh, DalyBMS2MQTT, Victron2MQTT,Architektur, HomeMatic CCU. Autor: Solaranlage Do-It-Yourself
Re: SDM630 + EW11 ab und zu 0 Readings
Ja, du hast Recht, das wäre tatsächlich sinnvoll.
Hier also der Codeabschnitt aus der functionen.inc.php:
Hier also der Codeabschnitt aus der functionen.inc.php:
Code: Alles auswählen
/**************************************************************************
// SDM630
// $Input["DeviceID"]
// $Input["BefehlFunctionCode"]
// $Input["RegisterAddress"]
// $Input["RegisterCount"]
**************************************************************************/
function sdm_auslesen($USB, $Input, $Studer = false) {
stream_set_blocking($USB, false);
$address = "";
$BefehlBin = hex2bin($Input["DeviceID"].$Input["BefehlFunctionCode"].$Input["RegisterAddress"].$Input["RegisterCount"]);
$BefehlBin = $BefehlBin.$this->crc16($BefehlBin);
// Befehl in HEX!
// echo "** ".$Input["DeviceID"].$Input["BefehlFunctionCode"].$Input["RegisterAddress"].$Input["RegisterCount"]."\n";
for ($k = 1; $k < 5; $k++) {
$buffer = fgets($USB, 500);
$buffer = "";
fputs($USB, $BefehlBin);
usleep(50000); // 0,05 Sekunden warten
for ($i = 1; $i < 30; $i++) {
$buffer .= fgets($USB, 100);
usleep(10000);
$buffer .= fgets($USB, 100);
$this->log_schreiben("Lese Buffer - Schleifennummer: ".$i, " ", 10);
$this->log_schreiben("Ausgewerteter Bufferinhalt: ".bin2hex($buffer), " ", 10);
$this->log_schreiben("Laenge: ".strlen($buffer), " ", 10);
// echo $i." ".bin2hex($buffer)."\n";
if (substr(bin2hex($buffer), 0, 2) == "00" and substr(bin2hex($buffer), - 2) == "00") {
// Mit Start und Stop Bit '00'
/*************************************/
if (substr(bin2hex($buffer), 0, 6) == "000000") {
// Das ist ein Fehler! "00" ist am Anfang zu viel.
$hex = bin2hex($buffer);
$hex = substr($hex, 4);
}
elseif (substr(bin2hex($buffer), 0, 4) == "000OC0") {
// Das ist ein Fehler! "00" ist am Anfang zu viel.
$hex = bin2hex($buffer);
$hex = substr($hex, 2);
}
else {
$hex = bin2hex($buffer);
}
$start = substr($hex, 0, 2);
$address = substr($hex, 2, 2);
$functioncode = substr($hex, 4, 2);
$lenght = substr($hex, 6, 2);
$data = substr($hex, 8, $lenght * 2);
$stop = substr($hex, - 2);
break 2;
}
elseif (substr(bin2hex($buffer), 0, 2) == $Input["DeviceID"] and substr(bin2hex($buffer), 2, 2) == $Input["BefehlFunctionCode"]) {
// ohne Start und Stop Bit. Buffer faengt mit Device ID und FunctionCode an.
// Relevant fuer Elfin EW11 und SDM630/SDM230
$hex = bin2hex($buffer);
$lenght = hexdec(substr($hex, 4, 2));
$buffer = substr($buffer, 0, ($lenght + 5));
// Zu lange Bufferinhalte werden auf die richtige Laenge eingekuerzt
if (($lenght + 5) == strlen($buffer)) {
// Bufferinhalt richtige Laenge?
if (bin2hex($this->crc16(substr($buffer, 0, -2))) == bin2hex(substr($buffer, -2))) {
//CRC OK?
//Alles OK. Buffer auswerten.
/*************************************/
$hex = bin2hex($buffer);
$address = substr($hex, 0, 2);
$functioncode = substr($hex, 2, 2);
$lenght = hexdec(substr($hex, 4, 2));
$data = substr($hex, 6, $lenght * 2);
$this->log_schreiben("Abfrage: ".bin2hex($BefehlBin), " ", 8);
$this->log_schreiben("ReadHex: ".bin2hex($buffer), " ", 8);
break 2; //lesen iO, beide Schleifen verlassen
}
else {
//CRC Fehler!
$this->log_schreiben("Abfrage: ".bin2hex($BefehlBin), " ", 7);
$this->log_schreiben("ReadHex: ".bin2hex($buffer), " ", 7);
$this->log_schreiben("CRC: ".bin2hex($this->crc16(substr($buffer, 0, -2))), " ", 7);
$this->log_schreiben("CRC Fehler!", " ", 7);
usleep(50000); // 0,05 Sekunden warten fuer Wiederholung Abfrage
break; //lesen niO, Schleife verlassen und neue Abfrage
}
}
else {
//falsche Laenge!
$this->log_schreiben("Abfrage: ".bin2hex($BefehlBin), " ", 8);
$this->log_schreiben("ReadHex: ".bin2hex($buffer), " ", 8);
$this->log_schreiben("Falsche Laenge! ".strlen($buffer), " ", 8);
//lesen niO, kein Break, naechste Schleife versuchen
}
}
elseif (strlen($buffer) > 0) {
// Buffer Inhalt vorhanden, aber weder Startbit, noch Device ID passt
/*************************************/
break; //lesen niO, Schleife verlassen und neue Abfrage
}
}
}
/*************************
echo $hex."\n";
echo $start."\n";
echo $address."\n";
echo $functioncode."\n";
echo $lenght."\n";
echo $data."\n";
echo $stop."\n";
************************/
stream_set_blocking($USB, true);
if ($address == $Input["DeviceID"] and $functioncode == $Input["BefehlFunctionCode"]) {
if ($Studer) {
return $data;
}
else {
return round($this->hex2float($data), 3);
}
}
$this->log_schreiben("Fehler! ".bin2hex($buffer), " ", 5);
return false;
}