Passed
Push — master ( 42322a...183c79 )
by
unknown
10:22 queued 16s
created

EnergyFlowDiagramItem.on_delete()   B

Complexity

Conditions 5

Size

Total Lines 41
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 41
rs 8.6933
c 0
b 0
f 0
cc 5
nop 3
1
import uuid
2
from datetime import datetime, timedelta
3
import falcon
4
import mysql.connector
5
import simplejson as json
6
from core.useractivity import user_logger, admin_control, access_control, api_key_control
7
import config
8
9
10
class EnergyFlowDiagramCollection:
11
    def __init__(self):
12
        """"Initializes EnergyFlowDiagramCollection"""
13
        pass
14
15
    @staticmethod
16
    def on_options(req, resp):
17
        _ = req
18
        resp.status = falcon.HTTP_200
19
20
    @staticmethod
21
    def on_get(req, resp):
22
        if 'API-KEY' not in req.headers or \
23
                not isinstance(req.headers['API-KEY'], str) or \
24
                len(str.strip(req.headers['API-KEY'])) == 0:
25
            access_control(req)
26
        else:
27
            api_key_control(req)
28
        cnx = mysql.connector.connect(**config.myems_system_db)
29
        cursor = cnx.cursor()
30
31
        query = (" SELECT id, name, uuid "
32
                 " FROM tbl_meters ")
33
        cursor.execute(query)
34
        rows_meters = cursor.fetchall()
35
36
        meter_dict = dict()
37
        if rows_meters is not None and len(rows_meters) > 0:
38
            for row in rows_meters:
39
                meter_dict[row[2]] = {"type": 'meter',
40
                                      "id": row[0],
41
                                      "name": row[1],
42
                                      "uuid": row[2]}
43
44
        query = (" SELECT id, name, uuid "
45
                 " FROM tbl_offline_meters ")
46
        cursor.execute(query)
47
        rows_offline_meters = cursor.fetchall()
48
49
        offline_meter_dict = dict()
50
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
51
            for row in rows_offline_meters:
52
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
53
                                              "id": row[0],
54
                                              "name": row[1],
55
                                              "uuid": row[2]}
56
57
        query = (" SELECT id, name, uuid "
58
                 " FROM tbl_virtual_meters ")
59
        cursor.execute(query)
60
        rows_virtual_meters = cursor.fetchall()
61
62
        virtual_meter_dict = dict()
63
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
64
            for row in rows_virtual_meters:
65
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
66
                                              "id": row[0],
67
                                              "name": row[1],
68
                                              "uuid": row[2]}
69
70
        query = (" SELECT id, energy_flow_diagram_id, name "
71
                 " FROM tbl_energy_flow_diagrams_nodes")
72
        cursor.execute(query)
73
        rows_nodes = cursor.fetchall()
74
75
        node_dict = dict()
76
        node_list_dict = dict()
77
        if rows_nodes is not None and len(rows_nodes) > 0:
78
            for row in rows_nodes:
79
                node_dict[row[0]] = row[2]
80
                if node_list_dict.get(row[1]) is None:
81
                    node_list_dict[row[1]] = list()
82
                node_list_dict[row[1]].append({"id": row[0], "name": row[2]})
83
84
        query = (" SELECT id, energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid "
85
                 " FROM tbl_energy_flow_diagrams_links")
86
        cursor.execute(query)
87
        rows_links = cursor.fetchall()
88
89
        link_list_dict = dict()
90
        if rows_links is not None and len(rows_links) > 0:
91
            for row in rows_links:
92
                # find meter by uuid
93
                meter = meter_dict.get(row[4], None)
94
                if meter is None:
95
                    meter = virtual_meter_dict.get(row[4], None)
96
                if meter is None:
97
                    meter = offline_meter_dict.get(row[4], None)
98
99
                if link_list_dict.get(row[1]) is None:
100
                    link_list_dict[row[1]] = list()
101
                link_list_dict[row[1]].append({"id": row[0],
102
                                               "source_node": {
103
                                                   "id": row[2],
104
                                                   "name": node_dict.get(row[2])},
105
                                               "target_node": {
106
                                                   "id": row[3],
107
                                                   "name": node_dict.get(row[3])},
108
                                               "meter": meter})
109
110
        query = (" SELECT id, name, uuid "
111
                 " FROM tbl_energy_flow_diagrams "
112
                 " ORDER BY id ")
113
        cursor.execute(query)
114
        rows_energy_flow_diagrams = cursor.fetchall()
115
116
        result = list()
117
        if rows_energy_flow_diagrams is not None and len(rows_energy_flow_diagrams) > 0:
118
            for row in rows_energy_flow_diagrams:
119
120
                meta_result = {"id": row[0],
121
                               "name": row[1],
122
                               "uuid": row[2],
123
                               "nodes": node_list_dict.get(row[0], None),
124
                               "links": link_list_dict.get(row[0], None), }
125
                result.append(meta_result)
126
127
        cursor.close()
128
        cnx.close()
129
        resp.text = json.dumps(result)
130
131
    @staticmethod
132
    @user_logger
133
    def on_post(req, resp):
134
        """Handles POST requests"""
135
        admin_control(req)
136
        try:
137
            raw_json = req.stream.read().decode('utf-8')
138
        except Exception as ex:
139
            print(str(ex))
140
            raise falcon.HTTPError(status=falcon.HTTP_400,
141
                                   title='API.BAD_REQUEST',
142
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
143
144
        new_values = json.loads(raw_json)
145
146
        if 'name' not in new_values['data'].keys() or \
147
                not isinstance(new_values['data']['name'], str) or \
148
                len(str.strip(new_values['data']['name'])) == 0:
149
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
150
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NAME')
151
        name = str.strip(new_values['data']['name'])
152
153
        cnx = mysql.connector.connect(**config.myems_system_db)
154
        cursor = cnx.cursor()
155
156
        cursor.execute(" SELECT name "
157
                       " FROM tbl_energy_flow_diagrams "
158
                       " WHERE name = %s ", (name,))
159
        if cursor.fetchone() is not None:
160
            cursor.close()
161
            cnx.close()
162
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
163
                                   description='API.ENERGY_FLOW_DIAGRAM_NAME_IS_ALREADY_IN_USE')
164
165
        add_values = (" INSERT INTO tbl_energy_flow_diagrams "
166
                      "    (name, uuid) "
167
                      " VALUES (%s, %s) ")
168
        cursor.execute(add_values, (name,
169
                                    str(uuid.uuid4())))
170
        new_id = cursor.lastrowid
171
        cnx.commit()
172
        cursor.close()
173
        cnx.close()
174
175
        resp.status = falcon.HTTP_201
176
        resp.location = '/energyflowdiagrams/' + str(new_id)
177
178
179
class EnergyFlowDiagramItem:
180
    def __init__(self):
181
        """"Initializes EnergyFlowDiagramItem"""
182
        pass
183
184
    @staticmethod
185
    def on_options(req, resp, id_):
186
        _ = req
187
        resp.status = falcon.HTTP_200
188
        _ = id_
189
190 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
191
    def on_get(req, resp, id_):
192
        if 'API-KEY' not in req.headers or \
193
                not isinstance(req.headers['API-KEY'], str) or \
194
                len(str.strip(req.headers['API-KEY'])) == 0:
195
            access_control(req)
196
        else:
197
            api_key_control(req)
198
        if not id_.isdigit() or int(id_) <= 0:
199
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
200
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
201
202
        cnx = mysql.connector.connect(**config.myems_system_db)
203
        cursor = cnx.cursor()
204
205
        query = (" SELECT id, name, uuid "
206
                 " FROM tbl_meters ")
207
        cursor.execute(query)
208
        rows_meters = cursor.fetchall()
209
210
        meter_dict = dict()
211
        if rows_meters is not None and len(rows_meters) > 0:
212
            for row in rows_meters:
213
                meter_dict[row[2]] = {"type": 'meter',
214
                                      "id": row[0],
215
                                      "name": row[1],
216
                                      "uuid": row[2]}
217
218
        query = (" SELECT id, name, uuid "
219
                 " FROM tbl_offline_meters ")
220
        cursor.execute(query)
221
        rows_offline_meters = cursor.fetchall()
222
223
        offline_meter_dict = dict()
