Daten aus Webinterface BYD HV

Hallo zusammen,

besteht eigentlich die Möglichkeit, die Daten eines Webinterfaces in Symcon zu bekommen?

Ich habe einen Batteriespeicher BYD HV 7.7

wie aufwendig ist es ein Modul dafür zu entwickeln?
gibt es da irgendwo eine Art „Startanleitung“
oder hat jemand Lust mir Step by Step zu helfen?

Schau mal hier, vielleicht hilft es:
Read data from BYD energy storage using Python and TCP | by Robert Diers | Medium

Danke schön :+1:

Mein Plan ist es jetzt den Pyton Code in PHP zu konvertieren.
Das Skript welches dabei rauskommt, zyklisch in Symcon ausführen.

Ist es wirklich so einfach ?

ich habe nun folgendes Skript.

Wie muss ich nun das Skript erweitern, damit mir auch Variablen angelegt werden.

Ich bin noch nicht wirklich damit vertraut :relieved:

Wer nimmt mich an die Hand?

BYD PHP.txt (2,3 KB)

wie kann ich eigentlich ein Skript mit euch teilen, ohne einen Anhang?

Hi,
Scripte direkt in Post einbauen geht oben mit dem Icon </>.

Variable anlegen geht in etwa so:

$soc=1.2;
$ID = @IPS_GetObjectIDByName("SOC", $_IPS['SELF']);
if ($ID == false){
    $ID = IPS_CreateVariable(2);                        // Floatvariable anlegen
    IPS_SetPosition($ID, 10);                               // Variable positionieren
    IPS_SetName($ID, "SOC");                            // Variable benennen
    IPS_SetParent($ID, $_IPS['SELF']);             // Variable einsortieren unter dem Script
}
SetValue($ID, $soc);
1 „Gefällt mir“

vielen Dank :smiley:

Das wäre mein Skript
leider weiß ich jetzt nicht an welcher Stelle ich was ändern muss, damit Symcon mir die Variablen anlegt :relieved:

<?php

define("BUFFER_SIZE", 1024);
define("MESSAGE_1", "010300000066c5e0"); //read serial
define("MESSAGE_2", "01030500001984cc"); //read data

// Signed 16-bit integer conversion
function buf2int16SI($byteArray, $pos) {
    $result = $byteArray[$pos] * 256 + $byteArray[$pos + 1];
    if ($result > 32768) {
        $result -= 65536;
    }
    return $result;
}

// Unsigned 16-bit integer conversion
function buf2int16US($byteArray, $pos) {
    return $byteArray[$pos] * 256 + $byteArray[$pos + 1];
}

// Read data from BYD device
function read($byd_ip, $byd_port) {
    try {
        // Connect to BYD
        $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_connect($client, "192.168.178.34", 8080);

        // Message 2 (Sending command to read data)
        socket_write($client, hex2bin(MESSAGE_2));

        // Read data
        $data = socket_read($client, BUFFER_SIZE);

        // Parse data
        $data = unpack("C*", $data); // Unpack binary data to array
        $soc = buf2int16SI($data, 3);
        $maxvolt = buf2int16SI($data, 5) * 1.0 / 100.0;
        $minvolt = buf2int16SI($data, 7) * 1.0 / 100.0;
        $soh = buf2int16SI($data, 9);
        $ampere = buf2int16SI($data, 11) * 1.0 / 10.0;
        $battvolt = buf2int16US($data, 13) * 1.0 / 100.0;
        $maxtemp = buf2int16SI($data, 15);
        $mintemp = buf2int16SI($data, 17);
        $battemp = buf2int16SI($data, 19);
        $error = buf2int16SI($data, 29);
        $paramt = chr($data[31]) . "." . chr($data[32]);
        $outvolt = buf2int16US($data, 35) * 1.0 / 100.0;
        $power = round(($ampere * $outvolt) * 100 / 100, 2);
        $diffvolt = round(($maxvolt - $minvolt) * 100 / 100, 2);

        socket_close($client);

        return [
            "soc" => $soc,
            "maxvolt" => $maxvolt,
            "minvolt" => $minvolt,
            "soh" => $soh,
            "ampere" => $ampere,
            "battvolt" => $battvolt,
            "maxtemp" => $maxtemp,
            "mintemp" => $mintemp,
            "battemp" => $battemp,
            "error" => $error,
            "paramt" => $paramt,
            "outvolt" => $outvolt,
            "power" => $power,
            "diffvolt" => $diffvolt
        ];

    } catch (Exception $ex) {
        echo "ERROR BYD: " . $ex->getMessage();
    }
}

?>

hmmm, ich glaube irgendwas stimmt schon grundlegend nicht.
wie kann ich festellen, ob der Websocket fehlerfrei funktioniert

