core.shopfloor   F
last analyzed

Complexity

Total Complexity 604

Size/Duplication

Total Lines 3293
Duplicated Lines 46.43 %

Importance

Changes 0
Metric Value
wmc 604
eloc 2435
dl 1529
loc 3293
rs 0.8
c 0
b 0
f 0

74 Methods

Rating   Name   Duplication   Size   Complexity  
A ShopfloorPointItem.__init__() 0 2 1
D ShopfloorPointCollection.on_get() 50 50 13
A ShopfloorMeterItem.__init__() 2 2 1
D ShopfloorOfflineMeterCollection.on_get() 51 51 13
A ShopfloorEquipmentItem.on_options() 6 6 1
F ShopfloorCollection.on_post() 11 121 24
F ShopfloorItem.on_put() 11 133 27
C ShopfloorCommandCollection.on_get() 38 38 10
A ShopfloorWorkingCalendarCollection.__init__() 2 2 1
A ShopfloorWorkingCalendarItem.__init__() 0 2 1
C ShopfloorVirtualMeterCollection.on_post() 71 71 11
C ShopfloorMeterCollection.on_post() 74 74 11
C ShopfloorSensorCollection.on_get() 38 38 10
A ShopfloorItem.__init__() 0 2 1
F ShopfloorEquipmentCollection.on_get() 76 76 16
A ShopfloorPointCollection.on_options() 5 5 1
F ShopfloorMeterCollection.on_get() 89 89 19
C ShopfloorOfflineMeterCollection.on_post() 71 71 11
A ShopfloorCommandItem.on_options() 0 6 1
A ShopfloorOfflineMeterItem.on_options() 0 6 1
A ShopfloorEquipmentItem.__init__() 2 2 1
A ShopfloorCommandCollection.__init__() 2 2 1
A ShopfloorImport.on_options() 0 4 1
A ShopfloorCollection.__init__() 0 2 1
A ShopfloorMeterCollection.on_options() 5 5 1
F ShopfloorImport.on_post() 11 313 64
A ShopfloorEquipmentCollection.on_options() 5 5 1
A ShopfloorVirtualMeterItem.on_options() 0 6 1
B ShopfloorEquipmentItem.on_delete() 53 53 8
A ShopfloorVirtualMeterCollection.__init__() 2 2 1
C ShopfloorWorkingCalendarCollection.on_post() 71 71 11
A ShopfloorCollection.on_options() 0 11 1
A ShopfloorOfflineMeterCollection.__init__() 2 2 1
A ShopfloorVirtualMeterCollection.on_options() 5 5 1
A ShopfloorSensorItem.__init__() 0 2 1
C ShopfloorCommandCollection.on_post() 71 71 11
A ShopfloorPointCollection.__init__() 2 2 1
A ShopfloorClone.__init__() 0 2 1
B ShopfloorSensorItem.on_delete() 0 49 8
F ShopfloorCollection.on_get() 122 122 22
A ShopfloorEquipmentCollection.__init__() 2 2 1
A ShopfloorImport.__init__() 0 2 1
A ShopfloorOfflineMeterCollection.on_options() 5 5 1
A ShopfloorSensorCollection.on_options() 5 5 1
C ShopfloorSensorCollection.on_post() 71 71 11
A ShopfloorCommandCollection.on_options() 5 5 1
B ShopfloorVirtualMeterItem.on_delete() 0 50 8
A ShopfloorExport.__init__() 0 2 1
A ShopfloorSensorCollection.__init__() 2 2 1
B ShopfloorCommandItem.on_delete() 0 49 8
A ShopfloorMeterCollection.__init__() 2 2 1
A ShopfloorCommandItem.__init__() 0 2 1
C ShopfloorWorkingCalendarCollection.on_get() 38 38 10
A ShopfloorVirtualMeterItem.__init__() 0 2 1
F ShopfloorExport.on_get() 0 235 50
B ShopfloorItem.on_delete() 0 67 6
A ShopfloorItem.on_options() 0 5 1
A ShopfloorWorkingCalendarCollection.on_options() 5 5 1
A ShopfloorMeterItem.on_options() 6 6 1
A ShopfloorExport.on_options() 0 5 1
B ShopfloorMeterItem.on_delete() 52 52 8
F ShopfloorItem.on_get() 98 98 19
D ShopfloorVirtualMeterCollection.on_get() 51 51 13
A ShopfloorWorkingCalendarItem.on_options() 0 6 1
B ShopfloorWorkingCalendarItem.on_delete() 0 50 8
A ShopfloorOfflineMeterItem.__init__() 0 2 1
B ShopfloorPointItem.on_delete() 0 50 8
B ShopfloorOfflineMeterItem.on_delete() 0 50 8
C ShopfloorPointCollection.on_post() 71 71 11
A ShopfloorPointItem.on_options() 0 6 1
A ShopfloorSensorItem.on_options() 0 6 1
F ShopfloorClone.on_post() 0 444 88
C ShopfloorEquipmentCollection.on_post() 74 74 11
A ShopfloorClone.on_options() 0 5 1

1 Function

Rating   Name   Duplication   Size   Complexity  
B clear_shopfloor_cache() 56 56 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complexity

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

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

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

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