feat(manager): add gated short-lease V4 control trial and local fallback
This commit is contained in:
+45
-3
@@ -6,6 +6,7 @@ require_once __DIR__ . '/../libs/VerbraucherSchnittstelle.php';
|
||||
require_once __DIR__ . '/../libs/VerbraucherBasisTrait.php';
|
||||
require_once __DIR__ . '/../libs/Nachrichtenvertrag.php';
|
||||
require_once __DIR__ . '/../libs/BatterieRegler.php';
|
||||
require_once __DIR__ . '/../libs/BatterieNetzfahrplanV4TestTrait.php';
|
||||
|
||||
use Belevo\EnelixEMS\BatterieRegler;
|
||||
use Belevo\EnelixEMS\Nachrichtenvertrag;
|
||||
@@ -15,6 +16,7 @@ use Belevo\EnelixEMS\VerbraucherSchnittstelle;
|
||||
class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
{
|
||||
use VerbraucherBasisTrait;
|
||||
use \Belevo\EnelixEMS\BatterieNetzfahrplanV4TestTrait;
|
||||
|
||||
private const MANAGER_MODULE_ID = '{6F771B18-59D4-4C8A-B951-3B2FE9F6A2C4}';
|
||||
private const STATUS_AKTIV = 102;
|
||||
@@ -68,6 +70,7 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
parent::Create();
|
||||
|
||||
$this->registriereVerbraucherBasis();
|
||||
$this->registriereV4BatterieTest();
|
||||
$this->RegisterPropertyInteger('Batterietyp', BatterieRegler::TYP_UNKONFIGURIERT);
|
||||
$this->RegisterPropertyInteger(
|
||||
'Batteriemanagement',
|
||||
@@ -152,6 +155,7 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
|
||||
$this->V4BatterieTestStoppen();
|
||||
$this->aktualisiereVariablen();
|
||||
$this->registriereMesswertmeldungen();
|
||||
$this->WriteAttributeBoolean('RegisterInitialisiert', false);
|
||||
@@ -248,7 +252,22 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
$this->aktualisiere(true);
|
||||
return;
|
||||
|
||||
case 'NetzfahrplanV4TestStart':
|
||||
if (!is_string($wert)) throw new InvalidArgumentException('JSON-Testanmeldung erforderlich.');
|
||||
$this->V4BatterieTestStarten($wert);
|
||||
return;
|
||||
case 'NetzfahrplanV4TestCommand':
|
||||
if (!is_string($wert)) throw new InvalidArgumentException('JSON-Testbefehl erforderlich.');
|
||||
$this->V4BatterieTestBefehl($wert);
|
||||
return;
|
||||
case 'NetzfahrplanV4TestStop':
|
||||
$this->V4BatterieTestStoppen();
|
||||
return;
|
||||
case 'NetzfahrplanV4TestWatchdog':
|
||||
$this->aktualisiere(true);
|
||||
return;
|
||||
case 'SichererZustand':
|
||||
$this->V4BatterieTestStoppen();
|
||||
$this->setzeZustand('SollwertGueltig', false);
|
||||
$this->schreibeRegister(0, true);
|
||||
$this->aktualisiere(true);
|
||||
@@ -287,6 +306,14 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
|
||||
/** @param array<string, mixed> $daten */
|
||||
public function ManagerdatenEmpfangen(array $daten): void
|
||||
{
|
||||
$lock = 'ENELIX.V4.Battery.' . $this->InstanceID;
|
||||
if (!IPS_SemaphoreEnter($lock, 1000)) throw new RuntimeException('Batterieannahme beschaeftigt.');
|
||||
try { $this->ManagerdatenEmpfangenIntern($daten); }
|
||||
finally { IPS_SemaphoreLeave($lock); }
|
||||
}
|
||||
|
||||
private function ManagerdatenEmpfangenIntern(array $daten): void
|
||||
{
|
||||
Nachrichtenvertrag::pruefeManagerdaten($daten);
|
||||
if ($daten['Kopf']['EmpfaengerID'] !== $this->InstanceID) {
|
||||
@@ -302,8 +329,13 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->v4BatterieTestAktiv()) {
|
||||
// Ordinary manager messages cannot overwrite or renew the independent short test lease.
|
||||
$this->planeMeldung();
|
||||
return;
|
||||
}
|
||||
$this->WriteAttributeString('Betriebsart', $daten['Betriebsart']);
|
||||
$this->aktualisiere(false);
|
||||
$this->aktualisiereIntern(false);
|
||||
|
||||
$sollleistung = $daten['Sollleistung_W'];
|
||||
if ($sollleistung === null) {
|
||||
@@ -314,7 +346,7 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
)
|
||||
) {
|
||||
$this->setzeZustand('SollwertGueltig', false);
|
||||
$this->aktualisiere(false);
|
||||
$this->aktualisiereIntern(false);
|
||||
}
|
||||
$this->planeMeldung();
|
||||
return;
|
||||
@@ -341,11 +373,19 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
$this->setzeZustand('Sollleistung', $sollleistung);
|
||||
$this->setzeZustand('SollwertGueltig', true);
|
||||
$this->planeVorgabeTimeout(time());
|
||||
$this->aktualisiere(false);
|
||||
$this->aktualisiereIntern(false);
|
||||
$this->planeMeldung();
|
||||
}
|
||||
|
||||
private function aktualisiere(bool $meldungPlanen): void
|
||||
{
|
||||
$lock = 'ENELIX.V4.Battery.' . $this->InstanceID;
|
||||
if (!IPS_SemaphoreEnter($lock, 0)) return;
|
||||
try { $this->aktualisiereIntern($meldungPlanen); }
|
||||
finally { IPS_SemaphoreLeave($lock); }
|
||||
}
|
||||
|
||||
private function aktualisiereIntern(bool $meldungPlanen): void
|
||||
{
|
||||
try {
|
||||
$jetzt = time();
|
||||
@@ -426,6 +466,8 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
||||
$ziel = $verfuegbar && (bool) $this->leseZustand('SollwertGueltig')
|
||||
? (int) $this->leseZustand('Sollleistung')
|
||||
: 0;
|
||||
$v4Ziel = $this->v4BatterieTestZiel($messwerte, $verfuegbar, $jetzt);
|
||||
if ($v4Ziel !== null) $ziel = $v4Ziel;
|
||||
$this->schreibeRegister($ziel, false);
|
||||
$this->setzeZustand('Sollleistung', $ziel);
|
||||
$this->setzeZustand('Verfuegbar', $verfuegbar);
|
||||
|
||||
Reference in New Issue
Block a user