core.point.PointImport.on_post()   F
last analyzed

Complexity

Conditions 55

Size

Total Lines 188
Code Lines 152

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 152
dl 0
loc 188
rs 0
c 0
b 0
f 0
cc 55
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like core.point.PointImport.on_post() 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 falcon
2
from datetime import datetime, timedelta
3
import mysql.connector
4
import simplejson as json
5
from core.useractivity import user_logger, admin_control
6
import config
7
from decimal import Decimal
8
9
10
class PointCollection:
11
    def __init__(self):
12
        """"Initializes PointCollection"""
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
        """Handles GET requests"""
22
        admin_control(req)
23
        cnx = mysql.connector.connect(**config.myems_system_db)
24
        cursor = cnx.cursor()
25
26
        query = (" SELECT id, name, uuid "
27
                 " FROM tbl_data_sources ")
28
        cursor.execute(query)
29
        rows_data_sources = cursor.fetchall()
30
31
        data_source_dict = dict()
32
        if rows_data_sources is not None and len(rows_data_sources) > 0:
33
            for row in rows_data_sources:
34
                data_source_dict[row[0]] = {"id": row[0],
35
                                            "name": row[1],
36
                                            "uuid": row[2]}
37
38
        query = (" SELECT id, name, data_source_id, object_type, units, "
39
                 "        high_limit, low_limit, higher_limit, lower_limit, ratio, offset_constant, "
40
                 "        is_trend, is_virtual, address, description, faults, definitions "
41
                 " FROM tbl_points ")
42
        cursor.execute(query)
43
        rows = cursor.fetchall()
44
        cursor.close()
45
        cnx.close()
46
47
        result = list()
48
        if rows is not None and len(rows) > 0:
49
            for row in rows:
50
                meta_result = {"id": row[0],
51
                               "name": row[1],
52
                               "data_source": data_source_dict.get(row[2], None),
53
                               "object_type": row[3],
54
                               "units": row[4],
55
                               "high_limit": row[5],
56
                               "low_limit": row[6],
57
                               "higher_limit": row[7],
58
                               "lower_limit": row[8],
59
                               "ratio": Decimal(row[9]),
60
                               "offset_constant": Decimal(row[10]),
61
                               "is_trend": bool(row[11]),
62
                               "is_virtual": bool(row[12]),
63
                               "address": row[13],
64
                               "description": row[14],
65
                               "faults": row[15],
66
                               "definitions": row[16]}
67
                result.append(meta_result)
68
69
        resp.text = json.dumps(result)
70
71
    @staticmethod
72
    @user_logger
73
    def on_post(req, resp):
74
        """Handles POST requests"""
75
        admin_control(req)
76
        try:
77
            raw_json = req.stream.read().decode('utf-8')
78
        except Exception as ex:
79
            raise falcon.HTTPError(status=falcon.HTTP_400,
80
                                   title='API.BAD_REQUEST',
81
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
82
83
        new_values = json.loads(raw_json)
84
85
        if 'name' not in new_values['data'].keys() or \
86
                not isinstance(new_values['data']['name'], str) or \
87
                len(str.strip(new_values['data']['name'])) == 0:
88
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
89
                                   description='API.INVALID_POINT_NAME')
90
        name = str.strip(new_values['data']['name'])
91
92
        if 'data_source_id' not in new_values['data'].keys() or \
93
                not isinstance(new_values['data']['data_source_id'], int) or \
94
                new_values['data']['data_source_id'] <= 0:
95
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
96
                                   description='API.INVALID_DATA_SOURCE_ID')
97
        data_source_id = new_values['data']['data_source_id']
98
99
        if 'object_type' not in new_values['data'].keys() \
100
                or str.strip(new_values['data']['object_type']) not in \
101
                ('ENERGY_VALUE', 'ANALOG_VALUE', 'DIGITAL_VALUE', 'TEXT_VALUE'):
102
            raise falcon.HTTPError(status=falcon.HTTP_400,
103
                                   title='API.BAD_REQUEST',
104
                                   description='API.INVALID_OBJECT_TYPE')
105
        object_type = str.strip(new_values['data']['object_type'])
106
107
        if 'units' not in new_values['data'].keys() or \
108
                not isinstance(new_values['data']['units'], str) or \
109
                len(str.strip(new_values['data']['units'])) == 0:
110
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
111
                                   description='API.INVALID_UNITS')
112
        units = str.strip(new_values['data']['units'])
113
114
        if 'high_limit' not in new_values['data'].keys() or \
115
                not (isinstance(new_values['data']['high_limit'], float) or
116
                     isinstance(new_values['data']['high_limit'], int)):
117
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
118
                                   description='API.INVALID_HIGH_LIMIT_VALUE')
119
        high_limit = new_values['data']['high_limit']
120
121
        if 'low_limit' not in new_values['data'].keys() or \
122
                not (isinstance(new_values['data']['low_limit'], float) or
123
                     isinstance(new_values['data']['low_limit'], int)):
124
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
125
                                   description='API.INVALID_LOW_LIMIT_VALUE')
126
        low_limit = new_values['data']['low_limit']
127
128
        # the higher_limit is optional
129
        if 'higher_limit' not in new_values['data'].keys() or \
130
                new_values['data']['higher_limit'] is None:
131
            higher_limit = None
132
        elif not (isinstance(new_values['data']['higher_limit'], float) or
133
                  isinstance(new_values['data']['higher_limit'], int)):
134
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
135
                                   description='API.INVALID_HIGHER_LIMIT_VALUE')
136
        else:
137
            higher_limit = new_values['data']['higher_limit']
138
139
        # the lower_limit is optional
140
        if 'lower_limit' not in new_values['data'].keys() or \
141
                new_values['data']['lower_limit'] is None:
142
            lower_limit = None
143
        elif not (isinstance(new_values['data']['lower_limit'], float) or
144
                  isinstance(new_values['data']['lower_limit'], int)):
145
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
146
                                   description='API.INVALID_LOWER_LIMIT_VALUE')
147
        else:
148
            lower_limit = new_values['data']['lower_limit']
149
150
        if 'ratio' not in new_values['data'].keys() or \
151
                not (isinstance(new_values['data']['ratio'], float) or
152
                     isinstance(new_values['data']['ratio'], int)):
153
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
154
                                   description='API.INVALID_RATIO_VALUE')
155
        ratio = new_values['data']['ratio']
156
157
        if 'offset_constant' not in new_values['data'].keys() or \
158
                not (isinstance(new_values['data']['offset_constant'], float) or
159
                     isinstance(new_values['data']['offset_constant'], int)):
160
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
161
                                   description='API.INVALID_OFFSET_CONSTANT_VALUE')
162
        offset_constant = new_values['data']['offset_constant']
163
164
        if 'is_trend' not in new_values['data'].keys() or \
165
                not isinstance(new_values['data']['is_trend'], bool):
166
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
167
                                   description='API.INVALID_IS_TREND_VALUE')
168
        is_trend = new_values['data']['is_trend']
169
170
        if 'is_virtual' not in new_values['data'].keys() or \
171
                not isinstance(new_values['data']['is_virtual'], bool):
172
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
173
                                   description='API.INVALID_IS_VIRTUAL_VALUE')
174
        if new_values['data']['is_virtual'] is True and object_type == 'DIGITAL_VALUE':
