Passed
Push — master ( f275b0...7ec867 )
by Guangyu
09:57 queued 14s
created

core.meter.MeterPointCollection.on_options()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 3
1
import falcon
2
import simplejson as json
3
import mysql.connector
4
import uuid
5
from core.useractivity import user_logger, access_control
6
import config
7
8
9
class MeterCollection:
10
    @staticmethod
11
    def __init__():
12
        """Initializes MeterCollection"""
13
        pass
14
15
    @staticmethod
16
    def on_options(req, resp):
17
        resp.status = falcon.HTTP_200
18
19
    @staticmethod
20
    def on_get(req, resp):
21
        cnx = mysql.connector.connect(**config.myems_system_db)
22
        cursor = cnx.cursor(dictionary=True)
23
24
        query = (" SELECT id, name, uuid "
25
                 " FROM tbl_energy_categories ")
26
        cursor.execute(query)
27
        rows_energy_categories = cursor.fetchall()
28
29
        energy_category_dict = dict()
30
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
31
            for row in rows_energy_categories:
32
                energy_category_dict[row['id']] = {"id": row['id'],
33
                                                   "name": row['name'],
34
                                                   "uuid": row['uuid']}
35
36
        query = (" SELECT id, name, uuid "
37
                 " FROM tbl_cost_centers ")
38
        cursor.execute(query)
39
        rows_cost_centers = cursor.fetchall()
40
41
        cost_center_dict = dict()
42
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
43
            for row in rows_cost_centers:
44
                cost_center_dict[row['id']] = {"id": row['id'],
45
                                               "name": row['name'],
46
                                               "uuid": row['uuid']}
47
48
        query = (" SELECT id, name, uuid "
49
                 " FROM tbl_energy_items ")
50
        cursor.execute(query)
51
        rows_energy_items = cursor.fetchall()
52
53
        energy_item_dict = dict()
54
        if rows_energy_items is not None and len(rows_energy_items) > 0:
55
            for row in rows_energy_items:
56
                energy_item_dict[row['id']] = {"id": row['id'],
57
                                               "name": row['name'],
58
                                               "uuid": row['uuid']}
59
60
        query = (" SELECT id, name, uuid "
61
                 " FROM tbl_meters ")
62
        cursor.execute(query)
63
        rows_master_meters = cursor.fetchall()
64
65
        master_meter_dict = dict()
66
        if rows_master_meters is not None and len(rows_master_meters) > 0:
67
            for row in rows_master_meters:
68
                master_meter_dict[row['id']] = {"id": row['id'],
69
                                                "name": row['name'],
70
                                                "uuid": row['uuid']}
71
72
        query = (" SELECT id, name, uuid, energy_category_id, "
73
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
74
                 "        cost_center_id, energy_item_id, master_meter_id, description "
75
                 " FROM tbl_meters "
76
                 " ORDER BY id ")
77
        cursor.execute(query)
78
        rows_meters = cursor.fetchall()
79
80
        result = list()
81
        if rows_meters is not None and len(rows_meters) > 0:
82
            for row in rows_meters:
83
                energy_category = energy_category_dict.get(row['energy_category_id'], None)
84
                cost_center = cost_center_dict.get(row['cost_center_id'], None)
85
                energy_item = energy_item_dict.get(row['energy_item_id'], None)
86
                master_meter = master_meter_dict.get(row['master_meter_id'], None)
87
                meta_result = {"id": row['id'],
88
                               "name": row['name'],
89
                               "uuid": row['uuid'],
90
                               "energy_category": energy_category,
91
                               "is_counted": True if row['is_counted'] else False,
92
                               "hourly_low_limit": row['hourly_low_limit'],
93
                               "hourly_high_limit": row['hourly_high_limit'],
94
                               "cost_center": cost_center,
95
                               "energy_item": energy_item,
96
                               "master_meter": master_meter,
97
                               "description": row['description'],
98
                               "qrcode": "meter:" + row['uuid']}
99
                result.append(meta_result)
100
101
        cursor.close()
102
        cnx.disconnect()
103
        resp.text = json.dumps(result)
104
105
    @staticmethod
106
    @user_logger
107
    def on_post(req, resp):
108
        """Handles POST requests"""
109
        access_control(req)
110
        try:
111
            raw_json = req.stream.read().decode('utf-8')
112
        except Exception as ex:
113
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
114
115
        new_values = json.loads(raw_json)
116
117
        if 'name' not in new_values['data'].keys() or \
118
                not isinstance(new_values['data']['name'], str) or \
119
                len(str.strip(new_values['data']['name'])) == 0:
120
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
121
                                   description='API.INVALID_METER_NAME')
122
        name = str.strip(new_values['data']['name'])
123
124
        if 'energy_category_id' not in new_values['data'].keys() or \
125
                not isinstance(new_values['data']['energy_category_id'], int) or \
126
                new_values['data']['energy_category_id'] <= 0:
127
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
128
                                   description='API.INVALID_ENERGY_CATEGORY_ID')
129
        energy_category_id = new_values['data']['energy_category_id']
130
131
        if 'is_counted' not in new_values['data'].keys() or \
132
                not isinstance(new_values['data']['is_counted'], bool):
