epyt-flow 0.8.1__py3-none-any.whl → 0.10.0__py3-none-any.whl

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.
Files changed (50) hide show
  1. epyt_flow/VERSION +1 -1
  2. epyt_flow/__init__.py +1 -0
  3. epyt_flow/data/benchmarks/batadal.py +1 -1
  4. epyt_flow/data/benchmarks/battledim.py +4 -3
  5. epyt_flow/data/benchmarks/gecco_water_quality.py +4 -4
  6. epyt_flow/data/benchmarks/leakdb.py +7 -7
  7. epyt_flow/data/benchmarks/water_usage.py +2 -2
  8. epyt_flow/data/networks.py +1 -1
  9. epyt_flow/gym/control_gyms.py +2 -2
  10. epyt_flow/gym/scenario_control_env.py +9 -1
  11. epyt_flow/metrics.py +28 -28
  12. epyt_flow/models/sensor_interpolation_detector.py +3 -3
  13. epyt_flow/rest_api/base_handler.py +4 -4
  14. epyt_flow/rest_api/scada_data/data_handlers.py +11 -11
  15. epyt_flow/rest_api/scada_data/export_handlers.py +2 -2
  16. epyt_flow/rest_api/scada_data/handlers.py +9 -9
  17. epyt_flow/rest_api/scenario/event_handlers.py +6 -6
  18. epyt_flow/rest_api/scenario/handlers.py +15 -15
  19. epyt_flow/rest_api/scenario/simulation_handlers.py +7 -7
  20. epyt_flow/rest_api/scenario/uncertainty_handlers.py +6 -6
  21. epyt_flow/serialization.py +8 -2
  22. epyt_flow/simulation/events/actuator_events.py +1 -1
  23. epyt_flow/simulation/events/leakages.py +1 -1
  24. epyt_flow/simulation/events/quality_events.py +16 -5
  25. epyt_flow/simulation/events/sensor_reading_attack.py +17 -4
  26. epyt_flow/simulation/events/sensor_reading_event.py +21 -6
  27. epyt_flow/simulation/events/system_event.py +1 -1
  28. epyt_flow/simulation/parallel_simulation.py +1 -1
  29. epyt_flow/simulation/scada/__init__.py +3 -1
  30. epyt_flow/simulation/scada/advanced_control.py +8 -4
  31. epyt_flow/simulation/scada/complex_control.py +625 -0
  32. epyt_flow/simulation/scada/custom_control.py +134 -0
  33. epyt_flow/simulation/scada/scada_data.py +133 -130
  34. epyt_flow/simulation/scada/scada_data_export.py +1 -1
  35. epyt_flow/simulation/scada/simple_control.py +317 -0
  36. epyt_flow/simulation/scenario_config.py +124 -24
  37. epyt_flow/simulation/scenario_simulator.py +514 -49
  38. epyt_flow/simulation/scenario_visualizer.py +9 -9
  39. epyt_flow/simulation/sensor_config.py +38 -28
  40. epyt_flow/topology.py +2 -2
  41. epyt_flow/uncertainty/model_uncertainty.py +624 -147
  42. epyt_flow/uncertainty/sensor_noise.py +94 -19
  43. epyt_flow/uncertainty/uncertainties.py +4 -4
  44. epyt_flow/uncertainty/utils.py +7 -7
  45. epyt_flow/utils.py +9 -8
  46. {epyt_flow-0.8.1.dist-info → epyt_flow-0.10.0.dist-info}/LICENSE +1 -1
  47. {epyt_flow-0.8.1.dist-info → epyt_flow-0.10.0.dist-info}/METADATA +7 -6
  48. {epyt_flow-0.8.1.dist-info → epyt_flow-0.10.0.dist-info}/RECORD +50 -47
  49. {epyt_flow-0.8.1.dist-info → epyt_flow-0.10.0.dist-info}/WHEEL +1 -1
  50. {epyt_flow-0.8.1.dist-info → epyt_flow-0.10.0.dist-info}/top_level.txt +0 -0
