LW IT Solutions
« Blog Overview /Smart Home / Integration des Fronius Symo Wechselrichters in Smart...
This post in other languages:

Integration des Fronius Symo Wechselrichters in Smart Home Systeme

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>
Ablauf der Abfrage alle fünf Minuten von der lokalen API des Fronius Symo über das PHP-Skript, mit der Verzweigung bei vorhandenem DAY_ENERGY-Wert und dem Rückfall auf die Datei 1.dat sowie der Farbskala für den Hintergrund
Die API liefert, 1.dat erinnert — deshalb behält die Anzeige nachts ihre Form, statt einen Fehler zu zeigen.

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.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

2 Kommentare

  1. Renata Fiedler

    Der Hinweis, dass dieselbe Schnittstelle sowohl das eigene Skript als auch die Integration in Home Assistant bedient, hat mir die Entscheidung abgenommen — beides gleichzeitig, ohne Cloud.

    Beim Energie-Dashboard hakt es allerdings: Der Tagesertrag springt um Mitternacht zurück auf null, und die Statistik zeigt daraufhin einen negativen Sprung. Falsch eingerichtet?

    1. Lukas Wojcik Autor

      Nicht falsch, sondern die falsche Grösse für diese Stelle. Das Energie-Dashboard erwartet einen fortlaufenden Zähler, der nur steigt; der Tagesertrag ist ein Zähler, der sich jeden Tag zurücksetzt.

      Zwei Wege führen zum Ziel. Der bessere ist der Gesamtertrag, den der Wechselrichter ebenfalls liefert — er steigt monoton und ist genau das, was das Dashboard modelliert. Der zweite ist, den Tagesertrag ausdrücklich als zurücksetzenden Zähler zu kennzeichnen; Home Assistant kennt diesen Fall und rechnet den Sprung dann als Neubeginn statt als Verbrauch mit negativem Vorzeichen.

      Was in beiden Fällen bleibt, ist der nächtliche Ausfall der Schnittstelle. Ein Zähler, der zwischendurch nicht verfügbar ist, erzeugt keine falschen Werte — er erzeugt eine Lücke, und das Dashboard kommt damit zurecht. Ein Zähler, der stattdessen den letzten bekannten Wert wiederholt, erzeugt eine waagerechte Linie, die aussieht wie echte Messung. Deshalb gehört „keine Antwort“ als eigener Zustand geführt und nicht durch den letzten Wert ersetzt.

Kommentar schreiben

Die E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind mit einem Stern versehen.

ALL ARTICLES & CATEGORIES

CCTV

Diese Rubrik per RSS verfolgen

Cloud & AI

Diese Rubrik per RSS verfolgen

Data Privacy

Alle 12 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Digital Analytics

Alle 49 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Digital Marketing

Alle 29 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

IT & Networks

Alle 16 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Music Production

Diese Rubrik per RSS verfolgen

Raspberry Pi

Diese Rubrik per RSS verfolgen

Smart Home

Alle 18 Artikel dieser Rubrik Diese Rubrik per RSS verfolgen

Web Entwicklung

Diese Rubrik per RSS verfolgen

WordPress-Plugins & Tricks

Diese Rubrik per RSS verfolgen