488 lines
20 KiB
PHP
488 lines
20 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Belevo\EnelixEMS\Tests;
|
|
|
|
use InvalidArgumentException;
|
|
use Manager;
|
|
use ManagerSDLRuntime;
|
|
use PHPUnit\Framework\TestCase;
|
|
use ReflectionMethod;
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* @runTestsInSeparateProcesses
|
|
* @preserveGlobalState disabled
|
|
*/
|
|
final class ManagerSDLTest extends TestCase
|
|
{
|
|
private Manager $manager;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
require_once __DIR__ . '/Support/ManagerSDLRuntime.php';
|
|
require_once __DIR__ . '/../Manager/module.php';
|
|
|
|
ManagerSDLRuntime::reset();
|
|
$this->manager = new Manager(42);
|
|
$this->manager->Create();
|
|
foreach ([101 => 1000.0, 102 => 5000.0, 103 => 200.0, 104 => 1500.0, 105 => 70.0] as $id => $value) {
|
|
ManagerSDLRuntime::variable($id, $value);
|
|
}
|
|
$this->properties([
|
|
'NetzleistungVariableID' => 101,
|
|
'AnlagenWechselrichter' => $this->json([
|
|
['ID' => 'pv', 'Typ' => 'pv', 'IstleistungVariableID' => 102],
|
|
]),
|
|
'AnlagenBatterien' => $this->json([
|
|
['ID' => 'battery', 'LeistungVariableID' => 103],
|
|
]),
|
|
'SDLLeistungVariableID' => 104,
|
|
'SDLSOCVariableID' => 105,
|
|
]);
|
|
foreach ([
|
|
'SDLLeistungArchiv', 'SDLSOCArchiv', 'SDLLadenEnergie', 'SDLEntladenEnergie',
|
|
] as $ident) {
|
|
ManagerSDLRuntime::child(42, $ident);
|
|
}
|
|
ManagerSDLRuntime::child(42, 'SDLStatus', 3);
|
|
}
|
|
|
|
public function testSDLByDefaultInactiveDoesNotRequireSources(): void
|
|
{
|
|
self::assertFalse($this->manager->testProperties['SDLAktiv']);
|
|
self::assertFalse($this->manager->testProperties['SDLEnergieflussAnzeigen']);
|
|
self::assertFalse($this->manager->testProperties['SDLDiagrammeAnzeigen']);
|
|
unset(ManagerSDLRuntime::$variables[104], ManagerSDLRuntime::$variables[105]);
|
|
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
$powers = $this->invoke('leseMessleistungen');
|
|
|
|
self::assertSame(0.0, $powers['SDL']);
|
|
self::assertSame(5800.0, $powers['Haus']);
|
|
self::assertNull($this->invoke('aktuelleSDLSOC'));
|
|
}
|
|
|
|
/** @dataProvider signedPowerProvider */
|
|
public function testSDLPowerIsExcludedFromHouseConsumption(float $raw, float $factor, float $sdl, float $house): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLLeistungsfaktor' => $factor]);
|
|
ManagerSDLRuntime::variable(104, $raw);
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
|
|
self::assertSame([
|
|
'PV' => 5000.0, 'Haus' => $house, 'Netz' => 1000.0, 'Batterie' => 200.0, 'SDL' => $sdl,
|
|
], $this->invoke('leseMessleistungen'));
|
|
}
|
|
|
|
public static function signedPowerProvider(): array
|
|
{
|
|
return [
|
|
'charging' => [1500.0, 1.0, 1500.0, 4300.0],
|
|
'discharging' => [-1500.0, 1.0, -1500.0, 7300.0],
|
|
'kilowatts' => [2.5, 1000.0, 2500.0, 3300.0],
|
|
'inverted source' => [1500.0, -1.0, -1500.0, 7300.0],
|
|
];
|
|
}
|
|
|
|
/** @dataProvider duplicatePowerProvider */
|
|
public function testRejectsSDLPowerAlsoUsedByAnotherEnergySource(int $duplicateID): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLLeistungVariableID' => $duplicateID]);
|
|
$this->expectException(InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('nicht zugleich');
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
}
|
|
|
|
public static function duplicatePowerProvider(): array
|
|
{
|
|
return ['grid' => [101], 'PV' => [102], 'battery' => [103]];
|
|
}
|
|
|
|
public function testRejectsSOCUsingThePowerVariable(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLSOCVariableID' => 104]);
|
|
$this->expectException(InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('separate numerische Variable');
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
}
|
|
|
|
/** @dataProvider invalidFactorProvider */
|
|
public function testRejectsInvalidSDLFactors(float $factor): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLLeistungsfaktor' => $factor]);
|
|
$this->expectException(InvalidArgumentException::class);
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
}
|
|
|
|
public static function invalidFactorProvider(): array
|
|
{
|
|
return ['zero' => [0.0], 'infinite' => [INF], 'not a number' => [NAN]];
|
|
}
|
|
|
|
public function testMissingSDLPowerFailsWithoutReturningHouseConsumption(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
unset(ManagerSDLRuntime::$variables[104]);
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('nicht verfuegbar');
|
|
$this->invoke('leseMessleistungen');
|
|
}
|
|
|
|
/** @dataProvider invalidPowerProvider */
|
|
public function testNonfiniteOrNonnumericPowerDoesNotBecomeZero($value): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
ManagerSDLRuntime::variable(104, $value);
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('keine endliche Zahl');
|
|
$this->invoke('leseMessleistungen');
|
|
}
|
|
|
|
public static function invalidPowerProvider(): array
|
|
{
|
|
return ['infinite' => [INF], 'negative infinite' => [-INF], 'not a number' => [NAN], 'string' => ['1500']];
|
|
}
|
|
|
|
public function testScaledSDLPowerOverflowIsRejected(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLLeistungsfaktor' => 2.0]);
|
|
ManagerSDLRuntime::variable(104, PHP_FLOAT_MAX);
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('skalierte SDL-Istleistung');
|
|
$this->invoke('leseMessleistungen');
|
|
}
|
|
|
|
public function testSDLPowerMustBeANumericVariable(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
ManagerSDLRuntime::variable(104, '1500', 3);
|
|
$this->expectException(InvalidArgumentException::class);
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
}
|
|
|
|
/** @dataProvider socProvider */
|
|
public function testSDLSOCBoundaries(float $value, ?float $expected): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
ManagerSDLRuntime::variable(105, $value);
|
|
self::assertSame($expected, $this->invoke('aktuelleSDLSOC'));
|
|
if ($expected === null) {
|
|
self::assertStringContainsString('SDL-SOC', $this->manager->GetValue('SDLStatus'));
|
|
}
|
|
}
|
|
|
|
public static function socProvider(): array
|
|
{
|
|
return [
|
|
'empty' => [0.0, 0.0], 'full' => [100.0, 100.0], 'normal' => [37.5, 37.5],
|
|
'negative' => [-0.1, null], 'overfull' => [100.1, null], 'infinite' => [INF, null], 'NaN' => [NAN, null],
|
|
];
|
|
}
|
|
|
|
public function testSDLSOCMayBeOmittedAndDisappearingSourceIsIgnored(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLSOCVariableID' => 0]);
|
|
$this->invoke('pruefeSDLKonfiguration');
|
|
self::assertNull($this->invoke('aktuelleSDLSOC'));
|
|
|
|
$this->properties(['SDLSOCVariableID' => 105]);
|
|
unset(ManagerSDLRuntime::$variables[105]);
|
|
self::assertNull($this->invoke('aktuelleSDLSOC'));
|
|
self::assertStringContainsString('SDL-SOC', $this->manager->GetValue('SDLStatus'));
|
|
}
|
|
|
|
public function testPowerReadingPreservesSOCErrorUntilRecovery(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
ManagerSDLRuntime::variable(105, 101.0);
|
|
$this->invoke('aktuelleSDLLeistung');
|
|
self::assertStringContainsString('SDL-SOC', $this->manager->GetValue('SDLStatus'));
|
|
$this->invoke('aktuelleSDLLeistung');
|
|
self::assertStringContainsString('SDL-SOC', $this->manager->GetValue('SDLStatus'));
|
|
ManagerSDLRuntime::variable(105, 47.5);
|
|
$this->invoke('aktuelleSDLLeistung');
|
|
self::assertSame('Aktiv', $this->manager->GetValue('SDLStatus'));
|
|
}
|
|
|
|
public function testSDLSOCDoesNotChangeWeightedNormalBatterySOC(): void
|
|
{
|
|
ManagerSDLRuntime::variable(106, 20.0);
|
|
ManagerSDLRuntime::variable(107, 80.0);
|
|
$this->properties([
|
|
'SDLAktiv' => true,
|
|
'AnlagenBatterien' => $this->json([
|
|
['ID' => 'small', 'SOCVariableID' => 106, 'Nutzkapazitaet_kWh' => 10.0],
|
|
['ID' => 'large', 'SOCVariableID' => 107, 'Nutzkapazitaet_kWh' => 30.0],
|
|
]),
|
|
]);
|
|
|
|
self::assertSame(65.0, $this->invoke('aktuelleBatterieSoc'));
|
|
self::assertSame(70.0, $this->invoke('aktuelleSDLSOC'));
|
|
ManagerSDLRuntime::variable(105, 0.0);
|
|
self::assertSame(65.0, $this->invoke('aktuelleBatterieSoc'));
|
|
}
|
|
|
|
public function testCounterDeltasExcludeSDLChargingAndIncludeDischarging(): void
|
|
{
|
|
$this->configureCounters();
|
|
$baseline = $this->invoke('leseEnergieZaehlerDeltas', [0.6, 0.2]);
|
|
self::assertCount(8, $baseline);
|
|
self::assertSame(array_fill_keys(array_keys($baseline), 0.0), $baseline);
|
|
$this->advanceCounters();
|
|
|
|
$deltas = $this->invoke('leseEnergieZaehlerDeltas', [0.6, 0.2]);
|
|
|
|
self::assertEqualsWithDelta(2.1, $deltas['Hausenergie'], 0.000001);
|
|
self::assertEqualsWithDelta(2.0, $deltas['PVEnergie'], 0.000001);
|
|
self::assertSame(0.6, $deltas['SDLLadenEnergie']);
|
|
self::assertSame(0.2, $deltas['SDLEntladenEnergie']);
|
|
self::assertEqualsWithDelta(0.4, $deltas['BatterieLadenEnergie'], 0.000001);
|
|
self::assertEqualsWithDelta(0.1, $deltas['BatterieEntladenEnergie'], 0.000001);
|
|
}
|
|
|
|
public function testMissingSDLIntervalDoesNotPolluteHouseEnergyOrTheNextInterval(): void
|
|
{
|
|
$this->configureCounters();
|
|
$this->invoke('leseEnergieZaehlerDeltas');
|
|
$this->advanceCounters();
|
|
$deltas = $this->invoke('leseEnergieZaehlerDeltas', [0.0, 0.0, false]);
|
|
|
|
self::assertSame(0.0, $deltas['Hausenergie']);
|
|
self::assertEqualsWithDelta(2.0, $deltas['PVEnergie'], 0.000001);
|
|
self::assertEqualsWithDelta(1.0, $deltas['NetzbezugEnergie'], 0.000001);
|
|
ManagerSDLRuntime::variable(201, 102.5);
|
|
$next = $this->invoke('leseEnergieZaehlerDeltas', [0.1, 0.0, true]);
|
|
self::assertEqualsWithDelta(0.4, $next['Hausenergie'], 0.000001);
|
|
}
|
|
|
|
public function testCounterResetSuppressesHouseEnergyForActiveSDL(): void
|
|
{
|
|
$this->configureCounters();
|
|
$this->invoke('leseEnergieZaehlerDeltas');
|
|
$this->advanceCounters();
|
|
ManagerSDLRuntime::variable(202, 0.0);
|
|
$deltas = $this->invoke('leseEnergieZaehlerDeltas', [0.6, 0.2]);
|
|
self::assertSame(0.0, $deltas['Hausenergie']);
|
|
self::assertSame(0.0, $deltas['NetzbezugEnergie']);
|
|
self::assertSame(0.6, $deltas['SDLLadenEnergie']);
|
|
}
|
|
|
|
public function testWithoutConfiguredCountersReturnsNull(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
self::assertNull($this->invoke('leseEnergieZaehlerDeltas', [0.6, 0.2]));
|
|
}
|
|
|
|
public function testChangingSDLSourceResetsBaselinesButKeepsCollectedEnergy(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true]);
|
|
$this->invoke('synchronisiereSDLMesskonfiguration');
|
|
$this->manager->testAttributes['MessungLetzterZeitstempel'] = 123;
|
|
$this->manager->testAttributes['MessungLetzteLeistungsaufzeichnung'] = 100;
|
|
$this->manager->testAttributes['MessungZaehlerstaende'] = '{"pv:pv":5.0}';
|
|
$this->manager->testAttributes['MessungEnergiePuffer'] = '{"Hausenergie":1.5}';
|
|
|
|
$this->invoke('synchronisiereSDLMesskonfiguration');
|
|
self::assertSame(123, $this->manager->testAttributes['MessungLetzterZeitstempel']);
|
|
$this->properties(['SDLLeistungsfaktor' => -1.0]);
|
|
$this->invoke('synchronisiereSDLMesskonfiguration');
|
|
|
|
self::assertSame(0, $this->manager->testAttributes['MessungLetzterZeitstempel']);
|
|
self::assertSame(0, $this->manager->testAttributes['MessungLetzteLeistungsaufzeichnung']);
|
|
self::assertSame('{}', $this->manager->testAttributes['MessungZaehlerstaende']);
|
|
self::assertSame('{"Hausenergie":1.5}', $this->manager->testAttributes['MessungEnergiePuffer']);
|
|
}
|
|
|
|
/** @dataProvider chartProvider */
|
|
public function testChartMergePreservesCustomizationsAndOnlyRemovesSDL(bool $energy): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLDiagrammeAnzeigen' => true]);
|
|
$powerIdent = $energy ? 'SDLLadenEnergie' : 'SDLLeistungArchiv';
|
|
$custom = ['variableID' => 999, 'title' => 'Custom series', 'strokeColor' => '#ABCDEF'];
|
|
$sdl = ['variableID' => $this->manager->GetIDForIdent($powerIdent), 'title' => 'Own SDL name', 'visible' => false];
|
|
ManagerSDLRuntime::$media[301] = base64_encode($this->json([
|
|
'datasets' => [$custom, $sdl], 'customOption' => ['keep' => true],
|
|
]));
|
|
|
|
$this->invoke('synchronisiereSDLDiagramm', [301, $energy]);
|
|
$chart = $this->chart();
|
|
self::assertSame($custom, $chart['datasets'][0]);
|
|
self::assertSame($sdl, $chart['datasets'][1]);
|
|
self::assertSame(['keep' => true], $chart['customOption']);
|
|
self::assertCount($energy ? 4 : 3, $chart['datasets']);
|
|
$soc = $chart['datasets'][count($chart['datasets']) - 1];
|
|
self::assertSame($this->manager->GetIDForIdent('SDLSOCArchiv'), $soc['variableID']);
|
|
self::assertSame('right', $soc['side']);
|
|
if ($energy) {
|
|
self::assertSame('bar', $chart['datasets'][2]['type']);
|
|
self::assertSame($this->manager->GetIDForIdent('SDLEntladenEnergie'), $chart['datasets'][2]['variableID']);
|
|
}
|
|
|
|
$writes = ManagerSDLRuntime::$writes;
|
|
$this->invoke('synchronisiereSDLDiagramm', [301, $energy]);
|
|
self::assertSame($writes, ManagerSDLRuntime::$writes);
|
|
|
|
$this->properties(['SDLDiagrammeAnzeigen' => false]);
|
|
$this->invoke('synchronisiereSDLDiagramm', [301, $energy]);
|
|
self::assertSame([$custom], $this->chart()['datasets']);
|
|
self::assertSame(['keep' => true], $this->chart()['customOption']);
|
|
}
|
|
|
|
public static function chartProvider(): array
|
|
{
|
|
return ['power chart' => [false], 'energy chart' => [true]];
|
|
}
|
|
|
|
public function testEnergyFlowMergePreservesCustomNodesAndIsIdempotent(): void
|
|
{
|
|
$this->properties(['SDLAktiv' => true, 'SDLEnergieflussAnzeigen' => true]);
|
|
$custom = ['VariableID' => 999, 'Name' => 'Custom consumer', 'Type' => 'consumer', 'Invert' => true];
|
|
ManagerSDLRuntime::$properties[302]['Config'] = $this->json([$custom]);
|
|
|
|
$this->invoke('synchronisiereSDLEnergiefluss', [302]);
|
|
$nodes = $this->flow();
|
|
self::assertSame($custom, $nodes[0]);
|
|
self::assertCount(2, $nodes);
|
|
self::assertSame('storage', $nodes[1]['Type']);
|
|
self::assertSame($this->manager->GetIDForIdent('EnergieflussSDL'), $nodes[1]['VariableID']);
|
|
self::assertSame($this->manager->GetIDForIdent('SDLSOCArchiv'), $nodes[1]['InfoVariableID']);
|
|
self::assertTrue(ManagerSDLRuntime::$hidden[$nodes[1]['VariableID']]);
|
|
|
|
$nodes[1]['Name'] = 'My SDL';
|
|
$nodes[1]['Invert'] = true;
|
|
ManagerSDLRuntime::$properties[302]['Config'] = $this->json($nodes);
|
|
$writes = ManagerSDLRuntime::$writes;
|
|
$this->invoke('synchronisiereSDLEnergiefluss', [302]);
|
|
self::assertSame($nodes, $this->flow());
|
|
self::assertSame($writes, ManagerSDLRuntime::$writes);
|
|
|
|
$this->properties(['SDLSOCVariableID' => 0]);
|
|
$this->invoke('synchronisiereSDLEnergiefluss', [302]);
|
|
self::assertSame(1, $this->flow()[1]['InfoVariableID']);
|
|
self::assertSame('My SDL', $this->flow()[1]['Name']);
|
|
|
|
$this->properties(['SDLAktiv' => false]);
|
|
$this->invoke('synchronisiereSDLEnergiefluss', [302]);
|
|
self::assertSame([$custom], $this->flow());
|
|
}
|
|
|
|
private function configureCounters(): void
|
|
{
|
|
$this->properties([
|
|
'SDLAktiv' => true,
|
|
'NetzbezugEnergieVariableID' => 202,
|
|
'NetzeinspeisungEnergieVariableID' => 203,
|
|
'AnlagenWechselrichter' => $this->json([
|
|
['ID' => 'pv', 'Typ' => 'pv', 'IstleistungVariableID' => 102, 'ErzeugungsenergieVariableID' => 201],
|
|
]),
|
|
'AnlagenBatterien' => $this->json([
|
|
['ID' => 'battery', 'LeistungVariableID' => 103, 'LadeenergieVariableID' => 204, 'EntladeenergieVariableID' => 205],
|
|
]),
|
|
]);
|
|
foreach ([201 => 100.0, 202 => 10.0, 203 => 5.0, 204 => 10.0, 205 => 8.0] as $id => $value) {
|
|
ManagerSDLRuntime::variable($id, $value);
|
|
}
|
|
}
|
|
|
|
public function testEnergyPieAttributionTracksSDLWithoutChangingCustomSettings(): void
|
|
{
|
|
$custom = [
|
|
'ProduktionZaehlerID' => 801,
|
|
'NetzbezugZaehlerID' => 802,
|
|
'EinspeisungZaehlerID' => 803,
|
|
'VerbrauchZaehlerID' => 804,
|
|
'FarbeEigenverbrauch' => '#123456',
|
|
'FarbeAutarkie' => '#ABCDEF',
|
|
'Standardzeitraum' => 'month',
|
|
'EnergieanteileBerechenbar' => true,
|
|
];
|
|
ManagerSDLRuntime::$properties[303] = $custom;
|
|
$this->properties(['SDLAktiv' => true]);
|
|
|
|
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
|
self::assertSame(array_replace($custom, ['EnergieanteileBerechenbar' => false]),
|
|
ManagerSDLRuntime::$properties[303]);
|
|
$writes = ManagerSDLRuntime::$writes;
|
|
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
|
self::assertSame($writes, ManagerSDLRuntime::$writes);
|
|
|
|
$this->properties(['SDLAktiv' => false]);
|
|
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
|
self::assertSame($custom, ManagerSDLRuntime::$properties[303]);
|
|
}
|
|
|
|
public function testOlderEnergyPieStaysVisibleWithoutSDLAndKeepsConfiguration(): void
|
|
{
|
|
$custom = ['ProduktionZaehlerID' => 801, 'FarbeEigenverbrauch' => '#123456'];
|
|
ManagerSDLRuntime::$properties[303] = $custom;
|
|
$this->properties(['SDLAktiv' => false]);
|
|
|
|
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
|
|
|
self::assertSame($custom, ManagerSDLRuntime::$properties[303]);
|
|
self::assertFalse(ManagerSDLRuntime::$hidden[303]);
|
|
self::assertSame([], ManagerSDLRuntime::$logs);
|
|
}
|
|
|
|
public function testOlderEnergyPieIsHiddenWithSDLAndRestoredAfterUtilsUpdate(): void
|
|
{
|
|
$custom = ['ProduktionZaehlerID' => 801, 'FarbeEigenverbrauch' => '#123456'];
|
|
ManagerSDLRuntime::$properties[303] = $custom;
|
|
$this->properties(['SDLAktiv' => true]);
|
|
|
|
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
|
|
|
self::assertSame($custom, ManagerSDLRuntime::$properties[303]);
|
|
self::assertTrue(ManagerSDLRuntime::$hidden[303]);
|
|
self::assertCount(1, ManagerSDLRuntime::$logs);
|
|
self::assertStringContainsString('Enelix Utils aktualisieren', ManagerSDLRuntime::$logs[0][1]);
|
|
|
|
ManagerSDLRuntime::$properties[303]['EnergieanteileBerechenbar'] = true;
|
|
$this->invoke('synchronisiereEnergyPieAnteile', [303]);
|
|
|
|
self::assertFalse(ManagerSDLRuntime::$hidden[303]);
|
|
self::assertSame(array_replace($custom, ['EnergieanteileBerechenbar' => false]),
|
|
ManagerSDLRuntime::$properties[303]);
|
|
self::assertCount(1, ManagerSDLRuntime::$logs);
|
|
}
|
|
|
|
private function advanceCounters(): void
|
|
{
|
|
foreach ([201 => 102.0, 202 => 11.0, 203 => 5.2, 204 => 10.4, 205 => 8.1] as $id => $value) {
|
|
ManagerSDLRuntime::variable($id, $value);
|
|
}
|
|
}
|
|
|
|
private function properties(array $properties): void
|
|
{
|
|
$this->manager->testProperties = array_replace($this->manager->testProperties, $properties);
|
|
}
|
|
|
|
private function invoke(string $name, array $arguments = [])
|
|
{
|
|
$method = new ReflectionMethod(Manager::class, $name);
|
|
if (PHP_VERSION_ID < 80100) {
|
|
$method->setAccessible(true);
|
|
}
|
|
|
|
return $method->invokeArgs($this->manager, $arguments);
|
|
}
|
|
|
|
private function json(array $value): string
|
|
{
|
|
return json_encode($value, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION);
|
|
}
|
|
|
|
private function chart(): array
|
|
{
|
|
return json_decode(base64_decode(ManagerSDLRuntime::$media[301]), true, 512, JSON_THROW_ON_ERROR);
|
|
}
|
|
|
|
private function flow(): array
|
|
{
|
|
return json_decode(ManagerSDLRuntime::$properties[302]['Config'], true, 512, JSON_THROW_ON_ERROR);
|
|
}
|
|
}
|