core.equipment.EquipmentExport.on_options()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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