133
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
134
                                   description='API.INVALID_IS_COUNTED_VALUE')
135
        is_counted = new_values['data']['is_counted']
136
137
        if 'hourly_low_limit' not in new_values['data'].keys() or \
138
                not (isinstance(new_values['data']['hourly_low_limit'], float) or
139
                     isinstance(new_values['data']['hourly_low_limit'], int)):
140
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
141
                                   description='API.INVALID_HOURLY_LOW_LIMIT_VALUE')
142
        hourly_low_limit = new_values['data']['hourly_low_limit']
143
144
        if 'hourly_high_limit' not in new_values['data'].keys() or \
145
                not (isinstance(new_values['data']['hourly_high_limit'], float) or
146
                     isinstance(new_values['data']['hourly_high_limit'], int)):
147
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
148
                                   description='API.INVALID_HOURLY_HIGH_LIMIT_VALUE')
149
        hourly_high_limit = new_values['data']['hourly_high_limit']
150
151
        if 'cost_center_id' not in new_values['data'].keys() or \
152
                not isinstance(new_values['data']['cost_center_id'], int) or \
153
                new_values['data']['cost_center_id'] <= 0:
154
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
155
                                   description='API.INVALID_COST_CENTER_ID')
156
        cost_center_id = new_values['data']['cost_center_id']
157
158
        if 'energy_item_id' in new_values['data'].keys() and \
159
                new_values['data']['energy_item_id'] is not None:
160
            if not isinstance(new_values['data']['energy_item_id'], int) or \
161
                    new_values['data']['energy_item_id'] <= 0:
162
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
163
                                       description='API.INVALID_ENERGY_ITEM_ID')
164
            energy_item_id = new_values['data']['energy_item_id']
165
        else:
166
            energy_item_id = None
167
168
        if 'master_meter_id' in new_values['data'].keys():
169
            if not isinstance(new_values['data']['master_meter_id'], int) or \
170
                    new_values['data']['master_meter_id'] <= 0:
171
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
172
                                       description='API.INVALID_MASTER_METER_ID')
173
            master_meter_id = new_values['data']['master_meter_id']
174
        else:
175
            master_meter_id = None
176
177
        if 'description' in new_values['data'].keys() and \
178
                new_values['data']['description'] is not None and \
179
                len(str(new_values['data']['description'])) > 0:
180
            description = str.strip(new_values['data']['description'])
181
        else:
182
            description = None
183
184
        cnx = mysql.connector.connect(**config.myems_system_db)
185
        cursor = cnx.cursor()
186
187
        cursor.execute(" SELECT name "
188
                       " FROM tbl_meters "
189
                       " WHERE name = %s ", (name,))
190
        if cursor.fetchone() is not None:
191
            cursor.close()
192
            cnx.disconnect()
193
            raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
194
                                   description='API.METER_NAME_IS_ALREADY_IN_USE')
195
196
        cursor.execute(" SELECT name "
197
                       " FROM tbl_energy_categories "
198
                       " WHERE id = %s ",
199
                       (new_values['data']['energy_category_id'],))
200
        if cursor.fetchone() is None:
201
            cursor.close()
202
            cnx.disconnect()
203
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
204
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
205
206
        cursor.execute(" SELECT name "
207
                       " FROM tbl_cost_centers "
208
                       " WHERE id = %s ",
209
                       (new_values['data']['cost_center_id'],))
210
        row = cursor.fetchone()
211
        if row is None:
212
            cursor.close()
213
            cnx.disconnect()
214
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
215
                                   description='API.COST_CENTER_NOT_FOUND')
216
217 View Code Duplication
        if energy_item_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
218
            cursor.execute(" SELECT name, energy_category_id "
219
                           " FROM tbl_energy_items "
220
                           " WHERE id = %s ",
221
                           (new_values['data']['energy_item_id'],))
222
            row = cursor.fetchone()
223
            if row is None:
224
                cursor.close()
225
                cnx.disconnect()
226
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
227
                                       description='API.ENERGY_ITEM_NOT_FOUND')
228
            else:
229
                if row[1] != energy_category_id:
230
                    cursor.close()
231
                    cnx.disconnect()
232
                    raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
233
                                           description='API.ENERGY_ITEM_DOES_NOT_BELONG_TO_ENERGY_CATEGORY')
234
235 View Code Duplication
        if master_meter_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
236
            cursor.execute(" SELECT name, energy_category_id "
237
                           " FROM tbl_meters "
238
                           " WHERE id = %s ",
239
                           (new_values['data']['master_meter_id'],))
240
            row = cursor.fetchone()
241
            if row is None:
242
                cursor.close()
243
                cnx.disconnect()
244
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
245
                                       description='API.MASTER_METER_NOT_FOUND')
246
            else:
247
                if row[1] != energy_category_id:
248
                    cursor.close()
249
                    cnx.disconnect()
250
                    raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
251
                                           description='API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY')