175
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
176
                                   description='API.VIRTUAL_POINT_CAN_NOT_BE_DIGITAL_VALUE')
177
        if new_values['data']['is_virtual'] is True and object_type == 'TEXT_VALUE':
178
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
179
                                   description='API.VIRTUAL_POINT_CAN_NOT_BE_TEXT_VALUE')
180
        is_virtual = new_values['data']['is_virtual']
181
182
        if 'address' not in new_values['data'].keys() or \
183
                not isinstance(new_values['data']['address'], str) or \
184
                len(str.strip(new_values['data']['address'])) == 0:
185
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
186
                                   description='API.INVALID_ADDRESS')
187
        address = str.strip(new_values['data']['address'])
188
189
        if 'description' in new_values['data'].keys() and \
190
                new_values['data']['description'] is not None and \
191
                len(str(new_values['data']['description'])) > 0:
192
            description = str.strip(new_values['data']['description'])
193
        else:
194
            description = None
195
196
        if 'faults' in new_values['data'].keys() and \
197
                new_values['data']['faults'] is not None and \
198
                len(str(new_values['data']['faults'])) > 0:
199
            faults = str.strip(new_values['data']['faults'])
200
        else:
201
            faults = None
202
203
        if 'definitions' in new_values['data'].keys() and \
204
                new_values['data']['definitions'] is not None and \
205
                len(str(new_values['data']['definitions'])) > 0:
206
            definitions = str.strip(new_values['data']['definitions'])
207
        else:
208
            definitions = None
209
210
        cnx = mysql.connector.connect(**config.myems_system_db)
211
        cursor = cnx.cursor()
212
213
        cursor.execute(" SELECT name "
214
                       " FROM tbl_points "
215
                       " WHERE name = %s AND data_source_id = %s ", (name, data_source_id))
216
        if cursor.fetchone() is not None:
217
            cursor.close()
218
            cnx.close()
219
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
220
                                   description='API.POINT_NAME_IS_ALREADY_IN_USE')
221
222
        cursor.execute(" SELECT name "
223
                       " FROM tbl_data_sources "
224
                       " WHERE id = %s ", (data_source_id,))
225
        if cursor.fetchone() is None:
226
            cursor.close()
227
            cnx.close()
228
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
229
                                   description='API.INVALID_DATA_SOURCE_ID')
230
231
        add_value = (" INSERT INTO tbl_points (name, data_source_id, object_type, units, "
232
                     "                         high_limit, low_limit, higher_limit, lower_limit, ratio, "
233
                     "                         offset_constant, is_trend, is_virtual, address, description, faults, "
234
                     "                         definitions) "
235
                     " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
236
        cursor.execute(add_value, (name,
237
                                   data_source_id,
238
                                   object_type,
239
                                   units,
240
                                   high_limit,
241
                                   low_limit,
242
                                   higher_limit,
243
                                   lower_limit,
244
                                   ratio,
245
                                   offset_constant,
246
                                   is_trend,
247
                                   is_virtual,
248
                                   address,
249
                                   description,
250
                                   faults,
251
                                   definitions))
252
        new_id = cursor.lastrowid
253
        cnx.commit()
254
        cursor.close()
255
        cnx.close()
256
257
        resp.status = falcon.HTTP_201
258
        resp.location = '/points/' + str(new_id)
259
260
261
class PointItem:
262
    def __init__(self):
263
        """"Initializes PointItem"""
264
        pass
265
266
    @staticmethod
267
    def on_options(req, resp, id_):
268
        resp.status = falcon.HTTP_200
269
270 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
271
    def on_get(req, resp, id_):
272
        """Handles GET requests"""
273
        admin_control(req)
274
        if not id_.isdigit() or int(id_) <= 0:
275
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
276
                                   description='API.INVALID_POINT_ID')
277
278
        cnx = mysql.connector.connect(**config.myems_system_db)
279
        cursor = cnx.cursor()
280
281
        query = (" SELECT id, name, uuid "
282
                 " FROM tbl_data_sources ")
283
        cursor.execute(query)
284
        rows_data_sources = cursor.fetchall()
285
286
        data_source_dict = dict()
287
        if rows_data_sources is not None and len(rows_data_sources) > 0:
288
            for row in rows_data_sources:
289
                data_source_dict[row[0]] = {"id": row[0],
290
                                            "name": row[1],
291
                                            "uuid": row[2]}
292
293
        query = (" SELECT id, name, data_source_id, object_type, units, "
294
                 "        high_limit, low_limit, higher_limit, lower_limit, ratio, offset_constant, "
295
                 "        is_trend, is_virtual, address, description, faults, definitions "
296
                 " FROM tbl_points "
297
                 " WHERE id = %s ")
298
        cursor.execute(query, (id_,))
299
        row = cursor.fetchone()
300
        cursor.close()
301
        cnx.close()
302
        if row is None:
303
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
304
                                   description='API.POINT_NOT_FOUND')
305
306
        result = {"id": row[0],
307
                  "name": row[1],
308
                  "data_source": data_source_dict.get(row[2], None),
309
                  "object_type": row[3],
310
                  "units": row[4],
311
                  "high_limit": row[5],
312
                  "low_limit": row[6],
313
                  "higher_limit": row[7],
314
                  "lower_limit": row[8],
315
                  "ratio": Decimal(row[9]),
316
                  "offset_constant": Decimal(row[10]),
317
                  "is_trend": bool(row[11]),
318
                  "is_virtual": bool(row[12]),
319
                  "address": row[13],
320
                  "description": row[14],
321
                  "faults": row[15],
322
                  "definitions": row[16]}
323
        resp.text = json.dumps(result)
324
325
    @staticmethod
326
    @user_logger
327
    def on_delete(req, resp, id_):
328
        admin_control(req)
329
        if not id_.isdigit() or int(id_) <= 0:
330
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
331
                                   description='API.INVALID_POINT_ID')
332
333
        cnx = mysql.connector.connect(**config.myems_system_db)
334
        cursor = cnx.cursor()
335
336
        cursor.execute(" SELECT name "
337
                       " FROM tbl_points "
338
                       " WHERE id = %s ", (id_,))
339
        if cursor.fetchone() is None:
340
            cursor.close()
341
            cnx.close()
342
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
343
                                   description='API.POINT_NOT_FOUND')
344
345
        # check if this point is being used by meters
346
        cursor.execute(" SELECT meter_id "
347
                       " FROM tbl_meters_points "
348
                       " WHERE point_id = %s "
349
                       " LIMIT 1 ",
350
                       (id_,))
351
        row_meter = cursor.fetchone()
352
        if row_meter is not None:
353
            cursor.close()
354
            cnx.close()
355
            raise falcon.HTTPError(status=falcon.HTTP_400,
356
                                   title='API.BAD_REQUEST',
357
                                   description='API.THERE_IS_RELATION_WITH_METERS')
358
359
        # check if this point is being used by sensors
360
        cursor.execute(" SELECT sensor_id "
361
                       " FROM tbl_sensors_points "
362
                       " WHERE point_id = %s "
363
                       " LIMIT 1 ",
364
                       (id_,))
365
        row_sensor = cursor.fetchone()
366
        if row_sensor is not None:
367
            cursor.close()
368
            cnx.close()
369
            raise falcon.HTTPError(status=falcon.HTTP_400,
370
                                   title='API.BAD_REQUEST',
371
                                   description='API.THERE_IS_RELATION_WITH_SENSORS')
