12.5, 'pv' => 6500.0, 'base' => 900.0, 'grid' => -800.0, 'boiler1' => 2400, 'boiler2' => 1500, 'dryer' => 900, 'buffer' => 1800, 'battery' => -1200, 'temp1' => 51.2, 'temp2' => 48.7, 'bufferTemp' => 39.4, 'batterySoc' => 63.5, 'manager' => 'PV', ]); self::assertStringContainsString('Enelix 2 Energiefluss', $html); self::assertStringContainsString('Boiler 1', $html); self::assertStringContainsString('Boiler 2', $html); self::assertStringContainsString('Entfeuchter', $html); self::assertStringContainsString('Pufferspeicher', $html); self::assertStringContainsString('Batterie', $html); self::assertStringContainsString('63,5 %', $html); self::assertStringContainsString('Einspeisung', $html); self::assertStringContainsString('12:30', $html); } public function testDiagrammStelltMehrereZeitreihenDar(): void { $html = enelixDemoRenderChart( 'Leistungsverlauf', [ ['name' => 'PV', 'color' => '#f4c542', 'values' => [ ['time' => 100, 'value' => 1000.0], ['time' => 200, 'value' => 3000.0], ]], ['name' => 'Netz', 'color' => '#e95d5d', 'values' => [ ['time' => 100, 'value' => -500.0], ['time' => 200, 'value' => 500.0], ]], ], 'W', 100, 200 ); self::assertStringContainsString(' 0, 'VariableID' => 12345, 'SecondaryVariableID' => 1, 'Name' => 'PV-Anlage', 'Type' => 'solar', 'Grouped' => false, 'CalculationType' => 0, 'InfoVariableID' => 54321, 'Invert' => false, ], enelixDemoEnergyNode(12345, 'PV-Anlage', 'solar', 54321)); self::assertSame( 1, enelixDemoEnergyNode(12345, 'PV-Anlage', 'solar')['InfoVariableID'] ); } public function testNativeDiagrammDatenreiheHatSymconFormat(): void { self::assertSame([ 'variableID' => 12345, 'fillColor' => 'clear', 'strokeColor' => '#f4c542', 'timeOffset' => 0, 'visible' => true, 'title' => 'PV', 'type' => 'line', 'side' => 'left', 'profile' => '~Power', ], enelixDemoChartDataset(12345, 'PV', '#f4c542', '~Power')); } public function testDashboardVerwendetNativeEnergieverteilungUndNeueBoilerlisten(): void { $source = file_get_contents(dirname(__DIR__) . '/examples/Demoanlage/bootstrap.php'); self::assertIsString($source); self::assertStringContainsString("IPS_SetHidden(\$legacyFlow, true);", $source); self::assertStringContainsString("'EnergieverteilungNativ'", $source); self::assertStringContainsString( 'enelixDemoConfigureVisualization($root, $energyDistribution);', $source ); self::assertStringContainsString('ENELIX_DEMO_DUMMY_MODULE', $source); self::assertStringContainsString("'Boiler1Liste'", $source); self::assertStringContainsString("'Boiler2Liste'", $source); self::assertStringContainsString("'PufferListe'", $source); self::assertStringContainsString("'BatterieListe'", $source); self::assertStringContainsString('ENELIX_DEMO_BUFFER_MODULE', $source); self::assertStringContainsString('ENELIX_DEMO_BATTERY_MODULE', $source); self::assertStringContainsString("'AnlagenWechselrichter'", $source); self::assertStringContainsString("'AnlagenPVFlaechen'", $source); self::assertStringContainsString("'AnlagenBatterien'", $source); self::assertStringContainsString("'PrognosePVVariableID' => \$pvDisplay", $source); self::assertStringContainsString("'PrognoseHausverbrauchVariableID' => \$houseDisplay", $source); self::assertStringContainsString("'PrognoseSOCVariableID' => \$batterySoc", $source); self::assertStringContainsString("'PrognoseSendeintervall' => 60", $source); self::assertStringContainsString("'demo-hybrid-1'", $source); self::assertStringContainsString("'demo-pv-1'", $source); self::assertStringContainsString("'demo-battery-1'", $source); self::assertStringContainsString("'EnergieflussPVkW'", $source); self::assertStringContainsString("'~Power'", $source); self::assertStringContainsString("'~Electricity'", $source); self::assertStringContainsString( "enelixDemoEnergyNode(\$flowPv, 'PV-Anlage', 'solar')", $source ); self::assertStringContainsString( "enelixDemoEnergyNode(\$flowBase, 'Haus-Grundlast', 'consumer')", $source ); self::assertStringContainsString( "enelixDemoEnergyNode(\$flowDryer, 'Entfeuchter', 'consumer')", $source ); self::assertStringContainsString( "enelixDemoEnergyNode(\$flowBuffer, 'Pufferspeicher', 'consumer', \$bufferTemp)", $source ); self::assertStringContainsString( "enelixDemoEnergyNode(\$flowBattery, 'Batteriespeicher', 'battery', \$batterySoc)", $source ); self::assertStringContainsString( "\$consumerIds = [\$boiler1, \$boiler2, \$dryer, \$buffer, \$battery]", $source ); self::assertStringContainsString("'consumerIds' => \$consumerIds", $source); self::assertStringContainsString("'VerbraucherZuordnung' => '[]'", $source); self::assertStringContainsString( "enelixDemoEnsureChart(\$history, 'LeistungsdiagrammNativ'", $source ); self::assertStringContainsString('IPS_SetHidden($powerChart, true);', $source); self::assertStringContainsString( "enelixDemoLinkInstanceVariables(\$boiler1List, \$boiler1, \$temp1);", $source ); self::assertStringContainsString( "foreach (['Boiler1Link', 'Boiler2Link'] as \$oldLinkIdent)", $source ); } public function testDynamischeUmgebungBleibtBegrenztUndVeraendertDenLastgang(): void { $static = enelixDemoEnvironment(12.0, 1000.0, 30, false); self::assertSame(['base' => 1000.0, 'cloud' => 30.0, 'outside' => 6.0], $static); $morning = enelixDemoEnvironment(7.5, 1000.0, 30, true); $night = enelixDemoEnvironment(2.0, 1000.0, 30, true); self::assertGreaterThan($night['base'], $morning['base']); self::assertGreaterThanOrEqual(0.0, $morning['cloud']); self::assertLessThanOrEqual(100.0, $morning['cloud']); self::assertNotSame($morning['outside'], $night['outside']); } public function testBatterieregisterWerdenMitKorrektemVorzeichenAbgebildet(): void { self::assertSame(1500.0, enelixDemoBatteryRegisterPower(2, 11, 1500.0)); self::assertSame(-1500.0, enelixDemoBatteryRegisterPower(2, 12, 1500.0)); self::assertSame(0.0, enelixDemoBatteryRegisterPower(1, 11, 1500.0)); self::assertSame(0.0, enelixDemoBatteryRegisterPower(2, 0, 1500.0)); } public function testRollbackIstExplizitBestaetigungspflichtig(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Rollback nur mit'); enelixDemoRemove(); } }