252
253
        add_values = (" INSERT INTO tbl_meters "
254
                      "    (name, uuid, energy_category_id, is_counted, hourly_low_limit, hourly_high_limit,"
255
                      "     cost_center_id, energy_item_id, master_meter_id, description) "
256
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
257
        cursor.execute(add_values, (name,
258
                                    str(uuid.uuid4()),
259
                                    energy_category_id,
260
                                    is_counted,
261
                                    hourly_low_limit,
262
                                    hourly_high_limit,
263
                                    cost_center_id,
264
                                    energy_item_id,
265
                                    master_meter_id,
266
                                    description))
267
        new_id = cursor.lastrowid
268
        cnx.commit()
269
        cursor.close()
270
        cnx.disconnect()
271
272
        resp.status = falcon.HTTP_201
273
        resp.location = '/meters/' + str(new_id)
274
275
276
class MeterItem:
277
    @staticmethod
278
    def __init__():
279
        """Initializes MeterItem"""
280
        pass
281
282
    @staticmethod
283
    def on_options(req, resp, id_):
284
        resp.status = falcon.HTTP_200
285
286
    @staticmethod
287
    def on_get(req, resp, id_):
288
        if not id_.isdigit() or int(id_) <= 0:
289
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
290
                                   description='API.INVALID_METER_ID')
291
292
        cnx = mysql.connector.connect(**config.myems_system_db)
293
        cursor = cnx.cursor(dictionary=True)
294
295
        query = (" SELECT id, name, uuid "
296
                 " FROM tbl_energy_categories ")
297
        cursor.execute(query)
298
        rows_energy_categories = cursor.fetchall()
299
300
        energy_category_dict = dict()
301
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
302
            for row in rows_energy_categories:
303
                energy_category_dict[row['id']] = {"id": row['id'],
304
                                                   "name": row['name'],
305
                                                   "uuid": row['uuid']}
306
307
        query = (" SELECT id, name, uuid "
308
                 " FROM tbl_cost_centers ")
309
        cursor.execute(query)
310
        rows_cost_centers = cursor.fetchall()
311
312
        cost_center_dict = dict()
313
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
314
            for row in rows_cost_centers:
315
                cost_center_dict[row['id']] = {"id": row['id'],
316
                                               "name": row['name'],
317
                                               "uuid": row['uuid']}
318
319
        query = (" SELECT id, name, uuid "
320
                 " FROM tbl_energy_items ")
321
        cursor.execute(query)
322
        rows_energy_items = cursor.fetchall()
323
324
        energy_item_dict = dict()
325
        if rows_energy_items is not None and len(rows_energy_items) > 0:
326
            for row in rows_energy_items:
327
                energy_item_dict[row['id']] = {"id": row['id'],
328
                                               "name": row['name'],
329
                                               "uuid": row['uuid']}
330
331
        query = (" SELECT id, name, uuid "
332
                 " FROM tbl_meters ")
333
        cursor.execute(query)
334
        rows_master_meters = cursor.fetchall()
335
336
        master_meter_dict = dict()
337
        if rows_master_meters is not None and len(rows_master_meters) > 0:
338
            for row in rows_master_meters:
339
                master_meter_dict[row['id']] = {"id": row['id'],
340
                                                "name": row['name'],
341
                                                "uuid": row['uuid']}
342
343
        query = (" SELECT id, name, uuid, energy_category_id, "
344
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
345
                 "        cost_center_id, energy_item_id, master_meter_id, description "
346
                 " FROM tbl_meters "
347
                 " WHERE id = %s ")
348
        cursor.execute(query, (id_,))
349
        row = cursor.fetchone()
350
        cursor.close()
351
        cnx.disconnect()
352
353
        if row is None:
354
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
355
                                   description='API.METER_NOT_FOUND')
356
        else:
357
            energy_category = energy_category_dict.get(row['energy_category_id'], None)
358
            cost_center = cost_center_dict.get(row['cost_center_id'], None)
359
            energy_item = energy_item_dict.get(row['energy_item_id'], None)
360
            master_meter = master_meter_dict.get(row['master_meter_id'], None)
361
            meta_result = {"id": row['id'],
362
                           "name": row['name'],
363
                           "uuid": row['uuid'],
364
                           "energy_category": energy_category,
365
                           "is_counted": True if row['is_counted'] else False,
366
                           "hourly_low_limit": row['hourly_low_limit'],
367
                           "hourly_high_limit": row['hourly_high_limit'],
368
                           "cost_center": cost_center,
369
                           "energy_item": energy_item,
370
                           "master_meter": master_meter,
371
                           "description": row['description'],
372
                           "qrcode": "meter:"+row['uuid']}
373
374
        resp.text = json.dumps(meta_result)
375
376
    @staticmethod
377
    @user_logger
378
    def on_delete(req, resp, id_):
379
        access_control(req)
380
        if not id_.isdigit() or int(id_) <= 0:
381
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
382
                                   description='API.INVALID_METER_ID')
383
384
        cnx = mysql.connector.connect(**config.myems_system_db)
385
        cursor = cnx.cursor()
386
387
        cursor.execute(" SELECT uuid "
388
                       " FROM tbl_meters "
389
                       " WHERE id = %s ", (id_,))
390
        row = cursor.fetchone()
391
        if row is None:
392
            cursor.close()
393
            cnx.disconnect()
394
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
395
                                   description='API.METER_NOT_FOUND')
396
        else:
397
            meter_uuid = row[0]
