Issues (1656)

myems-api/reports/microgriddetails.py (3 issues)

1
import re
2
from datetime import datetime, timedelta, timezone
3
from decimal import Decimal
4
import falcon
5
import mysql.connector
6
import simplejson as json
7
from core.useractivity import access_control, api_key_control
8
import config
9
10
11
class Reporting:
12
    def __init__(self):
13
        """Initializes Class"""
14
        pass
15
16
    @staticmethod
17
    def on_options(req, resp):
18
        _ = req
19
        resp.status = falcon.HTTP_200
20
21
    ####################################################################################################################
22
    # PROCEDURES
23
    # Step 1: valid parameters
24
    # Step 2: query the microgrid
25
    # Step 3: query associated batteries
26
    # Step 4: query associated power conversion systems
27
    # Step 5: query associated evchargers
28
    # Step 6: query associated generators
29
    # Step 7: query associated grids
30
    # Step 8: query associated heatpumps
31
    # Step 9: query associated loads
32
    # Step 10: query associated photovoltaics
33
    # Step 11: query associated schedules
34
    # Step 12: query associated sensors
35
    # Step 13: query associated meters data
36
    # Step 14: query associated points data
37
    # Step 15: construct the report
38
    ####################################################################################################################
39
    @staticmethod
40
    def on_get(req, resp):
41
        if 'API-KEY' not in req.headers or \
42
                not isinstance(req.headers['API-KEY'], str) or \
43
                len(str.strip(req.headers['API-KEY'])) == 0:
44
            access_control(req)
45
        else:
46
            api_key_control(req)
47
        print(req.params)
48
        # this procedure accepts microgrid id or microgrid uuid to identify a microgrid
49
        microgrid_id = req.params.get('id')
50
        microgrid_uuid = req.params.get('uuid')
51
52
        ################################################################################################################
53
        # Step 1: valid parameters
54
        ################################################################################################################
55
        if microgrid_id is None and microgrid_uuid is None:
56
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
57
                                   description='API.INVALID_MICROGRID_ID')
58
59
        if microgrid_id is not None:
60
            microgrid_id = str.strip(microgrid_id)
61
            if not microgrid_id.isdigit() or int(microgrid_id) <= 0:
62
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
63
                                       description='API.INVALID_MICROGRID_ID')
64
65
        if microgrid_uuid is not None:
66
            regex = re.compile(r'^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I)
67
            match = regex.match(str.strip(microgrid_uuid))
68
            if not bool(match):
69
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
70
                                       description='API.INVALID_MICROGRID_UUID')
71
72
        reporting_start_datetime_utc = datetime.utcnow() - timedelta(days=3)
73
        reporting_end_datetime_utc = datetime.utcnow()
74
75
        ################################################################################################################
76
        # Step 2: Step 2: query the microgrid
77
        ################################################################################################################
78
        cnx_system = mysql.connector.connect(**config.myems_system_db)
79
        cursor_system = cnx_system.cursor()
80
81
        cnx_energy = mysql.connector.connect(**config.myems_energy_db)
82
        cursor_energy = cnx_energy.cursor()
83
84
        cnx_billing = mysql.connector.connect(**config.myems_billing_db)
85
        cursor_billing = cnx_billing.cursor()
86
87
        cnx_carbon = mysql.connector.connect(**config.myems_carbon_db)
88
        cursor_carbon = cnx_carbon.cursor()
89
90
        cnx_historical = mysql.connector.connect(**config.myems_historical_db)
91
        cursor_historical = cnx_historical.cursor()
92
93
        query = (" SELECT id, name, uuid "
94
                 " FROM tbl_contacts ")
95
        cursor_system.execute(query)
96
        rows_contacts = cursor_system.fetchall()
97
98
        contact_dict = dict()
99
        if rows_contacts is not None and len(rows_contacts) > 0:
100
            for row in rows_contacts:
101
                contact_dict[row[0]] = {"id": row[0],
102
                                        "name": row[1],
103
                                        "uuid": row[2]}
104
105
        query = (" SELECT id, name, uuid "
106
                 " FROM tbl_cost_centers ")
107
        cursor_system.execute(query)
108
        rows_cost_centers = cursor_system.fetchall()
109
110
        cost_center_dict = dict()
111
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
112
            for row in rows_cost_centers:
113
                cost_center_dict[row[0]] = {"id": row[0],
114
                                            "name": row[1],
115
                                            "uuid": row[2]}
116
        if microgrid_id is not None:
117
            query = (" SELECT m.id, m.name, m.uuid, "
118
                     "        m.address, m.postal_code, m.latitude, m.longitude, m.rated_capacity, m.rated_power, "
119
                     "        m.contact_id, m.cost_center_id, m.serial_number, s.source_code, m.description "
120
                     " FROM tbl_microgrids m, tbl_svgs s"
121
                     " WHERE m.svg_id = s.id AND m.id = %s ")
122
            cursor_system.execute(query, (microgrid_id,))
123
            row = cursor_system.fetchone()
124
        elif microgrid_uuid is not None:
