CombinedEquipmentImport.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 1
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 CombinedEquipmentCollection:
11
    """
12
    Combined Equipment Collection Resource
13
14
    This class handles CRUD operations for combined equipment collection.
15
    It provides endpoints for listing all combined equipments and creating new ones.
16
    Combined equipments represent groups of related equipment that work together
17
    in the energy management system, such as HVAC systems, lighting groups, etc.
18
    """
19
20
    def __init__(self):
21
        pass
22
23
    @staticmethod
24
    def on_options(req, resp):
25
        """
26
        Handle OPTIONS request for CORS preflight
27
28
        Args:
29
            req: Falcon request object
30
            resp: Falcon response object
31
        """
32
        _ = req
33
        resp.status = falcon.HTTP_200
34
35 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
36
    def on_get(req, resp):
37
        """
38
        Handle GET requests to retrieve all combined equipments
39
40
        Returns a list of all combined equipments with their metadata including:
41
        - Equipment ID, name, and UUID
42
        - Input/output counting status
43
        - Cost center information
44
        - SVG diagram reference
45
        - Camera URL for monitoring
46
        - Description and QR code
47
48
        Args:
49
            req: Falcon request object
50
            resp: Falcon response object
51
        """
52
        # Check authentication method (API key or session)
53
        if 'API-KEY' not in req.headers or \
54
                not isinstance(req.headers['API-KEY'], str) or \
55
                len(str.strip(req.headers['API-KEY'])) == 0:
56
            access_control(req)
57
        else:
58
            api_key_control(req)
59
60
        search_query = req.get_param('q', default=None)
61
        if search_query is not None:
62
            search_query = search_query.strip()
63
        else:
64
            search_query = ''
65
66
        # Connect to database and retrieve cost centers
67
        cnx = mysql.connector.connect(**config.myems_system_db)
68
        cursor = cnx.cursor()
69
70
        # Query to retrieve all cost centers for reference
71
        query = (" SELECT id, name, uuid "
72
                 " FROM tbl_cost_centers ")
73
        cursor.execute(query)
74
        rows_cost_centers = cursor.fetchall()
75
76
        # Build cost center dictionary for quick lookup
77
        cost_center_dict = dict()
78
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
79
            for row in rows_cost_centers:
80
                cost_center_dict[row[0]] = {"id": row[0],
81
                                            "name": row[1],
82
                                            "uuid": row[2]}
83
84
        # Query to retrieve all SVG diagrams for reference
85
        query = (" SELECT id, name, uuid "
86
                 " FROM tbl_svgs ")
87
        cursor.execute(query)
88
        rows_svgs = cursor.fetchall()
89
90
        # Build SVG dictionary for quick lookup
91
        svg_dict = dict()
92
        if rows_svgs is not None and len(rows_svgs) > 0:
93
            for row in rows_svgs:
94
                svg_dict[row[0]] = {"id": row[0],
95
                                    "name": row[1],
96
                                    "uuid": row[2]}
97
98
        # Query to retrieve all combined equipments
99
        query = (" SELECT id, name, uuid, "
100
                 "        is_input_counted, is_output_counted, "
101
                 "        cost_center_id, svg_id, camera_url, description "
102
                 " FROM tbl_combined_equipments ")
103
        params = []
104
        if search_query:
105
            query += " WHERE name LIKE %s OR   description LIKE %s "
106
            params = [f'%{search_query}%', f'%{search_query}%']
107
        query += " ORDER BY id "
108
        cursor.execute(query, params)
109
        rows_combined_equipments = cursor.fetchall()
110
111
        # Build result list with all combined equipment data
112
        result = list()
113
        if rows_combined_equipments is not None and len(rows_combined_equipments) > 0:
114
            for row in rows_combined_equipments:
115
                meta_result = {"id": row[0],
116
                               "name": row[1],
117
                               "uuid": row[2],
118
                               "is_input_counted": bool(row[3]),
119
                               "is_output_counted": bool(row[4]),
120
                               "cost_center": cost_center_dict.get(row[5], None),
121
                               "svg": svg_dict.get(row[6], None),
122
                               "camera_url": row[7],
123
                               "description": row[8],
124
                               "qrcode": 'combinedequipment:' + row[2]}
125
                result.append(meta_result)
126
127
        cursor.close()
128
        cnx.close()
129
        resp.text = json.dumps(result)
130
131 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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 UnicodeDecodeError as ex:
139
            print("Failed to decode request")
140
            raise falcon.HTTPError(status=falcon.HTTP_400,
141
                                   title='API.BAD_REQUEST',
142
                                   description='API.INVALID_ENCODING')
143
        except Exception as ex:
144
            print("Unexpected error reading request stream")
145
            raise falcon.HTTPError(status=falcon.HTTP_400,
146
                                   title='API.BAD_REQUEST',
147
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
148
149
        new_values = json.loads(raw_json)
150
151
        if 'name' not in new_values['data'].keys() or \
152
                not isinstance(new_values['data']['name'], str) or \
153
                len(str.strip(new_values['data']['name'])) == 0:
154
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
155
                                   description='API.INVALID_COMBINED_EQUIPMENT_NAME')
156
        name = str.strip(new_values['data']['name'])
157
158
        if 'is_input_counted' not in new_values['data'].keys() or \
159
                not isinstance(new_values['data']['is_input_counted'], bool):
160
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
161
                                   description='API.INVALID_IS_INPUT_COUNTED_VALUE')
162
        is_input_counted = new_values['data']['is_input_counted']
163
164
        if 'is_output_counted' not in new_values['data'].keys() or \
165
                not isinstance(new_values['data']['is_output_counted'], bool):
166
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
167
                                   description='API.INVALID_IS_OUTPUT_COUNTED_VALUE')
168
        is_output_counted = new_values['data']['is_output_counted']
169
170
        if 'cost_center_id' not in new_values['data'].keys() or \
171
                not isinstance(new_values['data']['cost_center_id'], int) or \
172
                new_values['data']['cost_center_id'] <= 0:
173
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
174
                                   description='API.INVALID_COST_CENTER_ID')
175
        cost_center_id = new_values['data']['cost_center_id']
176
177
        if 'svg_id' in new_values['data'].keys() and \
178
                isinstance(new_values['data']['svg_id'], int) and \
179
                new_values['data']['svg_id'] > 0:
180
            svg_id = new_values['data']['svg_id']
181
        else:
182
            svg_id = None
183
184
        if 'camera_url' in new_values['data'].keys() and \
185
                new_values['data']['camera_url'] is not None and \
186
                len(str(new_values['data']['camera_url'])) > 0:
187
            camera_url = str.strip(new_values['data']['camera_url'])
188
        else:
189
            camera_url = None
190
191
        if 'description' in new_values['data'].keys() and \
192
                new_values['data']['description'] is not None and \
193
                len(str(new_values['data']['description'])) > 0:
194
            description = str.strip(new_values['data']['description'])
195
        else:
196
            description = None
197
198
        cnx = mysql.connector.connect(**config.myems_system_db)
199
        cursor = cnx.cursor()
200
201
        cursor.execute(" SELECT name "
202
                       " FROM tbl_combined_equipments "
203
                       " WHERE name = %s ", (name,))
204
        if cursor.fetchone() is not None:
205
            cursor.close()
206
            cnx.close()
207
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
208
                                   description='API.COMBINED_EQUIPMENT_NAME_IS_ALREADY_IN_USE')
209
210
        if cost_center_id is not None:
211
            cursor.execute(" SELECT name "
212
                           " FROM tbl_cost_centers "
213
                           " WHERE id = %s ",
214
                           (new_values['data']['cost_center_id'],))
215
            row = cursor.fetchone()
216
            if row is None:
217
                cursor.close()
218
                cnx.close()
219
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
220
                                       description='API.COST_CENTER_NOT_FOUND')
221
222
        if svg_id is not None:
223
            cursor.execute(" SELECT name "
224
                           " FROM tbl_svgs "
225
                           " WHERE id = %s ",
226
                           (svg_id,))
227
            row = cursor.fetchone()
228
            if row is None:
229
                cursor.close()
230
                cnx.close()
231
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
232
                                       description='API.SVG_NOT_FOUND')
233
234
        add_values = (" INSERT INTO tbl_combined_equipments "
235
                      "    (name, uuid, is_input_counted, is_output_counted, "
236
                      "     cost_center_id, svg_id, camera_url, description) "
237
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
238
        cursor.execute(add_values, (name,
239
                                    str(uuid.uuid4()),
240
                                    is_input_counted,
241
                                    is_output_counted,
242
                                    cost_center_id,
243
                                    svg_id,
244
                                    camera_url,
245
                                    description))
246
        new_id = cursor.lastrowid
247
        cnx.commit()
248
        cursor.close()
249
        cnx.close()
250
251
        resp.status = falcon.HTTP_201
252
        resp.location = '/combinedequipments/' + str(new_id)
253
254
255
class CombinedEquipmentItem:
256
    def __init__(self):
257
        pass
258
259
    @staticmethod
260
    def on_options(req, resp, id_):
261
        _ = req
262
        resp.status = falcon.HTTP_200
263
        _ = id_
264
265 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
266
    def on_get(req, resp, id_):
267
        if 'API-KEY' not in req.headers or \
268
                not isinstance(req.headers['API-KEY'], str) or \
269
                len(str.strip(req.headers['API-KEY'])) == 0:
270
            access_control(req)
271
        else:
272
            api_key_control(req)
273
        if not id_.isdigit() or int(id_) <= 0:
274
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
275
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
276
277
        cnx = mysql.connector.connect(**config.myems_system_db)
278
        cursor = cnx.cursor()
279
280
        query = (" SELECT id, name, uuid "
281
                 " FROM tbl_cost_centers ")
282
        cursor.execute(query)
283
        rows_cost_centers = cursor.fetchall()
284
285
        cost_center_dict = dict()
286
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
287
            for row in rows_cost_centers:
288
                cost_center_dict[row[0]] = {"id": row[0],
289
                                            "name": row[1],
290
                                            "uuid": row[2]}
291
292
        svg_dict = dict()
293
        query = (" SELECT id, name, uuid "
294
                 " FROM tbl_svgs ")
295
        cursor.execute(query)
296
        rows_svgs = cursor.fetchall()
297
        if rows_svgs is not None and len(rows_svgs) > 0:
298
            for row in rows_svgs:
299
                svg_dict[row[0]] = {"id": row[0],
300
                                    "name": row[1],
301
                                    "uuid": row[2]}
302
303
        query = (" SELECT id, name, uuid, "
304
                 "        is_input_counted, is_output_counted, "
305
                 "        cost_center_id, svg_id, camera_url, description "
306
                 " FROM tbl_combined_equipments "
307
                 " WHERE id = %s ")
308
        cursor.execute(query, (id_,))
309
        row = cursor.fetchone()
310
        cursor.close()
311
        cnx.close()
312
313
        if row is None:
314
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
315
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
316
        else:
317
            meta_result = {"id": row[0],
318
                           "name": row[1],
319
                           "uuid": row[2],
320
                           "is_input_counted": bool(row[3]),
321
                           "is_output_counted": bool(row[4]),
322
                           "cost_center": cost_center_dict.get(row[5], None),
323
                           "svg": svg_dict.get(row[6], None),
324
                           "camera_url": row[7],
325
                           "description": row[8],
326
                           "qrcode": 'combinedequipment:' + row[2]}
327
328
        resp.text = json.dumps(meta_result)
329
330
    @staticmethod
331
    @user_logger
332
    def on_delete(req, resp, id_):
333
        admin_control(req)
334
        if not id_.isdigit() or int(id_) <= 0:
335
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
336
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
337
338
        cnx = mysql.connector.connect(**config.myems_system_db)
339
        cursor = cnx.cursor()
340
341
        # check relation with space
342
        cursor.execute(" SELECT space_id "
343
                       " FROM tbl_spaces_combined_equipments "
344
                       " WHERE combined_equipment_id = %s ",
345
                       (id_,))
346
        rows_combined_equipments = cursor.fetchall()
347
        if rows_combined_equipments is not None and len(rows_combined_equipments) > 0:
348
            cursor.close()
349
            cnx.close()
350
            raise falcon.HTTPError(status=falcon.HTTP_400,
351
                                   title='API.BAD_REQUEST',
352
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
353
354
        # delete relation with commands
355
        cursor.execute(" DELETE FROM tbl_combined_equipments_commands WHERE combined_equipment_id = %s ", (id_,))
356
357
        # delete relation with equipments
358
        cursor.execute(" DELETE FROM tbl_combined_equipments_equipments WHERE combined_equipment_id = %s ", (id_,))
359
360
        # delete relation with meters
361
        cursor.execute(" DELETE FROM tbl_combined_equipments_meters WHERE combined_equipment_id = %s ", (id_,))
362
363
        # delete relation with offline meters
364
        cursor.execute(" DELETE FROM tbl_combined_equipments_offline_meters WHERE combined_equipment_id = %s ", (id_,))
365
366
        # delete all associated parameters
367
        cursor.execute(" DELETE FROM tbl_combined_equipments_parameters WHERE combined_equipment_id = %s ", (id_,))
368
369
        # delete relation with virtual meter
370
        cursor.execute(" DELETE FROM tbl_combined_equipments_virtual_meters WHERE combined_equipment_id = %s ", (id_,))
371
        cnx.commit()
372
373
        cursor.execute(" DELETE FROM tbl_combined_equipments WHERE id = %s ", (id_,))
374
        cnx.commit()
375
376
        cursor.close()
377
        cnx.close()
378
379
        resp.status = falcon.HTTP_204
380
381 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
382
    @user_logger
383
    def on_put(req, resp, id_):
384
        """Handles PUT requests"""
385
        admin_control(req)
386
        if not id_.isdigit() or int(id_) <= 0:
387
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
388
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
389
        try:
390
            raw_json = req.stream.read().decode('utf-8')
391
        except UnicodeDecodeError as ex:
392
            print("Failed to decode request")
393
            raise falcon.HTTPError(status=falcon.HTTP_400,
394
                                   title='API.BAD_REQUEST',
395
                                   description='API.INVALID_ENCODING')
396
        except Exception as ex:
397
            print("Unexpected error reading request stream")
398
            raise falcon.HTTPError(status=falcon.HTTP_400,
399
                                   title='API.BAD_REQUEST',
400
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
401
402
        new_values = json.loads(raw_json)
403
404
        if 'name' not in new_values['data'].keys() or \
405
                not isinstance(new_values['data']['name'], str) or \
406
                len(str.strip(new_values['data']['name'])) == 0:
407
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
408
                                   description='API.INVALID_COMBINED_EQUIPMENT_NAME')
409
        name = str.strip(new_values['data']['name'])
410
411
        if 'is_input_counted' not in new_values['data'].keys() or \
412
                not isinstance(new_values['data']['is_input_counted'], bool):
413
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
414
                                   description='API.INVALID_IS_INPUT_COUNTED_VALUE')
415
        is_input_counted = new_values['data']['is_input_counted']
416
417
        if 'is_output_counted' not in new_values['data'].keys() or \
418
                not isinstance(new_values['data']['is_output_counted'], bool):
419
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
420
                                   description='API.INVALID_IS_OUTPUT_COUNTED_VALUE')
421
        is_output_counted = new_values['data']['is_output_counted']
422
423
        if 'cost_center_id' not in new_values['data'].keys() or \
424
                not isinstance(new_values['data']['cost_center_id'], int) or \
425
                new_values['data']['cost_center_id'] <= 0:
426
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
427
                                   description='API.INVALID_COST_CENTER_ID')
428
        cost_center_id = new_values['data']['cost_center_id']
429
430
        if 'svg_id' in new_values['data'].keys() and \
431
                isinstance(new_values['data']['svg_id'], int) and \
432
                new_values['data']['svg_id'] > 0:
433
            svg_id = new_values['data']['svg_id']
434
        else:
435
            svg_id = None
436
437
        if 'camera_url' in new_values['data'].keys() and \
438
                new_values['data']['camera_url'] is not None and \
439
                len(str(new_values['data']['camera_url'])) > 0:
440
            camera_url = str.strip(new_values['data']['camera_url'])
441
        else:
442
            camera_url = None
443
444
        if 'description' in new_values['data'].keys() and \
445
                new_values['data']['description'] is not None and \
446
                len(str(new_values['data']['description'])) > 0:
447
            description = str.strip(new_values['data']['description'])
448
        else:
449
            description = None
450
451
        cnx = mysql.connector.connect(**config.myems_system_db)
452
        cursor = cnx.cursor()
453
454
        cursor.execute(" SELECT name "
455
                       " FROM tbl_combined_equipments "
456
                       " WHERE id = %s ", (id_,))
457
        if cursor.fetchone() is None:
458
            cursor.close()
459
            cnx.close()
460
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
461
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
462
463
        cursor.execute(" SELECT name "
464
                       " FROM tbl_combined_equipments "
465
                       " WHERE name = %s AND id != %s ", (name, id_))
466
        if cursor.fetchone() is not None:
467
            cursor.close()
468
            cnx.close()
469
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
470
                                   description='API.COMBINED_EQUIPMENT_NAME_IS_ALREADY_IN_USE')
471
472
        cursor.execute(" SELECT name "
473
                       " FROM tbl_cost_centers "
474
                       " WHERE id = %s ",
475
                       (new_values['data']['cost_center_id'],))
476
        row = cursor.fetchone()
477
        if row is None:
478
            cursor.close()
479
            cnx.close()
480
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
481
                                   description='API.COST_CENTER_NOT_FOUND')
482
483
        if svg_id is not None:
484
            cursor.execute(" SELECT name "
485
                           " FROM tbl_svgs "
486
                           " WHERE id = %s ",
487
                           (new_values['data']['svg_id'],))
488
            row = cursor.fetchone()
489
            if row is None:
490
                cursor.close()
491
                cnx.close()
492
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
493
                                       description='API.SVG_NOT_FOUND')
494
495
        update_row = (" UPDATE tbl_combined_equipments "
496
                      " SET name = %s, is_input_counted = %s, is_output_counted = %s, "
497
                      "     cost_center_id = %s, svg_id = %s, camera_url = %s, description = %s "
498
                      " WHERE id = %s ")
499
        cursor.execute(update_row, (name,
500
                                    is_input_counted,
501
                                    is_output_counted,
502
                                    cost_center_id,
503
                                    svg_id,
504
                                    camera_url,
505
                                    description,
506
                                    id_))
507
        cnx.commit()
508
509
        cursor.close()
510
        cnx.close()
511
512
        resp.status = falcon.HTTP_200
513
514
    # Clone a Combined Equipment
515 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
516
    @user_logger
517
    def on_post(req, resp, id_):
518
        """Handles POST requests"""
519
        admin_control(req)
520
        if not id_.isdigit() or int(id_) <= 0:
521
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
522
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
523
524
        cnx = mysql.connector.connect(**config.myems_system_db)
525
        cursor = cnx.cursor()
526
        cursor.execute(" SELECT name "
527
                       " FROM tbl_combined_equipments "
528
                       " WHERE id = %s ", (id_,))
529
        if cursor.fetchone() is None:
530
            cursor.close()
531
            cnx.close()
532
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
533
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
534
535
        query = (" SELECT name, is_input_counted, is_output_counted, "
536
                 "        cost_center_id, svg_id, camera_url, description "
537
                 " FROM tbl_combined_equipments "
538
                 " WHERE id = %s ")
539
        cursor.execute(query, (id_,))
540
        row = cursor.fetchone()
541
542
        if row is None:
543
            cursor.close()
544
            cnx.close()
