Integration des Fronius Symo Wechselrichters in Smart Home Systeme
Photovoltaikanlagen spielen eine entscheidende Rolle im modernen Energiemanagement. Der Wechselrichter Fronius Symo bietet hervorragende Möglichkeiten zur Integration in eine Smart Home-Umgebung. Dank einer offenen, lokalen API ist die Datenextraktion unkompliziert und erfordert keine ständige Cloud-Anbindung. Dieser lokale Ansatz sorgt für hohe Zuverlässigkeit und schnelle Reaktionszeiten bei Automatisierungen.
Maßgeschneidertes PHP-Skript und Smartphone-Widget
Zur Überwachung des Status der PV-Anlage kann ein dediziertes PHP-Skript auf einem lokalen Server eingesetzt werden. Das Skript fragt den API-Endpunkt des Wechselrichters unter [http://192.168.XXX.XXX/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=1&DataCollection=CommonInverterData] ab. Die JSON-Antwort wird dekodiert, um die wichtigsten Kennzahlen zu extrahieren: die aktuelle Leistung (PAC) und die produzierte Tagesenergie (DAY_ENERGY).
Die Datenabfrage erfolgt periodisch, beispielsweise alle 5 Minuten, um die Informationen stets aktuell zu halten. Für Zeiten, in denen der Wechselrichter in den Standby-Modus wechselt (etwa nachts, wenn die Solarproduktion auf null sinkt und der Wert DAY_ENERGY als “null” oder “false” zurückgegeben wird), ist ein Fallback-Mechanismus implementiert. In solchen Fällen liest das Skript die zuletzt bekannten Werte aus einer lokalen 1.dat-Datei aus, um Anzeigefehler zu vermeiden.
Optisch bietet das Skript eine dynamische Hintergrundfarbe, die sich je nach aktuell generierter Leistung anpasst. Durch eine spezielle Gradienten-Funktion geht die Hintergrundfarbe basierend auf dem PAC-Wert stufenlos in verschiedene Farben über (beispielsweise von Weiß über Orange zu Rot). Diese minimalistische Webseite kann anschließend über die App “Widgetify” als praktisches und personalisiertes Widget direkt auf dem Startbildschirm eines Smartphones platziert werden:
<?php
// Adjust the IP Address
$x = json_decode(file_get_contents("http://192.168.XXX.XXX/"
."solar_api/v1/GetInverterRealtimeData.cgi?".
"Scope=Device&DeviceId=1&DataCollection=CommonInverterData"), false);
$fallback1 = "";
$fallback2 = "";
if(!isset($x->Body->Data->DAY_ENERGY->Value) ||
$x->Body->Data->DAY_ENERGY->Value === null ||
$x->Body->Data->DAY_ENERGY->Value === false) {
$y = explode("|", file_get_contents("./1.dat"));
$fallback1 = $y[0];
$fallback2 = $y[1];
}
else
{
file_put_contents("./1.dat",
$x->Body->Data->PAC->Value.$x->Body->Data->PAC->Unit.
"|".$x->Body->Data->DAY_ENERGY->Value.$x->Body->Data->DAY_ENERGY->Unit);
}
if(isset($_GET["x"])) {
exit($x->Body->Data->PAC->Value.$x->Body->Data->PAC->Unit.
$fallback1."|".$x->Body->Data->DAY_ENERGY->Value.
$x->Body->Data->DAY_ENERGY->Unit.$fallback2."|".
date("H:i:s").($fallback1 != "" ? " F" : ""));
}
function Gradient($HexFrom, $HexTo, $ColorSteps) {
// credit: Hailwood (stackoverflow)
$FromRGB['r'] = hexdec(substr($HexFrom, 0, 2));
$FromRGB['g'] = hexdec(substr($HexFrom, 2, 2));
$FromRGB['b'] = hexdec(substr($HexFrom, 4, 2));
$ToRGB['r'] = hexdec(substr($HexTo, 0, 2));
$ToRGB['g'] = hexdec(substr($HexTo, 2, 2));
$ToRGB['b'] = hexdec(substr($HexTo, 4, 2));
$StepRGB['r'] = ($FromRGB['r'] - $ToRGB['r']) / ($ColorSteps - 1);
$StepRGB['g'] = ($FromRGB['g'] - $ToRGB['g']) / ($ColorSteps - 1);
$StepRGB['b'] = ($FromRGB['b'] - $ToRGB['b']) / ($ColorSteps - 1);
$GradientColors = array();
for($i = 0; $i <= $ColorSteps; $i++) {
$RGB['r'] = floor($FromRGB['r'] - ($StepRGB['r'] * $i));
$RGB['g'] = floor($FromRGB['g'] - ($StepRGB['g'] * $i));
$RGB['b'] = floor($FromRGB['b'] - ($StepRGB['b'] * $i));
$HexRGB['r'] = sprintf('%02x', ($RGB['r']));
$HexRGB['g'] = sprintf('%02x', ($RGB['g']));
$HexRGB['b'] = sprintf('%02x', ($RGB['b']));
$GradientColors[] = implode(NULL, $HexRGB);
}
$GradientColors = array_filter($GradientColors, function($val){
return (strlen($val) == 6 ? true : false );
});
return $GradientColors;
}
function ColorFromGradient($n, $min, $max, $colors) {
$tablecolors = [];
$prevcolor = array_shift($colors);
foreach ($colors as $color) {
$tablecolors = array_merge($tablecolors, Gradient($prevcolor, $color, 10));
$prevcolor = $color;
}
$max = $max-$min;
$n-= $min;
if ($n > $max) $n = $max;
$ncolor = round(count($tablecolors)/$max * $n)-1;
return $tablecolors[$ncolor];
}
?><!DOCTYPE html><html>
<head><script>
function dR() {
setInterval(function(){
document.getElementById('f3').innerHTML += 'R...';
var xhr = new XMLHttpRequest();
xhr.open("GET", "./pvgirdcgi.php?x="+new Date(), true);
xhr.timeout = 5000;
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
document.getElementById('f1').innerHTML = xhr.responseText.split("|")[0];
document.getElementById('f2').innerHTML = xhr.responseText.split("|")[1];
document.getElementById('f3').innerHTML = xhr.responseText.split("|")[2];
}
}
xhr.onerror = function() {};
xhr.send();
}, 8000);
}
//setTimeout(function(){window.location.reload()},1000*20);
</script>
<style>
<?php
if(isset($gear) && $gear == true) {
?>
body{text-align:center;margin-top:50px;font-size:32px;}
<?php
}
?>
span {
text-shadow:
0 0 7px #fff,
0 0 10px #fff,
0 0 21px #fff,
0 0 42px #0fa,
0 0 82px #0fa,
0 0 92px #0fa,
0 0 102px #0fa,
0 0 151px #0fa;
font-family:Arial,Verdana;
}
</style>
</head><body <?php
if(isset($gear) && $gear == true)
{
?> onClick="document.querySelector('#pvx').style.display='block';"+
"document.querySelector('.loader').style.display='block';"+
"document.querySelector('#pvall').style.display='none';"+
"window.location.reload();"<?php
}
?>style="background:#<?php echo ColorFromGradient($x->Body->Data->PAC->Value,
0, 9000, ['FFFFFF', 'FFAA00', 'CC0000']); ?>">
<?php
if(isset($gear) && $gear == true) {
?>
<style>
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
/* Safari */
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style><div style="display:none;text-align:center;width:100%;
margin-left:-16px;margin-top:100px;" id="pvx">
<span style="text-align: center;width: 120px;display: inline-block;">
<span class="loader" style="display:none;"></span>
</span>
</div>
<?php
}
?>
<div style="<?php
if(@$gear != true)
{?>width:80px;<?php } ?>text-align:center;" id="pvall">
<span style="text-shadow: 1px 1px #ffffff;
font-family:Arial,Verdana;font-weight:bold;">PV</span><br /><br />
<span style="font-weight:bold;" id="f1"><?php echo $x->Body->Data->PAC->Value.
$x->Body->Data->PAC->Unit.$fallback1; ?></span><br />
<span style="" id="f2"><?php echo $x->Body->Data->DAY_ENERGY->Value.
$x->Body->Data->DAY_ENERGY->Unit.$fallback2; ?></span>
<br /><br />
<span style="" id="f3"><?php echo date("H:i:s").($fallback1 != "" ? " F" : ""); ?></span>
</div>
</body>
</html>Möglichkeiten mit Home Assistant
Genau dieser Fronius-API-Endpunkt ist auch für umfassendere Smart Home-Plattformen wie Home Assistant äußerst wertvoll. Durch die Konfiguration der nativen Fronius-Integration fragt Home Assistant kontinuierlich dieselben JSON-Daten ab.
Daraus ergeben sich folgende Einsatzmöglichkeiten:
- Energie-Dashboard: Die generierten Energiedaten speisen direkt das Home Assistant Energie-Dashboard, welches Langzeitstatistiken, Kostenberechnungen und die Netzunabhängigkeit visuell aufbereitet.
- Smarte Automatisierungen: Die Echtzeit-Leistungsdaten (
PAC) können als Auslöser (Trigger) für Automatisierungen dienen. So lassen sich beispielsweise eine Wärmepumpe, eine Klimaanlage oder ein Ladegerät für Elektroautos automatisch einschalten, sobald die Solarproduktion einen bestimmten Schwellenwert überschreitet, wodurch der Eigenverbrauch maximiert wird.
Zusammenfassung
Der Fronius Symo Wechselrichter stellt durch seine lokale API leicht zugängliche Echtzeitdaten bereit. Ob über ein eigens entwickeltes PHP-Skript in Kombination mit der Widgetify-App zur schnellen Kontrolle auf dem Smartphone oder durch eine umfassende Einbindung in Home Assistant für komplexe Automatisierungen – die Integration dieses Wechselrichters in ein Smart Home-Ökosystem macht die Überwachung und Optimierung der Solarenergienutzung enorm effizient.