398
399
        # check if this meter is being used by virtual meters
400
        cursor.execute(" SELECT vm.name "
401
                       " FROM tbl_variables va, tbl_virtual_meters vm "
402
                       " WHERE va.meter_id = %s AND va.meter_type = 'meter' AND va.virtual_meter_id = vm.id ",
403
                       (id_,))
404
        row_virtual_meter = cursor.fetchone()
405
        if row_virtual_meter is not None:
406
            cursor.close()
407
            cnx.disconnect()
408
            raise falcon.HTTPError(falcon.HTTP_400,
409
                                   title='API.BAD_REQUEST',
410
                                   description='API.THIS_METER_IS_BEING_USED_BY_A_VIRTUAL_METER')
411
412
        # check relation with child meters
413
        cursor.execute(" SELECT id "
414
                       " FROM tbl_meters "
415
                       " WHERE master_meter_id = %s ", (id_,))
416
        rows_child_meters = cursor.fetchall()
417
        if rows_child_meters is not None and len(rows_child_meters) > 0:
418
            cursor.close()
419
            cnx.disconnect()
420
            raise falcon.HTTPError(falcon.HTTP_400,
421
                                   title='API.BAD_REQUEST',
422
                                   description='API.THERE_IS_RELATION_WITH_CHILD_METERS')
423
424
        # check relation with spaces
425
        cursor.execute(" SELECT id "
426
                       " FROM tbl_spaces_meters "
427
                       " WHERE meter_id = %s ", (id_,))
428
        rows_spaces = cursor.fetchall()
429
        if rows_spaces is not None and len(rows_spaces) > 0:
430
            cursor.close()
431
            cnx.disconnect()