@@ -54,7 +54,7 @@ class ScenarioRemoveHandler(ScenarioBaseHandler):
54
54
 
55
55
  Parameters
56
56
  ----------
57
- resp : `falcon.Response`
57
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
58
58
  Response instance.
59
59
  scenario_id : `str`
60
60
  UUID of the scenario.
@@ -95,7 +95,7 @@ class ScenarioExportHandler(ScenarioBaseHandler):
95
95
 
96
96
  Parameters
97
97
  ----------
98
- resp : `falcon.Response`
98
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
99
99
  Response instance.
100
100
  tmp_file : `str`
101
101
  Path to the temporary file to be send.
@@ -111,7 +111,7 @@ class ScenarioExportHandler(ScenarioBaseHandler):
111
111
 
112
112
  Parameters
113
113
  ----------
114
- resp : `falcon.Response`
114
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
115
115
  Response instance.
116
116
  scenario_id : `str`
117
117
  UUID of the scenario.
@@ -152,7 +152,7 @@ class ScenarioConfigHandler(ScenarioBaseHandler):
152
152
 
153
153
  Parameters
154
154
  ----------
155
- resp : `falcon.Response`
155
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
156
156
  Response instance.
157
157
  scenario_id : `str`
158
158
  UUID of the scenario.
@@ -179,9 +179,9 @@ class ScenarioNewHandler(ScenarioBaseHandler):
179
179
 
180
180
  Parameters
181
181
  ----------
182
- req : `falcon.Request`
182
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
183
183
  Request instance.
184
- resp : `falcon.Response`
184
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
185
185
  Response instance.
186
186
  scenario_id : `str`
187
187
  UUID of the scenario.
@@ -205,7 +205,7 @@ class ScenarioTopologyHandler(ScenarioBaseHandler):
205
205
 
206
206
  Parameters
207
207
  ----------
208
- resp : `falcon.Response`
208
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
209
209
  Response instance.
210
210
  scenario_id : `str`
211
211
  UUID of the scenario.
@@ -232,7 +232,7 @@ class ScenarioGeneralParamsHandler(ScenarioBaseHandler):
232
232
 
233
233
  Parameters
234
234
  ----------
235
- resp : `falcon.Response`
235
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
236
236
  Response instance.
237
237
  scenario_id : `str`
238
238
  UUID of the scenario.
@@ -255,9 +255,9 @@ class ScenarioGeneralParamsHandler(ScenarioBaseHandler):
255
255
 
256
256
  Parameters
257
257
  ----------
258
- req : `falcon.Request`
258
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
259
259
  Request instance.
260
- resp : `falcon.Request`
260
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
261
261
  Request instance.
262
262
  scenario_id : `str`
263
263
  UUID of the scenario.
@@ -288,7 +288,7 @@ class ScenarioSensorConfigHandler(ScenarioBaseHandler):
288
288
 
289
289
  Parameters
290
290
  ----------
291
- resp : `falcon.Response`
291
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
292
292
  Response instance.
293
293
  scenario_id : `str`
294
294
  UUID of the scenario.
@@ -310,9 +310,9 @@ class ScenarioSensorConfigHandler(ScenarioBaseHandler):
310
310
 
311
311
  Parameters
312
312
  ----------
313
- req : `falcon.Request`
313
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
314
314
  Request instance.
315
- resp : `falcon.Request`
315
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
316
316
  Request instance.
317
317
  scenario_id : `str`
318
318
  UUID of the scenario.
@@ -345,9 +345,9 @@ class ScenarioNodeDemandPatternHandler(ScenarioBaseHandler):
345
345
 
346
346
  Parameters
347
347
  ----------
348
- req : `falcon.Request`
348
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
349
349
  Request instance.
350
- resp : `falcon.Response`
350
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
351
351
  Response instance.
352
352
  scenario_id : `str`
353
353
  UUID of the scenario.
@@ -33,9 +33,9 @@ class ScenarioSimulationHandler(ScenarioBaseHandler):
33
33
 
34
34
  Parameters
35
35
  ----------
