This commit is contained in:
@@ -1,9 +1,5 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Label",
|
||||
"caption": "Mehrstufiger Warmwassererwaermer nach Enelix-2-Vertrag 3.0"
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Manager und Zeitverhalten",
|
||||
@@ -12,13 +8,13 @@
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "PrioritaetPV",
|
||||
"caption": "Prioritaet PV",
|
||||
"caption": "Priorität PV",
|
||||
"minimum": 0
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "PrioritaetPeak",
|
||||
"caption": "Prioritaet Peak",
|
||||
"caption": "Priorität Peak",
|
||||
"minimum": 0
|
||||
},
|
||||
{
|
||||
@@ -52,7 +48,7 @@
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Leistungsstufen",
|
||||
"caption": "Speichereinstellungen",
|
||||
"expanded": true,
|
||||
"items": [
|
||||
{
|
||||
@@ -94,38 +90,37 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Boilerfuehler_PT1",
|
||||
"caption": "Boilerfühler"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "LegionellenfunktionAktiv",
|
||||
"caption": "Legionellenschaltung aktiv"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "LegionellenMinimalintervallTage",
|
||||
"caption": "Frühestens nach",
|
||||
"suffix": " Tagen",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "LegionellenMaximalintervallTage",
|
||||
"caption": "Spätestens nach",
|
||||
"suffix": " Tagen",
|
||||
"minimum": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Temperatur und Speicher",
|
||||
"expanded": true,
|
||||
"caption": "Erweiterte Speichereinstellungen",
|
||||
"items": [
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "Boilerfuehler_PT1",
|
||||
"caption": "Boilerfuehler"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "TemperaturMaxAlter",
|
||||
"caption": "Maximales Messwertalter",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "BoilertemperaturGlaetten",
|
||||
"caption": "Boilertemperatur mit PT1 glaetten"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "ZeitKonstante",
|
||||
"caption": "PT1-Zeitkonstante",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Boilervolumen",
|
||||
@@ -141,21 +136,10 @@
|
||||
"minimum": 0.1,
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "EinstellungenInVisu",
|
||||
"caption": "Temperatursollwerte in der Visualisierung anzeigen und bedienen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Zeitplan",
|
||||
"items": [
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Zeitplan",
|
||||
"caption": "Naechste Solltemperatur vorausberechnen",
|
||||
"caption": "Zeitplan für Solltemperaturen",
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sortable": true,
|
||||
@@ -179,7 +163,7 @@
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"digits": 1,
|
||||
"suffix": " C"
|
||||
"suffix": " °C"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -188,60 +172,36 @@
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Legionellenfunktion",
|
||||
"caption": "Erweiterte sonstige Einstellungen",
|
||||
"items": [
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "TemperaturMaxAlter",
|
||||
"caption": "Maximales Messwertalter",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "LegionellenfunktionAktiv",
|
||||
"caption": "Legionellenfunktion aktiv"
|
||||
"name": "BoilertemperaturGlaetten",
|
||||
"caption": "Boilertemperatur mit PT1 glätten"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "LegionellenIntervallTage",
|
||||
"caption": "Intervall",
|
||||
"suffix": " Tage",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "LegionellenHaltezeit",
|
||||
"caption": "Haltezeit auf Legionellentemperatur",
|
||||
"suffix": " s",
|
||||
"minimum": 0
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "LegionellenMaximaldauer",
|
||||
"caption": "Maximaldauer",
|
||||
"name": "ZeitKonstante",
|
||||
"caption": "PT1-Zeitkonstante",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "NachtstartStunde",
|
||||
"caption": "Nachtbeginn",
|
||||
"suffix": " Uhr",
|
||||
"minimum": 0,
|
||||
"maximum": 23
|
||||
"type": "CheckBox",
|
||||
"name": "EinstellungenInVisu",
|
||||
"caption": "Temperatursollwerte in der Visualisierung anzeigen und bedienen"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "NachtendeStunde",
|
||||
"caption": "Nachtende",
|
||||
"suffix": " Uhr",
|
||||
"minimum": 0,
|
||||
"maximum": 23
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Diagnose",
|
||||
"items": [
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "DiagnosevariablenAnzeigen",
|
||||
"caption": "Diagnosevariablen anzeigen"
|
||||
"caption": "Diagnosevariablen anlegen"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
@@ -251,18 +211,6 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"type": "Button",
|
||||
"caption": "Regelung jetzt ausfuehren",
|
||||
"onClick": "IPS_RequestAction($id, 'Regelzyklus', false);"
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"caption": "Aktuellen Status einmalig ins Debug-Log schreiben",
|
||||
"onClick": "IPS_RequestAction($id, 'LogStatus', true);"
|
||||
}
|
||||
],
|
||||
"status": [
|
||||
{
|
||||
"code": 102,
|
||||
@@ -277,7 +225,7 @@
|
||||
{
|
||||
"code": 202,
|
||||
"icon": "error",
|
||||
"caption": "Konfiguration ungueltig"
|
||||
"caption": "Konfiguration ungültig"
|
||||
},
|
||||
{
|
||||
"code": 203,
|
||||
|
||||
+154
-153
@@ -55,11 +55,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->RegisterPropertyInteger('TemperaturMaxAlter', 30);
|
||||
$this->RegisterPropertyFloat('Hysterese', 5.0);
|
||||
$this->RegisterPropertyBoolean('LegionellenfunktionAktiv', true);
|
||||
$this->RegisterPropertyInteger('LegionellenIntervallTage', 7);
|
||||
$this->RegisterPropertyInteger('LegionellenHaltezeit', 0);
|
||||
$this->RegisterPropertyInteger('LegionellenMaximaldauer', 86400);
|
||||
$this->RegisterPropertyInteger('NachtstartStunde', 22);
|
||||
$this->RegisterPropertyInteger('NachtendeStunde', 7);
|
||||
$this->RegisterPropertyInteger('LegionellenMinimalintervallTage', 4);
|
||||
$this->RegisterPropertyInteger('LegionellenMaximalintervallTage', 7);
|
||||
$this->RegisterPropertyBoolean('DiagnosevariablenAnzeigen', false);
|
||||
|
||||
$this->RegisterVariableFloat('Boilertemperatur', 'Boilertemperatur', '~Temperature', 100);
|
||||
@@ -73,31 +70,25 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->EnableAction('Maximaltemperatur');
|
||||
$this->EnableAction('Legionellentemperatur');
|
||||
|
||||
$this->RegisterVariableBoolean('TemperaturGueltig', 'Temperatur gueltig', '~Switch', 200);
|
||||
$this->RegisterVariableBoolean('NachladenAktiv', 'Nachladen aktiv', '~Switch', 210);
|
||||
$this->RegisterVariableBoolean(
|
||||
'LegionellenbetriebAktiv',
|
||||
'Legionellenbetrieb aktiv',
|
||||
'~Switch',
|
||||
220
|
||||
);
|
||||
$this->RegisterVariableInteger('LegioCounter', 'Zeit seit Legionellenabschluss', '', 230);
|
||||
$this->RegisterVariableBoolean('Idle', 'Idle', '~Switch', 240);
|
||||
$this->RegisterVariableInteger('IdleCounter', 'Idle Counter', '', 250);
|
||||
|
||||
$this->RegisterAttributeBoolean('InitialwerteGesetzt', false);
|
||||
$this->RegisterAttributeInteger('RegistrierteFuehlerID', 0);
|
||||
$this->RegisterAttributeInteger('LetzteBerechnung', 0);
|
||||
$this->RegisterAttributeInteger('LetzteVorgabeZeit', 0);
|
||||
$this->RegisterAttributeInteger('LetzteManagerID', 0);
|
||||
$this->RegisterAttributeInteger('LetzterLegionellenabschluss', 0);
|
||||
$this->RegisterAttributeInteger('LegionellenStart', 0);
|
||||
$this->RegisterAttributeInteger('LegionellenSeitZiel', 0);
|
||||
$this->RegisterAttributeFloat('Glaettungswert', 0.0);
|
||||
$this->RegisterAttributeBoolean('GlaettungInitialisiert', false);
|
||||
$this->RegisterAttributeString('Leistungsangebot', '[]');
|
||||
$this->RegisterAttributeString('Schaltfehler', '');
|
||||
$this->RegisterAttributeString('Legionellenfehler', '');
|
||||
$this->RegisterAttributeBoolean('ZustandSollwertGueltig', false);
|
||||
$this->RegisterAttributeBoolean('ZustandVerfuegbar', false);
|
||||
$this->RegisterAttributeBoolean('ZustandAenderungMoeglich', false);
|
||||
$this->RegisterAttributeBoolean('ZustandTemperaturGueltig', false);
|
||||
$this->RegisterAttributeBoolean('ZustandNachladenAktiv', false);
|
||||
$this->RegisterAttributeBoolean('ZustandLegionellenbetriebAktiv', false);
|
||||
$this->RegisterAttributeInteger('ZustandLegioCounter', 0);
|
||||
$this->RegisterAttributeBoolean('ZustandIdle', true);
|
||||
$this->RegisterAttributeInteger('ZustandIdleCounter', 0);
|
||||
|
||||
$this->RegisterTimer(
|
||||
'Regelzyklus',
|
||||
@@ -121,7 +112,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
parent::ApplyChanges();
|
||||
|
||||
$this->initialisiereTemperaturen();
|
||||
$this->aktualisiereSichtbarkeit();
|
||||
$this->aktualisiereVariablen();
|
||||
|
||||
try {
|
||||
$this->pruefeKonfiguration();
|
||||
@@ -129,8 +120,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->SetTimerInterval('Regelzyklus', 0);
|
||||
$this->SetTimerInterval('Meldezyklus', 0);
|
||||
$this->SetTimerInterval('RueckmeldungVerzoegert', 0);
|
||||
$this->SetValue('Verfuegbar', false);
|
||||
$this->SetValue('AenderungMoeglich', false);
|
||||
$this->setzeZustand('Verfuegbar', false);
|
||||
$this->setzeZustand('AenderungMoeglich', false);
|
||||
$this->SetStatus(self::STATUS_KONFIGURATION_UNGUELTIG);
|
||||
$this->protokolliere('Konfiguration', $fehler->getMessage());
|
||||
return;
|
||||
@@ -191,9 +182,6 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->ManagerdatenEmpfangen($daten);
|
||||
return;
|
||||
|
||||
case 'LogStatus':
|
||||
$this->protokolliereStatus(true);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Unbekannte Aktion: ' . $ident);
|
||||
@@ -222,7 +210,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->WriteAttributeInteger('LetzteManagerID', $managerID);
|
||||
$this->WriteAttributeInteger('LetzteVorgabeZeit', time());
|
||||
$this->SetValue('Sollleistung', $sollleistung);
|
||||
$this->SetValue('SollwertGueltig', true);
|
||||
$this->setzeZustand('SollwertGueltig', true);
|
||||
$this->regelzyklus(false);
|
||||
|
||||
// Verhindert eine synchrone Manager-Verbraucher-Endlosschleife.
|
||||
@@ -240,24 +228,24 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
[$angebot, $aenderungMoeglich, $verfuegbar, $zwangsleistung] =
|
||||
$this->bestimmeLeistungsangebot($temperaturGueltig, $jetzt);
|
||||
$this->WriteAttributeString('Leistungsangebot', json_encode($angebot, JSON_THROW_ON_ERROR));
|
||||
$this->SetValue('Verfuegbar', $verfuegbar);
|
||||
$this->SetValue('AenderungMoeglich', $aenderungMoeglich);
|
||||
$this->setzeZustand('Verfuegbar', $verfuegbar);
|
||||
$this->setzeZustand('AenderungMoeglich', $aenderungMoeglich);
|
||||
|
||||
$letzteVorgabe = $this->ReadAttributeInteger('LetzteVorgabeZeit');
|
||||
if ($letzteVorgabe <= 0
|
||||
|| $jetzt - $letzteVorgabe > $this->ReadPropertyInteger('VorgabeTimeout')
|
||||
) {
|
||||
$this->SetValue('SollwertGueltig', false);
|
||||
$this->setzeZustand('SollwertGueltig', false);
|
||||
}
|
||||
|
||||
$ziel = 0;
|
||||
if ($verfuegbar) {
|
||||
if ($zwangsleistung !== null) {
|
||||
$ziel = $zwangsleistung;
|
||||
} elseif ((bool) $this->GetValue('SollwertGueltig')) {
|
||||
} elseif ((bool) $this->leseZustand('SollwertGueltig')) {
|
||||
$ziel = (int) $this->GetValue('Sollleistung');
|
||||
if (!in_array($ziel, $angebot, true)) {
|
||||
$this->SetValue('SollwertGueltig', false);
|
||||
$this->setzeZustand('SollwertGueltig', false);
|
||||
$ziel = 0;
|
||||
}
|
||||
}
|
||||
@@ -271,8 +259,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
}
|
||||
} catch (Throwable $fehler) {
|
||||
$this->WriteAttributeString('Schaltfehler', $fehler->getMessage());
|
||||
$this->SetValue('Verfuegbar', false);
|
||||
$this->SetValue('AenderungMoeglich', false);
|
||||
$this->setzeZustand('Verfuegbar', false);
|
||||
$this->setzeZustand('AenderungMoeglich', false);
|
||||
$this->SetValue('Stoerung', true);
|
||||
$this->SetValue('Stoertext', $fehler->getMessage());
|
||||
$this->SetStatus(self::STATUS_SCHALTFEHLER);
|
||||
@@ -284,18 +272,18 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
{
|
||||
$fuehlerID = $this->ReadPropertyInteger('Boilerfuehler_PT1');
|
||||
if ($fuehlerID <= 0 || !IPS_VariableExists($fuehlerID)) {
|
||||
$this->SetValue('TemperaturGueltig', false);
|
||||
$this->setzeZustand('TemperaturGueltig', false);
|
||||
return false;
|
||||
}
|
||||
|
||||
$variable = IPS_GetVariable($fuehlerID);
|
||||
if (time() - (int) $variable['VariableUpdated'] > $this->ReadPropertyInteger('TemperaturMaxAlter')) {
|
||||
$this->SetValue('TemperaturGueltig', false);
|
||||
$this->setzeZustand('TemperaturGueltig', false);
|
||||
return false;
|
||||
}
|
||||
$rohwert = GetValue($fuehlerID);
|
||||
if (!is_int($rohwert) && !is_float($rohwert)) {
|
||||
$this->SetValue('TemperaturGueltig', false);
|
||||
$this->setzeZustand('TemperaturGueltig', false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -318,7 +306,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
}
|
||||
|
||||
$this->SetValue('Boilertemperatur', $temperatur);
|
||||
$this->SetValue('TemperaturGueltig', true);
|
||||
$this->setzeZustand('TemperaturGueltig', true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -330,7 +318,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
{
|
||||
$stufen = WarmwasserRegler::dekodiereLeistungsstufen($this->ReadPropertyString('LeistungsStufen'));
|
||||
if (!(bool) $this->GetValue('Aktiv') || !$temperaturGueltig || $stufen === []) {
|
||||
$this->SetValue('NachladenAktiv', false);
|
||||
$this->setzeZustand('NachladenAktiv', false);
|
||||
return [[], false, false, 0];
|
||||
}
|
||||
|
||||
@@ -339,16 +327,25 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$temperatur = (float) $this->GetValue('Boilertemperatur');
|
||||
$minimum = (float) $this->GetValue('Mindesttemperatur');
|
||||
$maximum = (float) $this->GetValue('Maximaltemperatur');
|
||||
[$minimum, $maximum] = WarmwasserRegler::legionellenTemperaturgrenzen(
|
||||
$this->ReadPropertyBoolean('LegionellenfunktionAktiv'),
|
||||
max(0, $jetzt - $this->ReadAttributeInteger('LetzterLegionellenabschluss')),
|
||||
$this->ReadPropertyInteger('LegionellenMinimalintervallTage'),
|
||||
$this->ReadPropertyInteger('LegionellenMaximalintervallTage'),
|
||||
$minimum,
|
||||
$maximum,
|
||||
(float) $this->GetValue('Legionellentemperatur')
|
||||
);
|
||||
$hysterese = $this->ReadPropertyFloat('Hysterese');
|
||||
$aktuelleLeistung = (int) round((float) $this->GetValue('Istleistung'));
|
||||
|
||||
$nachladen = (bool) $this->GetValue('NachladenAktiv');
|
||||
$nachladen = (bool) $this->leseZustand('NachladenAktiv');
|
||||
if ($temperatur < $minimum) {
|
||||
$nachladen = true;
|
||||
} elseif ($temperatur >= $minimum + $hysterese) {
|
||||
$nachladen = false;
|
||||
}
|
||||
$this->SetValue('NachladenAktiv', $nachladen);
|
||||
$this->setzeZustand('NachladenAktiv', $nachladen);
|
||||
|
||||
$zeitplanErfordertHeizen = false;
|
||||
$naechster = WarmwasserRegler::naechsterZeitplaneintrag(
|
||||
@@ -365,7 +362,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
);
|
||||
}
|
||||
|
||||
if ((bool) $this->GetValue('LegionellenbetriebAktiv') || $nachladen || $zeitplanErfordertHeizen) {
|
||||
if ($nachladen || $zeitplanErfordertHeizen) {
|
||||
return [[$maximalleistung], false, true, $maximalleistung];
|
||||
}
|
||||
if ($temperatur >= $maximum) {
|
||||
@@ -380,54 +377,21 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
|
||||
private function aktualisiereLegionellenstatus(bool $temperaturGueltig, int $jetzt): void
|
||||
{
|
||||
$aktiviert = $this->ReadPropertyBoolean('LegionellenfunktionAktiv');
|
||||
$letzterAbschluss = $this->ReadAttributeInteger('LetzterLegionellenabschluss');
|
||||
$this->SetValue('LegioCounter', max(0, $jetzt - $letzterAbschluss));
|
||||
$sekundenSeitAbschluss = max(0, $jetzt - $letzterAbschluss);
|
||||
|
||||
if (!$this->ReadPropertyBoolean('LegionellenfunktionAktiv')) {
|
||||
$this->SetValue('LegionellenbetriebAktiv', false);
|
||||
$this->WriteAttributeInteger('LegionellenStart', 0);
|
||||
$this->WriteAttributeInteger('LegionellenSeitZiel', 0);
|
||||
$this->WriteAttributeString('Legionellenfehler', '');
|
||||
return;
|
||||
}
|
||||
|
||||
$aktiv = (bool) $this->GetValue('LegionellenbetriebAktiv');
|
||||
$faellig = $jetzt - $letzterAbschluss >= $this->ReadPropertyInteger('LegionellenIntervallTage') * 86400;
|
||||
if (!$aktiv && $faellig && $this->istNachtstunde((int) date('G', $jetzt))) {
|
||||
$aktiv = true;
|
||||
$this->WriteAttributeInteger('LegionellenStart', $jetzt);
|
||||
$this->WriteAttributeInteger('LegionellenSeitZiel', 0);
|
||||
}
|
||||
|
||||
if ($aktiv && $jetzt - $this->ReadAttributeInteger('LegionellenStart')
|
||||
> $this->ReadPropertyInteger('LegionellenMaximaldauer')
|
||||
) {
|
||||
$aktiv = false;
|
||||
$this->WriteAttributeInteger('LetzterLegionellenabschluss', $jetzt);
|
||||
$this->WriteAttributeString(
|
||||
'Legionellenfehler',
|
||||
'Legionellenprogramm innerhalb der Maximaldauer nicht abgeschlossen.'
|
||||
);
|
||||
}
|
||||
|
||||
if ($aktiv && $temperaturGueltig
|
||||
if ($aktiviert && $temperaturGueltig
|
||||
&& (float) $this->GetValue('Boilertemperatur') >= (float) $this->GetValue('Legionellentemperatur')
|
||||
) {
|
||||
$seitZiel = $this->ReadAttributeInteger('LegionellenSeitZiel');
|
||||
if ($seitZiel <= 0) {
|
||||
$seitZiel = $jetzt;
|
||||
$this->WriteAttributeInteger('LegionellenSeitZiel', $seitZiel);
|
||||
}
|
||||
if ($jetzt - $seitZiel >= $this->ReadPropertyInteger('LegionellenHaltezeit')) {
|
||||
$aktiv = false;
|
||||
$this->WriteAttributeInteger('LetzterLegionellenabschluss', $jetzt);
|
||||
$this->WriteAttributeInteger('LegionellenStart', 0);
|
||||
$this->WriteAttributeInteger('LegionellenSeitZiel', 0);
|
||||
$this->WriteAttributeString('Legionellenfehler', '');
|
||||
}
|
||||
$this->WriteAttributeInteger('LetzterLegionellenabschluss', $jetzt);
|
||||
$sekundenSeitAbschluss = 0;
|
||||
}
|
||||
|
||||
$this->SetValue('LegionellenbetriebAktiv', $aktiv);
|
||||
$fruehestensFaellig = $aktiviert
|
||||
&& $sekundenSeitAbschluss >= $this->ReadPropertyInteger('LegionellenMinimalintervallTage') * 86400;
|
||||
$this->setzeZustand('LegioCounter', $sekundenSeitAbschluss);
|
||||
$this->setzeZustand('LegionellenbetriebAktiv', $fruehestensFaellig);
|
||||
}
|
||||
|
||||
private function schalteLeistung(int $zielLeistung): void
|
||||
@@ -468,7 +432,7 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
|
||||
$this->WriteAttributeString('Schaltfehler', '');
|
||||
$this->SetValue('Istleistung', (float) $zielLeistung);
|
||||
$this->SetValue('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
|
||||
$this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
|
||||
$this->SetValue('AktiveStufe', $zielStufe);
|
||||
$this->verarbeiteIdle(true);
|
||||
$this->protokolliere('Leistungsstufe', ['Leistung_W' => $zielLeistung, 'Stufe' => $zielStufe]);
|
||||
@@ -494,14 +458,14 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
|
||||
private function verarbeiteIdle(bool $geaendert): void
|
||||
{
|
||||
$counter = (int) $this->GetValue('IdleCounter');
|
||||
$counter = (int) $this->leseZustand('IdleCounter');
|
||||
if ($geaendert) {
|
||||
$counter = $this->ReadPropertyInteger('IdleCounterMax');
|
||||
} elseif ($counter > 0) {
|
||||
--$counter;
|
||||
}
|
||||
$this->SetValue('IdleCounter', $counter);
|
||||
$this->SetValue('Idle', $counter === 0);
|
||||
$this->setzeZustand('IdleCounter', $counter);
|
||||
$this->setzeZustand('Idle', $counter === 0);
|
||||
}
|
||||
|
||||
private function aktualisiereEnergie(int $jetzt): void
|
||||
@@ -537,10 +501,6 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
if ($this->ReadAttributeString('Schaltfehler') !== '') {
|
||||
$stoerungen[] = $this->ReadAttributeString('Schaltfehler');
|
||||
}
|
||||
if ($this->ReadAttributeString('Legionellenfehler') !== '') {
|
||||
$stoerungen[] = $this->ReadAttributeString('Legionellenfehler');
|
||||
}
|
||||
|
||||
$this->SetValue('Stoerung', $stoerungen !== []);
|
||||
$this->SetValue('Stoertext', implode("\n", array_values(array_unique($stoerungen))));
|
||||
if ($this->ReadAttributeString('Schaltfehler') !== '') {
|
||||
@@ -572,9 +532,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
/** @return array<string, mixed> */
|
||||
private function baueVerbraucherdaten(int $managerID): array
|
||||
{
|
||||
$temperaturGueltig = (bool) $this->GetValue('TemperaturGueltig');
|
||||
$temperaturGueltig = (bool) $this->leseZustand('TemperaturGueltig');
|
||||
$schaltfehler = $this->ReadAttributeString('Schaltfehler');
|
||||
$legionellenfehler = $this->ReadAttributeString('Legionellenfehler');
|
||||
$uebertemperatur = $temperaturGueltig
|
||||
&& (float) $this->GetValue('Boilertemperatur')
|
||||
> max(
|
||||
@@ -592,15 +551,15 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
'PrioritaetPV' => $this->ReadPropertyInteger('PrioritaetPV'),
|
||||
'PrioritaetPeak' => $this->ReadPropertyInteger('PrioritaetPeak'),
|
||||
'Leistungswerte_W' => $this->leseLeistungsangebot(),
|
||||
'AenderungMoeglich' => (bool) $this->GetValue('AenderungMoeglich'),
|
||||
'Verfuegbar' => (bool) $this->GetValue('Verfuegbar'),
|
||||
'AenderungMoeglich' => (bool) $this->leseZustand('AenderungMoeglich'),
|
||||
'Verfuegbar' => (bool) $this->leseZustand('Verfuegbar'),
|
||||
'Istleistung_W' => (float) $this->GetValue('Istleistung'),
|
||||
'Leistungsquelle' => Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET,
|
||||
'Zustand' => [
|
||||
[
|
||||
'Kennung' => 'Sollleistung_W',
|
||||
'Art' => 'Sollwert',
|
||||
'Wert' => (bool) $this->GetValue('SollwertGueltig')
|
||||
'Wert' => (bool) $this->leseZustand('SollwertGueltig')
|
||||
? (int) $this->GetValue('Sollleistung')
|
||||
: null,
|
||||
'Einheit' => 'W',
|
||||
@@ -626,13 +585,13 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
[
|
||||
'Kennung' => 'NachladenAktiv',
|
||||
'Art' => 'Status',
|
||||
'Wert' => (bool) $this->GetValue('NachladenAktiv'),
|
||||
'Wert' => (bool) $this->leseZustand('NachladenAktiv'),
|
||||
'Einheit' => '',
|
||||
],
|
||||
[
|
||||
'Kennung' => 'LegionellenbetriebAktiv',
|
||||
'Art' => 'Status',
|
||||
'Wert' => (bool) $this->GetValue('LegionellenbetriebAktiv'),
|
||||
'Wert' => (bool) $this->leseZustand('LegionellenbetriebAktiv'),
|
||||
'Einheit' => '',
|
||||
],
|
||||
[
|
||||
@@ -656,13 +615,6 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
'Einheit' => '',
|
||||
'Text' => $schaltfehler,
|
||||
],
|
||||
[
|
||||
'Kennung' => 'Legionellenfehler',
|
||||
'Art' => 'Stoerung',
|
||||
'Wert' => $legionellenfehler !== '',
|
||||
'Einheit' => '',
|
||||
'Text' => $legionellenfehler,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -709,25 +661,23 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
}
|
||||
foreach ([
|
||||
'Meldeintervall', 'VorgabeTimeout', 'Interval', 'IdleCounterMax', 'TemperaturMaxAlter',
|
||||
'ZeitKonstante', 'Boilervolumen', 'LegionellenIntervallTage', 'LegionellenMaximaldauer',
|
||||
'ZeitKonstante', 'Boilervolumen', 'LegionellenMinimalintervallTage',
|
||||
'LegionellenMaximalintervallTage',
|
||||
] as $property) {
|
||||
if ($this->ReadPropertyInteger($property) <= 0) {
|
||||
throw new InvalidArgumentException($property . ' muss groesser als 0 sein.');
|
||||
}
|
||||
}
|
||||
if ($this->ReadPropertyInteger('LegionellenHaltezeit') < 0) {
|
||||
throw new InvalidArgumentException('LegionellenHaltezeit darf nicht negativ sein.');
|
||||
if ($this->ReadPropertyInteger('LegionellenMinimalintervallTage')
|
||||
> $this->ReadPropertyInteger('LegionellenMaximalintervallTage')
|
||||
) {
|
||||
throw new InvalidArgumentException(
|
||||
'Das Legionellen-Minimalintervall darf nicht groesser als das Maximalintervall sein.'
|
||||
);
|
||||
}
|
||||
if ($this->ReadPropertyFloat('Hysterese') <= 0) {
|
||||
throw new InvalidArgumentException('Hysterese muss groesser als 0 sein.');
|
||||
}
|
||||
foreach (['NachtstartStunde', 'NachtendeStunde'] as $property) {
|
||||
$stunde = $this->ReadPropertyInteger($property);
|
||||
if ($stunde < 0 || $stunde > 23) {
|
||||
throw new InvalidArgumentException($property . ' muss zwischen 0 und 23 liegen.');
|
||||
}
|
||||
}
|
||||
|
||||
$minimum = (float) $this->GetValue('Mindesttemperatur');
|
||||
$maximum = (float) $this->GetValue('Maximaltemperatur');
|
||||
$legionellen = (float) $this->GetValue('Legionellentemperatur');
|
||||
@@ -786,8 +736,8 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->SetValue('Mindesttemperatur', 45.0);
|
||||
$this->SetValue('Maximaltemperatur', 60.0);
|
||||
$this->SetValue('Legionellentemperatur', 65.0);
|
||||
$this->SetValue('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
|
||||
$this->SetValue('Idle', true);
|
||||
$this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
|
||||
$this->setzeZustand('Idle', true);
|
||||
$this->WriteAttributeBoolean('InitialwerteGesetzt', true);
|
||||
}
|
||||
|
||||
@@ -823,11 +773,33 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
$this->regelzyklus(true);
|
||||
}
|
||||
|
||||
private function aktualisiereSichtbarkeit(): void
|
||||
private function aktualisiereVariablen(): void
|
||||
{
|
||||
$diagnose = $this->ReadPropertyBoolean('DiagnosevariablenAnzeigen');
|
||||
foreach (self::DIAGNOSE_VARIABLEN as $ident) {
|
||||
IPS_SetHidden($this->GetIDForIdent($ident), !$diagnose);
|
||||
if ($this->ReadPropertyBoolean('DiagnosevariablenAnzeigen')) {
|
||||
$this->registriereVerbraucherDiagnose();
|
||||
$this->RegisterVariableBoolean('TemperaturGueltig', 'Temperatur gueltig', '~Switch', 200);
|
||||
$this->RegisterVariableBoolean('NachladenAktiv', 'Nachladen aktiv', '~Switch', 210);
|
||||
$this->RegisterVariableBoolean(
|
||||
'LegionellenbetriebAktiv',
|
||||
'Legionellenbetrieb aktiv',
|
||||
'~Switch',
|
||||
220
|
||||
);
|
||||
$this->RegisterVariableInteger('LegioCounter', 'Zeit seit Legionellenabschluss', '', 230);
|
||||
$this->RegisterVariableBoolean('Idle', 'Idle', '~Switch', 240);
|
||||
$this->RegisterVariableInteger('IdleCounter', 'Idle Counter', '', 250);
|
||||
|
||||
$this->setzeZustand('Leistungsquelle', Nachrichtenvertrag::LEISTUNGSQUELLE_BERECHNET);
|
||||
foreach (array_slice(self::DIAGNOSE_VARIABLEN, 1) as $ident) {
|
||||
$this->setzeZustand($ident, $this->leseZustand($ident));
|
||||
}
|
||||
} else {
|
||||
foreach (self::DIAGNOSE_VARIABLEN as $ident) {
|
||||
$variablenID = @IPS_GetObjectIDByIdent($ident, $this->InstanceID);
|
||||
if (is_int($variablenID) && $variablenID > 0 && IPS_VariableExists($variablenID)) {
|
||||
$this->UnregisterVariable($ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$einstellungen = $this->ReadPropertyBoolean('EinstellungenInVisu');
|
||||
@@ -841,6 +813,66 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
}
|
||||
}
|
||||
|
||||
/** @param bool|int $wert */
|
||||
private function setzeZustand(string $ident, $wert): void
|
||||
{
|
||||
$booleanAttribute = [
|
||||
'SollwertGueltig' => 'ZustandSollwertGueltig',
|
||||
'Verfuegbar' => 'ZustandVerfuegbar',
|
||||
'AenderungMoeglich' => 'ZustandAenderungMoeglich',
|
||||
'TemperaturGueltig' => 'ZustandTemperaturGueltig',
|
||||
'NachladenAktiv' => 'ZustandNachladenAktiv',
|
||||
'LegionellenbetriebAktiv' => 'ZustandLegionellenbetriebAktiv',
|
||||
'Idle' => 'ZustandIdle',
|
||||
];
|
||||
$integerAttribute = [
|
||||
'LegioCounter' => 'ZustandLegioCounter',
|
||||
'IdleCounter' => 'ZustandIdleCounter',
|
||||
];
|
||||
|
||||
if (isset($booleanAttribute[$ident])) {
|
||||
$wert = (bool) $wert;
|
||||
$this->WriteAttributeBoolean($booleanAttribute[$ident], $wert);
|
||||
} elseif (isset($integerAttribute[$ident])) {
|
||||
$wert = (int) $wert;
|
||||
$this->WriteAttributeInteger($integerAttribute[$ident], $wert);
|
||||
} elseif ($ident !== 'Leistungsquelle') {
|
||||
throw new LogicException('Unbekannter interner Zustand: ' . $ident);
|
||||
}
|
||||
|
||||
$variablenID = @IPS_GetObjectIDByIdent($ident, $this->InstanceID);
|
||||
if (is_int($variablenID) && $variablenID > 0 && IPS_VariableExists($variablenID)) {
|
||||
SetValue($variablenID, $wert);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return bool|int */
|
||||
private function leseZustand(string $ident)
|
||||
{
|
||||
$booleanAttribute = [
|
||||
'SollwertGueltig' => 'ZustandSollwertGueltig',
|
||||
'Verfuegbar' => 'ZustandVerfuegbar',
|
||||
'AenderungMoeglich' => 'ZustandAenderungMoeglich',
|
||||
'TemperaturGueltig' => 'ZustandTemperaturGueltig',
|
||||
'NachladenAktiv' => 'ZustandNachladenAktiv',
|
||||
'LegionellenbetriebAktiv' => 'ZustandLegionellenbetriebAktiv',
|
||||
'Idle' => 'ZustandIdle',
|
||||
];
|
||||
$integerAttribute = [
|
||||
'LegioCounter' => 'ZustandLegioCounter',
|
||||
'IdleCounter' => 'ZustandIdleCounter',
|
||||
];
|
||||
|
||||
if (isset($booleanAttribute[$ident])) {
|
||||
return $this->ReadAttributeBoolean($booleanAttribute[$ident]);
|
||||
}
|
||||
if (isset($integerAttribute[$ident])) {
|
||||
return $this->ReadAttributeInteger($integerAttribute[$ident]);
|
||||
}
|
||||
|
||||
throw new LogicException('Unbekannter interner Zustand: ' . $ident);
|
||||
}
|
||||
|
||||
/** @return list<int> */
|
||||
private function leseLeistungsangebot(): array
|
||||
{
|
||||
@@ -852,37 +884,6 @@ class VerbraucherWarmwassererwaermer extends IPSModule implements VerbraucherSch
|
||||
return array_values(array_map('intval', $angebot));
|
||||
}
|
||||
|
||||
private function istNachtstunde(int $stunde): bool
|
||||
{
|
||||
$start = $this->ReadPropertyInteger('NachtstartStunde');
|
||||
$ende = $this->ReadPropertyInteger('NachtendeStunde');
|
||||
if ($start === $ende) {
|
||||
return true;
|
||||
}
|
||||
if ($start < $ende) {
|
||||
return $stunde >= $start && $stunde < $ende;
|
||||
}
|
||||
|
||||
return $stunde >= $start || $stunde < $ende;
|
||||
}
|
||||
|
||||
private function protokolliereStatus(bool $erzwingen): void
|
||||
{
|
||||
if (!$erzwingen && !$this->ReadPropertyBoolean('LoggingEin')) {
|
||||
return;
|
||||
}
|
||||
$this->SendDebug('Status', json_encode([
|
||||
'Aktiv' => (bool) $this->GetValue('Aktiv'),
|
||||
'Boilertemperatur_C' => (float) $this->GetValue('Boilertemperatur'),
|
||||
'TemperaturGueltig' => (bool) $this->GetValue('TemperaturGueltig'),
|
||||
'Leistungsangebot_W' => $this->leseLeistungsangebot(),
|
||||
'Sollleistung_W' => (int) $this->GetValue('Sollleistung'),
|
||||
'Istleistung_W' => (float) $this->GetValue('Istleistung'),
|
||||
'AktiveStufe' => (int) $this->GetValue('AktiveStufe'),
|
||||
'Stoertext' => (string) $this->GetValue('Stoertext'),
|
||||
], JSON_THROW_ON_ERROR), 0);
|
||||
}
|
||||
|
||||
/** @param mixed $daten */
|
||||
private function protokolliere(string $bezeichnung, $daten): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user