432
            raise falcon.HTTPError(falcon.HTTP_400,
433
                                   title='API.BAD_REQUEST',
434
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
435
436
        # check relation with tenants
437
        cursor.execute(" SELECT tenant_id "
438
                       " FROM tbl_tenants_meters "
439
                       " WHERE meter_id = %s ", (id_,))
440
        rows_tenants = cursor.fetchall()
441
        if rows_tenants is not None and len(rows_tenants) > 0:
442
            cursor.close()
443
            cnx.disconnect()
444
            raise falcon.HTTPError(falcon.HTTP_400,
445
                                   title='API.BAD_REQUEST',
446
                                   description='API.THERE_IS_RELATION_WITH_TENANTS')
447
448
        # check relation with stores
449
        cursor.execute(" SELECT store_id "
450
                       " FROM tbl_stores_meters "
451
                       " WHERE meter_id = %s ", (id_,))
452
        rows_stores = cursor.fetchall()
453
        if rows_stores is not None and len(rows_stores) > 0:
454
            cursor.close()
455
            cnx.disconnect()
456
            raise falcon.HTTPError(falcon.HTTP_400,
457
                                   title='API.BAD_REQUEST',
458
                                   description='API.THERE_IS_RELATION_WITH_STORES')
459
460
        # check relation with shopfloors
461
        cursor.execute(" SELECT shopfloor_id "
462
                       " FROM tbl_shopfloors_meters "
463
                       " WHERE meter_id = %s ", (id_,))
464
        rows_shopfloors = cursor.fetchall()
465
        if rows_shopfloors is not None and len(rows_shopfloors) > 0:
466
            cursor.close()
467
            cnx.disconnect()
468
            raise falcon.HTTPError(falcon.HTTP_400,
469
                                   title='API.BAD_REQUEST',
470
                                   description='API.THERE_IS_RELATION_WITH_SHOPFLOORS')
471
472
        # check relation with combined equipments
473
        cursor.execute(" SELECT combined_equipment_id "
474
                       " FROM tbl_combined_equipments_meters "
475
                       " WHERE meter_id = %s ",
476
                       (id_,))
477
        rows_combined_equipments = cursor.fetchall()
478
        if rows_combined_equipments is not None and len(rows_combined_equipments) > 0:
479
            cursor.close()
480
            cnx.disconnect()
481
            raise falcon.HTTPError(falcon.HTTP_400,
482
                                   title='API.BAD_REQUEST',
483
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENTS')
484
485
        # check relation with combined equipment parameters
486
        cursor.execute(" SELECT combined_equipment_id "
487
                       " FROM tbl_combined_equipments_parameters "
488
                       " WHERE numerator_meter_uuid = %s OR denominator_meter_uuid = %s", (meter_uuid, meter_uuid,))
489
        rows_combined_equipments = cursor.fetchall()
490
        if rows_combined_equipments is not None and len(rows_combined_equipments) > 0:
491
            cursor.close()
492
            cnx.disconnect()
493
            raise falcon.HTTPError(falcon.HTTP_400,
494
                                   title='API.BAD_REQUEST',
495
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENT_PARAMETERS')
496
497
        # check relation with equipments
498
        cursor.execute(" SELECT equipment_id "
499
                       " FROM tbl_equipments_meters "
500
                       " WHERE meter_id = %s ", (id_,))
501
        rows_equipments = cursor.fetchall()
502
        if rows_equipments is not None and len(rows_equipments) > 0:
503
            cursor.close()
504
            cnx.disconnect()
505
            raise falcon.HTTPError(falcon.HTTP_400,
506
                                   title='API.BAD_REQUEST',
507
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENTS')
508
509
        # check relation with equipment parameters
510
        cursor.execute(" SELECT equipment_id "
511
                       " FROM tbl_equipments_parameters "
512
                       " WHERE numerator_meter_uuid = %s OR denominator_meter_uuid = %s", (meter_uuid, meter_uuid, ))
513
        rows_equipments = cursor.fetchall()
514
        if rows_equipments is not None and len(rows_equipments) > 0:
515
            cursor.close()
516
            cnx.disconnect()
517
            raise falcon.HTTPError(falcon.HTTP_400,
518
                                   title='API.BAD_REQUEST',
519
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENT_PARAMETERS')
520
521
        # check relation with points
522
        cursor.execute(" SELECT id "
523
                       " FROM tbl_meters_points "
524
                       " WHERE meter_id = %s ", (id_,))
525
        rows_equipments = cursor.fetchall()
526
        if rows_equipments is not None and len(rows_equipments) > 0:
527
            cursor.close()
528
            cnx.disconnect()
529
            raise falcon.HTTPError(falcon.HTTP_400,
530
                                   title='API.BAD_REQUEST',
531
                                   description='API.THERE_IS_RELATION_WITH_POINTS')
532
533
        # check relation with energy flow diagram links
534
        cursor.execute(" SELECT id "
535
                       " FROM tbl_energy_flow_diagrams_links "
536
                       " WHERE meter_uuid = %s ", (meter_uuid,))
537
        rows_links = cursor.fetchall()
538
        if rows_links is not None and len(rows_links) > 0:
539
            cursor.close()
540
            cnx.disconnect()
541
            raise falcon.HTTPError(falcon.HTTP_400,
542
                                   title='API.BAD_REQUEST',
543
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_FLOW_DIAGRAM_LINKS')
544
545
        cursor.execute(" DELETE FROM tbl_meters WHERE id = %s ", (id_,))
546
        cnx.commit()
547
548
        cursor.close()
549
        cnx.disconnect()
550
551
        resp.status = falcon.HTTP_204
552
553
    @staticmethod
554
    @user_logger
555
    def on_put(req, resp, id_):
556
        """Handles PUT requests"""
557
        access_control(req)
558
        try:
559
            raw_json = req.stream.read().decode('utf-8')
560
        except Exception as ex:
561
            raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex)
562
563
        if not id_.isdigit() or int(id_) <= 0:
564
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
565
                                   description='API.INVALID_METER_ID')
566
567
        new_values = json.loads(raw_json)
568
569
        if 'name' not in new_values['data'].keys() or \
570
                not isinstance(new_values['data']['name'], str) or \
571
                len(str.strip(new_values['data']['name'])) == 0:
572
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
573
                                   description='API.INVALID_METER_NAME')
574
        name = str.strip(new_values['data']['name'])
575
576
        if 'energy_category_id' not in new_values['data'].keys() or \
577
                not isinstance(new_values['data']['energy_category_id'], int) or \
578
                new_values['data']['energy_category_id'] <= 0:
579
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
580
                                   description='API.INVALID_ENERGY_CATEGORY_ID')
581
        energy_category_id = new_values['data']['energy_category_id']
582
583
        if 'is_counted' not in new_values['data'].keys() or \
584
                not isinstance(new_values['data']['is_counted'], bool):
585
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
586
                                   description='API.INVALID_IS_COUNTED_VALUE')
587
        is_counted = new_values['data']['is_counted']
588
589
        if 'hourly_low_limit' not in new_values['data'].keys() or \
590
                not (isinstance(new_values['data']['hourly_low_limit'], float) or
591
                     isinstance(new_values['data']['hourly_low_limit'], int)):
592
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
593
                                   description='API.INVALID_HOURLY_LOW_LIMIT_VALUE')
594
        hourly_low_limit = new_values['data']['hourly_low_limit']
595
596
        if 'hourly_high_limit' not in new_values['data'].keys() or \
597
                not (isinstance(new_values['data']['hourly_high_limit'], float) or
598
                     isinstance(new_values['data']['hourly_high_limit'], int)):
599
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
600
                                   description='API.INVALID_HOURLY_HIGH_LIMIT_VALUE')
601
        hourly_high_limit = new_values['data']['hourly_high_limit']
602
603
        if 'cost_center_id' not in new_values['data'].keys() or \
604
                not isinstance(new_values['data']['cost_center_id'], int) or \
605
                new_values['data']['cost_center_id'] <= 0:
606
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
607
                                   description='API.INVALID_COST_CENTER_ID')
608
609
        cost_center_id = new_values['data']['cost_center_id']
610
611
        if 'energy_item_id' in new_values['data'].keys() and \
612
                new_values['data']['energy_item_id'] is not None:
613
            if not isinstance(new_values['data']['energy_item_id'], int) or \
614
                    new_values['data']['energy_item_id'] <= 0:
615
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
616
                                       description='API.INVALID_ENERGY_ITEM_ID')
617
            energy_item_id = new_values['data']['energy_item_id']
618
        else:
619
            energy_item_id = None