36
- req : `falcon.Request`
36
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
37
37
  Request instance.
38
- resp : `falcon.Response`
38
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
39
39
  Response instance.
40
40
  scenario_id : `str`
41
41
  UUID of the scenario.
@@ -63,7 +63,7 @@ class ScenarioSimulationHandler(ScenarioBaseHandler):
63
63
 
64
64
  Parameters
65
65
  ----------
66
- resp : `falcon.Response`
66
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
67
67
  Response instance.
68
68
  scenario_id : `str`
69
69
  UUID of the scenario.
@@ -104,9 +104,9 @@ class ScenarioBasicQualitySimulationHandler(ScenarioBaseHandler):
104
104
 
105
105
  Parameters
106
106
  ----------
107
- req : `falcon.Request`
107
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
108
108
  Request instance.
109
- resp : `falcon.Response`
109
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
110
110
  Response instance.
111
111
  scenario_id : `str`
112
112
  UUID of the scenario.
@@ -149,9 +149,9 @@ class ScenarioAdvancedQualitySimulationHandler(ScenarioBaseHandler):
149
149
 
150
150
  Parameters
151
151
  ----------
152
- req : `falcon.Request`
152
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
153
153
  Request instance.
154
- resp : `falcon.Response`
154
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
155
155
  Response instance.
156
156
  scenario_id : `str`
157
157
  UUID of the scenario.
@@ -18,7 +18,7 @@ class ScenarioModelUncertaintyHandler(ScenarioBaseHandler):
18
18
 
19
19
  Parameters
20
20
  ----------
21
- resp : `falcon.Response`
21
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
22
22
  Response instance.
23
23
  scenario_id : `str`
24
24
  UUID of the scenario.
@@ -40,9 +40,9 @@ class ScenarioModelUncertaintyHandler(ScenarioBaseHandler):
40
40
 
41
41
  Parameters
42
42
  ----------
43
- req : `falcon.Request`
43
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
44
44
  Request instance.
45
- resp : `falcon.Response`
45
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
46
46
  Response instance.
47
47
  scenario_id : `str`
48
48
  UUID of the scenario.
@@ -73,7 +73,7 @@ class ScenarioSensorUncertaintyHandler(ScenarioBaseHandler):
73
73
 
74
74
  Parameters
75
75
  ----------
76
- resp : `falcon.Response`
76
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
77
77
  Response instance.
78
78
  scenario_id : `str`
79
79
  UUID of the scenario.
@@ -95,9 +95,9 @@ class ScenarioSensorUncertaintyHandler(ScenarioBaseHandler):
95
95
 
96
96
  Parameters
97
97
  ----------
98
- req : `falcon.Request`
98
+ req : `falcon.Request <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#request>`_
99
99
  Request instance.
100
- resp : `falcon.Response`
100
+ resp : `falcon.Response <https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#response>`_
101
101
  Response instance.
102
102
  scenario_id : `str`
103
103
  UUID of the scenario.
@@ -48,18 +48,24 @@ PUMP_STATE_EVENT_ID = 28
48
48
  PUMP_SPEED_EVENT_ID = 29
49
49
  VALVE_STATE_EVENT_ID = 30
50
50
  SPECIESINJECTION_EVENT_ID = 31
51
+ SIMPLE_CONTROL_ID = 32
52
+ COMPLEX_CONTROL_ID = 33
53
+ COMPLEX_CONTROL_CONDITION_ID = 34
54
+ COMPLEX_CONTROL_ACTION_ID = 35
51
55
 
52
56
 
53
57
  def my_packb(data: Any) -> bytes:
54
58
  """
55
- Overriden `umsgpack.packb` method to support custom serialization handlers.
59
+ Overriden `umsgpack.packb <https://msgpack-python.readthedocs.io/en/latest/api.html#msgpack.packb>`_
60
+ method to support custom serialization handlers.
56
61
  """
57
62
  return umsgpack.packb(data, ext_handlers=ext_handler_pack)
58
63
 
59
64
 
60
65
  def my_unpackb(data: Any) -> Any:
61
66
  """
62
- Overriden `umsgpack.unpackb` method to support custom serialization handlers.
67
+ Overriden `umsgpack.unpackb <https://msgpack-python.readthedocs.io/en/latest/api.html#msgpack.unpackb>`_
68
+ method to support custom serialization handlers.
63
69
  """
64
70
  return umsgpack.unpackb(data, ext_handlers=ext_handler_unpack)
65
71
 
@@ -180,7 +180,7 @@ class PumpSpeedEvent(PumpEvent, JsonSerializable):
180
180
  if pattern_idx == 0:
181
181
  warnings.warn(f"No pattern for pump '{self.pump_id}' found -- a new pattern is created")
182
182
  pattern_idx = self._epanet_api.addPattern(f"pump_speed_{self.pump_id}")
183
- self._epanet_api.setLinkPumpPatternIndex(pattern_idx)
183
+ self._epanet_api.setLinkPumpPatternIndex(pump_idx, pattern_idx)
184
184
 
185
185
  self._epanet_api.setPattern(pattern_idx, np.array([self.__pump_speed]))
186
186
 
@@ -37,7 +37,7 @@ class Leakage(SystemEvent, JsonSerializable):
37
37
  in this case, 'area' must be set to 'None'.
38
38
 
39
39
  The default is None.
40
- profile : `numpy.ndarray`
40
+ profile : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
41
41
  Pattern of this leak.
42
42
  node_id : `str`, optional
43
43
  ID of the node at which the leak is placed.
@@ -24,7 +24,7 @@ class SpeciesInjectionEvent(SystemEvent, JsonSerializable):
24
24
  ID of the bulk species that is going to be injected.
25
25
  node_id : `str`
26
26
  ID of the node at which the injection is palced.
27
- profile : `numpy.ndarray`
27
+ profile : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
28
28
  Injection strength profile -- i.e. every entry corresponds to the strength of the injection
29
29
  at a point in time. Pattern will repeat if it is shorter than the total injection time.
30
30
  source_type : `int`
@@ -136,7 +136,7 @@ class SpeciesInjectionEvent(SystemEvent, JsonSerializable):
136
136
  f"node_id: {self.__node_id} profile: {self.__profile} source_type: {self.__source_type}"
137
137
 
138
138
  def _get_pattern_id(self) -> str:
139
- return f"{self.__species_id}_{self.__node_id}_{self.start_time}"
139
+ return f"{self.__species_id}_{self.__node_id}"
140
140
 
141
141
  def init(self, epanet_api: epyt.epanet) -> None:
142
142
  super().init(epanet_api)
@@ -180,9 +180,20 @@ class SpeciesInjectionEvent(SystemEvent, JsonSerializable):
180
180
 
181
181
  pattern_id = self._get_pattern_id()
182
182
  if pattern_id in self._epanet_api.getMSXPatternsNameID():
183
- raise ValueError("Duplicated injection event")
184
-
185
- self._epanet_api.addMSXPattern(pattern_id, pattern)
183
+ node_idx = self._epanet_api.getNodeIndex(self.__node_id)
184
+ species_idx, = self._epanet_api.getMSXSpeciesIndex([self.__species_id])
185
+ cur_source_type = self._epanet_api.msx.MSXgetsource(node_idx, species_idx)
186
+ if cur_source_type[0] != source_type_:
187
+ raise ValueError("Source type does not match existing source type")
188
+
189
+ # Add new injection amount to existing injection --
190
+ # i.e. two injection events at the same node
191
+ pattern_idx, = self._epanet_api.getMSXPatternsIndex([pattern_id])
192
+ cur_pattern = self._epanet_api.getMSXPattern()[pattern_idx - 1]
193
+ cur_pattern += pattern
194
+ self._epanet_api.setMSXPattern(pattern_idx, cur_pattern)
195
+ else:
196
+ self._epanet_api.addMSXPattern(pattern_id, pattern)
186
197
  self._epanet_api.setMSXSources(self.__node_id, self.__species_id, source_type_, 1,
187
198
  pattern_id)
