This commit is contained in:
@@ -100,6 +100,7 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
|
|||||||
$this->RegisterAttributeInteger('PhasenerkennungSeit', 0);
|
$this->RegisterAttributeInteger('PhasenerkennungSeit', 0);
|
||||||
$this->RegisterAttributeInteger('PhasenerkennungVersion', 0);
|
$this->RegisterAttributeInteger('PhasenerkennungVersion', 0);
|
||||||
$this->RegisterAttributeBoolean('LadeleistungSeitFreigabeErkannt', false);
|
$this->RegisterAttributeBoolean('LadeleistungSeitFreigabeErkannt', false);
|
||||||
|
$this->RegisterAttributeInteger('GeraeteMaximalstrom', 32);
|
||||||
$this->RegisterAttributeInteger('ErkannterMaximalstrom', 32);
|
$this->RegisterAttributeInteger('ErkannterMaximalstrom', 32);
|
||||||
$this->RegisterAttributeInteger('FahrzeugstromKandidat', 0);
|
$this->RegisterAttributeInteger('FahrzeugstromKandidat', 0);
|
||||||
$this->RegisterAttributeInteger('FahrzeugstromKandidatSeit', 0);
|
$this->RegisterAttributeInteger('FahrzeugstromKandidatSeit', 0);
|
||||||
@@ -236,7 +237,6 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
|
|||||||
if ((bool) $wert) {
|
if ((bool) $wert) {
|
||||||
$this->SetTimerInterval('RueckmeldungVerzoegert', 0);
|
$this->SetTimerInterval('RueckmeldungVerzoegert', 0);
|
||||||
}
|
}
|
||||||
$this->aktualisiere(false);
|
|
||||||
$this->sendeVerbraucherdaten();
|
$this->sendeVerbraucherdaten();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -315,6 +315,7 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
|
|||||||
$phasenzahl = $this->ReadAttributeInteger('ZustandPhasenzahl');
|
$phasenzahl = $this->ReadAttributeInteger('ZustandPhasenzahl');
|
||||||
$maximalstrom = min(
|
$maximalstrom = min(
|
||||||
$this->ReadPropertyInteger('MaximalerLadestrom'),
|
$this->ReadPropertyInteger('MaximalerLadestrom'),
|
||||||
|
max(6, $this->ReadAttributeInteger('GeraeteMaximalstrom')),
|
||||||
max(6, $this->ReadAttributeInteger('ErkannterMaximalstrom'))
|
max(6, $this->ReadAttributeInteger('ErkannterMaximalstrom'))
|
||||||
);
|
);
|
||||||
$this->setzeSichtbareVariable('FahrzeugMaximalstrom', $maximalstrom);
|
$this->setzeSichtbareVariable('FahrzeugMaximalstrom', $maximalstrom);
|
||||||
@@ -423,6 +424,15 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
|
|||||||
$this->ReadPropertyInteger('Geraetetyp'),
|
$this->ReadPropertyInteger('Geraetetyp'),
|
||||||
$antwort
|
$antwort
|
||||||
);
|
);
|
||||||
|
if (isset($rohstatus['Sollstrom_A'])) {
|
||||||
|
$geraeteSollstrom = (int) $rohstatus['Sollstrom_A'];
|
||||||
|
if ($geraeteSollstrom === 0 || ($geraeteSollstrom >= 6 && $geraeteSollstrom <= 32)) {
|
||||||
|
$this->WriteAttributeInteger('LetzterGesetzterStrom', $geraeteSollstrom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($rohstatus['Maximalstrom_A'])) {
|
||||||
|
$this->WriteAttributeInteger('GeraeteMaximalstrom', (int) $rohstatus['Maximalstrom_A']);
|
||||||
|
}
|
||||||
|
|
||||||
$warVerbunden = $this->ReadAttributeBoolean('ZustandFahrzeugVerbunden');
|
$warVerbunden = $this->ReadAttributeBoolean('ZustandFahrzeugVerbunden');
|
||||||
$verbunden = $rohstatus['Rohstatus'] !== 1;
|
$verbunden = $rohstatus['Rohstatus'] !== 1;
|
||||||
|
|||||||
+15
-3
@@ -219,6 +219,11 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
0,
|
0,
|
||||||
"IPS_RequestAction(\$_IPS['TARGET'], 'Regeln', true);"
|
"IPS_RequestAction(\$_IPS['TARGET'], 'Regeln', true);"
|
||||||
);
|
);
|
||||||
|
$this->RegisterTimer(
|
||||||
|
'RegelungVerzoegert',
|
||||||
|
0,
|
||||||
|
"IPS_RequestAction(\$_IPS['TARGET'], 'RegelnVerzoegert', false);"
|
||||||
|
);
|
||||||
$this->RegisterTimer(
|
$this->RegisterTimer(
|
||||||
'PrognoseSenden',
|
'PrognoseSenden',
|
||||||
0,
|
0,
|
||||||
@@ -252,6 +257,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
$this->SetTimerInterval('Regelzyklus', 0);
|
$this->SetTimerInterval('Regelzyklus', 0);
|
||||||
$this->SetTimerInterval('VorgabenErneuern', 0);
|
$this->SetTimerInterval('VorgabenErneuern', 0);
|
||||||
$this->SetTimerInterval('KeepAlive', 0);
|
$this->SetTimerInterval('KeepAlive', 0);
|
||||||
|
$this->SetTimerInterval('RegelungVerzoegert', 0);
|
||||||
$this->SetTimerInterval('PrognoseSenden', 0);
|
$this->SetTimerInterval('PrognoseSenden', 0);
|
||||||
$this->SetTimerInterval('StoerungenSenden', 0);
|
$this->SetTimerInterval('StoerungenSenden', 0);
|
||||||
$this->SetTimerInterval('MesswerteAufzeichnen', 0);
|
$this->SetTimerInterval('MesswerteAufzeichnen', 0);
|
||||||
@@ -263,6 +269,7 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
$this->SetTimerInterval('Regelzyklus', 0);
|
$this->SetTimerInterval('Regelzyklus', 0);
|
||||||
$this->SetTimerInterval('VorgabenErneuern', 0);
|
$this->SetTimerInterval('VorgabenErneuern', 0);
|
||||||
$this->SetTimerInterval('KeepAlive', $this->ReadPropertyInteger('KeepAlive') * 1000);
|
$this->SetTimerInterval('KeepAlive', $this->ReadPropertyInteger('KeepAlive') * 1000);
|
||||||
|
$this->SetTimerInterval('RegelungVerzoegert', 0);
|
||||||
$this->SetTimerInterval('PrognoseSenden', 0);
|
$this->SetTimerInterval('PrognoseSenden', 0);
|
||||||
$this->SetTimerInterval(
|
$this->SetTimerInterval(
|
||||||
'StoerungenSenden',
|
'StoerungenSenden',
|
||||||
@@ -456,6 +463,11 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
$this->regeln((bool) $wert);
|
$this->regeln((bool) $wert);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 'RegelnVerzoegert':
|
||||||
|
$this->SetTimerInterval('RegelungVerzoegert', 0);
|
||||||
|
$this->regeln(false);
|
||||||
|
return;
|
||||||
|
|
||||||
case 'PrognoseSenden':
|
case 'PrognoseSenden':
|
||||||
$this->sendePrognoseTelemetrie();
|
$this->sendePrognoseTelemetrie();
|
||||||
return;
|
return;
|
||||||
@@ -624,9 +636,9 @@ class Manager extends IPSModule implements ManagerSchnittstelle
|
|||||||
$this->WriteAttributeString('VerbraucherCache', json_encode($cache, JSON_THROW_ON_ERROR));
|
$this->WriteAttributeString('VerbraucherCache', json_encode($cache, JSON_THROW_ON_ERROR));
|
||||||
$this->aktualisiereEnergieflusswerte();
|
$this->aktualisiereEnergieflusswerte();
|
||||||
$this->aktualisiereDiagrammMesswerte();
|
$this->aktualisiereDiagrammMesswerte();
|
||||||
if ($this->GetBuffer('VerbraucherSynchronisierungAktiv') !== '1') {
|
|
||||||
$this->regeln(false);
|
// Den synchronen Rueckruf in die noch meldende Verbraucherinstanz vermeiden.
|
||||||
}
|
$this->SetTimerInterval('RegelungVerzoegert', 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param array<string, mixed> $daten */
|
/** @param array<string, mixed> $daten */
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ final class LadestationAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{Rohstatus: int, Istleistung_W: float, Iststrom_A?: float, Phasenzahl?: int}
|
* @return array{Rohstatus: int, Istleistung_W: float, Sollstrom_A?: int, Maximalstrom_A?: int, Iststrom_A?: float, Phasenzahl?: int}
|
||||||
*/
|
*/
|
||||||
public static function dekodiereStatus(int $geraetetyp, string $antwort): array
|
public static function dekodiereStatus(int $geraetetyp, string $antwort): array
|
||||||
{
|
{
|
||||||
@@ -115,6 +115,20 @@ final class LadestationAdapter
|
|||||||
'Rohstatus' => (int) $daten['car'],
|
'Rohstatus' => (int) $daten['car'],
|
||||||
'Istleistung_W' => (float) $daten['nrg'][11] * $leistungsfaktor,
|
'Istleistung_W' => (float) $daten['nrg'][11] * $leistungsfaktor,
|
||||||
];
|
];
|
||||||
|
if (isset($daten['amp']) && is_numeric($daten['amp'])) {
|
||||||
|
$sollstrom = (int) $daten['amp'];
|
||||||
|
$freigabeEntzogen = isset($daten['alw']) && $daten['alw'] === false;
|
||||||
|
$erzwungenAus = $geraetetyp === self::GO_E_GEMINI
|
||||||
|
&& isset($daten['frc'])
|
||||||
|
&& (int) $daten['frc'] === 1;
|
||||||
|
$status['Sollstrom_A'] = $freigabeEntzogen || $erzwungenAus ? 0 : $sollstrom;
|
||||||
|
}
|
||||||
|
if (isset($daten['ama']) && is_numeric($daten['ama'])) {
|
||||||
|
$maximalstrom = (int) $daten['ama'];
|
||||||
|
if ($maximalstrom >= 6 && $maximalstrom <= 32) {
|
||||||
|
$status['Maximalstrom_A'] = $maximalstrom;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (isset($daten['nrg'][4], $daten['nrg'][5], $daten['nrg'][6])
|
if (isset($daten['nrg'][4], $daten['nrg'][5], $daten['nrg'][6])
|
||||||
&& is_numeric($daten['nrg'][4])
|
&& is_numeric($daten['nrg'][4])
|
||||||
&& is_numeric($daten['nrg'][5])
|
&& is_numeric($daten['nrg'][5])
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ final class LadestationAdapterTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider statusFaelle
|
* @dataProvider statusFaelle
|
||||||
* @param array<string, string> $konfiguration
|
* @param array<string, string> $konfiguration
|
||||||
* @param array{Rohstatus: int, Istleistung_W: float, Iststrom_A?: float, Phasenzahl?: int} $erwartet
|
* @param array{Rohstatus: int, Istleistung_W: float, Sollstrom_A?: int, Maximalstrom_A?: int, Iststrom_A?: float, Phasenzahl?: int} $erwartet
|
||||||
*/
|
*/
|
||||||
public function testStatusaufrufUndDekodierungFuerAlleGeraete(
|
public function testStatusaufrufUndDekodierungFuerAlleGeraete(
|
||||||
int $geraetetyp,
|
int $geraetetyp,
|
||||||
@@ -52,6 +52,8 @@ final class LadestationAdapterTest extends TestCase
|
|||||||
[
|
[
|
||||||
'Rohstatus' => 2,
|
'Rohstatus' => 2,
|
||||||
'Istleistung_W' => 11000.0,
|
'Istleistung_W' => 11000.0,
|
||||||
|
'Sollstrom_A' => 16,
|
||||||
|
'Maximalstrom_A' => 16,
|
||||||
'Iststrom_A' => 16.0,
|
'Iststrom_A' => 16.0,
|
||||||
'Phasenzahl' => 3,
|
'Phasenzahl' => 3,
|
||||||
],
|
],
|
||||||
@@ -64,6 +66,8 @@ final class LadestationAdapterTest extends TestCase
|
|||||||
[
|
[
|
||||||
'Rohstatus' => 2,
|
'Rohstatus' => 2,
|
||||||
'Istleistung_W' => 2300.0,
|
'Istleistung_W' => 2300.0,
|
||||||
|
'Sollstrom_A' => 16,
|
||||||
|
'Maximalstrom_A' => 16,
|
||||||
'Iststrom_A' => 9.8,
|
'Iststrom_A' => 9.8,
|
||||||
'Phasenzahl' => 1,
|
'Phasenzahl' => 1,
|
||||||
],
|
],
|
||||||
@@ -81,6 +85,20 @@ final class LadestationAdapterTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGoEAusFreigabeWirdAlsNullSollstromDekodiert(): void
|
||||||
|
{
|
||||||
|
$daten = json_decode($this->goEAntwort(2, 0, [0, 0, 0]), true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
$daten['alw'] = false;
|
||||||
|
$daten['frc'] = 1;
|
||||||
|
|
||||||
|
$status = LadestationAdapter::dekodiereStatus(
|
||||||
|
LadestationAdapter::GO_E_GEMINI,
|
||||||
|
json_encode($daten, JSON_THROW_ON_ERROR)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertSame(0, $status['Sollstrom_A']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider steuerFaelle
|
* @dataProvider steuerFaelle
|
||||||
* @param array<string, string> $konfiguration
|
* @param array<string, string> $konfiguration
|
||||||
@@ -180,6 +198,13 @@ final class LadestationAdapterTest extends TestCase
|
|||||||
}
|
}
|
||||||
$nrg[11] = $leistung;
|
$nrg[11] = $leistung;
|
||||||
|
|
||||||
return json_encode(['car' => $status, 'nrg' => $nrg], JSON_THROW_ON_ERROR);
|
return json_encode([
|
||||||
|
'car' => $status,
|
||||||
|
'nrg' => $nrg,
|
||||||
|
'amp' => 16,
|
||||||
|
'ama' => 16,
|
||||||
|
'alw' => true,
|
||||||
|
'frc' => 2,
|
||||||
|
], JSON_THROW_ON_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,4 +104,32 @@ final class LadestationStandAloneModulstrukturTest extends TestCase
|
|||||||
self::assertStringContainsString('PHASENERKENNUNGSSTROM = 6', $modul);
|
self::assertStringContainsString('PHASENERKENNUNGSSTROM = 6', $modul);
|
||||||
self::assertStringContainsString('UnregisterVariable($ident)', $modul);
|
self::assertStringContainsString('UnregisterVariable($ident)', $modul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMeldezyklusSendetDenBereitsGelesenenZustandOhneZusaetzlichenHttpAbruf(): void
|
||||||
|
{
|
||||||
|
$modul = (string) file_get_contents(self::MODULPFAD . 'module.php');
|
||||||
|
self::assertSame(1, preg_match(
|
||||||
|
"/case 'Melden':(?<block>.*?)case 'ManagerdatenEmpfangen':/s",
|
||||||
|
$modul,
|
||||||
|
$treffer
|
||||||
|
));
|
||||||
|
self::assertStringContainsString('$this->sendeVerbraucherdaten();', $treffer['block']);
|
||||||
|
self::assertStringNotContainsString('$this->aktualisiere(', $treffer['block']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testVomGeraetBestaetigterSollstromWirdFuerWiederholungVerwendet(): void
|
||||||
|
{
|
||||||
|
$modul = (string) file_get_contents(self::MODULPFAD . 'module.php');
|
||||||
|
|
||||||
|
self::assertStringContainsString("\$rohstatus['Sollstrom_A']", $modul);
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"WriteAttributeInteger('LetzterGesetzterStrom', \$geraeteSollstrom)",
|
||||||
|
$modul
|
||||||
|
);
|
||||||
|
self::assertStringContainsString("RegisterAttributeInteger('GeraeteMaximalstrom', 32)", $modul);
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"WriteAttributeInteger('GeraeteMaximalstrom', (int) \$rohstatus['Maximalstrom_A'])",
|
||||||
|
$modul
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -380,4 +380,25 @@ final class ManagerModulstrukturTest extends TestCase
|
|||||||
self::assertStringContainsString('VerbraucherdatenEmpfangen(array $daten)', $inhalt);
|
self::assertStringContainsString('VerbraucherdatenEmpfangen(array $daten)', $inhalt);
|
||||||
self::assertStringContainsString("'ManagerdatenEmpfangen'", $inhalt);
|
self::assertStringContainsString("'ManagerdatenEmpfangen'", $inhalt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testVerbrauchermeldungPlantRegelungOhneSynchronenRueckruf(): void
|
||||||
|
{
|
||||||
|
$inhalt = (string) file_get_contents(__DIR__ . '/../Manager/module.php');
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"RegisterTimer(\n 'RegelungVerzoegert'",
|
||||||
|
$inhalt
|
||||||
|
);
|
||||||
|
self::assertStringContainsString("case 'RegelnVerzoegert':", $inhalt);
|
||||||
|
self::assertSame(1, preg_match(
|
||||||
|
'/public function VerbraucherdatenEmpfangen\(array \$daten\): void(?<block>.*?)'
|
||||||
|
. 'private function aktualisiereVerbraucherEnergie/s',
|
||||||
|
$inhalt,
|
||||||
|
$treffer
|
||||||
|
));
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"SetTimerInterval('RegelungVerzoegert', 100)",
|
||||||
|
$treffer['block']
|
||||||
|
);
|
||||||
|
self::assertStringNotContainsString('$this->regeln(false);', $treffer['block']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user