LW IT Solutions
« Blog Overview /Smart Home / Integracja falownika Fronius Symo z systemami Smart...
This post in other languages:

Integracja falownika Fronius Symo z systemami Smart Home

Systemy fotowoltaiczne odgrywają kluczową rolę w nowoczesnym zarządzaniu energią. Falownik Fronius Symo oferuje doskonałe możliwości integracji ze środowiskiem Smart Home. Dzięki otwartemu, lokalnemu API pobieranie danych jest niezwykle proste i nie wymaga stałego dostępu do chmury producenta. Takie lokalne podejście gwarantuje wysoką niezawodność i szybki czas reakcji dla automatyzacji.

Autorski skrypt PHP i widżet na smartfonie

Do monitorowania statusu instalacji PV można wykorzystać dedykowany skrypt PHP uruchomiony na lokalnym serwerze. Skrypt ten odpytuje endpoint API falownika pod adresem [http://192.168.XXX.XXX/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=1&DataCollection=CommonInverterData]. Otrzymana odpowiedź w formacie JSON jest dekodowana w celu wyodrębnienia kluczowych parametrów: aktualnie generowanej mocy (PAC) oraz dziennego uzysku energii (DAY_ENERGY).

Odświeżanie danych odbywa się cyklicznie, na przykład co 5 minut, co pozwala na bieżące śledzenie produkcji. W przypadku, gdy falownik przechodzi w stan uśpienia (np. w nocy, gdy produkcja spada do zera, a wartość DAY_ENERGY zwraca błąd lub wartość pustą), zastosowano mechanizm awaryjny. Skrypt odczytuje wówczas ostatnie znane wartości z lokalnego pliku 1.dat, zapobiegając błędom wyświetlania.

Od strony wizualnej skrypt posiada dynamiczne tło, które zmienia kolor w zależności od aktualnie generowanej mocy. Dzięki specjalnej funkcji matematycznej generującej gradient, tło płynnie przechodzi między kolorami (np. od białego, przez pomarańczowy, aż po czerwony) na podstawie wartości PAC. Tak przygotowana strona, wyposażona w mechanizm autoodświeżania, może zostać użyta w aplikacji „Widgetify”, tworząc wygodny i spersonalizowany widżet bezpośrednio na ekranie głównym smartfona.

<?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>

Możliwości w systemie Home Assistant

Ten sam endpoint API Froniusa otwiera ogromne możliwości dla rozbudowanych platform Smart Home, takich jak Home Assistant. Po skonfigurowaniu natywnej integracji Fronius, Home Assistant nieustannie odpytuje dokładnie te same dane.

Daje to następujące możliwości:

  • Panel Energia (Energy Dashboard): Dane o wyprodukowanej energii zasilają wbudowany panel energetyczny, dostarczając długoterminowych statystyk, obliczeń opłacalności oraz poziomu niezależności od sieci energetycznej.
  • Inteligentne automatyzacje: Dane o mocy w czasie rzeczywistym (PAC) mogą służyć jako wyzwalacze (triggers). Na przykład bojler elektryczny, klimatyzator lub ładowarka do aut EV mogą włączać się automatycznie, gdy produkcja ze słońca przekroczy zadany próg, co maksymalizuje autokonsumpcję.

Podsumowanie

Falownik Fronius Symo udostępnia czytelne dane w czasie rzeczywistym za pośrednictwem lokalnego API. Zarówno w przypadku zastosowania autorskiego skryptu PHP połączonego z aplikacją Widgetify do szybkiego podglądu na telefonie, jak i przy wykorzystaniu potężnego systemu Home Assistant do zaawansowanych automatyzacji, integracja tego falownika czyni zarządzanie energią słoneczną procesem wysoce efektywnym.

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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

ALL ARTICLES & CATEGORIES

CCTV

Data Privacy

Digital Analytics

Digital Marketing

IT & Networks

Raspberry Pi

Smart Home

Tutorials

Tutorials

Tutorials

Tutorials

Tutorials

Tworzenie stron internetowych

Wordpress Hacks

Home Sitemap