Schau doch mal im Debug ob da irgendwelche Daten kommen.
Variablen über ein Script anlegen würde ich zum Schluss machen oder händisch anlegen und dann zuordnen.

Welcher Websocket?
Du hast hier ein Script welches sich per TCP auf Port 8080 verbindet. Einen Websocket sehe ich da nicht.
Die Funktion read wird auch nie aufgerufen, somit passiert da nix.

Welchen Debug? Das ist doch nur ein PHP Script und keine Instanz.
Michael

ist TCP Socket richtiger?
Sorry ich bin da immer noch Anfänger :relieved:

Was schlägst du vor?

Vielleicht das Script so erweitern das es die read Funktion überhaupt aufruft?
Und die Rückgabe z.b. mit var_dump ausgeben?
Dann siehst du ja ob als Rückgabe das Array mit Werten rauskommt.
Michael

puh,
Da brauche ich Hilfe

wo, bzw wie muss ich var_dump eingeben

ich glaube ich bin etwas weiter gekommen, und komme zumindest schon einmal bis auf die Batterie!?

<?php

define('BUFFER_SIZE', 1024);
define('MESSAGE_1', "010300000066c5e0"); // read serial
define('MESSAGE_2', "01030500001984cc"); // read data

function buf2int16SI($byteArray, $pos) { // signed
    $result = $byteArray[$pos] * 256 + $byteArray[$pos + 1];
    if ($result > 32768) {
        $result -= 65536;
    }
    return $result;
}

function buf2int16US($byteArray, $pos) { // unsigned
    $result = $byteArray[$pos] * 256 + $byteArray[$pos + 1];
    return $result;
}

function read($byd_ip, $byd_port) {
    try {
        // Verbindung zum BYD
        $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($client === false) {
            throw new Exception('Fehler beim Erstellen des Sockets: ' . socket_strerror(socket_last_error()));
        }

        // Verbindung zum Zielport herstellen
        $result = socket_connect($client, "192.168.178.34", 23
        );
        if ($result === false) {
            throw new Exception('Fehler beim Verbinden: ' . socket_strerror(socket_last_error($client)));
        }

        // Nachricht 2 senden
        socket_write($client, hex2bin(MESSAGE_2));

        // Daten lesen
        $data = socket_read($client, BUFFER_SIZE);
        if ($data === false) {
            throw new Exception('Fehler beim Empfangen von Daten: ' . socket_strerror(socket_last_error($client)));
        }

        // Umwandlung der empfangenen Daten
        $dataArray = unpack("C*", $data); // Byte-Daten in ein Array umwandeln

        // Die Werte aus den empfangenen Daten extrahieren
        $soc = buf2int16SI($dataArray, 3);
        $maxvolt = buf2int16SI($dataArray, 5) * 1.0 / 100.0;
        $minvolt = buf2int16SI($dataArray, 7) * 1.0 / 100.0;
        $soh = buf2int16SI($dataArray, 9);
        $ampere = buf2int16SI($dataArray, 11) * 1.0 / 10.0;
        $battvolt = buf2int16US($dataArray, 13) * 1.0 / 100.0;
        $maxtemp = buf2int16SI($dataArray, 15);
        $mintemp = buf2int16SI($dataArray, 17);
        $battemp = buf2int16SI($dataArray, 19);
        $error = buf2int16SI($dataArray, 29);
        $paramt = chr($dataArray[31]) . "." . chr($dataArray[32]);
        $outvolt = buf2int16US($dataArray, 35) * 1.0 / 100.0;
        $power = round(($ampere * $outvolt) * 100 / 100, 2);
        $diffvolt = round(($maxvolt - $minvolt) * 100 / 100, 2);

        // Socket schließen
        socket_close($client);

        return [
            "soc" => $soc,
            "maxvolt" => $maxvolt,
            "minvolt" => $minvolt,
            "soh" => $soh,
            "ampere" => $ampere,
            "battvolt" => $battvolt,
            "maxtemp" => $maxtemp,
            "mintemp" => $mintemp,
            "battemp" => $battemp,
            "error" => $error,
            "paramt" => $paramt,
            "outvolt" => $outvolt,
            "power" => $power,
            "diffvolt" => $diffvolt,
        ];
      
    } catch (Exception $ex) {
        echo "ERROR BYD: " . $ex->getMessage();
    }
}

// Beispielaufruf der Funktion
$byd_ip = "192.168.178.34";  // IP-Adresse des BYD Geräts
$byd_port = 23;  // Port des BYD Geräts
$result = read($byd_ip, $byd_port);

print_r($result);


?>

das kam diesmal zurück

Ich wundere mich das Du überhaupt soweit kommst denn Du übergibst das $dataArray an buf2int16SI das möchte aber vermutlich eher den String $data haben denn Du spichst es ja mit dem Offset an. mach mal ein print_r hinter unpack um zu sehen was Du deiner Funktion da vorsetzt.