620
621
        if 'master_meter_id' in new_values['data'].keys():
622
            if not isinstance(new_values['data']['master_meter_id'], int) or \
623
                    new_values['data']['master_meter_id'] <= 0 or \
624
                    new_values['data']['master_meter_id'] == int(id_):
625
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
626
                                       description='API.INVALID_MASTER_METER_ID')
627
            master_meter_id = new_values['data']['master_meter_id']
628
        else:
629
            master_meter_id = None
630
631
        if 'description' in new_values['data'].keys() and \
632
                new_values['data']['description'] is not None and \
633
                len(str(new_values['data']['description'])) > 0:
634
            description = str.strip(new_values['data']['description'])
635
        else:
636
            description = None
637
638
        cnx = mysql.connector.connect(**config.myems_system_db)
639
        cursor = cnx.cursor()
640
641
        cursor.execute(" SELECT name "
642
                       " FROM tbl_meters "
643
                       " WHERE id = %s ", (id_,))
644
        if cursor.fetchone() is None:
645
            cursor.close()
646
            cnx.disconnect()
647
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
648
                                   description='API.METER_NOT_FOUND')
649
650
        cursor.execute(" SELECT name "
651
                       " FROM tbl_meters "
652
                       " WHERE name = %s AND id != %s ", (name, id_))
653
        if cursor.fetchone() is not None:
654
            cursor.close()
655
            cnx.disconnect()
656
            raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
657
                                   description='API.METER_NAME_IS_ALREADY_IN_USE')
658
659
        cursor.execute(" SELECT name "
660
                       " FROM tbl_energy_categories "
661
                       " WHERE id = %s ",
662
                       (new_values['data']['energy_category_id'],))
663
        if cursor.fetchone() is None:
664
            cursor.close()
665
            cnx.disconnect()
666
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
667
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
668
669
        cursor.execute(" SELECT name "
670
                       " FROM tbl_cost_centers "
671
                       " WHERE id = %s ",
672
                       (new_values['data']['cost_center_id'],))
673
        row = cursor.fetchone()
674
        if row is None:
675
            cursor.close()
676
            cnx.disconnect()
677
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
678
                                   description='API.COST_CENTER_NOT_FOUND')
679
680 View Code Duplication
        if energy_item_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
681
            cursor.execute(" SELECT name, energy_category_id "
682
                           " FROM tbl_energy_items "
683
                           " WHERE id = %s ",
684
                           (new_values['data']['energy_item_id'],))
685
            row = cursor.fetchone()
686
            if row is None:
687
                cursor.close()
688
                cnx.disconnect()
689
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
690
                                       description='API.ENERGY_ITEM_NOT_FOUND')
691
            else:
692
                if row[1] != energy_category_id:
693
                    cursor.close()
694
                    cnx.disconnect()
695
                    raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
696
                                           description='API.ENERGY_ITEM_DOES_NOT_BELONG_TO_ENERGY_CATEGORY')
697
698 View Code Duplication
        if master_meter_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
699
            cursor.execute(" SELECT name, energy_category_id "
700
                           " FROM tbl_meters "
701
                           " WHERE id = %s ",
702
                           (new_values['data']['master_meter_id'],))
703
            row = cursor.fetchone()
704
            if row is None:
705
                cursor.close()
706
                cnx.disconnect()
707
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
708
                                       description='API.MASTER_METER_NOT_FOUND')
709
            else:
710
                if row[1] != energy_category_id:
711
                    cursor.close()
712
                    cnx.disconnect()
713
                    raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
714
                                           description='API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY')
715
716
        # todo: check all descendants against new_values['data']['master_meter_id']
717
        if master_meter_id is not None:
718
            cursor.execute(" SELECT name "
719
                           " FROM tbl_meters "
720
                           " WHERE id = %s AND master_meter_id = %s ",
721
                           (new_values['data']['master_meter_id'], id_))
722
            row = cursor.fetchone()
723
            if row is not None:
724
                cursor.close()
725
                cnx.disconnect()
726
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
727
                                       description='API.CANNOT_SET_EXISTING_SUBMETER_AS_MASTER_METER')
728
729
        update_row = (" UPDATE tbl_meters "
730
                      " SET name = %s, energy_category_id = %s, is_counted = %s, "
731
                      "     hourly_low_limit = %s, hourly_high_limit = %s, "
732
                      "     cost_center_id = %s, energy_item_id = %s, master_meter_id = %s, description = %s "
733
                      " WHERE id = %s ")
734
        cursor.execute(update_row, (name,
735
                                    energy_category_id,
736
                                    is_counted,
737
                                    hourly_low_limit,
738
                                    hourly_high_limit,
739
                                    cost_center_id,
740
                                    energy_item_id,
741
                                    master_meter_id,
742
                                    description,
743
                                    id_,))
744
        cnx.commit()
745
746
        cursor.close()
747
        cnx.disconnect()
748
749
        resp.status = falcon.HTTP_200
750
751
752
class MeterSubmeterCollection:
753
    @staticmethod
754
    def __init__():
755
        """Initializes MeterSubmeterCollection"""
756
        pass
757
758
    @staticmethod
759
    def on_options(req, resp, id_):