224
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
225
            for row in rows_offline_meters:
226
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
227
                                              "id": row[0],
228
                                              "name": row[1],
229
                                              "uuid": row[2]}
230
231
        query = (" SELECT id, name, uuid "
232
                 " FROM tbl_virtual_meters ")
233
        cursor.execute(query)
234
        rows_virtual_meters = cursor.fetchall()
235
236
        virtual_meter_dict = dict()
237
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
238
            for row in rows_virtual_meters:
239
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
240
                                              "id": row[0],
241
                                              "name": row[1],
242
                                              "uuid": row[2]}
243
244
        query = (" SELECT id, energy_flow_diagram_id, name "
245
                 " FROM tbl_energy_flow_diagrams_nodes")
246
        cursor.execute(query)
247
        rows_nodes = cursor.fetchall()
248
249
        node_dict = dict()
250
        node_list_dict = dict()
251
        if rows_nodes is not None and len(rows_nodes) > 0:
252
            for row in rows_nodes:
253
                node_dict[row[0]] = row[2]
254
                if node_list_dict.get(row[1]) is None:
255
                    node_list_dict[row[1]] = list()
256
                node_list_dict[row[1]].append({"id": row[0], "name": row[2]})
257
258
        query = (" SELECT id, energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid "
259
                 " FROM tbl_energy_flow_diagrams_links")
260
        cursor.execute(query)
261
        rows_links = cursor.fetchall()
262
263
        link_list_dict = dict()
264
        if rows_links is not None and len(rows_links) > 0:
265
            for row in rows_links:
266
                # find meter by uuid
267
                meter = meter_dict.get(row[4], None)
268
                if meter is None:
269
                    meter = virtual_meter_dict.get(row[4], None)
270
                if meter is None:
271
                    meter = offline_meter_dict.get(row[4], None)
272
273
                if link_list_dict.get(row[1]) is None:
274
                    link_list_dict[row[1]] = list()
275
                link_list_dict[row[1]].append({"id": row[0],
276
                                               "source_node": {
277
                                                   "id": row[2],
278
                                                   "name": node_dict.get(row[2])},
279
                                               "target_node": {
280
                                                   "id": row[3],
281
                                                   "name": node_dict.get(row[3])},
282
                                               "meter": meter})
283
284
        query = (" SELECT id, name, uuid "
285
                 " FROM tbl_energy_flow_diagrams "
286
                 " WHERE id = %s ")
287
        cursor.execute(query, (id_,))
288
        row = cursor.fetchone()
289
        cursor.close()
290
        cnx.close()
291
292
        if row is None:
293
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
294
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
295
        else:
296
            meta_result = {"id": row[0],
297
                           "name": row[1],
298
                           "uuid": row[2],
299
                           "nodes": node_list_dict.get(row[0], None),
300
                           "links": link_list_dict.get(row[0], None),
301
                           }
302
303
        resp.text = json.dumps(meta_result)
304
305
    @staticmethod
306
    @user_logger
307
    def on_delete(req, resp, id_):
308
        admin_control(req)
309
        if not id_.isdigit() or int(id_) <= 0:
310
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
311
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
312
313
        cnx = mysql.connector.connect(**config.myems_system_db)
314
        cursor = cnx.cursor()
315
316
        # check relation with spaces
317
        cursor.execute(" SELECT id "
318
                       " FROM  tbl_spaces_energy_flow_diagrams "
319
                       " WHERE energy_flow_diagram_id = %s ", (id_,))
320
        rows_spaces = cursor.fetchall()
321
        if rows_spaces is not None and len(rows_spaces) > 0:
322
            cursor.close()
323
            cnx.close()
324
            raise falcon.HTTPError(status=falcon.HTTP_400,
325
                                   title='API.BAD_REQUEST',
326
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
327
328
        # delete all associated nodes
329
        cursor.execute(" DELETE FROM tbl_energy_flow_diagrams_nodes"
330
                       " WHERE energy_flow_diagram_id = %s ", (id_,))
331
        cnx.commit()
332
333
        # delete all associated links
334
        cursor.execute(" DELETE FROM tbl_energy_flow_diagrams_links"
335
                       " WHERE energy_flow_diagram_id = %s ", (id_,))
336
        cnx.commit()
337
338
        cursor.execute(" DELETE FROM tbl_energy_flow_diagrams"
339
                       " WHERE id = %s ", (id_,))
340
        cnx.commit()
341
342
        cursor.close()
343
        cnx.close()
344
345
        resp.status = falcon.HTTP_204
346
347
    @staticmethod
348
    @user_logger
349
    def on_put(req, resp, id_):
350
        """Handles PUT requests"""
351
        admin_control(req)
352
        if not id_.isdigit() or int(id_) <= 0:
353
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
354
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
355
        try:
356
            raw_json = req.stream.read().decode('utf-8')
357
        except Exception as ex:
358
            print(str(ex))
359
            raise falcon.HTTPError(status=falcon.HTTP_400,
360
                                   title='API.BAD_REQUEST',
361
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
362
363
        new_values = json.loads(raw_json)
364
365
        if 'name' not in new_values['data'].keys() or \
366
                not isinstance(new_values['data']['name'], str) or \
367
                len(str.strip(new_values['data']['name'])) == 0:
368
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
369
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NAME')
370
        name = str.strip(new_values['data']['name'])
371
372
        cnx = mysql.connector.connect(**config.myems_system_db)
373
        cursor = cnx.cursor()
374
375
        cursor.execute(" SELECT name "
376
                       " FROM tbl_energy_flow_diagrams "
377
                       " WHERE id = %s ", (id_,))
378
        if cursor.fetchone() is None:
379
            cursor.close()
380
            cnx.close()
381
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
382
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
383
384
        cursor.execute(" SELECT name "
385
                       " FROM tbl_energy_flow_diagrams "
386
                       " WHERE name = %s AND id != %s ", (name, id_))
387
        if cursor.fetchone() is not None:
388
            cursor.close()
389
            cnx.close()
390
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
391
                                   description='API.ENERGY_FLOW_DIAGRAM_NAME_IS_ALREADY_IN_USE')
392
393
        update_row = (" UPDATE tbl_energy_flow_diagrams "
394
                      " SET name = %s "
395
                      " WHERE id = %s ")
396
        cursor.execute(update_row, (name,
397
                                    id_))
398
        cnx.commit()
399
400
        cursor.close()
401
        cnx.close()
402
403
        resp.status = falcon.HTTP_200
404
405
406
class EnergyFlowDiagramLinkCollection:
407
    def __init__(self):
408
        """"Initializes EnergyFlowDiagramLinkCollection"""
409
        pass
410
411
    @staticmethod
412
    def on_options(req, resp, id_):
413
        _ = req
414
        resp.status = falcon.HTTP_200
415
        _ = id_
416
417
    @staticmethod
418
    def on_get(req, resp, id_):
419
        if 'API-KEY' not in req.headers or \
420
                not isinstance(req.headers['API-KEY'], str) or \
421
                len(str.strip(req.headers['API-KEY'])) == 0:
422
            access_control(req)
423
        else:
424
            api_key_control(req)
425
        if not id_.isdigit() or int(id_) <= 0:
426
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
427
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
428
429
        cnx = mysql.connector.connect(**config.myems_system_db)
430
        cursor = cnx.cursor()
431
432
        query = (" SELECT id, name "
433
                 " FROM tbl_energy_flow_diagrams_nodes ")
434
        cursor.execute(query)
435
        rows_nodes = cursor.fetchall()
436
437
        node_dict = dict()
438
        if rows_nodes is not None and len(rows_nodes) > 0:
439
            for row in rows_nodes:
440
                node_dict[row[0]] = {"id": row[0],
441
                                     "name": row[1]}
442
443
        query = (" SELECT id, name, uuid "
444
                 " FROM tbl_meters ")
445
        cursor.execute(query)
446
        rows_meters = cursor.fetchall()
447
448
        meter_dict = dict()
449
        if rows_meters is not None and len(rows_meters) > 0:
450
            for row in rows_meters:
451
                meter_dict[row[2]] = {"type": 'meter',
452
                                      "id": row[0],
453
                                      "name": row[1],
454
                                      "uuid": row[2]}
455
456
        query = (" SELECT id, name, uuid "
457
                 " FROM tbl_offline_meters ")
458
        cursor.execute(query)
459
        rows_offline_meters = cursor.fetchall()
460
461
        offline_meter_dict = dict()
462
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
463
            for row in rows_offline_meters:
464
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
465
                                              "id": row[0],
466
                                              "name": row[1],
467
                                              "uuid": row[2]}
