Passed
Push — master ( d99a30...2e4a80 )
by
unknown
12:38
created

reports.microgridevcharger.Reporting.__init__()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 3
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 2
dl 3
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
from datetime import datetime, timedelta, timezone
2
from decimal import Decimal
3
import falcon
4
import mysql.connector
5
import simplejson as json
6
from core import utilities
7
import config
8
from core.useractivity import access_control, api_key_control
9
10
11 View Code Duplication
class Reporting:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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 list
25
    # Step 3: query evcharger energy data in 7 days
26
    # Step 4: query evcharger energy data in this month
27
    # Step 5: query evcharger energy data in this year
28
    # Step 6: construct the report
29
    ####################################################################################################################
30
    @staticmethod
31
    def on_get(req, resp):
32
        if 'API-KEY' not in req.headers or \
33
                not isinstance(req.headers['API-KEY'], str) or \
34
                len(str.strip(req.headers['API-KEY'])) == 0:
35
            access_control(req)
36
        else:
37
            api_key_control(req)
38
        user_uuid = req.params.get('useruuid')
39
40
        ################################################################################################################
41
        # Step 1: valid parameters
42
        ################################################################################################################
43
        if user_uuid is None:
44
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_USER_UUID')
45
        else:
46
            user_uuid = str.strip(user_uuid)
47
            if len(user_uuid) != 36:
48
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
49
                                       description='API.INVALID_USER_UUID')
50
51
        ################################################################################################################
52
        # Step 2: query the microgrid list
53
        ################################################################################################################
54
        cnx_user = mysql.connector.connect(**config.myems_user_db)
55
        cursor_user = cnx_user.cursor()
56
        cursor_user.execute(" SELECT id, is_admin, privilege_id "
57
                            " FROM tbl_users "
58
                            " WHERE uuid = %s ", (user_uuid,))
59
        row_user = cursor_user.fetchone()
60
        if row_user is None:
61
            if cursor_user:
62
                cursor_user.close()
63
            if cnx_user:
64
                cnx_user.close()
65
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
66
                                   description='API.USER_NOT_FOUND')
67
68
        user = {'id': row_user[0], 'is_admin': row_user[1], 'privilege_id': row_user[2]}
69
70
        # Get microgrids
71
        cnx_system_db = mysql.connector.connect(**config.myems_system_db)
72
        cursor_system_db = cnx_system_db.cursor()
73
        query = (" SELECT m.id, m.name, m.uuid, "
74
                 "        m.address, m.postal_code, m.latitude, m.longitude, "
75
                 "        m.rated_capacity, m.rated_power, m.serial_number, m.description "
76
                 " FROM tbl_microgrids m, tbl_microgrids_users mu "
77
                 " WHERE m.id = mu.microgrid_id AND mu.user_id = %s "
78
                 " ORDER BY id ")
79
        cursor_system_db.execute(query, (user['id'],))
80
        rows_microgrids = cursor_system_db.fetchall()
81
82
        microgrid_list = list()
83
        microgrid_names = list()
84
        if rows_microgrids is not None and len(rows_microgrids) > 0:
85
            for row in rows_microgrids:
86
                meta_result = {"id": row[0],
87
                               "name": row[1],
88
                               "uuid": row[2],
89
                               "address": row[3],
90
                               "postal_code": row[4],
91
                               "latitude": row[5],
92
                               "longitude": row[6],
93
                               "rated_capacity": row[7],
94
                               "rated_power": row[8],
95
                               "serial_number": row[9],
96
                               "description": row[10]}
97
                microgrid_list.append(meta_result)
98
                microgrid_names.append(row[1])
99
100
        ################################################################################################################
101
        # Step 3: query evcharger energy data in 7 days
102
        ################################################################################################################
103
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
104
        if config.utc_offset[0] == '-':
105
            timezone_offset = -timezone_offset
106
        reporting = dict()
107
        reporting['evcharger_7_days'] = dict()
108
        reporting['evcharger_this_month'] = dict()
109
        reporting['evcharger_this_year'] = dict()
110
111
        end_datetime_utc = datetime.utcnow()
112
        end_datetime_local = datetime.utcnow() + timedelta(minutes=timezone_offset)
113
        period_type = 'daily'
114
        start_datetime_local = end_datetime_local.replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=6)
115
        start_datetime_utc = start_datetime_local - timedelta(minutes=timezone_offset)
116
        print('start_datetime_local:' + start_datetime_local.isoformat())
117
        print('end_datetime_local:' + end_datetime_local.isoformat())
118
        print('start_datetime_utc:' + start_datetime_utc.isoformat())