188
199
 
@@ -26,7 +26,7 @@ class SensorOverrideAttack(SensorReadingAttack, JsonSerializable):
26
26
 
27
27
  Parameters
28
28
  ----------
29
- new_sensor_values : `numpy.ndarray`
29
+ new_sensor_values : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
30
30
  New sensor reading values -- i.e. these values replace the true sensor reading values.
31
31
  """
32
32
  def __init__(self, new_sensor_values: np.ndarray, **kwds):
@@ -46,7 +46,7 @@ class SensorOverrideAttack(SensorReadingAttack, JsonSerializable):
46
46
  @property
47
47
  def new_sensor_values(self) -> np.ndarray:
48
48
  """
49
- Get the new sensor reading values -- i.e. these values replace the
49
+ Returns the new sensor reading values -- i.e. these values replace the
50
50
  true sensor reading values.
51
51
 
52
52
  Returns
@@ -64,7 +64,7 @@ class SensorOverrideAttack(SensorReadingAttack, JsonSerializable):
64
64
  raise TypeError("Can not compare 'SensorOverrideAttack' instance " +
65
65
  f"with '{type(other)}' instance")
66
66
 
67
- return super().__eq__(other) and self.__new_sensor_values == other.new_sensor_values
67
+ return super().__eq__(other) and np.all(self.__new_sensor_values == other.new_sensor_values)
68
68
 
69
69
  def __str__(self) -> str:
70
70
  return f"{type(self).__name__} {super().__str__()} " +\
@@ -151,6 +151,19 @@ class SensorReplayAttack(SensorReadingAttack, JsonSerializable):
151
151
  """
152
152
  return self.__sensor_data_time_window_end
153
153
 
154
+ @property
155
+ def new_sensor_values(self) -> np.ndarray:
156
+ """
157
+ Returns the new sensor reading values -- i.e. these values replace the
158
+ true sensor reading values.
159
+
160
+ Returns
161
+ -------
162
+ `np.ndarray`
163
+ New sensor readings.
164
+ """
165
+ return deepcopy(self.__new_sensor_values)
166
+
154
167
  def get_attributes(self) -> dict:
155
168
  my_attributes = {"new_sensor_values": self.__new_sensor_values,
156
169
  "replay_data_time_window_start": self.__sensor_data_time_window_start,
@@ -163,7 +176,7 @@ class SensorReplayAttack(SensorReadingAttack, JsonSerializable):
163
176
  raise TypeError("Can not compare 'SensorReplayAttack' instance " +
164
177
  f"with '{type(other)}' instance")
165
178
 
166
- return super().__eq__(other) and self.__new_sensor_values == other.new_sensor_values
179
+ return super().__eq__(other) and np.all(self.__new_sensor_values == other.new_sensor_values)
167
180
 
168
181
  def __str__(self) -> str:
169
182
  return f"{type(self).__name__} {super().__str__()} " +\
@@ -95,13 +95,28 @@ class SensorReadingEvent(Event):
95
95
  if self.__sensor_id not in sensor_config.tank_volume_sensors:
96
96
  __show_warning()
97
97
  elif self.__sensor_type == SENSOR_TYPE_NODE_BULK_SPECIES:
98
- if self.__sensor_id not in sensor_config.bulk_species_node_sensors:
98
+ sensor_present = False
99
+ for _, sensors_id in sensor_config.bulk_species_node_sensors.items():
100
+ if self.__sensor_id in sensors_id:
101
+ sensor_present = True
102
+ break
103
+ if sensor_present is False:
99
104
  __show_warning()
100
105
  elif self.__sensor_type == SENSOR_TYPE_LINK_BULK_SPECIES:
101
- if self.__sensor_id not in sensor_config.bulk_species_link_sensors:
106
+ sensor_present = False
107
+ for _, sensors_id in sensor_config.bulk_species_link_sensors.items():
108
+ if self.__sensor_id in sensors_id:
109
+ sensor_present = True
110
+ break
111
+ if sensor_present is False:
102
112
  __show_warning()
103
113
  elif self.__sensor_type == SENSOR_TYPE_SURFACE_SPECIES:
104
- if self.__sensor_id not in sensor_config.surface_species_sensors:
114
+ sensor_present = False
115
+ for _, sensors_id in sensor_config.surface_species_sensors.items():
116
+ if self.__sensor_id in sensors_id:
117
+ sensor_present = True
118
+ break
119
+ if sensor_present is False:
105
120
  __show_warning()
106
121
 
107
122
  @property
@@ -157,14 +172,14 @@ class SensorReadingEvent(Event):
157
172
 
158
173
  Parameters
159
174
  ----------
160
- sensor_readings : `numpy.ndarray`
175
+ sensor_readings : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
161
176
  Original sensor readings.
162
- sensor_readings_time : `numpy.ndarray`
177
+ sensor_readings_time : `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
163
178
  Time (seconds since simulation start) for each sensor reading row in 'sensor_readings'.
164
179
 
165
180
  Returns
166
181
  -------
167
- `numpy.ndarray`
182
+ `numpy.ndarray <https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html>`_
168
183
  Modified sensor readings.
169
184
  """