545
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
546
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
547
        else:
548
            add_values = (" INSERT INTO tbl_combined_equipments "
549
                          "    (name, uuid, is_input_counted, is_output_counted, "
550
                          "     cost_center_id, svg_id, camera_url, description) "
551
                          " VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
552
            cursor.execute(add_values, (row[0] + ' Copy',
553
                                        str(uuid.uuid4()),
554
                                        row[1],
555
                                        row[2],
556
                                        row[3],
557
                                        row[4],
558
                                        row[5],
559
                                        row[6]))
560
            new_id = cursor.lastrowid
561
            cnx.commit()
562
563
        # clone relation with meter
564
        cursor.execute(" SELECT meter_id, is_output "
565
                       " FROM tbl_combined_equipments_meters "
566
                       " WHERE combined_equipment_id = %s ",
567
                       (id_,))
568
        rows_meters = cursor.fetchall()
569
        if rows_meters is not None and len(rows_meters) > 0:
570
            add_values = (" INSERT INTO tbl_combined_equipments_meters (combined_equipment_id, meter_id, is_output) "
571
                          " VALUES  ")
572
            for row in rows_meters:
573
                add_values += " (" + str(new_id) + ","
574
                add_values += str(row[0]) + ","
575
                add_values += str(bool(row[1])) + "), "
576
            # trim ", " at the end of string and then execute
577
            cursor.execute(add_values[:-2])
578
            cnx.commit()
579
580
        # clone relation with offline meter
581
        cursor.execute(" SELECT offline_meter_id, is_output "
582
                       " FROM tbl_combined_equipments_offline_meters "
583
                       " WHERE combined_equipment_id = %s ",
584
                       (id_,))
585
        rows_offline_meters = cursor.fetchall()
586
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
587
            add_values = (" INSERT INTO tbl_combined_equipments_offline_meters "
588
                          " (combined_equipment_id, offline_meter_id, is_output) "
589
                          " VALUES  ")
590
            for row in rows_offline_meters:
591
                add_values += " (" + str(new_id) + ","
592
                add_values += "'" + str(row[0]) + "',"
593
                add_values += str(bool(row[1])) + "), "
594
            # trim ", " at the end of string and then execute
595
            cursor.execute(add_values[:-2])
596
            cnx.commit()
597
598
        # clone relation with virtual meter
599
        cursor.execute(" SELECT virtual_meter_id, is_output "
600
                       " FROM tbl_combined_equipments_virtual_meters "
601
                       " WHERE combined_equipment_id = %s ",
602
                       (id_,))
603
        rows_virtual_meters = cursor.fetchall()
604
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
605
            add_values = (" INSERT INTO tbl_combined_equipments_virtual_meters "
606
                          " (combined_equipment_id, virtual_meter_id, is_output) "
607
                          " VALUES  ")
608
            for row in rows_virtual_meters:
609
                add_values += " (" + str(new_id) + ","
610
                add_values += str(row[0]) + ","
611
                add_values += str(bool(row[1])) + "), "
612
            # trim ", " at the end of string and then execute
613
            cursor.execute(add_values[:-2])
614
            cnx.commit()
615
616
        # clone parameters
617
        cursor.execute(" SELECT name, parameter_type, constant, point_id, numerator_meter_uuid, denominator_meter_uuid "
618
                       " FROM tbl_combined_equipments_parameters "
619
                       " WHERE combined_equipment_id = %s ",
620
                       (id_,))
621
        rows_parameters = cursor.fetchall()
622
        if rows_parameters is not None and len(rows_parameters) > 0:
623
            add_values = (" INSERT INTO tbl_combined_equipments_parameters"
624
                          "     (combined_equipment_id, name, parameter_type, constant, point_id, "
625
                          "      numerator_meter_uuid, denominator_meter_uuid) "
626
                          " VALUES  ")
627
            for row in rows_parameters:
628
                add_values += " (" + str(new_id) + ","
629
                add_values += "'" + str(row[0]) + "',"
630
                add_values += "'" + str(row[1]) + "',"
631
                if row[2] is not None:
632
                    add_values += "'" + str(row[2]) + "',"
633
                else:
634
                    add_values += "null, "
635
636
                if row[3] is not None:
637
                    add_values += str(row[2]) + ","
638
                else:
639
                    add_values += "null, "
640
641
                if row[4] is not None:
642
                    add_values += "'" + row[4] + "',"
643
                else:
644
                    add_values += "null, "
645
                if row[5] is not None:
646
                    add_values += "'" + row[5] + "'), "
647
                else:
648
                    add_values += "null), "
649
650
            # trim ", " at the end of string and then execute
651
            cursor.execute(add_values[:-2])
652
            cnx.commit()
653
654
        cursor.close()
655
        cnx.close()
656
        resp.status = falcon.HTTP_201
657
        resp.location = '/combinedequipments/' + str(new_id)
658
659
660 View Code Duplication
class CombinedEquipmentEquipmentCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
661
    def __init__(self):
662
        pass
663
664
    @staticmethod
665
    def on_options(req, resp, id_):
666
        _ = req
667
        resp.status = falcon.HTTP_200
668
        _ = id_
669
670
    @staticmethod
671
    def on_get(req, resp, id_):
672
        if 'API-KEY' not in req.headers or \
673
                not isinstance(req.headers['API-KEY'], str) or \
674
                len(str.strip(req.headers['API-KEY'])) == 0:
675
            access_control(req)
676
        else:
677
            api_key_control(req)
678
        if not id_.isdigit() or int(id_) <= 0:
679
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
680
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
681
682
        cnx = mysql.connector.connect(**config.myems_system_db)
683
        cursor = cnx.cursor()
684
685
        cursor.execute(" SELECT name "
686
                       " FROM tbl_combined_equipments "
687
                       " WHERE id = %s ", (id_,))
688
        if cursor.fetchone() is None:
689
            cursor.close()
690
            cnx.close()
691
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
692
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
693
694
        query = (" SELECT e.id, e.name, e.uuid "
695
                 " FROM tbl_combined_equipments c, tbl_combined_equipments_equipments ce, tbl_equipments e "
696
                 " WHERE ce.combined_equipment_id = c.id AND e.id = ce.equipment_id AND c.id = %s "
697
                 " ORDER BY e.id ")
698
        cursor.execute(query, (id_,))
699
        rows = cursor.fetchall()
700
        cursor.close()
701
        cnx.close()
702
703
        result = list()
704
        if rows is not None and len(rows) > 0:
705
            for row in rows:
706
                meta_result = {"id": row[0], "name": row[1], "uuid": row[2]}
707
                result.append(meta_result)
708
709
        resp.text = json.dumps(result)
710
711
    @staticmethod
712
    @user_logger
713
    def on_post(req, resp, id_):
714
        """Handles POST requests"""
715
        admin_control(req)
716
        try:
717
            raw_json = req.stream.read().decode('utf-8')
718
        except UnicodeDecodeError as ex:
719
            print("Failed to decode request")
720
            raise falcon.HTTPError(status=falcon.HTTP_400,
721
                                   title='API.BAD_REQUEST',
722
                                   description='API.INVALID_ENCODING')
723
        except Exception as ex:
724
            print("Unexpected error reading request stream")
725
            raise falcon.HTTPError(status=falcon.HTTP_400,
726
                                   title='API.BAD_REQUEST',
727
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
728
729
        if not id_.isdigit() or int(id_) <= 0:
730
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
731
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
732
733
        new_values = json.loads(raw_json)
734
735
        if 'equipment_id' not in new_values['data'].keys() or \
736
                not isinstance(new_values['data']['equipment_id'], int) or \
737
                new_values['data']['equipment_id'] <= 0:
738
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
739
                                   description='API.INVALID_EQUIPMENT_ID')
740
        equipment_id = new_values['data']['equipment_id']
741
742
        cnx = mysql.connector.connect(**config.myems_system_db)
743
        cursor = cnx.cursor()
744
745
        cursor.execute(" SELECT name "
746
                       " from tbl_combined_equipments "
747
                       " WHERE id = %s ", (id_,))
748
        if cursor.fetchone() is None:
749
            cursor.close()
750
            cnx.close()
751
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
752
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
753
754
        cursor.execute(" SELECT name "
755
                       " FROM tbl_equipments "
756
                       " WHERE id = %s ", (equipment_id,))
757
        if cursor.fetchone() is None:
758
            cursor.close()
759
            cnx.close()
760
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
761
                                   description='API.EQUIPMENT_NOT_FOUND')
762
763
        query = (" SELECT id "
764
                 " FROM tbl_combined_equipments_equipments "
765
                 " WHERE combined_equipment_id = %s AND equipment_id = %s")
766
        cursor.execute(query, (id_, equipment_id,))
767
        if cursor.fetchone() is not None:
768
            cursor.close()
769
            cnx.close()
770
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
771
                                   description='API.COMBINED_EQUIPMENT_EQUIPMENT_RELATION_EXISTS')
772
773
        add_row = (" INSERT INTO tbl_combined_equipments_equipments (combined_equipment_id, equipment_id) "
774
                   " VALUES (%s, %s) ")
775
        cursor.execute(add_row, (id_, equipment_id,))
776
        cnx.commit()
777
        cursor.close()
778
        cnx.close()
779
780
        resp.status = falcon.HTTP_201
781
        resp.location = '/combinedequipments/' + str(id_) + '/equipments/' + str(equipment_id)
782
783
784
class CombinedEquipmentEquipmentItem:
785
    def __init__(self):
786
        pass
787
788
    @staticmethod
789
    def on_options(req, resp, id_, eid):
790
        _ = req
791
        resp.status = falcon.HTTP_200
792
        _ = id_
793
794
    @staticmethod
795
    @user_logger
796
    def on_delete(req, resp, id_, eid):
797
        admin_control(req)
798
        if not id_.isdigit() or int(id_) <= 0:
799
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
800
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
801
802
        if not eid.isdigit() or int(eid) <= 0:
803
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
804
                                   description='API.INVALID_EQUIPMENT_ID')
805
806
        cnx = mysql.connector.connect(**config.myems_system_db)
807
        cursor = cnx.cursor()
808
809
        cursor.execute(" SELECT name "
810
                       " FROM tbl_combined_equipments "
811
                       " WHERE id = %s ", (id_,))
812
        if cursor.fetchone() is None:
813
            cursor.close()
814
            cnx.close()
815
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
816
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
817
818
        cursor.execute(" SELECT name "
819
                       " FROM tbl_equipments "
820
                       " WHERE id = %s ", (eid,))
821
        if cursor.fetchone() is None:
822
            cursor.close()
823
            cnx.close()
824
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
825
                                   description='API.EQUIPMENT_NOT_FOUND')
826
827
        cursor.execute(" SELECT id "
828
                       " FROM tbl_combined_equipments_equipments "
829
                       " WHERE combined_equipment_id = %s AND equipment_id = %s ", (id_, eid))
830
        if cursor.fetchone() is None:
831
            cursor.close()
832
            cnx.close()
833
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
834
                                   description='API.COMBINED_EQUIPMENT_EQUIPMENT_RELATION_NOT_FOUND')
835
836
        cursor.execute(" DELETE FROM tbl_combined_equipments_equipments "
837
                       " WHERE combined_equipment_id = %s AND equipment_id = %s ", (id_, eid))
838
        cnx.commit()
839
840
        cursor.close()
841
        cnx.close()
842
843
        resp.status = falcon.HTTP_204
844
845
846
class CombinedEquipmentParameterCollection:
847
    def __init__(self):
848
        pass
849
850
    @staticmethod
851
    def on_options(req, resp, id_):
852
        _ = req
853
        resp.status = falcon.HTTP_200
854
        _ = id_
855
856
    @staticmethod
857
    def on_get(req, resp, id_):
858
        if 'API-KEY' not in req.headers or \
859
                not isinstance(req.headers['API-KEY'], str) or \
860
                len(str.strip(req.headers['API-KEY'])) == 0:
861
            access_control(req)
862
        else:
863
            api_key_control(req)
864
        if not id_.isdigit() or int(id_) <= 0:
865
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
866
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
867
868
        cnx = mysql.connector.connect(**config.myems_system_db)
869
        cursor = cnx.cursor()
870
871
        cursor.execute(" SELECT name "
872
                       " FROM tbl_combined_equipments "
873
                       " WHERE id = %s ", (id_,))
874
        if cursor.fetchone() is None:
875
            cursor.close()
876
            cnx.close()
877
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
878
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
879
880
        cursor.execute(" SELECT data_source_id "
881
                       " FROM tbl_combined_equipments_data_sources "
882
                       " WHERE combined_equipment_id = %s ", (id_,))
883
        rows_data_sources = cursor.fetchall()
884
        data_source_ids = tuple({row[0] for row in rows_data_sources if row[0] is not None})
885
886
        if len(data_source_ids) > 0:
887
            format_strings = ','.join(['%s'] * len(data_source_ids))
888
            query = (" SELECT id, name "
889
                     " FROM tbl_points "
890
                     " WHERE data_source_id IN (" + format_strings + ") ")
891
            cursor.execute(query, data_source_ids)
892
            rows_points = cursor.fetchall()
893
        else:
894
            rows_points = list()
895
896
        point_dict = dict()
897
        if rows_points is not None and len(rows_points) > 0:
898
            for row in rows_points:
899
                point_dict[row[0]] = {"id": row[0],
900
                                      "name": row[1]}
901
902
        query = (" SELECT id, name, uuid "
903
                 " FROM tbl_meters ")
904
        cursor.execute(query)
905
        rows_meters = cursor.fetchall()
906
907
        meter_dict = dict()
908
        if rows_meters is not None and len(rows_meters) > 0:
909
            for row in rows_meters:
910
                meter_dict[row[2]] = {"type": 'meter',
911
                                      "id": row[0],
912
                                      "name": row[1],
913
                                      "uuid": row[2]}
914
915
        query = (" SELECT id, name, uuid "
916
                 " FROM tbl_offline_meters ")
917
        cursor.execute(query)
918
        rows_offline_meters = cursor.fetchall()
919
920
        offline_meter_dict = dict()
921
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
922
            for row in rows_offline_meters:
923
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
924
                                              "id": row[0],
925
                                              "name": row[1],
926
                                              "uuid": row[2]}
927
928
        query = (" SELECT id, name, uuid "
929
                 " FROM tbl_virtual_meters ")
930
        cursor.execute(query)
931
        rows_virtual_meters = cursor.fetchall()
932
933
        virtual_meter_dict = dict()
934
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
935
            for row in rows_virtual_meters:
936
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
937
                                              "id": row[0],
938
                                              "name": row[1],
939
                                              "uuid": row[2]}
940
941
        query = (" SELECT id, name, parameter_type, "
942
                 "        constant, point_id, numerator_meter_uuid, denominator_meter_uuid "
943
                 " FROM tbl_combined_equipments_parameters "
944
                 " WHERE combined_equipment_id = %s "
945
                 " ORDER BY id ")
946
        cursor.execute(query, (id_,))
947
        rows_parameters = cursor.fetchall()
948
949
        result = list()
950
        if rows_parameters is not None and len(rows_parameters) > 0:
951
            for row in rows_parameters:
952
                constant = None
953
                point = None
954
                numerator_meter = None
955
                denominator_meter = None
956 View Code Duplication
                if row[2] == 'point':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
957
                    point = point_dict.get(row[4], None)
958
                    if point is None and row[4] is not None:
959
                        query = (" SELECT id, name "
960
                                 " FROM tbl_points "
961
                                 " WHERE id = %s ")
962
                        cursor.execute(query, (row[4],))
963
                        point_row = cursor.fetchone()
964
                        if point_row is not None:
965
                            point = {"id": point_row[0],
966
                                     "name": point_row[1]}
967
                    constant = None
968
                    numerator_meter = None
969
                    denominator_meter = None
970
                elif row[2] == 'constant':
971
                    constant = row[3]
972
                    point = None
973
                    numerator_meter = None
974
                    denominator_meter = None
975
                elif row[2] == 'fraction':
976
                    constant = None
977
                    point = None
978
                    # find numerator meter by uuid
979
                    numerator_meter = meter_dict.get(row[5], None)
980
                    if numerator_meter is None:
981
                        numerator_meter = virtual_meter_dict.get(row[5], None)
982
                    if numerator_meter is None:
983
                        numerator_meter = offline_meter_dict.get(row[5], None)
984
                    # find denominator meter by uuid
985
                    denominator_meter = meter_dict.get(row[6], None)
986
                    if denominator_meter is None:
987
                        denominator_meter = virtual_meter_dict.get(row[6], None)
988
                    if denominator_meter is None:
989
                        denominator_meter = offline_meter_dict.get(row[6], None)
990
991
                meta_result = {"id": row[0],
992
                               "name": row[1],
993
                               "parameter_type": row[2],
994
                               "constant": constant,
995
                               "point": point,
996
                               "numerator_meter": numerator_meter,
997
                               "denominator_meter": denominator_meter}
998
                result.append(meta_result)
999
1000
        cursor.close()
1001
        cnx.close()
1002
        resp.text = json.dumps(result)
1003
1004
    @staticmethod
1005
    @user_logger
1006
    def on_post(req, resp, id_):
1007
        """Handles POST requests"""
1008
        admin_control(req)
1009
        if not id_.isdigit() or int(id_) <= 0:
1010
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1011
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1012
        try:
1013
            raw_json = req.stream.read().decode('utf-8')
1014
        except UnicodeDecodeError as ex:
1015
            print("Failed to decode request")
1016
            raise falcon.HTTPError(status=falcon.HTTP_400,
1017
                                   title='API.BAD_REQUEST',
1018
                                   description='API.INVALID_ENCODING')
1019
        except Exception as ex:
1020
            print("Unexpected error reading request stream")
1021
            raise falcon.HTTPError(status=falcon.HTTP_400,
1022
                                   title='API.BAD_REQUEST',
1023
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1024
1025
        new_values = json.loads(raw_json)
1026
1027
        if 'name' not in new_values['data'].keys() or \
1028
                not isinstance(new_values['data']['name'], str) or \
1029
                len(str.strip(new_values['data']['name'])) == 0:
1030
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1031
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_NAME')
1032
        name = str.strip(new_values['data']['name'])
1033
1034
        if 'parameter_type' not in new_values['data'].keys() or \
1035
                not isinstance(new_values['data']['parameter_type'], str) or \
1036
                len(str.strip(new_values['data']['parameter_type'])) == 0:
1037
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1038
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_TYPE')
1039
1040
        parameter_type = str.strip(new_values['data']['parameter_type'])
1041
1042
        if parameter_type not in ('constant', 'point', 'fraction'):
1043
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1044
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_TYPE')
1045
1046
        constant = None
1047
        if 'constant' in new_values['data'].keys():
1048
            if new_values['data']['constant'] is not None and \
1049
                    isinstance(new_values['data']['constant'], str) and \
1050
                    len(str.strip(new_values['data']['constant'])) > 0:
1051
                constant = str.strip(new_values['data']['constant'])
1052
1053
        point_id = None
1054
        if 'point_id' in new_values['data'].keys():
1055
            if new_values['data']['point_id'] is not None and \
1056
                    new_values['data']['point_id'] <= 0:
1057
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1058
                                       description='API.INVALID_POINT_ID')
1059
            point_id = new_values['data']['point_id']
1060
1061
        numerator_meter_uuid = None
1062
        if 'numerator_meter_uuid' in new_values['data'].keys():
1063
            if new_values['data']['numerator_meter_uuid'] is not None and \
1064
                    isinstance(new_values['data']['numerator_meter_uuid'], str) and \
1065
                    len(str.strip(new_values['data']['numerator_meter_uuid'])) > 0:
1066
                numerator_meter_uuid = str.strip(new_values['data']['numerator_meter_uuid'])
1067
1068
        denominator_meter_uuid = None
1069
        if 'denominator_meter_uuid' in new_values['data'].keys():
1070
            if new_values['data']['denominator_meter_uuid'] is not None and \
1071
                    isinstance(new_values['data']['denominator_meter_uuid'], str) and \
1072
                    len(str.strip(new_values['data']['denominator_meter_uuid'])) > 0:
1073
                denominator_meter_uuid = str.strip(new_values['data']['denominator_meter_uuid'])
1074
1075
        cnx = mysql.connector.connect(**config.myems_system_db)
1076
        cursor = cnx.cursor()
1077
1078
        cursor.execute(" SELECT name "
1079
                       " FROM tbl_combined_equipments "
1080
                       " WHERE id = %s ", (id_,))
1081
        if cursor.fetchone() is None:
1082
            cursor.close()
1083
            cnx.close()
1084
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1085
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1086
1087
        cursor.execute(" SELECT data_source_id "
1088
                       " FROM tbl_combined_equipments_data_sources "
1089
                       " WHERE combined_equipment_id = %s ", (id_,))
1090
        rows_data_sources = cursor.fetchall()
1091
        data_source_ids = tuple({row[0] for row in rows_data_sources if row[0] is not None})
1092
1093
        cursor.execute(" SELECT data_source_id "
1094
                       " FROM tbl_combined_equipments_data_sources "
1095
                       " WHERE combined_equipment_id = %s ", (id_,))
1096
        rows_data_sources = cursor.fetchall()
1097
        data_source_ids = tuple({row[0] for row in rows_data_sources if row[0] is not None})
1098
1099
        cursor.execute(" SELECT name "
1100
                       " FROM tbl_combined_equipments_parameters "
1101
                       " WHERE name = %s AND combined_equipment_id = %s ", (name, id_))
1102
        if cursor.fetchone() is not None:
1103
            cursor.close()
1104
            cnx.close()
1105
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1106
                                   description='API.COMBINED_EQUIPMENT_PARAMETER_NAME_IS_ALREADY_IN_USE')
1107
1108
        # validate by parameter type
1109 View Code Duplication
        if parameter_type == 'point':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1110
            if point_id is None:
1111
                cursor.close()
1112
                cnx.close()
1113
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1114
                                       description='API.INVALID_POINT_ID')
1115
1116
            if len(data_source_ids) == 0:
1117
                cursor.close()
1118
                cnx.close()
1119
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1120
                                       description='API.POINT_NOT_FOUND')
1121
1122
            format_strings = ','.join(['%s'] * len(data_source_ids))
1123
            query = (" SELECT id, name "
1124
                     " FROM tbl_points "
1125
                     " WHERE id = %s AND data_source_id IN (" + format_strings + ") ")
1126
            cursor.execute(query, (point_id,) + data_source_ids)
1127
            if cursor.fetchone() is None:
1128
                cursor.close()
1129
                cnx.close()
1130
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1131
                                       description='API.POINT_NOT_FOUND')
1132
1133
        elif parameter_type == 'constant':
1134
            if constant is None:
1135
                cursor.close()
1136
                cnx.close()
1137
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1138
                                       description='API.INVALID_CONSTANT_VALUE')
1139
1140
        elif parameter_type == 'fraction':
1141
1142
            query = (" SELECT id, name, uuid "
1143
                     " FROM tbl_meters ")
1144
            cursor.execute(query)
1145
            rows_meters = cursor.fetchall()
1146
1147
            meter_dict = dict()
1148
            if rows_meters is not None and len(rows_meters) > 0:
1149
                for row in rows_meters:
1150
                    meter_dict[row[2]] = {"type": 'meter',
1151
                                          "id": row[0],
1152
                                          "name": row[1],
1153
                                          "uuid": row[2]}
1154
1155
            query = (" SELECT id, name, uuid "
1156
                     " FROM tbl_offline_meters ")
1157
            cursor.execute(query)
1158
            rows_offline_meters = cursor.fetchall()
1159
1160
            offline_meter_dict = dict()
1161
            if rows_offline_meters is not None and len(rows_offline_meters) > 0:
1162
                for row in rows_offline_meters:
1163
                    offline_meter_dict[row[2]] = {"type": 'offline_meter',
1164
                                                  "id": row[0],
1165
                                                  "name": row[1],
1166
                                                  "uuid": row[2]}
1167
1168
            query = (" SELECT id, name, uuid "
1169
                     " FROM tbl_virtual_meters ")
1170
            cursor.execute(query)
1171
            rows_virtual_meters = cursor.fetchall()
1172
1173
            virtual_meter_dict = dict()
1174
            if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
1175
                for row in rows_virtual_meters:
1176
                    virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
1177
                                                  "id": row[0],
1178
                                                  "name": row[1],
1179
                                                  "uuid": row[2]}
1180
1181
            # validate numerator meter uuid
1182
            if meter_dict.get(numerator_meter_uuid) is None and \
1183
                    virtual_meter_dict.get(numerator_meter_uuid) is None and \
1184
                    offline_meter_dict.get(numerator_meter_uuid) is None:
1185
                cursor.close()
1186
                cnx.close()
1187
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1188
                                       description='API.INVALID_NUMERATOR_METER_UUID')
1189
1190
            # validate denominator meter uuid
1191
            if denominator_meter_uuid == numerator_meter_uuid:
1192
                cursor.close()
1193
                cnx.close()
1194
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1195
                                       description='API.INVALID_DENOMINATOR_METER_UUID')
1196
1197
            if denominator_meter_uuid not in meter_dict and \
1198
                    denominator_meter_uuid not in virtual_meter_dict and \
1199
                    denominator_meter_uuid not in offline_meter_dict:
1200
                cursor.close()
1201
                cnx.close()
1202
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1203
                                       description='API.INVALID_DENOMINATOR_METER_UUID')
1204
1205
        add_values = (" INSERT INTO tbl_combined_equipments_parameters "
1206
                      "    (combined_equipment_id, name, parameter_type, constant, "
1207
                      "     point_id, numerator_meter_uuid, denominator_meter_uuid) "
1208
                      " VALUES (%s, %s, %s, %s, %s, %s, %s) ")
1209
        cursor.execute(add_values, (id_,
1210
                                    name,
1211
                                    parameter_type,
1212
                                    constant,
1213
                                    point_id,
1214
                                    numerator_meter_uuid,
1215
                                    denominator_meter_uuid))
1216
        new_id = cursor.lastrowid
1217
        cnx.commit()
1218
        cursor.close()
1219
        cnx.close()
1220
1221
        resp.status = falcon.HTTP_201
1222
        resp.location = '/combinedequipments/' + str(id_) + 'parameters/' + str(new_id)
1223
1224
1225
class CombinedEquipmentParameterItem:
1226
    def __init__(self):
1227
        pass
1228
1229
    @staticmethod
1230
    def on_options(req, resp, id_, pid):
1231
        _ = req
1232
        resp.status = falcon.HTTP_200
1233
        _ = id_
1234
1235
    @staticmethod
1236
    def on_get(req, resp, id_, pid):
1237
        if 'API-KEY' not in req.headers or \
1238
                not isinstance(req.headers['API-KEY'], str) or \
1239
                len(str.strip(req.headers['API-KEY'])) == 0:
1240
            access_control(req)
1241
        else:
1242
            api_key_control(req)
1243
        if not id_.isdigit() or int(id_) <= 0:
1244
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1245
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1246
1247
        if not pid.isdigit() or int(pid) <= 0:
1248
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1249
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_ID')
1250
1251
        cnx = mysql.connector.connect(**config.myems_system_db)
1252
        cursor = cnx.cursor()
1253
1254
        cursor.execute(" SELECT data_source_id "
1255
                       " FROM tbl_combined_equipments_data_sources "
1256
                       " WHERE combined_equipment_id = %s ", (id_,))
1257
        rows_data_sources = cursor.fetchall()
1258
        data_source_ids = tuple({row[0] for row in rows_data_sources if row[0] is not None})
1259
1260
        if len(data_source_ids) > 0:
1261
            format_strings = ','.join(['%s'] * len(data_source_ids))
1262
            query = (" SELECT id, name "
1263
                     " FROM tbl_points "
1264
                     " WHERE data_source_id IN (" + format_strings + ") ")
1265
            cursor.execute(query, data_source_ids)
1266
            rows_points = cursor.fetchall()
1267
        else:
1268
            rows_points = list()
1269
1270
        point_dict = dict()
1271
        if rows_points is not None and len(rows_points) > 0:
1272
            for row in rows_points:
1273
                point_dict[row[0]] = {"id": row[0],
1274
                                      "name": row[1]}
1275
1276
        query = (" SELECT id, name, uuid "
1277
                 " FROM tbl_meters ")
1278
        cursor.execute(query)
1279
        rows_meters = cursor.fetchall()
1280
1281
        meter_dict = dict()
1282
        if rows_meters is not None and len(rows_meters) > 0:
1283
            for row in rows_meters:
1284
                meter_dict[row[2]] = {"type": 'meter',
1285
                                      "id": row[0],
1286
                                      "name": row[1],
1287
                                      "uuid": row[2]}
1288
1289
        query = (" SELECT id, name, uuid "
1290
                 " FROM tbl_offline_meters ")
1291
        cursor.execute(query)
1292
        rows_offline_meters = cursor.fetchall()
1293
1294
        offline_meter_dict = dict()
1295
        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
1296
            for row in rows_offline_meters:
1297
                offline_meter_dict[row[2]] = {"type": 'offline_meter',
1298
                                              "id": row[0],
1299
                                              "name": row[1],
1300
                                              "uuid": row[2]}
1301
1302
        query = (" SELECT id, name, uuid "
1303
                 " FROM tbl_virtual_meters ")
1304
        cursor.execute(query)
1305
        rows_virtual_meters = cursor.fetchall()
1306
1307
        virtual_meter_dict = dict()
1308
        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
1309
            for row in rows_virtual_meters:
1310
                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
1311
                                              "id": row[0],
1312
                                              "name": row[1],
1313
                                              "uuid": row[2]}
1314
1315
        query = (" SELECT id, name, parameter_type, "
1316
                 "        constant, point_id, numerator_meter_uuid, denominator_meter_uuid "
1317
                 " FROM tbl_combined_equipments_parameters "
1318
                 " WHERE combined_equipment_id = %s AND id = %s ")
1319
        cursor.execute(query, (id_, pid))
1320
        row = cursor.fetchone()
1321
1322
        if row is None:
1323
            cursor.close()
1324
            cnx.close()
1325
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1326
                                   description='API.COMBINED_EQUIPMENT_PARAMETER_NOT_FOUND_OR_NOT_MATCH')
1327
        else:
1328
            constant = None
1329
            point = None
1330
            numerator_meter = None
1331
            denominator_meter = None
1332 View Code Duplication
            if row[2] == 'point':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1333
                point = point_dict.get(row[4], None)
1334
                if point is None and row[4] is not None:
1335
                    query = (" SELECT id, name "
1336
                             " FROM tbl_points "
1337
                             " WHERE id = %s ")
1338
                    cursor.execute(query, (row[4],))
1339
                    point_row = cursor.fetchone()
1340
                    if point_row is not None:
1341
                        point = {"id": point_row[0],
1342
                                 "name": point_row[1]}
1343
                constant = None
1344
                numerator_meter = None
1345
                denominator_meter = None
1346
            elif row[2] == 'constant':
1347
                constant = row[3]
1348
                point = None
1349
                numerator_meter = None
1350
                denominator_meter = None
1351
            elif row[2] == 'fraction':
1352
                constant = None
1353
                point = None
1354
                # find numerator meter by uuid
1355
                numerator_meter = meter_dict.get(row[5], None)
1356
                if numerator_meter is None:
1357
                    numerator_meter = virtual_meter_dict.get(row[5], None)
1358
                if numerator_meter is None:
1359
                    numerator_meter = offline_meter_dict.get(row[5], None)
1360
                # find denominator meter by uuid
1361
                denominator_meter = meter_dict.get(row[6], None)
1362
                if denominator_meter is None:
1363
                    denominator_meter = virtual_meter_dict.get(row[6], None)
1364
                if denominator_meter is None:
1365
                    denominator_meter = offline_meter_dict.get(row[6], None)
1366
1367
            meta_result = {"id": row[0],
1368
                           "name": row[1],
1369
                           "parameter_type": row[2],
1370
                           "constant": constant,
1371
                           "point": point,
1372
                           "numerator_meter": numerator_meter,
1373
                           "denominator_meter": denominator_meter}
1374
1375
        cursor.close()
1376
        cnx.close()
1377
        resp.text = json.dumps(meta_result)
1378
1379
    @staticmethod
1380
    @user_logger
1381
    def on_delete(req, resp, id_, pid):
1382
        admin_control(req)
1383
        if not id_.isdigit() or int(id_) <= 0:
1384
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1385
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1386
1387
        if not pid.isdigit() or int(pid) <= 0:
1388
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1389
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_ID')
1390
1391
        cnx = mysql.connector.connect(**config.myems_system_db)
1392
        cursor = cnx.cursor()
1393
1394
        cursor.execute(" SELECT name "
1395
                       " FROM tbl_combined_equipments "
1396
                       " WHERE id = %s ",
1397
                       (id_,))
1398
        row = cursor.fetchone()
1399
        if row is None:
1400
            cursor.close()
1401
            cnx.close()
1402
            raise falcon.HTTPError(status=falcon.HTTP_400,
1403
                                   title='API.NOT_FOUND',
1404
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1405
1406
        cursor.execute(" SELECT name "
1407
                       " FROM tbl_combined_equipments_parameters "
1408
                       " WHERE combined_equipment_id = %s AND id = %s ",
1409
                       (id_, pid,))
1410
        row = cursor.fetchone()
1411
        if row is None:
1412
            cursor.close()
1413
            cnx.close()
1414
            raise falcon.HTTPError(status=falcon.HTTP_400,
1415
                                   title='API.NOT_FOUND',
1416
                                   description='API.COMBINED_EQUIPMENT_PARAMETER_NOT_FOUND_OR_NOT_MATCH')
1417
1418
        cursor.execute(" DELETE FROM tbl_combined_equipments_parameters "
1419
                       " WHERE id = %s ", (pid,))
1420
        cnx.commit()
1421
1422
        cursor.close()
1423
        cnx.close()
1424
1425
        resp.status = falcon.HTTP_204
1426
1427
    @staticmethod
1428
    @user_logger
1429
    def on_put(req, resp, id_, pid):
1430
        """Handles PUT requests"""
1431
        admin_control(req)
1432
        if not id_.isdigit() or int(id_) <= 0:
1433
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1434
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1435
1436
        if not pid.isdigit() or int(pid) <= 0:
1437
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1438
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_ID')
1439
1440
        try:
1441
            raw_json = req.stream.read().decode('utf-8')
1442
        except UnicodeDecodeError as ex:
1443
            print("Failed to decode request")
1444
            raise falcon.HTTPError(status=falcon.HTTP_400,
1445
                                   title='API.BAD_REQUEST',
1446
                                   description='API.INVALID_ENCODING')
1447
        except Exception as ex:
1448
            print("Unexpected error reading request stream")
1449
            raise falcon.HTTPError(status=falcon.HTTP_400,
1450
                                   title='API.BAD_REQUEST',
1451
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1452
1453
        new_values = json.loads(raw_json)
1454
1455
        if 'name' not in new_values['data'].keys() or \
1456
                not isinstance(new_values['data']['name'], str) or \
1457
                len(str.strip(new_values['data']['name'])) == 0:
1458
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1459
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_NAME')
1460
        name = str.strip(new_values['data']['name'])
1461
1462
        if 'parameter_type' not in new_values['data'].keys() or \
1463
                not isinstance(new_values['data']['parameter_type'], str) or \
1464
                len(str.strip(new_values['data']['parameter_type'])) == 0:
1465
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1466
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_TYPE')
1467
1468
        parameter_type = str.strip(new_values['data']['parameter_type'])
1469
1470
        if parameter_type not in ('constant', 'point', 'fraction'):
1471
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1472
                                   description='API.INVALID_COMBINED_EQUIPMENT_PARAMETER_TYPE')
1473
1474
        constant = None
1475
        if 'constant' in new_values['data'].keys():
1476
            if new_values['data']['constant'] is not None and \
1477
                    isinstance(new_values['data']['constant'], str) and \
1478
                    len(str.strip(new_values['data']['constant'])) > 0:
1479
                constant = str.strip(new_values['data']['constant'])
1480
1481
        point_id = None
1482
        if 'point_id' in new_values['data'].keys():
1483
            if new_values['data']['point_id'] is not None and \
1484
                    new_values['data']['point_id'] <= 0:
1485
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1486
                                       description='API.INVALID_POINT_ID')
1487
            point_id = new_values['data']['point_id']
1488
1489
        numerator_meter_uuid = None
1490
        if 'numerator_meter_uuid' in new_values['data'].keys():
1491
            if new_values['data']['numerator_meter_uuid'] is not None and \
1492
                    isinstance(new_values['data']['numerator_meter_uuid'], str) and \
1493
                    len(str.strip(new_values['data']['numerator_meter_uuid'])) > 0:
1494
                numerator_meter_uuid = str.strip(new_values['data']['numerator_meter_uuid'])
1495
1496
        denominator_meter_uuid = None
1497
        if 'denominator_meter_uuid' in new_values['data'].keys():
1498
            if new_values['data']['denominator_meter_uuid'] is not None and \
1499
                    isinstance(new_values['data']['denominator_meter_uuid'], str) and \
1500
                    len(str.strip(new_values['data']['denominator_meter_uuid'])) > 0:
1501
                denominator_meter_uuid = str.strip(new_values['data']['denominator_meter_uuid'])
1502
1503
        cnx = mysql.connector.connect(**config.myems_system_db)
1504
        cursor = cnx.cursor()
1505
1506
        cursor.execute(" SELECT name "
1507
                       " FROM tbl_combined_equipments "
1508
                       " WHERE id = %s ", (id_,))
1509
        if cursor.fetchone() is None:
1510
            cursor.close()
1511
            cnx.close()
1512
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1513
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1514
1515
        cursor.execute(" SELECT name "
1516
                       " FROM tbl_combined_equipments_parameters "
1517
                       " WHERE combined_equipment_id = %s AND id = %s ",
1518
                       (id_, pid,))
1519
        row = cursor.fetchone()
1520
        if row is None:
1521
            cursor.close()
1522
            cnx.close()
1523
            raise falcon.HTTPError(status=falcon.HTTP_400,
1524
                                   title='API.NOT_FOUND',
1525
                                   description='API.COMBINED_EQUIPMENT_PARAMETER_NOT_FOUND_OR_NOT_MATCH')
1526
1527
        cursor.execute(" SELECT name "
1528
                       " FROM tbl_combined_equipments_parameters "
1529
                       " WHERE name = %s AND combined_equipment_id = %s  AND id != %s ", (name, id_, pid))
1530
        row = cursor.fetchone()
1531
        if row is not None:
1532
            cursor.close()
1533
            cnx.close()
1534
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1535
                                   description='API.COMBINED_EQUIPMENT_PARAMETER_NAME_IS_ALREADY_IN_USE')
1536
1537
        # validate by parameter type
1538 View Code Duplication
        if parameter_type == 'point':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1539
            if point_id is None:
1540
                cursor.close()
1541
                cnx.close()
1542
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1543
                                       description='API.INVALID_POINT_ID')
1544
1545
            if len(data_source_ids) == 0:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable data_source_ids does not seem to be defined.
Loading history...
1546
                cursor.close()
1547
                cnx.close()
1548
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
1549
                                       description='API.POINT_NOT_FOUND')
1550
1551
            format_strings = ','.join(['%s'] * len(data_source_ids))
1552
            query = (" SELECT id, name "
1553
                     " FROM tbl_points "
1554
                     " WHERE id = %s AND data_source_id IN (" + format_strings + ") ")
1555
            cursor.execute(query, (point_id,) + data_source_ids)
1556
            row = cursor.fetchone()
1557
            if row is None:
1558
                cursor.close()
1559
                cnx.close()
1560
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1561
                                       description='API.POINT_NOT_FOUND')
1562
1563
        elif parameter_type == 'constant':
1564
            if constant is None:
1565
                cursor.close()
1566
                cnx.close()
1567
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1568
                                       description='API.INVALID_CONSTANT_VALUE')
1569
1570
        elif parameter_type == 'fraction':
1571
1572
            query = (" SELECT id, name, uuid "
1573
                     " FROM tbl_meters ")
1574
            cursor.execute(query)
1575
            rows_meters = cursor.fetchall()
1576
1577
            meter_dict = dict()
1578
            if rows_meters is not None and len(rows_meters) > 0:
1579
                for row in rows_meters:
1580
                    meter_dict[row[2]] = {"type": 'meter',
1581
                                          "id": row[0],
1582
                                          "name": row[1],
1583
                                          "uuid": row[2]}
1584
1585
            query = (" SELECT id, name, uuid "
1586
                     " FROM tbl_offline_meters ")
1587
            cursor.execute(query)
1588
            rows_offline_meters = cursor.fetchall()
1589
1590
            offline_meter_dict = dict()
1591
            if rows_offline_meters is not None and len(rows_offline_meters) > 0:
1592
                for row in rows_offline_meters:
1593
                    offline_meter_dict[row[2]] = {"type": 'offline_meter',
1594
                                                  "id": row[0],
1595
                                                  "name": row[1],
1596
                                                  "uuid": row[2]}
1597
1598
            query = (" SELECT id, name, uuid "
1599
                     " FROM tbl_virtual_meters ")
1600
            cursor.execute(query)
1601
            rows_virtual_meters = cursor.fetchall()
1602
1603
            virtual_meter_dict = dict()
1604
            if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
1605
                for row in rows_virtual_meters:
1606
                    virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
1607
                                                  "id": row[0],
1608
                                                  "name": row[1],
1609
                                                  "uuid": row[2]}
1610
1611
            # validate numerator meter uuid
1612
            if meter_dict.get(numerator_meter_uuid) is None and \
1613
                    virtual_meter_dict.get(numerator_meter_uuid) is None and \
1614
                    offline_meter_dict.get(numerator_meter_uuid) is None:
1615
                cursor.close()
1616
                cnx.close()
1617
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1618
                                       description='API.INVALID_NUMERATOR_METER_UUID')
1619
1620
            # validate denominator meter uuid
1621
            if denominator_meter_uuid == numerator_meter_uuid:
1622
                cursor.close()
1623
                cnx.close()
1624
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1625
                                       description='API.INVALID_DENOMINATOR_METER_UUID')
1626
1627
            if denominator_meter_uuid not in meter_dict and \
1628
                    denominator_meter_uuid not in virtual_meter_dict and \
1629
                    denominator_meter_uuid not in offline_meter_dict:
1630
                cursor.close()
1631
                cnx.close()
1632
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1633
                                       description='API.INVALID_DENOMINATOR_METER_UUID')
1634
1635
        add_values = (" UPDATE tbl_combined_equipments_parameters "
1636
                      " SET name = %s , parameter_type = %s, constant = %s, "
1637
                      "     point_id = %s, numerator_meter_uuid = %s, denominator_meter_uuid = %s "
1638
                      " WHERE id = %s ")
1639
        cursor.execute(add_values, (name,
1640
                                    parameter_type,
1641
                                    constant,
1642
                                    point_id,
1643
                                    numerator_meter_uuid,
1644
                                    denominator_meter_uuid,
1645
                                    pid))
1646
        cnx.commit()
1647
1648
        cursor.close()
1649
        cnx.close()
1650
1651
        resp.status = falcon.HTTP_200
1652
1653
1654 View Code Duplication
class CombinedEquipmentDataSourceCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1655
    def __init__(self):
1656
        pass
1657
1658
    @staticmethod
1659
    def on_options(req, resp, id_):
1660
        _ = req
1661
        resp.status = falcon.HTTP_200
1662
        _ = id_
1663
1664
    @staticmethod
1665
    def on_get(req, resp, id_):
1666
        if 'API-KEY' not in req.headers or \
1667
                not isinstance(req.headers['API-KEY'], str) or \
1668
                len(str.strip(req.headers['API-KEY'])) == 0:
1669
            access_control(req)
1670
        else:
1671
            api_key_control(req)
1672
1673
        if not id_.isdigit() or int(id_) <= 0:
1674
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1675
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1676
1677
        cnx = mysql.connector.connect(**config.myems_system_db)
1678
        cursor = cnx.cursor()
1679
1680
        cursor.execute(" SELECT name FROM tbl_combined_equipments WHERE id = %s ", (id_,))
1681
        if cursor.fetchone() is None:
1682
            cursor.close()
1683
            cnx.close()
1684
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1685
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1686
1687
        query = (" SELECT ds.id, ds.name, ds.uuid "
1688
                 " FROM tbl_combined_equipments ce, tbl_combined_equipments_data_sources ceds, tbl_data_sources ds "
1689
                 " WHERE ceds.combined_equipment_id = ce.id AND ds.id = ceds.data_source_id AND ce.id = %s "
1690
                 " ORDER BY ds.id ")
1691
        cursor.execute(query, (id_,))
1692
        rows = cursor.fetchall()
1693
1694
        result = list()
1695
        if rows is not None and len(rows) > 0:
1696
            for row in rows:
1697
                meta_result = {"id": row[0], "name": row[1], "uuid": row[2]}
1698
                result.append(meta_result)
1699
1700
        cursor.close()
1701
        cnx.close()
1702
1703
        resp.text = json.dumps(result)
1704
1705
    @staticmethod
1706
    @user_logger
1707
    def on_post(req, resp, id_):
1708
        admin_control(req)
1709
        try:
1710
            raw_json = req.stream.read().decode('utf-8')
1711
        except UnicodeDecodeError as ex:
1712
            print("Failed to decode request")
1713
            raise falcon.HTTPError(status=falcon.HTTP_400,
1714
                                   title='API.BAD_REQUEST',
1715
                                   description='API.INVALID_ENCODING')
1716
        except Exception as ex:
1717
            print("Unexpected error reading request stream")
1718
            raise falcon.HTTPError(status=falcon.HTTP_400,
1719
                                   title='API.BAD_REQUEST',
1720
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1721
        if not id_.isdigit() or int(id_) <= 0:
1722
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1723
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1724
1725
        new_values = json.loads(raw_json)
1726
1727
        if 'data_source_id' not in new_values['data'].keys() or \
1728
                not isinstance(new_values['data']['data_source_id'], int) or \
1729
                new_values['data']['data_source_id'] <= 0:
1730
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1731
                                   description='API.INVALID_DATA_SOURCE_ID')
1732
1733
        data_source_id = new_values['data']['data_source_id']
1734
1735
        cnx = mysql.connector.connect(**config.myems_system_db)
1736
        cursor = cnx.cursor()
1737
1738
        cursor.execute(" SELECT name FROM tbl_combined_equipments WHERE id = %s ", (id_,))
1739
        if cursor.fetchone() is None:
1740
            cursor.close()
1741
            cnx.close()
1742
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1743
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1744
1745
        cursor.execute(" SELECT name FROM tbl_data_sources WHERE id = %s ", (data_source_id,))
1746
        if cursor.fetchone() is None:
1747
            cursor.close()
1748
            cnx.close()
1749
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1750
                                   description='API.DATA_SOURCE_NOT_FOUND')
1751
1752
        cursor.execute(" SELECT id "
1753
                       " FROM tbl_combined_equipments_data_sources "
1754
                       " WHERE combined_equipment_id = %s AND data_source_id = %s", (id_, data_source_id))
1755
        if cursor.fetchone() is not None:
1756
            cursor.close()
1757
            cnx.close()
1758
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
1759
                                   description='API.COMBINED_EQUIPMENT_DATA_SOURCE_RELATION_EXISTS')
1760
1761
        cursor.execute(" INSERT INTO tbl_combined_equipments_data_sources (combined_equipment_id, data_source_id) "
1762
                       " VALUES (%s, %s) ", (id_, data_source_id))
1763
        cnx.commit()
1764
        cursor.close()
1765
        cnx.close()
1766
1767
        resp.status = falcon.HTTP_201
1768
        resp.location = '/combinedequipments/' + str(id_) + '/datasources/' + str(data_source_id)
1769
1770
1771
class CombinedEquipmentDataSourceItem:
1772
    def __init__(self):
1773
        pass
1774
1775
    @staticmethod
1776
    def on_options(req, resp, id_, dsid):
1777
        _ = req
1778
        _ = id_
1779
        _ = dsid
1780
        resp.status = falcon.HTTP_200
1781
1782
    @staticmethod
1783
    @user_logger
1784
    def on_delete(req, resp, id_, dsid):
1785
        admin_control(req)
1786
1787
        if not id_.isdigit() or int(id_) <= 0:
1788
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1789
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1790
1791
        if not dsid.isdigit() or int(dsid) <= 0:
1792
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1793
                                   description='API.INVALID_DATA_SOURCE_ID')
1794
1795
        cnx = mysql.connector.connect(**config.myems_system_db)
1796
        cursor = cnx.cursor()
1797
1798
        cursor.execute(" SELECT name FROM tbl_combined_equipments WHERE id = %s ", (id_,))
1799
        if cursor.fetchone() is None:
1800
            cursor.close()
1801
            cnx.close()
1802
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1803
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1804
1805
        cursor.execute(" SELECT name FROM tbl_data_sources WHERE id = %s ", (dsid,))
1806
        if cursor.fetchone() is None:
1807
            cursor.close()
1808
            cnx.close()
1809
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1810
                                   description='API.DATA_SOURCE_NOT_FOUND')
1811
1812
        cursor.execute(" SELECT id "
1813
                       " FROM tbl_combined_equipments_data_sources "
1814
                       " WHERE combined_equipment_id = %s AND data_source_id = %s ", (id_, dsid))
1815
        if cursor.fetchone() is None:
1816
            cursor.close()
1817
            cnx.close()
1818
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1819
                                   description='API.COMBINED_EQUIPMENT_DATA_SOURCE_RELATION_NOT_FOUND')
1820
1821
        cursor.execute(" DELETE FROM tbl_combined_equipments_data_sources "
1822
                       " WHERE combined_equipment_id = %s AND data_source_id = %s ", (id_, dsid))
1823
        cnx.commit()
1824
        cursor.close()
1825
        cnx.close()
1826
1827
        resp.status = falcon.HTTP_204
1828
1829
1830
class CombinedEquipmentDataSourcePointCollection:
1831
    def __init__(self):
1832
        pass
1833
1834
    @staticmethod
1835
    def on_options(req, resp, id_):
1836
        _ = req
1837
        resp.status = falcon.HTTP_200
1838
        _ = id_
1839
1840
    @staticmethod
1841
    def on_get(req, resp, id_):
1842
        if 'API-KEY' not in req.headers or \
1843
                not isinstance(req.headers['API-KEY'], str) or \
1844
                len(str.strip(req.headers['API-KEY'])) == 0:
1845
            access_control(req)
1846
        else:
1847
            api_key_control(req)
1848
        if not id_.isdigit() or int(id_) <= 0:
1849
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1850
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1851
1852
        cnx = mysql.connector.connect(**config.myems_system_db)
1853
        cursor = cnx.cursor()
1854
1855
        cursor.execute(" SELECT name FROM tbl_combined_equipments WHERE id = %s ", (id_,))
1856
        if cursor.fetchone() is None:
1857
            cursor.close()
1858
            cnx.close()
1859
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1860
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1861
1862
        query = (" SELECT p.id, p.name "
1863
                 " FROM tbl_points p, tbl_combined_equipments_data_sources ceds, tbl_data_sources ds "
1864
                 " WHERE ceds.combined_equipment_id = %s "
1865
                 "       AND ceds.data_source_id = ds.id "
1866
                 "       AND p.data_source_id = ds.id "
1867
                 " ORDER BY p.id ")
1868
        cursor.execute(query, (id_,))
1869
        rows = cursor.fetchall()
1870
1871
        result = list()
1872
        if rows is not None and len(rows) > 0:
1873
            for row in rows:
1874
                meta_result = {"id": row[0], "name": row[1]}
1875
                result.append(meta_result)
1876
1877
        cursor.close()
1878
        cnx.close()
1879
1880
        resp.text = json.dumps(result)
1881
1882
1883 View Code Duplication
class CombinedEquipmentMeterCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1884
    def __init__(self):
1885
        pass
1886
1887
    @staticmethod
1888
    def on_options(req, resp, id_):
1889
        _ = req
1890
        resp.status = falcon.HTTP_200
1891
        _ = id_
1892
1893
    @staticmethod
1894
    def on_get(req, resp, id_):
1895
        if 'API-KEY' not in req.headers or \
1896
                not isinstance(req.headers['API-KEY'], str) or \
1897
                len(str.strip(req.headers['API-KEY'])) == 0:
1898
            access_control(req)
1899
        else:
1900
            api_key_control(req)
1901
        if not id_.isdigit() or int(id_) <= 0:
1902
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1903
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1904
1905
        cnx = mysql.connector.connect(**config.myems_system_db)
1906
        cursor = cnx.cursor()
1907
1908
        cursor.execute(" SELECT name "
1909
                       " FROM tbl_combined_equipments "
1910
                       " WHERE id = %s ", (id_,))
1911
        if cursor.fetchone() is None:
1912
            cursor.close()
1913
            cnx.close()
1914
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1915
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1916
1917
        query = (" SELECT id, name, uuid "
1918
                 " FROM tbl_energy_categories ")
1919
        cursor.execute(query)
1920
        rows_energy_categories = cursor.fetchall()
1921
1922
        energy_category_dict = dict()
1923
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
1924
            for row in rows_energy_categories:
1925
                energy_category_dict[row[0]] = {"id": row[0],
1926
                                                "name": row[1],
1927
                                                "uuid": row[2]}
1928
1929
        query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
1930
                 " FROM tbl_combined_equipments e, tbl_combined_equipments_meters em, tbl_meters m "
1931
                 " WHERE em.combined_equipment_id = e.id AND m.id = em.meter_id AND e.id = %s "
1932
                 " ORDER BY m.id ")
1933
        cursor.execute(query, (id_,))
1934
        rows = cursor.fetchall()
1935
1936
        result = list()
1937
        if rows is not None and len(rows) > 0:
1938
            for row in rows:
1939
                meta_result = {"id": row[0], "name": row[1], "uuid": row[2],
1940
                               "energy_category": energy_category_dict.get(row[3], None),
1941
                               "is_output": bool(row[4])}
1942
                result.append(meta_result)
1943
1944
        cursor.close()
1945
        cnx.close()
1946
1947
        resp.text = json.dumps(result)
1948
1949
    @staticmethod
1950
    @user_logger
1951
    def on_post(req, resp, id_):
1952
        """Handles POST requests"""
1953
        admin_control(req)
1954
        try:
1955
            raw_json = req.stream.read().decode('utf-8')
1956
        except UnicodeDecodeError as ex:
1957
            print("Failed to decode request")
1958
            raise falcon.HTTPError(status=falcon.HTTP_400,
1959
                                   title='API.BAD_REQUEST',
1960
                                   description='API.INVALID_ENCODING')
1961
        except Exception as ex:
1962
            print("Unexpected error reading request stream")
1963
            raise falcon.HTTPError(status=falcon.HTTP_400,
1964
                                   title='API.BAD_REQUEST',
1965
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1966
1967
        if not id_.isdigit() or int(id_) <= 0:
1968
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1969
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
1970
1971
        new_values = json.loads(raw_json)
1972
1973
        if 'meter_id' not in new_values['data'].keys() or \
1974
                not isinstance(new_values['data']['meter_id'], int) or \
1975
                new_values['data']['meter_id'] <= 0:
1976
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1977
                                   description='API.INVALID_METER_ID')
1978
        meter_id = new_values['data']['meter_id']
1979
1980
        if 'is_output' not in new_values['data'].keys() or \
1981
                not isinstance(new_values['data']['is_output'], bool):
1982
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1983
                                   description='API.INVALID_IS_OUTPUT_VALUE')
1984
        is_output = new_values['data']['is_output']
1985
1986
        cnx = mysql.connector.connect(**config.myems_system_db)
1987
        cursor = cnx.cursor()
1988
1989
        cursor.execute(" SELECT name "
1990
                       " from tbl_combined_equipments "
1991
                       " WHERE id = %s ", (id_,))
1992
        if cursor.fetchone() is None:
1993
            cursor.close()
1994
            cnx.close()
1995
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1996
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
1997
1998
        cursor.execute(" SELECT name "
1999
                       " FROM tbl_meters "
2000
                       " WHERE id = %s ", (meter_id,))
2001
        if cursor.fetchone() is None:
2002
            cursor.close()
2003
            cnx.close()
2004
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2005
                                   description='API.METER_NOT_FOUND')
2006
2007
        query = (" SELECT id "
2008
                 " FROM tbl_combined_equipments_meters "
2009
                 " WHERE combined_equipment_id = %s AND meter_id = %s")
2010
        cursor.execute(query, (id_, meter_id,))
2011
        if cursor.fetchone() is not None:
2012
            cursor.close()
2013
            cnx.close()
2014
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2015
                                   description='API.COMBINED_EQUIPMENT_METER_RELATION_EXISTS')
2016
2017
        add_row = (" INSERT INTO tbl_combined_equipments_meters (combined_equipment_id, meter_id, is_output ) "
2018
                   " VALUES (%s, %s, %s) ")
2019
        cursor.execute(add_row, (id_, meter_id, is_output))
2020
        cnx.commit()
2021
        cursor.close()
2022
        cnx.close()
2023
2024
        resp.status = falcon.HTTP_201
2025
        resp.location = '/combinedequipments/' + str(id_) + '/meters/' + str(meter_id)
2026
2027
2028
class CombinedEquipmentMeterItem:
2029
    def __init__(self):
2030
        pass
2031
2032
    @staticmethod
2033
    def on_options(req, resp, id_, mid):
2034
        _ = req
2035
        resp.status = falcon.HTTP_200
2036
        _ = id_
2037
2038
    @staticmethod
2039
    @user_logger
2040
    def on_delete(req, resp, id_, mid):
2041
        admin_control(req)
2042
        if not id_.isdigit() or int(id_) <= 0:
2043
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2044
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2045
2046
        if not mid.isdigit() or int(mid) <= 0:
2047
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2048
                                   description='API.INVALID_METER_ID')
2049
2050
        cnx = mysql.connector.connect(**config.myems_system_db)
2051
        cursor = cnx.cursor()
2052
2053
        cursor.execute(" SELECT name "
2054
                       " FROM tbl_combined_equipments "
2055
                       " WHERE id = %s ", (id_,))
2056
        if cursor.fetchone() is None:
2057
            cursor.close()
2058
            cnx.close()
2059
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2060
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2061
2062
        cursor.execute(" SELECT name "
2063
                       " FROM tbl_meters "
2064
                       " WHERE id = %s ", (mid,))
2065
        if cursor.fetchone() is None:
2066
            cursor.close()
2067
            cnx.close()
2068
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2069
                                   description='API.METER_NOT_FOUND')
2070
2071
        cursor.execute(" SELECT id "
2072
                       " FROM tbl_combined_equipments_meters "
2073
                       " WHERE combined_equipment_id = %s AND meter_id = %s ", (id_, mid))
2074
        if cursor.fetchone() is None:
2075
            cursor.close()
2076
            cnx.close()
2077
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2078
                                   description='API.COMBINED_EQUIPMENT_METER_RELATION_NOT_FOUND')
2079
2080
        cursor.execute(" DELETE FROM tbl_combined_equipments_meters "
2081
                       " WHERE combined_equipment_id = %s AND meter_id = %s ", (id_, mid))
2082
        cnx.commit()
2083
2084
        cursor.close()
2085
        cnx.close()
2086
2087
        resp.status = falcon.HTTP_204
2088
2089
2090 View Code Duplication
class CombinedEquipmentOfflineMeterCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2091
    def __init__(self):
2092
        pass
2093
2094
    @staticmethod
2095
    def on_options(req, resp, id_):
2096
        _ = req
2097
        resp.status = falcon.HTTP_200
2098
        _ = id_
2099
2100
    @staticmethod
2101
    def on_get(req, resp, id_):
2102
        if 'API-KEY' not in req.headers or \
2103
                not isinstance(req.headers['API-KEY'], str) or \
2104
                len(str.strip(req.headers['API-KEY'])) == 0:
2105
            access_control(req)
2106
        else:
2107
            api_key_control(req)
2108
        if not id_.isdigit() or int(id_) <= 0:
2109
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2110
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2111
2112
        cnx = mysql.connector.connect(**config.myems_system_db)
2113
        cursor = cnx.cursor()
2114
2115
        cursor.execute(" SELECT name "
2116
                       " FROM tbl_combined_equipments "
2117
                       " WHERE id = %s ", (id_,))
2118
        if cursor.fetchone() is None:
2119
            cursor.close()
2120
            cnx.close()
2121
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2122
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2123
2124
        query = (" SELECT id, name, uuid "
2125
                 " FROM tbl_energy_categories ")
2126
        cursor.execute(query)
2127
        rows_energy_categories = cursor.fetchall()
2128
2129
        energy_category_dict = dict()
2130
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2131
            for row in rows_energy_categories:
2132
                energy_category_dict[row[0]] = {"id": row[0],
2133
                                                "name": row[1],
2134
                                                "uuid": row[2]}
2135
2136
        query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
2137
                 " FROM tbl_combined_equipments e, tbl_combined_equipments_offline_meters em, tbl_offline_meters m "
2138
                 " WHERE em.combined_equipment_id = e.id AND m.id = em.offline_meter_id AND e.id = %s "
2139
                 " ORDER BY m.id ")
2140
        cursor.execute(query, (id_,))
2141
        rows = cursor.fetchall()
2142
2143
        result = list()
2144
        if rows is not None and len(rows) > 0:
2145
            for row in rows:
2146
                meta_result = {"id": row[0], "name": row[1], "uuid": row[2],
2147
                               "energy_category": energy_category_dict.get(row[3], None),
2148
                               "is_output": bool(row[4])}
2149
                result.append(meta_result)
2150
2151
        cursor.close()
2152
        cnx.close()
2153
2154
        resp.text = json.dumps(result)
2155
2156
    @staticmethod
2157
    @user_logger
2158
    def on_post(req, resp, id_):
2159
        """Handles POST requests"""
2160
        admin_control(req)
2161
        try:
2162
            raw_json = req.stream.read().decode('utf-8')
2163
        except UnicodeDecodeError as ex:
2164
            print("Failed to decode request")
2165
            raise falcon.HTTPError(status=falcon.HTTP_400,
2166
                                   title='API.BAD_REQUEST',
2167
                                   description='API.INVALID_ENCODING')
2168
        except Exception as ex:
2169
            print("Unexpected error reading request stream")
2170
            raise falcon.HTTPError(status=falcon.HTTP_400,
2171
                                   title='API.BAD_REQUEST',
2172
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
2173
2174
        if not id_.isdigit() or int(id_) <= 0:
2175
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2176
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2177
2178
        new_values = json.loads(raw_json)
2179
2180
        if 'offline_meter_id' not in new_values['data'].keys() or \
2181
                not isinstance(new_values['data']['offline_meter_id'], int) or \
2182
                new_values['data']['offline_meter_id'] <= 0:
2183
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2184
                                   description='API.INVALID_OFFLINE_METER_ID')
2185
        offline_meter_id = new_values['data']['offline_meter_id']
2186
2187
        if 'is_output' not in new_values['data'].keys() or \
2188
                not isinstance(new_values['data']['is_output'], bool):
2189
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2190
                                   description='API.INVALID_IS_OUTPUT_VALUE')
2191
        is_output = new_values['data']['is_output']
2192
2193
        cnx = mysql.connector.connect(**config.myems_system_db)
2194
        cursor = cnx.cursor()
2195
2196
        cursor.execute(" SELECT name "
2197
                       " from tbl_combined_equipments "
2198
                       " WHERE id = %s ", (id_,))
2199
        if cursor.fetchone() is None:
2200
            cursor.close()
2201
            cnx.close()
2202
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2203
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2204
2205
        cursor.execute(" SELECT name "
2206
                       " FROM tbl_offline_meters "
2207
                       " WHERE id = %s ", (offline_meter_id,))
2208
        if cursor.fetchone() is None:
2209
            cursor.close()
2210
            cnx.close()
2211
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2212
                                   description='API.OFFLINE_METER_NOT_FOUND')
2213
2214
        query = (" SELECT id "
2215
                 " FROM tbl_combined_equipments_offline_meters "
2216
                 " WHERE combined_equipment_id = %s AND offline_meter_id = %s")
2217
        cursor.execute(query, (id_, offline_meter_id,))
2218
        if cursor.fetchone() is not None:
2219
            cursor.close()
2220
            cnx.close()
2221
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2222
                                   description='API.COMBINED_EQUIPMENT_OFFLINE_METER_RELATION_EXISTS')
2223
2224
        add_row = (" INSERT INTO tbl_combined_equipments_offline_meters "
2225
                   " (combined_equipment_id, offline_meter_id, is_output ) "
2226
                   " VALUES (%s, %s, %s) ")
2227
        cursor.execute(add_row, (id_, offline_meter_id, is_output))
2228
        cnx.commit()
2229
        cursor.close()
2230
        cnx.close()
2231
2232
        resp.status = falcon.HTTP_201
2233
        resp.location = '/combinedequipments/' + str(id_) + '/offlinemeters/' + str(offline_meter_id)
2234
2235
2236
class CombinedEquipmentOfflineMeterItem:
2237
    def __init__(self):
2238
        pass
2239
2240
    @staticmethod
2241
    def on_options(req, resp, id_, mid):
2242
        _ = req
2243
        resp.status = falcon.HTTP_200
2244
        _ = id_
2245
2246
    @staticmethod
2247
    @user_logger
2248
    def on_delete(req, resp, id_, mid):
2249
        admin_control(req)
2250
        if not id_.isdigit() or int(id_) <= 0:
2251
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2252
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2253
2254
        if not mid.isdigit() or int(mid) <= 0:
2255
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2256
                                   description='API.INVALID_OFFLINE_METER_ID')
2257
2258
        cnx = mysql.connector.connect(**config.myems_system_db)
2259
        cursor = cnx.cursor()
2260
2261
        cursor.execute(" SELECT name "
2262
                       " FROM tbl_combined_equipments "
2263
                       " WHERE id = %s ", (id_,))
2264
        if cursor.fetchone() is None:
2265
            cursor.close()
2266
            cnx.close()
2267
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2268
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2269
2270
        cursor.execute(" SELECT name "
2271
                       " FROM tbl_offline_meters "
2272
                       " WHERE id = %s ", (mid,))
2273
        if cursor.fetchone() is None:
2274
            cursor.close()
2275
            cnx.close()
2276
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2277
                                   description='API.OFFLINE_METER_NOT_FOUND')
2278
2279
        cursor.execute(" SELECT id "
2280
                       " FROM tbl_combined_equipments_offline_meters "
2281
                       " WHERE combined_equipment_id = %s AND offline_meter_id = %s ", (id_, mid))
2282
        if cursor.fetchone() is None:
2283
            cursor.close()
2284
            cnx.close()
2285
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2286
                                   description='API.COMBINED_EQUIPMENT_OFFLINE_METER_RELATION_NOT_FOUND')
2287
2288
        cursor.execute(" DELETE FROM tbl_combined_equipments_offline_meters "
2289
                       " WHERE combined_equipment_id = %s AND offline_meter_id = %s ", (id_, mid))
2290
        cnx.commit()
2291
2292
        cursor.close()
2293
        cnx.close()
2294
2295
        resp.status = falcon.HTTP_204
2296
2297
2298 View Code Duplication
class CombinedEquipmentVirtualMeterCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2299
    def __init__(self):
2300
        pass
2301
2302
    @staticmethod
2303
    def on_options(req, resp, id_):
2304
        _ = req
2305
        resp.status = falcon.HTTP_200
2306
        _ = id_
2307
2308
    @staticmethod
2309
    def on_get(req, resp, id_):
2310
        if 'API-KEY' not in req.headers or \
2311
                not isinstance(req.headers['API-KEY'], str) or \
2312
                len(str.strip(req.headers['API-KEY'])) == 0:
2313
            access_control(req)
2314
        else:
2315
            api_key_control(req)
2316
        if not id_.isdigit() or int(id_) <= 0:
2317
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2318
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2319
2320
        cnx = mysql.connector.connect(**config.myems_system_db)
2321
        cursor = cnx.cursor()
2322
2323
        cursor.execute(" SELECT name "
2324
                       " FROM tbl_combined_equipments "
2325
                       " WHERE id = %s ", (id_,))
2326
        if cursor.fetchone() is None:
2327
            cursor.close()
2328
            cnx.close()
2329
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2330
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2331
2332
        query = (" SELECT id, name, uuid "
2333
                 " FROM tbl_energy_categories ")
2334
        cursor.execute(query)
2335
        rows_energy_categories = cursor.fetchall()
2336
2337
        energy_category_dict = dict()
2338
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2339
            for row in rows_energy_categories:
2340
                energy_category_dict[row[0]] = {"id": row[0],
2341
                                                "name": row[1],
2342
                                                "uuid": row[2]}
2343
2344
        query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
2345
                 " FROM tbl_combined_equipments e, tbl_combined_equipments_virtual_meters em, tbl_virtual_meters m "
2346
                 " WHERE em.combined_equipment_id = e.id AND m.id = em.virtual_meter_id AND e.id = %s "
2347
                 " ORDER BY m.id ")
2348
        cursor.execute(query, (id_,))
2349
        rows = cursor.fetchall()
2350
2351
        result = list()
2352
        if rows is not None and len(rows) > 0:
2353
            for row in rows:
2354
                meta_result = {"id": row[0], "name": row[1], "uuid": row[2],
2355
                               "energy_category": energy_category_dict.get(row[3], None),
2356
                               "is_output": bool(row[4])}
2357
                result.append(meta_result)
2358
2359
        cursor.close()
2360
        cnx.close()
2361
        resp.text = json.dumps(result)
2362
2363
    @staticmethod
2364
    @user_logger
2365
    def on_post(req, resp, id_):
2366
        """Handles POST requests"""
2367
        admin_control(req)
2368
        try:
2369
            raw_json = req.stream.read().decode('utf-8')
2370
        except UnicodeDecodeError as ex:
2371
            print("Failed to decode request")
2372
            raise falcon.HTTPError(status=falcon.HTTP_400,
2373
                                   title='API.BAD_REQUEST',
2374
                                   description='API.INVALID_ENCODING')
2375
        except Exception as ex:
2376
            print("Unexpected error reading request stream")
2377
            raise falcon.HTTPError(status=falcon.HTTP_400,
2378
                                   title='API.BAD_REQUEST',
2379
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
2380
2381
        if not id_.isdigit() or int(id_) <= 0:
2382
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2383
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2384
2385
        new_values = json.loads(raw_json)
2386
2387
        if 'virtual_meter_id' not in new_values['data'].keys() or \
2388
                not isinstance(new_values['data']['virtual_meter_id'], int) or \
2389
                new_values['data']['virtual_meter_id'] <= 0:
2390
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2391
                                   description='API.INVALID_VIRTUAL_METER_ID')
2392
        virtual_meter_id = new_values['data']['virtual_meter_id']
2393
2394
        if 'is_output' not in new_values['data'].keys() or \
2395
                not isinstance(new_values['data']['is_output'], bool):
2396
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2397
                                   description='API.INVALID_IS_OUTPUT_VALUE')
2398
        is_output = new_values['data']['is_output']
2399
2400
        cnx = mysql.connector.connect(**config.myems_system_db)
2401
        cursor = cnx.cursor()
2402
2403
        cursor.execute(" SELECT name "
2404
                       " from tbl_combined_equipments "
2405
                       " WHERE id = %s ", (id_,))
2406
        if cursor.fetchone() is None:
2407
            cursor.close()
2408
            cnx.close()
2409
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2410
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2411
2412
        cursor.execute(" SELECT name "
2413
                       " FROM tbl_virtual_meters "
2414
                       " WHERE id = %s ", (virtual_meter_id,))
2415
        if cursor.fetchone() is None:
2416
            cursor.close()
2417
            cnx.close()
2418
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2419
                                   description='API.VIRTUAL_METER_NOT_FOUND')
2420
2421
        query = (" SELECT id "
2422
                 " FROM tbl_combined_equipments_virtual_meters "
2423
                 " WHERE combined_equipment_id = %s AND virtual_meter_id = %s")
2424
        cursor.execute(query, (id_, virtual_meter_id,))
2425
        if cursor.fetchone() is not None:
2426
            cursor.close()
2427
            cnx.close()
2428
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2429
                                   description='API.COMBINED_EQUIPMENT_VIRTUAL_METER_RELATION_EXISTS')
2430
2431
        add_row = (" INSERT INTO tbl_combined_equipments_virtual_meters "
2432
                   " (combined_equipment_id, virtual_meter_id, is_output ) "
2433
                   " VALUES (%s, %s, %s) ")
2434
        cursor.execute(add_row, (id_, virtual_meter_id, is_output))
2435
        cnx.commit()
2436
        cursor.close()
2437
        cnx.close()
2438
2439
        resp.status = falcon.HTTP_201
2440
        resp.location = '/combinedequipments/' + str(id_) + '/virtualmeters/' + str(virtual_meter_id)
2441
2442
2443
class CombinedEquipmentVirtualMeterItem:
2444
    def __init__(self):
2445
        pass
2446
2447
    @staticmethod
2448
    def on_options(req, resp, id_, mid):
2449
        _ = req
2450
        resp.status = falcon.HTTP_200
2451
        _ = id_
2452
2453
    @staticmethod
2454
    @user_logger
2455
    def on_delete(req, resp, id_, mid):
2456
        admin_control(req)
2457
        if not id_.isdigit() or int(id_) <= 0:
2458
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2459
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2460
2461
        if not mid.isdigit() or int(mid) <= 0:
2462
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2463
                                   description='API.INVALID_VIRTUAL_METER_ID')
2464
2465
        cnx = mysql.connector.connect(**config.myems_system_db)
2466
        cursor = cnx.cursor()
2467
2468
        cursor.execute(" SELECT name "
2469
                       " FROM tbl_combined_equipments "
2470
                       " WHERE id = %s ", (id_,))
2471
        if cursor.fetchone() is None:
2472
            cursor.close()
2473
            cnx.close()
2474
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2475
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2476
2477
        cursor.execute(" SELECT name "
2478
                       " FROM tbl_virtual_meters "
2479
                       " WHERE id = %s ", (mid,))
2480
        if cursor.fetchone() is None:
2481
            cursor.close()
2482
            cnx.close()
2483
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2484
                                   description='API.VIRTUAL_METER_NOT_FOUND')
2485
2486
        cursor.execute(" SELECT id "
2487
                       " FROM tbl_combined_equipments_virtual_meters "
2488
                       " WHERE combined_equipment_id = %s AND virtual_meter_id = %s ", (id_, mid))
2489
        if cursor.fetchone() is None:
2490
            cursor.close()
2491
            cnx.close()
2492
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2493
                                   description='API.COMBINED_EQUIPMENT_VIRTUAL_METER_RELATION_NOT_FOUND')
2494
2495
        cursor.execute(" DELETE FROM tbl_combined_equipments_virtual_meters "
2496
                       " WHERE combined_equipment_id = %s AND virtual_meter_id = %s ", (id_, mid))
2497
        cnx.commit()
2498
2499
        cursor.close()
2500
        cnx.close()
2501
2502
        resp.status = falcon.HTTP_204
2503
2504
2505 View Code Duplication
class CombinedEquipmentCommandCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2506
    def __init__(self):
2507
        pass
2508
2509
    @staticmethod
2510
    def on_options(req, resp, id_):
2511
        _ = req
2512
        resp.status = falcon.HTTP_200
2513
        _ = id_
2514
2515
    @staticmethod
2516
    def on_get(req, resp, id_):
2517
        if 'API-KEY' not in req.headers or \
2518
                not isinstance(req.headers['API-KEY'], str) or \
2519
                len(str.strip(req.headers['API-KEY'])) == 0:
2520
            access_control(req)
2521
        else:
2522
            api_key_control(req)
2523
        if not id_.isdigit() or int(id_) <= 0:
2524
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2525
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2526
2527
        cnx = mysql.connector.connect(**config.myems_system_db)
2528
        cursor = cnx.cursor()
2529
2530
        cursor.execute(" SELECT name "
2531
                       " FROM tbl_combined_equipments "
2532
                       " WHERE id = %s ", (id_,))
2533
        if cursor.fetchone() is None:
2534
            cursor.close()
2535
            cnx.close()
2536
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2537
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2538
2539
        query = (" SELECT c.id, c.name, c.uuid "
2540
                 " FROM tbl_combined_equipments ce, tbl_combined_equipments_commands cec, tbl_commands c "
2541
                 " WHERE cec.combined_equipment_id = ce.id AND c.id = cec.command_id AND ce.id = %s "
2542
                 " ORDER BY c.id ")
2543
        cursor.execute(query, (id_,))
2544
        rows = cursor.fetchall()
2545
2546
        result = list()
2547
        if rows is not None and len(rows) > 0:
2548
            for row in rows:
2549
                meta_result = {"id": row[0], "name": row[1], "uuid": row[2]}
2550
                result.append(meta_result)
2551
2552
        resp.text = json.dumps(result)
2553
2554
    @staticmethod
2555
    @user_logger
2556
    def on_post(req, resp, id_):
2557
        """Handles POST requests"""
2558
        admin_control(req)
2559
        try:
2560
            raw_json = req.stream.read().decode('utf-8')
2561
        except UnicodeDecodeError as ex:
2562
            print("Failed to decode request")
2563
            raise falcon.HTTPError(status=falcon.HTTP_400,
2564
                                   title='API.BAD_REQUEST',
2565
                                   description='API.INVALID_ENCODING')
2566
        except Exception as ex:
2567
            print("Unexpected error reading request stream")
2568
            raise falcon.HTTPError(status=falcon.HTTP_400,
2569
                                   title='API.BAD_REQUEST',
2570
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
2571
2572
        if not id_.isdigit() or int(id_) <= 0:
2573
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2574
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2575
2576
        new_values = json.loads(raw_json)
2577
2578
        if 'command_id' not in new_values['data'].keys() or \
2579
                not isinstance(new_values['data']['command_id'], int) or \
2580
                new_values['data']['command_id'] <= 0:
2581
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2582
                                   description='API.INVALID_COMMAND_ID')
2583
        command_id = new_values['data']['command_id']
2584
2585
        cnx = mysql.connector.connect(**config.myems_system_db)
2586
        cursor = cnx.cursor()
2587
2588
        cursor.execute(" SELECT name "
2589
                       " from tbl_combined_equipments "
2590
                       " WHERE id = %s ", (id_,))
2591
        if cursor.fetchone() is None:
2592
            cursor.close()
2593
            cnx.close()
2594
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2595
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2596
2597
        cursor.execute(" SELECT name "
2598
                       " FROM tbl_commands "
2599
                       " WHERE id = %s ", (command_id,))
2600
        if cursor.fetchone() is None:
2601
            cursor.close()
2602
            cnx.close()
2603
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2604
                                   description='API.COMMAND_NOT_FOUND')
2605
2606
        query = (" SELECT id "
2607
                 " FROM tbl_combined_equipments_commands "
2608
                 " WHERE combined_equipment_id = %s AND command_id = %s")
2609
        cursor.execute(query, (id_, command_id,))
2610
        if cursor.fetchone() is not None:
2611
            cursor.close()
2612
            cnx.close()
2613
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2614
                                   description='API.COMBINED_EQUIPMENT_COMMAND_RELATION_EXISTS')
2615
2616
        add_row = (" INSERT INTO tbl_combined_equipments_commands (combined_equipment_id, command_id) "
2617
                   " VALUES (%s, %s) ")
2618
        cursor.execute(add_row, (id_, command_id,))
2619
        cnx.commit()
2620
        cursor.close()
2621
        cnx.close()
2622
2623
        resp.status = falcon.HTTP_201
2624
        resp.location = '/combinedequipments/' + str(id_) + '/commands/' + str(command_id)
2625
2626
2627
class CombinedEquipmentCommandItem:
2628
    def __init__(self):
2629
        pass
2630
2631
    @staticmethod
2632
    def on_options(req, resp, id_, cid):
2633
        _ = req
2634
        resp.status = falcon.HTTP_200
2635
        _ = id_
2636
2637
    @staticmethod
2638
    @user_logger
2639
    def on_delete(req, resp, id_, cid):
2640
        admin_control(req)
2641
        if not id_.isdigit() or int(id_) <= 0:
2642
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2643
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2644
2645
        if not cid.isdigit() or int(cid) <= 0:
2646
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2647
                                   description='API.INVALID_COMMAND_ID')
2648
2649
        cnx = mysql.connector.connect(**config.myems_system_db)
2650
        cursor = cnx.cursor()
2651
2652
        cursor.execute(" SELECT name "
2653
                       " FROM tbl_combined_equipments "
2654
                       " WHERE id = %s ", (id_,))
2655
        if cursor.fetchone() is None:
2656
            cursor.close()
2657
            cnx.close()
2658
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2659
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2660
2661
        cursor.execute(" SELECT name "
2662
                       " FROM tbl_commands "
2663
                       " WHERE id = %s ", (cid,))
2664
        if cursor.fetchone() is None:
2665
            cursor.close()
2666
            cnx.close()
2667
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2668
                                   description='API.COMMAND_NOT_FOUND')
2669
2670
        cursor.execute(" SELECT id "
2671
                       " FROM tbl_combined_equipments_commands "
2672
                       " WHERE combined_equipment_id = %s AND command_id = %s ", (id_, cid))
2673
        if cursor.fetchone() is None:
2674
            cursor.close()
2675
            cnx.close()
2676
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2677
                                   description='API.COMBINED_EQUIPMENT_COMMAND_RELATION_NOT_FOUND')
2678
2679
        cursor.execute(" DELETE FROM tbl_combined_equipments_commands "
2680
                       " WHERE combined_equipment_id = %s AND command_id = %s ", (id_, cid))
2681
        cnx.commit()
2682
2683
        cursor.close()
2684
        cnx.close()
2685
2686
        resp.status = falcon.HTTP_204
2687
2688
2689
class CombinedEquipmentExport:
2690
    def __init__(self):
2691
        pass
2692
2693
    @staticmethod
2694
    def on_options(req, resp, id_):
2695
        _ = req
2696
        resp.status = falcon.HTTP_200
2697
        _ = id_
2698
2699
    @staticmethod
2700
    def on_get(req, resp, id_):
2701
        if 'API-KEY' not in req.headers or \
2702
                not isinstance(req.headers['API-KEY'], str) or \
2703
                len(str.strip(req.headers['API-KEY'])) == 0:
2704
            access_control(req)
2705
        else:
2706
            api_key_control(req)
2707
        if not id_.isdigit() or int(id_) <= 0:
2708
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2709
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
2710
2711
        cnx = mysql.connector.connect(**config.myems_system_db)
2712
        cursor = cnx.cursor()
2713
2714
        query = (" SELECT id, name, uuid "
2715
                 " FROM tbl_cost_centers ")
2716
        cursor.execute(query)
2717
        rows_cost_centers = cursor.fetchall()
2718
2719
        cost_center_dict = dict()
2720
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
2721
            for row in rows_cost_centers:
2722
                cost_center_dict[row[0]] = {"id": row[0],
2723
                                            "name": row[1],
2724
                                            "uuid": row[2]}
2725
2726
        query = (" SELECT id, name, uuid "
2727
                 " FROM tbl_svgs ")
2728
        cursor.execute(query)
2729
        rows_svgs = cursor.fetchall()
2730
2731
        svg_dict = dict()
2732
        if rows_svgs is not None and len(rows_svgs) > 0:
2733
            for row in rows_svgs:
2734
                svg_dict[row[0]] = {"id": row[0],
2735
                                    "name": row[1],
2736
                                    "uuid": row[2]}
2737
2738
        query = (" SELECT id, name, uuid, "
2739
                 "        is_input_counted, is_output_counted, "
2740
                 "        cost_center_id, svg_id, camera_url, description "
2741
                 " FROM tbl_combined_equipments "
2742
                 " WHERE id = %s ")
2743
        cursor.execute(query, (id_,))
2744
        row = cursor.fetchone()
2745
2746
        if row is None:
2747
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2748
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
2749
        else:
2750
            meta_result = {"id": row[0],
2751
                           "name": row[1],
2752
                           "uuid": row[2],
2753
                           "is_input_counted": bool(row[3]),
2754
                           "is_output_counted": bool(row[4]),
2755
                           "cost_center": cost_center_dict.get(row[5], None),
2756
                           "svg": svg_dict.get(row[6], None),
2757
                           "camera_url": row[7],
2758
                           "description": row[8],
2759
                           "equipments": None,
2760
                           "commands": None,
2761
                           "meters": None,
2762
                           "offline_meters": None,
2763
                           "virtual_meters": None,
2764
                           "parameters": None}
2765
            query = (" SELECT e.id, e.name, e.uuid "
2766
                     " FROM tbl_combined_equipments c, tbl_combined_equipments_equipments ce, tbl_equipments e "
2767
                     " WHERE ce.combined_equipment_id = c.id AND e.id = ce.equipment_id AND c.id = %s "
2768
                     " ORDER BY e.id ")
2769
            cursor.execute(query, (id_,))
2770
            rows = cursor.fetchall()
2771
2772
            equipment_result = list()
2773
            if rows is not None and len(rows) > 0:
2774
                for row in rows:
2775
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
2776
                    equipment_result.append(result)
2777
                meta_result['equipments'] = equipment_result
2778
2779
            query = (" SELECT c.id, c.name, c.uuid "
2780
                     " FROM tbl_combined_equipments ce, tbl_combined_equipments_commands cec, tbl_commands c "
2781
                     " WHERE cec.combined_equipment_id = ce.id AND c.id = cec.command_id AND ce.id = %s "
2782
                     " ORDER BY c.id ")
2783
            cursor.execute(query, (id_,))
2784
            rows = cursor.fetchall()
2785
2786
            command_result = list()
2787
            if rows is not None and len(rows) > 0:
2788
                for row in rows:
2789
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
2790
                    command_result.append(result)
2791
                meta_result['commands'] = command_result
2792
2793
            query = (" SELECT id, name, uuid "
2794
                     " FROM tbl_energy_categories ")
2795
            cursor.execute(query)
2796
            rows_energy_categories = cursor.fetchall()
2797
2798
            energy_category_dict = dict()
2799
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2800
                for row in rows_energy_categories:
2801
                    energy_category_dict[row[0]] = {"id": row[0],
2802
                                                    "name": row[1],
2803
                                                    "uuid": row[2]}
2804
2805
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
2806
                     " FROM tbl_combined_equipments e, tbl_combined_equipments_meters em, tbl_meters m "
2807
                     " WHERE em.combined_equipment_id = e.id AND m.id = em.meter_id AND e.id = %s "
2808
                     " ORDER BY m.id ")
2809
            cursor.execute(query, (id_,))
2810
            rows = cursor.fetchall()
2811
2812
            meter_result = list()
2813
            if rows is not None and len(rows) > 0:
2814
                for row in rows:
2815
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2816
                              "energy_category": energy_category_dict.get(row[3], None),
2817
                              "is_output": bool(row[4])}
2818
                    meter_result.append(result)
2819
                meta_result['meters'] = meter_result
2820
2821
            query = (" SELECT id, name, uuid "
2822
                     " FROM tbl_energy_categories ")
2823
            cursor.execute(query)
2824
            rows_energy_categories = cursor.fetchall()
2825
2826
            energy_category_dict = dict()
2827
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2828
                for row in rows_energy_categories:
2829
                    energy_category_dict[row[0]] = {"id": row[0],
2830
                                                    "name": row[1],
2831
                                                    "uuid": row[2]}
2832
2833
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
2834
                     " FROM tbl_combined_equipments e, tbl_combined_equipments_offline_meters em, tbl_offline_meters m "
2835
                     " WHERE em.combined_equipment_id = e.id AND m.id = em.offline_meter_id AND e.id = %s "
2836
                     " ORDER BY m.id ")
2837
            cursor.execute(query, (id_,))
2838
            rows = cursor.fetchall()
2839
2840
            offlinemeter_result = list()
2841
            if rows is not None and len(rows) > 0:
2842
                for row in rows:
2843
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2844
                              "energy_category": energy_category_dict.get(row[3], None),
2845
                              "is_output": bool(row[4])}
2846
                    offlinemeter_result.append(result)
2847
                meta_result['offline_meters'] = offlinemeter_result
2848
2849
            query = (" SELECT id, name, uuid "
2850
                     " FROM tbl_energy_categories ")
2851
            cursor.execute(query)
2852
            rows_energy_categories = cursor.fetchall()
2853
2854
            energy_category_dict = dict()
2855
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2856
                for row in rows_energy_categories:
2857
                    energy_category_dict[row[0]] = {"id": row[0],
2858
                                                    "name": row[1],
2859
                                                    "uuid": row[2]}
2860
2861
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
2862
                     " FROM tbl_combined_equipments e, tbl_combined_equipments_virtual_meters em, tbl_virtual_meters m "
2863
                     " WHERE em.combined_equipment_id = e.id AND m.id = em.virtual_meter_id AND e.id = %s "
2864
                     " ORDER BY m.id ")
2865
            cursor.execute(query, (id_,))
2866
            rows = cursor.fetchall()
2867
2868
            virtualmeter_result = list()
2869
            if rows is not None and len(rows) > 0:
2870
                for row in rows:
2871
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2872
                              "energy_category": energy_category_dict.get(row[3], None),
2873
                              "is_output": bool(row[4])}
2874
                    virtualmeter_result.append(result)
2875
                meta_result['virtual_meters'] = virtualmeter_result
2876
2877
            query = (" SELECT id, name "
2878
                     " FROM tbl_points ")
2879
            cursor.execute(query)
2880
            rows_points = cursor.fetchall()
2881
2882
            point_dict = dict()
2883
            if rows_points is not None and len(rows_points) > 0:
2884
                for row in rows_points:
2885
                    point_dict[row[0]] = {"id": row[0],
2886
                                          "name": row[1]}
2887
2888
            query = (" SELECT id, name, uuid "
2889
                     " FROM tbl_meters ")
2890
            cursor.execute(query)
2891
            rows_meters = cursor.fetchall()
2892
2893
            meter_dict = dict()
2894
            if rows_meters is not None and len(rows_meters) > 0:
2895
                for row in rows_meters:
2896
                    meter_dict[row[2]] = {"type": 'meter',
2897
                                          "id": row[0],
2898
                                          "name": row[1],
2899
                                          "uuid": row[2]}
2900
2901
            query = (" SELECT id, name, uuid "
2902
                     " FROM tbl_offline_meters ")
2903
            cursor.execute(query)
2904
            rows_offline_meters = cursor.fetchall()
2905
2906
            offline_meter_dict = dict()
2907
            if rows_offline_meters is not None and len(rows_offline_meters) > 0:
2908
                for row in rows_offline_meters:
2909
                    offline_meter_dict[row[2]] = {"type": 'offline_meter',
2910
                                                  "id": row[0],
2911
                                                  "name": row[1],
2912
                                                  "uuid": row[2]}
2913
2914
            query = (" SELECT id, name, uuid "
2915
                     " FROM tbl_virtual_meters ")
2916
            cursor.execute(query)
2917
            rows_virtual_meters = cursor.fetchall()
2918
2919
            virtual_meter_dict = dict()
2920
            if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
2921
                for row in rows_virtual_meters:
2922
                    virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
2923
                                                  "id": row[0],
2924
                                                  "name": row[1],
2925
                                                  "uuid": row[2]}
2926
2927
            query = (" SELECT id, name, parameter_type, "
2928
                     "        constant, point_id, numerator_meter_uuid, denominator_meter_uuid "
2929
                     " FROM tbl_combined_equipments_parameters "
2930
                     " WHERE combined_equipment_id = %s "
2931
                     " ORDER BY id ")
2932
            cursor.execute(query, (id_,))
2933
            rows_parameters = cursor.fetchall()
2934
2935
            parameter_result = list()
2936 View Code Duplication
            if rows_parameters is not None and len(rows_parameters) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2937
                for row in rows_parameters:
2938
                    constant = None
2939
                    point = None
2940
                    numerator_meter = None
2941
                    denominator_meter = None
2942
                    if row[2] == 'point':
2943
                        point = point_dict.get(row[4], None)
2944
                        constant = None
2945
                        numerator_meter = None
2946
                        denominator_meter = None
2947
                    elif row[2] == 'constant':
2948
                        constant = row[3]
2949
                        point = None
2950
                        numerator_meter = None
2951
                        denominator_meter = None
2952
                    elif row[2] == 'fraction':
2953
                        constant = None
2954
                        point = None
2955
                        # find numerator meter by uuid
2956
                        numerator_meter = meter_dict.get(row[5], None)
2957
                        if numerator_meter is None:
2958
                            numerator_meter = virtual_meter_dict.get(row[5], None)
2959
                        if numerator_meter is None:
2960
                            numerator_meter = offline_meter_dict.get(row[5], None)
2961
                        # find denominator meter by uuid
2962
                        denominator_meter = meter_dict.get(row[6], None)
2963
                        if denominator_meter is None:
2964
                            denominator_meter = virtual_meter_dict.get(row[6], None)
2965
                        if denominator_meter is None:
2966
                            denominator_meter = offline_meter_dict.get(row[6], None)
2967
2968
                    result = {"id": row[0],
2969
                              "name": row[1],
2970
                              "parameter_type": row[2],
2971
                              "constant": constant,
2972
                              "point": point,
2973
                              "numerator_meter": numerator_meter,
2974
                              "denominator_meter": denominator_meter}
2975
                    parameter_result.append(result)
2976
                meta_result['parameters'] = parameter_result
2977
2978
        cursor.close()
2979
        cnx.close()
2980
        resp.text = json.dumps(meta_result)
2981
2982
2983
class CombinedEquipmentImport:
2984
    def __init__(self):
2985
        """ Initializes CombinedEquipmentImport"""
2986
        pass
2987
2988
    @staticmethod
2989
    def on_options(req, resp):
2990
        _ = req
2991
        resp.status = falcon.HTTP_200
2992
2993
    @staticmethod
2994
    @user_logger
2995
    def on_post(req, resp):
2996
        """Handles POST requests"""
2997
        admin_control(req)
2998
        try:
2999
            raw_json = req.stream.read().decode('utf-8')
3000
        except UnicodeDecodeError as ex:
3001
            print("Failed to decode request")
3002
            raise falcon.HTTPError(status=falcon.HTTP_400,
3003
                                   title='API.BAD_REQUEST',
3004
                                   description='API.INVALID_ENCODING')
3005
        except Exception as ex:
3006
            print("Unexpected error reading request stream")
3007
            raise falcon.HTTPError(status=falcon.HTTP_400,
3008
                                   title='API.BAD_REQUEST',
3009
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
3010
3011
        new_values = json.loads(raw_json)
3012
3013
        if 'name' not in new_values.keys() or \
3014
                not isinstance(new_values['name'], str) or \
3015
                len(str.strip(new_values['name'])) == 0:
3016
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3017
                                   description='API.INVALID_COMBINED_EQUIPMENT_NAME')
3018
        name = str.strip(new_values['name'])
3019
3020
        if 'is_input_counted' not in new_values.keys() or \
3021
                not isinstance(new_values['is_input_counted'], bool):
3022
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3023
                                   description='API.INVALID_IS_INPUT_COUNTED_VALUE')
3024
        is_input_counted = new_values['is_input_counted']
3025
3026
        if 'is_output_counted' not in new_values.keys() or \
3027
                not isinstance(new_values['is_output_counted'], bool):
3028
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3029
                                   description='API.INVALID_IS_OUTPUT_COUNTED_VALUE')
3030
        is_output_counted = new_values['is_output_counted']
3031
3032
        if 'id' not in new_values['cost_center'].keys() or \
3033
                not isinstance(new_values['cost_center']['id'], int) or \
3034
                new_values['cost_center']['id'] <= 0:
3035
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3036
                                   description='API.INVALID_COST_CENTER_ID')
3037
        cost_center_id = new_values['cost_center']['id']
3038
3039
        if 'svg' in new_values.keys() and \
3040
                'id' in new_values['svg'].keys() and \
3041
                isinstance(new_values['svg']['id'], int) and \
3042
                new_values['svg']['id'] > 0:
3043
            svg_id = new_values['svg']['id']
3044
        else:
3045
            svg_id = None
3046
3047
        if 'camera_url' in new_values.keys() and \
3048
                new_values['camera_url'] is not None and \
3049
                len(str(new_values['camera_url'])) > 0:
3050
            camera_url = str.strip(new_values['camera_url'])
3051
        else:
3052
            camera_url = None
3053
3054
        if 'description' in new_values.keys() and \
3055
                new_values['description'] is not None and \
3056
                len(str(new_values['description'])) > 0:
3057
            description = str.strip(new_values['description'])
3058
        else:
3059
            description = None
3060
3061
        cnx = mysql.connector.connect(**config.myems_system_db)
3062
        cursor = cnx.cursor()
3063
3064
        cursor.execute(" SELECT name "
3065
                       " FROM tbl_combined_equipments "
3066
                       " WHERE name = %s ", (name,))
3067
        if cursor.fetchone() is not None:
3068
            cursor.close()
3069
            cnx.close()
3070
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3071
                                   description='API.COMBINED_EQUIPMENT_NAME_IS_ALREADY_IN_USE')
3072
3073
        if cost_center_id is not None:
3074
            cursor.execute(" SELECT name "
3075
                           " FROM tbl_cost_centers "
3076
                           " WHERE id = %s ",
3077
                           (new_values['cost_center']['id'],))
3078
            row = cursor.fetchone()
3079
            if row is None:
3080
                cursor.close()
3081
                cnx.close()
3082
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3083
                                       description='API.COST_CENTER_NOT_FOUND')
3084
        if svg_id is not None:
3085
            cursor.execute(" SELECT name "
3086
                           " FROM tbl_svgs "
3087
                           " WHERE id = %s ",
3088
                           (svg_id,))
3089
            row = cursor.fetchone()
3090
            if row is None:
3091
                cursor.close()
3092
                cnx.close()
3093
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3094
                                       description='API.SVG_NOT_FOUND')
3095
3096
        add_values = (" INSERT INTO tbl_combined_equipments "
3097
                      "    (name, uuid, is_input_counted, is_output_counted, "
3098
                      "     cost_center_id, svg_id, camera_url, description) "
3099
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
3100
        cursor.execute(add_values, (name,
3101
                                    str(uuid.uuid4()),
3102
                                    is_input_counted,
3103
                                    is_output_counted,
3104
                                    cost_center_id,
3105
                                    svg_id,
3106
                                    camera_url,
3107
                                    description))
3108
        new_id = cursor.lastrowid
3109
        if new_values['equipments'] is not None and len(new_values['equipments']) > 0:
3110
            for equipment in new_values['equipments']:
3111
                cursor.execute(" SELECT name "
3112
                               " FROM tbl_equipments "
3113
                               " WHERE id = %s ", (equipment['id'],))
3114
                if cursor.fetchone() is None:
3115
                    cursor.close()
3116
                    cnx.close()
3117
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3118
                                           description='API.EQUIPMENT_NOT_FOUND')
3119
3120
                query = (" SELECT id "
3121
                         " FROM tbl_combined_equipments_equipments "
3122
                         " WHERE combined_equipment_id = %s AND equipment_id = %s")
3123
                cursor.execute(query, (new_id, equipment['id'],))
3124
                if cursor.fetchone() is not None:
3125
                    cursor.close()
3126
                    cnx.close()
3127
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3128
                                           description='API.COMBINED_EQUIPMENT_EQUIPMENT_RELATION_EXISTS')
3129
3130
                add_row = (" INSERT INTO tbl_combined_equipments_equipments (combined_equipment_id, equipment_id) "
3131
                           " VALUES (%s, %s) ")
3132
                cursor.execute(add_row, (new_id, equipment['id'],))
3133
        if new_values['commands'] is not None and len(new_values['commands']) > 0:
3134
            for command in new_values['commands']:
3135
                cursor.execute(" SELECT name "
3136
                               " FROM tbl_commands "
3137
                               " WHERE id = %s ", (command['id'],))
3138
                if cursor.fetchone() is None:
3139
                    cursor.close()
3140
                    cnx.close()
3141
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3142
                                           description='API.COMMAND_NOT_FOUND')
3143
3144
                query = (" SELECT id "
3145
                         " FROM tbl_combined_equipments_commands "
3146
                         " WHERE combined_equipment_id = %s AND command_id = %s")
3147
                cursor.execute(query, (new_id, command['id'],))
3148
                if cursor.fetchone() is not None:
3149
                    cursor.close()
3150
                    cnx.close()
3151
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3152
                                           description='API.COMBINED_EQUIPMENT_COMMAND_RELATION_EXISTS')
3153
3154
                add_row = (" INSERT INTO tbl_combined_equipments_commands (combined_equipment_id, command_id) "
3155
                           " VALUES (%s, %s) ")
3156
                cursor.execute(add_row, (new_id, command['id'],))
3157
        if new_values['meters'] is not None and len(new_values['meters']) > 0:
3158
            for meter in new_values['meters']:
3159
                cursor.execute(" SELECT name "
3160
                               " FROM tbl_meters "
3161
                               " WHERE id = %s ", (meter['id'],))
3162
                if cursor.fetchone() is None:
3163
                    cursor.close()
3164
                    cnx.close()
3165
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3166
                                           description='API.METER_NOT_FOUND')
3167
3168
                query = (" SELECT id "
3169
                         " FROM tbl_combined_equipments_meters "
3170
                         " WHERE combined_equipment_id = %s AND meter_id = %s")
3171
                cursor.execute(query, (new_id, meter['id'],))
3172
                if cursor.fetchone() is not None:
3173
                    cursor.close()
3174
                    cnx.close()
3175
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3176
                                           description='API.COMBINED_EQUIPMENT_METER_RELATION_EXISTS')
3177
3178
                add_row = (" INSERT INTO tbl_combined_equipments_meters (combined_equipment_id, meter_id, is_output ) "
3179
                           " VALUES (%s, %s, %s) ")
3180
                cursor.execute(add_row, (new_id, meter['id'], meter['is_output']))
3181
        if new_values['offline_meters'] is not None and len(new_values['offline_meters']) > 0:
3182
            for offline_meter in new_values['offline_meters']:
3183
                cursor.execute(" SELECT name "
3184
                               " FROM tbl_offline_meters "
3185
                               " WHERE id = %s ", (offline_meter['id'],))
3186
                if cursor.fetchone() is None:
3187
                    cursor.close()
3188
                    cnx.close()
3189
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3190
                                           description='API.OFFLINE_METER_NOT_FOUND')
3191
3192
                query = (" SELECT id "
3193
                         " FROM tbl_combined_equipments_offline_meters "
3194
                         " WHERE combined_equipment_id = %s AND offline_meter_id = %s")
3195
                cursor.execute(query, (new_id, offline_meter['id'],))
3196
                if cursor.fetchone() is not None:
3197
                    cursor.close()
3198
                    cnx.close()
3199
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3200
                                           description='API.COMBINED_EQUIPMENT_OFFLINE_METER_RELATION_EXISTS')
3201
3202
                add_row = (" INSERT INTO tbl_combined_equipments_offline_meters "
3203
                           " (combined_equipment_id, offline_meter_id, is_output ) "
3204
                           " VALUES (%s, %s, %s) ")
3205
                cursor.execute(add_row, (new_id, offline_meter['id'], offline_meter['is_output']))
3206
        if new_values['virtual_meters'] is not None and len(new_values['virtual_meters']) > 0:
3207
            for virtual_meter in new_values['virtual_meters']:
3208
                cursor.execute(" SELECT name "
3209
                               " FROM tbl_virtual_meters "
3210
                               " WHERE id = %s ", (virtual_meter['id'],))
3211
                if cursor.fetchone() is None:
3212
                    cursor.close()
3213
                    cnx.close()
3214
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3215
                                           description='API.VIRTUAL_METER_NOT_FOUND')
3216
3217
                query = (" SELECT id "
3218
                         " FROM tbl_combined_equipments_virtual_meters "
3219
                         " WHERE combined_equipment_id = %s AND virtual_meter_id = %s")
3220
                cursor.execute(query, (new_id, virtual_meter['id'],))
3221
                if cursor.fetchone() is not None:
3222
                    cursor.close()
3223
                    cnx.close()
3224
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3225
                                           description='API.COMBINED_EQUIPMENT_VIRTUAL_METER_RELATION_EXISTS')
3226
3227
                add_row = (" INSERT INTO tbl_combined_equipments_virtual_meters "
3228
                           " (combined_equipment_id, virtual_meter_id, is_output ) "
3229
                           " VALUES (%s, %s, %s) ")
3230
                cursor.execute(add_row, (new_id, virtual_meter['id'], virtual_meter['is_output']))
3231 View Code Duplication
        if new_values['parameters'] is not None and len(new_values['parameters']) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3232
            for parameters in new_values['parameters']:
3233
                cursor.execute(" SELECT name "
3234
                               " FROM tbl_combined_equipments_parameters "
3235
                               " WHERE name = %s AND combined_equipment_id = %s ", (parameters['name'], new_id))
3236
                if cursor.fetchone() is not None:
3237
                    cursor.close()
3238
                    cnx.close()
3239
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3240
                                           description='API.COMBINED_EQUIPMENT_PARAMETER_NAME_IS_ALREADY_IN_USE')
3241
                if 'point' in parameters:
3242
                    if parameters['point'] is None:
3243
                        point_id = None
3244
                    elif parameters['point']['id'] is not None and \
3245
                            parameters['point']['id'] <= 0:
3246
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3247
                                               description='API.INVALID_POINT_ID')
3248
                    else:
3249
                        point_id = parameters['point']['id']
3250
                else:
3251
                    point_id = None
3252
                numerator_meter_uuid = None
3253
                if 'numerator_meter' in parameters:
3254
                    if parameters['numerator_meter'] is not None and \
3255
                            isinstance(parameters['numerator_meter']['uuid'], str) and \
3256
                            len(str.strip(parameters['numerator_meter']['uuid'])) > 0:
3257
                        numerator_meter_uuid = str.strip(parameters['numerator_meter']['uuid'])
3258
3259
                denominator_meter_uuid = None
3260
                if 'denominator_meter' in parameters:
3261
                    if parameters['denominator_meter'] is not None and \
3262
                            isinstance(parameters['denominator_meter']['uuid'], str) and \
3263
                            len(str.strip(parameters['denominator_meter']['uuid'])) > 0:
3264
                        denominator_meter_uuid = str.strip(parameters['denominator_meter']['uuid'])
3265
3266
                # validate by parameter type
3267
                if parameters['parameter_type'] == 'point':
3268
                    if point_id is None:
3269
                        cursor.close()
3270
                        cnx.close()
3271
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3272
                                               description='API.INVALID_POINT_ID')
3273
3274
                    query = (" SELECT id, name "
3275
                             " FROM tbl_points "
3276
                             " WHERE id = %s ")
3277
                    cursor.execute(query, (point_id,))
3278
                    if cursor.fetchone() is None:
3279
                        cursor.close()
3280
                        cnx.close()
3281
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3282
                                               description='API.POINT_NOT_FOUND')
3283
3284
                elif parameters['parameter_type'] == 'constant':
3285
                    if parameters['constant'] is None:
3286
                        cursor.close()
3287
                        cnx.close()
3288
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3289
                                               description='API.INVALID_CONSTANT_VALUE')
3290
3291
                elif parameters['parameter_type'] == 'fraction':
3292
3293
                    query = (" SELECT id, name, uuid "
3294
                             " FROM tbl_meters ")
3295
                    cursor.execute(query)
3296
                    rows_meters = cursor.fetchall()
3297
3298
                    meter_dict = dict()
3299
                    if rows_meters is not None and len(rows_meters) > 0:
3300
                        for row in rows_meters:
3301
                            meter_dict[row[2]] = {"type": 'meter',
3302
                                                  "id": row[0],
3303
                                                  "name": row[1],
3304
                                                  "uuid": row[2]}
3305
3306
                    query = (" SELECT id, name, uuid "
3307
                             " FROM tbl_offline_meters ")
3308
                    cursor.execute(query)
3309
                    rows_offline_meters = cursor.fetchall()
3310
3311
                    offline_meter_dict = dict()
3312
                    if rows_offline_meters is not None and len(rows_offline_meters) > 0:
3313
                        for row in rows_offline_meters:
3314
                            offline_meter_dict[row[2]] = {"type": 'offline_meter',
3315
                                                          "id": row[0],
3316
                                                          "name": row[1],
3317
                                                          "uuid": row[2]}
3318
3319
                    query = (" SELECT id, name, uuid "
3320
                             " FROM tbl_virtual_meters ")
3321
                    cursor.execute(query)
3322
                    rows_virtual_meters = cursor.fetchall()
3323
3324
                    virtual_meter_dict = dict()
3325
                    if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
3326
                        for row in rows_virtual_meters:
3327
                            virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
3328
                                                          "id": row[0],
3329
                                                          "name": row[1],
3330
                                                          "uuid": row[2]}
3331
3332
                    # validate numerator meter uuid
3333
                    if meter_dict.get(numerator_meter_uuid) is None and \
3334
                            virtual_meter_dict.get(numerator_meter_uuid) is None and \
3335
                            offline_meter_dict.get(numerator_meter_uuid) is None:
3336
                        cursor.close()
3337
                        cnx.close()
3338
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3339
                                               description='API.INVALID_NUMERATOR_METER_UUID')
3340
3341
                    # validate denominator meter uuid
3342
                    if denominator_meter_uuid is None:
3343
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3344
                                               description='API.INVALID_DENOMINATOR_METER_UUID')
3345
3346
                    if denominator_meter_uuid == numerator_meter_uuid:
3347
                        cursor.close()
3348
                        cnx.close()
3349
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3350
                                               description='API.INVALID_DENOMINATOR_METER_UUID')
3351
3352
                    if denominator_meter_uuid not in meter_dict and \
3353
                            denominator_meter_uuid not in virtual_meter_dict and \
3354
                            denominator_meter_uuid not in offline_meter_dict:
3355
                        cursor.close()
3356
                        cnx.close()
3357
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3358
                                               description='API.INVALID_DENOMINATOR_METER_UUID')
3359
3360
                add_values = (" INSERT INTO tbl_combined_equipments_parameters "
3361
                              "    (combined_equipment_id, name, parameter_type, constant, "
3362
                              "     point_id, numerator_meter_uuid, denominator_meter_uuid) "
3363
                              " VALUES (%s, %s, %s, %s, %s, %s, %s) ")
3364
                cursor.execute(add_values, (new_id,
3365
                                            parameters['name'],
3366
                                            parameters['parameter_type'],
3367
                                            parameters['constant'],
3368
                                            point_id,
3369
                                            numerator_meter_uuid,
3370
                                            denominator_meter_uuid))
3371
        cnx.commit()
3372
        cursor.close()
3373
        cnx.close()
3374
3375
        resp.status = falcon.HTTP_201
3376
        resp.location = '/combinedequipments/' + str(new_id)
3377
3378
3379
class CombinedEquipmentClone:
3380
    def __init__(self):
3381
        pass
3382
3383
    @staticmethod
3384
    def on_options(req, resp, id_):
3385
        _ = req
3386
        resp.status = falcon.HTTP_200
3387
        _ = id_
3388
3389
    @staticmethod
3390
    @user_logger
3391
    def on_post(req, resp, id_):
3392
        """Handles POST requests"""
3393
        admin_control(req)
3394
        if not id_.isdigit() or int(id_) <= 0:
3395
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3396
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
3397
3398
        cnx = mysql.connector.connect(**config.myems_system_db)
3399
        cursor = cnx.cursor()
3400
3401
        query = (" SELECT id, name, uuid "
3402
                 " FROM tbl_cost_centers ")
3403
        cursor.execute(query)
3404
        rows_cost_centers = cursor.fetchall()
3405
3406
        cost_center_dict = dict()
3407
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
3408
            for row in rows_cost_centers:
3409
                cost_center_dict[row[0]] = {"id": row[0],
3410
                                            "name": row[1],
3411
                                            "uuid": row[2]}
3412
3413
        query = (" SELECT id, name, uuid, "
3414
                 "        is_input_counted, is_output_counted, "
3415
                 "        cost_center_id, svg_id, camera_url, description "
3416
                 " FROM tbl_combined_equipments "
3417
                 " WHERE id = %s ")
3418
        cursor.execute(query, (id_,))
3419
        row = cursor.fetchone()
3420
3421
        if row is None:
3422
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3423
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
3424
        else:
3425
            meta_result = {"id": row[0],
3426
                           "name": row[1],
3427
                           "uuid": row[2],
3428
                           "is_input_counted": bool(row[3]),
3429
                           "is_output_counted": bool(row[4]),
3430
                           "cost_center": cost_center_dict.get(row[5], None),
3431
                           "svg_id": row[6],
3432
                           "camera_url": row[7],
3433
                           "description": row[8],
3434
                           "equipments": None,
3435
                           "commands": None,
3436
                           "meters": None,
3437
                           "offline_meters": None,
3438
                           "virtual_meters": None,
3439
                           "parameters": None
3440
                           }
3441
            query = (" SELECT e.id, e.name, e.uuid "
3442
                     " FROM tbl_combined_equipments c, tbl_combined_equipments_equipments ce, tbl_equipments e "
3443
                     " WHERE ce.combined_equipment_id = c.id AND e.id = ce.equipment_id AND c.id = %s "
3444
                     " ORDER BY e.id ")
3445
            cursor.execute(query, (id_,))
3446
            rows = cursor.fetchall()
3447
3448
            equipment_result = list()
3449
            if rows is not None and len(rows) > 0:
3450
                for row in rows:
3451
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
3452
                    equipment_result.append(result)
3453
                meta_result['equipments'] = equipment_result
3454
3455
            query = (" SELECT c.id, c.name, c.uuid "
3456
                     " FROM tbl_combined_equipments ce, tbl_combined_equipments_commands cec, tbl_commands c "
3457
                     " WHERE cec.combined_equipment_id = ce.id AND c.id = cec.command_id AND ce.id = %s "
3458
                     " ORDER BY c.id ")
3459
            cursor.execute(query, (id_,))
3460
            rows = cursor.fetchall()
3461
3462
            command_result = list()
3463
            if rows is not None and len(rows) > 0:
3464
                for row in rows:
3465
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
3466
                    command_result.append(result)
3467
                meta_result['commands'] = command_result
3468
3469
            query = (" SELECT id, name, uuid "
3470
                     " FROM tbl_energy_categories ")
3471
            cursor.execute(query)
3472
            rows_energy_categories = cursor.fetchall()
3473
3474
            energy_category_dict = dict()
3475
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
3476
                for row in rows_energy_categories:
3477
                    energy_category_dict[row[0]] = {"id": row[0],
3478
                                                    "name": row[1],
3479
                                                    "uuid": row[2]}
3480
3481
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
3482
                     " FROM tbl_combined_equipments e, tbl_combined_equipments_meters em, tbl_meters m "
3483
                     " WHERE em.combined_equipment_id = e.id AND m.id = em.meter_id AND e.id = %s "
3484
                     " ORDER BY m.id ")
3485
            cursor.execute(query, (id_,))
3486
            rows = cursor.fetchall()
3487
3488
            meter_result = list()
3489
            if rows is not None and len(rows) > 0:
3490
                for row in rows:
3491
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
3492
                              "energy_category": energy_category_dict.get(row[3], None),
3493
                              "is_output": bool(row[4])}
3494
                    meter_result.append(result)
3495
                meta_result['meters'] = meter_result
3496
3497
            query = (" SELECT id, name, uuid "
3498
                     " FROM tbl_energy_categories ")
3499
            cursor.execute(query)
3500
            rows_energy_categories = cursor.fetchall()
3501
3502
            energy_category_dict = dict()
3503
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
3504
                for row in rows_energy_categories:
3505
                    energy_category_dict[row[0]] = {"id": row[0],
3506
                                                    "name": row[1],
3507
                                                    "uuid": row[2]}
3508
3509
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
3510
                     " FROM tbl_combined_equipments e, tbl_combined_equipments_offline_meters em, tbl_offline_meters m "
3511
                     " WHERE em.combined_equipment_id = e.id AND m.id = em.offline_meter_id AND e.id = %s "
3512
                     " ORDER BY m.id ")