125
            query = (" SELECT m.id, m.name, m.uuid, "
126
                     "        m.address, m.postal_code, m.latitude, m.longitude, m.rated_capacity, m.rated_power, "
127
                     "        m.contact_id, m.cost_center_id, m.serial_number, s.source_code, m.description "
128
                     " FROM tbl_microgrids m, tbl_svgs s "
129
                     " WHERE m.svg_id = s.id AND m.uuid = %s ")
130
            cursor_system.execute(query, (microgrid_uuid,))
131
            row = cursor_system.fetchone()
132
133
        if row is None:
0 ignored issues
show
The variable row does not seem to be defined for all execution paths.
Loading history...
134
            cursor_system.close()
135
            cnx_system.close()
136
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
137
                                   description='API.MICROGRID_NOT_FOUND')
138
        else:
139
            microgrid_id = row[0]
140
            meta_result = {"id": row[0],
141
                           "name": row[1],
142
                           "uuid": row[2],
143
                           "address": row[3],
144
                           "postal_code": row[4],
145
                           "latitude": row[5],
146
                           "longitude": row[6],
147
                           "rated_capacity": row[7],
148
                           "rated_power": row[8],
149
                           "contact": contact_dict.get(row[9], None),
150
                           "cost_center": cost_center_dict.get(row[10], None),
151
                           "serial_number": row[11],
152
                           "svg": row[12],
153
                           "description": row[13],
154
                           "qrcode": 'microgrid:' + row[2]}
155
156
        point_list = list()
157
        meter_list = list()
158
159
        # query all energy categories in system
160
        cursor_system.execute(" SELECT id, name, unit_of_measure, kgce, kgco2e "
161
                              " FROM tbl_energy_categories "
162
                              " ORDER BY id ", )
163
        rows_energy_categories = cursor_system.fetchall()
164
        if rows_energy_categories is None or len(rows_energy_categories) == 0:
165
            if cursor_system:
166
                cursor_system.close()
167
            if cnx_system:
168
                cnx_system.close()