372
373
        # check if this point is being used by shopfloors
374
        cursor.execute(" SELECT shopfloor_id "
375
                       " FROM tbl_shopfloors_points "
376
                       " WHERE point_id = %s "
377
                       " LIMIT 1 ",
378
                       (id_,))
379
        row_shopfloor = cursor.fetchone()
380
        if row_shopfloor is not None:
381
            cursor.close()
382
            cnx.close()
383
            raise falcon.HTTPError(status=falcon.HTTP_400,
384
                                   title='API.BAD_REQUEST',
385
                                   description='API.THERE_IS_RELATION_WITH_SHOPFLOORS')
386
387
        # check if this point is being used by stores
388
        cursor.execute(" SELECT store_id "
389
                       " FROM tbl_stores_points "
390
                       " WHERE point_id = %s "
391
                       " LIMIT 1 ",
392
                       (id_,))
393
        row_store = cursor.fetchone()
394
        if row_store is not None:
395
            cursor.close()
396
            cnx.close()
397
            raise falcon.HTTPError(status=falcon.HTTP_400,
398
                                   title='API.BAD_REQUEST',
399
                                   description='API.THERE_IS_RELATION_WITH_STORES')
400
401
        # check if this point is being used by spaces
402
        cursor.execute(" SELECT space_id "
403
                       " FROM tbl_spaces_points "
404
                       " WHERE point_id = %s "
405
                       " LIMIT 1 ",
406
                       (id_,))
407
        row_space = cursor.fetchone()
408
        if row_space is not None:
409
            cursor.close()
410
            cnx.close()