3513
            cursor.execute(query, (id_,))
3514
            rows = cursor.fetchall()
3515
3516
            offlinemeter_result = list()
3517
            if rows is not None and len(rows) > 0:
3518
                for row in rows:
3519
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
3520
                              "energy_category": energy_category_dict.get(row[3], None),
3521
                              "is_output": bool(row[4])}
3522
                    offlinemeter_result.append(result)
3523
                meta_result['offline_meters'] = offlinemeter_result
3524
3525
            query = (" SELECT id, name, uuid "
3526
                     " FROM tbl_energy_categories ")
3527
            cursor.execute(query)
3528
            rows_energy_categories = cursor.fetchall()
3529
3530
            energy_category_dict = dict()
3531
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
3532
                for row in rows_energy_categories:
3533
                    energy_category_dict[row[0]] = {"id": row[0],
3534
                                                    "name": row[1],
3535
                                                    "uuid": row[2]}
3536
3537
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id, em.is_output "
3538
                     " FROM tbl_combined_equipments e, tbl_combined_equipments_virtual_meters em, tbl_virtual_meters m "
3539
                     " WHERE em.combined_equipment_id = e.id AND m.id = em.virtual_meter_id AND e.id = %s "
3540
                     " ORDER BY m.id ")
3541
            cursor.execute(query, (id_,))
3542
            rows = cursor.fetchall()
3543
3544
            virtualmeter_result = list()
3545
            if rows is not None and len(rows) > 0:
3546
                for row in rows:
3547
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
3548
                              "energy_category": energy_category_dict.get(row[3], None),
3549
                              "is_output": bool(row[4])}
3550
                    virtualmeter_result.append(result)
3551
                meta_result['virtual_meters'] = virtualmeter_result
3552
3553
            query = (" SELECT id, name "
3554
                     " FROM tbl_points ")
3555
            cursor.execute(query)
3556
            rows_points = cursor.fetchall()
3557
3558
            point_dict = dict()
3559
            if rows_points is not None and len(rows_points) > 0:
3560
                for row in rows_points:
3561
                    point_dict[row[0]] = {"id": row[0],
3562
                                          "name": row[1]}
3563
3564
            query = (" SELECT id, name, uuid "
3565
                     " FROM tbl_meters ")
3566
            cursor.execute(query)
3567
            rows_meters = cursor.fetchall()
3568
3569
            meter_dict = dict()
3570
            if rows_meters is not None and len(rows_meters) > 0:
3571
                for row in rows_meters:
3572
                    meter_dict[row[2]] = {"type": 'meter',
3573
                                          "id": row[0],
3574
                                          "name": row[1],
3575
                                          "uuid": row[2]}
3576
3577
            query = (" SELECT id, name, uuid "
3578
                     " FROM tbl_offline_meters ")
3579
            cursor.execute(query)
3580
            rows_offline_meters = cursor.fetchall()
3581
3582
            offline_meter_dict = dict()
3583
            if rows_offline_meters is not None and len(rows_offline_meters) > 0:
3584
                for row in rows_offline_meters:
3585
                    offline_meter_dict[row[2]] = {"type": 'offline_meter',
3586
                                                  "id": row[0],
3587
                                                  "name": row[1],
3588
                                                  "uuid": row[2]}
3589
3590
            query = (" SELECT id, name, uuid "
3591
                     " FROM tbl_virtual_meters ")
3592
            cursor.execute(query)
3593
            rows_virtual_meters = cursor.fetchall()
3594
3595
            virtual_meter_dict = dict()
3596
            if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
3597
                for row in rows_virtual_meters:
3598
                    virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
3599
                                                  "id": row[0],
3600
                                                  "name": row[1],
3601
                                                  "uuid": row[2]}
3602
3603
            query = (" SELECT id, name, parameter_type, "
3604
                     "        constant, point_id, numerator_meter_uuid, denominator_meter_uuid "
3605
                     " FROM tbl_combined_equipments_parameters "
3606
                     " WHERE combined_equipment_id = %s "
3607
                     " ORDER BY id ")
3608
            cursor.execute(query, (id_,))
3609
            rows_parameters = cursor.fetchall()
3610
3611
            parameter_result = list()
3612 View Code Duplication
            if rows_parameters is not None and len(rows_parameters) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3613
                for row in rows_parameters:
3614
                    constant = None
3615
                    point = None
3616
                    numerator_meter = None
3617
                    denominator_meter = None
3618
                    if row[2] == 'point':
3619
                        point = point_dict.get(row[4], None)
3620
                        constant = None
3621
                        numerator_meter = None
3622
                        denominator_meter = None
3623
                    elif row[2] == 'constant':
3624
                        constant = row[3]
3625
                        point = None
3626
                        numerator_meter = None
3627
                        denominator_meter = None
3628
                    elif row[2] == 'fraction':
3629
                        constant = None
3630
                        point = None
3631
                        # find numerator meter by uuid
3632
                        numerator_meter = meter_dict.get(row[5], None)
3633
                        if numerator_meter is None:
3634
                            numerator_meter = virtual_meter_dict.get(row[5], None)
3635
                        if numerator_meter is None:
3636
                            numerator_meter = offline_meter_dict.get(row[5], None)
3637
                        # find denominator meter by uuid
3638
                        denominator_meter = meter_dict.get(row[6], None)
3639
                        if denominator_meter is None:
3640
                            denominator_meter = virtual_meter_dict.get(row[6], None)
3641
                        if denominator_meter is None:
3642
                            denominator_meter = offline_meter_dict.get(row[6], None)
3643
3644
                    result = {"id": row[0],
3645
                              "name": row[1],
3646
                              "parameter_type": row[2],
3647
                              "constant": constant,
3648
                              "point": point,
3649
                              "numerator_meter": numerator_meter,
3650
                              "denominator_meter": denominator_meter}
3651
                    parameter_result.append(result)
3652
                meta_result['parameters'] = parameter_result
3653
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
3654
            if config.utc_offset[0] == '-':
3655
                timezone_offset = -timezone_offset
3656
            new_name = (str.strip(meta_result['name']) +
3657
                        (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
3658
            add_values = (" INSERT INTO tbl_combined_equipments "
3659
                          "    (name, uuid, is_input_counted, is_output_counted, "
3660
                          "     cost_center_id, svg_id, camera_url, description) "
3661
                          " VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
3662
            cursor.execute(add_values, (new_name,
3663
                                        str(uuid.uuid4()),
3664
                                        meta_result['is_input_counted'],
3665
                                        meta_result['is_output_counted'],
3666
                                        meta_result['cost_center']['id'],
3667
                                        meta_result['svg_id'],
3668
                                        meta_result['camera_url'],
3669
                                        meta_result['description']))
3670
            new_id = cursor.lastrowid
3671
            if meta_result['equipments'] is not None and len(meta_result['equipments']) > 0:
3672
                for equipment in meta_result['equipments']:
3673
                    cursor.execute(" SELECT name "
3674
                                   " FROM tbl_equipments "
3675
                                   " WHERE id = %s ", (equipment['id'],))
3676
                    if cursor.fetchone() is None:
3677
                        cursor.close()
3678
                        cnx.close()
3679
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3680
                                               description='API.EQUIPMENT_NOT_FOUND')
3681
3682
                    query = (" SELECT id "
3683
                             " FROM tbl_combined_equipments_equipments "
3684
                             " WHERE combined_equipment_id = %s AND equipment_id = %s")
3685
                    cursor.execute(query, (new_id, equipment['id'],))
3686
                    if cursor.fetchone() is not None:
3687
                        cursor.close()
3688
                        cnx.close()
3689
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3690
                                               description='API.COMBINED_EQUIPMENT_EQUIPMENT_RELATION_EXISTS')
3691
3692
                    add_row = (" INSERT INTO tbl_combined_equipments_equipments (combined_equipment_id, equipment_id) "
3693
                               " VALUES (%s, %s) ")
3694
                    cursor.execute(add_row, (new_id, equipment['id'],))
3695
            if meta_result['commands'] is not None and len(meta_result['commands']) > 0:
3696
                for command in meta_result['commands']:
3697
                    cursor.execute(" SELECT name "
3698
                                   " FROM tbl_commands "
3699
                                   " WHERE id = %s ", (command['id'],))
3700
                    if cursor.fetchone() is None:
3701
                        cursor.close()
3702
                        cnx.close()
3703
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3704
                                               description='API.COMMAND_NOT_FOUND')
3705
3706
                    query = (" SELECT id "
3707
                             " FROM tbl_combined_equipments_commands "
3708
                             " WHERE combined_equipment_id = %s AND command_id = %s")
3709
                    cursor.execute(query, (new_id, command['id'],))
3710
                    if cursor.fetchone() is not None:
3711
                        cursor.close()
3712
                        cnx.close()
3713
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3714
                                               description='API.COMBINED_EQUIPMENT_COMMAND_RELATION_EXISTS')
3715
3716
                    add_row = (" INSERT INTO tbl_combined_equipments_commands (combined_equipment_id, command_id) "
3717
                               " VALUES (%s, %s) ")
3718
                    cursor.execute(add_row, (new_id, command['id'],))
3719
            if meta_result['meters'] is not None and len(meta_result['meters']) > 0:
3720
                for meter in meta_result['meters']:
3721
                    cursor.execute(" SELECT name "
3722
                                   " FROM tbl_meters "
3723
                                   " WHERE id = %s ", (meter['id'],))
3724
                    if cursor.fetchone() is None:
3725
                        cursor.close()
3726
                        cnx.close()
3727
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3728
                                               description='API.METER_NOT_FOUND')
3729
3730
                    query = (" SELECT id "
3731
                             " FROM tbl_combined_equipments_meters "
3732
                             " WHERE combined_equipment_id = %s AND meter_id = %s")
3733
                    cursor.execute(query, (new_id, meter['id'],))
3734
                    if cursor.fetchone() is not None:
3735
                        cursor.close()
3736
                        cnx.close()
3737
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3738
                                               description='API.COMBINED_EQUIPMENT_METER_RELATION_EXISTS')
3739
3740
                    add_row = (
3741
                        " INSERT INTO tbl_combined_equipments_meters (combined_equipment_id, meter_id, is_output ) "
3742
                        " VALUES (%s, %s, %s) ")
3743
                    cursor.execute(add_row, (new_id, meter['id'], meter['is_output']))
3744
            if meta_result['offline_meters'] is not None and len(meta_result['offline_meters']) > 0:
3745
                for offline_meter in meta_result['offline_meters']:
3746
                    cursor.execute(" SELECT name "
3747
                                   " FROM tbl_offline_meters "
3748
                                   " WHERE id = %s ", (offline_meter['id'],))
3749
                    if cursor.fetchone() is None:
3750
                        cursor.close()
3751
                        cnx.close()
3752
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3753
                                               description='API.OFFLINE_METER_NOT_FOUND')
3754
3755
                    query = (" SELECT id "
3756
                             " FROM tbl_combined_equipments_offline_meters "
3757
                             " WHERE combined_equipment_id = %s AND offline_meter_id = %s")
3758
                    cursor.execute(query, (new_id, offline_meter['id'],))
3759
                    if cursor.fetchone() is not None:
3760
                        cursor.close()
3761
                        cnx.close()
3762
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3763
                                               description='API.COMBINED_EQUIPMENT_OFFLINE_METER_RELATION_EXISTS')
3764
3765
                    add_row = (" INSERT INTO tbl_combined_equipments_offline_meters "
3766
                               " (combined_equipment_id, offline_meter_id, is_output ) "
3767
                               " VALUES (%s, %s, %s) ")
3768
                    cursor.execute(add_row, (new_id, offline_meter['id'], offline_meter['is_output']))
3769
            if meta_result['virtual_meters'] is not None and len(meta_result['virtual_meters']) > 0:
3770
                for virtual_meter in meta_result['virtual_meters']:
3771
                    cursor.execute(" SELECT name "
3772
                                   " FROM tbl_virtual_meters "
3773
                                   " WHERE id = %s ", (virtual_meter['id'],))
3774
                    if cursor.fetchone() is None:
3775
                        cursor.close()
3776
                        cnx.close()
3777
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3778
                                               description='API.VIRTUAL_METER_NOT_FOUND')
3779
3780
                    query = (" SELECT id "
3781
                             " FROM tbl_combined_equipments_virtual_meters "
3782
                             " WHERE combined_equipment_id = %s AND virtual_meter_id = %s")
3783
                    cursor.execute(query, (new_id, virtual_meter['id'],))
3784
                    if cursor.fetchone() is not None:
3785
                        cursor.close()
3786
                        cnx.close()
3787
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3788
                                               description='API.COMBINED_EQUIPMENT_VIRTUAL_METER_RELATION_EXISTS')
3789
3790
                    add_row = (" INSERT INTO tbl_combined_equipments_virtual_meters "
3791
                               " (combined_equipment_id, virtual_meter_id, is_output ) "
3792
                               " VALUES (%s, %s, %s) ")
3793
                    cursor.execute(add_row, (new_id, virtual_meter['id'], virtual_meter['is_output']))
3794 View Code Duplication
            if meta_result['parameters'] is not None and len(meta_result['parameters']) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3795
                for parameters in meta_result['parameters']:
3796
                    cursor.execute(" SELECT name "
3797
                                   " FROM tbl_combined_equipments_parameters "
3798
                                   " WHERE name = %s AND combined_equipment_id = %s ", (parameters['name'], new_id))
3799
                    if cursor.fetchone() is not None:
3800
                        cursor.close()
3801
                        cnx.close()
3802
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3803
                                               description='API.COMBINED_EQUIPMENT_PARAMETER_NAME_IS_ALREADY_IN_USE')
3804
                    if 'point' in parameters:
3805
                        if parameters['point'] is None:
3806
                            point_id = None
3807
                        elif parameters['point']['id'] is not None and \
3808
                                parameters['point']['id'] <= 0:
3809
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3810
                                                   description='API.INVALID_POINT_ID')
3811
                        else:
3812
                            point_id = parameters['point']['id']
3813
                    else:
3814
                        point_id = None
3815
                    numerator_meter_uuid = None
3816
                    if 'numerator_meter' in parameters:
3817
                        if parameters['numerator_meter'] is not None and \
3818
                                isinstance(parameters['numerator_meter']['uuid'], str) and \
3819
                                len(str.strip(parameters['numerator_meter']['uuid'])) > 0:
3820
                            numerator_meter_uuid = str.strip(parameters['numerator_meter']['uuid'])
3821
3822
                    denominator_meter_uuid = None
3823
                    if 'denominator_meter' in parameters:
3824
                        if parameters['denominator_meter'] is not None and \
3825
                                isinstance(parameters['denominator_meter']['uuid'], str) and \
3826
                                len(str.strip(parameters['denominator_meter']['uuid'])) > 0:
3827
                            denominator_meter_uuid = str.strip(parameters['denominator_meter']['uuid'])
3828
3829
                    # validate by parameter type
3830
                    if parameters['parameter_type'] == 'point':
3831
                        if point_id is None:
3832
                            cursor.close()
3833
                            cnx.close()
3834
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3835
                                                   description='API.INVALID_POINT_ID')
3836
3837
                        query = (" SELECT id, name "
3838
                                 " FROM tbl_points "
3839
                                 " WHERE id = %s ")
3840
                        cursor.execute(query, (point_id,))
3841
                        if cursor.fetchone() is None:
3842
                            cursor.close()
3843
                            cnx.close()
3844
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3845
                                                   description='API.POINT_NOT_FOUND')
3846
3847
                    elif parameters['parameter_type'] == 'constant':
3848
                        if parameters['constant'] is None:
3849
                            cursor.close()
3850
                            cnx.close()
3851
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3852
                                                   description='API.INVALID_CONSTANT_VALUE')
3853
3854
                    elif parameters['parameter_type'] == 'fraction':
3855
3856
                        query = (" SELECT id, name, uuid "
3857
                                 " FROM tbl_meters ")
3858
                        cursor.execute(query)
3859
                        rows_meters = cursor.fetchall()
3860
3861
                        meter_dict = dict()
3862
                        if rows_meters is not None and len(rows_meters) > 0:
3863
                            for row in rows_meters:
3864
                                meter_dict[row[2]] = {"type": 'meter',
3865
                                                      "id": row[0],
3866
                                                      "name": row[1],
3867
                                                      "uuid": row[2]}
3868
3869
                        query = (" SELECT id, name, uuid "
3870
                                 " FROM tbl_offline_meters ")
3871
                        cursor.execute(query)
3872
                        rows_offline_meters = cursor.fetchall()
3873
3874
                        offline_meter_dict = dict()
3875
                        if rows_offline_meters is not None and len(rows_offline_meters) > 0:
3876
                            for row in rows_offline_meters:
3877
                                offline_meter_dict[row[2]] = {"type": 'offline_meter',
3878
                                                              "id": row[0],
3879
                                                              "name": row[1],
3880
                                                              "uuid": row[2]}
3881
3882
                        query = (" SELECT id, name, uuid "
3883
                                 " FROM tbl_virtual_meters ")
3884
                        cursor.execute(query)
3885
                        rows_virtual_meters = cursor.fetchall()
3886
3887
                        virtual_meter_dict = dict()
3888
                        if rows_virtual_meters is not None and len(rows_virtual_meters) > 0:
3889
                            for row in rows_virtual_meters:
3890
                                virtual_meter_dict[row[2]] = {"type": 'virtual_meter',
3891
                                                              "id": row[0],
3892
                                                              "name": row[1],
3893
                                                              "uuid": row[2]}
3894
3895
                        # validate numerator meter uuid
3896
                        if meter_dict.get(numerator_meter_uuid) is None and \
3897
                                virtual_meter_dict.get(numerator_meter_uuid) is None and \
3898
                                offline_meter_dict.get(numerator_meter_uuid) is None:
3899
                            cursor.close()
3900
                            cnx.close()
3901
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3902
                                                   description='API.INVALID_NUMERATOR_METER_UUID')
3903
3904
                        # validate denominator meter uuid
3905
                        if denominator_meter_uuid is None:
3906
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3907
                                                   description='API.INVALID_DENOMINATOR_METER_UUID')
3908
3909
                        if denominator_meter_uuid == numerator_meter_uuid:
3910
                            cursor.close()
3911
                            cnx.close()
3912
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3913
                                                   description='API.INVALID_DENOMINATOR_METER_UUID')
3914
3915
                        if denominator_meter_uuid not in meter_dict and \
3916
                                denominator_meter_uuid not in virtual_meter_dict and \
3917
                                denominator_meter_uuid not in offline_meter_dict:
3918
                            cursor.close()
3919
                            cnx.close()
3920
                            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
3921
                                                   description='API.INVALID_DENOMINATOR_METER_UUID')
3922
3923
                    add_values = (" INSERT INTO tbl_combined_equipments_parameters "
3924
                                  "    (combined_equipment_id, name, parameter_type, constant, "
3925
                                  "     point_id, numerator_meter_uuid, denominator_meter_uuid) "
3926
                                  " VALUES (%s, %s, %s, %s, %s, %s, %s) ")
3927
                    cursor.execute(add_values, (new_id,
3928
                                                parameters['name'],
3929
                                                parameters['parameter_type'],
3930
                                                parameters['constant'],
3931
                                                point_id,
3932
                                                numerator_meter_uuid,
3933
                                                denominator_meter_uuid))
3934
            cnx.commit()
3935
            cursor.close()
3936
            cnx.close()
3937
3938
            resp.status = falcon.HTTP_201
3939
            resp.location = '/combinedequipments/' + str(new_id)
3940