170
185
  raise NotImplementedError()
@@ -23,7 +23,7 @@ class SystemEvent(Event):
23
23
 
24
24
  Parameters
25
25
  ----------
26
- epanet_api : `epyt.epanet`
26
+ epanet_api : `epyt.epanet <https://epanet-python-toolkit-epyt.readthedocs.io/en/stable/api.html#epyt.epanet.epanet>`_
27
27
  API to EPANET and EPANET-MSX.
28
28
  """
29
29
  self._epanet_api = epanet_api
@@ -4,8 +4,8 @@ Module provides functions for simulating several scenarios in parallel.
4
4
  from typing import Callable, Any
5
5
  import os
6
6
  import warnings
7
- from multiprocess import Pool, cpu_count
8
7
  import shutil
8
+ from multiprocess import Pool, cpu_count
9
9
  import psutil
10
10
 
11
11
  from .scenario_config import ScenarioConfig
@@ -1,3 +1,5 @@
1
1
  from .scada_data import *
2
2
  from .scada_data_export import *
3
- from .advanced_control import *
3
+ from .custom_control import *
4
+ from .simple_control import *
5
+ from .complex_control import *
@@ -1,21 +1,25 @@
1
1
  """
2
- Module provides a base class for control modules.
2
+ Deprecated -- use epyt_flow.simulation.scada.custom_control instead
3
3
  """
4
- from abc import abstractmethod, ABC
5
4
  import warnings
5
+ from abc import abstractmethod, ABC
6
6
  import numpy as np
7
7
  import epyt
8
8
 
9
9
  from . import ScadaData
10
10
 
11
11
 
12
+ warnings.warn("'epyt_flow.simulation.scada.advanced_control' is deprecated and will be removed " +
13
+ "in future releases -- use 'epyt_flow.simulation.scada.custom_control' instead")
14
+
15
+
12
16
  class AdvancedControlModule(ABC):
13
17
  """
14
18
  Base class for a control module.
15
19
 
16
20
  Attributes
17
21
  ----------
18
- epanet_api : `epyt.epanet`
22
+ epanet_api : `epyt.epanet <https://epanet-python-toolkit-epyt.readthedocs.io/en/latest/api.html#epyt.epanet.epanet>`_
19
23
  API to EPANET and EPANET-MSX. Is set in :func:`init`.
20
24
  """
21
25
  def __init__(self, **kwds):
@@ -29,7 +33,7 @@ class AdvancedControlModule(ABC):
29
33
 
30
34
  Parameters
31
35
  ----------
32
- epanet_api : `epyt.epanet`
36
+ epanet_api : `epyt.epanet <https://epanet-python-toolkit-epyt.readthedocs.io/en/latest/api.html#epyt.epanet.epanet>`_
33
37
  API to EPANET for implementing the control module.
34
38
  """
35
39
  if not isinstance(epanet_api, epyt.epanet):