411
            raise falcon.HTTPError(status=falcon.HTTP_400,
412
                                   title='API.BAD_REQUEST',
413
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
414
415
        # check if this point is being used by tenants
416
        cursor.execute(" SELECT tenant_id "
417
                       " FROM tbl_tenants_points "
418
                       " WHERE point_id = %s "
419
                       " LIMIT 1 ",
420
                       (id_,))
421
        row_tenant = cursor.fetchone()
422
        if row_tenant is not None:
423
            cursor.close()
424
            cnx.close()
425
            raise falcon.HTTPError(status=falcon.HTTP_400,
426
                                   title='API.BAD_REQUEST',
427
                                   description='API.THERE_IS_RELATION_WITH_TENANTS')
428
429
        # check if this point is being used by equipment parameters
430
        cursor.execute(" SELECT equipment_id "
431
                       " FROM tbl_equipments_parameters "
432
                       " WHERE point_id = %s "
433
                       " LIMIT 1 ",
434
                       (id_,))
435
        row_equipment = cursor.fetchone()
436
        if row_equipment is not None:
437
            cursor.close()
438
            cnx.close()
439
            raise falcon.HTTPError(status=falcon.HTTP_400,
440
                                   title='API.BAD_REQUEST',
441
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENT_PARAMETERS')
442
443
        # check if this point is being used by combined equipment parameters
444
        cursor.execute(" SELECT combined_equipment_id "
445
                       " FROM tbl_combined_equipments_parameters "
446
                       " WHERE point_id = %s "
447
                       " LIMIT 1 ",
448
                       (id_,))
449
        row_combined_equipment = cursor.fetchone()
450
        if row_combined_equipment is not None:
451
            cursor.close()
452
            cnx.close()
453
            raise falcon.HTTPError(status=falcon.HTTP_400,
454
                                   title='API.BAD_REQUEST',
455
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENT_PARAMETERS')
456
457
        # check if this point is being used by distribution circuit point
458
        cursor.execute(" SELECT distribution_circuit_id "
459
                       " FROM tbl_distribution_circuits_points "
460
                       " WHERE point_id = %s "
461
                       " LIMIT 1 ",
462
                       (id_,))
463
        row_distribution_circuit = cursor.fetchone()
464
        if row_distribution_circuit is not None:
465
            cursor.close()
466
            cnx.close()
467
            raise falcon.HTTPError(status=falcon.HTTP_400,
468
                                   title='API.BAD_REQUEST',
469
                                   description='API.THERE_IS_RELATION_WITH_DISTRIBUTION_CIRCUITS_POINTS')
470
471
        # check if this point is being used by distribution integrator
472
        cursor.execute(" SELECT name "
473
                       " FROM tbl_integrators "
474
                       " WHERE high_temperature_point_id = %s "
475
                       "    OR low_temperature_point_id = %s "
476
                       "    OR flow_point_id = %s "
477
                       "    OR result_point_id = %s "
478
                       " LIMIT 1",
479
                       (id_, id_, id_, id_))
480
        row_integrator = cursor.fetchone()
481
        if row_integrator is not None:
482
            cursor.close()
483
            cnx.close()
484
            raise falcon.HTTPError(status=falcon.HTTP_400,
485
                                   title='API.BAD_REQUEST',
486
                                   description='API.THERE_IS_RELATION_WITH_INTEGRATORS')
487
488
        # check if this point is being used by microgrid battery
489
        cursor.execute(" SELECT microgrid_id "
490
                       " FROM tbl_microgrids_batteries "
491
                       " WHERE battery_state_point_id = %s "
492
                       "    OR soc_point_id = %s "
493
                       "    OR power_point_id = %s "
494
                       " LIMIT 1",
495
                       (id_, id_, id_))
496
        row_microgrid_battery = cursor.fetchone()
497
        if row_microgrid_battery is not None:
498
            cursor.close()
499
            cnx.close()
500
            raise falcon.HTTPError(status=falcon.HTTP_400,
501
                                   title='API.BAD_REQUEST',
502
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_BATTERIES')
503
504
        # check if this point is being used by microgrid power conversion system
505
        cursor.execute("SELECT microgrid_id "
506
                       "FROM tbl_microgrids_power_conversion_systems "
507
                       "WHERE run_state_point_id = %s "
508
                       "   OR today_charge_energy_point_id = %s "
509
                       "   OR today_discharge_energy_point_id = %s "
510
                       "   OR total_charge_energy_point_id = %s "
511
                       "   OR total_discharge_energy_point_id = %s "
512
                       "LIMIT 1",
513
                       (id_, id_, id_, id_, id_))
514
        row_microgrid_power_conversion_system = cursor.fetchone()
515
        if row_microgrid_power_conversion_system is not None:
516
            cursor.close()
517
            cnx.close()
518
            raise falcon.HTTPError(status=falcon.HTTP_400,
519
                                   title='API.BAD_REQUEST',
520
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_POWER_CONVERSION_SYSTEMS')
521
522
        # check if this point is being used by microgrid evcharger
523
        cursor.execute(" SELECT microgrid_id "
524
                       " FROM tbl_microgrids_evchargers "
525
                       " WHERE power_point_id = %s "
526
                       " LIMIT 1 ",
527
                       (id_,))
528
        row_microgrid_evcharger = cursor.fetchone()
529
        if row_microgrid_evcharger is not None:
530
            cursor.close()
531
            cnx.close()
532
            raise falcon.HTTPError(status=falcon.HTTP_400,
533
                                   title='API.BAD_REQUEST',
534
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_EVCHARGERS')
535
536
        # check if this point is being used by microgrid generator
537
        cursor.execute(" SELECT microgrid_id "
538
                       " FROM tbl_microgrids_generators "
539
                       " WHERE power_point_id = %s "
540
                       " LIMIT 1 ",
541
                       (id_,))
542
        row_microgrid_generator = cursor.fetchone()
543
        if row_microgrid_generator is not None:
544
            cursor.close()
545
            cnx.close()
546
            raise falcon.HTTPError(status=falcon.HTTP_400,
547
                                   title='API.BAD_REQUEST',
548
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_GENERATORS')
549
550
        # check if this point is being used by microgrid grid
551
        cursor.execute(" SELECT microgrid_id "
552
                       " FROM tbl_microgrids_grids "
553
                       " WHERE power_point_id = %s "
554
                       " LIMIT 1 ",
555
                       (id_,))
556
        row_microgrid_grid = cursor.fetchone()
557
        if row_microgrid_grid is not None:
558
            cursor.close()
559
            cnx.close()
560
            raise falcon.HTTPError(status=falcon.HTTP_400,
561
                                   title='API.BAD_REQUEST',
562
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_GRIDS')
563
564
        # check if this point is being used by microgrid heatpump
565
        cursor.execute(" SELECT microgrid_id "
566
                       " FROM tbl_microgrids_heatpumps "
567
                       " WHERE power_point_id = %s "
568
                       " LIMIT 1 ",
569
                       (id_,))
570
        row_microgrid_heatpump = cursor.fetchone()
571
        if row_microgrid_heatpump is not None:
572
            cursor.close()
573
            cnx.close()
574
            raise falcon.HTTPError(status=falcon.HTTP_400,
575
                                   title='API.BAD_REQUEST',
576
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_HEATPUMPS')
577
578
        # check if this point is being used by microgrid load
579
        cursor.execute(" SELECT microgrid_id "
580
                       " FROM tbl_microgrids_loads "
581
                       " WHERE power_point_id = %s "
582
                       " LIMIT 1 ",
583
                       (id_,))
584
        row_microgrid_load = cursor.fetchone()
585
        if row_microgrid_load is not None:
586
            cursor.close()
587
            cnx.close()
588
            raise falcon.HTTPError(status=falcon.HTTP_400,
589
                                   title='API.BAD_REQUEST',
590
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_LOADS')
591
592
        # check if this point is being used by microgrid photovoltaic
593
        cursor.execute(" SELECT microgrid_id "
594
                       " FROM tbl_microgrids_photovoltaics "
595
                       " WHERE power_point_id = %s "
596
                       " LIMIT 1 ",
597
                       (id_,))
598
        row_microgrid_photovoltaic = cursor.fetchone()
599
        if row_microgrid_photovoltaic is not None:
600
            cursor.close()
601
            cnx.close()
602
            raise falcon.HTTPError(status=falcon.HTTP_400,
603
                                   title='API.BAD_REQUEST',
604
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS_PHOTOVOLTAICS')
605
606
        # check if this point is being used by virtual power plant
607
        cursor.execute(" SELECT name "
608
                       " FROM tbl_virtual_power_plants "
609
                       " WHERE balancing_price_point_id = %s "
610
                       " LIMIT 1 ",
611
                       (id_,))
612
        row_virtual_power_plant = cursor.fetchone()
613
        if row_virtual_power_plant is not None:
614
            cursor.close()
615
            cnx.close()
616
            raise falcon.HTTPError(status=falcon.HTTP_400,
617
                                   title='API.BAD_REQUEST',
618
                                   description='API.THERE_IS_RELATION_WITH_VIRTUAL_POWER_PLANTS')
619
620
        # check if this point is being used by energy storage container battery
621
        cursor.execute(" SELECT name "
622
                       " FROM tbl_energy_storage_containers_batteries "
623
                       " WHERE battery_state_point_id = %s "
624
                       "   OR soc_point_id = %s "
625
                       "   OR power_point_id = %s "
626
                       " LIMIT 1 ", (id_, id_, id_,))
627
        row_energy_storage_container_battery = cursor.fetchone()
628
        if row_energy_storage_container_battery is not None:
629
            cursor.close()
630
            cnx.close()
631
            raise falcon.HTTPError(status=falcon.HTTP_400,
632
                                   title='API.BAD_REQUEST',
633
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_BATTERIES')
634
635
        cursor.execute(" SELECT id "
636
                       " FROM tbl_energy_storage_containers_bmses_points "
637
                       " WHERE point_id = %s "
638
                       " LIMIT 1 ", (id_, ))
639
        row_energy_storage_container_battery = cursor.fetchone()
640
        if row_energy_storage_container_battery is not None:
641
            cursor.close()
642
            cnx.close()
643
            raise falcon.HTTPError(status=falcon.HTTP_400,
644
                                   title='API.BAD_REQUEST',
645
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_BATTERIES')
646
        # check if this point is being used by energy storage container dcdc
647
        cursor.execute(" SELECT id "
648
                       " FROM tbl_energy_storage_containers_dcdcs_points "
649
                       " WHERE point_id = %s "
650
                       " LIMIT 1 ", (id_, ))
651
        row_energy_storage_container_dcdc = cursor.fetchone()
652
        if row_energy_storage_container_dcdc is not None:
653
            cursor.close()
654
            cnx.close()
655
            raise falcon.HTTPError(status=falcon.HTTP_400,
656
                                   title='API.BAD_REQUEST',
657
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_DCDCS')
658
        # check if this point is being used by energy storage container firecontrol
659
        cursor.execute(" SELECT id "
660
                       " FROM tbl_energy_storage_containers_firecontrols_points "
661
                       " WHERE point_id = %s "
662
                       " LIMIT 1 ", (id_,))
663
        row_energy_storage_container_dcdc = cursor.fetchone()
664
        if row_energy_storage_container_dcdc is not None:
665
            cursor.close()
666
            cnx.close()
667
            raise falcon.HTTPError(status=falcon.HTTP_400,
668
                                   title='API.BAD_REQUEST',
669
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_FIRECONTROLS')
670
671
        # check if this point is being used by energy storage container grid
672
        cursor.execute(" SELECT name "
673
                       " FROM tbl_energy_storage_containers_grids "
674
                       " WHERE power_point_id = %s "
675
                       " LIMIT 1 ",
676
                       (id_,))
677
        row_energy_storage_container_grid = cursor.fetchone()
678
        if row_energy_storage_container_grid is not None:
679
            cursor.close()
680
            cnx.close()
681
            raise falcon.HTTPError(status=falcon.HTTP_400,
682
                                   title='API.BAD_REQUEST',
683
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_GRIDS')
684
685
        cursor.execute(" SELECT id "
686
                       " FROM tbl_energy_storage_containers_grids_points "
687
                       " WHERE point_id = %s "
688
                       " LIMIT 1 ",
689
                       (id_,))
690
        row_energy_storage_container_grid = cursor.fetchone()
691
        if row_energy_storage_container_grid is not None:
692
            cursor.close()
693
            cnx.close()
694
            raise falcon.HTTPError(status=falcon.HTTP_400,
695
                                   title='API.BAD_REQUEST',
696
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_GRIDS')
697
698
        # check if this point is being used by energy storage container hvac
699
        cursor.execute(" SELECT id "
700
                       " FROM tbl_energy_storage_containers_hvacs_points "
701
                       " WHERE point_id = %s "
702
                       " LIMIT 1 ",
703
                       (id_,))
704
        row_energy_storage_container_hvac = cursor.fetchone()
705
        if row_energy_storage_container_hvac is not None:
706
            cursor.close()
707
            cnx.close()
708
            raise falcon.HTTPError(status=falcon.HTTP_400,
709
                                   title='API.BAD_REQUEST',
710
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_HVACS')
711
712
        # check if this point is being used by energy storage container load
713
        cursor.execute(" SELECT name "
714
                       " FROM tbl_energy_storage_containers_loads "
715
                       " WHERE power_point_id = %s "
716
                       " LIMIT 1 ",
717
                       (id_,))
718
        row_energy_storage_container_load = cursor.fetchone()
719
        if row_energy_storage_container_load is not None:
720
            cursor.close()
721
            cnx.close()
722
            raise falcon.HTTPError(status=falcon.HTTP_400,
723
                                   title='API.BAD_REQUEST',
724
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_LOADS')
725
        cursor.execute(" SELECT id "
726
                       " FROM tbl_energy_storage_containers_loads_points "
727
                       " WHERE point_id = %s "
728
                       " LIMIT 1 ",
729
                       (id_,))
730
        row_energy_storage_container_load = cursor.fetchone()
731
        if row_energy_storage_container_load is not None:
732
            cursor.close()
733
            cnx.close()
734
            raise falcon.HTTPError(status=falcon.HTTP_400,
735
                                   title='API.BAD_REQUEST',
736
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_LOADS')
737
738
        # check if this point is being used by energy storage container power conversion system
739
        cursor.execute(" SELECT name "
740
                       " FROM tbl_energy_storage_containers_power_conversion_systems "
741
                       " WHERE run_state_point_id = %s "
742
                       " LIMIT 1 ",
743
                       (id_, ))
744
        row_energy_storage_container_power_conversion_system = cursor.fetchone()
745
        if row_energy_storage_container_power_conversion_system is not None:
746
            cursor.close()
747
            cnx.close()
748
            raise falcon.HTTPError(status=falcon.HTTP_400,
749
                                   title='API.BAD_REQUEST',
750
                                   description=
751
                                   'API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_POWER_CONVERSION_SYSTEMS')
752
        cursor.execute(" SELECT id "
753
                       " FROM tbl_energy_storage_containers_pcses_points "
754
                       " WHERE point_id = %s "
755
                       " LIMIT 1 ",
756
                       (id_,))
757
        row_energy_storage_container_power_conversion_system = cursor.fetchone()
758
        if row_energy_storage_container_power_conversion_system is not None:
759
            cursor.close()
760
            cnx.close()
761
            raise falcon.HTTPError(status=falcon.HTTP_400,
762
                                   title='API.BAD_REQUEST',
763
                                   description=
764
                                   'API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_POWER_CONVERSION_SYSTEMS')
765
766
        # check if this point is being used by energy storage container sts
767
        cursor.execute(" SELECT id "
768
                       " FROM tbl_energy_storage_containers_stses_points "
769
                       " WHERE point_id = %s "
770
                       " LIMIT 1 ",
771
                       (id_,))
772
        row_energy_storage_container_sts = cursor.fetchone()
773
        if row_energy_storage_container_sts is not None:
774
            cursor.close()
775
            cnx.close()
776
            raise falcon.HTTPError(status=falcon.HTTP_400,
777
                                   title='API.BAD_REQUEST',
778
                                   description=
779
                                   'API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_CONTAINERS_STSES')
780
781
        cursor.execute(" DELETE FROM tbl_points WHERE id = %s ", (id_,))
782
        cnx.commit()
783
784
        cursor.close()
785
        cnx.close()
786
787
        resp.status = falcon.HTTP_204
788
789
    @staticmethod
790
    @user_logger
791
    def on_put(req, resp, id_):
792
        """Handles PUT requests"""
793
        admin_control(req)
794
        try:
795
            raw_json = req.stream.read().decode('utf-8')
796
        except Exception as ex:
797
            raise falcon.HTTPError(status=falcon.HTTP_400,
798
                                   title='API.BAD_REQUEST',
799
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
800
801
        if not id_.isdigit() or int(id_) <= 0:
802
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
803
                                   description='API.INVALID_POINT_ID')
804
805
        new_values = json.loads(raw_json)
806
807
        if 'name' not in new_values['data'].keys() or \
808
                not isinstance(new_values['data']['name'], str) or \
809
                len(str.strip(new_values['data']['name'])) == 0:
810
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
811
                                   description='API.INVALID_POINT_NAME')
812
        name = str.strip(new_values['data']['name'])
813
814
        if 'data_source_id' not in new_values['data'].keys() or \
815
                not isinstance(new_values['data']['data_source_id'], int) or \
816
                new_values['data']['data_source_id'] <= 0:
817
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
818
                                   description='API.INVALID_DATA_SOURCE_ID')
819
        data_source_id = new_values['data']['data_source_id']
820
821
        if 'object_type' not in new_values['data'].keys() \
822
                or str.strip(new_values['data']['object_type']) not in \
823
                ('ENERGY_VALUE', 'ANALOG_VALUE', 'DIGITAL_VALUE', 'TEXT_VALUE'):
824
            raise falcon.HTTPError(status=falcon.HTTP_400,
825
                                   title='API.BAD_REQUEST',
826
                                   description='API.INVALID_OBJECT_TYPE')
827
        object_type = str.strip(new_values['data']['object_type'])
828
829
        if 'units' not in new_values['data'].keys() or \
830
                not isinstance(new_values['data']['units'], str) or \
831
                len(str.strip(new_values['data']['units'])) == 0:
832
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
833
                                   description='API.INVALID_UNITS')
834
        units = str.strip(new_values['data']['units'])
835
836
        if 'high_limit' not in new_values['data'].keys() or \
837
                not (isinstance(new_values['data']['high_limit'], float) or
838
                     isinstance(new_values['data']['high_limit'], int)):
839
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
840
                                   description='API.INVALID_HIGH_LIMIT_VALUE')
841
        high_limit = new_values['data']['high_limit']
842
843
        if 'low_limit' not in new_values['data'].keys() or \
844
                not (isinstance(new_values['data']['low_limit'], float) or
845
                     isinstance(new_values['data']['low_limit'], int)):
846
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
847
                                   description='API.INVALID_LOW_LIMIT_VALUE')
848
        low_limit = new_values['data']['low_limit']
849
850
        # the higher_limit is optional
851
        if 'higher_limit' not in new_values['data'].keys() or \
852
                new_values['data']['higher_limit'] is None:
853
            higher_limit = None
854
        elif not (isinstance(new_values['data']['higher_limit'], float) or
855
                  isinstance(new_values['data']['higher_limit'], int)):
856
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
857
                                   description='API.INVALID_HIGHER_LIMIT_VALUE')
858
        else:
859
            higher_limit = new_values['data']['higher_limit']
860
861
        # the lower_limit is optional
862
        if 'lower_limit' not in new_values['data'].keys() or \
863
                new_values['data']['lower_limit'] is None:
864
            lower_limit = None
865
        elif not (isinstance(new_values['data']['lower_limit'], float) or
866
                  isinstance(new_values['data']['lower_limit'], int)):
867
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
868
                                   description='API.INVALID_LOWER_LIMIT_VALUE')
869
        else:
870
            lower_limit = new_values['data']['lower_limit']
871
872
        if 'ratio' not in new_values['data'].keys() or \
873
                not (isinstance(new_values['data']['ratio'], float) or
874
                     isinstance(new_values['data']['ratio'], int)):
875
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
876
                                   description='API.INVALID_RATIO_VALUE')
877
        ratio = new_values['data']['ratio']
878
879
        if 'offset_constant' not in new_values['data'].keys() or \
880
                not (isinstance(new_values['data']['offset_constant'], float) or
881
                     isinstance(new_values['data']['offset_constant'], int)):
882
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
883
                                   description='API.INVALID_OFFSET_CONSTANT_VALUE')
884
        offset_constant = new_values['data']['offset_constant']
885
886
        if 'is_trend' not in new_values['data'].keys() or \
887
                not isinstance(new_values['data']['is_trend'], bool):
888
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
889
                                   description='API.INVALID_IS_TREND_VALUE')
890
        is_trend = new_values['data']['is_trend']
891
892
        if 'is_virtual' not in new_values['data'].keys() or \
893
                not isinstance(new_values['data']['is_virtual'], bool):
894
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
895
                                   description='API.INVALID_IS_VIRTUAL_VALUE')
896
        if new_values['data']['is_virtual'] is True and object_type == 'DIGITAL_VALUE':
897
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
898
                                   description='API.VIRTUAL_POINT_CAN_NOT_BE_DIGITAL_VALUE')
899
        if new_values['data']['is_virtual'] is True and object_type == 'TEXT_VALUE':
900
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
901
                                   description='API.VIRTUAL_POINT_CAN_NOT_BE_TEXT_VALUE')
902
        is_virtual = new_values['data']['is_virtual']
903
904
        if 'address' not in new_values['data'].keys() or \
905
                not isinstance(new_values['data']['address'], str) or \
906
                len(str.strip(new_values['data']['address'])) == 0:
907
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
908
                                   description='API.INVALID_ADDRESS')
909
        address = str.strip(new_values['data']['address'])
910
911
        if 'description' in new_values['data'].keys() and \
912
                new_values['data']['description'] is not None and \
913
                len(str(new_values['data']['description'])) > 0:
914
            description = str.strip(new_values['data']['description'])
915
        else:
916
            description = None
917
918
        if 'faults' in new_values['data'].keys() and \
919
                new_values['data']['faults'] is not None and \
920
                len(str(new_values['data']['faults'])) > 0:
921
            faults = str.strip(new_values['data']['faults'])
922
        else:
923
            faults = None
924
925
        if 'definitions' in new_values['data'].keys() and \
926
                new_values['data']['definitions'] is not None and \
927
                len(str(new_values['data']['definitions'])) > 0:
928
            definitions = str.strip(new_values['data']['definitions'])
929
        else:
930
            definitions = None
931
        cnx = mysql.connector.connect(**config.myems_system_db)
932
        cursor = cnx.cursor()
933
934
        cursor.execute(" SELECT name "
935
                       " FROM tbl_points "
936
                       " WHERE id = %s ", (id_,))
937
        if cursor.fetchone() is None:
938
            cursor.close()
939
            cnx.close()
940
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
941
                                   description='API.POINT_NOT_FOUND')
942
943
        cursor.execute(" SELECT name "
944
                       " FROM tbl_data_sources "
945
                       " WHERE id = %s ", (data_source_id,))
946
        if cursor.fetchone() is None:
947
            cursor.close()
948
            cnx.close()
949
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
950
                                   description='API.INVALID_DATA_SOURCE_ID')
951
952
        cursor.execute(" SELECT name "
953
                       " FROM tbl_points "
954
                       " WHERE name = %s AND data_source_id = %s AND id != %s ", (name, data_source_id, id_))
955
        if cursor.fetchone() is not None:
956
            cursor.close()
957
            cnx.close()
958
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
959
                                   description='API.POINT_NAME_IS_ALREADY_IN_USE')
960
961
        update_row = (" UPDATE tbl_points "
962
                      " SET name = %s, data_source_id = %s, "
963
                      "     object_type = %s, units = %s, "
964
                      "     high_limit = %s, low_limit = %s, higher_limit = %s, lower_limit = %s, ratio = %s, "
965
                      "     offset_constant = %s, is_trend = %s, is_virtual = %s, address = %s, description = %s, "
966
                      "     faults = %s, definitions = %s "
967
                      " WHERE id = %s ")
968
        cursor.execute(update_row, (name,
969
                                    data_source_id,
970
                                    object_type,
971
                                    units,
972
                                    high_limit,
973
                                    low_limit,
974
                                    higher_limit,
975
                                    lower_limit,
976
                                    ratio,
977
                                    offset_constant,
978
                                    is_trend,
979
                                    is_virtual,
980
                                    address,
981
                                    description,
982
                                    faults,
983
                                    definitions,
984
                                    id_,))
985
        cnx.commit()
986
987
        cursor.close()
988
        cnx.close()
989
990
        resp.status = falcon.HTTP_200
991
992
993
class PointLimit:
994
    def __init__(self):
995
        """"Initializes PointLimit"""
996
        pass
997
998
    @staticmethod
999
    def on_options(req, resp, id_):
1000
        resp.status = falcon.HTTP_200
1001
1002
    @staticmethod
1003
    @user_logger
1004
    def on_put(req, resp, id_):
1005
        """Handles PUT requests"""
1006
        admin_control(req)
1007
        try:
1008
            raw_json = req.stream.read().decode('utf-8')
1009
        except Exception as ex:
1010
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.EXCEPTION', description=str(ex))
1011
1012
        if not id_.isdigit() or int(id_) <= 0:
1013
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1014
                                   description='API.INVALID_POINT_ID')
1015
1016
        new_values = json.loads(raw_json)
1017
1018
        if 'high_limit' not in new_values['data'].keys() or \
1019
                not (isinstance(new_values['data']['high_limit'], float) or
1020
                     isinstance(new_values['data']['high_limit'], int)):
1021
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1022
                                   description='API.INVALID_HIGH_LIMIT_VALUE')
1023
        high_limit = new_values['data']['high_limit']
1024
1025
        if 'low_limit' not in new_values['data'].keys() or \
1026
                not (isinstance(new_values['data']['low_limit'], float) or
1027
                     isinstance(new_values['data']['low_limit'], int)):
1028
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1029
                                   description='API.INVALID_LOW_LIMIT_VALUE')