468
469
        query = (" SELECT id, name, uuid "
470
                 " FROM tbl_virtual_meters ")
471
        cursor.execute(query)
472
        rows_virtual_meters = cursor.fetchall()
473
474
        virtual_meter_dict = dict()
475
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
476
            for row in rows_virtual_meters:
477
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
478
                                              "id": row[0],
479
                                              "name": row[1],
480
                                              "uuid": row[2]}
481
482
        cursor.execute(" SELECT name "
483
                       " FROM tbl_energy_flow_diagrams "
484
                       " WHERE id = %s ", (id_,))
485
        if cursor.fetchone() is None:
486
            cursor.close()
487
            cnx.close()
488
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
489
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
490
491
        query = (" SELECT id, source_node_id, target_node_id, meter_uuid "
492
                 " FROM tbl_energy_flow_diagrams_links "
493
                 " WHERE energy_flow_diagram_id = %s "
494
                 " ORDER BY id ")
495
        cursor.execute(query, (id_, ))
496
        rows_links = cursor.fetchall()
497
498
        result = list()
499
        if rows_links is not None and len(rows_links) > 0:
500
            for row in rows_links:
501
                source_node = node_dict.get(row[1], None)
502
                target_node = node_dict.get(row[2], None)
503
                # find meter by uuid
504
                meter = meter_dict.get(row[3], None)
505
                if meter is None:
506
                    meter = virtual_meter_dict.get(row[3], None)
507
                if meter is None:
508
                    meter = offline_meter_dict.get(row[3], None)
509
510
                meta_result = {"id": row[0],
511
                               "source_node": source_node,
512
                               "target_node": target_node,
513
                               "meter": meter}
514
                result.append(meta_result)
515
516
        cursor.close()
517
        cnx.close()
518
        resp.text = json.dumps(result)
519
520
    @staticmethod
521
    @user_logger
522
    def on_post(req, resp, id_):
523
        """Handles POST requests"""
524
        admin_control(req)
525
        if not id_.isdigit() or int(id_) <= 0:
526
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
527
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
528
        try:
529
            raw_json = req.stream.read().decode('utf-8')
530
        except Exception as ex:
531
            print(str(ex))
532
            raise falcon.HTTPError(status=falcon.HTTP_400,
533
                                   title='API.BAD_REQUEST',
534
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
535
536
        new_values = json.loads(raw_json)
537
538
        source_node_id = None
539
        if 'source_node_id' in new_values['data'].keys():
540
            if new_values['data']['source_node_id'] is not None and \
541
                    new_values['data']['source_node_id'] <= 0:
542
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
543
                                       description='API.INVALID_SOURCE_NODE_ID')
544
            source_node_id = new_values['data']['source_node_id']
545
546
        target_node_id = None
547
        if 'target_node_id' in new_values['data'].keys():
548
            if new_values['data']['target_node_id'] is not None and \
549
                    new_values['data']['target_node_id'] <= 0:
550
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
551
                                       description='API.INVALID_TARGET_NODE_ID')
552
            target_node_id = new_values['data']['target_node_id']
553
554
        meter_uuid = None
555
        if 'meter_uuid' in new_values['data'].keys():
556
            if new_values['data']['meter_uuid'] is not None and \
557
                    isinstance(new_values['data']['meter_uuid'], str) and \
558
                    len(str.strip(new_values['data']['meter_uuid'])) > 0:
559
                meter_uuid = str.strip(new_values['data']['meter_uuid'])
560
561
        cnx = mysql.connector.connect(**config.myems_system_db)
562
        cursor = cnx.cursor()
563
564
        cursor.execute(" SELECT name "
565
                       " FROM tbl_energy_flow_diagrams "
566
                       " WHERE id = %s ", (id_,))
567
        if cursor.fetchone() is None:
568
            cursor.close()
569
            cnx.close()
570
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
571
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
572
573
        cursor.execute(" SELECT id "
574
                       " FROM tbl_energy_flow_diagrams_links "
575
                       " WHERE energy_flow_diagram_id = %s AND "
576
                       "       source_node_id = %s AND target_node_id = %s ",
577
                       (id_, source_node_id, target_node_id,))
578
        row = cursor.fetchone()
579
        if row is not None:
580
            cursor.close()
581
            cnx.close()
582
            raise falcon.HTTPError(status=falcon.HTTP_400,
583
                                   title='API.NOT_FOUND',
584
                                   description='API.ENERGY_FLOW_DIAGRAM_LINK_IS_ALREADY_IN_USE')
585
586
        query = (" SELECT id, name "
587
                 " FROM tbl_energy_flow_diagrams_nodes "
588
                 " WHERE id = %s ")
589
        cursor.execute(query, (source_node_id,))
590
        if cursor.fetchone() is None:
591
            cursor.close()
592
            cnx.close()
593
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
594
                                   description='API.SOURCE_NODE_NOT_FOUND')
595
596
        query = (" SELECT id, name "
597
                 " FROM tbl_energy_flow_diagrams_nodes "
598
                 " WHERE id = %s ")
599
        cursor.execute(query, (target_node_id,))
600
        if cursor.fetchone() is None:
601
            cursor.close()
602
            cnx.close()
603
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
604
                                   description='API.TARGET_NODE_NOT_FOUND')
605
606
        query = (" SELECT id, name, uuid "
607
                 " FROM tbl_meters ")
608
        cursor.execute(query)
609
        rows_meters = cursor.fetchall()
610
611
        meter_dict = dict()
612
        if rows_meters is not None and len(rows_meters) > 0:
613
            for row in rows_meters:
614
                meter_dict[row[2]] = {"type": 'meter',
615
                                      "id": row[0],
616
                                      "name": row[1],
617
                                      "uuid": row[2]}
618
619
        query = (" SELECT id, name, uuid "
620
                 " FROM tbl_offline_meters ")
621
        cursor.execute(query)
622
        rows_offline_meters = cursor.fetchall()
623
624
        offline_meter_dict = dict()
625
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
626
            for row in rows_offline_meters:
627
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
628
                                              "id": row[0],
629
                                              "name": row[1],
630
                                              "uuid": row[2]}
631
632
        query = (" SELECT id, name, uuid "
633
                 " FROM tbl_virtual_meters ")
634
        cursor.execute(query)
635
        rows_virtual_meters = cursor.fetchall()
636
637
        virtual_meter_dict = dict()
638
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
639
            for row in rows_virtual_meters:
640
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
641
                                              "id": row[0],
642
                                              "name": row[1],
643
                                              "uuid": row[2]}
644
645
        # validate meter uuid
646
        if meter_dict.get(meter_uuid) is None and \
647
                virtual_meter_dict.get(meter_uuid) is None and \
648
                offline_meter_dict.get(meter_uuid) is None:
649
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
650
                                   description='API.INVALID_METER_UUID')
651
652
        add_values = (" INSERT INTO tbl_energy_flow_diagrams_links "
653
                      "    (energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid) "
654
                      " VALUES (%s, %s, %s, %s) ")
655
        cursor.execute(add_values, (id_,
656
                                    source_node_id,
657
                                    target_node_id,
658
                                    meter_uuid))
659
        new_id = cursor.lastrowid
660
        cnx.commit()
661
        cursor.close()
662
        cnx.close()
663
664
        resp.status = falcon.HTTP_201
665
        resp.location = '/energyflowdiagrams/' + str(id_) + 'links/' + str(new_id)
666
667
668
class EnergyFlowDiagramLinkItem:
669
    def __init__(self):
670
        """"Initializes EnergyFlowDiagramLinkItem"""
671
        pass
672
673
    @staticmethod
674
    def on_options(req, resp, id_, lid):
675
        _ = req
676
        resp.status = falcon.HTTP_200
677
        _ = id_
678
679
    @staticmethod
680
    def on_get(req, resp, id_, lid):
681
        access_control(req)
