Issues (382)

reports/combinedequipmentefficiency.py (2 issues)

1
import falcon
2
import simplejson as json
3
import mysql.connector
4
import config
5
from datetime import datetime, timedelta, timezone
6
from core import utilities
7
from decimal import Decimal
8
9
10 View Code Duplication
class Reporting:
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
11
    @staticmethod
12
    def __init__():
13
        pass
14
15
    @staticmethod
16
    def on_options(req, resp):
17
        resp.status = falcon.HTTP_200
18
19
    ####################################################################################################################
20
    # PROCEDURES
21
    # Step 1: valid parameters
22
    # Step 2: query the combined equipment
23
    # Step 3: query associated equipments
24
    # Step 4: query energy categories
25
    # Step 5: query associated points
26
    # Step 6: query base period energy input
27
    # Step 7: query base period energy output
28
    # Step 8: query reporting period energy input
29
    # Step 9: query reporting period energy output
30
    # Step 10: query tariff data
31
    # Step 11: query associated points data
32
    # Step 12: construct the report
33
    ####################################################################################################################
34
    @staticmethod
35
    def on_get(req, resp):
36
        print(req.params)
37
        combined_equipment_id = req.params.get('combinedequipmentid')
38
        period_type = req.params.get('periodtype')
39
        base_start_datetime_local = req.params.get('baseperiodstartdatetime')
40
        base_end_datetime_local = req.params.get('baseperiodenddatetime')
41
        reporting_start_datetime_local = req.params.get('reportingperiodstartdatetime')
42
        reporting_end_datetime_local = req.params.get('reportingperiodenddatetime')
43
44
        ################################################################################################################
45
        # Step 1: valid parameters
46
        ################################################################################################################
47
        if combined_equipment_id is None:
48
            raise falcon.HTTPError(falcon.HTTP_400,
49
                                   title='API.BAD_REQUEST',
50
                                   description='API.INVALID_COMBINED_EQUIPMENT_ID')
51
        else:
52
            combined_equipment_id = str.strip(combined_equipment_id)
53
            if not combined_equipment_id.isdigit() or int(combined_equipment_id) <= 0:
54
                raise falcon.HTTPError(falcon.HTTP_400,
55
                                       title='API.BAD_REQUEST',
56
                                       description='API.INVALID_COMBINED_EQUIPMENT_ID')
57
58
        if period_type is None:
59
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_PERIOD_TYPE')
60
        else:
61
            period_type = str.strip(period_type)
62
            if period_type not in ['hourly', 'daily', 'monthly', 'yearly']:
63
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_PERIOD_TYPE')
64
65
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
66
        if config.utc_offset[0] == '-':
67
            timezone_offset = -timezone_offset
68
69
        base_start_datetime_utc = None
70
        if base_start_datetime_local is not None and len(str.strip(base_start_datetime_local)) > 0:
71
            base_start_datetime_local = str.strip(base_start_datetime_local)
72
            try:
73
                base_start_datetime_utc = datetime.strptime(base_start_datetime_local,
74
                                                            '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
75
                    timedelta(minutes=timezone_offset)
76
            except ValueError:
77
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
78
                                       description="API.INVALID_BASE_PERIOD_START_DATETIME")
79
80
        base_end_datetime_utc = None
81
        if base_end_datetime_local is not None and len(str.strip(base_end_datetime_local)) > 0:
82
            base_end_datetime_local = str.strip(base_end_datetime_local)
83
            try:
84
                base_end_datetime_utc = datetime.strptime(base_end_datetime_local,
85
                                                          '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
86
                    timedelta(minutes=timezone_offset)
87
            except ValueError:
88
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
89
                                       description="API.INVALID_BASE_PERIOD_END_DATETIME")
90
91
        if base_start_datetime_utc is not None and base_end_datetime_utc is not None and \
92
                base_start_datetime_utc >= base_end_datetime_utc:
93
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
94
                                   description='API.INVALID_BASE_PERIOD_END_DATETIME')
95
96
        if reporting_start_datetime_local is None:
97
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
98
                                   description="API.INVALID_REPORTING_PERIOD_START_DATETIME")
99
        else:
100
            reporting_start_datetime_local = str.strip(reporting_start_datetime_local)
101
            try:
102
                reporting_start_datetime_utc = datetime.strptime(reporting_start_datetime_local,
103
                                                                 '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
104
                    timedelta(minutes=timezone_offset)
105
            except ValueError:
106
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
107
                                       description="API.INVALID_REPORTING_PERIOD_START_DATETIME")
108
109
        if reporting_end_datetime_local is None:
110
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
111
                                   description="API.INVALID_REPORTING_PERIOD_END_DATETIME")
112
        else:
113
            reporting_end_datetime_local = str.strip(reporting_end_datetime_local)
114
            try:
115
                reporting_end_datetime_utc = datetime.strptime(reporting_end_datetime_local,
116
                                                               '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
117
                    timedelta(minutes=timezone_offset)
118
            except ValueError:
119
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
120
                                       description="API.INVALID_REPORTING_PERIOD_END_DATETIME")
121
122
        if reporting_start_datetime_utc >= reporting_end_datetime_utc:
123
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
124
                                   description='API.INVALID_REPORTING_PERIOD_END_DATETIME')
125
126
        ################################################################################################################
127
        # Step 2: query the combined equipment
128
        ################################################################################################################
129
        cnx_system = mysql.connector.connect(**config.myems_system_db)
130
        cursor_system = cnx_system.cursor()
131
132
        cnx_energy = mysql.connector.connect(**config.myems_energy_db)
133
        cursor_energy = cnx_energy.cursor()
134
135
        cnx_historical = mysql.connector.connect(**config.myems_historical_db)
136
        cursor_historical = cnx_historical.cursor()
137
138
        cursor_system.execute(" SELECT id, name, cost_center_id "
139
                              " FROM tbl_combined_equipments "
140
                              " WHERE id = %s ", (combined_equipment_id,))
141
        row_combined_equipment = cursor_system.fetchone()
142
        if row_combined_equipment is None:
143
            if cursor_system:
144
                cursor_system.close()
145
            if cnx_system:
146
                cnx_system.disconnect()
147
148
            if cursor_energy:
149
                cursor_energy.close()
150
            if cnx_energy:
151
                cnx_energy.disconnect()
152
153
            if cnx_historical:
154
                cnx_historical.close()
155
            if cursor_historical:
156
                cursor_historical.disconnect()
157
            raise falcon.HTTPError(falcon.HTTP_404,
158
                                   title='API.NOT_FOUND',
159
                                   description='API.COMBINED_EQUIPMENT_NOT_FOUND')
160
161
        combined_equipment = dict()
162
        combined_equipment['id'] = row_combined_equipment[0]
163
        combined_equipment['name'] = row_combined_equipment[1]
164
        combined_equipment['cost_center_id'] = row_combined_equipment[2]
165
        ################################################################################################################
166
        # Step 3: query associated equipments
167
        ################################################################################################################
168
        # todo
169
170
        ################################################################################################################
171
        # Step 4: query input energy categories and output energy categories
172
        ################################################################################################################
173
        energy_category_set_input = set()
174
        energy_category_set_output = set()
175
        # query input energy categories in base period
176
        cursor_energy.execute(" SELECT DISTINCT(energy_category_id) "
177
                              " FROM tbl_combined_equipment_input_category_hourly "
178
                              " WHERE combined_equipment_id = %s "
179
                              "     AND start_datetime_utc >= %s "
180
                              "     AND start_datetime_utc < %s ",
181
                              (combined_equipment['id'], base_start_datetime_utc, base_end_datetime_utc))
182
        rows_energy_categories = cursor_energy.fetchall()
183
        if rows_energy_categories is not None or len(rows_energy_categories) > 0:
184
            for row_energy_category in rows_energy_categories:
185
                energy_category_set_input.add(row_energy_category[0])
186
187
        # query input energy categories in reporting period
188
        cursor_energy.execute(" SELECT DISTINCT(energy_category_id) "
189
                              " FROM tbl_combined_equipment_input_category_hourly "
190
                              " WHERE combined_equipment_id = %s "
191
                              "     AND start_datetime_utc >= %s "
192
                              "     AND start_datetime_utc < %s ",
193
                              (combined_equipment['id'], reporting_start_datetime_utc, reporting_end_datetime_utc))
194
        rows_energy_categories = cursor_energy.fetchall()
195
        if rows_energy_categories is not None or len(rows_energy_categories) > 0:
196
            for row_energy_category in rows_energy_categories:
197
                energy_category_set_input.add(row_energy_category[0])
198
199
        # query output energy categories in base period
200
        cursor_energy.execute(" SELECT DISTINCT(energy_category_id) "
201
                              " FROM tbl_combined_equipment_output_category_hourly "
202
                              " WHERE combined_equipment_id = %s "
203
                              "     AND start_datetime_utc >= %s "
204
                              "     AND start_datetime_utc < %s ",
205
                              (combined_equipment['id'], base_start_datetime_utc, base_end_datetime_utc))
206
        rows_energy_categories = cursor_energy.fetchall()
