archivID(); if ($archivID === 0) { $this->protokolliere('Energiearchiv', 'Kein Archiv Control vorhanden.'); return; } $aktiv = $this->ReadPropertyBoolean('EnergieaufzeichnungAktiv'); $geaendert = []; $leistungstyp = $this->verdichtungstyp( $this->ReadPropertyInteger('LeistungsaufzeichnungMinuten') ); $energietyp = $this->verdichtungstyp( $this->ReadPropertyInteger('EnergieaufzeichnungMinuten') ); foreach (self::LEISTUNGS_VARIABLEN as $ident) { $variableID = $this->GetIDForIdent($ident); AC_SetLoggingStatus($archivID, $variableID, $aktiv); AC_SetAggregationType($archivID, $variableID, 0); AC_SetGraphStatus($archivID, $variableID, $aktiv); $regeln = [-1 => $leistungstyp]; $loeschen = $this->ReadPropertyInteger('LeistungLoeschenMonate'); if ($loeschen > 0) { $regeln[$loeschen] = 7; } if ($aktiv && $this->setzeVerdichtung($archivID, $variableID, $regeln)) { $geaendert[] = $variableID; } } foreach (self::ENERGIE_VARIABLEN as $ident) { $variableID = $this->GetIDForIdent($ident); AC_SetLoggingStatus($archivID, $variableID, $aktiv); AC_SetAggregationType($archivID, $variableID, 1); AC_SetGraphStatus($archivID, $variableID, $aktiv); $regeln = [-1 => $energietyp]; $verdichten = $this->ReadPropertyInteger('EnergieVerdichtenMonate'); if ($verdichten > 0) { $regeln[$verdichten] = 3; } $loeschen = $this->ReadPropertyInteger('EnergieLoeschenMonate'); if ($loeschen > 0) { $regeln[$loeschen] = 7; } if ($aktiv && $this->setzeVerdichtung($archivID, $variableID, $regeln)) { $geaendert[] = $variableID; } } IPS_ApplyChanges($archivID); foreach (array_unique($geaendert) as $variableID) { AC_ReAggregateVariable($archivID, $variableID); } } /** @param array $regeln */ private function setzeVerdichtung(int $archivID, int $variableID, array $regeln): bool { ksort($regeln); $aktuell = []; $eintraege = AC_GetCompaction($archivID, $variableID); if (is_array($eintraege)) { foreach ($eintraege as $eintrag) { $monat = (int) ($eintrag['MonthOffset'] ?? -999); $typ = (int) ($eintrag['CompactionType'] ?? -1); if ($monat >= -1 && $typ >= 0) { $aktuell[$monat] = $typ; } } } ksort($aktuell); if ($aktuell === $regeln) { return false; } foreach (array_keys($aktuell) as $monat) { AC_SetCompaction($archivID, $variableID, $monat, -1); } foreach ($regeln as $monat => $typ) { AC_SetCompaction($archivID, $variableID, $monat, $typ); } return true; } private function verdichtungstyp(int $minuten): int { return [1 => 0, 5 => 1, 60 => 2][$minuten] ?? 0; } private function archivID(): int { $archive = IPS_GetInstanceListByModuleID(self::ARCHIVE_MODULE_ID); return $archive === [] ? 0 : (int) $archive[0]; } private function synchronisiereEnergievisualisierungen(): void { $this->synchronisiereEnergyPie($this->ReadPropertyBoolean('EnergyPieAnzeigen')); $this->synchronisiereEnergiediagramme( $this->ReadPropertyBoolean('EnergiediagrammeAnzeigen') ); $this->synchronisiereFunFacts($this->ReadPropertyBoolean('FunFactsAnzeigen')); $this->synchronisiereEnergiefluss($this->ReadPropertyBoolean('EnergieflussAnzeigen')); } private function synchronisiereEnergyPie(bool $anzeigen): void { if ($anzeigen) { $this->erstelleEnergyPie(); return; } $this->entferneInstanzUnterobjekt('EnergyPie', self::ENERGY_PIE_MODULE_ID); } private function synchronisiereEnergiediagramme(bool $anzeigen): void { if ($anzeigen) { $this->erstelleEnergiediagramme(); return; } $this->entferneDiagrammUnterobjekt('Leistungsdiagramm'); $this->entferneDiagrammUnterobjekt('Energiediagramm'); } private function synchronisiereFunFacts(bool $anzeigen): void { if ($anzeigen) { $this->erstelleFunFacts(); return; } $variableID = $this->findeUnterobjekt('EnergieFunFacts'); if ($variableID === 0) { return; } if ((int) IPS_GetObject($variableID)['ObjectType'] !== 2) { throw new RuntimeException('Unterobjekt EnergieFunFacts ist keine Variable.'); } $this->UnregisterVariable('EnergieFunFacts'); } private function synchronisiereEnergiefluss(bool $anzeigen): void { if ($anzeigen) { $this->erstelleEnergiefluss(); return; } $instanzID = $this->findeUnterobjekt('Energiefluss'); if ($instanzID === 0) { return; } $objekt = IPS_GetObject($instanzID); $modulID = $objekt['ObjectType'] === 1 ? (string) IPS_GetInstance($instanzID)['ModuleInfo']['ModuleID'] : ''; if ($modulID !== self::ENERGY_FLOW_MODULE_ID) { throw new RuntimeException('Unterobjekt Energiefluss hat einen unpassenden Typ.'); } IPS_SetHidden($instanzID, true); } private function entferneInstanzUnterobjekt(string $ident, string $modulID): void { $instanzID = $this->findeUnterobjekt($ident); if ($instanzID === 0) { return; } $objekt = IPS_GetObject($instanzID); $istModulID = $objekt['ObjectType'] === 1 ? (string) IPS_GetInstance($instanzID)['ModuleInfo']['ModuleID'] : ''; if ($istModulID !== $modulID) { throw new RuntimeException('Unterobjekt ' . $ident . ' hat einen unpassenden Typ.'); } IPS_DeleteInstance($instanzID); } private function entferneDiagrammUnterobjekt(string $ident): void { $medienID = $this->findeUnterobjekt($ident); if ($medienID === 0) { return; } $objekt = IPS_GetObject($medienID); if ($objekt['ObjectType'] !== 5 || (int) IPS_GetMedia($medienID)['MediaType'] !== 4) { throw new RuntimeException('Unterobjekt ' . $ident . ' ist kein Diagramm.'); } IPS_DeleteMedia($medienID, true); } private function erstelleEnergyPie(): string { if (!in_array(self::ENERGY_PIE_MODULE_ID, IPS_GetModuleList(), true)) { throw new RuntimeException( 'Das Modul Energy Pie aus Enelix Utils ist nicht installiert.' ); } $instanzID = $this->findeUnterobjekt('EnergyPie'); if ($instanzID === 0) { $instanzID = IPS_CreateInstance(self::ENERGY_PIE_MODULE_ID); IPS_SetParent($instanzID, $this->InstanceID); IPS_SetIdent($instanzID, 'EnergyPie'); } else { $objekt = IPS_GetObject($instanzID); $modulID = $objekt['ObjectType'] === 1 ? (string) IPS_GetInstance($instanzID)['ModuleInfo']['ModuleID'] : ''; if ($modulID !== self::ENERGY_PIE_MODULE_ID) { throw new RuntimeException('Unterobjekt EnergyPie hat einen unpassenden Typ.'); } } IPS_SetName($instanzID, 'Energy Pie'); IPS_SetPosition($instanzID, 500); IPS_SetHidden($instanzID, false); foreach ([ 'ProduktionZaehlerID' => $this->GetIDForIdent('PVEnergie'), 'EinspeisungZaehlerID' => $this->GetIDForIdent('EinspeisungEnergie'), 'NetzbezugZaehlerID' => $this->GetIDForIdent('NetzbezugEnergie'), 'VerbrauchZaehlerID' => $this->GetIDForIdent('Hausenergie'), 'Zaehlerfaktor' => 1.0, ] as $property => $wert) { IPS_SetProperty($instanzID, $property, $wert); } IPS_ApplyChanges($instanzID); return 'Energy Pie wurde erstellt oder aktualisiert.'; } private function erstelleEnergiefluss(): string { if (!in_array(self::ENERGY_FLOW_MODULE_ID, IPS_GetModuleList(), true)) { throw new RuntimeException('Das Symcon-Modul Energy Distribution ist nicht installiert.'); } $instanzID = $this->findeUnterobjekt('Energiefluss'); if ($instanzID === 0) { $instanzID = IPS_CreateInstance(self::ENERGY_FLOW_MODULE_ID); IPS_SetParent($instanzID, $this->InstanceID); IPS_SetIdent($instanzID, 'Energiefluss'); } else { $objekt = IPS_GetObject($instanzID); $modulID = $objekt['ObjectType'] === 1 ? (string) IPS_GetInstance($instanzID)['ModuleInfo']['ModuleID'] : ''; if ($modulID !== self::ENERGY_FLOW_MODULE_ID) { throw new RuntimeException('Unterobjekt Energiefluss hat einen unpassenden Typ.'); } } IPS_SetName($instanzID, 'Energiefluss'); IPS_SetPosition($instanzID, 540); IPS_SetHidden($instanzID, false); $profil = $this->energieflussLeistungsprofil(); $pvID = $this->energieflussLeistungsvariable( 'EnergieflussPV', 'Energiefluss PV', $profil, 600 ); $netzID = $this->energieflussLeistungsvariable( 'EnergieflussNetz', 'Energiefluss Netz', $profil, 610 ); $hausID = $this->energieflussLeistungsvariable( 'EnergieflussHaus', 'Energiefluss Hausverbrauch', $profil, 620 ); $batterieID = $this->energieflussLeistungsvariable( 'EnergieflussBatterie', 'Energiefluss Batteriespeicher', $profil, 630 ); $verbraucher = $this->energieflussVerbraucher(); $knoten = [ $this->energieflussKnoten($pvID, 'PV-Anlage', 'solar'), $this->energieflussKnoten($netzID, 'Stromnetz', 'grid'), $this->energieflussKnoten($hausID, 'Hausverbrauch', 'consumer'), ]; $hatBatterieverbraucher = false; $position = 640; foreach ($verbraucher as $eintrag) { $istID = $this->energieflussLeistungsvariable( 'EnergieflussIst_' . $eintrag['InstanzID'], $eintrag['Name'] . ' Istleistung', $profil, $position ); $sollID = $this->energieflussLeistungsvariable( 'EnergieflussSoll_' . $eintrag['InstanzID'], $eintrag['Name'] . ' Sollleistung', $profil, $position + 1 ); $knoten[] = $this->energieflussKnoten( $istID, $eintrag['Name'], $eintrag['Typ'], true, $sollID ); $hatBatterieverbraucher = $hatBatterieverbraucher || $eintrag['Typ'] === 'storage'; $position += 10; } if (!$hatBatterieverbraucher) { $knoten[] = $this->energieflussKnoten( $batterieID, 'Batteriespeicher', 'storage' ); } IPS_SetProperty($instanzID, 'Calculation', true); IPS_SetProperty( $instanzID, 'Config', json_encode($knoten, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES) ); IPS_SetProperty($instanzID, 'EnableLimits', false); IPS_SetProperty($instanzID, 'Restrictions', '[]'); IPS_ApplyChanges($instanzID); $this->aktualisiereEnergieflusswerte($verbraucher); return 'Der Energiefluss wurde erstellt oder aktualisiert.'; } /** @return array */ private function energieflussKnoten( int $variableID, string $name, string $typ, bool $gruppiert = false, int $infoVariableID = 1 ): array { return [ 'VariableConfigType' => 0, 'VariableID' => $variableID, 'SecondaryVariableID' => 1, 'Name' => $name, 'Type' => $typ, 'Grouped' => $gruppiert, 'CalculationType' => 0, 'InfoVariableID' => $infoVariableID, 'Invert' => false, ]; } private function energieflussLeistungsprofil(): string { if ($this->ReadPropertyInteger('EnergieflussLeistungseinheit') !== 1) { return '~Power'; } $profil = 'Enelix.Power.kW'; if (!IPS_VariableProfileExists($profil)) { IPS_CreateVariableProfile($profil, 2); IPS_SetVariableProfileValues($profil, -1000000.0, 1000000.0, 0.001); IPS_SetVariableProfileDigits($profil, 3); IPS_SetVariableProfileText($profil, '', ' kW'); } return $profil; } private function energieflussLeistungsvariable( string $ident, string $name, string $profil, int $position ): int { $this->RegisterVariableFloat($ident, $name, $profil, $position); $variableID = $this->GetIDForIdent($ident); IPS_SetHidden($variableID, true); return $variableID; } /** * @return list */ private function energieflussVerbraucher(): array { $cache = $this->leseJsonAttribut('VerbraucherCache'); $ergebnis = []; foreach ($this->konfigurierteAktiveVerbraucherIDs() as $instanzID) { if (!IPS_InstanceExists($instanzID)) { continue; } $daten = $cache[(string) $instanzID]['Daten'] ?? null; $istleistung = 0.0; $sollleistung = 0.0; if (is_array($daten)) { $istleistung = $this->verbraucherleistung($daten); $sollleistung = (float) (ManagerRegler::angenommenerSollwert($daten) ?? 0); } $modulID = strtoupper( (string) IPS_GetInstance($instanzID)['ModuleInfo']['ModuleID'] ); $katalog = self::VERBRAUCHER_LIZENZEN[$modulID]['Katalog'] ?? ''; $ergebnis[] = [ 'InstanzID' => $instanzID, 'Name' => IPS_GetName($instanzID), 'Typ' => match ($katalog) { 'battery' => 'storage', 'ev_charger' => 'wallbox', default => 'consumer', }, 'Istleistung_W' => $istleistung, 'Sollleistung_W' => $sollleistung, ]; } return $ergebnis; } /** * @param list>|null $verbraucher */ private function aktualisiereEnergieflusswerte(?array $verbraucher = null): void { if (!$this->ReadPropertyBoolean('EnergieflussAnzeigen')) { return; } $verbraucher = $verbraucher ?? $this->energieflussVerbraucher(); $verbraucherleistung = 0.0; $hatBatterieverbraucher = false; foreach ($verbraucher as $eintrag) { $this->setzeEnergieflussLeistungswert( 'EnergieflussIst_' . $eintrag['InstanzID'], (float) $eintrag['Istleistung_W'] ); $this->setzeEnergieflussLeistungswert( 'EnergieflussSoll_' . $eintrag['InstanzID'], (float) $eintrag['Sollleistung_W'] ); if ($eintrag['Typ'] === 'storage') { $hatBatterieverbraucher = true; } else { $verbraucherleistung += max(0.0, (float) $eintrag['Istleistung_W']); } } try { $leistungen = $this->leseMessleistungen(); } catch (Throwable $fehler) { $this->protokolliere('Energiefluss', $fehler->getMessage()); return; } $this->setzeEnergieflussLeistungswert('EnergieflussPV', $leistungen['PV']); $this->setzeEnergieflussLeistungswert('EnergieflussNetz', $leistungen['Netz']); $this->setzeEnergieflussLeistungswert( 'EnergieflussHaus', max(0.0, $leistungen['Haus'] - $verbraucherleistung) ); if (!$hatBatterieverbraucher) { $this->setzeEnergieflussLeistungswert( 'EnergieflussBatterie', $leistungen['Batterie'] ); } } private function setzeEnergieflussLeistungswert(string $ident, float $watt): void { $variableID = @IPS_GetObjectIDByIdent($ident, $this->InstanceID); if (!is_int($variableID) || $variableID <= 0 || !IPS_VariableExists($variableID)) { return; } $faktor = $this->ReadPropertyInteger('EnergieflussLeistungseinheit') === 1 ? 0.001 : 1.0; SetValue($variableID, $watt * $faktor); } private function erstelleEnergiediagramme(): string { $leistung = [ $this->chartDatensatz('PVLeistungArchiv', 'PV', '#F4C542', '~Power'), $this->chartDatensatz('HausverbrauchLeistungArchiv', 'Haus', '#22A06B', '~Power'), $this->chartDatensatz('NetzleistungArchiv', 'Netz', '#E95D5D', '~Power'), $this->chartDatensatz('BatterieleistungArchiv', 'Batterie', '#8B5CF6', '~Power'), ]; $energie = [ $this->chartDatensatz('PVEnergie', 'PV', '#F4C542', '~Electricity'), $this->chartDatensatz('Hausenergie', 'Haus', '#22A06B', '~Electricity'), $this->chartDatensatz('NetzbezugEnergie', 'Netzbezug', '#E95D5D', '~Electricity'), $this->chartDatensatz('EinspeisungEnergie', 'Einspeisung', '#2F80ED', '~Electricity'), $this->chartDatensatz('BatterieLadenEnergie', 'Batterie laden', '#8B5CF6', '~Electricity'), $this->chartDatensatz('BatterieEntladenEnergie', 'Batterie entladen', '#F59E0B', '~Electricity'), ]; $this->erstelleDiagramm('Leistungsdiagramm', 'Leistungen', $leistung, 510); $this->erstelleDiagramm('Energiediagramm', 'Energien', $energie, 520); return 'Die Diagramme Leistungen und Energien wurden erstellt oder aktualisiert.'; } /** @param list> $datensaetze */ private function erstelleDiagramm( string $ident, string $name, array $datensaetze, int $position ): int { $medienID = $this->findeUnterobjekt($ident); if ($medienID === 0) { $medienID = IPS_CreateMedia(4); IPS_SetParent($medienID, $this->InstanceID); IPS_SetIdent($medienID, $ident); } $objekt = IPS_GetObject($medienID); if ($objekt['ObjectType'] !== 5 || (int) IPS_GetMedia($medienID)['MediaType'] !== 4) { throw new RuntimeException('Unterobjekt ' . $ident . ' ist kein Diagramm.'); } IPS_SetName($medienID, $name); IPS_SetPosition($medienID, $position); IPS_SetHidden($medienID, false); IPS_SetMediaFile($medienID, 'media/' . $medienID . '.chart', false); IPS_SetMediaContent( $medienID, base64_encode(json_encode(['datasets' => $datensaetze], JSON_THROW_ON_ERROR)) ); return $medienID; } /** @return array */ private function chartDatensatz( string $ident, string $titel, string $farbe, string $profil ): array { return [ 'variableID' => $this->GetIDForIdent($ident), 'fillColor' => 'clear', 'strokeColor' => $farbe, 'timeOffset' => 0, 'visible' => true, 'title' => $titel, 'type' => 'line', 'side' => 'left', 'profile' => $profil, ]; } private function findeUnterobjekt(string $ident): int { $objektID = @IPS_GetObjectIDByIdent($ident, $this->InstanceID); return is_int($objektID) && $objektID > 0 ? $objektID : 0; } private function erstelleFunFacts(): string { $this->RegisterVariableString('EnergieFunFacts', 'Energy Facts', '~HTMLBox', 530); $variableID = $this->GetIDForIdent('EnergieFunFacts'); IPS_SetHidden($variableID, false); $this->aktualisiereFunFacts($variableID); return 'Energy Facts wurden erstellt oder aktualisiert.'; } private function aktualisiereFunFacts(int $variableID): void { $archivID = $this->archivID(); if ($archivID === 0) { SetValue($variableID, '
Archiv nicht verfuegbar.
'); return; } $heute = strtotime('today'); $jahr = mktime(0, 0, 0, 1, 1, (int) date('Y')); $jetzt = time(); $pvID = $this->GetIDForIdent('PVEnergie'); $hausID = $this->GetIDForIdent('Hausenergie'); $bezugID = $this->GetIDForIdent('NetzbezugEnergie'); $exportID = $this->GetIDForIdent('EinspeisungEnergie'); $pvHeute = $this->energieSumme($archivID, $pvID, $heute, $jetzt); $pvJahr = $this->energieSumme($archivID, $pvID, $jahr, $jetzt); $pvTotal = max(0.0, (float) GetValue($pvID)); [$besterTag, $besterTagZeit] = $this->maximalerTageswert($archivID, $pvID); [$maxPV, $maxPVZeit] = $this->maximaleLeistung( $archivID, $this->GetIDForIdent('PVLeistungArchiv') ); [$maxHausTag, $maxHausTagZeit] = $this->maximalerTageswert($archivID, $hausID); [$maxHaus, $maxHausZeit] = $this->maximaleLeistung( $archivID, $this->GetIDForIdent('HausverbrauchLeistungArchiv') ); [$maxBezug, $maxBezugZeit] = $this->maximalerTageswert($archivID, $bezugID); [$maxExport, $maxExportZeit] = $this->maximalerTageswert($archivID, $exportID); $werte = [ '{{PV_HEUTE}}' => $this->formatiereEnergie($pvHeute), '{{PV_JAHR}}' => $this->formatiereEnergie($pvJahr), '{{PV_TOTAL}}' => $this->formatiereEnergie($pvTotal), '{{BESTER_TAG}}' => $this->formatiereEnergie($besterTag), '{{BESTER_TAG_DATUM}}' => $this->formatiereDatum($besterTagZeit), '{{MAX_PV}}' => $this->formatiereLeistung($maxPV), '{{MAX_PV_DATUM}}' => $this->formatiereDatum($maxPVZeit), '{{MAX_HAUS_TAG}}' => $this->formatiereEnergie($maxHausTag), '{{MAX_HAUS_TAG_DATUM}}' => $this->formatiereDatum($maxHausTagZeit), '{{MAX_HAUS}}' => $this->formatiereLeistung($maxHaus), '{{MAX_HAUS_DATUM}}' => $this->formatiereDatum($maxHausZeit), '{{MAX_BEZUG}}' => $this->formatiereEnergie($maxBezug), '{{MAX_BEZUG_DATUM}}' => $this->formatiereDatum($maxBezugZeit), '{{MAX_EXPORT}}' => $this->formatiereEnergie($maxExport), '{{MAX_EXPORT_DATUM}}' => $this->formatiereDatum($maxExportZeit), '{{HEIZOEL}}' => number_format($pvTotal / 10.0, 0, ',', "'") . ' Liter', '{{FLUGKM}}' => number_format($pvTotal * 2.4, 0, ',', "'") . ' km', ]; SetValue($variableID, strtr($this->funFactsHtml(), $werte)); } private function energieSumme(int $archivID, int $variableID, int $start, int $ende): float { $werte = @AC_GetAggregatedValues($archivID, $variableID, 1, $start, $ende, 0); if (!is_array($werte)) { return 0.0; } return array_sum(array_map( static fn (array $wert): float => max(0.0, (float) ($wert['Avg'] ?? 0.0)), $werte )); } /** @return array{0: float, 1: int} */ private function maximalerTageswert(int $archivID, int $variableID): array { $werte = @AC_GetAggregatedValues($archivID, $variableID, 1, 0, time(), 0); $maximum = 0.0; $zeit = 0; if (is_array($werte)) { foreach ($werte as $wert) { $kandidat = max(0.0, (float) ($wert['Avg'] ?? 0.0)); if ($kandidat > $maximum) { $maximum = $kandidat; $zeit = (int) ($wert['TimeStamp'] ?? 0); } } } return [$maximum, $zeit]; } /** @return array{0: float, 1: int} */ private function maximaleLeistung(int $archivID, int $variableID): array { $werte = @AC_GetAggregatedValues($archivID, $variableID, 1, 0, time(), 0); $maximum = 0.0; $zeit = 0; if (is_array($werte)) { foreach ($werte as $wert) { $kandidat = max(0.0, (float) ($wert['Max'] ?? 0.0)); if ($kandidat > $maximum) { $maximum = $kandidat; $zeit = (int) ($wert['MaxTime'] ?? $wert['TimeStamp'] ?? 0); } } } return [$maximum, $zeit]; } private function formatiereEnergie(float $wert): string { if ($wert >= 1000.0) { return number_format($wert / 1000.0, 2, ',', "'") . ' MWh'; } return number_format($wert, 1, ',', "'") . ' kWh'; } private function formatiereLeistung(float $wert): string { if ($wert >= 10000.0) { return number_format($wert / 1000.0, 1, ',', "'") . ' kW'; } return number_format($wert, 0, ',', "'") . ' W'; } private function formatiereDatum(int $zeit): string { return $zeit > 0 ? date('d.m.Y', $zeit) : 'Noch keine Daten'; } private function funFactsHtml(): string { return <<<'HTML'
SolarERZEUGUNG
Heute{{PV_HEUTE}}
Dieses Jahr{{PV_JAHR}}
Total{{PV_TOTAL}}
Bester Tag{{BESTER_TAG}}{{BESTER_TAG_DATUM}}
Max. Leistung{{MAX_PV}}{{MAX_PV_DATUM}}
Netz & HausSPITZENWERTE
Max. Tagesverbrauch{{MAX_HAUS_TAG}}{{MAX_HAUS_TAG_DATUM}}
Max. Hauslast{{MAX_HAUS}}{{MAX_HAUS_DATUM}}
Max. Tagesbezug{{MAX_BEZUG}}{{MAX_BEZUG_DATUM}}
Max. Einspeisung{{MAX_EXPORT}}{{MAX_EXPORT_DATUM}}
WirkungVERGLEICHE
{{HEIZOEL}}
rechnerisch kompensiertes Heizoel
{{FLUGKM}}
rechnerisch kompensierte Flugkilometer
Vergleichswerte auf Basis von 10 kWh pro Liter Heizoel und 2,4 Flugkilometern pro erzeugter kWh.
HTML; } }