epyt-flow 0.1.1__py3-none-any.whl → 0.3.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 (31) hide show
  1. epyt_flow/EPANET/compile_linux.sh +4 -0
  2. epyt_flow/EPANET/compile_macos.sh +4 -0
  3. epyt_flow/VERSION +1 -1
  4. epyt_flow/__init__.py +29 -18
  5. epyt_flow/data/benchmarks/leakdb.py +7 -12
  6. epyt_flow/data/networks.py +404 -40
  7. epyt_flow/rest_api/base_handler.py +14 -0
  8. epyt_flow/rest_api/scada_data/__init__.py +0 -0
  9. epyt_flow/rest_api/{scada_data_handler.py → scada_data/data_handlers.py} +3 -162
  10. epyt_flow/rest_api/scada_data/export_handlers.py +140 -0
  11. epyt_flow/rest_api/scada_data/handlers.py +209 -0
  12. epyt_flow/rest_api/scenario/__init__.py +0 -0
  13. epyt_flow/rest_api/scenario/event_handlers.py +118 -0
  14. epyt_flow/rest_api/{scenario_handler.py → scenario/handlers.py} +86 -67
  15. epyt_flow/rest_api/scenario/simulation_handlers.py +174 -0
  16. epyt_flow/rest_api/scenario/uncertainty_handlers.py +118 -0
  17. epyt_flow/rest_api/server.py +61 -24
  18. epyt_flow/simulation/events/leakages.py +27 -17
  19. epyt_flow/simulation/scada/scada_data.py +545 -14
  20. epyt_flow/simulation/scada/scada_data_export.py +39 -12
  21. epyt_flow/simulation/scenario_config.py +14 -20
  22. epyt_flow/simulation/scenario_simulator.py +358 -114
  23. epyt_flow/simulation/sensor_config.py +693 -37
  24. epyt_flow/topology.py +149 -8
  25. epyt_flow/utils.py +75 -18
  26. {epyt_flow-0.1.1.dist-info → epyt_flow-0.3.0.dist-info}/METADATA +33 -5
  27. {epyt_flow-0.1.1.dist-info → epyt_flow-0.3.0.dist-info}/RECORD +30 -22
  28. epyt_flow/EPANET/compile.sh +0 -4
  29. {epyt_flow-0.1.1.dist-info → epyt_flow-0.3.0.dist-info}/LICENSE +0 -0
  30. {epyt_flow-0.1.1.dist-info → epyt_flow-0.3.0.dist-info}/WHEEL +0 -0
  31. {epyt_flow-0.1.1.dist-info → epyt_flow-0.3.0.dist-info}/top_level.txt +0 -0
@@ -4,15 +4,24 @@ This module provides the EPyT-Flow REST API server.
4
4
  from wsgiref.simple_server import make_server, WSGIServer
5
5
  import falcon
6
6
 
7
- from .scenario_handler import ScenarioManager, ScenarioNewHandler, ScenarioRemoveHandler, \
8
- ScenarioGeneralParamsHandler, ScenarioSensorConfigHandler, ScenarioSimulationHandler, \
9
- ScenarioTopologyHandler, ScenarioConfigHandler, ScenarioLeakageHandler
10
- from .scada_data_handler import ScadaDataManager, ScadaDataSensorConfigHandler, \
11
- ScadaDataPressuresHandler, ScadaDataDemandsHandler, ScadaDataFlowsHandler, \
12
- ScadaDataLinksQualityHandler, ScadaDataNodesQualityHandler, ScadaDataRemoveHandler, \
13
- ScadaDataSensorFaultsHandler, ScadaDataNodeBulkSpeciesHandler, \
14
- ScadaDataLinkBulkSpeciesHandler, ScadaDataSurfaceSpeciesHandler, ScadaDataTankVolumesHandler, \
15
- ScadaDataPumpStatesHandler, ScadaDataValveStatesHandler
7
+ from .scenario.handlers import ScenarioManager, ScenarioNewHandler, \
8
+ ScenarioRemoveHandler, ScenarioGeneralParamsHandler, ScenarioSensorConfigHandler, \
9
+ ScenarioExportHandler, ScenarioTopologyHandler, ScenarioConfigHandler, \
10
+ ScenarioNodeDemandPatternHandler
11
+ from .scenario.uncertainty_handlers import ScenarioModelUncertaintyHandler, \
12
+ ScenarioSensorUncertaintyHandler
13
+ from .scenario.event_handlers import ScenarioLeakageHandler, ScenarioSensorFaultHandler
14
+ from .scenario.simulation_handlers import ScenarioSimulationHandler, \
15
+ ScenarioBasicQualitySimulationHandler, ScenarioAdvancedQualitySimulationHandler
16
+ from .scada_data.handlers import ScadaDataManager, ScadaDataSensorConfigHandler, \
17
+ ScadaDataRemoveHandler, ScadaDataSensorFaultsHandler, ScadaDataConvertUnitsHandler
18
+ from .scada_data.data_handlers import ScadaDataPressuresHandler, ScadaDataDemandsHandler, \
19
+ ScadaDataFlowsHandler, ScadaDataLinksQualityHandler, ScadaDataNodesQualityHandler, \
20
+ ScadaDataNodeBulkSpeciesHandler, ScadaDataLinkBulkSpeciesHandler, \
21
+ ScadaDataSurfaceSpeciesHandler, ScadaDataTankVolumesHandler, ScadaDataPumpStatesHandler, \
22
+ ScadaDataValveStatesHandler
23
+ from .scada_data.export_handlers import ScadaDataExportHandler, ScadaDataXlsxExportHandler, \
24
+ ScadaDataMatlabExportHandler, ScadaDataNumpyExportHandler
16
25
 