Ralf

kannst du mir das bitte genau markieren, wo ich das machen soll

und wie schon gesagt, das ursprüngliche Script ist ja in Pyton geschrieben worden.
Ich habe es durch ChatGPT übersetzen lassen.

Ich weiß nicht wie zuverlassig das ist.
gepaart mit meinem Halbwissen, bestimmt nicht die beste Combo :stuck_out_tongue_winking_eye:

Hi,
unpack wandelt den String ja schon in ein Array um und dann greift man z.B. mit $dataArray[‚SOC‘] oder so auf das Array zu. Ich würde mal

<?php

define('BUFFER_SIZE', 1024);
define('MESSAGE_1', "010300000066c5e0"); // read serial
define('MESSAGE_2', "01030500001984cc"); // read data

function buf2int16SI($byteArray, $pos) { // signed
    $result = $byteArray[$pos] * 256 + $byteArray[$pos + 1];
    if ($result > 32768) {
        $result -= 65536;
    }
    return $result;
}

function buf2int16US($byteArray, $pos) { // unsigned
    $result = $byteArray[$pos] * 256 + $byteArray[$pos + 1];
    return $result;
}

function read($byd_ip, $byd_port) {
    try {
        // Verbindung zum BYD
        $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($client === false) {
            throw new Exception('Fehler beim Erstellen des Sockets: ' . socket_strerror(socket_last_error()));
        }

        // Verbindung zum Zielport herstellen
        $result = socket_connect($client, "192.168.178.34", 23
        );
        if ($result === false) {
            throw new Exception('Fehler beim Verbinden: ' . socket_strerror(socket_last_error($client)));
        }

        // Nachricht 2 senden
        socket_write($client, hex2bin(MESSAGE_2));

        // Daten lesen
        $data = socket_read($client, BUFFER_SIZE);
        if ($data === false) {
            throw new Exception('Fehler beim Empfangen von Daten: ' . socket_strerror(socket_last_error($client)));
        }

        // Umwandlung der empfangenen Daten
        $dataArray = unpack("C*", $data); // Byte-Daten in ein Array umwandeln

        // Die Werte aus den empfangenen Daten extrahieren
        $soc = buf2int16SI($data, 3);
        $maxvolt = buf2int16SI($data, 5) * 1.0 / 100.0;
        $minvolt = buf2int16SI($data, 7) * 1.0 / 100.0;
        $soh = buf2int16SI($data, 9);
        $ampere = buf2int16SI($data, 11) * 1.0 / 10.0;
        $battvolt = buf2int16US($data, 13) * 1.0 / 100.0;
        $maxtemp = buf2int16SI($data, 15);
        $mintemp = buf2int16SI($data, 17);
        $battemp = buf2int16SI($data, 19);
        $error = buf2int16SI($data, 29);
        $paramt = chr($data[31]) . "." . chr($data[32]);
        $outvolt = buf2int16US($data, 35) * 1.0 / 100.0;
        $power = round(($ampere * $outvolt) * 100 / 100, 2);
        $diffvolt = round(($maxvolt - $minvolt) * 100 / 100, 2);

        // Socket schließen
        socket_close($client);

        return [
            "soc" => $soc,
            "maxvolt" => $maxvolt,
            "minvolt" => $minvolt,
            "soh" => $soh,
            "ampere" => $ampere,
            "battvolt" => $battvolt,
            "maxtemp" => $maxtemp,
            "mintemp" => $mintemp,
            "battemp" => $battemp,
            "error" => $error,
            "paramt" => $paramt,
            "outvolt" => $outvolt,
            "power" => $power,
            "diffvolt" => $diffvolt,
        ];
      
    } catch (Exception $ex) {
        echo "ERROR BYD: " . $ex->getMessage();
    }
}

// Beispielaufruf der Funktion
$byd_ip = "192.168.178.34";  // IP-Adresse des BYD Geräts
$byd_port = 23;  // Port des BYD Geräts
$result = read($byd_ip, $byd_port);

print_r($result);


?>

versuchen.

Ralf

Hi,
wirklich vielen Dank das du versuchst zu helfen. :+1:

das kommt jetzt zurück

Hi,

erstze mal

$dataArray = unpack("C*", $data);

durch

$dataArray = unpack("C*", $data);
print_r($dataArray);

mir ist aufgefallen das die Fehler bei deinem Script erst bei 17 anfangen. Vielleicht empfängst Du zu wenig.

Vielleicht hat das Geräte nach socket_write zu wenig Zeit alles zu schicken bis Du abholst da könnte dann eine kleine Pause mit sleep(1); helfen.

Ralf

habe ich gemacht,
jetzt kommt folgendes
Ich glaube gar nicht so schlecht :upside_down_face: