epyt-flow 0.1.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 (131) hide show
  1. epyt_flow/EPANET/EPANET/SRC_engines/AUTHORS +28 -0
  2. epyt_flow/EPANET/EPANET/SRC_engines/LICENSE +21 -0
  3. epyt_flow/EPANET/EPANET/SRC_engines/Readme_SRC_Engines.txt +18 -0
  4. epyt_flow/EPANET/EPANET/SRC_engines/enumstxt.h +134 -0
  5. epyt_flow/EPANET/EPANET/SRC_engines/epanet.c +5578 -0
  6. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.c +865 -0
  7. epyt_flow/EPANET/EPANET/SRC_engines/epanet2.def +131 -0
  8. epyt_flow/EPANET/EPANET/SRC_engines/errors.dat +73 -0
  9. epyt_flow/EPANET/EPANET/SRC_engines/funcs.h +193 -0
  10. epyt_flow/EPANET/EPANET/SRC_engines/genmmd.c +1000 -0
  11. epyt_flow/EPANET/EPANET/SRC_engines/hash.c +177 -0
  12. epyt_flow/EPANET/EPANET/SRC_engines/hash.h +28 -0
  13. epyt_flow/EPANET/EPANET/SRC_engines/hydcoeffs.c +1151 -0
  14. epyt_flow/EPANET/EPANET/SRC_engines/hydraul.c +1117 -0
  15. epyt_flow/EPANET/EPANET/SRC_engines/hydsolver.c +720 -0
  16. epyt_flow/EPANET/EPANET/SRC_engines/hydstatus.c +476 -0
  17. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2.h +431 -0
  18. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_2.h +1786 -0
  19. epyt_flow/EPANET/EPANET/SRC_engines/include/epanet2_enums.h +468 -0
  20. epyt_flow/EPANET/EPANET/SRC_engines/inpfile.c +810 -0
  21. epyt_flow/EPANET/EPANET/SRC_engines/input1.c +707 -0
  22. epyt_flow/EPANET/EPANET/SRC_engines/input2.c +864 -0
  23. epyt_flow/EPANET/EPANET/SRC_engines/input3.c +2170 -0
  24. epyt_flow/EPANET/EPANET/SRC_engines/main.c +93 -0
  25. epyt_flow/EPANET/EPANET/SRC_engines/mempool.c +142 -0
  26. epyt_flow/EPANET/EPANET/SRC_engines/mempool.h +24 -0
  27. epyt_flow/EPANET/EPANET/SRC_engines/output.c +852 -0
  28. epyt_flow/EPANET/EPANET/SRC_engines/project.c +1359 -0
  29. epyt_flow/EPANET/EPANET/SRC_engines/quality.c +685 -0
  30. epyt_flow/EPANET/EPANET/SRC_engines/qualreact.c +743 -0
  31. epyt_flow/EPANET/EPANET/SRC_engines/qualroute.c +694 -0
  32. epyt_flow/EPANET/EPANET/SRC_engines/report.c +1489 -0
  33. epyt_flow/EPANET/EPANET/SRC_engines/rules.c +1362 -0
  34. epyt_flow/EPANET/EPANET/SRC_engines/smatrix.c +871 -0
  35. epyt_flow/EPANET/EPANET/SRC_engines/text.h +497 -0
  36. epyt_flow/EPANET/EPANET/SRC_engines/types.h +874 -0
  37. epyt_flow/EPANET/EPANET-MSX/MSX_Updates.txt +53 -0
  38. epyt_flow/EPANET/EPANET-MSX/Src/dispersion.h +27 -0
  39. epyt_flow/EPANET/EPANET-MSX/Src/hash.c +107 -0
  40. epyt_flow/EPANET/EPANET-MSX/Src/hash.h +28 -0
  41. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx.h +102 -0
  42. epyt_flow/EPANET/EPANET-MSX/Src/include/epanetmsx_export.h +42 -0
  43. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.c +937 -0
  44. epyt_flow/EPANET/EPANET-MSX/Src/mathexpr.h +39 -0
  45. epyt_flow/EPANET/EPANET-MSX/Src/mempool.c +204 -0
  46. epyt_flow/EPANET/EPANET-MSX/Src/mempool.h +24 -0
  47. epyt_flow/EPANET/EPANET-MSX/Src/msxchem.c +1285 -0
  48. epyt_flow/EPANET/EPANET-MSX/Src/msxcompiler.c +368 -0
  49. epyt_flow/EPANET/EPANET-MSX/Src/msxdict.h +42 -0
  50. epyt_flow/EPANET/EPANET-MSX/Src/msxdispersion.c +586 -0
  51. epyt_flow/EPANET/EPANET-MSX/Src/msxerr.c +116 -0
  52. epyt_flow/EPANET/EPANET-MSX/Src/msxfile.c +260 -0
  53. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.c +175 -0
  54. epyt_flow/EPANET/EPANET-MSX/Src/msxfuncs.h +35 -0
  55. epyt_flow/EPANET/EPANET-MSX/Src/msxinp.c +1504 -0
  56. epyt_flow/EPANET/EPANET-MSX/Src/msxout.c +401 -0
  57. epyt_flow/EPANET/EPANET-MSX/Src/msxproj.c +791 -0
  58. epyt_flow/EPANET/EPANET-MSX/Src/msxqual.c +2010 -0
  59. epyt_flow/EPANET/EPANET-MSX/Src/msxrpt.c +400 -0
  60. epyt_flow/EPANET/EPANET-MSX/Src/msxtank.c +422 -0
  61. epyt_flow/EPANET/EPANET-MSX/Src/msxtoolkit.c +1164 -0
  62. epyt_flow/EPANET/EPANET-MSX/Src/msxtypes.h +551 -0
  63. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.c +524 -0
  64. epyt_flow/EPANET/EPANET-MSX/Src/msxutils.h +56 -0
  65. epyt_flow/EPANET/EPANET-MSX/Src/newton.c +158 -0
  66. epyt_flow/EPANET/EPANET-MSX/Src/newton.h +34 -0
  67. epyt_flow/EPANET/EPANET-MSX/Src/rk5.c +287 -0
  68. epyt_flow/EPANET/EPANET-MSX/Src/rk5.h +39 -0
  69. epyt_flow/EPANET/EPANET-MSX/Src/ros2.c +293 -0
  70. epyt_flow/EPANET/EPANET-MSX/Src/ros2.h +35 -0
  71. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.c +816 -0
  72. epyt_flow/EPANET/EPANET-MSX/Src/smatrix.h +29 -0
  73. epyt_flow/EPANET/EPANET-MSX/readme.txt +14 -0
  74. epyt_flow/EPANET/compile.sh +4 -0
  75. epyt_flow/VERSION +1 -0
  76. epyt_flow/__init__.py +24 -0
  77. epyt_flow/data/__init__.py +0 -0
  78. epyt_flow/data/benchmarks/__init__.py +11 -0
  79. epyt_flow/data/benchmarks/batadal.py +257 -0
  80. epyt_flow/data/benchmarks/batadal_data.py +28 -0
  81. epyt_flow/data/benchmarks/battledim.py +473 -0
  82. epyt_flow/data/benchmarks/battledim_data.py +51 -0
  83. epyt_flow/data/benchmarks/gecco_water_quality.py +267 -0
  84. epyt_flow/data/benchmarks/leakdb.py +592 -0
  85. epyt_flow/data/benchmarks/leakdb_data.py +18923 -0
  86. epyt_flow/data/benchmarks/water_usage.py +123 -0
  87. epyt_flow/data/networks.py +650 -0
  88. epyt_flow/gym/__init__.py +4 -0
  89. epyt_flow/gym/control_gyms.py +47 -0
  90. epyt_flow/gym/scenario_control_env.py +101 -0
  91. epyt_flow/metrics.py +404 -0
  92. epyt_flow/models/__init__.py +2 -0
  93. epyt_flow/models/event_detector.py +31 -0
  94. epyt_flow/models/sensor_interpolation_detector.py +118 -0
  95. epyt_flow/rest_api/__init__.py +4 -0
  96. epyt_flow/rest_api/base_handler.py +70 -0
  97. epyt_flow/rest_api/res_manager.py +95 -0
  98. epyt_flow/rest_api/scada_data_handler.py +476 -0
  99. epyt_flow/rest_api/scenario_handler.py +352 -0
  100. epyt_flow/rest_api/server.py +106 -0
  101. epyt_flow/serialization.py +438 -0
  102. epyt_flow/simulation/__init__.py +5 -0
  103. epyt_flow/simulation/events/__init__.py +6 -0
  104. epyt_flow/simulation/events/actuator_events.py +259 -0
  105. epyt_flow/simulation/events/event.py +81 -0
  106. epyt_flow/simulation/events/leakages.py +404 -0
  107. epyt_flow/simulation/events/sensor_faults.py +267 -0
  108. epyt_flow/simulation/events/sensor_reading_attack.py +185 -0
  109. epyt_flow/simulation/events/sensor_reading_event.py +170 -0
  110. epyt_flow/simulation/events/system_event.py +88 -0
  111. epyt_flow/simulation/parallel_simulation.py +147 -0
  112. epyt_flow/simulation/scada/__init__.py +3 -0
  113. epyt_flow/simulation/scada/advanced_control.py +134 -0
  114. epyt_flow/simulation/scada/scada_data.py +1589 -0
  115. epyt_flow/simulation/scada/scada_data_export.py +255 -0
  116. epyt_flow/simulation/scenario_config.py +608 -0
  117. epyt_flow/simulation/scenario_simulator.py +1897 -0
  118. epyt_flow/simulation/scenario_visualizer.py +61 -0
  119. epyt_flow/simulation/sensor_config.py +1289 -0
  120. epyt_flow/topology.py +290 -0
  121. epyt_flow/uncertainty/__init__.py +3 -0
  122. epyt_flow/uncertainty/model_uncertainty.py +302 -0
  123. epyt_flow/uncertainty/sensor_noise.py +73 -0
  124. epyt_flow/uncertainty/uncertainties.py +555 -0
  125. epyt_flow/uncertainty/utils.py +206 -0
  126. epyt_flow/utils.py +306 -0
  127. epyt_flow-0.1.0.dist-info/LICENSE +21 -0
  128. epyt_flow-0.1.0.dist-info/METADATA +139 -0
  129. epyt_flow-0.1.0.dist-info/RECORD +131 -0
  130. epyt_flow-0.1.0.dist-info/WHEEL +5 -0
  131. epyt_flow-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,352 @@