682
        if not id_.isdigit() or int(id_) <= 0:
683
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
684
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
685
686
        if not lid.isdigit() or int(lid) <= 0:
687
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
688
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_LINK_ID')
689
690
        cnx = mysql.connector.connect(**config.myems_system_db)
691
        cursor = cnx.cursor()
692
693
        query = (" SELECT id, name "
694
                 " FROM tbl_energy_flow_diagrams_nodes ")
695
        cursor.execute(query)
696
        rows_nodes = cursor.fetchall()
697
698
        node_dict = dict()
699
        if rows_nodes is not None and len(rows_nodes) > 0:
700
            for row in rows_nodes:
701
                node_dict[row[0]] = {"id": row[0],
702
                                     "name": row[1]}
703
704
        query = (" SELECT id, name, uuid "
705
                 " FROM tbl_meters ")
706
        cursor.execute(query)
707
        rows_meters = cursor.fetchall()
708
709
        meter_dict = dict()
710
        if rows_meters is not None and len(rows_meters) > 0:
711
            for row in rows_meters:
712
                meter_dict[row[2]] = {"type": 'meter',
713
                                      "id": row[0],
714
                                      "name": row[1],
715
                                      "uuid": row[2]}
716
717
        query = (" SELECT id, name, uuid "
718
                 " FROM tbl_offline_meters ")
719
        cursor.execute(query)
720
        rows_offline_meters = cursor.fetchall()
721
722
        offline_meter_dict = dict()
723
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
724
            for row in rows_offline_meters:
725
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
726
                                              "id": row[0],
727
                                              "name": row[1],
728
                                              "uuid": row[2]}
729
730
        query = (" SELECT id, name, uuid "
731
                 " FROM tbl_virtual_meters ")
732
        cursor.execute(query)
733
        rows_virtual_meters = cursor.fetchall()
734
735
        virtual_meter_dict = dict()
736
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
737
            for row in rows_virtual_meters:
738
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
739
                                              "id": row[0],
740
                                              "name": row[1],
741
                                              "uuid": row[2]}
742
743
        query = (" SELECT id, source_node_id, target_node_id, meter_uuid "
744
                 " FROM tbl_energy_flow_diagrams_links "
745
                 " WHERE energy_flow_diagram_id = %s AND id = %s ")
746
        cursor.execute(query, (id_, lid))
747
        row = cursor.fetchone()
748
        cursor.close()
749
        cnx.close()
750
751
        if row is None:
752
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
753
                                   description='API.ENERGY_FLOW_DIAGRAM_LINK_NOT_FOUND_OR_NOT_MATCH')
754
        else:
755
            source_node = node_dict.get(row[1], None)
756
            target_node = node_dict.get(row[2], None)
757
            # find meter by uuid
758
            meter = meter_dict.get(row[3], None)
759
            if meter is None:
760
                meter = virtual_meter_dict.get(row[3], None)
761
            if meter is None:
762
                meter = offline_meter_dict.get(row[3], None)
763
764
            meta_result = {"id": row[0],
765
                           "source_node": source_node,
766
                           "target_node": target_node,
767
                           "meter": meter}
768
            resp.text = json.dumps(meta_result)
769
770
    @staticmethod
771
    @user_logger
772
    def on_delete(req, resp, id_, lid):
773
        admin_control(req)
774
        if not id_.isdigit() or int(id_) <= 0:
775
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
776
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
777
778
        if not lid.isdigit() or int(lid) <= 0:
779
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
780
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_LINK_ID')
781
782
        cnx = mysql.connector.connect(**config.myems_system_db)
783
        cursor = cnx.cursor()
784
785
        cursor.execute(" SELECT name "
786
                       " FROM tbl_energy_flow_diagrams "
787
                       " WHERE id = %s ",
788
                       (id_,))
789
        row = cursor.fetchone()
790
        if row is None:
791
            cursor.close()
792
            cnx.close()
793
            raise falcon.HTTPError(status=falcon.HTTP_400,
794
                                   title='API.NOT_FOUND',
795
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
796
797
        cursor.execute(" SELECT id "
798
                       " FROM tbl_energy_flow_diagrams_links "
799
                       " WHERE energy_flow_diagram_id = %s AND id = %s ",
800
                       (id_, lid,))
801
        row = cursor.fetchone()
802
        if row is None:
803
            cursor.close()
804
            cnx.close()
805
            raise falcon.HTTPError(status=falcon.HTTP_400,
806
                                   title='API.NOT_FOUND',
807
                                   description='API.ENERGY_FLOW_DIAGRAM_LINK_NOT_FOUND_OR_NOT_MATCH')
808
809
        cursor.execute(" DELETE FROM tbl_energy_flow_diagrams_links "
810
                       " WHERE id = %s ", (lid, ))
811
        cnx.commit()
812
813
        cursor.close()
814
        cnx.close()
815
816
        resp.status = falcon.HTTP_204
817
818
    @staticmethod
819
    @user_logger
820
    def on_put(req, resp, id_, lid):
821
        """Handles PUT requests"""
822
        admin_control(req)
823
        if not id_.isdigit() or int(id_) <= 0:
824
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
825
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
826
827
        if not lid.isdigit() or int(lid) <= 0:
828
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
829
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_LINK_ID')
830
831
        try:
832
            raw_json = req.stream.read().decode('utf-8')
833
        except Exception as ex:
834
            print(str(ex))
835
            raise falcon.HTTPError(status=falcon.HTTP_400,
836
                                   title='API.BAD_REQUEST',
837
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
838
839
        new_values = json.loads(raw_json)
840
841
        source_node_id = None
842
        if 'source_node_id' in new_values['data'].keys():
843
            if new_values['data']['source_node_id'] is not None and \
844
                    new_values['data']['source_node_id'] <= 0:
845
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
846
                                       description='API.INVALID_SOURCE_NODE_ID')
847
            source_node_id = new_values['data']['source_node_id']
848
849
        target_node_id = None
850
        if 'target_node_id' in new_values['data'].keys():
851
            if new_values['data']['target_node_id'] is not None and \
852
                    new_values['data']['target_node_id'] <= 0:
853
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
854
                                       description='API.INVALID_TARGET_NODE_ID')
855
            target_node_id = new_values['data']['target_node_id']
856
857
        meter_uuid = None
858
        if 'meter_uuid' in new_values['data'].keys():
859
            if new_values['data']['meter_uuid'] is not None and \
860
                    isinstance(new_values['data']['meter_uuid'], str) and \
861
                    len(str.strip(new_values['data']['meter_uuid'])) > 0:
862
                meter_uuid = str.strip(new_values['data']['meter_uuid'])
863
864
        cnx = mysql.connector.connect(**config.myems_system_db)
865
        cursor = cnx.cursor()
866
867
        cursor.execute(" SELECT name "
868
                       " FROM tbl_energy_flow_diagrams "
869
                       " WHERE id = %s ", (id_,))
870
        if cursor.fetchone() is None:
871
            cursor.close()
872
            cnx.close()
873
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
874
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
875
876
        cursor.execute(" SELECT id "
877
                       " FROM tbl_energy_flow_diagrams_links "
878
                       " WHERE energy_flow_diagram_id = %s AND id = %s ",
879
                       (id_, lid,))
880
        row = cursor.fetchone()
881
        if row is None:
882
            cursor.close()
883
            cnx.close()
884
            raise falcon.HTTPError(status=falcon.HTTP_400,
885
                                   title='API.NOT_FOUND',
886
                                   description='API.ENERGY_FLOW_DIAGRAM_LINK_NOT_FOUND_OR_NOT_MATCH')
887
888
        cursor.execute(" SELECT id "
889
                       " FROM tbl_energy_flow_diagrams_links "
890
                       " WHERE energy_flow_diagram_id = %s AND id != %s "
891
                       "       AND source_node_id = %s AND target_node_id = %s ",
892
                       (id_, lid, source_node_id, target_node_id,))
893
        row = cursor.fetchone()
894
        if row is not None:
895
            cursor.close()
896
            cnx.close()
897
            raise falcon.HTTPError(status=falcon.HTTP_400,
898
                                   title='API.NOT_FOUND',
899
                                   description='API.ENERGY_FLOW_DIAGRAM_LINK_IS_ALREADY_IN_USE')
