224 lines
6.9 KiB
PHP
224 lines
6.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Belevo\EnelixEMS\Tests;
|
|
|
|
use Belevo\EnelixEMS\ManagerRegler;
|
|
use Belevo\EnelixEMS\Nachrichtenvertrag;
|
|
use InvalidArgumentException;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class ManagerReglerTest extends TestCase
|
|
{
|
|
public function testOhnePeakBegrenzungBleibtSolarladenAktiv(): void
|
|
{
|
|
self::assertSame(
|
|
ManagerRegler::BETRIEBSART_PV,
|
|
ManagerRegler::bestimmeBetriebsart(
|
|
true,
|
|
true,
|
|
25000.0,
|
|
ManagerRegler::BETRIEBSART_INAKTIV,
|
|
false,
|
|
0.0,
|
|
15000.0,
|
|
0.0
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testBetriebsartBleibtZwischenDenZielwertenErhalten(): void
|
|
{
|
|
self::assertSame(
|
|
ManagerRegler::BETRIEBSART_PEAK,
|
|
ManagerRegler::bestimmeBetriebsart(
|
|
true,
|
|
true,
|
|
5000.0,
|
|
ManagerRegler::BETRIEBSART_PEAK,
|
|
true,
|
|
0.0,
|
|
12000.0,
|
|
0.0
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testUmschaltdifferenzVerhindertZuKleineAenderung(): void
|
|
{
|
|
self::assertSame(
|
|
ManagerRegler::BETRIEBSART_PV,
|
|
ManagerRegler::bestimmeBetriebsart(
|
|
true,
|
|
true,
|
|
11000.0,
|
|
ManagerRegler::BETRIEBSART_PV,
|
|
true,
|
|
10000.0,
|
|
10500.0,
|
|
60.0
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testWechseltOberhalbDerPeakgrenzeInDenPeakbetrieb(): void
|
|
{
|
|
self::assertSame(
|
|
ManagerRegler::BETRIEBSART_PEAK,
|
|
ManagerRegler::bestimmeBetriebsart(
|
|
true,
|
|
true,
|
|
12500.0,
|
|
ManagerRegler::BETRIEBSART_PV,
|
|
true,
|
|
0.0,
|
|
12000.0,
|
|
5.0
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testWechseltUnterhalbDesSolarsollwertsInDenPvBetrieb(): void
|
|
{
|
|
self::assertSame(
|
|
ManagerRegler::BETRIEBSART_PV,
|
|
ManagerRegler::bestimmeBetriebsart(
|
|
true,
|
|
true,
|
|
-500.0,
|
|
ManagerRegler::BETRIEBSART_PEAK,
|
|
true,
|
|
0.0,
|
|
12000.0,
|
|
5.0
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testVerteilungBeruecksichtigtPrioritaetEinzelwerteUndBereiche(): void
|
|
{
|
|
$ergebnis = ManagerRegler::verteile(
|
|
0.0,
|
|
4500.0,
|
|
[
|
|
$this->verbraucher(20, 5, [0, 3000], 0),
|
|
$this->verbraucher(10, 0, [0, ['Von_W' => 1000, 'Bis_W' => 2000], 4000], 0),
|
|
],
|
|
'PrioritaetPV'
|
|
);
|
|
|
|
self::assertSame(4500, $ergebnis['Verteilbudget_W']);
|
|
self::assertSame([10 => 4000, 20 => 0], $ergebnis['Sollwerte']);
|
|
self::assertSame(500, $ergebnis['Restabweichung_W']);
|
|
}
|
|
|
|
public function testFestwertWirdUnabhaengigVonAenderungMoeglichZugewiesen(): void
|
|
{
|
|
$fest = $this->verbraucher(10, 0, [3000], 3000, false);
|
|
$steuerbar = $this->verbraucher(20, 1, [0, ['Von_W' => 1, 'Bis_W' => 4000]], 0);
|
|
|
|
$ergebnis = ManagerRegler::verteile(3000.0, 5000.0, [$fest, $steuerbar], 'PrioritaetPV');
|
|
|
|
self::assertSame(0, $ergebnis['NichtSteuerbar_W']);
|
|
self::assertSame([10 => 3000, 20 => 2000], $ergebnis['Sollwerte']);
|
|
self::assertSame(0, $ergebnis['Restabweichung_W']);
|
|
}
|
|
|
|
public function testFestwerteWerdenMitHoeherPriorisierterBatterieZugewiesen(): void
|
|
{
|
|
$ergebnis = ManagerRegler::verteile(
|
|
-2411.0,
|
|
0.0,
|
|
[
|
|
$this->verbraucher(
|
|
44234,
|
|
0,
|
|
[['Von_W' => -39000, 'Bis_W' => 39000]],
|
|
0
|
|
),
|
|
$this->verbraucher(38676, 1, [0, 4600], 0),
|
|
$this->verbraucher(29743, 1, [0, 6500], 0),
|
|
$this->verbraucher(43878, 2, [13850], 10151, false),
|
|
$this->verbraucher(46052, 2, [11000], 0, false),
|
|
],
|
|
'PrioritaetPV'
|
|
);
|
|
|
|
self::assertSame(12562, $ergebnis['Verteilbudget_W']);
|
|
self::assertSame(
|
|
[
|
|
44234 => -12288,
|
|
29743 => 0,
|
|
38676 => 0,
|
|
43878 => 13850,
|
|
46052 => 11000,
|
|
],
|
|
$ergebnis['Sollwerte']
|
|
);
|
|
self::assertSame(0, $ergebnis['Restabweichung_W']);
|
|
}
|
|
|
|
public function testFehlendeIstleistungFaelltAufAngenommenenSollwertZurueck(): void
|
|
{
|
|
$verbraucher = $this->verbraucher(10, 0, [3000], null, false);
|
|
$verbraucher['Daten']['Leistungsquelle'] = Nachrichtenvertrag::LEISTUNGSQUELLE_NICHT_VORHANDEN;
|
|
$verbraucher['Daten']['Istleistung_W'] = null;
|
|
$verbraucher['Daten']['Zustand'][0]['Wert'] = 3000;
|
|
|
|
$ergebnis = ManagerRegler::verteile(3000.0, 0.0, [$verbraucher], 'PrioritaetPV');
|
|
|
|
self::assertSame(3000, $ergebnis['AktuelleVerbraucherleistung_W']);
|
|
self::assertSame([10 => 3000], $ergebnis['Sollwerte']);
|
|
self::assertSame(-3000, $ergebnis['Restabweichung_W']);
|
|
}
|
|
|
|
public function testMonatlicheGrenzeMussVollstaendigSein(): void
|
|
{
|
|
$this->expectException(InvalidArgumentException::class);
|
|
ManagerRegler::wirksameLastspitzengrenze(2, 0.0, [1 => 12000.0], 9);
|
|
}
|
|
|
|
/**
|
|
* @param list<int|array{Von_W: int, Bis_W: int}> $leistungswerte
|
|
* @return array{InstanzID: int, Daten: array<string, mixed>}
|
|
*/
|
|
private function verbraucher(
|
|
int $instanzID,
|
|
int $prioritaet,
|
|
array $leistungswerte,
|
|
?int $istleistung,
|
|
bool $aenderungMoeglich = true
|
|
): array {
|
|
$quelle = $istleistung === null
|
|
? Nachrichtenvertrag::LEISTUNGSQUELLE_NICHT_VORHANDEN
|
|
: Nachrichtenvertrag::LEISTUNGSQUELLE_GEMESSEN;
|
|
|
|
return [
|
|
'InstanzID' => $instanzID,
|
|
'Daten' => [
|
|
'Kopf' => [
|
|
'Version' => Nachrichtenvertrag::VERSION,
|
|
'AbsenderID' => $instanzID,
|
|
'EmpfaengerID' => 1,
|
|
'Zeitpunkt' => 1788825600,
|
|
],
|
|
'Betriebsart' => Nachrichtenvertrag::BETRIEBSART_PV,
|
|
'PrioritaetPV' => $prioritaet,
|
|
'PrioritaetPeak' => $prioritaet,
|
|
'Leistungswerte_W' => $leistungswerte,
|
|
'AenderungMoeglich' => $aenderungMoeglich,
|
|
'Verfuegbar' => true,
|
|
'Istleistung_W' => $istleistung,
|
|
'Leistungsquelle' => $quelle,
|
|
'Zustand' => [[
|
|
'Kennung' => 'Sollleistung_W',
|
|
'Art' => 'Sollwert',
|
|
'Wert' => $istleistung,
|
|
'Einheit' => 'W',
|
|
]],
|
|
],
|
|
];
|
|
}
|
|
}
|