1030
        low_limit = new_values['data']['low_limit']
1031
1032
        if 'higher_limit' not in new_values['data'].keys() or \
1033
                not (isinstance(new_values['data']['higher_limit'], float) or
1034
                     isinstance(new_values['data']['higher_limit'], int)):
1035
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1036
                                   description='API.INVALID_HIGHER_LIMIT_VALUE')
1037
        higher_limit = new_values['data']['higher_limit']
1038
1039
        if 'lower_limit' not in new_values['data'].keys() or \
1040
                not (isinstance(new_values['data']['lower_limit'], float) or
1041
                     isinstance(new_values['data']['lower_limit'], int)):
1042
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1043
                                   description='API.INVALID_LOWER_LIMIT_VALUE')
1044
        lower_limit = new_values['data']['lower_limit']
1045
1046
        cnx = mysql.connector.connect(**config.myems_system_db)
1047
        cursor = cnx.cursor()
1048
1049
        cursor.execute(" SELECT name "
1050
                       " FROM tbl_points "
1051
                       " WHERE id = %s ", (id_,))
1052
        if cursor.fetchone() is None:
1053
            cursor.close()
1054
            cnx.close()
1055
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1056
                                   description='API.POINT_NOT_FOUND')
1057
1058
        update_row = (" UPDATE tbl_points "
1059
                      " SET  high_limit = %s, low_limit = %s, higher_limit = %s, lower_limit = %s "
1060
                      " WHERE id = %s ")
