This commit is contained in:
+236
-137
@@ -1,159 +1,258 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "Select",
|
||||
"name": "Rolle",
|
||||
"caption": "Rolle",
|
||||
"options": [
|
||||
{"caption": "Alleine", "value": 0},
|
||||
{"caption": "Hauptmanager", "value": 1},
|
||||
{"caption": "Untermanager", "value": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "NetzleistungVariableID",
|
||||
"caption": "Netzleistung"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Netzleistungsfaktor",
|
||||
"caption": "Netzleistungsfaktor",
|
||||
"digits": 4
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MesswertMaxAlter",
|
||||
"caption": "Maximales Messwertalter",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "VerbraucherZuordnung",
|
||||
"caption": "Verbraucher",
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sortable": true,
|
||||
"columns": [
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Grundeinstellungen",
|
||||
"expanded": true,
|
||||
"items": [
|
||||
{
|
||||
"caption": "Instanz",
|
||||
"name": "InstanzID",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {"type": "SelectInstance"}
|
||||
"type": "Select",
|
||||
"name": "Rolle",
|
||||
"caption": "Rolle",
|
||||
"options": [
|
||||
{"caption": "Alleine", "value": 0},
|
||||
{"caption": "Hauptmanager", "value": 1},
|
||||
{"caption": "Untermanager", "value": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"caption": "Aktiv",
|
||||
"name": "Aktiv",
|
||||
"width": "100px",
|
||||
"type": "SelectVariable",
|
||||
"name": "NetzleistungVariableID",
|
||||
"caption": "Netzleistung"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "SollwertSolarladen",
|
||||
"caption": "Sollwert Solarladen",
|
||||
"suffix": " W",
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "Select",
|
||||
"name": "Lastspitzenmodus",
|
||||
"caption": "Lastspitzenmodus",
|
||||
"onChange": "IPS_RequestAction($id, 'FormLastspitzenmodus', $Lastspitzenmodus);",
|
||||
"options": [
|
||||
{"caption": "Aus", "value": 0},
|
||||
{"caption": "Konstant", "value": 1},
|
||||
{"caption": "Monatlich", "value": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Lastspitzengrenze",
|
||||
"caption": "Lastspitzengrenze",
|
||||
"suffix": " W",
|
||||
"digits": 1,
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "MonatsgrenzenUmschalten",
|
||||
"caption": "Monatsgrenzen anzeigen",
|
||||
"visible": false,
|
||||
"onClick": "IPS_RequestAction($id, 'FormMonatsgrenzenUmschalten', true);"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Monatsgrenzen",
|
||||
"caption": "Monatliche Lastspitzengrenzen",
|
||||
"rowCount": 12,
|
||||
"add": false,
|
||||
"edit": {"type": "CheckBox"}
|
||||
"delete": false,
|
||||
"sortable": false,
|
||||
"loadValuesFromConfiguration": false,
|
||||
"visible": false,
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Monat",
|
||||
"name": "Monat",
|
||||
"width": "auto",
|
||||
"save": true
|
||||
},
|
||||
{
|
||||
"caption": "Grenze",
|
||||
"name": "Grenze_W",
|
||||
"width": "180px",
|
||||
"save": true,
|
||||
"edit": {
|
||||
"type": "NumberSpinner",
|
||||
"suffix": " W",
|
||||
"digits": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Monatsnummer",
|
||||
"name": "MonatIndex",
|
||||
"width": "0px",
|
||||
"visible": false,
|
||||
"save": true
|
||||
}
|
||||
],
|
||||
"values": []
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "AutomatischeSuche",
|
||||
"caption": "Verbraucher automatisch suchen",
|
||||
"onChange": "IPS_RequestAction($id, 'FormAutomatischeSuche', $AutomatischeSuche);"
|
||||
},
|
||||
{
|
||||
"type": "SelectObject",
|
||||
"name": "SuchbereichID",
|
||||
"caption": "Suchbereich",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "VerbraucherZuordnung",
|
||||
"caption": "Verbraucher manuell auswaehlen",
|
||||
"rowCount": 6,
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sortable": true,
|
||||
"visible": false,
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Instanz",
|
||||
"name": "InstanzID",
|
||||
"width": "auto",
|
||||
"add": 0,
|
||||
"edit": {"type": "SelectInstance"}
|
||||
},
|
||||
{
|
||||
"caption": "Aktiv",
|
||||
"name": "Aktiv",
|
||||
"width": "100px",
|
||||
"add": false,
|
||||
"edit": {"type": "CheckBox"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "AutomatischeVerbraucherZuordnung",
|
||||
"caption": "Gefundene Verbraucher",
|
||||
"rowCount": 8,
|
||||
"add": false,
|
||||
"delete": false,
|
||||
"loadValuesFromConfiguration": false,
|
||||
"visible": true,
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Verbraucher",
|
||||
"name": "Name",
|
||||
"width": "auto",
|
||||
"save": true
|
||||
},
|
||||
{
|
||||
"caption": "Instanz-ID",
|
||||
"name": "InstanzID",
|
||||
"width": "100px",
|
||||
"save": true
|
||||
},
|
||||
{
|
||||
"caption": "Verwenden",
|
||||
"name": "Aktiv",
|
||||
"width": "100px",
|
||||
"save": true,
|
||||
"edit": {"type": "CheckBox"}
|
||||
}
|
||||
],
|
||||
"values": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "AutomatischeSuche",
|
||||
"caption": "Verbraucher automatisch suchen"
|
||||
},
|
||||
{
|
||||
"type": "SelectObject",
|
||||
"name": "SuchbereichID",
|
||||
"caption": "Suchbereich"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Regelintervall",
|
||||
"caption": "Regelintervall",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Vorgabeintervall",
|
||||
"caption": "Vorgabeintervall",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "VerbraucherTimeout",
|
||||
"caption": "Verbraucher-Timeout",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "Select",
|
||||
"name": "Lastspitzenmodus",
|
||||
"caption": "Lastspitzenmodus",
|
||||
"options": [
|
||||
{"caption": "Aus", "value": 0},
|
||||
{"caption": "Konstant", "value": 1},
|
||||
{"caption": "Monatlich", "value": 2}
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Erweiterte Einstellungen",
|
||||
"items": [
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "KeepAlive",
|
||||
"caption": "Keep alive",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "VerbraucherTimeout",
|
||||
"caption": "Verbraucher-Timeout",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "MesswertMaxAlter",
|
||||
"caption": "Maximales Messwertalter",
|
||||
"suffix": " s",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Umschaltdifferenz",
|
||||
"caption": "Mindestdifferenz vor Umschaltung",
|
||||
"suffix": " %",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Netzleistungsfaktor",
|
||||
"caption": "Netzleistungsfaktor",
|
||||
"digits": 4
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "LoggingEin",
|
||||
"caption": "Logging ein"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Lastspitzengrenze",
|
||||
"caption": "Lastspitzengrenze",
|
||||
"suffix": " W",
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "Monatsgrenzen",
|
||||
"caption": "Monatsgrenzen als JSON"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "MonatsgrenzenVisuBedienbar",
|
||||
"caption": "Monatsgrenzen in der Visualisierung bedienen"
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "SollwertSolarladen",
|
||||
"caption": "Sollwert Solarladen",
|
||||
"suffix": " W",
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "UmschaltschwelleUeberschuss",
|
||||
"caption": "Umschaltschwelle Ueberschuss",
|
||||
"suffix": " W",
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "UmschaltschwelleLastspitze",
|
||||
"caption": "Umschaltschwelle Lastspitze",
|
||||
"suffix": " W",
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "Umschaltdifferenz",
|
||||
"caption": "Mindestdifferenz vor Umschaltung",
|
||||
"suffix": " %",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"digits": 1
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Optionale obere Anschluesse",
|
||||
"caption": "Prognose / Forecast",
|
||||
"items": [
|
||||
{"type": "ValidationTextBox", "name": "PrognoseAnschluss", "caption": "Prognose / Forecast als JSON"},
|
||||
{"type": "ValidationTextBox", "name": "SDLAnschluss", "caption": "SDL / VGT als JSON"},
|
||||
{"type": "ValidationTextBox", "name": "LizenzAnschluss", "caption": "Lizenzierung als JSON"},
|
||||
{"type": "ValidationTextBox", "name": "StoermeldeAnschluss", "caption": "Stoerueberwachung als JSON"}
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "PrognoseAnschluss",
|
||||
"caption": "Konfiguration als JSON"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "LoggingEin",
|
||||
"caption": "Logging ein"
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "SDL / VGT",
|
||||
"items": [
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "SDLAnschluss",
|
||||
"caption": "Konfiguration als JSON"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Lizenzierung",
|
||||
"items": [
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "LizenzAnschluss",
|
||||
"caption": "Konfiguration als JSON"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "Stoerueberwachung",
|
||||
"items": [
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "StoermeldeAnschluss",
|
||||
"caption": "Konfiguration als JSON"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
|
||||
+275
-43
@@ -16,6 +16,13 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
private const STATUS_MESSWERT_UNGUELTIG = 201;
|
||||
private const STATUS_KONFIGURATION_UNGUELTIG = 202;
|
||||
private const VM_UPDATE = 10603;
|
||||
private const VERBRAUCHER_MODUL_IDS = [
|
||||
'{B7C54AF4-AD7D-4FE4-B75D-203693906251}',
|
||||
];
|
||||
private const MONATSNAMEN = [
|
||||
1 => 'Januar', 'Februar', 'Maerz', 'April', 'Mai', 'Juni',
|
||||
'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
|
||||
];
|
||||
|
||||
public function Create(): void
|
||||
{
|
||||
@@ -24,21 +31,18 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->RegisterPropertyInteger('Rolle', 0);
|
||||
$this->RegisterPropertyInteger('NetzleistungVariableID', 0);
|
||||
$this->RegisterPropertyFloat('Netzleistungsfaktor', 1.0);
|
||||
$this->RegisterPropertyInteger('MesswertMaxAlter', 30);
|
||||
$this->RegisterPropertyInteger('MesswertMaxAlter', 60);
|
||||
$this->RegisterPropertyString('VerbraucherZuordnung', '[]');
|
||||
$this->RegisterPropertyString('AutomatischeVerbraucherZuordnung', '[]');
|
||||
$this->RegisterPropertyBoolean('AutomatischeSuche', true);
|
||||
$this->RegisterPropertyInteger('SuchbereichID', 0);
|
||||
$this->RegisterPropertyInteger('Regelintervall', 2);
|
||||
$this->RegisterPropertyInteger('Vorgabeintervall', 10);
|
||||
$this->RegisterPropertyInteger('VerbraucherTimeout', 30);
|
||||
$this->RegisterPropertyInteger('KeepAlive', 60);
|
||||
$this->RegisterPropertyInteger('VerbraucherTimeout', 60);
|
||||
$this->RegisterPropertyInteger('Lastspitzenmodus', 0);
|
||||
$this->RegisterPropertyFloat('Lastspitzengrenze', 0.0);
|
||||
$this->RegisterPropertyString('Monatsgrenzen', $this->standardMonatsgrenzen());
|
||||
$this->RegisterPropertyBoolean('MonatsgrenzenVisuBedienbar', false);
|
||||
$this->RegisterPropertyFloat('SollwertSolarladen', 0.0);
|
||||
$this->RegisterPropertyFloat('UmschaltschwelleUeberschuss', 0.0);
|
||||
$this->RegisterPropertyFloat('UmschaltschwelleLastspitze', 0.0);
|
||||
$this->RegisterPropertyFloat('Umschaltdifferenz', 0.0);
|
||||
$this->RegisterPropertyFloat('Umschaltdifferenz', 5.0);
|
||||
$this->RegisterPropertyString('PrognoseAnschluss', '{}');
|
||||
$this->RegisterPropertyString('SDLAnschluss', '{}');
|
||||
$this->RegisterPropertyString('LizenzAnschluss', '{}');
|
||||
@@ -67,13 +71,11 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->RegisterAttributeString('LetzteSollwerte', '{}');
|
||||
$this->RegisterAttributeInteger('RegistrierteNetzleistungVariableID', 0);
|
||||
|
||||
// Die alten Timer bleiben deaktiviert registriert, damit bestehende Instanzen sauber migrieren.
|
||||
$this->RegisterTimer('Regelzyklus', 0, '');
|
||||
$this->RegisterTimer('VorgabenErneuern', 0, '');
|
||||
$this->RegisterTimer(
|
||||
'Regelzyklus',
|
||||
0,
|
||||
"IPS_RequestAction(\$_IPS['TARGET'], 'Regeln', false);"
|
||||
);
|
||||
$this->RegisterTimer(
|
||||
'VorgabenErneuern',
|
||||
'KeepAlive',
|
||||
0,
|
||||
"IPS_RequestAction(\$_IPS['TARGET'], 'Regeln', true);"
|
||||
);
|
||||
@@ -89,19 +91,82 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->SetStatus(self::STATUS_KONFIGURATION_UNGUELTIG);
|
||||
$this->SetTimerInterval('Regelzyklus', 0);
|
||||
$this->SetTimerInterval('VorgabenErneuern', 0);
|
||||
$this->SetTimerInterval('KeepAlive', 0);
|
||||
$this->protokolliere('Konfiguration', $fehler->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
$this->registriereNetzleistungsmeldung();
|
||||
$this->SetTimerInterval('Regelzyklus', $this->ReadPropertyInteger('Regelintervall') * 1000);
|
||||
$this->SetTimerInterval('VorgabenErneuern', $this->ReadPropertyInteger('Vorgabeintervall') * 1000);
|
||||
$this->SetTimerInterval('Regelzyklus', 0);
|
||||
$this->SetTimerInterval('VorgabenErneuern', 0);
|
||||
$this->SetTimerInterval('KeepAlive', $this->ReadPropertyInteger('KeepAlive') * 1000);
|
||||
$this->SetValue('Monatsgrenzen', $this->ReadPropertyString('Monatsgrenzen'));
|
||||
$this->aktualisiereSichtbarkeit();
|
||||
$this->aktualisiereAnschlussstatus();
|
||||
$this->SetStatus(self::STATUS_AKTIV);
|
||||
}
|
||||
|
||||
public function GetConfigurationForm(): string
|
||||
{
|
||||
$formular = json_decode(
|
||||
(string) file_get_contents(__DIR__ . '/form.json'),
|
||||
true,
|
||||
512,
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
$automatisch = $this->ReadPropertyBoolean('AutomatischeSuche');
|
||||
$lastspitzenmodus = $this->ReadPropertyInteger('Lastspitzenmodus');
|
||||
$monatsgrenzenSichtbar = $lastspitzenmodus === 2
|
||||
&& $this->GetBuffer('MonatsgrenzenSichtbar') === '1';
|
||||
|
||||
$this->setzeFormularParameter($formular['elements'], 'VerbraucherZuordnung', 'visible', !$automatisch);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'AutomatischeVerbraucherZuordnung',
|
||||
'visible',
|
||||
$automatisch
|
||||
);
|
||||
$this->setzeFormularParameter($formular['elements'], 'SuchbereichID', 'visible', $automatisch);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'AutomatischeVerbraucherZuordnung',
|
||||
'values',
|
||||
$this->automatischeVerbraucherFuerFormular()
|
||||
);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'Lastspitzengrenze',
|
||||
'visible',
|
||||
$lastspitzenmodus === 1
|
||||
);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'MonatsgrenzenUmschalten',
|
||||
'visible',
|
||||
$lastspitzenmodus === 2
|
||||
);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'MonatsgrenzenUmschalten',
|
||||
'caption',
|
||||
$monatsgrenzenSichtbar ? 'Monatsgrenzen ausblenden' : 'Monatsgrenzen anzeigen'
|
||||
);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'Monatsgrenzen',
|
||||
'visible',
|
||||
$monatsgrenzenSichtbar
|
||||
);
|
||||
$this->setzeFormularParameter(
|
||||
$formular['elements'],
|
||||
'Monatsgrenzen',
|
||||
'values',
|
||||
$this->monatsgrenzenFuerFormular()
|
||||
);
|
||||
|
||||
return json_encode($formular, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
public function MessageSink($zeitstempel, $senderID, $nachricht, $daten): void
|
||||
{
|
||||
if ((int) $senderID === $this->ReadPropertyInteger('NetzleistungVariableID')
|
||||
@@ -123,6 +188,39 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->regeln((bool) $wert);
|
||||
return;
|
||||
|
||||
case 'FormAutomatischeSuche':
|
||||
$automatisch = (bool) $wert;
|
||||
$this->UpdateFormField('VerbraucherZuordnung', 'visible', !$automatisch);
|
||||
$this->UpdateFormField('AutomatischeVerbraucherZuordnung', 'visible', $automatisch);
|
||||
$this->UpdateFormField('SuchbereichID', 'visible', $automatisch);
|
||||
return;
|
||||
|
||||
case 'FormLastspitzenmodus':
|
||||
$modus = (int) $wert;
|
||||
$this->UpdateFormField('Lastspitzengrenze', 'visible', $modus === 1);
|
||||
$this->UpdateFormField('MonatsgrenzenUmschalten', 'visible', $modus === 2);
|
||||
if ($modus !== 2) {
|
||||
$this->SetBuffer('MonatsgrenzenSichtbar', '0');
|
||||
$this->UpdateFormField('Monatsgrenzen', 'visible', false);
|
||||
$this->UpdateFormField(
|
||||
'MonatsgrenzenUmschalten',
|
||||
'caption',
|
||||
'Monatsgrenzen anzeigen'
|
||||
);
|
||||
}
|
||||
return;
|
||||
|
||||
case 'FormMonatsgrenzenUmschalten':
|
||||
$sichtbar = $this->GetBuffer('MonatsgrenzenSichtbar') !== '1';
|
||||
$this->SetBuffer('MonatsgrenzenSichtbar', $sichtbar ? '1' : '0');
|
||||
$this->UpdateFormField('Monatsgrenzen', 'visible', $sichtbar);
|
||||
$this->UpdateFormField(
|
||||
'MonatsgrenzenUmschalten',
|
||||
'caption',
|
||||
$sichtbar ? 'Monatsgrenzen ausblenden' : 'Monatsgrenzen anzeigen'
|
||||
);
|
||||
return;
|
||||
|
||||
case 'VerbraucherdatenEmpfangen':
|
||||
if (!is_string($wert)) {
|
||||
throw new InvalidArgumentException('Verbraucherdaten muessen als JSON uebergeben werden.');
|
||||
@@ -134,14 +232,6 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$this->VerbraucherdatenEmpfangen($daten);
|
||||
return;
|
||||
|
||||
case 'Monatsgrenzen':
|
||||
if (!$this->ReadPropertyBoolean('MonatsgrenzenVisuBedienbar')) {
|
||||
throw new RuntimeException('Monatsgrenzen sind in der Visualisierung nicht bedienbar.');
|
||||
}
|
||||
$this->dekodiereMonatsgrenzen((string) $wert);
|
||||
IPS_SetProperty($this->InstanceID, 'Monatsgrenzen', (string) $wert);
|
||||
IPS_ApplyChanges($this->InstanceID);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Unbekannte Aktion: ' . $ident);
|
||||
@@ -200,8 +290,6 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
$netzleistung,
|
||||
(string) $this->GetValue('Betriebsart'),
|
||||
$lastspitzengrenze !== null,
|
||||
$this->ReadPropertyFloat('UmschaltschwelleUeberschuss'),
|
||||
$this->ReadPropertyFloat('UmschaltschwelleLastspitze'),
|
||||
$this->ReadPropertyFloat('SollwertSolarladen'),
|
||||
$lastspitzengrenze ?? 0.0,
|
||||
$this->ReadPropertyFloat('Umschaltdifferenz')
|
||||
@@ -297,9 +385,30 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
/** @return list<int> */
|
||||
private function aktiveVerbraucherIDs(): array
|
||||
{
|
||||
$zuordnung = json_decode($this->ReadPropertyString('VerbraucherZuordnung'), true, 512, JSON_THROW_ON_ERROR);
|
||||
if (!$this->ReadPropertyBoolean('AutomatischeSuche')) {
|
||||
return $this->leseAktiveVerbraucherIDs('VerbraucherZuordnung');
|
||||
}
|
||||
|
||||
$gespeichert = json_decode(
|
||||
$this->ReadPropertyString('AutomatischeVerbraucherZuordnung'),
|
||||
true,
|
||||
512,
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
if ($gespeichert === []) {
|
||||
// Bestehende Installationen behalten ihre Auswahl, bis die neue Liste gespeichert wurde.
|
||||
return $this->leseAktiveVerbraucherIDs('VerbraucherZuordnung');
|
||||
}
|
||||
|
||||
return $this->leseAktiveVerbraucherIDs('AutomatischeVerbraucherZuordnung');
|
||||
}
|
||||
|
||||
/** @return list<int> */
|
||||
private function leseAktiveVerbraucherIDs(string $property): array
|
||||
{
|
||||
$zuordnung = json_decode($this->ReadPropertyString($property), true, 512, JSON_THROW_ON_ERROR);
|
||||
if (!is_array($zuordnung)) {
|
||||
throw new InvalidArgumentException('VerbraucherZuordnung muss eine JSON-Liste sein.');
|
||||
throw new InvalidArgumentException($property . ' muss eine JSON-Liste sein.');
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
@@ -319,6 +428,102 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
/** @return list<array{Name: string, InstanzID: int, Aktiv: bool}> */
|
||||
private function automatischeVerbraucherFuerFormular(): array
|
||||
{
|
||||
$gespeichert = json_decode(
|
||||
$this->ReadPropertyString('AutomatischeVerbraucherZuordnung'),
|
||||
true,
|
||||
512,
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
$ausgewaehlt = $gespeichert === []
|
||||
? $this->leseAktiveVerbraucherIDs('VerbraucherZuordnung')
|
||||
: $this->leseAktiveVerbraucherIDs('AutomatischeVerbraucherZuordnung');
|
||||
|
||||
$suchbereichID = $this->ReadPropertyInteger('SuchbereichID');
|
||||
$werte = [];
|
||||
foreach (self::VERBRAUCHER_MODUL_IDS as $modulID) {
|
||||
foreach (IPS_GetInstanceListByModuleID($modulID) as $instanzID) {
|
||||
if (!$this->istImSuchbereich($instanzID, $suchbereichID)) {
|
||||
continue;
|
||||
}
|
||||
$werte[] = [
|
||||
'Name' => IPS_GetName($instanzID),
|
||||
'InstanzID' => $instanzID,
|
||||
'Aktiv' => in_array($instanzID, $ausgewaehlt, true),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
usort($werte, static function (array $links, array $rechts): int {
|
||||
$nameVergleich = strcasecmp($links['Name'], $rechts['Name']);
|
||||
|
||||
return $nameVergleich !== 0
|
||||
? $nameVergleich
|
||||
: $links['InstanzID'] <=> $rechts['InstanzID'];
|
||||
});
|
||||
|
||||
return $werte;
|
||||
}
|
||||
|
||||
private function istImSuchbereich(int $objektID, int $suchbereichID): bool
|
||||
{
|
||||
if ($suchbereichID <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while ($objektID > 0) {
|
||||
if ($objektID === $suchbereichID) {
|
||||
return true;
|
||||
}
|
||||
$objektID = IPS_GetParent($objektID);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return list<array{Monat: string, Grenze_W: float, MonatIndex: int}> */
|
||||
private function monatsgrenzenFuerFormular(): array
|
||||
{
|
||||
$grenzen = $this->dekodiereMonatsgrenzen($this->ReadPropertyString('Monatsgrenzen'));
|
||||
$werte = [];
|
||||
foreach (self::MONATSNAMEN as $monat => $name) {
|
||||
$werte[] = [
|
||||
'Monat' => $name,
|
||||
'Grenze_W' => $grenzen[$monat],
|
||||
'MonatIndex' => $monat,
|
||||
];
|
||||
}
|
||||
|
||||
return $werte;
|
||||
}
|
||||
|
||||
/** @param list<array<string, mixed>> $elemente */
|
||||
private function setzeFormularParameter(
|
||||
array &$elemente,
|
||||
string $name,
|
||||
string $parameter,
|
||||
$wert
|
||||
): bool {
|
||||
foreach ($elemente as &$element) {
|
||||
if (($element['name'] ?? null) === $name) {
|
||||
$element[$parameter] = $wert;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (isset($element['items'])
|
||||
&& is_array($element['items'])
|
||||
&& $this->setzeFormularParameter($element['items'], $name, $parameter, $wert)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unset($element);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function sendeSollwert(int $instanzID, int $sollleistung): void
|
||||
{
|
||||
if (!IPS_InstanceExists($instanzID)) {
|
||||
@@ -381,13 +586,8 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
] as $ident) {
|
||||
IPS_SetHidden($this->GetIDForIdent($ident), !$logging);
|
||||
}
|
||||
$monatsgrenzenBedienbar = $logging && $this->ReadPropertyBoolean('MonatsgrenzenVisuBedienbar');
|
||||
IPS_SetHidden($this->GetIDForIdent('Monatsgrenzen'), !$monatsgrenzenBedienbar);
|
||||
if ($monatsgrenzenBedienbar) {
|
||||
$this->EnableAction('Monatsgrenzen');
|
||||
} else {
|
||||
$this->DisableAction('Monatsgrenzen');
|
||||
}
|
||||
IPS_SetHidden($this->GetIDForIdent('Monatsgrenzen'), true);
|
||||
$this->DisableAction('Monatsgrenzen');
|
||||
}
|
||||
|
||||
private function aktualisiereAnschlussstatus(): void
|
||||
@@ -406,7 +606,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
|
||||
private function pruefeKonfiguration(): void
|
||||
{
|
||||
foreach (['MesswertMaxAlter', 'Regelintervall', 'Vorgabeintervall', 'VerbraucherTimeout'] as $property) {
|
||||
foreach (['MesswertMaxAlter', 'KeepAlive', 'VerbraucherTimeout'] as $property) {
|
||||
if ($this->ReadPropertyInteger($property) <= 0) {
|
||||
throw new InvalidArgumentException($property . ' muss groesser als 0 sein.');
|
||||
}
|
||||
@@ -416,7 +616,8 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
) {
|
||||
throw new InvalidArgumentException('Umschaltdifferenz muss zwischen 0 und 100 liegen.');
|
||||
}
|
||||
$this->aktiveVerbraucherIDs();
|
||||
$this->leseAktiveVerbraucherIDs('VerbraucherZuordnung');
|
||||
$this->leseAktiveVerbraucherIDs('AutomatischeVerbraucherZuordnung');
|
||||
$this->dekodiereMonatsgrenzen($this->ReadPropertyString('Monatsgrenzen'));
|
||||
foreach (['PrognoseAnschluss', 'SDLAnschluss', 'LizenzAnschluss', 'StoermeldeAnschluss'] as $property) {
|
||||
$wert = json_decode($this->ReadPropertyString($property), true, 512, JSON_THROW_ON_ERROR);
|
||||
@@ -434,13 +635,35 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
throw new InvalidArgumentException('Monatsgrenzen muss ein JSON-Objekt sein.');
|
||||
}
|
||||
$ergebnis = [];
|
||||
for ($monat = 1; $monat <= 12; ++$monat) {
|
||||
$wert = $werte[(string) $monat] ?? $werte[$monat] ?? null;
|
||||
if (!is_int($wert) && !is_float($wert)) {
|
||||
throw new InvalidArgumentException('Monatsgrenzen muss fuer jeden Monat einen Zahlenwert enthalten.');
|
||||
if (isset($werte[0]) && is_array($werte[0])) {
|
||||
foreach ($werte as $eintrag) {
|
||||
if (!is_array($eintrag)) {
|
||||
throw new InvalidArgumentException('Monatsgrenzen muss eine Liste von Monatswerten sein.');
|
||||
}
|
||||
$monat = $eintrag['MonatIndex'] ?? null;
|
||||
$wert = $eintrag['Grenze_W'] ?? null;
|
||||
if (!is_int($monat) || $monat < 1 || $monat > 12
|
||||
|| (!is_int($wert) && !is_float($wert))
|
||||
) {
|
||||
throw new InvalidArgumentException('Jeder Monatswert benoetigt Monatsnummer und Grenze.');
|
||||
}
|
||||
$ergebnis[$monat] = (float) $wert;
|
||||
}
|
||||
} else {
|
||||
for ($monat = 1; $monat <= 12; ++$monat) {
|
||||
$wert = $werte[(string) $monat] ?? $werte[$monat] ?? null;
|
||||
if (!is_int($wert) && !is_float($wert)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Monatsgrenzen muss fuer jeden Monat einen Zahlenwert enthalten.'
|
||||
);
|
||||
}
|
||||
$ergebnis[$monat] = (float) $wert;
|
||||
}
|
||||
$ergebnis[$monat] = (float) $wert;
|
||||
}
|
||||
if (count($ergebnis) !== 12) {
|
||||
throw new InvalidArgumentException('Monatsgrenzen muss genau zwoelf Monatswerte enthalten.');
|
||||
}
|
||||
ksort($ergebnis);
|
||||
|
||||
return $ergebnis;
|
||||
}
|
||||
@@ -455,7 +678,16 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
||||
|
||||
private function standardMonatsgrenzen(): string
|
||||
{
|
||||
return json_encode(array_fill_keys(range(1, 12), 0), JSON_THROW_ON_ERROR);
|
||||
$werte = [];
|
||||
foreach (self::MONATSNAMEN as $monat => $name) {
|
||||
$werte[] = [
|
||||
'Monat' => $name,
|
||||
'Grenze_W' => 0.0,
|
||||
'MonatIndex' => $monat,
|
||||
];
|
||||
}
|
||||
|
||||
return json_encode($werte, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
/** @param mixed $daten */
|
||||
|
||||
Reference in New Issue
Block a user