Diagnosevariablen bedarfsgesteuert anlegen
Tests / test (push) Successful in 43s

This commit is contained in:
dh
2026-09-17 08:54:17 +00:00
parent 4514ccb557
commit 9e6a675b25
5 changed files with 183 additions and 73 deletions
+138 -47
View File
@@ -25,10 +25,16 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
/** @var list<string> */ /** @var list<string> */
private const DIAGNOSE_VARIABLEN = [ private const DIAGNOSE_VARIABLEN = [
'Istleistung',
'Leistungsquelle', 'Leistungsquelle',
'Sollleistung',
'SollwertGueltig', 'SollwertGueltig',
'Verfuegbar', 'Verfuegbar',
'AenderungMoeglich', 'AenderungMoeglich',
'Stoerung',
'Stoertext',
'AktiveStufe',
'BezogeneEnergie',
'TemperaturGueltig', 'TemperaturGueltig',
'NachladenAktiv', 'NachladenAktiv',
'LegionellenbetriebAktiv', 'LegionellenbetriebAktiv',
@@ -60,15 +66,10 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->RegisterPropertyBoolean('DiagnosevariablenAnzeigen', false); $this->RegisterPropertyBoolean('DiagnosevariablenAnzeigen', false);
$this->RegisterVariableFloat('Boilertemperatur', 'Boilertemperatur', '~Temperature', 100); $this->RegisterVariableFloat('Boilertemperatur', 'Boilertemperatur', '~Temperature', 100);
$this->RegisterVariableInteger('AktiveStufe', 'Aktive Stufe', '', 110);
$this->RegisterVariableFloat('BezogeneEnergie', 'Bezogene Energie', '~Electricity', 120);
$this->RegisterVariableFloat('Mindesttemperatur', 'Mindesttemperatur', '~Temperature', 130); $this->RegisterVariableFloat('Mindesttemperatur', 'Mindesttemperatur', '~Temperature', 130);
$this->RegisterVariableFloat('Maximaltemperatur', 'Maximaltemperatur', '~Temperature', 140); $this->RegisterVariableFloat('Maximaltemperatur', 'Maximaltemperatur', '~Temperature', 140);
$this->RegisterVariableFloat('Legionellentemperatur', 'Legionellentemperatur', '~Temperature', 150);
$this->EnableAction('Mindesttemperatur'); $this->EnableAction('Mindesttemperatur');
$this->EnableAction('Maximaltemperatur'); $this->EnableAction('Maximaltemperatur');
$this->EnableAction('Legionellentemperatur');
$this->RegisterAttributeBoolean('InitialwerteGesetzt', false); $this->RegisterAttributeBoolean('InitialwerteGesetzt', false);
$this->RegisterAttributeInteger('RegistrierteFuehlerID', 0); $this->RegisterAttributeInteger('RegistrierteFuehlerID', 0);
@@ -80,6 +81,13 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->RegisterAttributeBoolean('GlaettungInitialisiert', false); $this->RegisterAttributeBoolean('GlaettungInitialisiert', false);
$this->RegisterAttributeString('Leistungsangebot', '[]'); $this->RegisterAttributeString('Leistungsangebot', '[]');
$this->RegisterAttributeString('Schaltfehler', ''); $this->RegisterAttributeString('Schaltfehler', '');
$this->RegisterAttributeFloat('ZustandIstleistung', 0.0);
$this->RegisterAttributeInteger('ZustandSollleistung', 0);
$this->RegisterAttributeBoolean('ZustandStoerung', false);
$this->RegisterAttributeString('ZustandStoertext', '');
$this->RegisterAttributeInteger('ZustandAktiveStufe', 0);
$this->RegisterAttributeFloat('ZustandBezogeneEnergie', 0.0);
$this->RegisterAttributeFloat('ZustandLegionellentemperatur', 65.0);
$this->RegisterAttributeBoolean('ZustandSollwertGueltig', false); $this->RegisterAttributeBoolean('ZustandSollwertGueltig', false);
$this->RegisterAttributeBoolean('ZustandVerfuegbar', false); $this->RegisterAttributeBoolean('ZustandVerfuegbar', false);
$this->RegisterAttributeBoolean('ZustandAenderungMoeglich', false); $this->RegisterAttributeBoolean('ZustandAenderungMoeglich', false);
@@ -209,7 +217,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->WriteAttributeInteger('LetzteManagerID', $managerID); $this->WriteAttributeInteger('LetzteManagerID', $managerID);
$this->WriteAttributeInteger('LetzteVorgabeZeit', time()); $this->WriteAttributeInteger('LetzteVorgabeZeit', time());
$this->SetValue('Sollleistung', $sollleistung); $this->setzeZustand('Sollleistung', $sollleistung);
$this->setzeZustand('SollwertGueltig', true); $this->setzeZustand('SollwertGueltig', true);
$this->regelzyklus(false); $this->regelzyklus(false);
@@ -243,7 +251,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
if ($zwangsleistung !== null) { if ($zwangsleistung !== null) {
$ziel = $zwangsleistung; $ziel = $zwangsleistung;
} elseif ((bool) $this->leseZustand('SollwertGueltig')) { } elseif ((bool) $this->leseZustand('SollwertGueltig')) {
$ziel = (int) $this->GetValue('Sollleistung'); $ziel = (int) $this->leseZustand('Sollleistung');
if (!in_array($ziel, $angebot, true)) { if (!in_array($ziel, $angebot, true)) {
$this->setzeZustand('SollwertGueltig', false); $this->setzeZustand('SollwertGueltig', false);
$ziel = 0; $ziel = 0;
@@ -252,7 +260,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
$this->schalteLeistung($ziel); $this->schalteLeistung($ziel);
$this->SetValue('Sollleistung', $ziel); $this->setzeZustand('Sollleistung', $ziel);
$this->aktualisiereStoerungen($temperaturGueltig); $this->aktualisiereStoerungen($temperaturGueltig);
if ($meldungPlanen) { if ($meldungPlanen) {
$this->SetTimerInterval('RueckmeldungVerzoegert', 100); $this->SetTimerInterval('RueckmeldungVerzoegert', 100);
@@ -261,8 +269,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->WriteAttributeString('Schaltfehler', $fehler->getMessage()); $this->WriteAttributeString('Schaltfehler', $fehler->getMessage());
$this->setzeZustand('Verfuegbar', false); $this->setzeZustand('Verfuegbar', false);
$this->setzeZustand('AenderungMoeglich', false); $this->setzeZustand('AenderungMoeglich', false);
$this->SetValue('Stoerung', true); $this->setzeZustand('Stoerung', true);
$this->SetValue('Stoertext', $fehler->getMessage()); $this->setzeZustand('Stoertext', $fehler->getMessage());
$this->SetStatus(self::STATUS_SCHALTFEHLER); $this->SetStatus(self::STATUS_SCHALTFEHLER);
$this->protokolliere('Regelzyklus', $fehler->getMessage()); $this->protokolliere('Regelzyklus', $fehler->getMessage());
} }
@@ -334,10 +342,10 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->ReadPropertyInteger('LegionellenMaximalintervallTage'), $this->ReadPropertyInteger('LegionellenMaximalintervallTage'),
$minimum, $minimum,
$maximum, $maximum,
(float) $this->GetValue('Legionellentemperatur') (float) $this->ReadAttributeFloat('ZustandLegionellentemperatur')
); );
$hysterese = $this->ReadPropertyFloat('Hysterese'); $hysterese = $this->ReadPropertyFloat('Hysterese');
$aktuelleLeistung = (int) round((float) $this->GetValue('Istleistung')); $aktuelleLeistung = (int) round((float) $this->leseZustand('Istleistung'));
$nachladen = (bool) $this->leseZustand('NachladenAktiv'); $nachladen = (bool) $this->leseZustand('NachladenAktiv');
if ($temperatur < $minimum) { if ($temperatur < $minimum) {
@@ -382,7 +390,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$sekundenSeitAbschluss = max(0, $jetzt - $letzterAbschluss); $sekundenSeitAbschluss = max(0, $jetzt - $letzterAbschluss);
if ($aktiviert && $temperaturGueltig if ($aktiviert && $temperaturGueltig
&& (float) $this->GetValue('Boilertemperatur') >= (float) $this->GetValue('Legionellentemperatur') && (float) $this->GetValue('Boilertemperatur')
>= $this->ReadAttributeFloat('ZustandLegionellentemperatur')
) { ) {
$this->WriteAttributeInteger('LetzterLegionellenabschluss', $jetzt); $this->WriteAttributeInteger('LetzterLegionellenabschluss', $jetzt);
$sekundenSeitAbschluss = 0; $sekundenSeitAbschluss = 0;
@@ -398,7 +407,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
{ {
$stufen = WarmwasserRegler::dekodiereLeistungsstufen($this->ReadPropertyString('LeistungsStufen')); $stufen = WarmwasserRegler::dekodiereLeistungsstufen($this->ReadPropertyString('LeistungsStufen'));
$zielStufe = WarmwasserRegler::stufeFuerLeistung($stufen, $zielLeistung); $zielStufe = WarmwasserRegler::stufeFuerLeistung($stufen, $zielLeistung);
$bisherigeLeistung = (int) round((float) $this->GetValue('Istleistung')); $bisherigeLeistung = (int) round((float) $this->leseZustand('Istleistung'));
if ($zielLeistung === $bisherigeLeistung && $this->kontakteEntsprechenZiel($stufen, $zielLeistung)) { if ($zielLeistung === $bisherigeLeistung && $this->kontakteEntsprechenZiel($stufen, $zielLeistung)) {
$this->WriteAttributeString('Schaltfehler', ''); $this->WriteAttributeString('Schaltfehler', '');
$this->verarbeiteIdle(false); $this->verarbeiteIdle(false);
@@ -425,15 +434,15 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} catch (Throwable $ignoriert) { } catch (Throwable $ignoriert) {
} }
} }
$this->SetValue('Istleistung', 0.0); $this->setzeZustand('Istleistung', 0.0);
$this->SetValue('AktiveStufe', 0); $this->setzeZustand('AktiveStufe', 0);
throw new RuntimeException('Leistungsstufe konnte nicht sicher geschaltet werden: ' . $fehler->getMessage()); throw new RuntimeException('Leistungsstufe konnte nicht sicher geschaltet werden: ' . $fehler->getMessage());
} }
$this->WriteAttributeString('Schaltfehler', ''); $this->WriteAttributeString('Schaltfehler', '');
$this->SetValue('Istleistung', (float) $zielLeistung); $this->setzeZustand('Istleistung', (float) $zielLeistung);
$this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET); $this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
$this->SetValue('AktiveStufe', $zielStufe); $this->setzeZustand('AktiveStufe', $zielStufe);
$this->verarbeiteIdle(true); $this->verarbeiteIdle(true);
$this->protokolliere('Leistungsstufe', ['Leistung_W' => $zielLeistung, 'Stufe' => $zielStufe]); $this->protokolliere('Leistungsstufe', ['Leistung_W' => $zielLeistung, 'Stufe' => $zielStufe]);
} }
@@ -477,10 +486,10 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
$zuwachs = WarmwasserRegler::energieKWh( $zuwachs = WarmwasserRegler::energieKWh(
(float) $this->GetValue('Istleistung'), (float) $this->leseZustand('Istleistung'),
$jetzt - $letzteBerechnung $jetzt - $letzteBerechnung
); );
$this->SetValue('BezogeneEnergie', (float) $this->GetValue('BezogeneEnergie') + $zuwachs); $this->setzeZustand('BezogeneEnergie', (float) $this->leseZustand('BezogeneEnergie') + $zuwachs);
} }
private function aktualisiereStoerungen(bool $temperaturGueltig): void private function aktualisiereStoerungen(bool $temperaturGueltig): void
@@ -489,20 +498,15 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
if (!$temperaturGueltig) { if (!$temperaturGueltig) {
$stoerungen[] = 'Boilertemperatur fehlt oder ist veraltet.'; $stoerungen[] = 'Boilertemperatur fehlt oder ist veraltet.';
} }
$uebertemperatur = $temperaturGueltig $uebertemperatur = $this->istUebertemperatur($temperaturGueltig);
&& (float) $this->GetValue('Boilertemperatur')
> max(
(float) $this->GetValue('Maximaltemperatur'),
(float) $this->GetValue('Legionellentemperatur')
) + $this->ReadPropertyFloat('Hysterese');
if ($uebertemperatur) { if ($uebertemperatur) {
$stoerungen[] = 'Uebertemperatur erkannt.'; $stoerungen[] = 'Uebertemperatur erkannt.';
} }
if ($this->ReadAttributeString('Schaltfehler') !== '') { if ($this->ReadAttributeString('Schaltfehler') !== '') {
$stoerungen[] = $this->ReadAttributeString('Schaltfehler'); $stoerungen[] = $this->ReadAttributeString('Schaltfehler');
} }
$this->SetValue('Stoerung', $stoerungen !== []); $this->setzeZustand('Stoerung', $stoerungen !== []);
$this->SetValue('Stoertext', implode("\n", array_values(array_unique($stoerungen)))); $this->setzeZustand('Stoertext', implode("\n", array_values(array_unique($stoerungen))));
if ($this->ReadAttributeString('Schaltfehler') !== '') { if ($this->ReadAttributeString('Schaltfehler') !== '') {
$this->SetStatus(self::STATUS_SCHALTFEHLER); $this->SetStatus(self::STATUS_SCHALTFEHLER);
} elseif (!$temperaturGueltig) { } elseif (!$temperaturGueltig) {
@@ -512,6 +516,21 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
} }
private function istUebertemperatur(bool $temperaturGueltig): bool
{
if (!$temperaturGueltig) {
return false;
}
$grenze = (float) $this->GetValue('Maximaltemperatur');
if ($this->ReadPropertyBoolean('LegionellenfunktionAktiv')) {
$grenze = max($grenze, $this->ReadAttributeFloat('ZustandLegionellentemperatur'));
}
return (float) $this->GetValue('Boilertemperatur')
> $grenze + $this->ReadPropertyFloat('Hysterese');
}
private function sendeVerbraucherdaten(): void private function sendeVerbraucherdaten(): void
{ {
foreach ($this->zugeordneteManagerIDs() as $managerID) { foreach ($this->zugeordneteManagerIDs() as $managerID) {
@@ -534,12 +553,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
{ {
$temperaturGueltig = (bool) $this->leseZustand('TemperaturGueltig'); $temperaturGueltig = (bool) $this->leseZustand('TemperaturGueltig');
$schaltfehler = $this->ReadAttributeString('Schaltfehler'); $schaltfehler = $this->ReadAttributeString('Schaltfehler');
$uebertemperatur = $temperaturGueltig $uebertemperatur = $this->istUebertemperatur($temperaturGueltig);
&& (float) $this->GetValue('Boilertemperatur')
> max(
(float) $this->GetValue('Maximaltemperatur'),
(float) $this->GetValue('Legionellentemperatur')
) + $this->ReadPropertyFloat('Hysterese');
return [ return [
'Kopf' => [ 'Kopf' => [
@@ -553,14 +567,14 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
'Leistungswerte_W' => $this->leseLeistungsangebot(), 'Leistungswerte_W' => $this->leseLeistungsangebot(),
'AenderungMoeglich' => (bool) $this->leseZustand('AenderungMoeglich'), 'AenderungMoeglich' => (bool) $this->leseZustand('AenderungMoeglich'),
'Verfuegbar' => (bool) $this->leseZustand('Verfuegbar'), 'Verfuegbar' => (bool) $this->leseZustand('Verfuegbar'),
'Istleistung_W' => (float) $this->GetValue('Istleistung'), 'Istleistung_W' => (float) $this->leseZustand('Istleistung'),
'Leistungsquelle' => Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET, 'Leistungsquelle' => Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET,
'Zustand' => [ 'Zustand' => [
[ [
'Kennung' => 'Sollleistung_W', 'Kennung' => 'Sollleistung_W',
'Art' => 'Sollwert', 'Art' => 'Sollwert',
'Wert' => (bool) $this->leseZustand('SollwertGueltig') 'Wert' => (bool) $this->leseZustand('SollwertGueltig')
? (int) $this->GetValue('Sollleistung') ? (int) $this->leseZustand('Sollleistung')
: null, : null,
'Einheit' => 'W', 'Einheit' => 'W',
], ],
@@ -579,7 +593,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
[ [
'Kennung' => 'AktiveStufe', 'Kennung' => 'AktiveStufe',
'Art' => 'Status', 'Art' => 'Status',
'Wert' => (int) $this->GetValue('AktiveStufe'), 'Wert' => (int) $this->leseZustand('AktiveStufe'),
'Einheit' => '', 'Einheit' => '',
], ],
[ [
@@ -680,7 +694,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
$minimum = (float) $this->GetValue('Mindesttemperatur'); $minimum = (float) $this->GetValue('Mindesttemperatur');
$maximum = (float) $this->GetValue('Maximaltemperatur'); $maximum = (float) $this->GetValue('Maximaltemperatur');
$legionellen = (float) $this->GetValue('Legionellentemperatur'); $legionellen = (float) $this->ReadAttributeFloat('ZustandLegionellentemperatur');
if ($minimum < 0 || $minimum >= $maximum || $legionellen < $maximum) { if ($minimum < 0 || $minimum >= $maximum || $legionellen < $maximum) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
'Temperaturen muessen Mindesttemperatur < Maximaltemperatur <= Legionellentemperatur erfuellen.' 'Temperaturen muessen Mindesttemperatur < Maximaltemperatur <= Legionellentemperatur erfuellen.'
@@ -735,7 +749,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
$this->SetValue('Mindesttemperatur', 45.0); $this->SetValue('Mindesttemperatur', 45.0);
$this->SetValue('Maximaltemperatur', 60.0); $this->SetValue('Maximaltemperatur', 60.0);
$this->SetValue('Legionellentemperatur', 65.0); $this->WriteAttributeFloat('ZustandLegionellentemperatur', 65.0);
$this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET); $this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
$this->setzeZustand('Idle', true); $this->setzeZustand('Idle', true);
$this->WriteAttributeBoolean('InitialwerteGesetzt', true); $this->WriteAttributeBoolean('InitialwerteGesetzt', true);
@@ -747,6 +761,11 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
if (!$this->ReadPropertyBoolean('EinstellungenInVisu')) { if (!$this->ReadPropertyBoolean('EinstellungenInVisu')) {
throw new RuntimeException('Temperatureinstellungen sind in der Visualisierung nicht freigegeben.'); throw new RuntimeException('Temperatureinstellungen sind in der Visualisierung nicht freigegeben.');
} }
if ($ident === 'Legionellentemperatur'
&& !$this->ReadPropertyBoolean('LegionellenfunktionAktiv')
) {
throw new RuntimeException('Die Legionellenfunktion ist nicht aktiviert.');
}
if (!is_int($wert) && !is_float($wert)) { if (!is_int($wert) && !is_float($wert)) {
throw new InvalidArgumentException('Temperatursollwert muss numerisch sein.'); throw new InvalidArgumentException('Temperatursollwert muss numerisch sein.');
} }
@@ -758,7 +777,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$werte = [ $werte = [
'Mindesttemperatur' => (float) $this->GetValue('Mindesttemperatur'), 'Mindesttemperatur' => (float) $this->GetValue('Mindesttemperatur'),
'Maximaltemperatur' => (float) $this->GetValue('Maximaltemperatur'), 'Maximaltemperatur' => (float) $this->GetValue('Maximaltemperatur'),
'Legionellentemperatur' => (float) $this->GetValue('Legionellentemperatur'), 'Legionellentemperatur' => $this->ReadAttributeFloat('ZustandLegionellentemperatur'),
]; ];
$werte[$ident] = $temperatur; $werte[$ident] = $temperatur;
if ($werte['Mindesttemperatur'] >= $werte['Maximaltemperatur'] if ($werte['Mindesttemperatur'] >= $werte['Maximaltemperatur']
@@ -769,14 +788,34 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
); );
} }
$this->SetValue($ident, $temperatur); if ($ident === 'Legionellentemperatur') {
$this->WriteAttributeFloat('ZustandLegionellentemperatur', $temperatur);
$variablenID = @IPS_GetObjectIDByIdent($ident, $this->InstanceID);
if (is_int($variablenID) && $variablenID > 0 && IPS_VariableExists($variablenID)) {
SetValue($variablenID, $temperatur);
}
} else {
$this->SetValue($ident, $temperatur);
}
$this->regelzyklus(true); $this->regelzyklus(true);
} }
private function aktualisiereVariablen(): void private function aktualisiereVariablen(): void
{ {
foreach (self::DIAGNOSE_VARIABLEN as $ident) {
if ($ident === 'Leistungsquelle') {
continue;
}
$variablenID = @IPS_GetObjectIDByIdent($ident, $this->InstanceID);
if (is_int($variablenID) && $variablenID > 0 && IPS_VariableExists($variablenID)) {
$this->setzeZustand($ident, GetValue($variablenID));
}
}
if ($this->ReadPropertyBoolean('DiagnosevariablenAnzeigen')) { if ($this->ReadPropertyBoolean('DiagnosevariablenAnzeigen')) {
$this->registriereVerbraucherDiagnose(); $this->registriereVerbraucherDiagnose();
$this->RegisterVariableInteger('AktiveStufe', 'Aktive Stufe', '', 110);
$this->RegisterVariableFloat('BezogeneEnergie', 'Bezogene Energie', '~Electricity', 120);
$this->RegisterVariableBoolean('TemperaturGueltig', 'Temperatur gueltig', '~Switch', 200); $this->RegisterVariableBoolean('TemperaturGueltig', 'Temperatur gueltig', '~Switch', 200);
$this->RegisterVariableBoolean('NachladenAktiv', 'Nachladen aktiv', '~Switch', 210); $this->RegisterVariableBoolean('NachladenAktiv', 'Nachladen aktiv', '~Switch', 210);
$this->RegisterVariableBoolean( $this->RegisterVariableBoolean(
@@ -789,9 +828,11 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->RegisterVariableBoolean('Idle', 'Idle', '~Switch', 240); $this->RegisterVariableBoolean('Idle', 'Idle', '~Switch', 240);
$this->RegisterVariableInteger('IdleCounter', 'Idle Counter', '', 250); $this->RegisterVariableInteger('IdleCounter', 'Idle Counter', '', 250);
$this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET); foreach (self::DIAGNOSE_VARIABLEN as $ident) {
foreach (array_slice(self::DIAGNOSE_VARIABLEN, 1) as $ident) { $wert = $ident === 'Leistungsquelle'
$this->setzeZustand($ident, $this->leseZustand($ident)); ? Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET
: $this->leseZustand($ident);
$this->setzeZustand($ident, $wert);
} }
} else { } else {
foreach (self::DIAGNOSE_VARIABLEN as $ident) { foreach (self::DIAGNOSE_VARIABLEN as $ident) {
@@ -803,7 +844,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
$einstellungen = $this->ReadPropertyBoolean('EinstellungenInVisu'); $einstellungen = $this->ReadPropertyBoolean('EinstellungenInVisu');
foreach (['Mindesttemperatur', 'Maximaltemperatur', 'Legionellentemperatur'] as $ident) { foreach (['Mindesttemperatur', 'Maximaltemperatur'] as $ident) {
IPS_SetHidden($this->GetIDForIdent($ident), !$einstellungen); IPS_SetHidden($this->GetIDForIdent($ident), !$einstellungen);
if ($einstellungen) { if ($einstellungen) {
$this->EnableAction($ident); $this->EnableAction($ident);
@@ -811,24 +852,52 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
$this->DisableAction($ident); $this->DisableAction($ident);
} }
} }
$legionellenID = @IPS_GetObjectIDByIdent('Legionellentemperatur', $this->InstanceID);
if (is_int($legionellenID) && $legionellenID > 0 && IPS_VariableExists($legionellenID)) {
$this->WriteAttributeFloat('ZustandLegionellentemperatur', (float) GetValue($legionellenID));
}
if ($this->ReadPropertyBoolean('LegionellenfunktionAktiv')) {
$this->RegisterVariableFloat('Legionellentemperatur', 'Legionellentemperatur', '~Temperature', 150);
$legionellenID = $this->GetIDForIdent('Legionellentemperatur');
SetValue($legionellenID, $this->ReadAttributeFloat('ZustandLegionellentemperatur'));
IPS_SetHidden($legionellenID, !$einstellungen);
if ($einstellungen) {
$this->EnableAction('Legionellentemperatur');
} else {
$this->DisableAction('Legionellentemperatur');
}
} elseif (is_int($legionellenID) && $legionellenID > 0 && IPS_VariableExists($legionellenID)) {
$this->UnregisterVariable('Legionellentemperatur');
}
} }
/** @param bool|int $wert */ /** @param bool|int|float|string $wert */
private function setzeZustand(string $ident, $wert): void private function setzeZustand(string $ident, $wert): void
{ {
$booleanAttribute = [ $booleanAttribute = [
'SollwertGueltig' => 'ZustandSollwertGueltig', 'SollwertGueltig' => 'ZustandSollwertGueltig',
'Verfuegbar' => 'ZustandVerfuegbar', 'Verfuegbar' => 'ZustandVerfuegbar',
'AenderungMoeglich' => 'ZustandAenderungMoeglich', 'AenderungMoeglich' => 'ZustandAenderungMoeglich',
'Stoerung' => 'ZustandStoerung',
'TemperaturGueltig' => 'ZustandTemperaturGueltig', 'TemperaturGueltig' => 'ZustandTemperaturGueltig',
'NachladenAktiv' => 'ZustandNachladenAktiv', 'NachladenAktiv' => 'ZustandNachladenAktiv',
'LegionellenbetriebAktiv' => 'ZustandLegionellenbetriebAktiv', 'LegionellenbetriebAktiv' => 'ZustandLegionellenbetriebAktiv',
'Idle' => 'ZustandIdle', 'Idle' => 'ZustandIdle',
]; ];
$integerAttribute = [ $integerAttribute = [
'Sollleistung' => 'ZustandSollleistung',
'AktiveStufe' => 'ZustandAktiveStufe',
'LegioCounter' => 'ZustandLegioCounter', 'LegioCounter' => 'ZustandLegioCounter',
'IdleCounter' => 'ZustandIdleCounter', 'IdleCounter' => 'ZustandIdleCounter',
]; ];
$floatAttribute = [
'Istleistung' => 'ZustandIstleistung',
'BezogeneEnergie' => 'ZustandBezogeneEnergie',
];
$stringAttribute = [
'Stoertext' => 'ZustandStoertext',
];
if (isset($booleanAttribute[$ident])) { if (isset($booleanAttribute[$ident])) {
$wert = (bool) $wert; $wert = (bool) $wert;
@@ -836,6 +905,12 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} elseif (isset($integerAttribute[$ident])) { } elseif (isset($integerAttribute[$ident])) {
$wert = (int) $wert; $wert = (int) $wert;
$this->WriteAttributeInteger($integerAttribute[$ident], $wert); $this->WriteAttributeInteger($integerAttribute[$ident], $wert);
} elseif (isset($floatAttribute[$ident])) {
$wert = (float) $wert;
$this->WriteAttributeFloat($floatAttribute[$ident], $wert);
} elseif (isset($stringAttribute[$ident])) {
$wert = (string) $wert;
$this->WriteAttributeString($stringAttribute[$ident], $wert);
} elseif ($ident !== 'Leistungsquelle') { } elseif ($ident !== 'Leistungsquelle') {
throw new LogicException('Unbekannter interner Zustand: ' . $ident); throw new LogicException('Unbekannter interner Zustand: ' . $ident);
} }
@@ -846,22 +921,32 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
} }
} }
/** @return bool|int */ /** @return bool|int|float|string */
private function leseZustand(string $ident) private function leseZustand(string $ident)
{ {
$booleanAttribute = [ $booleanAttribute = [
'SollwertGueltig' => 'ZustandSollwertGueltig', 'SollwertGueltig' => 'ZustandSollwertGueltig',
'Verfuegbar' => 'ZustandVerfuegbar', 'Verfuegbar' => 'ZustandVerfuegbar',
'AenderungMoeglich' => 'ZustandAenderungMoeglich', 'AenderungMoeglich' => 'ZustandAenderungMoeglich',
'Stoerung' => 'ZustandStoerung',
'TemperaturGueltig' => 'ZustandTemperaturGueltig', 'TemperaturGueltig' => 'ZustandTemperaturGueltig',
'NachladenAktiv' => 'ZustandNachladenAktiv', 'NachladenAktiv' => 'ZustandNachladenAktiv',
'LegionellenbetriebAktiv' => 'ZustandLegionellenbetriebAktiv', 'LegionellenbetriebAktiv' => 'ZustandLegionellenbetriebAktiv',
'Idle' => 'ZustandIdle', 'Idle' => 'ZustandIdle',
]; ];
$integerAttribute = [ $integerAttribute = [
'Sollleistung' => 'ZustandSollleistung',
'AktiveStufe' => 'ZustandAktiveStufe',
'LegioCounter' => 'ZustandLegioCounter', 'LegioCounter' => 'ZustandLegioCounter',
'IdleCounter' => 'ZustandIdleCounter', 'IdleCounter' => 'ZustandIdleCounter',
]; ];
$floatAttribute = [
'Istleistung' => 'ZustandIstleistung',
'BezogeneEnergie' => 'ZustandBezogeneEnergie',
];
$stringAttribute = [
'Stoertext' => 'ZustandStoertext',
];
if (isset($booleanAttribute[$ident])) { if (isset($booleanAttribute[$ident])) {
return $this->ReadAttributeBoolean($booleanAttribute[$ident]); return $this->ReadAttributeBoolean($booleanAttribute[$ident]);
@@ -869,6 +954,12 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
if (isset($integerAttribute[$ident])) { if (isset($integerAttribute[$ident])) {
return $this->ReadAttributeInteger($integerAttribute[$ident]); return $this->ReadAttributeInteger($integerAttribute[$ident]);
} }
if (isset($floatAttribute[$ident])) {
return $this->ReadAttributeFloat($floatAttribute[$ident]);
}
if (isset($stringAttribute[$ident])) {
return $this->ReadAttributeString($stringAttribute[$ident]);
}
throw new LogicException('Unbekannter interner Zustand: ' . $ident); throw new LogicException('Unbekannter interner Zustand: ' . $ident);
} }
+18 -7
View File
@@ -42,26 +42,34 @@ Zu den sechs gemeinsamen Verbraucher-Properties aus
| `LegionellenfunktionAktiv` | Boolean | `true` | Zweistufige periodische Aufheizung aktiv. | | `LegionellenfunktionAktiv` | Boolean | `true` | Zweistufige periodische Aufheizung aktiv. |
| `LegionellenMinimalintervallTage` | Integer | `4` | Ab diesem Intervall wird die Legionellentemperatur als Maximaltemperatur angeboten. | | `LegionellenMinimalintervallTage` | Integer | `4` | Ab diesem Intervall wird die Legionellentemperatur als Maximaltemperatur angeboten. |
| `LegionellenMaximalintervallTage` | Integer | `7` | Ab diesem Intervall wird die Legionellentemperatur zwingend nachgeladen. | | `LegionellenMaximalintervallTage` | Integer | `7` | Ab diesem Intervall wird die Legionellentemperatur zwingend nachgeladen. |
| `DiagnosevariablenAnzeigen` | Boolean | `false` | Legt zehn Diagnosevariablen bei Bedarf an. | | `DiagnosevariablenAnzeigen` | Boolean | `false` | Legt 16 Diagnosevariablen bei Bedarf an. |
`LoggingEin` aktiviert laufende Debug-Ausgaben. `LoggingEin` aktiviert laufende Debug-Ausgaben.
## Variablen ## Variablen
Standardmaessig sichtbar sind nur die acht Betriebsvariablen `Aktiv`, Standardmaessig sichtbar sind nur `Aktiv` und `Boilertemperatur`.
`Istleistung`, `Sollleistung`, `Stoerung`, `Stoertext`, `Boilertemperatur`,
`AktiveStufe` und `BezogeneEnergie`.
Mit `EinstellungenInVisu` werden `Mindesttemperatur`, `Maximaltemperatur` und Mit `EinstellungenInVisu` werden `Mindesttemperatur` und `Maximaltemperatur`
`Legionellentemperatur` sichtbar und geprueft bedienbar. Die Reihenfolge sichtbar und geprueft bedienbar. `Legionellentemperatur` wird nur angelegt,
wenn `LegionellenfunktionAktiv` eingeschaltet ist, und ist ebenfalls nur mit
`EinstellungenInVisu` sichtbar. Beim Abschalten der Legionellenfunktion wird
die Variable geloescht; ihr letzter Wert bleibt intern fuer ein spaeteres
Wiedereinschalten erhalten. Die Reihenfolge
`Mindesttemperatur < Maximaltemperatur <= Legionellentemperatur` ist zwingend. `Mindesttemperatur < Maximaltemperatur <= Legionellentemperatur` ist zwingend.
Mit `DiagnosevariablenAnzeigen` werden diese zehn Variablen eingeblendet: Mit `DiagnosevariablenAnzeigen` werden diese 16 Variablen angelegt:
- `Istleistung`
- `Leistungsquelle` - `Leistungsquelle`
- `Sollleistung`
- `SollwertGueltig` - `SollwertGueltig`
- `Verfuegbar` - `Verfuegbar`
- `AenderungMoeglich` - `AenderungMoeglich`
- `Stoerung`
- `Stoertext`
- `AktiveStufe`
- `BezogeneEnergie`
- `TemperaturGueltig` - `TemperaturGueltig`
- `NachladenAktiv` - `NachladenAktiv`
- `LegionellenbetriebAktiv` - `LegionellenbetriebAktiv`
@@ -69,6 +77,9 @@ Mit `DiagnosevariablenAnzeigen` werden diese zehn Variablen eingeblendet:
- `Idle` - `Idle`
- `IdleCounter` - `IdleCounter`
Die Regelung und Managerkommunikation verwenden fuer diese Werte eine interne
Zustandsablage und funktionieren auch ohne angelegte Diagnosevariablen weiter.
## Managerkommunikation ## Managerkommunikation
Das Modul implementiert `VerbraucherSchnittstelle::ManagerdatenEmpfangen()`. Das Modul implementiert `VerbraucherSchnittstelle::ManagerdatenEmpfangen()`.
+4 -4
View File
@@ -23,17 +23,17 @@ trait VerbraucherBasisTrait
$this->RegisterVariableBoolean('Aktiv', 'Aktiv', '~Switch', 10); $this->RegisterVariableBoolean('Aktiv', 'Aktiv', '~Switch', 10);
$this->EnableAction('Aktiv'); $this->EnableAction('Aktiv');
$this->RegisterVariableFloat('Istleistung', 'Istleistung', '', 20);
$this->RegisterVariableInteger('Sollleistung', 'Sollleistung', '', 40);
$this->RegisterVariableBoolean('Stoerung', 'Stoerung', '', 80);
$this->RegisterVariableString('Stoertext', 'Stoertext', '', 90);
} }
protected function registriereVerbraucherDiagnose(): void protected function registriereVerbraucherDiagnose(): void
{ {
$this->RegisterVariableFloat('Istleistung', 'Istleistung', '', 20);
$this->RegisterVariableInteger('Leistungsquelle', 'Leistungsquelle', '', 30); $this->RegisterVariableInteger('Leistungsquelle', 'Leistungsquelle', '', 30);
$this->RegisterVariableInteger('Sollleistung', 'Sollleistung', '', 40);
$this->RegisterVariableBoolean('SollwertGueltig', 'Sollwert gueltig', '~Switch', 50); $this->RegisterVariableBoolean('SollwertGueltig', 'Sollwert gueltig', '~Switch', 50);
$this->RegisterVariableBoolean('Verfuegbar', 'Verfuegbar', '~Switch', 60); $this->RegisterVariableBoolean('Verfuegbar', 'Verfuegbar', '~Switch', 60);
$this->RegisterVariableBoolean('AenderungMoeglich', 'Aenderung moeglich', '~Switch', 70); $this->RegisterVariableBoolean('AenderungMoeglich', 'Aenderung moeglich', '~Switch', 70);
$this->RegisterVariableBoolean('Stoerung', 'Stoerung', '', 80);
$this->RegisterVariableString('Stoertext', 'Stoertext', '', 90);
} }
} }
+4 -13
View File
@@ -25,16 +25,7 @@ final class VerbraucherBasisTraitTest extends TestCase
], ],
array_keys($modul->properties) array_keys($modul->properties)
); );
self::assertSame( self::assertSame(['Aktiv'], array_keys($modul->variablen));
[
'Aktiv',
'Istleistung',
'Sollleistung',
'Stoerung',
'Stoertext',
],
array_keys($modul->variablen)
);
self::assertSame(['Aktiv'], $modul->aktionen); self::assertSame(['Aktiv'], $modul->aktionen);
$modul->registriereDiagnose(); $modul->registriereDiagnose();
@@ -42,13 +33,13 @@ final class VerbraucherBasisTraitTest extends TestCase
[ [
'Aktiv', 'Aktiv',
'Istleistung', 'Istleistung',
'Sollleistung',
'Stoerung',
'Stoertext',
'Leistungsquelle', 'Leistungsquelle',
'Sollleistung',
'SollwertGueltig', 'SollwertGueltig',
'Verfuegbar', 'Verfuegbar',
'AenderungMoeglich', 'AenderungMoeglich',
'Stoerung',
'Stoertext',
], ],
array_keys($modul->variablen) array_keys($modul->variablen)
); );
+19 -2
View File
@@ -55,14 +55,18 @@ final class WarmwassererwaermerModulstrukturTest extends TestCase
self::assertStringNotContainsString("RegisterPropertyInteger('ManagerID'", $inhalt); self::assertStringNotContainsString("RegisterPropertyInteger('ManagerID'", $inhalt);
} }
public function testZehnDiagnosevariablenWerdenBedarfsgesteuertAngelegtUndGeloescht(): void public function testSechzehnDiagnosevariablenWerdenBedarfsgesteuertAngelegtUndGeloescht(): void
{ {
$inhalt = (string) file_get_contents(self::MODULPFAD . 'module.php'); $inhalt = (string) file_get_contents(self::MODULPFAD . 'module.php');
preg_match('/private const DIAGNOSE_VARIABLEN = \[(.*?)\];/s', $inhalt, $treffer); preg_match('/private const DIAGNOSE_VARIABLEN = \[(.*?)\];/s', $inhalt, $treffer);
self::assertArrayHasKey(1, $treffer); self::assertArrayHasKey(1, $treffer);
preg_match_all('/\'([^\']+)\'/', $treffer[1], $variablen); preg_match_all('/\'([^\']+)\'/', $treffer[1], $variablen);
self::assertCount(10, $variablen[1]); self::assertCount(16, $variablen[1]);
foreach (['Istleistung', 'Sollleistung', 'Stoerung', 'Stoertext', 'AktiveStufe', 'BezogeneEnergie'] as $ident) {
self::assertContains($ident, $variablen[1]);
self::assertStringContainsString("Zustand" . $ident, $inhalt);
}
self::assertStringContainsString("ReadPropertyBoolean('DiagnosevariablenAnzeigen')", $inhalt); self::assertStringContainsString("ReadPropertyBoolean('DiagnosevariablenAnzeigen')", $inhalt);
self::assertStringContainsString('registriereVerbraucherDiagnose', $inhalt); self::assertStringContainsString('registriereVerbraucherDiagnose', $inhalt);
self::assertStringContainsString('UnregisterVariable($ident)', $inhalt); self::assertStringContainsString('UnregisterVariable($ident)', $inhalt);
@@ -70,6 +74,19 @@ final class WarmwassererwaermerModulstrukturTest extends TestCase
self::assertStringNotContainsString("case 'LogStatus':", $inhalt); self::assertStringNotContainsString("case 'LogStatus':", $inhalt);
} }
public function testLegionellentemperaturWirdNurBeiAktiverFunktionAngelegt(): void
{
$inhalt = (string) file_get_contents(self::MODULPFAD . 'module.php');
self::assertStringContainsString("ReadPropertyBoolean('LegionellenfunktionAktiv')", $inhalt);
self::assertStringContainsString(
"RegisterVariableFloat('Legionellentemperatur'",
$inhalt
);
self::assertStringContainsString("UnregisterVariable('Legionellentemperatur')", $inhalt);
self::assertStringContainsString("ZustandLegionellentemperatur", $inhalt);
}
public function testFormularIstWieGewuenschtGegliedertUndHatKeineAktionsknoepfe(): void public function testFormularIstWieGewuenschtGegliedertUndHatKeineAktionsknoepfe(): void
{ {
$formular = json_decode( $formular = json_decode(