900
901
        query = (" SELECT id, name "
902
                 " FROM tbl_energy_flow_diagrams_nodes "
903
                 " WHERE id = %s ")
904
        cursor.execute(query, (source_node_id,))
905
        if cursor.fetchone() is None:
906
            cursor.close()
907
            cnx.close()
908
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
909
                                   description='API.SOURCE_NODE_NOT_FOUND')
910
911
        query = (" SELECT id, name "
912
                 " FROM tbl_energy_flow_diagrams_nodes "
913
                 " WHERE id = %s ")
914
        cursor.execute(query, (target_node_id,))
915
        if cursor.fetchone() is None:
916
            cursor.close()
917
            cnx.close()
918
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
919
                                   description='API.TARGET_NODE_NOT_FOUND')
920
921
        query = (" SELECT id, name, uuid "
922
                 " FROM tbl_meters ")
923
        cursor.execute(query)
924
        rows_meters = cursor.fetchall()
925
926
        meter_dict = dict()
927
        if rows_meters is not None and len(rows_meters) > 0:
928
            for row in rows_meters:
929
                meter_dict[row[2]] = {"type": 'meter',
930
                                      "id": row[0],
931
                                      "name": row[1],
932
                                      "uuid": row[2]}
933
934
        query = (" SELECT id, name, uuid "
935
                 " FROM tbl_offline_meters ")
936
        cursor.execute(query)
937
        rows_offline_meters = cursor.fetchall()
938
939
        offline_meter_dict = dict()
940
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
941
            for row in rows_offline_meters:
942
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
943
                                              "id": row[0],
944
                                              "name": row[1],
945
                                              "uuid": row[2]}
946
947
        query = (" SELECT id, name, uuid "
948
                 " FROM tbl_virtual_meters ")
949
        cursor.execute(query)
950
        rows_virtual_meters = cursor.fetchall()
951
952
        virtual_meter_dict = dict()
953
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
954
            for row in rows_virtual_meters:
955
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
956
                                              "id": row[0],
957
                                              "name": row[1],
958
                                              "uuid": row[2]}
959
960
        # validate meter uuid
961
        if meter_dict.get(meter_uuid) is None and \
962
                virtual_meter_dict.get(meter_uuid) is None and \
963
                offline_meter_dict.get(meter_uuid) is None:
964
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
965
                                   description='API.INVALID_METER_UUID')
966
967
        add_values = (" UPDATE tbl_energy_flow_diagrams_links "
968
                      " SET source_node_id = %s, target_node_id = %s, meter_uuid = %s "
969
                      " WHERE id = %s ")
970
        cursor.execute(add_values, (source_node_id,
971
                                    target_node_id,
972
                                    meter_uuid,
973
                                    lid))
974
        cnx.commit()
975
976
        cursor.close()
977
        cnx.close()
978
979
        resp.status = falcon.HTTP_200
980
981
982
class EnergyFlowDiagramNodeCollection:
983
    def __init__(self):
984
        """"Initializes EnergyFlowDiagramNodeCollection"""
985
        pass
986
987
    @staticmethod
988
    def on_options(req, resp, id_):
989
        _ = req
990
        resp.status = falcon.HTTP_200
991
        _ = id_
992
993
    @staticmethod
994
    def on_get(req, resp, id_):
995
        if 'API-KEY' not in req.headers or \
996
                not isinstance(req.headers['API-KEY'], str) or \
997
                len(str.strip(req.headers['API-KEY'])) == 0:
998
            access_control(req)
999
        else:
1000
            api_key_control(req)
1001
        if not id_.isdigit() or int(id_) <= 0:
1002
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1003
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1004
1005
        cnx = mysql.connector.connect(**config.myems_system_db)
1006
        cursor = cnx.cursor()
1007
1008
        cursor.execute(" SELECT name "
1009
                       " FROM tbl_energy_flow_diagrams "
1010
                       " WHERE id = %s ", (id_,))
1011
        if cursor.fetchone() is None:
1012
            cursor.close()
1013
            cnx.close()
1014
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1015
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1016
1017
        query = (" SELECT id, name "
1018
                 " FROM tbl_energy_flow_diagrams_nodes "
1019
                 " WHERE energy_flow_diagram_id = %s "
1020
                 " ORDER BY id ")
1021
        cursor.execute(query, (id_, ))
1022
        rows_nodes = cursor.fetchall()
1023
1024
        result = list()
1025
        if rows_nodes is not None and len(rows_nodes) > 0:
1026
            for row in rows_nodes:
1027
                meta_result = {"id": row[0],
1028
                               "name": row[1]}
1029
                result.append(meta_result)
1030
1031
        cursor.close()
1032
        cnx.close()
1033
        resp.text = json.dumps(result)
1034
1035
    @staticmethod
1036
    @user_logger
1037
    def on_post(req, resp, id_):
1038
        """Handles POST requests"""
1039
        admin_control(req)
1040
        if not id_.isdigit() or int(id_) <= 0:
1041
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1042
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1043
        try:
1044
            raw_json = req.stream.read().decode('utf-8')
1045
        except Exception as ex:
1046
            print(str(ex))
1047
            raise falcon.HTTPError(status=falcon.HTTP_400,
1048
                                   title='API.BAD_REQUEST',
1049
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1050
1051
        new_values = json.loads(raw_json)
1052
1053
        if 'name' not in new_values['data'].keys() or \
1054
                not isinstance(new_values['data']['name'], str) or \
1055
                len(str.strip(new_values['data']['name'])) == 0:
1056
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1057
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NODE_NAME')
1058
        name = str.strip(new_values['data']['name'])
1059
1060
        cnx = mysql.connector.connect(**config.myems_system_db)
1061
        cursor = cnx.cursor()
1062
1063
        cursor.execute(" SELECT name "
1064
                       " FROM tbl_energy_flow_diagrams "
1065
                       " WHERE id = %s ", (id_,))
1066
        if cursor.fetchone() is None:
1067
            cursor.close()
1068
            cnx.close()
1069
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1070
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1071
1072
        cursor.execute(" SELECT name "
1073
                       " FROM tbl_energy_flow_diagrams_nodes "
1074
                       " WHERE name = %s AND energy_flow_diagram_id = %s ", (name, id_))
1075
        if cursor.fetchone() is not None:
1076
            cursor.close()
1077
            cnx.close()
1078
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1079
                                   description='API.ENERGY_FLOW_DIAGRAM_NAME_IS_ALREADY_IN_USE')
1080
1081
        add_values = (" INSERT INTO tbl_energy_flow_diagrams_nodes "
1082
                      "    (energy_flow_diagram_id, name) "
1083
                      " VALUES (%s, %s) ")
1084
        cursor.execute(add_values, (id_,
1085
                                    name))
1086
        new_id = cursor.lastrowid
1087
        cnx.commit()
1088
        cursor.close()
1089
        cnx.close()
1090
1091
        resp.status = falcon.HTTP_201
1092
        resp.location = '/energyflowdiagrams/' + str(id_) + 'nodes/' + str(new_id)
1093
1094
1095
class EnergyFlowDiagramNodeItem:
1096
    def __init__(self):
1097
        """"Initializes EnergyFlowDiagramNodeItem"""
1098
        pass
1099
1100
    @staticmethod
1101
    def on_options(req, resp, id_, nid):
1102
        _ = req
1103
        resp.status = falcon.HTTP_200
1104
        _ = id_
1105
1106
    @staticmethod
1107
    def on_get(req, resp, id_, nid):
1108
        access_control(req)
1109
        if not id_.isdigit() or int(id_) <= 0:
1110
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1111
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1112
1113
        if not nid.isdigit() or int(nid) <= 0:
1114
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1115
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NODE_ID')
1116
1117
        cnx = mysql.connector.connect(**config.myems_system_db)
1118
        cursor = cnx.cursor()
1119
1120
        query = (" SELECT id, name "
1121
                 " FROM tbl_energy_flow_diagrams_nodes "
1122
                 " WHERE energy_flow_diagram_id = %s AND id = %s ")
1123
        cursor.execute(query, (id_, nid))
1124
        row = cursor.fetchone()
1125
        cursor.close()
1126
        cnx.close()
1127
1128
        if row is None:
1129
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1130
                                   description='API.ENERGY_FLOW_DIAGRAM_NODE_NOT_FOUND_OR_NOT_MATCH')
1131
        else:
1132
            meta_result = {"id": row[0],
1133
                           "name": row[1]}
1134
1135
        resp.text = json.dumps(meta_result)
1136
1137
    @staticmethod
1138
    @user_logger
1139
    def on_delete(req, resp, id_, nid):
1140
        admin_control(req)
1141
        if not id_.isdigit() or int(id_) <= 0:
1142
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1143
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1144
1145
        if not nid.isdigit() or int(nid) <= 0:
1146
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1147
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NODE_ID')
1148
1149
        cnx = mysql.connector.connect(**config.myems_system_db)
1150
        cursor = cnx.cursor()
1151
1152
        cursor.execute(" SELECT name "
1153
                       " FROM tbl_energy_flow_diagrams "
1154
                       " WHERE id = %s ",
1155
                       (id_,))
1156
        row = cursor.fetchone()
1157
        if row is None:
1158
            cursor.close()
1159
            cnx.close()
1160
            raise falcon.HTTPError(status=falcon.HTTP_400,
1161
                                   title='API.NOT_FOUND',
1162
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1163
1164
        cursor.execute(" SELECT name "
1165
                       " FROM tbl_energy_flow_diagrams_nodes "
1166
                       " WHERE energy_flow_diagram_id = %s AND id = %s ",
1167
                       (id_, nid,))
1168
        row = cursor.fetchone()
1169
        if row is None:
1170
            cursor.close()
1171
            cnx.close()
1172
            raise falcon.HTTPError(status=falcon.HTTP_400,
1173
                                   title='API.NOT_FOUND',
1174
                                   description='API.ENERGY_FLOW_DIAGRAM_NODE_NOT_FOUND_OR_NOT_MATCH')
1175
1176
        cursor.execute(" DELETE FROM tbl_energy_flow_diagrams_nodes "
1177
                       " WHERE id = %s ", (nid, ))
1178
        cnx.commit()
1179
1180
        cursor.close()
1181
        cnx.close()
1182
1183
        resp.status = falcon.HTTP_204
1184
1185
    @staticmethod
1186
    @user_logger
1187
    def on_put(req, resp, id_, nid):
1188
        """Handles PUT requests"""
1189
        admin_control(req)
1190
        if not id_.isdigit() or int(id_) <= 0:
1191
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1192
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1193
1194
        if not nid.isdigit() or int(nid) <= 0:
1195
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1196
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NODE_ID')
1197
1198
        try:
1199
            raw_json = req.stream.read().decode('utf-8')
1200
        except Exception as ex:
1201
            print(str(ex))
1202
            raise falcon.HTTPError(status=falcon.HTTP_400,
1203
                                   title='API.BAD_REQUEST',
1204
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1205
1206
        new_values = json.loads(raw_json)
1207
1208
        if 'name' not in new_values['data'].keys() or \
1209
                not isinstance(new_values['data']['name'], str) or \
1210
                len(str.strip(new_values['data']['name'])) == 0:
1211
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1212
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NODE_NAME')
1213
        name = str.strip(new_values['data']['name'])
1214
1215
        cnx = mysql.connector.connect(**config.myems_system_db)
1216
        cursor = cnx.cursor()
1217
1218
        cursor.execute(" SELECT name "
1219
                       " FROM tbl_energy_flow_diagrams "
1220
                       " WHERE id = %s ", (id_,))
1221
        if cursor.fetchone() is None:
1222
            cursor.close()
1223
            cnx.close()
1224
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1225
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1226
1227
        cursor.execute(" SELECT name "
1228
                       " FROM tbl_energy_flow_diagrams_nodes "
1229
                       " WHERE energy_flow_diagram_id = %s AND id = %s ",
1230
                       (id_, nid,))
1231
        row = cursor.fetchone()
1232
        if row is None:
1233
            cursor.close()
1234
            cnx.close()
1235
            raise falcon.HTTPError(status=falcon.HTTP_400,
1236
                                   title='API.NOT_FOUND',
1237
                                   description='API.ENERGY_FLOW_DIAGRAM_NODE_NOT_FOUND_OR_NOT_MATCH')
1238
1239
        cursor.execute(" SELECT name "
1240
                       " FROM tbl_energy_flow_diagrams_nodes "
1241
                       " WHERE name = %s AND energy_flow_diagram_id = %s  AND id != %s ", (name, id_, nid))
1242
        row = cursor.fetchone()
1243
        if row is not None:
1244
            cursor.close()
1245
            cnx.close()
1246
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1247
                                   description='API.ENERGY_FLOW_DIAGRAM_NODE_NAME_IS_ALREADY_IN_USE')
1248
1249
        add_values = (" UPDATE tbl_energy_flow_diagrams_nodes "
1250
                      " SET name = %s "
1251
                      " WHERE id = %s ")
1252
        cursor.execute(add_values, (name,
1253
                                    nid))
1254
        cnx.commit()
1255
1256
        cursor.close()
1257
        cnx.close()
1258
1259
        resp.status = falcon.HTTP_200
1260
1261
1262
class EnergyFlowDiagramExport:
1263
    def __init__(self):
1264
        """"Initializes EnergyFlowDiagramExport"""
1265
        pass
1266
1267
    @staticmethod
1268
    def on_options(req, resp, id_):
1269
        _ = req
1270
        resp.status = falcon.HTTP_200
1271
        _ = id_
1272
1273 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1274
    def on_get(req, resp, id_):
1275
        if 'API-KEY' not in req.headers or \
1276
                not isinstance(req.headers['API-KEY'], str) or \
1277
                len(str.strip(req.headers['API-KEY'])) == 0:
1278
            access_control(req)
1279
        else:
1280
            api_key_control(req)
1281
        if not id_.isdigit() or int(id_) <= 0:
1282
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1283
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1284
1285
        cnx = mysql.connector.connect(**config.myems_system_db)
1286
        cursor = cnx.cursor()
1287
1288
        query = (" SELECT id, name, uuid "
1289
                 " FROM tbl_meters ")
1290
        cursor.execute(query)
1291
        rows_meters = cursor.fetchall()
1292
1293
        meter_dict = dict()
1294
        if rows_meters is not None and len(rows_meters) > 0:
1295
            for row in rows_meters:
1296
                meter_dict[row[2]] = {"type": 'meter',
1297
                                      "id": row[0],
1298
                                      "name": row[1],
1299
                                      "uuid": row[2]}
1300
1301
        query = (" SELECT id, name, uuid "
1302
                 " FROM tbl_offline_meters ")
1303
        cursor.execute(query)
1304
        rows_offline_meters = cursor.fetchall()
1305
1306
        offline_meter_dict = dict()
1307
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
1308
            for row in rows_offline_meters:
1309
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
1310
                                              "id": row[0],
1311
                                              "name": row[1],
1312
                                              "uuid": row[2]}
1313
1314
        query = (" SELECT id, name, uuid "
1315
                 " FROM tbl_virtual_meters ")
1316
        cursor.execute(query)
1317
        rows_virtual_meters = cursor.fetchall()
1318
1319
        virtual_meter_dict = dict()
1320
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
1321
            for row in rows_virtual_meters:
1322
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
1323
                                              "id": row[0],
1324
                                              "name": row[1],
1325
                                              "uuid": row[2]}
1326
1327
        query = (" SELECT id, energy_flow_diagram_id, name "
1328
                 " FROM tbl_energy_flow_diagrams_nodes")
1329
        cursor.execute(query)
1330
        rows_nodes = cursor.fetchall()
1331
1332
        node_dict = dict()
1333
        node_list_dict = dict()
1334
        if rows_nodes is not None and len(rows_nodes) > 0:
1335
            for row in rows_nodes:
1336
                node_dict[row[0]] = row[2]
1337
                if node_list_dict.get(row[1]) is None:
1338
                    node_list_dict[row[1]] = list()
1339
                node_list_dict[row[1]].append({"id": row[0], "name": row[2]})
1340
1341
        query = (" SELECT id, energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid "
1342
                 " FROM tbl_energy_flow_diagrams_links")
1343
        cursor.execute(query)
1344
        rows_links = cursor.fetchall()
1345
1346
        link_list_dict = dict()