1
+ """
2
+ This module provides all handlers for requests concerning scenarios.
3
+ """
4
+ import warnings
5
+ import falcon
6
+
7
+ from .base_handler import BaseHandler
8
+ from .res_manager import ResourceManager
9
+ from .scada_data_handler import ScadaDataManager
10
+ from ..simulation import ScenarioSimulator, Leakage, SensorConfig
11
+
12
+
13
+ class ScenarioManager(ResourceManager):
14
+ """
15
+ Class for managing all scenarios that are currently used by the REST API.
16
+ """
17
+ def create(self, **kwds) -> str:
18
+ """
19
+ Creates a new scenario -- e.g. loading a given .inp file or
20
+ using a given scenario configuration.
21
+
22
+ Returns
23
+ -------
24
+ `str`
25
+ UUID of the new scenario.
26
+ """
27
+ return self.create_new_item(ScenarioSimulator(**kwds))
28
+
29
+ def close_item(self, item: ScenarioSimulator) -> None:
30
+ item.close()
31
+
32
+
33
+ class ScenarioBaseHandler(BaseHandler):
34
+ """
35
+ Base class for all handlers concerning scenarios.
36
+
37
+ Parameters
38
+ ----------
39
+ scenario_mgr : :class:`~epyt_flow.rest_api.scenario_handler.ScenarioManager`
40
+ Instance for managing all scenarios.
41
+ """
42
+ def __init__(self, scenario_mgr: ScenarioManager):
43
+ self.scenario_mgr = scenario_mgr
44
+
45
+
46
+ class ScenarioRemoveHandler(ScenarioBaseHandler):
47
+ """
48
+ Class for handling a DELETE request for a given scenario.
49
+ """
50
+ def on_delete(self, _, resp: falcon.Response, scenario_id: str) -> None:
51
+ """
52
+ Deletes a given scenario.
53
+
54
+ Parameters
55
+ ----------
56
+ resp : `falcon.Response`
57
+ Response instance.
58
+ scenario_id : `str`
59
+ UUID of the scenario.
60
+ """
61
+ try:
62
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
63
+ self.send_invalid_resource_id_error(resp)
64
+ return
65
+
66
+ self.scenario_mgr.remove(scenario_id)
67
+ except Exception as ex:
68
+ warnings.warn(str(ex))
69
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
70
+
71
+
72
+ class ScenarioConfigHandler(ScenarioBaseHandler):
73
+ """
74
+ Class for handling a GET request for getting the scenario configuration of a given scenario.
75
+ """
76
+ def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
77
+ """
78
+ Gets the scenario configuration of a given scenario.
79
+
80
+ Parameters
81
+ ----------
82
+ resp : `falcon.Response`
83
+ Response instance.
84
+ scenario_id : `str`
85
+ UUID of the scenario.
86
+ """
87
+ try:
88
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
89
+ self.send_invalid_resource_id_error(resp)
90
+ return
91
+
92
+ my_sceanrio_config = self.scenario_mgr.get(scenario_id).get_scenario_config()
93
+ self.send_json_response(resp, my_sceanrio_config)
94
+ except Exception as ex:
95
+ warnings.warn(str(ex))
96
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
97
+
98
+
99
+ class ScenarioNewHandler(ScenarioBaseHandler):
100
+ """
101
+ Class for handling POST requests for creating a new scenario.
102
+ """
103
+ def on_post(self, req: falcon.Request, resp: falcon.Response) -> None:
104
+ """
105
+ Creates/Loads a new scenario.
106
+
107
+ Parameters
108
+ ----------
109
+ req : `falcon.Request`
110
+ Request instance.
111
+ resp : `falcon.Response`
112
+ Response instance.
113
+ scenario_id : `str`
114
+ UUID of the scenario.
115
+ """
116
+ try:
117
+ args = self.load_json_data_from_request(req)
118
+ scenario_id = self.scenario_mgr.create(**args)
119
+ self.send_json_response(resp, {"scenario_id": scenario_id})
120
+ except Exception as ex:
121
+ warnings.warn(str(ex))
122
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
123
+
124
+
125
+ class ScenarioLeakageHandler(ScenarioBaseHandler):
126
+ """
127
+ Class for handling GET and POST requests concerning leakages.
128
+ """
129
+ def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
130
+ """
131
+ Gets all leakages of a given scenario.
132
+
133
+ Parameters
134
+ ----------
135
+ resp : `falcon.Response`
136
+ Response instance.
137
+ scenario_id : `str`
138
+ UUID of the scenario.
139
+ """
140
+ try:
141
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
142
+ self.send_invalid_resource_id_error(resp)
143
+ return
144
+
145
+ my_leakages = self.scenario_mgr.get(scenario_id).leakages
146
+ self.send_json_response(resp, my_leakages)
147
+ except Exception as ex:
148
+ warnings.warn(str(ex))
149
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
150
+
151
+ def on_post(self, req: falcon.Request, resp: falcon.Response, scenario_id: str) -> None:
152
+ """
153
+ Adds a new leakage to a given scenario.
154
+
155
+ Parameters
156
+ ----------
157
+ req : `falcon.Request`
158
+ Request instance.
159
+ resp : `falcon.Response`
160
+ Response instance.
161
+ scenario_id : `str`
162
+ UUID of the scenario.
163
+ """
164
+ try:
165
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
166
+ self.send_invalid_resource_id_error(resp)
167
+ return
168
+
169
+ leakage = self.load_json_data_from_request(req)
170
+ if not isinstance(leakage, Leakage):
171
+ self.send_json_parsing_error(resp)
172
+ return
173
+
174
+ self.scenario_mgr.get(scenario_id).add_leakage(leakage)
175
+ except Exception as ex:
176
+ warnings.warn(str(ex))
177
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
178
+
179
+
180
+ class ScenarioTopologyHandler(ScenarioBaseHandler):
181
+ """
182
+ Class for handling GET requests for getting the topology of a given scenario.
183
+ """
184
+ def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
185
+ """
186
+ Gets the topology of a given scenario.
187
+
188
+ Parameters
189
+ ----------
190
+ resp : `falcon.Response`
191
+ Response instance.
192
+ scenario_id : `str`
193
+ UUID of the scenario.
194
+ """
195
+ try:
196
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
197
+ self.send_invalid_resource_id_error(resp)
198
+ return
199
+
200
+ my_topology = self.scenario_mgr.get(scenario_id).get_topology()
201
+ self.send_json_response(resp, my_topology)
202
+ except Exception as ex:
203
+ warnings.warn(str(ex))
204
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
205
+
206
+
207
+ class ScenarioGeneralParamsHandler(ScenarioBaseHandler):
208
+ """
209
+ Class for handling GET and POST requests for the general parameters of a given scenario.
210
+ """
211
+ def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
212
+ """
213
+ Gets the general parameters (e.g. simulation duration, etc.) of a given scenario.
214
+
215
+ Parameters
216
+ ----------
217
+ resp : `falcon.Response`
218
+ Response instance.
219
+ scenario_id : `str`
220
+ UUID of the scenario.
221
+ """
222
+ try:
223
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
224
+ self.send_invalid_resource_id_error(resp)
225
+ return
226
+
227
+ my_general_params = self.scenario_mgr.get(scenario_id).get_scenario_config().\
228
+ general_params
229
+ self.send_json_response(resp, my_general_params)
230
+ except Exception as ex:
231
+ warnings.warn(str(ex))
232
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
233
+
234
+ def on_post(self, req: falcon.Request, resp: falcon.Response, scenario_id: str) -> None:
235
+ """
236
+ Sets the general parameters of a given scenario.
237
+
238
+ Parameters
239
+ ----------
240
+ resp : `falcon.Request`
241
+ Request instance.
242
+ scenario_id : `str`
243
+ UUID of the scenario.
244
+ """
245
+ try:
246
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
247
+ self.send_invalid_resource_id_error(resp)
248
+ return
249
+
250
+ general_params = self.load_json_data_from_request(req)
251
+ if not isinstance(general_params, dict):
252
+ self.send_json_parsing_error(resp)
253
+ return
254
+
255
+ self.scenario_mgr.get(scenario_id).set_general_parameters(**general_params)
256
+ except Exception as ex:
257
+ warnings.warn(str(ex))
258
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
259
+
260
+
261
+ class ScenarioSensorConfigHandler(ScenarioBaseHandler):
262
+ """
263
+ Class for handling GET and POST requests for the sensor configuration of a given scenario.
264
+ """
265
+ def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
266
+ """
267
+ Gets the sensor configuration of a given scenario.
268
+
269
+ Parameters
270
+ ----------
271
+ resp : `falcon.Response`
272
+ Response instance.
273
+ scenario_id : `str`
274
+ UUID of the scenario.
275
+ """
276
+ try:
277
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
278
+ self.send_invalid_resource_id_error(resp)
279
+ return
280
+
281
+ my_sensor_config = self.scenario_mgr.get(scenario_id).sensor_config
282
+ self.send_json_response(resp, my_sensor_config)
283
+ except Exception as ex:
284
+ warnings.warn(str(ex))
285
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
286
+
287
+ def on_post(self, req: falcon.Request, resp: falcon.Response, scenario_id: str) -> None:
288
+ """
289
+ Sets the sensor configuration of a given scenario.
290
+
291
+ Parameters
292
+ ----------
293
+ resp : `falcon.Request`
294
+ Request instance.
295
+ scenario_id : `str`
296
+ UUID of the scenario.
297
+ """
298
+ try:
299
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
300
+ self.send_invalid_resource_id_error(resp)
301
+ return
302
+
303
+ sensor_config = self.load_json_data_from_request(req)
304
+ if not isinstance(sensor_config, SensorConfig):
305
+ self.send_json_parsing_error(resp)
306
+ return
307
+
308
+ my_scenario = self.scenario_mgr.get(scenario_id)
309
+ my_scenario.sensor_config = sensor_config
310
+ except Exception as ex:
311
+ warnings.warn(str(ex))
312
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
313
+
314
+
315
+ class ScenarioSimulationHandler(ScenarioBaseHandler):
316
+ """
317
+ Class for handling GET requests for simulating a given scenario.
318
+
319
+ Parameters
320
+ ----------
321
+ scada_data_mgr : :class:`~epyt_flow.rest_api.scenario_handler.ScadaDataBaseHandler`
322
+ SCADA data manager.
323
+ """
324
+ def __init__(self, scada_data_mgr: ScadaDataManager, **kwds):
325
+ self.scada_data_mgr = scada_data_mgr
326
+
327
+ super().__init__(**kwds)
328
+
329
+ def on_get(self, _, resp: falcon.Response, scenario_id: str) -> None:
330
+ """
331
+ Runs the simulation of a given scenario.
332
+
333
+ Parameters
334
+ ----------
335
+ resp : `falcon.Response`
336
+ Response instance.
337
+ scenario_id : `str`
338
+ UUID of the scenario.
339
+ """
340
+ try:
341
+ if self.scenario_mgr.validate_uuid(scenario_id) is False:
342
+ self.send_invalid_resource_id_error(resp)
343
+ return
344
+
345
+ my_scenario = self.scenario_mgr.get(scenario_id)
346
+ res = my_scenario.run_simulation()
347
+
348
+ data_id = self.scada_data_mgr.create_new_item(res)
349
+ self.send_json_response(resp, {"data_id": data_id})
350
+ except Exception as ex:
351
+ warnings.warn(str(ex))
352
+ resp.status = falcon.HTTP_INTERNAL_SERVER_ERROR
@@ -0,0 +1,106 @@
1
+ """
2
+ This module provides the EPyT-Flow REST API server.
3
+ """
4
+ from wsgiref.simple_server import make_server, WSGIServer
5
+ import falcon
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
16
+
17
+
18
+ class RestApiService():
19
+ """
20
+ Class implementing the REST API server.
21
+
22
+ Parameters
23
+ ----------
24
+ port : `int`, optional
25
+ Port of the server.
26
+
27
+ The default is 8080
28
+ """
29
+ def __init__(self, port: int = 8080):
30
+ self.app = falcon.App()
31
+ self.__port = port
32
+
33
+ self.scenario_mgr = ScenarioManager()
34
+ self.scada_data_mgr = ScadaDataManager()
35
+
36
+ self.app.add_route("/scenario/new",
37
+ ScenarioNewHandler(self.scenario_mgr))
38
+ self.app.add_route("/scenario/{scenario_id}",
39
+ ScenarioRemoveHandler(self.scenario_mgr))
40
+ self.app.add_route("/scenario/{scenario_id}/topology",
41
+ ScenarioTopologyHandler(self.scenario_mgr))
42
+ self.app.add_route("/scenario/{scenario_id}/scenario_config",
43
+ ScenarioConfigHandler(self.scenario_mgr))
44
+ self.app.add_route("/scenario/{scenario_id}/general_params",
45
+ ScenarioGeneralParamsHandler(self.scenario_mgr))
46
+ self.app.add_route("/scenario/{scenario_id}/sensor_config",
47
+ ScenarioSensorConfigHandler(self.scenario_mgr))
48
+ self.app.add_route("/scenario/{scenario_id}/leakages",
49
+ ScenarioLeakageHandler(self.scenario_mgr))
50
+ self.app.add_route("/scenario/{scenario_id}/simulation",
51
+ ScenarioSimulationHandler(scenario_mgr=self.scenario_mgr,
52
+ scada_data_mgr=self.scada_data_mgr))
53
+
54
+ self.app.add_route("/scada_data/{data_id}",
55
+ ScadaDataRemoveHandler(self.scada_data_mgr))
56
+ self.app.add_route("/scada_data/{data_id}/sensor_config",
57
+ ScadaDataSensorConfigHandler(self.scada_data_mgr))
58
+ self.app.add_route("/scada_data/{data_id}/sensor_faults",
59
+ ScadaDataSensorFaultsHandler(self.scada_data_mgr))
60
+ self.app.add_route("/scada_data/{data_id}/pressures",
61
+ 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",
65
+ ScadaDataDemandsHandler(self.scada_data_mgr))
66
+ self.app.add_route("/scada_data/{data_id}/pump_states",
67
+ ScadaDataPumpStatesHandler(self.scada_data_mgr))
68
+ self.app.add_route("/scada_data/{data_id}/valve_states",
69
+ ScadaDataValveStatesHandler(self.scada_data_mgr))
70
+ self.app.add_route("/scada_data/{data_id}/tank_volumes",
71
+ 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))
82
+
83
+ @property
84
+ def port(self) -> int:
85
+ """
86
+ Gets the port of the web server.
87
+
88
+ Returns
89
+ -------
90
+ `int`
91
+ Port.
92
+ """
93
+ return self.__port
94
+
95
+ def make_server(self) -> WSGIServer:
96
+ """
97
+ Returns a new web server.
98
+ """
99
+ return make_server("", self.__port, self.app)
100
+
101
+ def run(self) -> None:
102
+ """
103
+ Runs the REST service.
104
+ """
105
+ with self.make_server() as httpd:
106
+ httpd.serve_forever()