760
        resp.status = falcon.HTTP_200
761
762
    @staticmethod
763
    def on_get(req, resp, id_):
764
        if not id_.isdigit() or int(id_) <= 0:
765
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
766
                                   description='API.INVALID_METER_ID')
767
768
        cnx = mysql.connector.connect(**config.myems_system_db)
769
        cursor = cnx.cursor(dictionary=True)
770
771
        cursor.execute(" SELECT name, uuid "
772
                       " FROM tbl_meters "
773
                       " WHERE id = %s ", (id_,))
774
        row = cursor.fetchone()
775
        if row is None:
776
            cursor.close()
777
            cnx.disconnect()
778
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
779
                                   description='API.METER_NOT_FOUND')
780
        else:
781
            master_meter = {"id": id_,
782
                            "name": row['name'],
783
                            "uuid": row['uuid']}
784
785
        query = (" SELECT id, name, uuid "
786
                 " FROM tbl_energy_categories ")
787
        cursor.execute(query)
788
        rows_energy_categories = cursor.fetchall()
789
790
        energy_category_dict = dict()
791
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
792
            for row in rows_energy_categories:
793
                energy_category_dict[row['id']] = {"id": row['id'],
794
                                                   "name": row['name'],
795
                                                   "uuid": row['uuid']}
796
797
        query = (" SELECT id, name, uuid "
798
                 " FROM tbl_cost_centers ")
799
        cursor.execute(query)
800
        rows_cost_centers = cursor.fetchall()
801
802
        cost_center_dict = dict()
803
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
804
            for row in rows_cost_centers:
805
                cost_center_dict[row['id']] = {"id": row['id'],
806
                                               "name": row['name'],
807
                                               "uuid": row['uuid']}
808
809
        query = (" SELECT id, name, uuid "
810
                 " FROM tbl_energy_items ")
811
        cursor.execute(query)
812
        rows_energy_items = cursor.fetchall()
813
814
        energy_item_dict = dict()
815
        if rows_energy_items is not None and len(rows_energy_items) > 0:
816
            for row in rows_energy_items:
817
                energy_item_dict[row['id']] = {"id": row['id'],
818
                                               "name": row['name'],
819
                                               "uuid": row['uuid']}
820
821
        query = (" SELECT id, name, uuid, energy_category_id, "
822
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
823
                 "        cost_center_id, energy_item_id, master_meter_id, description "
824
                 " FROM tbl_meters "
825
                 " WHERE master_meter_id = %s "
826
                 " ORDER BY id ")
827
        cursor.execute(query, (id_, ))
828
        rows_meters = cursor.fetchall()
829
830
        result = list()
831 View Code Duplication
        if rows_meters is not None and len(rows_meters) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
832
            for row in rows_meters:
833
                energy_category = energy_category_dict.get(row['energy_category_id'], None)
834
                cost_center = cost_center_dict.get(row['cost_center_id'], None)
835
                energy_item = energy_item_dict.get(row['energy_item_id'], None)
836
                meta_result = {"id": row['id'],
837
                               "name": row['name'],
838
                               "uuid": row['uuid'],
839
                               "energy_category": energy_category,
840
                               "is_counted": True if row['is_counted'] else False,
841
                               "hourly_low_limit": row['hourly_low_limit'],
842
                               "hourly_high_limit": row['hourly_high_limit'],
843
                               "cost_center": cost_center,
844
                               "energy_item": energy_item,
845
                               "master_meter": master_meter,
846
                               "description": row['description']}
847
                result.append(meta_result)
848
849
        cursor.close()
850
        cnx.disconnect()
851
        resp.text = json.dumps(result)
852
853
854
class MeterPointCollection:
855
    @staticmethod
856
    def __init__():
857
        """Initializes MeterPointCollection"""
858
        pass
859
860
    @staticmethod
861
    def on_options(req, resp, id_):
862
        resp.status = falcon.HTTP_200
863
864 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
865
    def on_get(req, resp, id_):
866
        if not id_.isdigit() or int(id_) <= 0:
867
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
868
                                   description='API.INVALID_METER_ID')
869
870
        cnx = mysql.connector.connect(**config.myems_system_db)
871
        cursor = cnx.cursor()
872
873
        cursor.execute(" SELECT name "
874
                       " FROM tbl_meters "
875
                       " WHERE id = %s ", (id_,))
876
        if cursor.fetchone() is None:
877
            cursor.close()
878
            cnx.disconnect()
879
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
880
                                   description='API.METER_NOT_FOUND')
881
882
        query = (" SELECT p.id, p.name, "
883
                 "        ds.id, ds.name, ds.uuid, "
884
                 "        p.address "
885
                 " FROM tbl_points p, tbl_meters_points mp, tbl_data_sources ds "
886
                 " WHERE mp.meter_id = %s AND p.id = mp.point_id AND p.data_source_id = ds.id "
887
                 " ORDER BY p.name ")
888
        cursor.execute(query, (id_,))
889
        rows = cursor.fetchall()
890
891
        result = list()
892
        if rows is not None and len(rows) > 0:
893
            for row in rows:
894
                meta_result = {"id": row[0], "name": row[1],
895
                               "data_source": {"id": row[2], "name": row[3], "uuid": row[4]},
896
                               "address": row[5]}