1347
        if rows_links is not None and len(rows_links) > 0:
1348
            for row in rows_links:
1349
                # find meter by uuid
1350
                meter = meter_dict.get(row[4], None)
1351
                if meter is None:
1352
                    meter = virtual_meter_dict.get(row[4], None)
1353
                if meter is None:
1354
                    meter = offline_meter_dict.get(row[4], None)
1355
1356
                if link_list_dict.get(row[1]) is None:
1357
                    link_list_dict[row[1]] = list()
1358
                link_list_dict[row[1]].append({"id": row[0],
1359
                                               "source_node": {
1360
                                                   "id": row[2],
1361
                                                   "name": node_dict.get(row[2])},
1362
                                               "target_node": {
1363
                                                   "id": row[3],
1364
                                                   "name": node_dict.get(row[3])},
1365
                                               "meter": meter})
1366
1367
        query = (" SELECT id, name, uuid "
1368
                 " FROM tbl_energy_flow_diagrams "
1369
                 " WHERE id = %s ")
1370
        cursor.execute(query, (id_,))
1371
        row = cursor.fetchone()
1372
        cursor.close()
1373
        cnx.close()
1374
1375
        if row is None:
1376
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1377
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1378
        else:
1379
            meta_result = {"id": row[0],
1380
                           "name": row[1],
1381
                           "uuid": row[2],
1382
                           "nodes": node_list_dict.get(row[0], None),
1383
                           "links": link_list_dict.get(row[0], None),
1384
                           }
1385
1386
        resp.text = json.dumps(meta_result)
1387
1388
1389
class EnergyFlowDiagramImport:
1390
    def __init__(self):
1391
        """"Initializes EnergyFlowDiagramImport"""
1392
        pass
1393
1394
    @staticmethod
1395
    def on_options(req, resp):
1396
        _ = req
1397
        resp.status = falcon.HTTP_200
1398
1399
    @staticmethod
1400
    @user_logger
1401
    def on_post(req, resp):
1402
        """Handles POST requests"""
1403
        admin_control(req)
1404
        try:
1405
            raw_json = req.stream.read().decode('utf-8')
1406
        except Exception as ex:
1407
            print(str(ex))
1408
            raise falcon.HTTPError(status=falcon.HTTP_400,
1409
                                   title='API.BAD_REQUEST',
1410
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1411
1412
        new_values = json.loads(raw_json)
1413
1414
        if 'name' not in new_values.keys() or \
1415
                not isinstance(new_values['name'], str) or \
1416
                len(str.strip(new_values['name'])) == 0:
1417
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1418
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_NAME')
1419
        name = str.strip(new_values['name'])
1420
1421
        cnx = mysql.connector.connect(**config.myems_system_db)
1422
        cursor = cnx.cursor()
1423
1424
        cursor.execute(" SELECT name "
1425
                       " FROM tbl_energy_flow_diagrams "
1426
                       " WHERE name = %s ", (name,))
1427
        if cursor.fetchone() is not None:
1428
            cursor.close()
1429
            cnx.close()
1430
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1431
                                   description='API.ENERGY_FLOW_DIAGRAM_NAME_IS_ALREADY_IN_USE')
1432
1433
        add_values = (" INSERT INTO tbl_energy_flow_diagrams "
1434
                      "    (name, uuid) "
1435
                      " VALUES (%s, %s) ")
1436
        cursor.execute(add_values, (name,
1437
                                    str(uuid.uuid4())))
1438
        new_id = cursor.lastrowid
1439
        for node in new_values['nodes']:
1440
            if 'name' not in node.keys() or \
1441
                    not isinstance(node['name'], str) or \
1442
                    len(str.strip(node['name'])) == 0:
1443
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1444
                                       description='API.INVALID_ENERGY_FLOW_DIAGRAM_NODE_NAME')
1445
            name = str.strip(node['name'])
1446
1447
            cursor.execute(" SELECT name "
1448
                           " FROM tbl_energy_flow_diagrams "
1449
                           " WHERE id = %s ", (new_id,))
1450
            if cursor.fetchone() is None:
1451
                cursor.close()
1452
                cnx.close()
1453
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1454
                                       description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1455
1456
            cursor.execute(" SELECT name "
1457
                           " FROM tbl_energy_flow_diagrams_nodes "
1458
                           " WHERE name = %s AND energy_flow_diagram_id = %s ", (name, new_id))
1459
            if cursor.fetchone() is not None:
1460
                cursor.close()
1461
                cnx.close()
1462
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1463
                                       description='API.ENERGY_FLOW_DIAGRAM_NAME_IS_ALREADY_IN_USE')
1464
1465
            add_values = (" INSERT INTO tbl_energy_flow_diagrams_nodes "
1466
                          "    (energy_flow_diagram_id, name) "
1467
                          " VALUES (%s, %s) ")
1468
            cursor.execute(add_values, (new_id,
1469
                                        name))
1470
        for link in new_values['links']:
1471
            source_node_id = None
1472
            if 'id' in link['source_node'].keys():
1473
                if link['source_node']['id'] is not None and \
1474
                        link['source_node']['id'] <= 0:
1475
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1476
                                           description='API.INVALID_SOURCE_NODE_ID')
1477
                source_node_id = link['source_node']['id']
1478
1479
            target_node_id = None
1480
            if 'id' in link['target_node'].keys():
1481
                if link['target_node']['id'] is not None and \
1482
                        link['target_node']['id'] <= 0:
1483
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1484
                                           description='API.INVALID_TARGET_NODE_ID')
1485
                target_node_id = link['target_node']['id']
1486
1487
            meter_uuid = None
1488
            if 'uuid' in link['meter'].keys():
1489
                if link['meter']['uuid'] is not None and \
1490
                        isinstance(link['meter']['uuid'], str) and \
1491
                        len(str.strip(link['meter']['uuid'])) > 0:
1492
                    meter_uuid = str.strip(link['meter']['uuid'])
1493
1494
            cursor.execute(" SELECT name "
1495
                           " FROM tbl_energy_flow_diagrams "
1496
                           " WHERE id = %s ", (new_id,))
1497
            if cursor.fetchone() is None:
1498
                cursor.close()
1499
                cnx.close()
1500
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1501
                                       description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1502
1503
            cursor.execute(" SELECT id "
1504
                           " FROM tbl_energy_flow_diagrams_links "
1505
                           " WHERE energy_flow_diagram_id = %s AND "
1506
                           "       source_node_id = %s AND target_node_id = %s ",
1507
                           (new_id, source_node_id, target_node_id,))
1508
            row = cursor.fetchone()
1509
            if row is not None:
1510
                cursor.close()
1511
                cnx.close()
1512
                raise falcon.HTTPError(status=falcon.HTTP_400,
1513
                                       title='API.NOT_FOUND',
1514
                                       description='API.ENERGY_FLOW_DIAGRAM_LINK_IS_ALREADY_IN_USE')
1515
1516
            query = (" SELECT id, name "
1517
                     " FROM tbl_energy_flow_diagrams_nodes "
1518
                     " WHERE id = %s ")
1519
            cursor.execute(query, (source_node_id,))
1520
            if cursor.fetchone() is None:
1521
                cursor.close()
1522
                cnx.close()
1523
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1524
                                       description='API.SOURCE_NODE_NOT_FOUND')
1525
1526
            query = (" SELECT id, name "
1527
                     " FROM tbl_energy_flow_diagrams_nodes "
1528
                     " WHERE id = %s ")
1529
            cursor.execute(query, (target_node_id,))
1530
            if cursor.fetchone() is None:
1531
                cursor.close()
1532
                cnx.close()
1533
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1534
                                       description='API.TARGET_NODE_NOT_FOUND')
1535
1536
            query = (" SELECT id, name, uuid "
1537
                     " FROM tbl_meters ")
1538
            cursor.execute(query)
1539
            rows_meters = cursor.fetchall()
1540
1541
            meter_dict = dict()
1542
            if rows_meters is not None and len(rows_meters) > 0:
1543
                for row in rows_meters:
1544
                    meter_dict[row[2]] = {"type": 'meter',
1545
                                          "id": row[0],
1546
                                          "name": row[1],
1547
                                          "uuid": row[2]}
