Hallo zusammen,
ich denke ich habe einen vielversprechenden Ansatz negative Werte bei der Leistung vom Zähler richtig zu dekodieren.
Ich will hier nicht nur Fragen stellen, sondern auch meine Erkenntnisse teilen. Deshalb findet ihr hier meinen Lösungsansatz:
In einer Doku von VDE war der Hinweis, die führenden ‚FF‘ einfach wegzulassen.
Zitat:
6…2…3… Datentypen Unsigned8, Unsigned16, Unsigned32 und Unsigned64
(125) Diese vorzeichenlosen Integer-Datentypen werden wie folgt kodiert, wobei in der
Datenübertragung jeweils ganze Bytes, die führende Nullen enthalten, weggelassen
werden dürfen:
Zitat Ende, Quelle http://www.vde.com/de/fnn/arbeitsgebiete/messwesen/Sym2/Infomaterial/Documents/SML_081112_103.pdf
Nur weglassen alleine brachte nicht die Lösung.
Ich denke man muss das die Zahlen als Zweierkomplement interpretieren. Jetzt macht auch Sinn für mich, warum man, wenn im Scaler FF steht, durch 10 dividieren muss um plausible Werte zu erhalten. FF ist im Zweierkomplement -1 , also ausgelesener Wert * 10 hoch -1 sprich dividiert durch 10.
Mal schauen, was die Leistungswerte bei Rücklieferung ins Netz morgen sagen, wenn die PV-Anlage wieder produziert!
Als nächstes werde ich den Eigenverbrauch berechnen, bzw. die augenblickliche verbrauchte Leistung im Haus, wenn ein Teil aus dem EVU-Netz kommt und ein Teil von meiner PV-Anlage. Wahrscheinlich muss ich da noch aufpassen, dass ich irgendwie die Zählerstände synchron abrufen kann, weil nur Werte die zur gleichen Zeit gemessen wurde auch wirklich miteinander verrechnet werden dürfen. Gab es da schon Ansätze von jemandem?
Viele Grüße
Alexander
PS: soweit mein überarbeitetes Script zum dekodieren und berechnen der Werte:
<?
function bin2si($bin,$bits=32)
{
if (strlen($bin)==$bits)
{
if (substr($bin,0,1) == 0) // positive or zero
{
$si = base_convert($bin,2,10);
}
else // negative
{
$si = base_convert($bin,2,10);
$si = -(pow(2,$bits)-$si);
}
return $si;
}
}
function read_value($obj_raw, $objName, $objLength, $obj_position,$integer_length)
{
$obj = str_split(substr(bin2hex($obj_raw),strpos(bin2hex($obj_raw),$objName)+16,$objLength),2);
//print_r($obj);
$result = '';
foreach($obj_position as $index) {
$result = $result . $obj[$index]; }
$scaler = base_convert($obj[5],16,2);
$scaler = str_repeat('0',8-strlen($scaler)) . $scaler;
$scaler = bin2si($scaler,8);
//echo 'S:' . $scaler;
$bin = base_convert($result,16,2);
$bin = str_repeat('0',$integer_length-strlen($bin)) . $bin;
//echo 'Binary:' . $bin;
return bin2si($bin,$integer_length)* pow(10,$scaler);
}
?>