119
        print('end_datetime_utc:' + end_datetime_utc.isoformat())
120
121
        cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
122
        cursor_energy_db = cnx_energy_db.cursor()
123
124
        reporting['evcharger_7_days'] = dict()
125
        reporting['evcharger_7_days']['timestamps_array'] = list()
126
        reporting['evcharger_7_days']['values_array'] = list()
127
128
        for microgrid in microgrid_list:
129
            timestamps = list()
130
            values = list()
131
            query = (" SELECT start_datetime_utc, actual_value "
132
                     " FROM tbl_microgrid_evcharger_hourly "
133
                     " WHERE microgrid_id = %s "
134
                     " AND start_datetime_utc >= %s "
135
                     " AND start_datetime_utc < %s "
136
                     " ORDER BY start_datetime_utc ")
137
            cursor_energy_db.execute(query, (microgrid['id'], start_datetime_utc, end_datetime_utc))
138
            rows_evcharger_hourly = cursor_energy_db.fetchall()
139
140
            rows_evcharger_periodically = utilities.aggregate_hourly_data_by_period(rows_evcharger_hourly,
141
                                                                                    start_datetime_utc,
142
                                                                                    end_datetime_utc,
143
                                                                                    period_type)
144
            for row_evcharger_periodically in rows_evcharger_periodically:
145
                current_datetime_local = row_evcharger_periodically[0].replace(tzinfo=timezone.utc) + \
146
                                         timedelta(minutes=timezone_offset)
147
                if period_type == 'hourly':
148
                    current_datetime = current_datetime_local.isoformat()[0:19]
149
                elif period_type == 'daily':
150
                    current_datetime = current_datetime_local.isoformat()[0:10]
151
                elif period_type == 'weekly':
152
                    current_datetime = current_datetime_local.isoformat()[0:10]
153
                elif period_type == 'monthly':
154
                    current_datetime = current_datetime_local.isoformat()[0:7]
155
                elif period_type == 'yearly':
156
                    current_datetime = current_datetime_local.isoformat()[0:4]
157
158
                actual_value = Decimal(0.0) if row_evcharger_periodically[1] is None else row_evcharger_periodically[1]
159
                timestamps.append(current_datetime)
0 ignored issues
show
introduced by
The variable current_datetime does not seem to be defined for all execution paths.
Loading history...
160
                values.append(actual_value)
161
            reporting['evcharger_7_days']['timestamps_array'].append(timestamps)
162
            reporting['evcharger_7_days']['values_array'].append(values)
163
164
        ################################################################################################################
165
        # Step 4: query evcharger energy data in this month
166
        ################################################################################################################
167
        end_datetime_utc = datetime.utcnow()
168
        end_datetime_local = datetime.utcnow() + timedelta(minutes=timezone_offset)
169
        period_type = 'daily'
170
        start_datetime_local = end_datetime_local.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
171
        start_datetime_utc = start_datetime_local - timedelta(minutes=timezone_offset)
172
        print('start_datetime_local:' + start_datetime_local.isoformat())
173
        print('end_datetime_local:' + end_datetime_local.isoformat())
174
        print('start_datetime_utc:' + start_datetime_utc.isoformat())
175
        print('end_datetime_utc:' + end_datetime_utc.isoformat())
176
177
        reporting['evcharger_this_month'] = dict()
178
        reporting['evcharger_this_month']['timestamps_array'] = list()
179
        reporting['evcharger_this_month']['values_array'] = list()
180
181
        for microgrid in microgrid_list:
182
            timestamps = list()
183
            values = list()
184
            query = (" SELECT start_datetime_utc, actual_value "
185
                     " FROM tbl_microgrid_evcharger_hourly "
186
                     " WHERE microgrid_id = %s "
187
                     " AND start_datetime_utc >= %s "
188
                     " AND start_datetime_utc < %s "
189
                     " ORDER BY start_datetime_utc ")
190
            cursor_energy_db.execute(query, (microgrid['id'], start_datetime_utc, end_datetime_utc))
191
            rows_evcharger_hourly = cursor_energy_db.fetchall()
192
193
            rows_evcharger_periodically = utilities.aggregate_hourly_data_by_period(rows_evcharger_hourly,
194
                                                                                    start_datetime_utc,
195
                                                                                    end_datetime_utc,
196
                                                                                    period_type)
197
198
            for row_evcharger_periodically in rows_evcharger_periodically:
199
                current_datetime_local = row_evcharger_periodically[0].replace(tzinfo=timezone.utc) + \
200
                                         timedelta(minutes=timezone_offset)