207
        if rows_energy_categories is not None or len(rows_energy_categories) > 0:
208
            for row_energy_category in rows_energy_categories:
209
                energy_category_set_output.add(row_energy_category[0])
210
211
        # query output energy categories in reporting period
212
        cursor_energy.execute(" SELECT DISTINCT(energy_category_id) "
213
                              " FROM tbl_combined_equipment_output_category_hourly "
214
                              " WHERE combined_equipment_id = %s "
215
                              "     AND start_datetime_utc >= %s "
216
                              "     AND start_datetime_utc < %s ",
217
                              (combined_equipment['id'], reporting_start_datetime_utc, reporting_end_datetime_utc))
218
        rows_energy_categories = cursor_energy.fetchall()
219
        if rows_energy_categories is not None or len(rows_energy_categories) > 0:
220
            for row_energy_category in rows_energy_categories:
221
                energy_category_set_output.add(row_energy_category[0])
222
223
        # query properties of all energy categories above
224
        cursor_system.execute(" SELECT id, name, unit_of_measure, kgce, kgco2e "
225
                              " FROM tbl_energy_categories "
226
                              " ORDER BY id ", )
227
        rows_energy_categories = cursor_system.fetchall()
228
        if rows_energy_categories is None or len(rows_energy_categories) == 0:
229
            if cursor_system:
230
                cursor_system.close()
231
            if cnx_system:
232
                cnx_system.disconnect()
233
234
            if cursor_energy:
235
                cursor_energy.close()
236
            if cnx_energy:
237
                cnx_energy.disconnect()
238
239
            if cnx_historical:
240
                cnx_historical.close()
241
            if cursor_historical:
242
                cursor_historical.disconnect()