897
                result.append(meta_result)
898
899
        resp.text = json.dumps(result)
900
901
    @staticmethod
902
    @user_logger
903
    def on_post(req, resp, id_):
904
        """Handles POST requests"""
905
        access_control(req)
906
        try:
907
            raw_json = req.stream.read().decode('utf-8')
908
        except Exception as ex:
909
            raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex)
910
911
        if not id_.isdigit() or int(id_) <= 0:
912
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
913
                                   description='API.INVALID_METER_ID')
914
915
        new_values = json.loads(raw_json)
916
        cnx = mysql.connector.connect(**config.myems_system_db)
917
        cursor = cnx.cursor()
918
919
        cursor.execute(" SELECT name "
920
                       " from tbl_meters "
921
                       " WHERE id = %s ", (id_,))
922
        if cursor.fetchone() is None:
923
            cursor.close()
924
            cnx.disconnect()
925
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
926
                                   description='API.METER_NOT_FOUND')
927
        cursor.execute(" SELECT name, object_type "
928
                       " FROM tbl_points "
929
                       " WHERE id = %s ", (new_values['data']['point_id'],))
930
        row = cursor.fetchone()
931
        if row is None:
932
            cursor.close()
933
            cnx.disconnect()
934
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
935
                                   description='API.POINT_NOT_FOUND')
936
        elif row[1] == 'ENERGY_VALUE':
937
            query = (" SELECT p.id "
938
                     " FROM tbl_meters_points mp, tbl_points p "
939
                     " WHERE mp.meter_id = %s AND mp.point_id = p.id AND p.object_type = 'ENERGY_VALUE' ")
940
            cursor.execute(query, (id_,))
941
            rows_points = cursor.fetchall()
942
            if rows_points is not None and len(rows_points) > 0:
943
                cursor.close()
944
                cnx.disconnect()
945
                raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
946
                                       description='API.METER_CANNOT_HAVE_MORE_THAN_ONE_ENERGY_VALUE_POINTS')
947
948
        query = (" SELECT id " 
949
                 " FROM tbl_meters_points "
950
                 " WHERE meter_id = %s AND point_id = %s")
951
        cursor.execute(query, (id_, new_values['data']['point_id'],))
952
        if cursor.fetchone() is not None:
953
            cursor.close()
954
            cnx.disconnect()
955
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
956
                                   description='API.METER_POINT_RELATION_EXISTS')
957
958
        add_row = (" INSERT INTO tbl_meters_points (meter_id, point_id) "
959
                   " VALUES (%s, %s) ")
960
        cursor.execute(add_row, (id_, new_values['data']['point_id'],))
961
        new_id = cursor.lastrowid
962
        cnx.commit()
963
        cursor.close()
964
        cnx.disconnect()
965
966
        resp.status = falcon.HTTP_201
967
        resp.location = '/meters/' + str(id_) + '/points/' + str(new_values['data']['point_id'])
968
969
970 View Code Duplication
class MeterPointItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
971
    @staticmethod
972
    def __init__():
973
        """Initializes MeterPointItem"""
974
        pass
975
976
    @staticmethod
977
    def on_options(req, resp, id_, pid):
978
        resp.status = falcon.HTTP_200
979
980
    @staticmethod
981
    @user_logger
982
    def on_delete(req, resp, id_, pid):
983
        """Handles DELETE requests"""
984
        access_control(req)
985
        if not id_.isdigit() or int(id_) <= 0:
986
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
987
                                   description='API.INVALID_METER_ID')
988
989
        if not pid.isdigit() or int(pid) <= 0:
990
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
991
                                   description='API.INVALID_POINT_ID')
992
993
        cnx = mysql.connector.connect(**config.myems_system_db)
994
        cursor = cnx.cursor()
995
996
        cursor.execute(" SELECT name "
997
                       " FROM tbl_meters "
998
                       " WHERE id = %s ", (id_,))
999
        if cursor.fetchone() is None:
1000
            cursor.close()
1001
            cnx.disconnect()
1002
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
1003
                                   description='API.METER_NOT_FOUND')
1004
1005
        cursor.execute(" SELECT name "
1006
                       " FROM tbl_points "
1007
                       " WHERE id = %s ", (pid,))
1008
        if cursor.fetchone() is None:
1009
            cursor.close()
1010
            cnx.disconnect()
1011
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
1012
                                   description='API.POINT_NOT_FOUND')
1013
1014
        cursor.execute(" SELECT id "
1015
                       " FROM tbl_meters_points "
1016
                       " WHERE meter_id = %s AND point_id = %s ", (id_, pid))
1017
        if cursor.fetchone() is None:
1018
            cursor.close()
1019
            cnx.disconnect()
1020
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
1021
                                   description='API.METER_POINT_RELATION_NOT_FOUND')
1022
1023
        cursor.execute(" DELETE FROM tbl_meters_points WHERE meter_id = %s AND point_id = %s ", (id_, pid))
1024
        cnx.commit()
1025
1026
        cursor.close()
1027
        cnx.disconnect()
1028
1029
        resp.status = falcon.HTTP_204
1030
1031