1548
1549
            query = (" SELECT id, name, uuid "
1550
                     " FROM tbl_offline_meters ")
1551
            cursor.execute(query)
1552
            rows_offline_meters = cursor.fetchall()
1553
1554
            offline_meter_dict = dict()
1555
            if rows_offline_meters is not None and len(rows_offline_meters) > 0:
1556
                for row in rows_offline_meters:
1557
                    offline_meter_dict[row[2]] = {"type": 'offline_meter',
1558
                                                  "id": row[0],
1559
                                                  "name": row[1],
1560
                                                  "uuid": row[2]}
1561
1562
            query = (" SELECT id, name, uuid "
1563
                     " FROM tbl_virtual_meters ")
1564
            cursor.execute(query)
1565
            rows_virtual_meters = cursor.fetchall()
1566
1567
            virtual_meter_dict = dict()
1568
            if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
1569
                for row in rows_virtual_meters:
1570
                    virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
1571
                                                  "id": row[0],
1572
                                                  "name": row[1],
1573
                                                  "uuid": row[2]}
1574
1575
            # validate meter uuid
1576
            if meter_dict.get(meter_uuid) is None and \
1577
                    virtual_meter_dict.get(meter_uuid) is None and \
1578
                    offline_meter_dict.get(meter_uuid) is None:
1579
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1580
                                       description='API.INVALID_METER_UUID')
1581
1582
            add_values = (" INSERT INTO tbl_energy_flow_diagrams_links "
1583
                          "    (energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid) "
1584
                          " VALUES (%s, %s, %s, %s) ")
1585
            cursor.execute(add_values, (new_id,
1586
                                        source_node_id,
1587
                                        target_node_id,
1588
                                        meter_uuid))
1589
        cnx.commit()
1590
        cursor.close()
1591
        cnx.close()
1592
1593
        resp.status = falcon.HTTP_201
1594
        resp.location = '/energyflowdiagrams/' + str(new_id)
1595
1596
1597
class EnergyFlowDiagramClone:
1598
    def __init__(self):
1599
        """"Initializes EnergyFlowDiagramClone"""
1600
        pass
1601
1602
    @staticmethod
1603
    def on_options(req, resp, id_):
1604
        _ = req
1605
        resp.status = falcon.HTTP_200
1606
        _ = id_
1607
1608
    @staticmethod
1609
    @user_logger
1610
    def on_post(req, resp, id_):
1611
        admin_control(req)
1612
        if not id_.isdigit() or int(id_) <= 0:
1613
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1614
                                   description='API.INVALID_ENERGY_FLOW_DIAGRAM_ID')
1615
1616
        cnx = mysql.connector.connect(**config.myems_system_db)
1617
        cursor = cnx.cursor()
1618
1619
        query = (" SELECT id, name, uuid "
1620
                 " FROM tbl_meters ")
1621
        cursor.execute(query)
1622
        rows_meters = cursor.fetchall()
1623
1624
        meter_dict = dict()
1625
        if rows_meters is not None and len(rows_meters) > 0:
1626
            for row in rows_meters:
1627
                meter_dict[row[2]] = {"type": 'meter',
1628
                                      "id": row[0],
1629
                                      "name": row[1],
1630
                                      "uuid": row[2]}
1631
1632
        query = (" SELECT id, name, uuid "
1633
                 " FROM tbl_offline_meters ")
1634
        cursor.execute(query)
1635
        rows_offline_meters = cursor.fetchall()
1636
1637
        offline_meter_dict = dict()
1638
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
1639
            for row in rows_offline_meters:
1640
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
1641
                                              "id": row[0],
1642
                                              "name": row[1],
1643
                                              "uuid": row[2]}
1644
1645
        query = (" SELECT id, name, uuid "
1646
                 " FROM tbl_virtual_meters ")
1647
        cursor.execute(query)
1648
        rows_virtual_meters = cursor.fetchall()
1649
1650
        virtual_meter_dict = dict()
1651
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
1652
            for row in rows_virtual_meters:
1653
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
1654
                                              "id": row[0],
1655
                                              "name": row[1],
1656
                                              "uuid": row[2]}
1657
1658
        query = (" SELECT id, energy_flow_diagram_id, name "
1659
                 " FROM tbl_energy_flow_diagrams_nodes")
1660
        cursor.execute(query)
1661
        rows_nodes = cursor.fetchall()
1662
1663
        node_dict = dict()
1664
        node_list_dict = dict()
1665
        if rows_nodes is not None and len(rows_nodes) > 0:
1666
            for row in rows_nodes:
1667
                node_dict[row[0]] = row[2]
1668
                if node_list_dict.get(row[1]) is None:
1669
                    node_list_dict[row[1]] = list()
1670
                node_list_dict[row[1]].append({"id": row[0], "name": row[2]})
1671
1672
        query = (" SELECT id, energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid "
1673
                 " FROM tbl_energy_flow_diagrams_links")
1674
        cursor.execute(query)
1675
        rows_links = cursor.fetchall()
1676
1677
        link_list_dict = dict()
1678
        if rows_links is not None and len(rows_links) > 0:
1679
            for row in rows_links:
1680
                # find meter by uuid
1681
                meter = meter_dict.get(row[4], None)
1682
                if meter is None:
1683
                    meter = virtual_meter_dict.get(row[4], None)
1684
                if meter is None:
1685
                    meter = offline_meter_dict.get(row[4], None)
1686
1687
                if link_list_dict.get(row[1]) is None:
1688
                    link_list_dict[row[1]] = list()
1689
                link_list_dict[row[1]].append({"id": row[0],
1690
                                               "source_node": {
1691
                                                   "id": row[2],
1692
                                                   "name": node_dict.get(row[2])},
1693
                                               "target_node": {
1694
                                                   "id": row[3],
1695
                                                   "name": node_dict.get(row[3])},
1696
                                               "meter": meter})
1697
1698
        query = (" SELECT id, name, uuid "
1699
                 " FROM tbl_energy_flow_diagrams "
1700
                 " WHERE id = %s ")
1701
        cursor.execute(query, (id_,))
1702
        row = cursor.fetchone()
1703
1704
        if row is None:
1705
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1706
                                   description='API.ENERGY_FLOW_DIAGRAM_NOT_FOUND')
1707
        else:
1708
            meta_result = {"id": row[0],
1709
                           "name": row[1],
1710
                           "uuid": row[2],
1711
                           "nodes": node_list_dict.get(row[0], None),
1712
                           "links": link_list_dict.get(row[0], None),
1713
                           }
1714
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
1715
            if config.utc_offset[0] == '-':
1716
                timezone_offset = -timezone_offset
1717
            new_name = (str.strip(meta_result['name']) +
1718
                        (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
1719
            add_values = (" INSERT INTO tbl_energy_flow_diagrams "
1720
                          "    (name, uuid) "
1721
                          " VALUES (%s, %s) ")
1722
            cursor.execute(add_values, (new_name,
1723
                                        str(uuid.uuid4())))
1724
            new_id = cursor.lastrowid
1725
            if meta_result['nodes'] is not None and len(meta_result['nodes']) > 0:
1726
                for node in meta_result['nodes']:
1727
                    add_values = (" INSERT INTO tbl_energy_flow_diagrams_nodes "
1728
                                  "    (energy_flow_diagram_id, name) "
1729
                                  " VALUES (%s, %s) ")
1730
                    cursor.execute(add_values, (new_id,
1731
                                                node['name']))
1732
            if meta_result['links'] is not None and len(meta_result['links']) > 0:
1733
                for link in meta_result['links']:
1734
                    if link['meter'] is None:
1735
                        continue
1736
                    add_values = (" INSERT INTO tbl_energy_flow_diagrams_links "
1737
                                  "    (energy_flow_diagram_id, source_node_id, target_node_id, meter_uuid) "
1738
                                  " VALUES (%s, %s, %s, %s) ")
1739
                    cursor.execute(add_values, (new_id,
1740
                                                link['source_node']['id'],
1741
                                                link['target_node']['id'],
1742
                                                link['meter']['uuid']))
1743
            cnx.commit()
1744
            cursor.close()
1745
            cnx.close()
1746
1747
            resp.status = falcon.HTTP_201
1748
            resp.location = '/energyflowdiagrams/' + str(new_id)
1749
1750