243
            raise falcon.HTTPError(falcon.HTTP_404,
244
                                   title='API.NOT_FOUND',
245
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
246
        energy_category_dict = dict()
247
        for row_energy_category in rows_energy_categories:
248
            if row_energy_category[0] in energy_category_set_input or \
249
                    row_energy_category[0] in energy_category_set_output:
250
                energy_category_dict[row_energy_category[0]] = {"name": row_energy_category[1],
251
                                                                "unit_of_measure": row_energy_category[2],
252
                                                                "kgce": row_energy_category[3],
253
                                                                "kgco2e": row_energy_category[4]}
254
255
        ################################################################################################################
256
        # Step 5: query associated points
257
        ################################################################################################################
258
        point_list = list()
259
        cursor_system.execute(" SELECT p.id, p.name, p.units, p.object_type  "
260
                              " FROM tbl_combined_equipments e, tbl_combined_equipments_parameters ep, tbl_points p "
261
                              " WHERE e.id = %s AND e.id = ep.combined_equipment_id AND ep.parameter_type = 'point' "
262
                              "       AND ep.point_id = p.id "
263
                              " ORDER BY p.id ", (combined_equipment['id'],))
264
        rows_points = cursor_system.fetchall()
265
        if rows_points is not None and len(rows_points) > 0:
266
            for row in rows_points:
267
                point_list.append({"id": row[0], "name": row[1], "units": row[2], "object_type": row[3]})
268
269
        ################################################################################################################
270
        # Step 6: query base period energy input
271
        ################################################################################################################
272
        base_input = dict()
273
        if energy_category_set_input is not None and len(energy_category_set_input) > 0:
274
            for energy_category_id in energy_category_set_input:
275
                base_input[energy_category_id] = dict()
276
                base_input[energy_category_id]['timestamps'] = list()
277
                base_input[energy_category_id]['values'] = list()
278
                base_input[energy_category_id]['subtotal'] = Decimal(0.0)
279
280
                cursor_energy.execute(" SELECT start_datetime_utc, actual_value "
281
                                      " FROM tbl_combined_equipment_input_category_hourly "
282
                                      " WHERE combined_equipment_id = %s "
283
                                      "     AND energy_category_id = %s "
284
                                      "     AND start_datetime_utc >= %s "
285
                                      "     AND start_datetime_utc < %s "
286
                                      " ORDER BY start_datetime_utc ",
287
                                      (combined_equipment['id'],
288
                                       energy_category_id,
289
                                       base_start_datetime_utc,
290
                                       base_end_datetime_utc))
291
                rows_combined_equipment_hourly = cursor_energy.fetchall()
292
293
                rows_combined_equipment_periodically = \
294
                    utilities.aggregate_hourly_data_by_period(rows_combined_equipment_hourly,
295
                                                              base_start_datetime_utc,
296
                                                              base_end_datetime_utc,
297
                                                              period_type)
298
                for row_combined_equipment_periodically in rows_combined_equipment_periodically:
299
                    current_datetime_local = row_combined_equipment_periodically[0].replace(tzinfo=timezone.utc) + \
300
                                             timedelta(minutes=timezone_offset)
301
                    if period_type == 'hourly':
302
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
303
                    elif period_type == 'daily':
304
                        current_datetime = current_datetime_local.strftime('%Y-%m-%d')
305
                    elif period_type == 'monthly':
306
                        current_datetime = current_datetime_local.strftime('%Y-%m')
307
                    elif period_type == 'yearly':
308
                        current_datetime = current_datetime_local.strftime('%Y')
309
310
                    actual_value = Decimal(0.0) if row_combined_equipment_periodically[1] is None \
311
                        else row_combined_equipment_periodically[1]
312
                    base_input[energy_category_id]['timestamps'].append(current_datetime)
0 ignored issues
show
The variable current_datetime does not seem to be defined for all execution paths.
Loading history...
313
                    base_input[energy_category_id]['values'].append(actual_value)
314
                    base_input[energy_category_id]['subtotal'] += actual_value
315
316
        ################################################################################################################
317
        # Step 7: query base period energy output
318
        ################################################################################################################
319
        base_output = dict()
320
        if energy_category_set_output is not None and len(energy_category_set_output) > 0:
321
            for energy_category_id in energy_category_set_output:
322
                base_output[energy_category_id] = dict()
323
                base_output[energy_category_id]['timestamps'] = list()
324
                base_output[energy_category_id]['values'] = list()
325
                base_output[energy_category_id]['subtotal'] = Decimal(0.0)
326
327
                cursor_energy.execute(" SELECT start_datetime_utc, actual_value "
328
                                      " FROM tbl_combined_equipment_output_category_hourly "
329
                                      " WHERE combined_equipment_id = %s "
330
                                      "     AND energy_category_id = %s "
331
                                      "     AND start_datetime_utc >= %s "
332
                                      "     AND start_datetime_utc < %s "
333
                                      " ORDER BY start_datetime_utc ",
334
                                      (combined_equipment['id'],
335
                                       energy_category_id,
336
                                       base_start_datetime_utc,
337
                                       base_end_datetime_utc))
338
                rows_combined_equipment_hourly = cursor_energy.fetchall()
339
340
                rows_combined_equipment_periodically = \
341
                    utilities.aggregate_hourly_data_by_period(rows_combined_equipment_hourly,
342
                                                              base_start_datetime_utc,
343
                                                              base_end_datetime_utc,
344
                                                              period_type)
345
                for row_combined_equipment_periodically in rows_combined_equipment_periodically:
346
                    current_datetime_local = row_combined_equipment_periodically[0].replace(tzinfo=timezone.utc) + \
347
                                             timedelta(minutes=timezone_offset)
348
                    if period_type == 'hourly':
349
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
350
                    elif period_type == 'daily':
351
                        current_datetime = current_datetime_local.strftime('%Y-%m-%d')
352
                    elif period_type == 'monthly':
353
                        current_datetime = current_datetime_local.strftime('%Y-%m')
354
                    elif period_type == 'yearly':
355
                        current_datetime = current_datetime_local.strftime('%Y')
356
357
                    actual_value = Decimal(0.0) if row_combined_equipment_periodically[1] is None \
358
                        else row_combined_equipment_periodically[1]
359
                    base_output[energy_category_id]['timestamps'].append(current_datetime)
360
                    base_output[energy_category_id]['values'].append(actual_value)
361
                    base_output[energy_category_id]['subtotal'] += actual_value
362
        ################################################################################################################
363
        # Step 8: query reporting period energy input
364
        ################################################################################################################
365
        reporting_input = dict()
366
        if energy_category_set_input is not None and len(energy_category_set_input) > 0:
367
            for energy_category_id in energy_category_set_input:
368
369
                reporting_input[energy_category_id] = dict()
370
                reporting_input[energy_category_id]['timestamps'] = list()
371
                reporting_input[energy_category_id]['values'] = list()
372
                reporting_input[energy_category_id]['subtotal'] = Decimal(0.0)
373
374
                cursor_energy.execute(" SELECT start_datetime_utc, actual_value "
375
                                      " FROM tbl_combined_equipment_input_category_hourly "
376
                                      " WHERE combined_equipment_id = %s "
377
                                      "     AND energy_category_id = %s "
378
                                      "     AND start_datetime_utc >= %s "
379
                                      "     AND start_datetime_utc < %s "
380
                                      " ORDER BY start_datetime_utc ",
381
                                      (combined_equipment['id'],
382
                                       energy_category_id,
383
                                       reporting_start_datetime_utc,
384
                                       reporting_end_datetime_utc))
385
                rows_combined_equipment_hourly = cursor_energy.fetchall()
386
387
                rows_combined_equipment_periodically = \
388
                    utilities.aggregate_hourly_data_by_period(rows_combined_equipment_hourly,
389
                                                              reporting_start_datetime_utc,
390
                                                              reporting_end_datetime_utc,
391
                                                              period_type)
392
                for row_combined_equipment_periodically in rows_combined_equipment_periodically:
393
                    current_datetime_local = row_combined_equipment_periodically[0].replace(tzinfo=timezone.utc) + \
394
                                             timedelta(minutes=timezone_offset)
395
                    if period_type == 'hourly':
396
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
397
                    elif period_type == 'daily':
398
                        current_datetime = current_datetime_local.strftime('%Y-%m-%d')
399
                    elif period_type == 'monthly':
400
                        current_datetime = current_datetime_local.strftime('%Y-%m')
401
                    elif period_type == 'yearly':
402
                        current_datetime = current_datetime_local.strftime('%Y')
403
404
                    actual_value = Decimal(0.0) if row_combined_equipment_periodically[1] is None \
405
                        else row_combined_equipment_periodically[1]
406
                    reporting_input[energy_category_id]['timestamps'].append(current_datetime)
407
                    reporting_input[energy_category_id]['values'].append(actual_value)
408
                    reporting_input[energy_category_id]['subtotal'] += actual_value
409
410
        ################################################################################################################
411
        # Step 9: query reporting period energy output
412
        ################################################################################################################
413
        reporting_output = dict()
414
        if energy_category_set_output is not None and len(energy_category_set_output) > 0:
415
            for energy_category_id in energy_category_set_output:
416
417
                reporting_output[energy_category_id] = dict()
418
                reporting_output[energy_category_id]['timestamps'] = list()
419
                reporting_output[energy_category_id]['values'] = list()
420
                reporting_output[energy_category_id]['subtotal'] = Decimal(0.0)
421
422
                cursor_energy.execute(" SELECT start_datetime_utc, actual_value "
423
                                      " FROM tbl_combined_equipment_output_category_hourly "
424
                                      " WHERE combined_equipment_id = %s "
425
                                      "     AND energy_category_id = %s "
426
                                      "     AND start_datetime_utc >= %s "
427
                                      "     AND start_datetime_utc < %s "
428
                                      " ORDER BY start_datetime_utc ",
429
                                      (combined_equipment['id'],
430
                                       energy_category_id,
431
                                       reporting_start_datetime_utc,
432
                                       reporting_end_datetime_utc))
433
                rows_combined_equipment_hourly = cursor_energy.fetchall()
434
435
                rows_combined_equipment_periodically = \
436
                    utilities.aggregate_hourly_data_by_period(rows_combined_equipment_hourly,
437
                                                              reporting_start_datetime_utc,
438
                                                              reporting_end_datetime_utc,
439
                                                              period_type)
440
                for row_combined_equipment_periodically in rows_combined_equipment_periodically:
441
                    current_datetime_local = row_combined_equipment_periodically[0].replace(tzinfo=timezone.utc) + \
442
                                             timedelta(minutes=timezone_offset)
443
                    if period_type == 'hourly':
444
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
445
                    elif period_type == 'daily':
446
                        current_datetime = current_datetime_local.strftime('%Y-%m-%d')
447
                    elif period_type == 'monthly':
448
                        current_datetime = current_datetime_local.strftime('%Y-%m')
449
                    elif period_type == 'yearly':
450
                        current_datetime = current_datetime_local.strftime('%Y')
451
452
                    actual_value = Decimal(0.0) if row_combined_equipment_periodically[1] is None \
453
                        else row_combined_equipment_periodically[1]
454
                    reporting_output[energy_category_id]['timestamps'].append(current_datetime)
455
                    reporting_output[energy_category_id]['values'].append(actual_value)
456
                    reporting_output[energy_category_id]['subtotal'] += actual_value
457
458
        ################################################################################################################
459
        # Step 10: query tariff data
460
        ################################################################################################################
461
        parameters_data = dict()
462
        parameters_data['names'] = list()
463
        parameters_data['timestamps'] = list()
464
        parameters_data['values'] = list()
465
        if energy_category_set_input is not None and len(energy_category_set_input) > 0:
466
            for energy_category_id in energy_category_set_input:
467
                energy_category_tariff_dict = utilities.get_energy_category_tariffs(
468
                    combined_equipment['cost_center_id'],
469
                    energy_category_id,
470
                    reporting_start_datetime_utc,
471
                    reporting_end_datetime_utc)
472
473
                tariff_timestamp_list = list()
474
                tariff_value_list = list()
475
                for k, v in energy_category_tariff_dict.items():
476
                    # convert k from utc to local
477
                    k = k + timedelta(minutes=timezone_offset)
478
                    tariff_timestamp_list.append(k.isoformat()[0:19][0:19])
479
                    tariff_value_list.append(v)
480
481
                parameters_data['names'].append('TARIFF-' + energy_category_dict[energy_category_id]['name'])
482
                parameters_data['timestamps'].append(tariff_timestamp_list)
483
                parameters_data['values'].append(tariff_value_list)
484
485
        ################################################################################################################
486
        # Step 11: query associated points data
487
        ################################################################################################################
488
        for point in point_list:
489
            point_values = []
490
            point_timestamps = []
491
            if point['object_type'] == 'ANALOG_VALUE':
492
                query = (" SELECT utc_date_time, actual_value "
493
                         " FROM tbl_analog_value "
494
                         " WHERE point_id = %s "
495
                         "       AND utc_date_time BETWEEN %s AND %s "
496
                         " ORDER BY utc_date_time ")
497
                cursor_historical.execute(query, (point['id'],
498
                                                  reporting_start_datetime_utc,
499
                                                  reporting_end_datetime_utc))
500
                rows = cursor_historical.fetchall()
501
502
                if rows is not None and len(rows) > 0:
503
                    for row in rows:
504
                        current_datetime_local = row[0].replace(tzinfo=timezone.utc) + \
505
                                                 timedelta(minutes=timezone_offset)
506
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
507
                        point_timestamps.append(current_datetime)
508
                        point_values.append(row[1])
509
510
            elif point['object_type'] == 'ENERGY_VALUE':
511
                query = (" SELECT utc_date_time, actual_value "
512
                         " FROM tbl_energy_value "
513
                         " WHERE point_id = %s "
514
                         "       AND utc_date_time BETWEEN %s AND %s "
515
                         " ORDER BY utc_date_time ")
516
                cursor_historical.execute(query, (point['id'],
517
                                                  reporting_start_datetime_utc,
518
                                                  reporting_end_datetime_utc))
519
                rows = cursor_historical.fetchall()
520
521
                if rows is not None and len(rows) > 0:
522
                    for row in rows:
523
                        current_datetime_local = row[0].replace(tzinfo=timezone.utc) + \
524
                                                 timedelta(minutes=timezone_offset)
525
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
526
                        point_timestamps.append(current_datetime)
527
                        point_values.append(row[1])
528
            elif point['object_type'] == 'DIGITAL_VALUE':
529
                query = (" SELECT utc_date_time, actual_value "
530
                         " FROM tbl_digital_value "
531
                         " WHERE point_id = %s "
532
                         "       AND utc_date_time BETWEEN %s AND %s ")
533
                cursor_historical.execute(query, (point['id'],
534
                                                  reporting_start_datetime_utc,
535
                                                  reporting_end_datetime_utc))
536
                rows = cursor_historical.fetchall()
537
538
                if rows is not None and len(rows) > 0:
539
                    for row in rows:
540
                        current_datetime_local = row[0].replace(tzinfo=timezone.utc) + \
541
                                                 timedelta(minutes=timezone_offset)
542
                        current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
543
                        point_timestamps.append(current_datetime)
544
                        point_values.append(row[1])
545
546
            parameters_data['names'].append(point['name'] + ' (' + point['units'] + ')')
547
            parameters_data['timestamps'].append(point_timestamps)
548
            parameters_data['values'].append(point_values)
549
550
        ################################################################################################################
551
        # Step 12: construct the report
552
        ################################################################################################################
553
        if cursor_system:
554
            cursor_system.close()
555
        if cnx_system:
556
            cnx_system.disconnect()
557
558
        if cursor_energy:
559
            cursor_energy.close()
560
        if cnx_energy:
561
            cnx_energy.disconnect()
562
563
        result = dict()
564
565
        result['combined_equipment'] = dict()
566
        result['combined_equipment']['name'] = combined_equipment['name']
567
568
        result['base_period_input'] = dict()
569
        result['base_period_input']['names'] = list()
570
        result['base_period_input']['units'] = list()
571
        result['base_period_input']['timestamps'] = list()
572
        result['base_period_input']['values'] = list()
573
        result['base_period_input']['subtotals'] = list()
574
        if energy_category_set_input is not None and len(energy_category_set_input) > 0:
575
            for energy_category_id in energy_category_set_input:
576
                result['base_period_input']['names'].append(energy_category_dict[energy_category_id]['name'])
577
                result['base_period_input']['units'].append(energy_category_dict[energy_category_id]['unit_of_measure'])
578
                result['base_period_input']['timestamps'].append(base_input[energy_category_id]['timestamps'])
579
                result['base_period_input']['values'].append(base_input[energy_category_id]['values'])
580
                result['base_period_input']['subtotals'].append(base_input[energy_category_id]['subtotal'])
581
582
        result['base_period_output'] = dict()
583
        result['base_period_output']['names'] = list()
584
        result['base_period_output']['units'] = list()
585
        result['base_period_output']['timestamps'] = list()
586
        result['base_period_output']['values'] = list()
587
        result['base_period_output']['subtotals'] = list()
588
589
        if energy_category_set_output is not None and len(energy_category_set_output) > 0:
590
            for energy_category_id in energy_category_set_output:
591
                result['base_period_output']['names'].append(energy_category_dict[energy_category_id]['name'])
592
                result['base_period_output']['units'].append(
593
                    energy_category_dict[energy_category_id]['unit_of_measure'])
594
                result['base_period_output']['timestamps'].append(base_output[energy_category_id]['timestamps'])
595
                result['base_period_output']['values'].append(base_output[energy_category_id]['values'])
596
                result['base_period_output']['subtotals'].append(base_output[energy_category_id]['subtotal'])
597
598
        result['base_period_efficiency'] = dict()
599
        result['base_period_efficiency']['names'] = list()
600
        result['base_period_efficiency']['units'] = list()
601
        result['base_period_efficiency']['timestamps'] = list()
602
        result['base_period_efficiency']['values'] = list()
603
        result['base_period_efficiency']['cumulations'] = list()
604
605
        if energy_category_set_output is not None and len(energy_category_set_output) > 0:
606
            for energy_category_id_output in energy_category_set_output:
607
                for energy_category_id_input in energy_category_set_input:
608
                    result['base_period_efficiency']['names'].append(
609
                        energy_category_dict[energy_category_id_output]['name'] + '/' +
610
                        energy_category_dict[energy_category_id_input]['name'])
611
                    result['base_period_efficiency']['units'].append(
612
                        energy_category_dict[energy_category_id_output]['unit_of_measure'] + '/' +
613
                        energy_category_dict[energy_category_id_input]['unit_of_measure'])
614
                    result['base_period_efficiency']['timestamps'].append(
615
                        base_output[energy_category_id_output]['timestamps'])
616
                    efficiency_values = list()
617
                    for i in range(len(base_output[energy_category_id_output]['timestamps'])):
618
                        efficiency_values.append((base_output[energy_category_id_output]['values'][i] /
619
                                                  base_input[energy_category_id_input]['values'][i])
620
                                                 if base_input[energy_category_id_input]['values'][i] > Decimal(0.0)
621
                                                 else None)
622
                    result['base_period_efficiency']['values'].append(efficiency_values)
623
624
                    base_cumulation = (base_output[energy_category_id_output]['subtotal'] /
625
                                       base_input[energy_category_id_input]['subtotal']) if \
626
                        base_input[energy_category_id_input]['subtotal'] > Decimal(0.0) else None
627
                    result['base_period_efficiency']['cumulations'].append(base_cumulation)
628
629
        result['reporting_period_input'] = dict()
630
        result['reporting_period_input']['names'] = list()
631
        result['reporting_period_input']['energy_category_ids'] = list()
632
        result['reporting_period_input']['units'] = list()
633
        result['reporting_period_input']['timestamps'] = list()
634
        result['reporting_period_input']['values'] = list()
635
        result['reporting_period_input']['subtotals'] = list()
636
        result['reporting_period_input']['increment_rates'] = list()
637
638
        if energy_category_set_input is not None and len(energy_category_set_input) > 0:
639
            for energy_category_id in energy_category_set_input:
640
                result['reporting_period_input']['names'].append(energy_category_dict[energy_category_id]['name'])
641
                result['reporting_period_input']['energy_category_ids'].append(energy_category_id)
642
                result['reporting_period_input']['units'].append(
643
                    energy_category_dict[energy_category_id]['unit_of_measure'])
644
                result['reporting_period_input']['timestamps'].append(
645
                    reporting_input[energy_category_id]['timestamps'])
646
                result['reporting_period_input']['values'].append(
647
                    reporting_input[energy_category_id]['values'])
648
                result['reporting_period_input']['subtotals'].append(
649
                    reporting_input[energy_category_id]['subtotal'])
650
                result['reporting_period_input']['increment_rates'].append(
651
                    (reporting_input[energy_category_id]['subtotal'] -
652
                     base_input[energy_category_id]['subtotal']) /
653
                    base_input[energy_category_id]['subtotal']
654
                    if base_input[energy_category_id]['subtotal'] > 0.0 else None)
655
656
        result['reporting_period_output'] = dict()
657
        result['reporting_period_output']['names'] = list()
658
        result['reporting_period_output']['energy_category_ids'] = list()
659
        result['reporting_period_output']['units'] = list()
660
        result['reporting_period_output']['timestamps'] = list()
661
        result['reporting_period_output']['values'] = list()
662
        result['reporting_period_output']['subtotals'] = list()
663
        result['reporting_period_output']['increment_rates'] = list()
664
665
        if energy_category_set_output is not None and len(energy_category_set_output) > 0:
666
            for energy_category_id in energy_category_set_output:
667
                result['reporting_period_output']['names'].append(energy_category_dict[energy_category_id]['name'])
668
                result['reporting_period_output']['energy_category_ids'].append(energy_category_id)
669
                result['reporting_period_output']['units'].append(
670
                    energy_category_dict[energy_category_id]['unit_of_measure'])
671
                result['reporting_period_output']['timestamps'].append(
672
                    reporting_output[energy_category_id]['timestamps'])
673
                result['reporting_period_output']['values'].append(reporting_output[energy_category_id]['values'])
674
                result['reporting_period_output']['subtotals'].append(reporting_output[energy_category_id]['subtotal'])
675
                result['reporting_period_output']['increment_rates'].append(
676
                    (reporting_output[energy_category_id]['subtotal'] -
677
                     base_output[energy_category_id]['subtotal']) /
678
                    base_output[energy_category_id]['subtotal']
679
                    if base_output[energy_category_id]['subtotal'] > 0.0 else None)
680
681
        result['reporting_period_efficiency'] = dict()
682
        result['reporting_period_efficiency']['names'] = list()
683
        result['reporting_period_efficiency']['units'] = list()
684
        result['reporting_period_efficiency']['timestamps'] = list()
685
        result['reporting_period_efficiency']['values'] = list()
686
        result['reporting_period_efficiency']['cumulations'] = list()
687
        result['reporting_period_efficiency']['increment_rates'] = list()
688
689
        if energy_category_set_output is not None and len(energy_category_set_output) > 0:
690
            for energy_category_id_output in energy_category_set_output:
691
                for energy_category_id_input in energy_category_set_input:
692
                    result['reporting_period_efficiency']['names'].append(
693
                        energy_category_dict[energy_category_id_output]['name'] + '/' +
694
                        energy_category_dict[energy_category_id_input]['name'])
695
                    result['reporting_period_efficiency']['units'].append(
696
                        energy_category_dict[energy_category_id_output]['unit_of_measure'] + '/' +
697
                        energy_category_dict[energy_category_id_input]['unit_of_measure'])
698
                    result['reporting_period_efficiency']['timestamps'].append(
699
                        reporting_output[energy_category_id_output]['timestamps'])
700
                    efficiency_values = list()
701
                    for i in range(len(reporting_output[energy_category_id_output]['timestamps'])):
702
                        efficiency_values.append((reporting_output[energy_category_id_output]['values'][i] /
703
                                                 reporting_input[energy_category_id_input]['values'][i])
704
                                                 if reporting_input[energy_category_id_input]['values'][i] >
705
                                                 Decimal(0.0) else None)
706
                    result['reporting_period_efficiency']['values'].append(efficiency_values)
707
708
                    base_cumulation = (base_output[energy_category_id_output]['subtotal'] /
709
                                       base_input[energy_category_id_input]['subtotal']) if \
710
                        base_input[energy_category_id_input]['subtotal'] > Decimal(0.0) else None
711
712
                    reporting_cumulation = (reporting_output[energy_category_id_output]['subtotal'] /
713
                                            reporting_input[energy_category_id_input]['subtotal']) if \
714
                        reporting_input[energy_category_id_input]['subtotal'] > Decimal(0.0) else None
715
716
                    result['reporting_period_efficiency']['cumulations'].append(reporting_cumulation)
717
                    result['reporting_period_efficiency']['increment_rates'].append(
718
                        ((reporting_cumulation - base_cumulation) / base_cumulation if (base_cumulation > Decimal(0.0))
719
                         else None)
720
                    )
721
722
        result['parameters'] = {
723
            "names": parameters_data['names'],
724
            "timestamps": parameters_data['timestamps'],
725
            "values": parameters_data['values']
726
        }
727
728
        resp.body = json.dumps(result)
729