This commit is contained in:
@@ -742,6 +742,15 @@
|
|||||||
"name": "EnergieflussAnzeigen",
|
"name": "EnergieflussAnzeigen",
|
||||||
"caption": "Energiefluss unter dem Manager anzeigen",
|
"caption": "Energiefluss unter dem Manager anzeigen",
|
||||||
"onChange": "IPS_RequestAction($id, 'FormEnergieflussAnzeigen', $EnergieflussAnzeigen);"
|
"onChange": "IPS_RequestAction($id, 'FormEnergieflussAnzeigen', $EnergieflussAnzeigen);"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Select",
|
||||||
|
"name": "EnergieflussLeistungseinheit",
|
||||||
|
"caption": "Leistungseinheit im Energiefluss",
|
||||||
|
"options": [
|
||||||
|
{"caption": "Watt (W)", "value": 0},
|
||||||
|
{"caption": "Kilowatt (kW)", "value": 1}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
$this->RegisterPropertyBoolean('EnergiediagrammeAnzeigen', false);
|
$this->RegisterPropertyBoolean('EnergiediagrammeAnzeigen', false);
|
||||||
$this->RegisterPropertyBoolean('FunFactsAnzeigen', false);
|
$this->RegisterPropertyBoolean('FunFactsAnzeigen', false);
|
||||||
$this->RegisterPropertyBoolean('EnergieflussAnzeigen', false);
|
$this->RegisterPropertyBoolean('EnergieflussAnzeigen', false);
|
||||||
|
$this->RegisterPropertyInteger('EnergieflussLeistungseinheit', 0);
|
||||||
|
|
||||||
$this->RegisterVariableBoolean('Aktiv', 'Aktiv', '~Switch', 10);
|
$this->RegisterVariableBoolean('Aktiv', 'Aktiv', '~Switch', 10);
|
||||||
$this->EnableAction('Aktiv');
|
$this->EnableAction('Aktiv');
|
||||||
@@ -431,6 +432,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
if ((int) $senderID === $this->ReadPropertyInteger('NetzleistungVariableID')
|
if ((int) $senderID === $this->ReadPropertyInteger('NetzleistungVariableID')
|
||||||
&& (int) $nachricht === self::VM_UPDATE
|
&& (int) $nachricht === self::VM_UPDATE
|
||||||
) {
|
) {
|
||||||
|
$this->aktualisiereEnergieflusswerte();
|
||||||
$this->regeln(false);
|
$this->regeln(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -613,6 +615,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
'Daten' => $daten,
|
'Daten' => $daten,
|
||||||
];
|
];
|
||||||
$this->WriteAttributeString('VerbraucherCache', json_encode($cache, JSON_THROW_ON_ERROR));
|
$this->WriteAttributeString('VerbraucherCache', json_encode($cache, JSON_THROW_ON_ERROR));
|
||||||
|
$this->aktualisiereEnergieflusswerte();
|
||||||
$this->regeln(false);
|
$this->regeln(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2121,6 +2124,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
if (is_int($funFactsID) && $funFactsID > 0 && IPS_VariableExists($funFactsID)) {
|
if (is_int($funFactsID) && $funFactsID > 0 && IPS_VariableExists($funFactsID)) {
|
||||||
$this->aktualisiereFunFacts($funFactsID);
|
$this->aktualisiereFunFacts($funFactsID);
|
||||||
}
|
}
|
||||||
|
$this->aktualisiereEnergieflusswerte();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function istNumerischeVariable(int $variableID): bool
|
private function istNumerischeVariable(int $variableID): bool
|
||||||
|
|||||||
@@ -256,12 +256,73 @@ trait ManagerEnergieTrait
|
|||||||
IPS_SetName($instanzID, 'Energiefluss');
|
IPS_SetName($instanzID, 'Energiefluss');
|
||||||
IPS_SetPosition($instanzID, 540);
|
IPS_SetPosition($instanzID, 540);
|
||||||
IPS_SetHidden($instanzID, false);
|
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 = [
|
$knoten = [
|
||||||
$this->energieflussKnoten('PVLeistungArchiv', 'PV-Anlage', 'solar'),
|
$this->energieflussKnoten($pvID, 'PV-Anlage', 'solar'),
|
||||||
$this->energieflussKnoten('NetzleistungArchiv', 'Stromnetz', 'grid'),
|
$this->energieflussKnoten($netzID, 'Stromnetz', 'grid'),
|
||||||
$this->energieflussKnoten('HausverbrauchLeistungArchiv', 'Hausverbrauch', 'consumer'),
|
$this->energieflussKnoten($hausID, 'Hausverbrauch', 'consumer'),
|
||||||
$this->energieflussKnoten('BatterieleistungArchiv', 'Batteriespeicher', 'battery'),
|
|
||||||
];
|
];
|
||||||
|
$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, 'Calculation', true);
|
||||||
IPS_SetProperty(
|
IPS_SetProperty(
|
||||||
$instanzID,
|
$instanzID,
|
||||||
@@ -271,26 +332,166 @@ trait ManagerEnergieTrait
|
|||||||
IPS_SetProperty($instanzID, 'EnableLimits', false);
|
IPS_SetProperty($instanzID, 'EnableLimits', false);
|
||||||
IPS_SetProperty($instanzID, 'Restrictions', '[]');
|
IPS_SetProperty($instanzID, 'Restrictions', '[]');
|
||||||
IPS_ApplyChanges($instanzID);
|
IPS_ApplyChanges($instanzID);
|
||||||
|
$this->aktualisiereEnergieflusswerte($verbraucher);
|
||||||
|
|
||||||
return 'Der Energiefluss wurde erstellt oder aktualisiert.';
|
return 'Der Energiefluss wurde erstellt oder aktualisiert.';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return array<string, mixed> */
|
/** @return array<string, mixed> */
|
||||||
private function energieflussKnoten(string $ident, string $name, string $typ): array
|
private function energieflussKnoten(
|
||||||
{
|
int $variableID,
|
||||||
|
string $name,
|
||||||
|
string $typ,
|
||||||
|
bool $gruppiert = false,
|
||||||
|
int $infoVariableID = 1
|
||||||
|
): array {
|
||||||
return [
|
return [
|
||||||
'VariableConfigType' => 0,
|
'VariableConfigType' => 0,
|
||||||
'VariableID' => $this->GetIDForIdent($ident),
|
'VariableID' => $variableID,
|
||||||
'SecondaryVariableID' => 1,
|
'SecondaryVariableID' => 1,
|
||||||
'Name' => $name,
|
'Name' => $name,
|
||||||
'Type' => $typ,
|
'Type' => $typ,
|
||||||
'Grouped' => false,
|
'Grouped' => $gruppiert,
|
||||||
'CalculationType' => 0,
|
'CalculationType' => 0,
|
||||||
'InfoVariableID' => 1,
|
'InfoVariableID' => $infoVariableID,
|
||||||
'Invert' => false,
|
'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<array{
|
||||||
|
* InstanzID: int,
|
||||||
|
* Name: string,
|
||||||
|
* Typ: string,
|
||||||
|
* Istleistung_W: float,
|
||||||
|
* Sollleistung_W: float
|
||||||
|
* }>
|
||||||
|
*/
|
||||||
|
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<array<string, mixed>>|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
|
private function erstelleEnergiediagramme(): string
|
||||||
{
|
{
|
||||||
$leistung = [
|
$leistung = [
|
||||||
|
|||||||
+32
-14
@@ -128,7 +128,8 @@ final class ManagerRegler
|
|||||||
}
|
}
|
||||||
|
|
||||||
$festwert = self::istFestwert($daten['Leistungswerte_W']);
|
$festwert = self::istFestwert($daten['Leistungswerte_W']);
|
||||||
if ($festwert) {
|
$festgehalten = !$daten['AenderungMoeglich'];
|
||||||
|
if ($festwert || $festgehalten) {
|
||||||
$nichtSteuerbar += $leistung;
|
$nichtSteuerbar += $leistung;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +145,8 @@ final class ManagerRegler
|
|||||||
'Energiegruppe' => (int) round((float) $energie / 2000.0),
|
'Energiegruppe' => (int) round((float) $energie / 2000.0),
|
||||||
'Leistungswerte_W' => $daten['Leistungswerte_W'],
|
'Leistungswerte_W' => $daten['Leistungswerte_W'],
|
||||||
'Festwert' => $festwert,
|
'Festwert' => $festwert,
|
||||||
|
'Festgehalten' => $festgehalten,
|
||||||
|
'Sollwert' => self::angenommenerSollwert($daten),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +163,7 @@ final class ManagerRegler
|
|||||||
});
|
});
|
||||||
|
|
||||||
$verteilbudget = (int) round($aktuelleLeistung + $zielnetzleistung - $netzleistung);
|
$verteilbudget = (int) round($aktuelleLeistung + $zielnetzleistung - $netzleistung);
|
||||||
|
$positiveRichtung = $verteilbudget - $nichtSteuerbar >= 0;
|
||||||
$sollwerte = [];
|
$sollwerte = [];
|
||||||
$ausgangssumme = 0;
|
$ausgangssumme = 0;
|
||||||
foreach ($steuerbar as $eintrag) {
|
foreach ($steuerbar as $eintrag) {
|
||||||
@@ -169,26 +173,41 @@ final class ManagerRegler
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ($eintrag['Festgehalten']) {
|
||||||
|
if ($eintrag['Sollwert'] !== null) {
|
||||||
|
$sollwerte[$eintrag['InstanzID']] = $eintrag['Sollwert'];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$ausgangswert = self::neutralerLeistungswert($eintrag['Leistungswerte_W']);
|
$ausgangswert = self::richtungsneutralerLeistungswert(
|
||||||
|
$eintrag['Leistungswerte_W'],
|
||||||
|
$positiveRichtung
|
||||||
|
);
|
||||||
$sollwerte[$eintrag['InstanzID']] = $ausgangswert;
|
$sollwerte[$eintrag['InstanzID']] = $ausgangswert;
|
||||||
$ausgangssumme += $ausgangswert;
|
$ausgangssumme += $ausgangswert;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rest = $verteilbudget - $nichtSteuerbar - $ausgangssumme;
|
$rest = $verteilbudget - $nichtSteuerbar - $ausgangssumme;
|
||||||
foreach ($steuerbar as $eintrag) {
|
foreach ($steuerbar as $eintrag) {
|
||||||
if ($eintrag['Festwert']) {
|
if ($eintrag['Festwert'] || $eintrag['Festgehalten']) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$instanzID = $eintrag['InstanzID'];
|
$instanzID = $eintrag['InstanzID'];
|
||||||
$ausgangswert = $sollwerte[$instanzID];
|
$ausgangswert = $sollwerte[$instanzID];
|
||||||
if ($rest >= 0) {
|
if ($positiveRichtung) {
|
||||||
|
if ($rest <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$neuerSollwert = self::groessterLeistungswertBis(
|
$neuerSollwert = self::groessterLeistungswertBis(
|
||||||
$eintrag['Leistungswerte_W'],
|
$eintrag['Leistungswerte_W'],
|
||||||
$ausgangswert + $rest
|
$ausgangswert + $rest
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
if ($rest >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$neuerSollwert = self::kleinsterLeistungswertAb(
|
$neuerSollwert = self::kleinsterLeistungswertAb(
|
||||||
$eintrag['Leistungswerte_W'],
|
$eintrag['Leistungswerte_W'],
|
||||||
$ausgangswert + $rest
|
$ausgangswert + $rest
|
||||||
@@ -200,7 +219,7 @@ final class ManagerRegler
|
|||||||
|
|
||||||
$zugeteilt = $nichtSteuerbar;
|
$zugeteilt = $nichtSteuerbar;
|
||||||
foreach ($steuerbar as $eintrag) {
|
foreach ($steuerbar as $eintrag) {
|
||||||
if (!$eintrag['Festwert']) {
|
if (!$eintrag['Festwert'] && !$eintrag['Festgehalten']) {
|
||||||
$zugeteilt += $sollwerte[$eintrag['InstanzID']];
|
$zugeteilt += $sollwerte[$eintrag['InstanzID']];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,8 +293,10 @@ final class ManagerRegler
|
|||||||
/**
|
/**
|
||||||
* @param list<int|array{Von_W: int, Bis_W: int}> $leistungswerte
|
* @param list<int|array{Von_W: int, Bis_W: int}> $leistungswerte
|
||||||
*/
|
*/
|
||||||
private static function neutralerLeistungswert(array $leistungswerte): int
|
private static function richtungsneutralerLeistungswert(
|
||||||
{
|
array $leistungswerte,
|
||||||
|
bool $positiveRichtung
|
||||||
|
): int {
|
||||||
$negativ = null;
|
$negativ = null;
|
||||||
$positiv = null;
|
$positiv = null;
|
||||||
foreach ($leistungswerte as $eintrag) {
|
foreach ($leistungswerte as $eintrag) {
|
||||||
@@ -298,14 +319,11 @@ final class ManagerRegler
|
|||||||
: $positiv;
|
: $positiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($negativ === null) {
|
if ($positiveRichtung) {
|
||||||
return $positiv;
|
return $positiv ?? $negativ;
|
||||||
}
|
|
||||||
if ($positiv === null) {
|
|
||||||
return $negativ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return abs($negativ) <= abs($positiv) ? $negativ : $positiv;
|
return $negativ ?? $positiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -361,6 +379,6 @@ final class ManagerRegler
|
|||||||
return max($eintrag['Von_W'], $untergrenze);
|
return max($eintrag['Von_W'], $untergrenze);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::neutralerLeistungswert($leistungswerte);
|
return self::richtungsneutralerLeistungswert($leistungswerte, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ final class ManagerEnergieModulstrukturTest extends TestCase
|
|||||||
"RegisterPropertyBoolean('EnergiediagrammeAnzeigen', false)",
|
"RegisterPropertyBoolean('EnergiediagrammeAnzeigen', false)",
|
||||||
"RegisterPropertyBoolean('FunFactsAnzeigen', false)",
|
"RegisterPropertyBoolean('FunFactsAnzeigen', false)",
|
||||||
"RegisterPropertyBoolean('EnergieflussAnzeigen', false)",
|
"RegisterPropertyBoolean('EnergieflussAnzeigen', false)",
|
||||||
|
"RegisterPropertyInteger('EnergieflussLeistungseinheit', 0)",
|
||||||
"RegisterPropertyInteger('LeistungsaufzeichnungMinuten', 1)",
|
"RegisterPropertyInteger('LeistungsaufzeichnungMinuten', 1)",
|
||||||
"RegisterPropertyInteger('LeistungLoeschenMonate', 12)",
|
"RegisterPropertyInteger('LeistungLoeschenMonate', 12)",
|
||||||
"RegisterPropertyInteger('EnergieaufzeichnungMinuten', 5)",
|
"RegisterPropertyInteger('EnergieaufzeichnungMinuten', 5)",
|
||||||
@@ -48,6 +49,7 @@ final class ManagerEnergieModulstrukturTest extends TestCase
|
|||||||
'FormEnergiediagrammeAnzeigen',
|
'FormEnergiediagrammeAnzeigen',
|
||||||
'FormFunFactsAnzeigen',
|
'FormFunFactsAnzeigen',
|
||||||
'FormEnergieflussAnzeigen',
|
'FormEnergieflussAnzeigen',
|
||||||
|
'EnergieflussLeistungseinheit',
|
||||||
'MesswerteAnzeigen',
|
'MesswerteAnzeigen',
|
||||||
'IstleistungVariableID',
|
'IstleistungVariableID',
|
||||||
'LeistungVariableID',
|
'LeistungVariableID',
|
||||||
|
|||||||
@@ -258,6 +258,67 @@ final class ManagerReglerTest extends TestCase
|
|||||||
self::assertSame(0, $ergebnis['Restabweichung_W']);
|
self::assertSame(0, $ergebnis['Restabweichung_W']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPvBetriebNutztBeiPositivemBudgetKeineNegativeLeistungsstufe(): void
|
||||||
|
{
|
||||||
|
$ergebnis = ManagerRegler::verteile(
|
||||||
|
0.0,
|
||||||
|
500.0,
|
||||||
|
[
|
||||||
|
$this->verbraucher(10, 0, [-1000, 5000], 0),
|
||||||
|
$this->verbraucher(20, 1, [0, 3000], 0),
|
||||||
|
],
|
||||||
|
'PrioritaetPV'
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertSame(500, $ergebnis['Verteilbudget_W']);
|
||||||
|
self::assertSame([10 => 5000, 20 => 0], $ergebnis['Sollwerte']);
|
||||||
|
self::assertGreaterThanOrEqual(0, $ergebnis['Sollwerte'][10]);
|
||||||
|
self::assertSame(-4500, $ergebnis['Restabweichung_W']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPvBetriebNutztNegativeLeistungErstBeiTatsaechlichemDefizit(): void
|
||||||
|
{
|
||||||
|
$ergebnis = ManagerRegler::verteile(
|
||||||
|
1000.0,
|
||||||
|
0.0,
|
||||||
|
[
|
||||||
|
$this->verbraucher(
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
[['Von_W' => -5000, 'Bis_W' => 5000]],
|
||||||
|
0
|
||||||
|
),
|
||||||
|
$this->verbraucher(20, 1, [0, 3000], 0),
|
||||||
|
],
|
||||||
|
'PrioritaetPV'
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertSame(-1000, $ergebnis['Verteilbudget_W']);
|
||||||
|
self::assertSame([10 => -1000, 20 => 0], $ergebnis['Sollwerte']);
|
||||||
|
self::assertSame(0, $ergebnis['Restabweichung_W']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFestgehaltenerVerbraucherBilanziertIstUndBehaeltSollwert(): void
|
||||||
|
{
|
||||||
|
$festgehalten = $this->verbraucher(10, 0, [0, 3000, 5000], 2000, false);
|
||||||
|
$festgehalten['Daten']['Zustand'][0]['Wert'] = 3000;
|
||||||
|
|
||||||
|
$ergebnis = ManagerRegler::verteile(
|
||||||
|
0.0,
|
||||||
|
3000.0,
|
||||||
|
[
|
||||||
|
$festgehalten,
|
||||||
|
$this->verbraucher(20, 1, [['Von_W' => 0, 'Bis_W' => 5000]], 0),
|
||||||
|
],
|
||||||
|
'PrioritaetPV'
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertSame(5000, $ergebnis['Verteilbudget_W']);
|
||||||
|
self::assertSame(2000, $ergebnis['NichtSteuerbar_W']);
|
||||||
|
self::assertSame([10 => 3000, 20 => 3000], $ergebnis['Sollwerte']);
|
||||||
|
self::assertSame(0, $ergebnis['Restabweichung_W']);
|
||||||
|
}
|
||||||
|
|
||||||
public function testFehlendeIstleistungFaelltAufAngenommenenSollwertZurueck(): void
|
public function testFehlendeIstleistungFaelltAufAngenommenenSollwertZurueck(): void
|
||||||
{
|
{
|
||||||
$verbraucher = $this->verbraucher(10, 0, [3000], null, false);
|
$verbraucher = $this->verbraucher(10, 0, [3000], null, false);
|
||||||
|
|||||||
@@ -268,6 +268,33 @@ return static function (TestContext $test): void {
|
|||||||
'{BA90FDB3-C203-8F26-B4D6-F3DB99905724}',
|
'{BA90FDB3-C203-8F26-B4D6-F3DB99905724}',
|
||||||
IPS_GetInstance($energieflussID)['ModuleInfo']['ModuleID']
|
IPS_GetInstance($energieflussID)['ModuleInfo']['ModuleID']
|
||||||
);
|
);
|
||||||
|
$knoten = json_decode(
|
||||||
|
(string) IPS_GetProperty($energieflussID, 'Config'),
|
||||||
|
true,
|
||||||
|
512,
|
||||||
|
JSON_THROW_ON_ERROR
|
||||||
|
);
|
||||||
|
$namen = array_column($knoten, 'Name');
|
||||||
|
foreach (['Verbraucher 1-Stufig', 'Wassererwärmer', 'Pufferspeicher'] as $name) {
|
||||||
|
$test->assertTrue(in_array($name, $namen, true));
|
||||||
|
}
|
||||||
|
foreach ($knoten as $knotenEintrag) {
|
||||||
|
if (in_array(
|
||||||
|
$knotenEintrag['Name'],
|
||||||
|
['Verbraucher 1-Stufig', 'Wassererwärmer', 'Pufferspeicher'],
|
||||||
|
true
|
||||||
|
)) {
|
||||||
|
$test->assertTrue((int) $knotenEintrag['InfoVariableID'] > 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$pvFlussID = $test->objectByIdent('EnergieflussPV', $managerId);
|
||||||
|
$test->assertSame(4200.0, (float) GetValue($pvFlussID));
|
||||||
|
$test->assertSame('~Power', IPS_GetVariable($pvFlussID)['VariableProfile']);
|
||||||
|
|
||||||
|
IPS_SetProperty($managerId, 'EnergieflussLeistungseinheit', 1);
|
||||||
|
IPS_ApplyChanges($managerId);
|
||||||
|
$test->assertSame(4.2, (float) GetValue($pvFlussID));
|
||||||
|
$test->assertSame('Enelix.Power.kW', IPS_GetVariable($pvFlussID)['VariableProfile']);
|
||||||
|
|
||||||
IPS_RequestAction($managerId, 'FormEnergieflussAnzeigen', false);
|
IPS_RequestAction($managerId, 'FormEnergieflussAnzeigen', false);
|
||||||
$test->assertSame(true, (bool) IPS_GetObject($energieflussID)['ObjectIsHidden']);
|
$test->assertSame(true, (bool) IPS_GetObject($energieflussID)['ObjectIsHidden']);
|
||||||
@@ -416,12 +443,10 @@ return static function (TestContext $test): void {
|
|||||||
|
|
||||||
SetValue($temperaturId, 53.0);
|
SetValue($temperaturId, 53.0);
|
||||||
$test->waitUntil(static function () use (
|
$test->waitUntil(static function () use (
|
||||||
$managerId,
|
|
||||||
$warmwasserId,
|
$warmwasserId,
|
||||||
$verbraucherstatus,
|
$verbraucherstatus,
|
||||||
$zustandswert
|
$zustandswert
|
||||||
): bool {
|
): bool {
|
||||||
IPS_RequestAction($managerId, 'Regeln', false);
|
|
||||||
$wert = $zustandswert(
|
$wert = $zustandswert(
|
||||||
$verbraucherstatus(),
|
$verbraucherstatus(),
|
||||||
$warmwasserId,
|
$warmwasserId,
|
||||||
|
|||||||
Reference in New Issue
Block a user