epyt-flow 0.10.0__tar.gz → 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/PKG-INFO +15 -4
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/README.md +11 -0
- epyt_flow-0.12.0/epyt_flow/VERSION +1 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/gecco_water_quality.py +2 -2
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/leakdb.py +40 -5
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/water_usage.py +4 -3
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/networks.py +27 -14
- epyt_flow-0.12.0/epyt_flow/gym/__init__.py +1 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/gym/scenario_control_env.py +11 -13
- epyt_flow-0.10.0/epyt_flow/rest_api/scenario/event_handlers.py → epyt_flow-0.12.0/epyt_flow/rest_api/scenario/control_handlers.py +20 -20
- epyt_flow-0.12.0/epyt_flow/rest_api/scenario/event_handlers.py +231 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scenario/handlers.py +33 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/server.py +14 -2
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/serialization.py +1 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/__init__.py +0 -1
- epyt_flow-0.12.0/epyt_flow/simulation/backend/__init__.py +1 -0
- epyt_flow-0.12.0/epyt_flow/simulation/backend/my_epyt.py +1056 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/actuator_events.py +7 -1
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/quality_events.py +3 -1
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scada/scada_data.py +716 -5
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scenario_config.py +1 -40
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scenario_simulator.py +645 -119
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/sensor_config.py +18 -2
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/topology.py +24 -7
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/uncertainty/model_uncertainty.py +80 -62
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/uncertainty/sensor_noise.py +15 -4
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/uncertainty/uncertainties.py +71 -18
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/uncertainty/utils.py +40 -13
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/utils.py +45 -1
- epyt_flow-0.12.0/epyt_flow/visualization/__init__.py +2 -0
- epyt_flow-0.12.0/epyt_flow/visualization/scenario_visualizer.py +1240 -0
- epyt_flow-0.12.0/epyt_flow/visualization/visualization_utils.py +738 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow.egg-info/PKG-INFO +15 -4
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow.egg-info/SOURCES.txt +7 -8
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/pyproject.toml +1 -2
- epyt_flow-0.10.0/epyt_flow/VERSION +0 -1
- epyt_flow-0.10.0/epyt_flow/gym/__init__.py +0 -4
- epyt_flow-0.10.0/epyt_flow/gym/control_gyms.py +0 -47
- epyt_flow-0.10.0/epyt_flow/metrics.py +0 -466
- epyt_flow-0.10.0/epyt_flow/models/__init__.py +0 -2
- epyt_flow-0.10.0/epyt_flow/models/event_detector.py +0 -31
- epyt_flow-0.10.0/epyt_flow/models/sensor_interpolation_detector.py +0 -118
- epyt_flow-0.10.0/epyt_flow/simulation/scada/advanced_control.py +0 -138
- epyt_flow-0.10.0/epyt_flow/simulation/scenario_visualizer.py +0 -1307
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/CITATION.cff +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/CODE_OF_CONDUCT.md +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/LICENSE +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/MANIFEST.in +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/REQUIREMENTS.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/hash.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/hash.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/input1.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/input2.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/input3.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/main.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/output.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/project.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/quality.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/report.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/rules.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/text.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET/SRC_engines/types.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/hash.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/hash.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/newton.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/newton.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/EPANET-MSX/readme.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/compile_linux.sh +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/EPANET/compile_macos.sh +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/batadal.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/batadal_data.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/battledim.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/battledim_data.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/data/benchmarks/leakdb_data.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/base_handler.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/res_manager.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scada_data/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scada_data/data_handlers.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scada_data/export_handlers.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scada_data/handlers.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scenario/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scenario/simulation_handlers.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/rest_api/scenario/uncertainty_handlers.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/event.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/leakages.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/sensor_faults.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/sensor_reading_attack.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/sensor_reading_event.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/events/system_event.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/parallel_simulation.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scada/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scada/complex_control.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scada/custom_control.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scada/scada_data_export.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/simulation/scada/simple_control.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow/uncertainty/__init__.py +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow.egg-info/dependency_links.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow.egg-info/requires.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/epyt_flow.egg-info/top_level.txt +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/setup.cfg +0 -0
- {epyt_flow-0.10.0 → epyt_flow-0.12.0}/setup.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: epyt-flow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: EPyT-Flow -- EPANET Python Toolkit - Flow
|
|
5
5
|
Author-email: André Artelt <aartelt@techfak.uni-bielefeld.de>, "Marios S. Kyriakou" <kiriakou.marios@ucy.ac.cy>, "Stelios G. Vrachimis" <vrachimis.stelios@ucy.ac.cy>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/WaterFutures/EPyT-Flow
|
|
8
8
|
Project-URL: Documentation, https://epyt-flow.readthedocs.io/en/stable/
|
|
9
9
|
Project-URL: Repository, https://github.com/WaterFutures/EPyT-Flow.git
|
|
@@ -11,7 +11,6 @@ Project-URL: Issues, https://github.com/WaterFutures/EPyT-Flow/issues
|
|
|
11
11
|
Keywords: epanet,water,networks,hydraulics,quality,simulations
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Intended Audience :: Science/Research
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
14
|
Classifier: Programming Language :: Python :: 3
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -35,6 +34,7 @@ Requires-Dist: geopandas>=0.14.4
|
|
|
35
34
|
Requires-Dist: svgpath2mpl>=1.0.0
|
|
36
35
|
Requires-Dist: Deprecated>=1.2.14
|
|
37
36
|
Requires-Dist: psutil
|
|
37
|
+
Dynamic: license-file
|
|
38
38
|
|
|
39
39
|
[](https://pypi.org/project/epyt-flow/)
|
|
40
40
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -184,6 +184,17 @@ Besides that, you can read in-depth about the different functionalities of EPyT-
|
|
|
184
184
|
we recommend reading the chapters in the order in which they are presented;
|
|
185
185
|
you might decide to skip some of the last chapters if their content is not relevant to you.
|
|
186
186
|
|
|
187
|
+
## More Networks and Benchmarks
|
|
188
|
+
|
|
189
|
+
More Water Distribution Networks (WDNs) and benchmarks are available on the
|
|
190
|
+
[WaterBenchmarkHub](https://waterfutures.github.io/WaterBenchmarkHub) platform.
|
|
191
|
+
|
|
192
|
+
## More on Control
|
|
193
|
+
|
|
194
|
+
We recommend checking out [EPyT-Control](https://github.com/WaterFutures/EPyT-Control)
|
|
195
|
+
if you are intersted in (data-driven) control and relates tasks such as state estimation
|
|
196
|
+
and event diagnosis in Water Distribution Networks.
|
|
197
|
+
|
|
187
198
|
## License
|
|
188
199
|
|
|
189
200
|
MIT license -- see [LICENSE](LICENSE)
|
|
@@ -146,6 +146,17 @@ Besides that, you can read in-depth about the different functionalities of EPyT-
|
|
|
146
146
|
we recommend reading the chapters in the order in which they are presented;
|
|
147
147
|
you might decide to skip some of the last chapters if their content is not relevant to you.
|
|
148
148
|
|
|
149
|
+
## More Networks and Benchmarks
|
|
150
|
+
|
|
151
|
+
More Water Distribution Networks (WDNs) and benchmarks are available on the
|
|
152
|
+
[WaterBenchmarkHub](https://waterfutures.github.io/WaterBenchmarkHub) platform.
|
|
153
|
+
|
|
154
|
+
## More on Control
|
|
155
|
+
|
|
156
|
+
We recommend checking out [EPyT-Control](https://github.com/WaterFutures/EPyT-Control)
|
|
157
|
+
if you are intersted in (data-driven) control and relates tasks such as state estimation
|
|
158
|
+
and event diagnosis in Water Distribution Networks.
|
|
159
|
+
|
|
149
160
|
## License
|
|
150
161
|
|
|
151
162
|
MIT license -- see [LICENSE](LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.12.0
|
|
@@ -17,9 +17,9 @@ import os
|
|
|
17
17
|
from typing import Union
|
|
18
18
|
import numpy as np
|
|
19
19
|
import pandas as pd
|
|
20
|
+
from sklearn.metrics import f1_score
|
|
20
21
|
|
|
21
22
|
from ...utils import get_temp_folder, download_if_necessary
|
|
22
|
-
from ...metrics import f1_score
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def compute_evaluation_score(y_pred: np.ndarray, y: np.ndarray) -> float:
|
|
@@ -41,7 +41,7 @@ def compute_evaluation_score(y_pred: np.ndarray, y: np.ndarray) -> float:
|
|
|
41
41
|
`float`
|
|
42
42
|
Evaluation score.
|
|
43
43
|
"""
|
|
44
|
-
return f1_score(
|
|
44
|
+
return f1_score(y, y_pred)
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def load_gecco2017_water_quality_data(download_dir: str = None, return_X_y: bool = True,
|
|
@@ -13,8 +13,6 @@ This module provides functions for loading the original LeakDB data set
|
|
|
13
13
|
The official scoring/evaluation is implemented in
|
|
14
14
|
:func:`~epyt_flow.data.benchmarks.leakdb.compute_evaluation_score` -- i.e. those results can be
|
|
15
15
|
directly compared to the official paper.
|
|
16
|
-
Besides this, the user can choose to evaluate predictions using any other metric from
|
|
17
|
-
:mod:`~epyt_flow.metrics`.
|
|
18
16
|
"""
|
|
19
17
|
import os
|
|
20
18
|
from typing import Union
|
|
@@ -24,12 +22,12 @@ import scipy
|
|
|
24
22
|
import numpy as np
|
|
25
23
|
import pandas as pd
|
|
26
24
|
from scipy.sparse import bsr_array
|
|
25
|
+
from sklearn.metrics import f1_score, recall_score as true_positive_rate
|
|
27
26
|
|
|
28
27
|
from ..networks import load_net1, load_hanoi
|
|
29
28
|
from .leakdb_data import NET1_LEAKAGES, HANOI_LEAKAGES
|
|
30
29
|
from ...utils import get_temp_folder, to_seconds, unpack_zip_archive, create_path_if_not_exist, \
|
|
31
30
|
download_if_necessary
|
|
32
|
-
from ...metrics import f1_score, true_positive_rate, true_negative_rate
|
|
33
31
|
from ...simulation import ScenarioSimulator, ToolkitConstants
|
|
34
32
|
from ...simulation.events import AbruptLeakage, IncipientLeakage
|
|
35
33
|
from ...simulation import ScenarioConfig
|
|
@@ -37,6 +35,43 @@ from ...simulation.scada import ScadaData
|
|
|
37
35
|
from ...uncertainty import ModelUncertainty, UniformUncertainty
|
|
38
36
|
|
|
39
37
|
|
|
38
|
+
def true_negative_rate(y_pred: np.ndarray, y: np.ndarray) -> float:
|
|
39
|
+
"""
|
|
40
|
+
Computes the true negative rate (also called specificity).
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
y_pred : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
|
|
45
|
+
Predicted labels.
|
|
46
|
+
y : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
|
|
47
|
+
Ground truth labels.
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
`float`
|
|
52
|
+
True negative rate.
|
|
53
|
+
"""
|
|
54
|
+
if not isinstance(y_pred, np.ndarray):
|
|
55
|
+
raise TypeError("'y_pred' must be an instance of 'numpy.ndarray' " +
|
|
56
|
+
f"but not of '{type(y_pred)}'")
|
|
57
|
+
if not isinstance(y, np.ndarray):
|
|
58
|
+
raise TypeError("'y' must be an instance of 'numpy.ndarray' " +
|
|
59
|
+
f"but not of '{type(y)}'")
|
|
60
|
+
if y_pred.shape != y.shape:
|
|
61
|
+
raise ValueError(f"Shape mismatch: {y_pred.shape} vs. {y.shape}")
|
|
62
|
+
if len(y_pred.shape) > 1:
|
|
63
|
+
raise ValueError("'y_pred' must be a 1d array")
|
|
64
|
+
if len(y.shape) > 1:
|
|
65
|
+
raise ValueError("'y' must be a 1d array")
|
|
66
|
+
if set(np.unique(y_pred)) != set([0, 1]):
|
|
67
|
+
raise ValueError("Labels must be either '0' or '1'")
|
|
68
|
+
|
|
69
|
+
tn = np.sum((y == 0) & (y_pred == 0))
|
|
70
|
+
fp = np.sum((y == 0) & (y_pred == 1))
|
|
71
|
+
|
|
72
|
+
return tn / (tn + fp)
|
|
73
|
+
|
|
74
|
+
|
|
40
75
|
def __leak_time_to_idx(t: int, round_up: bool = False, hydraulic_time_step: int = 1800):
|
|
41
76
|
if round_up is False:
|
|
42
77
|
return math.floor(t / hydraulic_time_step)
|
|
@@ -134,8 +169,8 @@ def compute_evaluation_score(scenarios_id: list[int], use_net1: bool,
|
|
|
134
169
|
y_pred = np.stack(y_pred_labels_per_scenario, axis=0)
|
|
135
170
|
|
|
136
171
|
# Evaluate predictions
|
|
137
|
-
f1 = f1_score(
|
|
138
|
-
tpr = true_positive_rate(
|
|
172
|
+
f1 = f1_score(y_true, y_pred)
|
|
173
|
+
tpr = true_positive_rate(y_true, y_pred)
|
|
139
174
|
tnr = true_negative_rate(y_pred, y_true)
|
|
140
175
|
|
|
141
176
|
early_detection_score = 0
|
|
@@ -4,9 +4,9 @@ Module provides a function for loading the water usage data set by P. Pavlou et
|
|
|
4
4
|
import os
|
|
5
5
|
import numpy as np
|
|
6
6
|
import pandas as pd
|
|
7
|
+
from sklearn.metrics import accuracy_score, precision_score, roc_auc_score, f1_score
|
|
7
8
|
|
|
8
9
|
from ...utils import get_temp_folder, download_if_necessary
|
|
9
|
-
from ...metrics import accuracy_score, precision_score, roc_auc_score, f1_micro_score
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def compute_evaluation_score(y_pred: np.ndarray, y: np.ndarray) -> dict:
|
|
@@ -32,8 +32,9 @@ def compute_evaluation_score(y_pred: np.ndarray, y: np.ndarray) -> dict:
|
|
|
32
32
|
`dict`
|
|
33
33
|
All evaluation scores.
|
|
34
34
|
"""
|
|
35
|
-
return {"accuracy": accuracy_score(
|
|
36
|
-
"
|
|
35
|
+
return {"accuracy": accuracy_score(y, y_pred),
|
|
36
|
+
"precision": precision_score(y, y_pred, average="weighted"),
|
|
37
|
+
"f1-micro": f1_score(y, y_pred, average="micro"), "roc-auc": roc_auc_score(y, y_pred)}
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
def load_water_usage(download_dir: str = None, return_X_y: bool = True, verbose: bool = True) -> dict:
|
|
@@ -154,8 +154,9 @@ def load_net1(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
154
154
|
"""
|
|
155
155
|
f_in = os.path.join(download_dir, "Net1.inp")
|
|
156
156
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Net1.inp"
|
|
157
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Net1.inp"]
|
|
157
158
|
|
|
158
|
-
download_if_necessary(f_in, url, verbose)
|
|
159
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
159
160
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
160
161
|
|
|
161
162
|
|
|
@@ -201,8 +202,9 @@ def load_net2(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
201
202
|
"""
|
|
202
203
|
f_in = os.path.join(download_dir, "Net2.inp")
|
|
203
204
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Net2.inp"
|
|
205
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Net2.inp"]
|
|
204
206
|
|
|
205
|
-
download_if_necessary(f_in, url, verbose)
|
|
207
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
206
208
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
207
209
|
|
|
208
210
|
|
|
@@ -248,8 +250,9 @@ def load_net3(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
248
250
|
"""
|
|
249
251
|
f_in = os.path.join(download_dir, "Net3.inp")
|
|
250
252
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Net3.inp"
|
|
253
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Net3.inp"]
|
|
251
254
|
|
|
252
|
-
download_if_necessary(f_in, url, verbose)
|
|
255
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
253
256
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
254
257
|
|
|
255
258
|
|
|
@@ -342,8 +345,9 @@ def load_richmond(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
342
345
|
"""
|
|
343
346
|
f_in = os.path.join(download_dir, "Richmond_standard.inp")
|
|
344
347
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Richmond_standard.inp"
|
|
348
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/Richmond_standard.inp"]
|
|
345
349
|
|
|
346
|
-
download_if_necessary(f_in, url, verbose)
|
|
350
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
347
351
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
348
352
|
|
|
349
353
|
|
|
@@ -389,8 +393,9 @@ def load_micropolis(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
389
393
|
"""
|
|
390
394
|
f_in = os.path.join(download_dir, "MICROPOLIS_v1.inp")
|
|
391
395
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/MICROPOLIS_v1.inp"
|
|
396
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/MICROPOLIS_v1.inp"]
|
|
392
397
|
|
|
393
|
-
download_if_necessary(f_in, url, verbose)
|
|
398
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
394
399
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
395
400
|
|
|
396
401
|
|
|
@@ -436,8 +441,9 @@ def load_balerma(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
436
441
|
"""
|
|
437
442
|
f_in = os.path.join(download_dir, "Balerma.inp")
|
|
438
443
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Balerma.inp"
|
|
444
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/Balerma.inp"]
|
|
439
445
|
|
|
440
|
-
download_if_necessary(f_in, url, verbose)
|
|
446
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
441
447
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
442
448
|
|
|
443
449
|
|
|
@@ -483,8 +489,9 @@ def load_rural(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
483
489
|
"""
|
|
484
490
|
f_in = os.path.join(download_dir, "RuralNetwork.inp")
|
|
485
491
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/RuralNetwork.inp"
|
|
492
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/RuralNetwork.inp"]
|
|
486
493
|
|
|
487
|
-
download_if_necessary(f_in, url, verbose)
|
|
494
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
488
495
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
489
496
|
|
|
490
497
|
|
|
@@ -530,8 +537,9 @@ def load_bwsn1(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
530
537
|
"""
|
|
531
538
|
f_in = os.path.join(download_dir, "BWSN_Network_1.inp")
|
|
532
539
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/BWSN_Network_1.inp"
|
|
540
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/BWSN_Network_1.inp"]
|
|
533
541
|
|
|
534
|
-
download_if_necessary(f_in, url, verbose)
|
|
542
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
535
543
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
536
544
|
|
|
537
545
|
|
|
@@ -577,8 +585,9 @@ def load_bwsn2(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
577
585
|
"""
|
|
578
586
|
f_in = os.path.join(download_dir, "BWSN_Network_2.inp")
|
|
579
587
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/BWSN_Network_2.inp"
|
|
588
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/BWSN_Network_2.inp"]
|
|
580
589
|
|
|
581
|
-
download_if_necessary(f_in, url, verbose)
|
|
590
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
582
591
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
583
592
|
|
|
584
593
|
|
|
@@ -624,8 +633,9 @@ def load_anytown(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
624
633
|
"""
|
|
625
634
|
f_in = os.path.join(download_dir, "Anytown.inp")
|
|
626
635
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Anytown.inp"
|
|
636
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Anytown.inp"]
|
|
627
637
|
|
|
628
|
-
download_if_necessary(f_in, url, verbose)
|
|
638
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
629
639
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
630
640
|
|
|
631
641
|
|
|
@@ -670,9 +680,10 @@ def load_dtown(download_dir: str = get_temp_folder(), verbose: bool = True,
|
|
|
670
680
|
:class:`~epyt_flow.simulation.scenario_simulator.ScenarioSimulator`.
|
|
671
681
|
"""
|
|
672
682
|
f_in = os.path.join(download_dir, "d-town.inp")
|
|
673
|
-
url = "https://
|
|
683
|
+
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/d-town.inp"
|
|
684
|
+
backup_urls = ["https://raw.githubusercontent.com/KIOS-Research/EPANET-Benchmarks/refs/heads/master/collect-epanet-inp/d-town.inp"]
|
|
674
685
|
|
|
675
|
-
download_if_necessary(f_in, url, verbose)
|
|
686
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
676
687
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
677
688
|
|
|
678
689
|
|
|
@@ -774,8 +785,9 @@ def load_kentucky(wdn_id: int = 1, download_dir: str = get_temp_folder(),
|
|
|
774
785
|
|
|
775
786
|
f_in = os.path.join(download_dir, f"ky{wdn_id}.inp")
|
|
776
787
|
url = f"https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/ky{wdn_id}.inp"
|
|
788
|
+
backup_urls = [f"https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/ky{wdn_id}.inp"]
|
|
777
789
|
|
|
778
|
-
download_if_necessary(f_in, url, verbose)
|
|
790
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
779
791
|
return load_inp(f_in, flow_units_id=flow_units_id)
|
|
780
792
|
|
|
781
793
|
|
|
@@ -826,8 +838,9 @@ def load_hanoi(download_dir: str = get_temp_folder(),
|
|
|
826
838
|
"""
|
|
827
839
|
f_in = os.path.join(download_dir, "Hanoi.inp")
|
|
828
840
|
url = "https://filedn.com/lumBFq2P9S74PNoLPWtzxG4/EPyT-Flow/Networks/Hanoi.inp"
|
|
841
|
+
backup_urls = ["https://raw.githubusercontent.com/OpenWaterAnalytics/EPyT/refs/heads/dev/epyt/networks/asce-tf-wdst/Hanoi.inp"]
|
|
829
842
|
|
|
830
|
-
download_if_necessary(f_in, url, verbose)
|
|
843
|
+
download_if_necessary(f_in, url, verbose, backup_urls)
|
|
831
844
|
config = load_inp(f_in, flow_units_id=flow_units_id)
|
|
832
845
|
|
|
833
846
|
if include_default_sensor_placement is True:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .scenario_control_env import *
|
|
@@ -79,11 +79,13 @@ class ScenarioControlEnv(ABC):
|
|
|
79
79
|
if self._sim_generator is not None:
|
|
80
80
|
next(self._sim_generator)
|
|
81
81
|
self._sim_generator.send(True)
|
|
82
|
+
self._sim_generator = None
|
|
82
83
|
except StopIteration:
|
|
83
84
|
pass
|
|
84
85
|
|
|
85
86
|
if self._scenario_sim is not None:
|
|
86
87
|
self._scenario_sim.close()
|
|
88
|
+
self._scenario_sim = None
|
|
87
89
|
|
|
88
90
|
def contains_events(self) -> bool:
|
|
89
91
|
"""
|
|
@@ -106,16 +108,7 @@ class ScenarioControlEnv(ABC):
|
|
|
106
108
|
:class:`~epyt_flow.simulation.scada.scada_data.ScadaData`
|
|
107
109
|
Current SCADA data (i.e. sensor readings).
|
|
108
110
|
"""
|
|
109
|
-
|
|
110
|
-
# Abort current simulation if any is runing
|
|
111
|
-
try:
|
|
112
|
-
next(self._sim_generator)
|
|
113
|
-
self._sim_generator.send(True)
|
|
114
|
-
except StopIteration:
|
|
115
|
-
pass
|
|
116
|
-
|
|
117
|
-
# Close scenario
|
|
118
|
-
self._scenario_sim.close()
|
|
111
|
+
self.close()
|
|
119
112
|
|
|
120
113
|
self._scenario_sim = ScenarioSimulator(
|
|
121
114
|
scenario_config=self._scenario_config)
|
|
@@ -177,9 +170,14 @@ class ScenarioControlEnv(ABC):
|
|
|
177
170
|
raise RuntimeError("Can not execute actions affecting the hydraulics "+
|
|
178
171
|
"when running EPANET-MSX")
|
|
179
172
|
|
|
180
|
-
pump_idx = self._scenario_sim.epanet_api.getLinkPumpNameID().index(pump_id)
|
|
181
|
-
pump_link_idx = self._scenario_sim.epanet_api.getLinkPumpIndex(pump_idx
|
|
182
|
-
|
|
173
|
+
pump_idx = self._scenario_sim.epanet_api.getLinkPumpNameID().index(pump_id) + 1
|
|
174
|
+
pump_link_idx = self._scenario_sim.epanet_api.getLinkPumpIndex(pump_idx)
|
|
175
|
+
|
|
176
|
+
pattern_idx = self._scenario_sim.epanet_api.getLinkPumpPatternIndex(pump_idx)
|
|
177
|
+
if pattern_idx != 0:
|
|
178
|
+
warnings.warn(f"Can not set pump state of pump {pump_id} because a pump pattern exists")
|
|
179
|
+
else:
|
|
180
|
+
self._scenario_sim.epanet_api.setLinkStatus(pump_link_idx, status)
|
|
183
181
|
|
|
184
182
|
def set_pump_speed(self, pump_id: str, speed: float) -> None:
|
|
185
183
|
"""
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"""
|
|
2
|
-
This module provides REST API handlers for
|
|
2
|
+
This module provides REST API handlers for complex and simple control modules of scenarios.
|
|
3
3
|
"""
|
|
4
4
|
import warnings
|
|
5
5
|
import falcon
|
|
6
6
|
|
|
7
7
|
from .handlers import ScenarioBaseHandler
|
|
8
|
-
from ...simulation import
|
|
8
|
+
from ...simulation import ComplexControlModule, SimpleControlModule
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class ScenarioComplexControlHandler(ScenarioBaseHandler):
|
|
12
12
|
"""
|
|
13
|
-
Class for handling GET and POST requests concerning
|
|
13
|
+
Class for handling GET and POST requests concerning complex control modules.
|
|
14
14
|
"""
|
|
15
15
|
def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
|
|
16
16
|
"""
|
|
17
|
-
Gets all
|
|
17
|
+
Gets all complex control modules of a given scenario.
|
|
18
18
|
|
|
19
19
|
Parameters
|
|
20
20
|
----------
|
|
@@ -28,15 +28,15 @@ class ScenarioLeakageHandler(ScenarioBaseHandler):
|
|
|
28
28
|
self.send_invalid_resource_id_error(resp)
|
|
29
29
|
return
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
self.send_json_response(resp,
|
|
31
|
+
my_simple_controls = self.scenario_mgr.get(scenario_id).complex_controls
|
|
32
|
+
self.send_json_response(resp, my_simple_controls)
|
|
33
33
|
except Exception as ex:
|
|
34
34
|
warnings.warn(str(ex))
|
|
35
35
|
resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
|
|
36
36
|
|
|
37
37
|
def on_post(self, req: falcon.Request, resp: falcon.Response, scenario_id: str) -> None:
|
|
38
38
|
"""
|
|
39
|
-
Adds a new
|
|
39
|
+
Adds a new complex control module to a given scenario.
|
|
40
40
|
|
|
41
41
|
Parameters
|
|
42
42
|
----------
|
|
@@ -52,24 +52,24 @@ class ScenarioLeakageHandler(ScenarioBaseHandler):
|
|
|
52
52
|
self.send_invalid_resource_id_error(resp)
|
|
53
53
|
return
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
if not isinstance(
|
|
55
|
+
complex_control = self.load_json_data_from_request(req)
|
|
56
|
+
if not isinstance(complex_control, ComplexControlModule):
|
|
57
57
|
self.send_json_parsing_error(resp)
|
|
58
58
|
return
|
|
59
59
|
|
|
60
|
-
self.scenario_mgr.get(scenario_id).
|
|
60
|
+
self.scenario_mgr.get(scenario_id).add_complex_control(complex_control)
|
|
61
61
|
except Exception as ex:
|
|
62
62
|
warnings.warn(str(ex))
|
|
63
63
|
resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
class
|
|
66
|
+
class ScenarioSimpleControlHandler(ScenarioBaseHandler):
|
|
67
67
|
"""
|
|
68
|
-
Class for handling GET and POST requests concerning
|
|
68
|
+
Class for handling GET and POST requests concerning simple control modules.
|
|
69
69
|
"""
|
|
70
70
|
def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
|
|
71
71
|
"""
|
|
72
|
-
Gets all
|
|
72
|
+
Gets all simple control modules of a given scenario.
|
|
73
73
|
|
|
74
74
|
Parameters
|
|
75
75
|
----------
|
|
@@ -83,15 +83,15 @@ class ScenarioSensorFaultHandler(ScenarioBaseHandler):
|
|
|
83
83
|
self.send_invalid_resource_id_error(resp)
|
|
84
84
|
return
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
self.send_json_response(resp,
|
|
86
|
+
my_simple_controls = self.scenario_mgr.get(scenario_id).simple_controls
|
|
87
|
+
self.send_json_response(resp, my_simple_controls)
|
|
88
88
|
except Exception as ex:
|
|
89
89
|
warnings.warn(str(ex))
|
|
90
90
|
resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
|
|
91
91
|
|
|
92
92
|
def on_post(self, req: falcon.Request, resp: falcon.Response, scenario_id: str) -> None:
|
|
93
93
|
"""
|
|
94
|
-
Adds a new
|
|
94
|
+
Adds a new simple control module to a given scenario.
|
|
95
95
|
|
|
96
96
|
Parameters
|
|
97
97
|
----------
|
|
@@ -107,12 +107,12 @@ class ScenarioSensorFaultHandler(ScenarioBaseHandler):
|
|
|
107
107
|
self.send_invalid_resource_id_error(resp)
|
|
108
108
|
return
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
if not isinstance(
|
|
110
|
+
simple_control = self.load_json_data_from_request(req)
|
|
111
|
+
if not isinstance(simple_control, SimpleControlModule):
|
|
112
112
|
self.send_json_parsing_error(resp)
|
|
113
113
|
return
|
|
114
114
|
|
|
115
|
-
self.scenario_mgr.get(scenario_id).
|
|
115
|
+
self.scenario_mgr.get(scenario_id).add_simple_control(simple_control)
|
|
116
116
|
except Exception as ex:
|
|
117
117
|
warnings.warn(str(ex))
|
|
118
118
|
resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
|