169
            raise falcon.HTTPError(status=falcon.HTTP_404,
170
                                   title='API.NOT_FOUND',
171
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
172
        energy_category_dict = dict()
173
        for row_energy_category in rows_energy_categories:
174
            energy_category_dict[row_energy_category[0]] = {"name": row_energy_category[1],
175
                                                            "unit_of_measure": row_energy_category[2],
176
                                                            "kgce": row_energy_category[3],
177
                                                            "kgco2e": row_energy_category[4]}
178
179
        ################################################################################################################
180
        # Step 3: query associated batteries
181
        ################################################################################################################
182
183
        energy_value_latest_dict = dict()
184
        query = (" SELECT point_id, actual_value "
185
                 " FROM tbl_energy_value_latest ")
186
        cursor_historical.execute(query, )
187
        energy_value_latest_rows = cursor_historical.fetchall()
188
        for row in energy_value_latest_rows:
189
            energy_value_latest_dict[row[0]] = row[1]
190
191
        analog_value_latest_dict = dict()
192
        query = (" SELECT point_id, actual_value "
193
                 " FROM tbl_analog_value_latest ")
194
        cursor_historical.execute(query, )
195
        analog_value_latest_rows = cursor_historical.fetchall()
196
        for row in analog_value_latest_rows:
197
            analog_value_latest_dict[row[0]] = row[1]
198
199
        digital_value_latest_dict = dict()
200
        query = (" SELECT point_id, actual_value "
201
                 " FROM tbl_digital_value_latest ")
202
        cursor_historical.execute(query, )
203
        digital_value_latest_rows = cursor_historical.fetchall()
204
        for row in digital_value_latest_rows:
205
            digital_value_latest_dict[row[0]] = row[1]
206
207
        cursor_system.execute(" SELECT battery_state_point_id "
208
                              " FROM tbl_microgrids_batteries "
209
                              " WHERE microgrid_id = %s "
210
                              " ORDER BY id "
211
                              " LIMIT 1 ",
212
                              (microgrid_id,))
213
        row_point = cursor_system.fetchone()
214
        if row_point is not None:
215
            battery_state_point_id = row_point[0]
216
217
        if digital_value_latest_dict.get(battery_state_point_id) is not None:
0 ignored issues
show
The variable battery_state_point_id does not seem to be defined in case row_point is not None on line 214 is False. Are you sure this can never be the case?
Loading history...
218
            battery_state_point_value = digital_value_latest_dict.get(battery_state_point_id)
219
220
        cursor_system.execute(" SELECT p.id, mb.name, p.units, p.object_type  "
221
                              " FROM tbl_microgrids_batteries mb, tbl_points p "
222
                              " WHERE mb.microgrid_id = %s AND mb.soc_point_id = p.id ",
223
                              (microgrid_id,))
224
        row_point = cursor_system.fetchone()
225
        if row_point is not None:
226
            point_list.append({"id": row_point[0],
227
                               "name": row_point[1] + '.SOC',
228
                               "units": row_point[2],
229
                               "object_type": row_point[3]})
230
231
        cursor_system.execute(" SELECT p.id, mb.name, p.units, p.object_type  "
232
                              " FROM tbl_microgrids_batteries mb, tbl_points p "
233
                              " WHERE mb.microgrid_id = %s AND mb.power_point_id = p.id ",
234
                              (microgrid_id,))
235
        row_point = cursor_system.fetchone()
236
        if row_point is not None:
237
            point_list.append({"id": row_point[0],
238
                               "name": row_point[1]+'.P',
239
                               "units": row_point[2],
240
                               "object_type": row_point[3]})
241
        charge_meter_id = None
242
        cursor_system.execute(" SELECT m.id, mb.name, m.energy_category_id  "
243
                              " FROM tbl_microgrids_batteries mb, tbl_meters m "
244
                              " WHERE mb.microgrid_id = %s AND mb.charge_meter_id = m.id ",
245
                              (microgrid_id,))
246
        row_meter = cursor_system.fetchone()
247
        if row_meter is not None:
248
            meter_list.append({"id": row_meter[0],
249
                               "name": row_meter[1] + '.Charge',
250
                               "energy_category_id": row_meter[2]})
251
            charge_meter_id = row_meter[0]
252
253
        discharge_meter_id = None
254
        cursor_system.execute(" SELECT m.id, mb.name, m.energy_category_id  "
255
                              " FROM tbl_microgrids_batteries mb, tbl_meters m "
256
                              " WHERE mb.microgrid_id = %s AND mb.discharge_meter_id = m.id ",
257
                              (microgrid_id,))
258
        row_meter = cursor_system.fetchone()
259
        if row_meter is not None:
260
            meter_list.append({"id": row_meter[0],
261
                               "name": row_meter[1] + '.Discharge',
262
                               "energy_category_id": row_meter[2]})
263
            discharge_meter_id = row_meter[0]
264
265
        ################################################################################################################
266
        # Step 4: query associated power conversion systems
267
        ################################################################################################################
268
        # Step 4.1 query energy indicator data
269
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
270
        if config.utc_offset[0] == '-':
271
            timezone_offset = -timezone_offset
272
273
        today_end_datetime_utc = datetime.utcnow()
274
        today_end_datetime_local = datetime.utcnow() + timedelta(minutes=timezone_offset)
275
        today_start_datetime_local = today_end_datetime_local.replace(hour=0, minute=0, second=0, microsecond=0)
276
        today_start_datetime_utc = today_start_datetime_local - timedelta(minutes=timezone_offset)
277
278
        today_charge_energy_value = Decimal(0.0)
279
        today_discharge_energy_value = Decimal(0.0)
280
        total_charge_energy_value = Decimal(0.0)
281
        total_discharge_energy_value = Decimal(0.0)
282
283
        # query meter energy
284
        cursor_energy.execute(" SELECT SUM(actual_value) "
285
                              " FROM tbl_meter_hourly "
286
                              " WHERE meter_id = %s "
287
                              "     AND start_datetime_utc >= %s "
288
                              "     AND start_datetime_utc < %s ",
289
                              (charge_meter_id,
290
                               today_start_datetime_utc,
291
                               today_end_datetime_utc))
292
        row = cursor_energy.fetchone()
293
        if row is not None:
294
            today_charge_energy_value = row[0]
295
296
        cursor_energy.execute(" SELECT SUM(actual_value) "
297
                              " FROM tbl_meter_hourly "
298
                              " WHERE meter_id = %s "
299
                              "     AND start_datetime_utc >= %s "
300
                              "     AND start_datetime_utc < %s ",
301
                              (discharge_meter_id,
302
                               today_start_datetime_utc,
303
                               today_end_datetime_utc))
304
        row = cursor_energy.fetchone()
305
        if row is not None:
306
            today_discharge_energy_value = row[0]
307
308
        cursor_energy.execute(" SELECT SUM(actual_value) "
309
                              " FROM tbl_meter_hourly "
310
                              " WHERE meter_id = %s ",
311
                              (charge_meter_id,))
312
        row = cursor_energy.fetchone()
313
        if row is not None:
314
            total_charge_energy_value = row[0]
315
316
        cursor_energy.execute(" SELECT SUM(actual_value) "
317
                              " FROM tbl_meter_hourly "
318
                              " WHERE meter_id = %s ",
319
                              (discharge_meter_id,))
320
        row = cursor_energy.fetchone()
321
        if row is not None:
322
            total_discharge_energy_value = row[0]
323
324
        # Step 4.2 query revenue indicator data
325
        today_charge_revenue_value = Decimal(0.0)
326
        today_discharge_revenue_value = Decimal(0.0)
327
        total_charge_revenue_value = Decimal(0.0)
328
        total_discharge_revenue_value = Decimal(0.0)
329
330
        # query meter revenue
331
        cursor_billing.execute(" SELECT SUM(actual_value) "
332
                               " FROM tbl_meter_hourly "
333
                               " WHERE meter_id = %s "
334
                               "     AND start_datetime_utc >= %s "
335
                               "     AND start_datetime_utc < %s ",
336
                               (charge_meter_id,
337
                                today_start_datetime_utc,
338
                                today_end_datetime_utc))
339
        row = cursor_billing.fetchone()
340
        if row is not None:
341
            today_charge_revenue_value = row[0]
342
343
        cursor_billing.execute(" SELECT SUM(actual_value) "
344
                               " FROM tbl_meter_hourly "
345
                               " WHERE meter_id = %s "
346
                               "     AND start_datetime_utc >= %s "
347
                               "     AND start_datetime_utc < %s ",
348
                               (discharge_meter_id,
349
                                today_start_datetime_utc,
350
                                today_end_datetime_utc))
351
        row = cursor_billing.fetchone()
352
        if row is not None:
353
            today_discharge_revenue_value = row[0]
354
355
        cursor_billing.execute(" SELECT SUM(actual_value) "
356
                               " FROM tbl_meter_hourly "
357
                               " WHERE meter_id = %s ",
358
                               (charge_meter_id,))
359
        row = cursor_billing.fetchone()
360
        if row is not None:
361
            total_charge_revenue_value = row[0]
362
363
        cursor_billing.execute(" SELECT SUM(actual_value) "
364
                               " FROM tbl_meter_hourly "
365
                               " WHERE meter_id = %s ",
366
                               (discharge_meter_id,))
367
        row = cursor_billing.fetchone()
368
        if row is not None:
369
            total_discharge_revenue_value = row[0]
370
371
        # Step 4.3 query carbon indicator data
372
        today_charge_carbon_value = Decimal(0.0)
373
        today_discharge_carbon_value = Decimal(0.0)
374
        total_charge_carbon_value = Decimal(0.0)
375
        total_discharge_carbon_value = Decimal(0.0)
376
377
        # query meter carbon
378
        cursor_carbon.execute(" SELECT SUM(actual_value) "
379
                              " FROM tbl_meter_hourly "
380
                              " WHERE meter_id = %s "
381
                              "     AND start_datetime_utc >= %s "
382
                              "     AND start_datetime_utc < %s ",
383
                              (charge_meter_id,
384
                               today_start_datetime_utc,
385
                               today_end_datetime_utc))
386
        row = cursor_carbon.fetchone()
387
        if row is not None:
388
            today_charge_carbon_value = row[0]
389
390
        cursor_carbon.execute(" SELECT SUM(actual_value) "
391
                              " FROM tbl_meter_hourly "
392
                              " WHERE meter_id = %s "
393
                              "     AND start_datetime_utc >= %s "
394
                              "     AND start_datetime_utc < %s ",
395
                              (discharge_meter_id,
396
                               today_start_datetime_utc,
397
                               today_end_datetime_utc))
398
        row = cursor_carbon.fetchone()
399
        if row is not None:
400
            today_discharge_carbon_value = row[0]
401
402
        cursor_carbon.execute(" SELECT SUM(actual_value) "
403
                              " FROM tbl_meter_hourly "
404
                              " WHERE meter_id = %s ",
405
                              (charge_meter_id,))
406
        row = cursor_carbon.fetchone()
407
        if row is not None:
408
            total_charge_carbon_value = row[0]
409
410
        cursor_carbon.execute(" SELECT SUM(actual_value) "
411
                              " FROM tbl_meter_hourly "
412
                              " WHERE meter_id = %s ",
413
                              (discharge_meter_id,))
414
        row = cursor_carbon.fetchone()
415
        if row is not None:
416
            total_discharge_carbon_value = row[0]
417
418
        ################################################################################################################
419
        # Step 5: query associated evchargers
420
        ################################################################################################################
421
        cursor_system.execute(" SELECT p.id, me.name, p.units, p.object_type  "
422
                              " FROM tbl_microgrids_evchargers me, tbl_points p "
423
                              " WHERE me.microgrid_id = %s AND me.power_point_id = p.id ",
424
                              (microgrid_id,))
425
        rows_points = cursor_system.fetchall()
426
        if rows_points is not None and len(rows_points) > 0:
427
            for row_point in rows_points:
428
                point_list.append({"id": row_point[0],
429
                                   "name": row_point[1]+'.P',
430
                                   "units": row_point[2],
431
                                   "object_type": row_point[3]})
432
433
        cursor_system.execute(" SELECT m.id, me.name, m.energy_category_id  "
434
                              " FROM tbl_microgrids_evchargers me, tbl_meters m "
435
                              " WHERE me.microgrid_id = %s AND me.meter_id = m.id ",
436
                              (microgrid_id,))
437
        rows_meters = cursor_system.fetchall()
438
        if rows_meters is not None and len(rows_meters) > 0:
439
            for row_meter in rows_meters:
440
                meter_list.append({"id": row_meter[0],
441
                                   "name": row_meter[1],
442
                                   "energy_category_id": row_meter[2]})
443
        ################################################################################################################
444
        # Step 6: query associated generators
445
        ################################################################################################################
446
        cursor_system.execute(" SELECT p.id, mg.name, p.units, p.object_type  "
447
                              " FROM tbl_microgrids_generators mg, tbl_points p "
448
                              " WHERE mg.microgrid_id = %s AND mg.power_point_id = p.id ",
449
                              (microgrid_id,))
450
        row_point = cursor_system.fetchone()
451
        if row_point is not None:
452
            point_list.append({"id": row_point[0],
453
                               "name": row_point[1]+'.P',
454
                               "units": row_point[2],
455
                               "object_type": row_point[3]})
456
457
        cursor_system.execute(" SELECT m.id, mg.name, m.energy_category_id  "
458
                              " FROM tbl_microgrids_generators mg, tbl_meters m "
459
                              " WHERE mg.microgrid_id = %s AND mg.meter_id = m.id ",
460
                              (microgrid_id,))
461
        row_meter = cursor_system.fetchone()
462
        if row_meter is not None:
463
            meter_list.append({"id": row_meter[0],
464
                               "name": row_meter[1],
465
                               "energy_category_id": row_meter[2]})
466
        ################################################################################################################
467
        # Step 7: query associated grids
468
        ################################################################################################################
469
        cursor_system.execute(" SELECT p.id, mg.name, p.units, p.object_type  "
470
                              " FROM tbl_microgrids_grids mg, tbl_points p "
471
                              " WHERE mg.microgrid_id = %s AND mg.power_point_id = p.id ",
472
                              (microgrid_id,))
473
        row_point = cursor_system.fetchone()
474
        if row_point is not None:
475
            point_list.append({"id": row_point[0],
476
                               "name": row_point[1]+'.P',
477
                               "units": row_point[2],
478
                               "object_type": row_point[3]})
479
480
        cursor_system.execute(" SELECT m.id, mg.name, m.energy_category_id  "
481
                              " FROM tbl_microgrids_grids mg, tbl_meters m "
482
                              " WHERE mg.microgrid_id = %s AND mg.buy_meter_id = m.id ",
483
                              (microgrid_id,))
484
        row_meter = cursor_system.fetchone()
485
        if row_meter is not None:
486
            meter_list.append({"id": row_meter[0],
487
                               "name": row_meter[1] + '.Buy',
488
                               "energy_category_id": row_meter[2]})
489
490
        cursor_system.execute(" SELECT m.id, mg.name, m.energy_category_id  "
491
                              " FROM tbl_microgrids_grids mg, tbl_meters m "
492
                              " WHERE mg.microgrid_id = %s AND mg.sell_meter_id = m.id ",
493
                              (microgrid_id,))
494
        row_meter = cursor_system.fetchone()
495
        if row_meter is not None:
496
            meter_list.append({"id": row_meter[0],
497
                               "name": row_meter[1] + '.Sell',
498
                               "energy_category_id": row_meter[2]})
499
500
        ################################################################################################################
501
        # Step 8: query associated heatpumps
502
        ################################################################################################################
503
        cursor_system.execute(" SELECT p.id, mh.name, p.units, p.object_type  "
504
                              " FROM tbl_microgrids_heatpumps mh, tbl_points p "
505
                              " WHERE mh.microgrid_id = %s AND mh.power_point_id = p.id ",
506
                              (microgrid_id,))
507
        row_point = cursor_system.fetchone()
508
        if row_point is not None:
509
            point_list.append({"id": row_point[0],
510
                               "name": row_point[1]+'.P',
511
                               "units": row_point[2],
512
                               "object_type": row_point[3]})
513
514
        cursor_system.execute(" SELECT m.id, mh.name, m.energy_category_id  "
515
                              " FROM tbl_microgrids_heatpumps mh, tbl_meters m "
516
                              " WHERE mh.microgrid_id = %s AND mh.electricity_meter_id = m.id ",
517
                              (microgrid_id,))
518
        row_meter = cursor_system.fetchone()
519
        if row_meter is not None:
520
            meter_list.append({"id": row_meter[0],
521
                               "name": row_meter[1] + '.Electricity',
522
                               "energy_category_id": row_meter[2]})
523
524
        cursor_system.execute(" SELECT m.id, mh.name, m.energy_category_id  "
525
                              " FROM tbl_microgrids_heatpumps mh, tbl_meters m "
526
                              " WHERE mh.microgrid_id = %s AND mh.heat_meter_id = m.id ",
527
                              (microgrid_id,))
528
        row_meter = cursor_system.fetchone()
529
        if row_meter is not None:
530
            meter_list.append({"id": row_meter[0],
531
                               "name": row_meter[1] + '.Heat',
532
                               "energy_category_id": row_meter[2]})
533
534
        cursor_system.execute(" SELECT m.id, mh.name, m.energy_category_id  "
535
                              " FROM tbl_microgrids_heatpumps mh, tbl_meters m "
536
                              " WHERE mh.microgrid_id = %s AND mh.cooling_meter_id = m.id ",
537
                              (microgrid_id,))
538
        row_meter = cursor_system.fetchone()
539
        if row_meter is not None:
540
            meter_list.append({"id": row_meter[0],
541
                               "name": row_meter[1] + '.Cooling',
542
                               "energy_category_id": row_meter[2]})
543
544
        ################################################################################################################
545
        # Step 9: query associated loads
546
        ################################################################################################################
547
        cursor_system.execute(" SELECT p.id, ml.name, p.units, p.object_type  "
548
                              " FROM tbl_microgrids_loads ml, tbl_points p "
549
                              " WHERE ml.microgrid_id = %s AND ml.power_point_id = p.id ",
550
                              (microgrid_id,))
551
        row_point = cursor_system.fetchone()
552
        if row_point is not None:
553
            point_list.append({"id": row_point[0],
554
                               "name": row_point[1]+'.P',
555
                               "units": row_point[2],
556
                               "object_type": row_point[3]})
557
558
        cursor_system.execute(" SELECT m.id, ml.name, m.energy_category_id  "
559
                              " FROM tbl_microgrids_loads ml, tbl_meters m "
560
                              " WHERE ml.microgrid_id = %s AND ml.meter_id = m.id ",
561
                              (microgrid_id,))
562
        row_meter = cursor_system.fetchone()
563
        if row_meter is not None:
564
            meter_list.append({"id": row_meter[0],
565
                               "name": row_meter[1],
566
                               "energy_category_id": row_meter[2]})
567
        ################################################################################################################
568
        # Step 10: query associated photovoltaics
569
        ################################################################################################################
570
        cursor_system.execute(" SELECT p.id, mp.name, p.units, p.object_type  "
571
                              " FROM tbl_microgrids_photovoltaics mp, tbl_points p "
572
                              " WHERE mp.id = %s AND mp.power_point_id = p.id ",
573
                              (microgrid_id,))
574
        row_point = cursor_system.fetchone()
575
        if row_point is not None:
576
            point_list.append({"id": row_point[0],
577
                               "name": row_point[1]+'.P',
578
                               "units": row_point[2],
579
                               "object_type": row_point[3]})
580
581
        cursor_system.execute(" SELECT m.id, mp.name, m.energy_category_id  "
582
                              " FROM tbl_microgrids_photovoltaics mp, tbl_meters m "
583
                              " WHERE mp.id = %s AND mp.meter_id = m.id ",
584
                              (microgrid_id,))
585
        row_meter = cursor_system.fetchone()
586
        if row_meter is not None:
587
            meter_list.append({"id": row_meter[0],
588
                               "name": row_meter[1],
589
                               "energy_category_id": row_meter[2]})
590
591
        ################################################################################################################
592
        # Step 11: query associated schedules
593
        ################################################################################################################
594
        schedule_list = list()
595
        schedule_series_data = list()
596
        cursor_system.execute(" SELECT start_time_of_day, end_time_of_day, peak_type, power "
597
                              " FROM tbl_microgrids_schedules "
598
                              " WHERE microgrid_id = %s "
599
                              " ORDER BY start_time_of_day ",
600
                              (microgrid_id,))
601
        rows_schedules = cursor_system.fetchall()
602 View Code Duplication
        if rows_schedules is None or len(rows_schedules) == 0:
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
603
            pass
604
        else:
605
            for row_schedule in rows_schedules:
606
                start_time = row_schedule[0]
607
                end_time = row_schedule[1]
608
                current_time = start_time
609
                if row_schedule[2] == 'toppeak':
610
                    peak_type = 'Top-Peak'
611
                elif row_schedule[2] == 'onpeak':
612
                    peak_type = 'On-Peak'
613
                elif row_schedule[2] == 'midpeak':
614
                    peak_type = 'Mid-Peak'
615
                elif row_schedule[2] == 'offpeak':
616
                    peak_type = 'Off-Peak'
617
                elif row_schedule[2] == 'deep':
618
                    peak_type = 'Deep-Valley'
619
                else:
620
                    peak_type = 'Unknown'
621
622
                while current_time < end_time:
623
                    schedule_series_data.append(row_schedule[3])
624
                    current_time = current_time + timedelta(minutes=30)
625
626
                schedule_list.append({"start_time_of_day": '0' + str(start_time) if len(str(start_time)) == 7
627
                                     else str(start_time),
628
                                      "end_time_of_day": '0' + str(end_time) if len(str(end_time)) == 7
629
                                      else str(end_time),
630
                                      "peak_type": peak_type,
631
                                      "power": row_schedule[3]})
632
            print('schedule_list:' + str(schedule_list))
633
        ################################################################################################################
634
        # Step 12: query associated sensors
635
        ################################################################################################################
636
        cursor_system.execute(" SELECT p.id, p.name, p.units, p.object_type "
637
                              " FROM tbl_microgrids_sensors ms, tbl_sensors_points sp, tbl_points p "
638
                              " WHERE ms.microgrid_id = %s "
639
                              " AND ms.sensor_id = sp.sensor_id "
640
                              " AND sp.point_id  = p.id ",
641
                              (microgrid_id,))
642
        rows_points = cursor_system.fetchall()
643
        if rows_points is not None and len(rows_points) > 0:
644
            for row_point in rows_points:
645
                point_list.append({"id": row_point[0],
646
                                   "name": row_point[1],
647
                                   "units": row_point[2],
648
                                   "object_type": row_point[3]})
649
        ################################################################################################################
650
        # Step 13: query associated meters data
651
        ################################################################################################################
652
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
653
        if config.utc_offset[0] == '-':
654
            timezone_offset = -timezone_offset
655
656
        cnx_energy = mysql.connector.connect(**config.myems_energy_db)
657
        cursor_energy = cnx_energy.cursor()
658
659
        meter_report_list = list()
660
661
        for meter in meter_list:
662
            cursor_energy.execute(" SELECT start_datetime_utc, actual_value "
663
                                  " FROM tbl_meter_hourly "
664
                                  " WHERE meter_id = %s "
665
                                  "     AND start_datetime_utc >= %s "
666
                                  "     AND start_datetime_utc < %s "
667
                                  " ORDER BY start_datetime_utc ",
668
                                  (meter['id'],
669
                                   reporting_start_datetime_utc,
670
                                   reporting_end_datetime_utc))
671
            rows_meter_hourly = cursor_energy.fetchall()
672
            if rows_meter_hourly is not None and len(rows_meter_hourly) > 0:
673
                meter_report = dict()
674
                meter_report['timestamps'] = list()
675
                meter_report['values'] = list()
676
                meter_report['subtotal'] = Decimal(0.0)
677
678
                for row_meter_hourly in rows_meter_hourly:
679
                    current_datetime_local = row_meter_hourly[0].replace(tzinfo=timezone.utc) + \
680
                                             timedelta(minutes=timezone_offset)
681
                    current_datetime = current_datetime_local.isoformat()[0:19]
682
683
                    actual_value = Decimal(0.0) if row_meter_hourly[1] is None else row_meter_hourly[1]
684
685
                    meter_report['timestamps'].append(current_datetime)
686
                    meter_report['values'].append(actual_value)
687
                    meter_report['subtotal'] += actual_value
688
                    meter_report['name'] = meter['name']
689
                    meter_report['unit_of_measure'] = \
690
                        energy_category_dict[meter['energy_category_id']]['unit_of_measure']
691
692
                meter_report_list.append(meter_report)
693
694
        ################################################################################################################
695
        # Step 14: query associated points data
696
        ################################################################################################################
697
698
        parameters_data = dict()
699
        parameters_data['names'] = list()
700
        parameters_data['timestamps'] = list()
701
        parameters_data['values'] = list()
702
        for point in point_list:
703
            point_values = []
704
            point_timestamps = []
705
            if point['object_type'] == 'ENERGY_VALUE':
706
                query = (" SELECT utc_date_time, actual_value "
707
                         " FROM tbl_energy_value "
708
                         " WHERE point_id = %s "
709
                         "       AND utc_date_time BETWEEN %s AND %s "
710
                         " ORDER BY utc_date_time ")
711
                cursor_historical.execute(query, (point['id'],
712
                                                  reporting_start_datetime_utc,
713
                                                  reporting_end_datetime_utc))
714
                rows = cursor_historical.fetchall()
715
716
                if rows is not None and len(rows) > 0:
717
                    reporting_start_datetime_local = reporting_start_datetime_utc.replace(tzinfo=timezone.utc) + \
718
                                                     timedelta(minutes=timezone_offset)
719
                    current_datetime_local = reporting_start_datetime_local
720
721
                    while current_datetime_local < rows[0][0].replace(tzinfo=timezone.utc) + \
722
                            timedelta(minutes=timezone_offset):
723
                        point_timestamps.append(current_datetime_local.isoformat()[5:16])
724
                        point_values.append(rows[0][1])
725
                        current_datetime_local += timedelta(minutes=1)
726
727
                    for index in range(len(rows) - 1):
728
                        while current_datetime_local < rows[index + 1][0].replace(tzinfo=timezone.utc) + \
729
                                timedelta(minutes=timezone_offset):
730
                            point_timestamps.append(current_datetime_local.isoformat()[5:16])
731
                            point_values.append(rows[index][1])
732
                            current_datetime_local += timedelta(minutes=1)
733
            elif point['object_type'] == 'ANALOG_VALUE':
734
                query = (" SELECT utc_date_time, actual_value "
735
                         " FROM tbl_analog_value "
736
                         " WHERE point_id = %s "
737
                         "       AND utc_date_time BETWEEN %s AND %s "
738
                         " ORDER BY utc_date_time ")
739
                cursor_historical.execute(query, (point['id'],
740
                                                  reporting_start_datetime_utc,
741
                                                  reporting_end_datetime_utc))
742
                rows = cursor_historical.fetchall()
743
744
                if rows is not None and len(rows) > 0:
745
                    reporting_start_datetime_local = reporting_start_datetime_utc.replace(tzinfo=timezone.utc) + \
746
                                                     timedelta(minutes=timezone_offset)
747
                    current_datetime_local = reporting_start_datetime_local
748
749
                    while current_datetime_local < rows[0][0].replace(tzinfo=timezone.utc) + \
750
                            timedelta(minutes=timezone_offset):
751
                        point_timestamps.append(current_datetime_local.isoformat()[5:16])
752
                        point_values.append(rows[0][1])
753
                        current_datetime_local += timedelta(minutes=1)
754
755
                    for index in range(len(rows) - 1):
756
                        while current_datetime_local < rows[index + 1][0].replace(tzinfo=timezone.utc) + \
757
                                timedelta(minutes=timezone_offset):
758
                            point_timestamps.append(current_datetime_local.isoformat()[5:16])
759
                            point_values.append(rows[index][1])
760
                            current_datetime_local += timedelta(minutes=1)
761
            elif point['object_type'] == 'DIGITAL_VALUE':
762
                query = (" SELECT utc_date_time, actual_value "
763
                         " FROM tbl_digital_value "
764
                         " WHERE point_id = %s "
765
                         "       AND utc_date_time BETWEEN %s AND %s "
766
                         " ORDER BY utc_date_time ")
767
                cursor_historical.execute(query, (point['id'],
768
                                                  reporting_start_datetime_utc,
769
                                                  reporting_end_datetime_utc))
770
                rows = cursor_historical.fetchall()
771
772
                if rows is not None and len(rows) > 0:
773
                    reporting_start_datetime_local = reporting_start_datetime_utc.replace(tzinfo=timezone.utc) + \
774
                                                     timedelta(minutes=timezone_offset)
775
                    current_datetime_local = reporting_start_datetime_local
776
777
                    while current_datetime_local < rows[0][0].replace(tzinfo=timezone.utc) + \
778
                            timedelta(minutes=timezone_offset):
779
                        point_timestamps.append(current_datetime_local.isoformat()[5:16])
780
                        point_values.append(rows[0][1])
781
                        current_datetime_local += timedelta(minutes=1)
782
783
                    for index in range(len(rows) - 1):
784
                        while current_datetime_local < rows[index + 1][0].replace(tzinfo=timezone.utc) + \
785
                                timedelta(minutes=timezone_offset):
786
                            point_timestamps.append(current_datetime_local.isoformat()[5:16])
787
                            point_values.append(rows[index][1])
788
                            current_datetime_local += timedelta(minutes=1)
789
790
            parameters_data['names'].append(point['name'] + ' (' + point['units'] + ')')
791
            parameters_data['timestamps'].append(point_timestamps)
792
            parameters_data['values'].append(point_values)
793
794
        if cursor_system:
795
            cursor_system.close()
796
        if cnx_system:
797
            cnx_system.close()
798
799
        if cursor_historical:
800
            cursor_historical.close()
801
        if cnx_historical:
802
            cnx_historical.close()
803
        ################################################################################################################
804
        # Step 15: construct the report
805
        ################################################################################################################
806
        result = dict()
807
        result['microgrid'] = meta_result
808
809
        result['reporting_period'] = dict()
810
        result['reporting_period']['names'] = list()
811
        result['reporting_period']['units'] = list()
812
        result['reporting_period']['subtotals'] = list()
813
        result['reporting_period']['increment_rates'] = list()
814
        result['reporting_period']['timestamps'] = list()
815
        result['reporting_period']['values'] = list()
816
817
        if meter_report_list is not None and len(meter_report_list) > 0:
818
            for meter_report in meter_report_list:
819
                result['reporting_period']['names'].append(meter_report['name'])
820
                result['reporting_period']['units'].append(meter_report['unit_of_measure'])
821
                result['reporting_period']['timestamps'].append(meter_report['timestamps'])
822
                result['reporting_period']['values'].append(meter_report['values'])
823
                result['reporting_period']['subtotals'].append(meter_report['subtotal'])
824
825
        result['schedule'] = dict()
826
        result['schedule']['series_data'] = schedule_series_data
827
        result['schedule']['schedule_list'] = schedule_list
828
829
        result['energy_indicators'] = dict()
830
        result['energy_indicators']['today_charge_energy_value'] = today_charge_energy_value
831
        result['energy_indicators']['today_discharge_energy_value'] = today_discharge_energy_value
832
        result['energy_indicators']['total_charge_energy_value'] = total_charge_energy_value
833
        result['energy_indicators']['total_discharge_energy_value'] = total_discharge_energy_value
834
835
        result['revenue_indicators'] = dict()
836
        result['revenue_indicators']['today_charge_revenue_value'] = today_charge_revenue_value
837
        result['revenue_indicators']['today_discharge_revenue_value'] = today_discharge_revenue_value
838
        result['revenue_indicators']['total_charge_revenue_value'] = total_charge_revenue_value
839
        result['revenue_indicators']['total_discharge_revenue_value'] = total_discharge_revenue_value
840
841
        result['carbon_indicators'] = dict()
842
        result['carbon_indicators']['today_charge_carbon_value'] = today_charge_carbon_value
843
        result['carbon_indicators']['today_discharge_carbon_value'] = today_discharge_carbon_value
844
        result['carbon_indicators']['total_charge_carbon_value'] = total_charge_carbon_value
845
        result['carbon_indicators']['total_discharge_carbon_value'] = total_discharge_carbon_value
846
847
        result['parameters'] = {
848
            "names": parameters_data['names'],
849
            "timestamps": parameters_data['timestamps'],
850
            "values": parameters_data['values']
851
        }
852
853
        resp.text = json.dumps(result)
854
855