core.equipment   F
last analyzed

Complexity

Total Complexity 752

Size/Duplication

Total Lines 3593
Duplicated Lines 42.14 %

Importance

Changes 0
Metric Value
wmc 752
eloc 2739
dl 1514
loc 3593
rs 0.8
c 0
b 0
f 0

69 Methods

Rating   Name   Duplication   Size   Complexity  
A EquipmentItem.__init__() 0 2 1
D EquipmentVirtualMeterCollection.on_get() 54 54 13
A EquipmentClone.__init__() 0 2 1
A EquipmentDataSourceCollection.on_options() 5 5 1
A EquipmentVirtualMeterItem.on_options() 0 6 1
B EquipmentDataSourceItem.on_delete() 0 46 8
D EquipmentItem.on_get() 64 64 13
A EquipmentExport.__init__() 0 2 1
D EquipmentOfflineMeterCollection.on_get() 54 54 13
F EquipmentItem.on_post() 139 139 21
C EquipmentCommandCollection.on_post() 66 66 10
A EquipmentDataSourceCollection.__init__() 2 2 1
F EquipmentParameterItem.on_get() 0 121 28
A EquipmentOfflineMeterItem.__init__() 0 2 1
A EquipmentOfflineMeterCollection.__init__() 2 2 1
D EquipmentVirtualMeterCollection.on_post() 72 72 12
A EquipmentParameterCollection.on_options() 0 5 1
B EquipmentParameterItem.on_delete() 0 47 7
A EquipmentCommandItem.on_options() 0 6 1
A EquipmentCommandItem.__init__() 0 2 1
F EquipmentEditPointsCollection.on_get() 0 85 21
A EquipmentOfflineMeterCollection.on_options() 5 5 1
A EquipmentDataSourceItem.__init__() 0 2 1
B EquipmentVirtualMeterItem.on_delete() 0 50 8
F EquipmentCollection.on_get() 0 69 16
F EquipmentImport.on_post() 0 342 86
A EquipmentVirtualMeterCollection.__init__() 2 2 1
F EquipmentExport.on_get() 41 249 50
A EquipmentVirtualMeterCollection.on_options() 5 5 1
D EquipmentMeterCollection.on_post() 72 72 12
A EquipmentMeterCollection.__init__() 2 2 1
D EquipmentMeterCollection.on_get() 54 54 13
A EquipmentMeterItem.on_options() 0 6 1
F EquipmentParameterCollection.on_get() 41 139 31
F EquipmentParameterItem.on_put() 79 203 53
A EquipmentMeterCollection.on_options() 5 5 1
A EquipmentOfflineMeterItem.on_options() 0 6 1
B EquipmentCommandItem.on_delete() 0 49 8
B EquipmentMeterItem.on_delete() 0 49 8
A EquipmentMeterItem.__init__() 0 2 1
F EquipmentCollection.on_post() 117 117 26
F EquipmentClone.on_post() 168 478 104
A EquipmentDataSourceItem.on_options() 0 6 1
A EquipmentParameterItem.on_options() 0 6 1
F EquipmentParameterCollection.on_post() 75 181 50
A EquipmentCommandCollection.__init__() 2 2 1
C EquipmentItem.on_delete() 0 74 9
A EquipmentImport.__init__() 0 2 1
C EquipmentDataSourceCollection.on_get() 40 40 10
F EquipmentItem.on_put() 127 127 28
A EquipmentCommandCollection.on_options() 5 5 1
A EquipmentEditPointsCollection.on_options() 0 6 1
A EquipmentAddPointsCollection.on_options() 0 5 1
A EquipmentVirtualMeterItem.__init__() 0 2 1
A EquipmentAddPointsCollection.__init__() 0 2 1
A EquipmentParameterCollection.__init__() 0 2 1
A EquipmentClone.on_options() 0 5 1
A EquipmentExport.on_options() 0 5 1
A EquipmentItem.on_options() 0 5 1
D EquipmentOfflineMeterCollection.on_post() 72 72 12
C EquipmentCommandCollection.on_get() 40 40 10
A EquipmentImport.on_options() 0 4 1
B EquipmentOfflineMeterItem.on_delete() 0 50 8
C EquipmentDataSourceCollection.on_post() 59 59 10
A EquipmentParameterItem.__init__() 0 4 1
F EquipmentAddPointsCollection.on_get() 22 69 16
A EquipmentCollection.on_options() 0 5 1
A EquipmentEditPointsCollection.__init__() 0 2 1
A EquipmentCollection.__init__() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like core.equipment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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