1061
        cursor.execute(update_row, (high_limit,
1062
                                    low_limit,
1063
                                    higher_limit,
1064
                                    lower_limit,
1065
                                    id_,))
1066
        cnx.commit()
1067
1068
        cursor.close()
1069
        cnx.close()
1070
1071
        resp.status = falcon.HTTP_200
1072
1073
1074
class PointExport:
1075
    def __init__(self):
1076
        """"Initializes PointExport"""
1077
        pass
1078
1079
    @staticmethod
1080
    def on_options(req, resp, id_):
1081
        resp.status = falcon.HTTP_200
1082
1083 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1084
    def on_get(req, resp, id_):
1085
        """Handles GET requests"""
1086
        admin_control(req)
1087
        if not id_.isdigit() or int(id_) <= 0:
1088
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1089
                                   description='API.INVALID_POINT_ID')
1090
1091
        cnx = mysql.connector.connect(**config.myems_system_db)
1092
        cursor = cnx.cursor()
1093
1094
        query = (" SELECT id, name, uuid "
1095
                 " FROM tbl_data_sources ")
1096
        cursor.execute(query)
1097
        rows_data_sources = cursor.fetchall()
1098
1099
        data_source_dict = dict()
1100
        if rows_data_sources is not None and len(rows_data_sources) > 0:
1101
            for row in rows_data_sources:
1102
                data_source_dict[row[0]] = {"id": row[0],
1103
                                            "name": row[1],
1104
                                            "uuid": row[2]}
1105
1106
        query = (" SELECT id, name, data_source_id, object_type, units, "
1107
                 "        high_limit, low_limit, higher_limit, lower_limit, ratio, offset_constant, "
1108
                 "        is_trend, is_virtual, address, description, faults, definitions "
1109
                 " FROM tbl_points "
1110
                 " WHERE id = %s ")
1111
        cursor.execute(query, (id_,))
1112
        row = cursor.fetchone()
1113
        cursor.close()
1114
        cnx.close()
1115
        if row is None:
1116
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1117
                                   description='API.POINT_NOT_FOUND')
1118
1119
        result = {"id": row[0],
1120
                  "name": row[1],
1121
                  "data_source": data_source_dict.get(row[2], None),
1122
                  "object_type": row[3],
1123
                  "units": row[4],
1124
                  "high_limit": row[5],
1125
                  "low_limit": row[6],
1126
                  "higher_limit": row[7],
1127
                  "lower_limit": row[8],
1128
                  "ratio": Decimal(row[9]),
1129
                  "offset_constant": Decimal(row[10]),
1130
                  "is_trend": bool(row[11]),
1131
                  "is_virtual": bool(row[12]),
1132
                  "address": row[13],
1133
                  "description": row[14],
1134
                  "faults": row[15],
1135
                  "definitions": row[16]}
1136
        resp.text = json.dumps(result)
1137
1138
1139
class PointImport:
1140
    def __init__(self):
1141
        """"Initializes PointImport"""
1142
        pass
1143
1144
    @staticmethod
1145
    def on_options(req, resp):
1146
        resp.status = falcon.HTTP_200
1147
1148
    @staticmethod
1149
    @user_logger
1150
    def on_post(req, resp):
1151
        """Handles POST requests"""
1152
        admin_control(req)
1153
        try:
1154
            raw_json = req.stream.read().decode('utf-8')
1155
        except Exception as ex:
1156
            raise falcon.HTTPError(status=falcon.HTTP_400,
1157
                                   title='API.BAD_REQUEST',
1158
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1159
1160
        new_values = json.loads(raw_json)
1161
1162
        if 'name' not in new_values.keys() or \
1163
                not isinstance(new_values['name'], str) or \
1164
                len(str.strip(new_values['name'])) == 0:
1165
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1166
                                   description='API.INVALID_POINT_NAME')
1167
        name = str.strip(new_values['name'])
1168
1169
        if 'id' not in new_values['data_source'].keys() or \
1170
                not isinstance(new_values['data_source']['id'], int) or \
1171
                new_values['data_source']['id'] <= 0:
1172
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1173
                                   description='API.INVALID_DATA_SOURCE_ID')
1174
        data_source_id = new_values['data_source']['id']
1175
1176
        if 'object_type' not in new_values.keys() \
1177
                or str.strip(new_values['object_type']) not in (
1178
                'ENERGY_VALUE', 'ANALOG_VALUE', 'DIGITAL_VALUE', 'TEXT_VALUE'):
1179
            raise falcon.HTTPError(status=falcon.HTTP_400,
1180
                                   title='API.BAD_REQUEST',
1181
                                   description='API.INVALID_OBJECT_TYPE')
1182
        object_type = str.strip(new_values['object_type'])
1183
1184
        if 'units' not in new_values.keys() or \
1185
                not isinstance(new_values['units'], str) or \
1186
                len(str.strip(new_values['units'])) == 0:
1187
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1188
                                   description='API.INVALID_UNITS')
1189
        units = str.strip(new_values['units'])
1190
1191
        if 'high_limit' not in new_values.keys() or \
1192
                not (isinstance(new_values['high_limit'], float) or
1193
                     isinstance(new_values['high_limit'], int)):
1194
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1195
                                   description='API.INVALID_HIGH_LIMIT_VALUE')
1196
        high_limit = new_values['high_limit']
1197
1198
        if 'low_limit' not in new_values.keys() or \
1199
                not (isinstance(new_values['low_limit'], float) or
1200
                     isinstance(new_values['low_limit'], int)):
1201
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1202
                                   description='API.INVALID_LOW_LIMIT_VALUE')
1203
        low_limit = new_values['low_limit']
1204
1205
        # the higher_limit is optional
1206
        if 'higher_limit' not in new_values.keys() or \
1207
                new_values['higher_limit'] is None:
1208
            higher_limit = None
1209
        elif not (isinstance(new_values['higher_limit'], float) or
1210
                  isinstance(new_values['higher_limit'], int)):
1211
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1212
                                   description='API.INVALID_HIGHER_LIMIT_VALUE')
1213
        else:
1214
            higher_limit = new_values['higher_limit']
1215
1216
        # the lower_limit is optional
1217
        if 'lower_limit' not in new_values.keys() or \
1218
                new_values['lower_limit'] is None:
1219
            lower_limit = None
1220
        elif not (isinstance(new_values['lower_limit'], float) or
1221
                  isinstance(new_values['lower_limit'], int)):
1222
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1223
                                   description='API.INVALID_LOWER_LIMIT_VALUE')
1224
        else:
1225
            lower_limit = new_values['lower_limit']
1226
1227
        if 'ratio' not in new_values.keys() or \
1228
                not (isinstance(new_values['ratio'], float) or
1229
                     isinstance(new_values['ratio'], int)):
1230
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1231
                                   description='API.INVALID_RATIO_VALUE')
1232
        ratio = new_values['ratio']
1233
1234
        if 'offset_constant' not in new_values.keys() or \