17
26
 
18
27
  class RestApiService():
@@ -37,6 +46,8 @@ class RestApiService():
37
46
  ScenarioNewHandler(self.scenario_mgr))
38
47
  self.app.add_route("/scenario/{scenario_id}",
39
48
  ScenarioRemoveHandler(self.scenario_mgr))
49
+ self.app.add_route("/scenario/{scenario_id}/export",
50
+ ScenarioExportHandler(self.scenario_mgr))
40
51
  self.app.add_route("/scenario/{scenario_id}/topology",
41
52
  ScenarioTopologyHandler(self.scenario_mgr))
42
53
  self.app.add_route("/scenario/{scenario_id}/scenario_config",
@@ -45,11 +56,27 @@ class RestApiService():
45
56
  ScenarioGeneralParamsHandler(self.scenario_mgr))
46
57
  self.app.add_route("/scenario/{scenario_id}/sensor_config",
47
58
  ScenarioSensorConfigHandler(self.scenario_mgr))
48
- self.app.add_route("/scenario/{scenario_id}/leakages",
59
+ self.app.add_route("/scenario/{scenario_id}/uncertainty/model",
60
+ ScenarioModelUncertaintyHandler(self.scenario_mgr))
61
+ self.app.add_route("/scenario/{scenario_id}/uncertainty/sensors",
62
+ ScenarioSensorUncertaintyHandler(self.scenario_mgr))
63
+ self.app.add_route("/scenario/{scenario_id}/events/leakages",
49
64
  ScenarioLeakageHandler(self.scenario_mgr))
65
+ self.app.add_route("/scenario/{scenario_id}/events/sensor_faults",
66
+ ScenarioSensorFaultHandler(self.scenario_mgr))
67
+ self.app.add_route("/scenario/{scenario_id}/node/{node_id}/demand_pattern",
68
+ ScenarioNodeDemandPatternHandler(self.scenario_mgr))
50
69
  self.app.add_route("/scenario/{scenario_id}/simulation",
51
70
  ScenarioSimulationHandler(scenario_mgr=self.scenario_mgr,
52
71
  scada_data_mgr=self.scada_data_mgr))
72
+ self.app.add_route("/scenario/{scenario_id}/simulation/advanced_quality",
73
+ ScenarioBasicQualitySimulationHandler(scenario_mgr=self.scenario_mgr,
74
+ scada_data_mgr=
75
+ self.scada_data_mgr))
76
+ self.app.add_route("/scenario/{scenario_id}/simulation/basic_quality",
77
+ ScenarioAdvancedQualitySimulationHandler(scenario_mgr=self.scenario_mgr,
78
+ scada_data_mgr=
79
+ self.scada_data_mgr))
53
80
 
54
81
  self.app.add_route("/scada_data/{data_id}",
55
82
  ScadaDataRemoveHandler(self.scada_data_mgr))
@@ -57,28 +84,38 @@ class RestApiService():
57
84
  ScadaDataSensorConfigHandler(self.scada_data_mgr))
58
85
  self.app.add_route("/scada_data/{data_id}/sensor_faults",
59
86
  ScadaDataSensorFaultsHandler(self.scada_data_mgr))
