From ef93574f872f4e629001f1f4a2918a812b82e9fa Mon Sep 17 00:00:00 2001 From: Dominique Lasserre Date: Sun, 10 Nov 2024 23:22:30 +0100 Subject: [PATCH] Add more optimization tests (#171) * Integrated single_test_optimization into pytest to run a basic optimization test with tolerance set to 1e-6, ensuring quick detection of deviations. * Added a long-run test (400 generations, like single_test_optimization), which can be triggered using --full-run in pytest. * Mocked PDF creation in optimization tests and added a new PDF generation test with image comparison validation. Note: Current tolerance is set to 1e-6; feedback on whether this tolerance is tight enough is welcome. --------- Co-authored-by: Normann Co-authored-by: Michael Osthege --- .gitignore | 4 + Makefile | 7 +- tests/conftest.py | 11 ++ tests/test_class_optimize.py | 45 ++++++-- tests/test_visualize.py | 30 ++++++ .../images/visualize_base_output_1.pdf | Bin 0 -> 43879 bytes tests/testdata/optimize_input_2.json | 47 +++++++++ tests/testdata/optimize_result_2.json | 99 ++++++++++++++++++ tests/testdata/optimize_result_2_full.json | 99 ++++++++++++++++++ tests/testdata/visualize_input_1.json | 63 +++++++++++ 10 files changed, 395 insertions(+), 10 deletions(-) create mode 100644 tests/test_visualize.py create mode 100644 tests/testdata/images/visualize_base_output_1.pdf create mode 100644 tests/testdata/optimize_input_2.json create mode 100644 tests/testdata/optimize_result_2.json create mode 100644 tests/testdata/optimize_result_2_full.json create mode 100644 tests/testdata/visualize_input_1.json diff --git a/.gitignore b/.gitignore index 2fcf6c5..efc7783 100644 --- a/.gitignore +++ b/.gitignore @@ -246,3 +246,7 @@ $RECYCLE.BIN/ # Visualization side effects **/visualization_results.pdf +visualize_output_*.pdf + +# Test images +*_pdf.png diff --git a/Makefile b/Makefile index ac0856b..37cc1ef 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # Define the targets -.PHONY: help venv pip install dist test docker-run docs clean +.PHONY: help venv pip install dist test test-full docker-run docs clean # Default target all: help @@ -70,6 +70,11 @@ test: @echo "Running tests..." .venv/bin/pytest -vs --cov src --cov-report term-missing +# Target to run all tests. +test-full: + @echo "Running all tests..." + .venv/bin/pytest --full-run + # Run entire setup on docker docker-run: @docker compose up --remove-orphans diff --git a/tests/conftest.py b/tests/conftest.py index 58dfb07..ccd1580 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,6 +6,17 @@ import pytest from xprocess import ProcessStarter +def pytest_addoption(parser): + parser.addoption( + "--full-run", action="store_true", default=False, help="Run with all optimization tests." + ) + + +@pytest.fixture +def is_full_run(request): + yield bool(request.config.getoption("--full-run")) + + @pytest.fixture def server(xprocess): class Starter(ProcessStarter): diff --git a/tests/test_class_optimize.py b/tests/test_class_optimize.py index 7fad6b2..f0396d4 100644 --- a/tests/test_class_optimize.py +++ b/tests/test_class_optimize.py @@ -1,16 +1,39 @@ import json from pathlib import Path +from typing import Any +from unittest.mock import patch import pytest from akkudoktoreos.class_optimize import optimization_problem -from akkudoktoreos.config import output_dir DIR_TESTDATA = Path(__file__).parent / "testdata" -@pytest.mark.parametrize("fn_in, fn_out", [("optimize_input_1.json", "optimize_result_1.json")]) -def test_optimize(fn_in, fn_out): +def compare_dict(actual: dict[str, Any], expected: dict[str, Any]): + assert set(actual) == set(expected) + + for key, value in expected.items(): + if isinstance(value, dict): + assert isinstance(actual[key], dict) + compare_dict(actual[key], value) + elif isinstance(value, list): + assert isinstance(actual[key], list) + assert actual[key] == pytest.approx(value) + else: + assert actual[key] == pytest.approx(value) + + +@pytest.mark.parametrize( + "fn_in, fn_out, ngen", + [ + ("optimize_input_1.json", "optimize_result_1.json", 3), + ("optimize_input_2.json", "optimize_result_2.json", 3), + ("optimize_input_2.json", "optimize_result_2_full.json", 400), + ], +) +@patch("akkudoktoreos.class_optimize.visualisiere_ergebnisse") +def test_optimize(visualisiere_ergebnisse_patch, fn_in: str, fn_out: str, ngen: int, is_full_run): # Load input and output data with open(DIR_TESTDATA / fn_in, "r") as f_in: input_data = json.load(f_in) @@ -23,16 +46,20 @@ def test_optimize(fn_in, fn_out): ) start_hour = 10 + if ngen > 10 and not is_full_run: + pytest.skip() + # Call the optimization function - ergebnis = opt_class.optimierung_ems(parameter=input_data, start_hour=start_hour, ngen=3) - # with open("new.json", "w") as f_out: - # json.dump(ergebnis, f_out, indent=4) + ergebnis = opt_class.optimierung_ems(parameter=input_data, start_hour=start_hour, ngen=ngen) + # with open(f"new_{fn_out}", "w") as f_out: + # from akkudoktoreos.class_numpy_encoder import NumpyEncoder + # json_data_str = NumpyEncoder.dumps(ergebnis) + # json.dump(json.loads(json_data_str), f_out, indent=4) # Assert that the output contains all expected entries. # This does not assert that the optimization always gives the same result! # Reproducibility and mathematical accuracy should be tested on the level of individual components. - assert set(ergebnis) == set(expected_output_data) + compare_dict(ergebnis, expected_output_data) # The function creates a visualization result PDF as a side-effect. - fp_viz = Path(output_dir) / "visualization_results.pdf" - assert fp_viz.exists() + visualisiere_ergebnisse_patch.assert_called_once() diff --git a/tests/test_visualize.py b/tests/test_visualize.py new file mode 100644 index 0000000..da6b459 --- /dev/null +++ b/tests/test_visualize.py @@ -0,0 +1,30 @@ +import json +from pathlib import Path +from unittest.mock import patch + +import pytest +from matplotlib.testing.compare import compare_images + +from akkudoktoreos.visualize import visualisiere_ergebnisse + +DIR_TESTDATA = Path(__file__).parent / "testdata" +DIR_IMAGEDATA = DIR_TESTDATA / "images" + + +@pytest.mark.parametrize( + "fn_in, fn_out, fn_out_base", + [("visualize_input_1.json", "visualize_output_1.pdf", "visualize_base_output_1.pdf")], +) +@patch("akkudoktoreos.visualize.output_dir", DIR_IMAGEDATA) +def test_visualisiere_ergebnisse(fn_in, fn_out, fn_out_base): + with open(DIR_TESTDATA / fn_in, "r") as f: + input_data = json.load(f) + visualisiere_ergebnisse(**input_data) + assert ( + compare_images( + str(DIR_IMAGEDATA / fn_out), + str(DIR_IMAGEDATA / fn_out_base), + 0, + ) + is None + ) diff --git a/tests/testdata/images/visualize_base_output_1.pdf b/tests/testdata/images/visualize_base_output_1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c607cc494a55b5ce88dffd8212272d6a8a9202bc GIT binary patch literal 43879 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 Djn_h4 literal 0 HcmV?d00001 diff --git a/tests/testdata/optimize_input_2.json b/tests/testdata/optimize_input_2.json new file mode 100644 index 0000000..910ef7e --- /dev/null +++ b/tests/testdata/optimize_input_2.json @@ -0,0 +1,47 @@ +{ + "preis_euro_pro_wh_akku": 0.0001, + "pv_soc": 80, + "pv_akku_cap": 26400, + "year_energy": 4100000, + "einspeiseverguetung_euro_pro_wh": 0.00007, + "max_heizleistung": 1000, + "gesamtlast": [ + 676.71, 876.19, 527.13, 468.88, 531.38, 517.95, 483.15, 472.28, 1011.68, 995.00, + 1053.07, 1063.91, 1320.56, 1132.03, 1163.67, 1176.82, 1216.22, 1103.78, 1129.12, + 1178.71, 1050.98, 988.56, 912.38, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, + 488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, + 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "pv_forecast": [ + 0, 0, 0, 0, 0, 0, 0, 8.05, 352.91, 728.51, 930.28, 1043.25, 1106.74, 1161.69, + 6018.82, 5519.07, 3969.88, 3017.96, 1943.07, 1007.17, 319.67, 7.88, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5.04, 335.59, 705.32, 1121.12, 1604.79, 2157.38, 1433.25, 5718.49, + 4553.96, 3027.55, 2574.46, 1720.4, 963.4, 383.3, 0, 0, 0 + ], + "temperature_forecast": [ + 18.3, 17.8, 16.9, 16.2, 15.6, 15.1, 14.6, 14.2, 14.3, 14.8, 15.7, 16.7, 17.4, + 18.0, 18.6, 19.2, 19.1, 18.7, 18.5, 17.7, 16.2, 14.6, 13.6, 13.0, 12.6, 12.2, + 11.7, 11.6, 11.3, 11.0, 10.7, 10.2, 11.4, 14.4, 16.4, 18.3, 19.5, 20.7, 21.9, + 22.7, 23.1, 23.1, 22.8, 21.8, 20.2, 19.1, 18.0, 17.4 + ], + "strompreis_euro_pro_wh": [ + 0.0003384, 0.0003318, 0.0003284, 0.0003283, 0.0003289, 0.0003334, 0.0003290, + 0.0003302, 0.0003042, 0.0002430, 0.0002280, 0.0002212, 0.0002093, 0.0001879, + 0.0001838, 0.0002004, 0.0002198, 0.0002270, 0.0002997, 0.0003195, 0.0003081, + 0.0002969, 0.0002921, 0.0002780, 0.0003384, 0.0003318, 0.0003284, 0.0003283, + 0.0003289, 0.0003334, 0.0003290, 0.0003302, 0.0003042, 0.0002430, 0.0002280, + 0.0002212, 0.0002093, 0.0001879, 0.0001838, 0.0002004, 0.0002198, 0.0002270, + 0.0002997, 0.0003195, 0.0003081, 0.0002969, 0.0002921, 0.0002780 + ], + "eauto_min_soc": 80, + "eauto_cap": 60000, + "eauto_charge_efficiency": 0.95, + "eauto_charge_power": 11040, + "eauto_soc": 5, + "pvpowernow": 211.137503624, + "start_solution": null, + "haushaltsgeraet_wh": 5000, + "haushaltsgeraet_dauer": 2, + "min_soc_prozent": 15 + } + \ No newline at end of file diff --git a/tests/testdata/optimize_result_2.json b/tests/testdata/optimize_result_2.json new file mode 100644 index 0000000..bd643bb --- /dev/null +++ b/tests/testdata/optimize_result_2.json @@ -0,0 +1,99 @@ +{ + "ac_charge": [ + 0.0, 0.0, 0.6, 0.4, 0.0, 0.4, 0.0, 0.8, 1.0, 0.6, 0.0, 0.4, 1.0, 0.6, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.4, 0.6, 0.0, 0.4, 0.2, 0.6, 0.6, 0.2, 0.4, 0.2, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 1.0, 1.0, 0.2, 0.0, 0.6, 0.4, 0.4, 0.2, 1.0, 0.6, 0.0, 0.0 + ], + "dc_charge": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "discharge_allowed": [ + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 + ], + "eautocharge_hours_float": [ + 0.0, 0.375, 0.875, 0.375, 0.5, 0.75, 1.0, 1.0, 0.875, 0.0, 0.5, 0.375, 1.0, 0.875, 1.0, 0.625, 0.5, 1.0, 1.0, 0.375, 0.375, 0.375, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "result": { + "Last_Wh_pro_Stunde": [ + 6297.07, 6756.91, 16208.56, 15449.029999999999, 16313.488181818184, 7731.82, 6460.22, 6974.78, 1129.12, 1178.71, 1050.98, 988.56, 912.38, 1741.405454545456, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1718.014090909092, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "Netzeinspeisung_Wh_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 813.95, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 128.65999999999985, 448.79999999999995, 1330.3700000000001, 175.26999999999998, 4485.82, 3682.7, 2166.67, 1416.43, 497.68000000000006, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Netzbezug_Wh_pro_Stunde": [ + 366.78999999999996, 5713.66, 15101.82, 14287.339999999998, 10294.668181818184, 2212.75, 2490.34, 3956.8199999999997, 0.0, 171.54000000000008, 731.31, 980.68, 0.0, 1741.405454545456, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 0.0, 799.85, 1382.424090909092, 351.65, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 257.64, 566.69, 987.01, 0.0, 0.0 + ], + "Kosten_Euro_pro_Stunde": [ + 0.08362812, 1.263861592, 3.160810926, 2.6845911859999996, 1.8921600118181823, 0.44343509999999997, 0.547376732, 0.8981981399999999, 0.0, 0.05480703000000003, 0.225316611, 0.291163892, 0.0, 0.48411071636363673, 0.174739608, 0.28801899, 0.22802125600000003, 0.199865757, 0.182970359, 0.162995926, 0.0, 0.26411047, 0.42053340845454584, 0.08545095, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08231598, 0.174597189, 0.293043269, 0.0, 0.0 + ], + "akku_soc_pro_stunde": [ + 58.47796143250689, 65.14462809917354, 81.81129476584022, 91.81129476584022, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 96.07274449035812, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 97.8180526859504, 97.8180526859504, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 96.84060778236915, 94.28822314049587 + ], + "Einnahmen_Euro_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0569765, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.009006199999999989, 0.03141599999999999, 0.0931259, 0.012268899999999998, 0.31400739999999994, 0.257789, 0.1516669, 0.09915009999999999, 0.0348376, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Gesamtbilanz_Euro": 13.525878719636365, + "E-Auto_SoC_pro_Stunde": [ + 13.74, 20.294999999999998, 37.775, 53.06999999999999, 70.55, 81.475, 90.215, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0 + ], + "Gesamteinnahmen_Euro": 1.0602444999999998, + "Gesamtkosten_Euro": 14.586123219636365, + "Verluste_Pro_Stunde": [ + 957.818181818182, 447.0, 1152.0, 843.0, 846.7933884297522, 345.0, 276.0, 309.0, 0.0, 0.0, 0.0, 0.0, 124.41545454545451, 141.38119834710756, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 69.12409090909085, 0.0, 78.55010330578523, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.08954545454549, 80.85954545454547 + ], + "Gesamt_Verluste": 5771.031508264463, + "Haushaltsgeraet_wh_pro_stunde": [ + 0.0, 0.0, 0.0, 2500.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ] + }, + "eauto_obj": { + "kapazitaet_wh": 60000, + "start_soc_prozent": 5, + "soc_wh": 60000.0, + "hours": 48, + "discharge_array": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "charge_array": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "lade_effizienz": 0.95, + "entlade_effizienz": 1.0, + "max_ladeleistung_w": 11040 + }, + "start_solution": [ + 0, 0, 4, 3, 1, 3, 1, 5, 6, 4, 1, 3, 6, 4, 6, 0, 6, 6, 0, 0, 3, 4, 1, 3, 2, 4, 4, 2, 3, 2, 1, 0, 2, 4, 1, 0, 6, 6, 2, 0, 4, 3, 3, 2, 6, 4, 1, 1, 0, 1, 5, 1, 2, 4, 6, 6, 5, 0, 2, 1, 6, 5, 6, 3, 2, 6, 6, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 + ], + "spuelstart": 13, + "simulation_data": { + "Last_Wh_pro_Stunde": [ + 6297.07, 6756.91, 16208.56, 15449.029999999999, 16313.488181818184, 7731.82, 6460.22, 6974.78, 1129.12, 1178.71, 1050.98, 988.56, 912.38, 1741.405454545456, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1718.014090909092, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "Netzeinspeisung_Wh_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 813.95, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 128.65999999999985, 448.79999999999995, 1330.3700000000001, 175.26999999999998, 4485.82, 3682.7, 2166.67, 1416.43, 497.68000000000006, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Netzbezug_Wh_pro_Stunde": [ + 366.78999999999996, 5713.66, 15101.82, 14287.339999999998, 10294.668181818184, 2212.75, 2490.34, 3956.8199999999997, 0.0, 171.54000000000008, 731.31, 980.68, 0.0, 1741.405454545456, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 0.0, 799.85, 1382.424090909092, 351.65, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 257.64, 566.69, 987.01, 0.0, 0.0 + ], + "Kosten_Euro_pro_Stunde": [ + 0.08362812, 1.263861592, 3.160810926, 2.6845911859999996, 1.8921600118181823, 0.44343509999999997, 0.547376732, 0.8981981399999999, 0.0, 0.05480703000000003, 0.225316611, 0.291163892, 0.0, 0.48411071636363673, 0.174739608, 0.28801899, 0.22802125600000003, 0.199865757, 0.182970359, 0.162995926, 0.0, 0.26411047, 0.42053340845454584, 0.08545095, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08231598, 0.174597189, 0.293043269, 0.0, 0.0 + ], + "akku_soc_pro_stunde": [ + 58.47796143250689, 65.14462809917354, 81.81129476584022, 91.81129476584022, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 96.07274449035812, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 97.8180526859504, 97.8180526859504, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 96.84060778236915, 94.28822314049587 + ], + "Einnahmen_Euro_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0569765, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.009006199999999989, 0.03141599999999999, 0.0931259, 0.012268899999999998, 0.31400739999999994, 0.257789, 0.1516669, 0.09915009999999999, 0.0348376, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Gesamtbilanz_Euro": 13.525878719636365, + "E-Auto_SoC_pro_Stunde": [ + 13.74, 20.294999999999998, 37.775, 53.06999999999999, 70.55, 81.475, 90.215, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0 + ], + "Gesamteinnahmen_Euro": 1.0602444999999998, + "Gesamtkosten_Euro": 14.586123219636365, + "Verluste_Pro_Stunde": [ + 957.818181818182, 447.0, 1152.0, 843.0, 846.7933884297522, 345.0, 276.0, 309.0, 0.0, 0.0, 0.0, 0.0, 124.41545454545451, 141.38119834710756, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 69.12409090909085, 0.0, 78.55010330578523, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.08954545454549, 80.85954545454547 + ], + "Gesamt_Verluste": 5771.031508264463, + "Haushaltsgeraet_wh_pro_stunde": [ + 0.0, 0.0, 0.0, 2500.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ] + } +} \ No newline at end of file diff --git a/tests/testdata/optimize_result_2_full.json b/tests/testdata/optimize_result_2_full.json new file mode 100644 index 0000000..d2898f0 --- /dev/null +++ b/tests/testdata/optimize_result_2_full.json @@ -0,0 +1,99 @@ +{ + "ac_charge": [ + 0.4, 0.2, 1.0, 0.4, 0.8, 0.6, 0.0, 0.8, 0.6, 1.0, 0.0, 0.0, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.2, 0.2, 1.0, 0.8, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.2, 0.2, 0.2, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "dc_charge": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "discharge_allowed": [ + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 + ], + "eautocharge_hours_float": [ + 0.0, 0.875, 0.625, 0.375, 0.375, 0.5, 0.0, 0.375, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 1.0, 0.875, 0.5, 0.5, 0.625, 1.0, 0.375, 0.875, 0.375, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "result": { + "Last_Wh_pro_Stunde": [ + 6297.07, 1063.91, 12688.56, 18520.03, 18551.67, 11659.115454545456, 6460.22, 6347.78, 1756.12, 1178.71, 1050.98, 988.56, 912.38, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 2494.6908545454626, 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "Netzeinspeisung_Wh_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 186.95000000000005, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3682.7, 2166.67, 1416.43, 497.68000000000006, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Netzbezug_Wh_pro_Stunde": [ + 366.78999999999996, 0.0, 11581.82, 17358.339999999997, 12532.85, 6140.045454545456, 2490.34, 3329.8199999999997, 0.0, 171.54000000000008, 731.31, 980.68, 912.38, 704.61, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1262.0208545454625, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Kosten_Euro_pro_Stunde": [ + 0.08362812, 0.0, 2.424074926, 3.261632085999999, 2.30353783, 1.2304651090909093, 0.547376732, 0.7558691399999999, 0.0, 0.05480703000000003, 0.225316611, 0.291163892, 0.26650619799999997, 0.19588158, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.231959433065456, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "akku_soc_pro_stunde": [ + 58.47796143250689, 58.38903236914601, 61.722365702479344, 78.38903236914601, 95.05569903581267, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 97.77733298898072, 94.04089187327823, 91.05216942148759, 88.43168904958677, 86.03710399449034, 83.93272210743798, 81.75077479338839, 78.30789428374652, 74.83686294765836, 73.32321797520657, 73.75208464187324, 75.24808464187323, 79.6826513085399, 80.26688464187325, 100.0, 100.0, 100.0, 100.0, 100.0, 98.89101239669421, 96.45174758953168, 92.20325413223141, 89.04386191460057, 86.4914772727273 + ], + "Einnahmen_Euro_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.013086500000000003, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.257789, 0.1516669, 0.09915009999999999, 0.0348376, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Gesamtbilanz_Euro": 11.315688587156364, + "E-Auto_SoC_pro_Stunde": [ + 13.74, 13.74, 31.22, 48.699999999999996, 66.18, 81.475, 90.215, 98.955, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0 + ], + "Gesamteinnahmen_Euro": 0.5565300999999999, + "Gesamtkosten_Euro": 11.872218687156364, + "Verluste_Pro_Stunde": [ + 957.818181818182, 2.817272727272737, 672.0, 1152.0, 1152.0, 660.994834710744, 276.0, 276.0, 33.0, 0.0, 0.0, 0.0, 0.0, 0.0, 70.41409090909087, 118.37045454545455, 94.68272727272722, 83.01681818181817, 75.86045454545456, 66.66681818181814, 69.12409090909085, 109.0704545454546, 109.96227272727276, 47.952272727272714, 15.439199999999985, 53.855999999999995, 159.6443999999999, 21.032399999999996, 710.3921528925632, 0.0, 0.0, 0.0, 0.0, 35.132727272727266, 77.27590909090907, 134.59227272727276, 100.08954545454549, 80.85954545454547 + ], + "Gesamt_Verluste": 7416.064896694217, + "Haushaltsgeraet_wh_pro_stunde": [ + 0.0, 0.0, 0.0, 2500.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ] + }, + "eauto_obj": { + "kapazitaet_wh": 60000, + "start_soc_prozent": 5, + "soc_wh": 60000.0, + "hours": 48, + "discharge_array": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "charge_array": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "lade_effizienz": 0.95, + "entlade_effizienz": 1.0, + "max_ladeleistung_w": 11040 + }, + "start_solution": [ + 3, 2, 6, 3, 5, 4, 1, 5, 4, 6, 1, 1, 2, 6, 6, 6, 6, 6, 1, 2, 2, 6, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 6, 2, 2, 2, 6, 1, 1, 1, 1, 1, 0, 5, 3, 1, 1, 2, 0, 1, 0, 6, 2, 0, 6, 6, 6, 5, 2, 2, 3, 6, 1, 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 + ], + "spuelstart": 13, + "simulation_data": { + "Last_Wh_pro_Stunde": [ + 6297.07, 1063.91, 12688.56, 18520.03, 18551.67, 11659.115454545456, 6460.22, 6347.78, 1756.12, 1178.71, 1050.98, 988.56, 912.38, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 2494.6908545454626, 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "Netzeinspeisung_Wh_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 186.95000000000005, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3682.7, 2166.67, 1416.43, 497.68000000000006, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Netzbezug_Wh_pro_Stunde": [ + 366.78999999999996, 0.0, 11581.82, 17358.339999999997, 12532.85, 6140.045454545456, 2490.34, 3329.8199999999997, 0.0, 171.54000000000008, 731.31, 980.68, 912.38, 704.61, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1262.0208545454625, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Kosten_Euro_pro_Stunde": [ + 0.08362812, 0.0, 2.424074926, 3.261632085999999, 2.30353783, 1.2304651090909093, 0.547376732, 0.7558691399999999, 0.0, 0.05480703000000003, 0.225316611, 0.291163892, 0.26650619799999997, 0.19588158, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.231959433065456, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "akku_soc_pro_stunde": [ + 58.47796143250689, 58.38903236914601, 61.722365702479344, 78.38903236914601, 95.05569903581267, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 97.77733298898072, 94.04089187327823, 91.05216942148759, 88.43168904958677, 86.03710399449034, 83.93272210743798, 81.75077479338839, 78.30789428374652, 74.83686294765836, 73.32321797520657, 73.75208464187324, 75.24808464187323, 79.6826513085399, 80.26688464187325, 100.0, 100.0, 100.0, 100.0, 100.0, 98.89101239669421, 96.45174758953168, 92.20325413223141, 89.04386191460057, 86.4914772727273 + ], + "Einnahmen_Euro_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.013086500000000003, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.257789, 0.1516669, 0.09915009999999999, 0.0348376, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Gesamtbilanz_Euro": 11.315688587156364, + "E-Auto_SoC_pro_Stunde": [ + 13.74, 13.74, 31.22, 48.699999999999996, 66.18, 81.475, 90.215, 98.955, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0 + ], + "Gesamteinnahmen_Euro": 0.5565300999999999, + "Gesamtkosten_Euro": 11.872218687156364, + "Verluste_Pro_Stunde": [ + 957.818181818182, 2.817272727272737, 672.0, 1152.0, 1152.0, 660.994834710744, 276.0, 276.0, 33.0, 0.0, 0.0, 0.0, 0.0, 0.0, 70.41409090909087, 118.37045454545455, 94.68272727272722, 83.01681818181817, 75.86045454545456, 66.66681818181814, 69.12409090909085, 109.0704545454546, 109.96227272727276, 47.952272727272714, 15.439199999999985, 53.855999999999995, 159.6443999999999, 21.032399999999996, 710.3921528925632, 0.0, 0.0, 0.0, 0.0, 35.132727272727266, 77.27590909090907, 134.59227272727276, 100.08954545454549, 80.85954545454547 + ], + "Gesamt_Verluste": 7416.064896694217, + "Haushaltsgeraet_wh_pro_stunde": [ + 0.0, 0.0, 0.0, 2500.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ] + } +} \ No newline at end of file diff --git a/tests/testdata/visualize_input_1.json b/tests/testdata/visualize_input_1.json new file mode 100644 index 0000000..318c975 --- /dev/null +++ b/tests/testdata/visualize_input_1.json @@ -0,0 +1,63 @@ +{ + "gesamtlast": [ + 676.71, 876.19, 527.13, 468.88, 531.38, 517.95, 483.15, 472.28, 1011.68, 995.0, 1053.07, 1063.91, 1320.56, 1132.03, 1163.67, 1176.82, 1216.22, 1103.78, 1129.12, 1178.71, 1050.98, 988.56, 912.38, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "pv_forecast": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "strompreise": [ + 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.001, 0.00005, 0.00005, 0.00005, 0.00005, 0.001, 0.001, 0.001, 0.001, 0.001, 0.00001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001 + ], + "ergebnisse": { + "Last_Wh_pro_Stunde": [ + 12493.71, 10502.19, 12775.13, 15356.88, 11468.38, 4037.95, 6047.15, 3112.2799999999997, 3211.68, 995.0, 1053.07, 1063.91, 1320.56, 1132.03, 1163.67, 1176.82, 1216.22, 1103.78, 1129.12, 1178.71, 1050.98, 988.56, 2035.7436363636361, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, 871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 + ], + "Netzeinspeisung_Wh_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3679.44, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Netzbezug_Wh_pro_Stunde": [ + 12493.71, 10502.19, 12775.13, 15356.88, 11468.38, 4037.95, 6047.15, 3112.2799999999997, 3211.68, 995.0, 1053.07, 1063.91, 0.0, 1132.03, 1163.67, 1176.82, 1216.22, 1103.78, 1129.12, 1178.71, 1050.98, 0.0, 2035.7436363636361, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, 488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, 871.26, 860.88, 1158.03, 0.0, 1221.04, 0.0, 0.0, 0.0, 592.97 + ], + "Kosten_Euro_pro_Stunde": [ + 0.1249371, 0.10502190000000002, 0.1277513, 0.1535688, 0.1146838, 0.0403795, 0.060471500000000004, 0.0311228, 0.0321168, 0.00995, 1.05307, 0.05319550000000001, 0.0, 0.0566015, 0.058183500000000006, 1.17682, 1.21622, 1.10378, 1.12912, 1.1787100000000001, 0.010509800000000001, 0.0, 2.035743636363636, 0.7046100000000001, 0.51637, 0.86805, 0.6943400000000001, 0.6087899999999999, 0.55631, 0.48889, 0.5069100000000001, 0.80489, 1.14198, 1.05697, 0.99246, 1.15599, 0.82701, 1.25798, 1.2326700000000002, 0.87126, 0.86088, 1.15803, 0.0, 1.22104, 0.0, 0.0, 0.0, 0.59297 + ], + "akku_soc_pro_stunde": [ + 25.0, 31.666666666666664, 38.333333333333336, 55.00000000000001, 61.66666666666667, 75.0, 81.66666666666667, 91.66666666666666, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 95.7448347107438, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 94.73691460055097, 94.73691460055097, 90.64777031680441, 86.39927685950414, 83.23988464187329, 83.23988464187329 + ], + "Einnahmen_Euro_pro_Stunde": [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2575608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "Gesamtbilanz_Euro": 27.732796636363638, + "E-Auto_SoC_pro_Stunde": [ + 30.294999999999998, 43.405, 60.885, 78.365, 93.66, 93.66, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0 + ], + "Gesamteinnahmen_Euro": 0.2575608, + "Gesamtkosten_Euro": 27.990357436363638, + "Verluste_Pro_Stunde": [ + 843.0, 654.0, 792.0, 1152.0, 723.0, 480.0, 440.2105263157896, 360.0, 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 134.80363636363631, 153.18595041322305, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 166.73454545454547, 0.0, 129.54409090909098, 134.59227272727276, 100.08954545454549, 0.0 + ], + "Gesamt_Verluste": 6563.160567638104, + "Haushaltsgeraet_wh_pro_stunde": [ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null + ] + }, + "ac": [ + 0.6, 0.4, 0.4, 1.0, 0.4, 0.8, 0.4, 0.6, 1.0, 0.2, 0.2, 0.2, 0.6, 0.0, 0.2, 0.6, 0.0, 0.0, 0.8, 0.8, 0.4, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.2, 0.8, 0.2, 0.4, 0.6, 1.0, 0.0, 1.0, 0.8, 0.4, 0.4, 1.0, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + ], + "dc": [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + "discharge": [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0 + ], + "temperature": [ + 18.3, 17.8, 16.9, 16.2, 15.6, 15.1, 14.6, 14.2, 14.3, 14.8, 15.7, 16.7, 17.4, 18.0, 18.6, 19.2, 19.1, 18.7, 18.5, 17.7, 16.2, 14.6, 13.6, 13.0, 12.6, 12.2, 11.7, 11.6, 11.3, 11.0, 10.7, 10.2, 11.4, 14.4, 16.4, 18.3, 19.5, 20.7, 21.9, 22.7, 23.1, 23.1, 22.8, 21.8, 20.2, 19.1, 18.0, 17.4 + ], + "start_hour": 0, + "prediction_hours": 48, + "einspeiseverguetung_euro_pro_wh": [ + 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007, 0.00007 + ], + "filename": "visualize_output_1.pdf", + "extra_data": null +}