1235
                not (isinstance(new_values['offset_constant'], float) or
1236
                     isinstance(new_values['offset_constant'], int)):
1237
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1238
                                   description='API.INVALID_OFFSET_CONSTANT_VALUE')
1239
        offset_constant = new_values['offset_constant']
1240
1241
        if 'is_trend' not in new_values.keys() or \
1242
                not isinstance(new_values['is_trend'], bool):
1243
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1244
                                   description='API.INVALID_IS_TREND_VALUE')
1245
        is_trend = new_values['is_trend']
1246
1247
        if 'is_virtual' not in new_values.keys() or \
1248
                not isinstance(new_values['is_virtual'], bool):
1249
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1250
                                   description='API.INVALID_IS_VIRTUAL_VALUE')
1251
        if new_values['is_virtual'] is True and object_type == 'DIGITAL_VALUE':
1252
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1253
                                   description='API.VIRTUAL_POINT_CAN_NOT_BE_DIGITAL_VALUE')
1254
        if new_values['is_virtual'] is True and object_type == 'TEXT_VALUE':
1255
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1256
                                   description='API.VIRTUAL_POINT_CAN_NOT_BE_TEXT_VALUE')
1257
        is_virtual = new_values['is_virtual']
1258
1259
        if 'address' not in new_values.keys() or \
1260
                not isinstance(new_values['address'], str) or \
1261
                len(str.strip(new_values['address'])) == 0:
1262
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1263
                                   description='API.INVALID_ADDRESS')
1264
        address = str.strip(new_values['address'])
1265
1266
        if 'description' in new_values.keys() and \
1267
                new_values['description'] is not None and \
1268
                len(str(new_values['description'])) > 0:
1269
            description = str.strip(new_values['description'])
1270
        else:
1271
            description = None
1272
1273
        if 'faults' in new_values.keys() and \
1274
                new_values['faults'] is not None and \
1275
                len(str(new_values['faults'])) > 0:
1276
            faults = str.strip(new_values['faults'])
1277
        else:
1278
            faults = None
1279
1280
        if 'definitions' in new_values.keys() and \
1281
                new_values['definitions'] is not None and \
1282
                len(str(new_values['definitions'])) > 0:
1283
            definitions = str.strip(new_values['definitions'])
1284
        else:
1285
            definitions = None
1286
1287
        cnx = mysql.connector.connect(**config.myems_system_db)
1288
        cursor = cnx.cursor()
1289
1290
        cursor.execute(" SELECT name "
1291
                       " FROM tbl_points "
1292
                       " WHERE name = %s AND data_source_id = %s ", (name, data_source_id))
1293
        if cursor.fetchone() is not None:
1294
            cursor.close()
1295
            cnx.close()
1296
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1297
                                   description='API.POINT_NAME_IS_ALREADY_IN_USE')
1298
1299
        cursor.execute(" SELECT name "
1300
                       " FROM tbl_data_sources "
1301
                       " WHERE id = %s ", (data_source_id,))
1302
        if cursor.fetchone() is None:
1303
            cursor.close()
1304
            cnx.close()
1305
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1306
                                   description='API.INVALID_DATA_SOURCE_ID')
1307
1308
        add_value = (" INSERT INTO tbl_points (name, data_source_id, object_type, units, "
1309
                     "                         high_limit, low_limit, higher_limit, lower_limit, ratio, "
1310
                     "                         offset_constant, is_trend, is_virtual, address, description, faults, "
1311
                     "                         definitions) "
1312
                     " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
1313
        cursor.execute(add_value, (name,
1314
                                   data_source_id,
1315
                                   object_type,
1316
                                   units,
1317
                                   high_limit,
1318
                                   low_limit,
1319
                                   higher_limit,
1320
                                   lower_limit,
1321
                                   ratio,
1322
                                   offset_constant,
1323
                                   is_trend,
1324
                                   is_virtual,
1325
                                   address,
1326
                                   description,
1327
                                   faults,
1328
                                   definitions))
1329
        new_id = cursor.lastrowid
1330
        cnx.commit()
1331
        cursor.close()
1332
        cnx.close()
1333
1334
        resp.status = falcon.HTTP_201
1335
        resp.location = '/points/' + str(new_id)
1336
1337
1338
class PointClone:
1339
    def __init__(self):
1340
        """"Initializes PointClone"""
1341
        pass
1342
1343
    @staticmethod
1344
    def on_options(req, resp, id_):
1345
        resp.status = falcon.HTTP_200
1346
1347
    @staticmethod
1348
    @user_logger
1349
    def on_post(req, resp, id_):
1350
        admin_control(req)
1351
        if not id_.isdigit() or int(id_) <= 0:
1352
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1353
                                   description='API.INVALID_POINT_ID')
1354
1355
        cnx = mysql.connector.connect(**config.myems_system_db)
1356
        cursor = cnx.cursor()
1357
1358
        query = (" SELECT id, name, data_source_id, object_type, units, "
1359
                 "        high_limit, low_limit, higher_limit, lower_limit, ratio, offset_constant, "
1360
                 "        is_trend, is_virtual, address, description, faults, definitions "
1361
                 " FROM tbl_points "
1362
                 " WHERE id = %s ")
1363
        cursor.execute(query, (id_,))
1364
        row = cursor.fetchone()
1365
        if row is None:
1366
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1367
                                   description='API.POINT_NOT_FOUND')
1368
1369
        result = {"id": row[0],
1370
                  "name": row[1],
1371
                  "data_source_id": row[2],
1372
                  "object_type": row[3],
1373
                  "units": row[4],
1374
                  "high_limit": row[5],
1375
                  "low_limit": row[6],
1376
                  "higher_limit": row[7],
1377
                  "lower_limit": row[8],
1378
                  "ratio": Decimal(row[9]),
1379
                  "offset_constant": Decimal(row[10]),
1380
                  "is_trend": bool(row[11]),
1381
                  "is_virtual": bool(row[12]),
1382
                  "address": row[13],
1383
                  "description": row[14],
1384
                  "faults": row[15],
1385
                  "definitions": row[16]}
1386
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
1387
        if config.utc_offset[0] == '-':
1388
            timezone_offset = -timezone_offset
1389
        new_name = (str.strip(result['name']) +
1390
                    (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
1391
        add_value = (" INSERT INTO tbl_points (name, data_source_id, object_type, units, "
1392
                     "                         high_limit, low_limit, higher_limit, lower_limit, ratio, "
1393
                     "                         offset_constant, is_trend, is_virtual, address, description, faults, "
1394
                     "                         definitions) "
1395
                     " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
1396
        cursor.execute(add_value, (new_name,
1397
                                   result['data_source_id'],
1398
                                   result['object_type'],
1399
                                   result['units'],
1400
                                   result['high_limit'],
1401
                                   result['low_limit'],
1402
                                   result['higher_limit'],
1403
                                   result['lower_limit'],
1404
                                   result['ratio'],
1405
                                   result['offset_constant'],
1406
                                   result['is_trend'],
1407
                                   result['is_virtual'],
1408
                                   result['address'],
1409
                                   result['description'],
1410
                                   result['faults'],
1411
                                   result['definitions']))
1412
        new_id = cursor.lastrowid
1413
        cnx.commit()
1414
        cursor.close()
1415
        cnx.close()
1416
1417
        resp.status = falcon.HTTP_201
1418
        resp.location = '/points/' + str(new_id)
1419
1420