201
                if period_type == 'hourly':
202
                    current_datetime = current_datetime_local.isoformat()[0:19]
203
                elif period_type == 'daily':
204
                    current_datetime = current_datetime_local.isoformat()[0:10]
205
                elif period_type == 'weekly':
206
                    current_datetime = current_datetime_local.isoformat()[0:10]
207
                elif period_type == 'monthly':
208
                    current_datetime = current_datetime_local.isoformat()[0:7]
209
                elif period_type == 'yearly':
210
                    current_datetime = current_datetime_local.isoformat()[0:4]
211
212
                actual_value = Decimal(0.0) if row_evcharger_periodically[1] is None else row_evcharger_periodically[1]
213
                timestamps.append(current_datetime)
214
                values.append(actual_value)
215
            reporting['evcharger_this_month']['timestamps_array'].append(timestamps)
216
            reporting['evcharger_this_month']['values_array'].append(values)
217
218
        ################################################################################################################
219
        # Step 5: query evcharger energy data in this year
220
        ################################################################################################################
221
        end_datetime_utc = datetime.utcnow()
222
        end_datetime_local = datetime.utcnow() + timedelta(minutes=timezone_offset)
223
        period_type = 'monthly'
224
        start_datetime_local = end_datetime_local.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
225
        start_datetime_utc = start_datetime_local - timedelta(minutes=timezone_offset)
226
        print('start_datetime_local:' + start_datetime_local.isoformat())
227
        print('end_datetime_local:' + end_datetime_local.isoformat())
228
        print('start_datetime_utc:' + start_datetime_utc.isoformat())
229
        print('end_datetime_utc:' + end_datetime_utc.isoformat())
230
231
        reporting['evcharger_this_year'] = dict()
232
        reporting['evcharger_this_year']['timestamps_array'] = list()
233
        reporting['evcharger_this_year']['values_array'] = list()
234
235
        for microgrid in microgrid_list:
236
            timestamps = list()
237
            values = list()
238
            query = (" SELECT start_datetime_utc, actual_value "
239
                     " FROM tbl_microgrid_evcharger_hourly "
240
                     " WHERE microgrid_id = %s "
241
                     " AND start_datetime_utc >= %s "
242
                     " AND start_datetime_utc < %s "
243
                     " ORDER BY start_datetime_utc ")
244
            cursor_energy_db.execute(query, (microgrid['id'], start_datetime_utc, end_datetime_utc))
245
            rows_evcharger_hourly = cursor_energy_db.fetchall()
246
247
            rows_evcharger_periodically = utilities.aggregate_hourly_data_by_period(rows_evcharger_hourly,
248
                                                                                    start_datetime_utc,
249
                                                                                    end_datetime_utc,
250
                                                                                    period_type)
251
            for row_evcharger_periodically in rows_evcharger_periodically:
252
                current_datetime_local = row_evcharger_periodically[0].replace(tzinfo=timezone.utc) + \
253
                                         timedelta(minutes=timezone_offset)
254
                if period_type == 'hourly':
255
                    current_datetime = current_datetime_local.isoformat()[0:19]
256
                elif period_type == 'daily':
257
                    current_datetime = current_datetime_local.isoformat()[0:10]
258
                elif period_type == 'weekly':
259
                    current_datetime = current_datetime_local.isoformat()[0:10]
260
                elif period_type == 'monthly':
261
                    current_datetime = current_datetime_local.isoformat()[0:7]
262
                elif period_type == 'yearly':
263
                    current_datetime = current_datetime_local.isoformat()[0:4]
264
265
                actual_value = Decimal(0.0) if row_evcharger_periodically[1] is None else row_evcharger_periodically[1]
266
                timestamps.append(current_datetime)
267
                values.append(actual_value)
268
            reporting['evcharger_this_year']['timestamps_array'].append(timestamps)
269
            reporting['evcharger_this_year']['values_array'].append(values)
270
271
        ################################################################################################################
272
        # Step 6: construct the report
273
        ################################################################################################################
274
        if cursor_user:
275
            cursor_user.close()
276
        if cnx_user:
277
            cnx_user.close()
278
279
        if cursor_system_db:
280
            cursor_system_db.close()
281
        if cnx_system_db:
282
            cnx_system_db.close()
283
284
        if cursor_energy_db:
285
            cursor_energy_db.close()
286
        if cnx_energy_db:
287
            cnx_energy_db.close()
288
289
        result = dict()
290
        result['microgrid_names'] = microgrid_names
291
        result['reporting'] = reporting
292
        resp.text = json.dumps(result)
293
294