Passed
Push — master ( 46ddd0...0c924f )
by
unknown
12:05 queued 14s
created

core.point.PointSetValue.on_put()   B

Complexity

Conditions 8

Size

Total Lines 43
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

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