60
- self.app.add_route("/scada_data/{data_id}/pressures",
87
+ self.app.add_route("/scada_data/{data_id}/nodes/pressures",
61
88
  ScadaDataPressuresHandler(self.scada_data_mgr))
62
- self.app.add_route("/scada_data/{data_id}/flows",
63
- ScadaDataFlowsHandler(self.scada_data_mgr))
64
- self.app.add_route("/scada_data/{data_id}/demands",
89
+ self.app.add_route("/scada_data/{data_id}/nodes/demands",
65
90
  ScadaDataDemandsHandler(self.scada_data_mgr))
91
+ self.app.add_route("/scada_data/{data_id}/nodes/quality",
92
+ ScadaDataNodesQualityHandler(self.scada_data_mgr))
93
+ self.app.add_route("/scada_data/{data_id}/nodes/bulk_species",
94
+ ScadaDataNodeBulkSpeciesHandler(self.scada_data_mgr))
95
+ self.app.add_route("/scada_data/{data_id}/links/flows",
96
+ ScadaDataFlowsHandler(self.scada_data_mgr))
97
+ self.app.add_route("/scada_data/{data_id}/links/quality",
98
+ ScadaDataLinksQualityHandler(self.scada_data_mgr))
99
+ self.app.add_route("/scada_data/{data_id}/links/bulk_species",
100
+ ScadaDataLinkBulkSpeciesHandler(self.scada_data_mgr))
101
+ self.app.add_route("/scada_data/{data_id}/links/surface_species",
102
+ ScadaDataSurfaceSpeciesHandler(self.scada_data_mgr))
66
103
  self.app.add_route("/scada_data/{data_id}/pump_states",
67
104
  ScadaDataPumpStatesHandler(self.scada_data_mgr))
68
105
  self.app.add_route("/scada_data/{data_id}/valve_states",
69
106
  ScadaDataValveStatesHandler(self.scada_data_mgr))
70
107
  self.app.add_route("/scada_data/{data_id}/tank_volumes",
71
108
  ScadaDataTankVolumesHandler(self.scada_data_mgr))
72
- self.app.add_route("/scada_data/{data_id}/node_qualities",
73
- ScadaDataNodesQualityHandler(self.scada_data_mgr))
74
- self.app.add_route("/scada_data/{data_id}/link_qualities",
75
- ScadaDataLinksQualityHandler(self.scada_data_mgr))
76
- self.app.add_route("/scada_data/{data_id}/node_bulk_species",
77
- ScadaDataNodeBulkSpeciesHandler(self.scada_data_mgr))
78
- self.app.add_route("/scada_data/{data_id}/link_bulk_species",
79
- ScadaDataLinkBulkSpeciesHandler(self.scada_data_mgr))
80
- self.app.add_route("/scada_data/{data_id}/surface_species",
81
- ScadaDataSurfaceSpeciesHandler(self.scada_data_mgr))
109
+ self.app.add_route("/scada_data/{data_id}/export/xlsx",
110
+ ScadaDataXlsxExportHandler(scada_data_mgr=self.scada_data_mgr))
111
+ self.app.add_route("/scada_data/{data_id}/export/matlab",
112
+ ScadaDataMatlabExportHandler(scada_data_mgr=self.scada_data_mgr))
113
+ self.app.add_route("/scada_data/{data_id}/export/numpy",
114
+ ScadaDataNumpyExportHandler(scada_data_mgr=self.scada_data_mgr))
115
+ self.app.add_route("/scada_data/{data_id}/export",
116
+ ScadaDataExportHandler(scada_data_mgr=self.scada_data_mgr))
117
+ self.app.add_route("/scada_data/{data_id}/convert_units",
118
+ ScadaDataConvertUnitsHandler(scada_data_mgr=self.scada_data_mgr))
82
119
 
83
120
  @property
84
121
  def port(self) -> int:
@@ -5,6 +5,7 @@ from copy import deepcopy
5
5
  import math
6
6
  import numpy as np
7
7
  import epyt
8
+ from epyt.epanet import ToolkitConstants
8
9
 
9
10
  from .system_event import SystemEvent
10
11
  from ...serialization import serializable, JsonSerializable, \
@@ -23,14 +24,14 @@ class Leakage(SystemEvent, JsonSerializable):
23
24
  Note that if the leak is placed at a node, then 'link_id' must be None and the
24
25
  ID of the node must be set in 'node_id'
25
26
  diameter : `float`, optional
26
- Diameter of this leak.
27
+ Diameter of this leak in either *foot* or *meter* (depending on the used flow units).
27
28
 
28
29
  Alternatively, 'area' can be used for specifying the size of this leakage --
29
30
  in this case, 'diameter' must be set to 'None'.
30
31
 
31
32
  The default is None.
32
33
  area : `float`, optional
33
- Area of this leak.
34
+ Area of this leak in either *foot^2* or *meter^2* (depending on the used flow units).
34
35
 
35
36
  Alternatively, 'diameter' can be used for specifying the size of this leakage --
36
37
  in this case, 'area' must be set to 'None'.
@@ -124,19 +125,21 @@ class Leakage(SystemEvent, JsonSerializable):
124
125
  @property
125
126
  def diameter(self) -> float:
126
127
  """
127
- Gets the diameter of the leak.
128
+ Gets the diameter of the leak in either *foot* or *meter*
129
+ (depending on the sued flow units).
128
130
 
129
131
  Returns
130
132
  -------
131
133
  `float`
132
- Diameter of the leak.
134
+ Diameter (*foot* or *meter*) of the leak.
133
135
  """
134
136
  return self.__diameter
135
137
 
136
138
  @property
137
139
  def area(self) -> float:
138
140
  """
139
- Gets the area of the leak.
141
+ Gets the area of the leak in either *foot^2* or *meter^2*
142
+ (depending on the sued flow units).
140
143
 
141
144
  Returns
142
145
  -------
@@ -190,46 +193,53 @@ class Leakage(SystemEvent, JsonSerializable):
190
193
  """
191
194
  Computes the leak area given the diameter.
192
195
 
196
+ leak_area = pi * (diameter * .5)^2
197
+
193
198
  Parameters
194
199
  ----------
195
200
  diameter : `float`
196
- Diameter (m) of the leak.
201
+ Diameter (*foot* or *meter*) of the leak.
197
202
 
198
203
  Returns
199
204
  -------
200
205
  `float`
201
- Leak area in mm^2.
206
+ Leak area in *foot^2* or *meter^2*.
202
207
  """
203
- return (np.pi * (diameter / 2) ** 2) * 10000.
208
+ return np.pi * (diameter / 2) ** 2
204
209
 
205
- def compute_leak_emitter_coefficient(self, area: float, discharge_coef: float = .75,
206
- g: float = 9.80665) -> float:
210
+ def compute_leak_emitter_coefficient(self, area: float, discharge_coef: float = .75) -> float:
207
211
  """
208
212
  Computes the leak emitter coefficient.
209
213
 
210
- emitter_coef = discharge_coef * area * sqrt(2*g) where g = 9.8, discharge_coef = .75
214
+ emitter_coef = discharge_coef * area * sqrt(2*g)
215
+ where g is the gravitational constant, and discharge_coef = .75
211
216
 
212
217
  leak_demand = emitter_coef * pressure^alpha where alpha = .5
213
218
 
214
219
  Parameters
215
220
  ----------
216
221
  area : `float`
217
- Leak area (mm^2) as computed in
218
- :func:`epyt_flow.simulation.events.leakages.Leakage.compute_leak_area`.
222
+ Leak area (foot^2 or meter^2) as computed in
223
+ :func:`~epyt_flow.simulation.events.leakages.Leakage.compute_leak_area`.
219
224
  discharge_coef : `float`, optional
220
225
  Discharge coefficient.
221
226
 
222
227
  The default is set to 0.75
223
- g : `float`, optional
224
- Gravitational constant. Do not change this!
225
-
226
- The default is 9.8
227
228
 
228
229
  Returns
229
230
  -------
230
231
  `float`
231
232
  Leak emitter coefficient.
232
233
  """
234
+ flow_unit = self._epanet_api.api.ENgetflowunits()
235
+ if flow_unit == ToolkitConstants.EN_CMH:
236
+ g = 127137600 # m/h^2
237
+ elif flow_unit == ToolkitConstants.EN_CFS:
238
+ g = 32.17405 # feet/s^2
239
+ else:
240
+ raise ValueError("Leakages are only implemented for the following flow units:\n" +
241
+ " EN_CMH (cubic foot/sec)\n EN_CFS (cubic meter/hr)")
242
+
233
243
  return discharge_coef * area * np.sqrt(2. * g)
234
244
 
235
245
  def init(self, epanet_api: epyt.epanet) -> None: