Total Complexity | 226 |
Total Lines | 1036 |
Duplicated Lines | 43.53 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like core.utilities often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | import collections |
||
2 | import statistics |
||
3 | from datetime import datetime, timedelta |
||
4 | from decimal import Decimal |
||
5 | import mysql.connector |
||
6 | import config |
||
7 | import gettext |
||
8 | |||
9 | |||
10 | ######################################################################################################################## |
||
11 | # Aggregate hourly data by period |
||
12 | # |
||
13 | # This function aggregates hourly energy data into different time periods (hourly, daily, weekly, monthly, yearly). |
||
14 | # It processes raw hourly data and groups it according to the specified period type for reporting and analysis. |
||
15 | # |
||
16 | # Args: |
||
17 | # rows_hourly: List of tuples containing (start_datetime_utc, actual_value) for hourly data |
||
18 | # Should belong to one energy_category_id |
||
19 | # start_datetime_utc: Start datetime in UTC for the aggregation period |
||
20 | # end_datetime_utc: End datetime in UTC for the aggregation period |
||
21 | # period_type: Period type for aggregation - 'hourly', 'daily', 'weekly', 'monthly', or 'yearly' |
||
22 | # |
||
23 | # Returns: |
||
24 | # List of tuples containing (datetime_utc, aggregated_value) for the specified period type |
||
25 | # |
||
26 | # Note: This procedure doesn't work with multiple energy categories |
||
27 | ######################################################################################################################## |
||
28 | def aggregate_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetime_utc, period_type): |
||
29 | # Validate input parameters |
||
30 | if start_datetime_utc is None or \ |
||
31 | end_datetime_utc is None or \ |
||
32 | start_datetime_utc >= end_datetime_utc or \ |
||
33 | period_type not in ('hourly', 'daily', 'weekly', 'monthly', 'yearly'): |
||
34 | return list() |
||
35 | |||
36 | # Remove timezone info for consistent processing |
||
37 | start_datetime_utc = start_datetime_utc.replace(tzinfo=None) |
||
38 | end_datetime_utc = end_datetime_utc.replace(tzinfo=None) |
||
39 | |||
40 | # Process hourly aggregation |
||
41 | if period_type == "hourly": |
||
42 | result_rows_hourly = list() |
||
43 | # TODO: add config.working_day_start_time_local |
||
44 | # TODO: add config.minutes_to_count |
||
45 | current_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None) |
||
46 | while current_datetime_utc <= end_datetime_utc: |
||
47 | subtotal = None |
||
48 | # Sum values within the current hour period |
||
49 | for row in rows_hourly: |
||
50 | if current_datetime_utc <= row[0] < current_datetime_utc + \ |
||
51 | timedelta(minutes=config.minutes_to_count): |
||
52 | if row[1] is not None: |
||
53 | if subtotal is None: |
||
54 | subtotal = row[1] |
||
55 | else: |
||
56 | subtotal += row[1] |
||
57 | result_rows_hourly.append((current_datetime_utc, subtotal)) |
||
58 | current_datetime_utc += timedelta(minutes=config.minutes_to_count) |
||
59 | |||
60 | return result_rows_hourly |
||
61 | |||
62 | # Process daily aggregation |
||
63 | elif period_type == "daily": |
||
64 | result_rows_daily = list() |
||
65 | # TODO: add config.working_day_start_time_local |
||
66 | # TODO: add config.minutes_to_count |
||
67 | # Calculate the start datetime in UTC of the first day in local timezone |
||
68 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
69 | current_datetime_utc = start_datetime_local.replace(hour=0) - timedelta(hours=int(config.utc_offset[1:3])) |
||
70 | while current_datetime_utc <= end_datetime_utc: |
||
71 | subtotal = None |
||
72 | for row in rows_hourly: |
||
73 | if current_datetime_utc <= row[0] < current_datetime_utc + timedelta(days=1): |
||
74 | if row[1] is not None: |
||
75 | if subtotal is None: |
||
76 | subtotal = row[1] |
||
77 | else: |
||
78 | subtotal += row[1] |
||
79 | result_rows_daily.append((current_datetime_utc, subtotal)) |
||
80 | current_datetime_utc += timedelta(days=1) |
||
81 | |||
82 | return result_rows_daily |
||
83 | |||
84 | elif period_type == 'weekly': |
||
85 | result_rows_weekly = list() |
||
86 | # todo: add config.working_day_start_time_local |
||
87 | # todo: add config.minutes_to_count |
||
88 | # calculate the start datetime in utc of the monday in the first week in local |
||
89 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
90 | weekday = start_datetime_local.weekday() |
||
91 | current_datetime_utc = \ |
||
92 | start_datetime_local.replace(hour=0) - timedelta(days=weekday, hours=int(config.utc_offset[1:3])) |
||
93 | while current_datetime_utc <= end_datetime_utc: |
||
94 | |||
95 | next_datetime_utc = current_datetime_utc + timedelta(days=7) |
||
96 | subtotal = None |
||
97 | for row in rows_hourly: |
||
98 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
99 | if row[1] is not None: |
||
100 | if subtotal is None: |
||
101 | subtotal = row[1] |
||
102 | else: |
||
103 | subtotal += row[1] |
||
104 | result_rows_weekly.append((current_datetime_utc, subtotal)) |
||
105 | current_datetime_utc = next_datetime_utc |
||
106 | |||
107 | return result_rows_weekly |
||
108 | |||
109 | elif period_type == "monthly": |
||
110 | result_rows_monthly = list() |
||
111 | # todo: add config.working_day_start_time_local |
||
112 | # todo: add config.minutes_to_count |
||
113 | # calculate the start datetime the first day in the first month in local |
||
114 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
115 | current_datetime_local = start_datetime_local.replace(day=1, hour=0, minute=0, |
||
116 | second=0, microsecond=0) |
||
117 | end_datetime_local = end_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
118 | while current_datetime_local <= end_datetime_local: |
||
119 | # calculate the next datetime in local |
||
120 | if current_datetime_local.month < 12: |
||
121 | next_datetime_local = datetime(year=current_datetime_local.year, |
||
122 | month=current_datetime_local.month + 1, |
||
123 | day=1, hour=0, minute=0, second=0, microsecond=0, tzinfo=None) |
||
124 | elif current_datetime_local.month == 12: |
||
125 | next_datetime_local = datetime(year=current_datetime_local.year + 1, |
||
126 | month=1, |
||
127 | day=1, hour=0, minute=0, second=0, microsecond=0, tzinfo=None) |
||
128 | current_datetime_utc = current_datetime_local - timedelta(hours=int(config.utc_offset[1:3])) |
||
129 | next_datetime_utc = next_datetime_local - timedelta(hours=int(config.utc_offset[1:3])) |
||
|
|||
130 | subtotal = None |
||
131 | for row in rows_hourly: |
||
132 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
133 | if row[1] is not None: |
||
134 | if subtotal is None: |
||
135 | subtotal = row[1] |
||
136 | else: |
||
137 | subtotal += row[1] |
||
138 | |||
139 | result_rows_monthly.append((current_datetime_utc, subtotal)) |
||
140 | current_datetime_local = next_datetime_local |
||
141 | |||
142 | return result_rows_monthly |
||
143 | |||
144 | elif period_type == "yearly": |
||
145 | result_rows_yearly = list() |
||
146 | # todo: add config.working_day_start_time_local |
||
147 | # todo: add config.minutes_to_count |
||
148 | # calculate the start datetime in utc of the first day in the first year in local |
||
149 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
150 | current_datetime_utc = start_datetime_local.replace(month=1, day=1, hour=0) - timedelta( |
||
151 | hours=int(config.utc_offset[1:3])) |
||
152 | |||
153 | while current_datetime_utc <= end_datetime_utc: |
||
154 | # calculate the next datetime in utc |
||
155 | # todo: timedelta of year |
||
156 | next_datetime_utc = datetime(year=current_datetime_utc.year + 2, |
||
157 | month=1, |
||
158 | day=1, |
||
159 | hour=current_datetime_utc.hour, |
||
160 | minute=current_datetime_utc.minute, |
||
161 | second=current_datetime_utc.second, |
||
162 | microsecond=current_datetime_utc.microsecond, |
||
163 | tzinfo=current_datetime_utc.tzinfo) - timedelta(days=1) |
||
164 | subtotal = None |
||
165 | for row in rows_hourly: |
||
166 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
167 | if row[1] is not None: |
||
168 | if subtotal is None: |
||
169 | subtotal = row[1] |
||
170 | else: |
||
171 | subtotal += row[1] |
||
172 | |||
173 | result_rows_yearly.append((current_datetime_utc, subtotal)) |
||
174 | current_datetime_utc = next_datetime_utc |
||
175 | return result_rows_yearly |
||
176 | else: |
||
177 | return list() |
||
178 | |||
179 | |||
180 | ######################################################################################################################## |
||
181 | # Get tariffs by energy category |
||
182 | ######################################################################################################################## |
||
183 | View Code Duplication | def get_energy_category_tariffs(cost_center_id, energy_category_id, start_datetime_utc, end_datetime_utc): |
|
184 | # todo: validate parameters |
||
185 | if cost_center_id is None: |
||
186 | return dict() |
||
187 | |||
188 | start_datetime_utc = start_datetime_utc.replace(tzinfo=None) |
||
189 | end_datetime_utc = end_datetime_utc.replace(tzinfo=None) |
||
190 | |||
191 | # get timezone offset in minutes, this value will be returned to client |
||
192 | timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6]) |
||
193 | if config.utc_offset[0] == '-': |
||
194 | timezone_offset = -timezone_offset |
||
195 | |||
196 | tariff_dict = collections.OrderedDict() |
||
197 | |||
198 | cnx = None |
||
199 | cursor = None |
||
200 | try: |
||
201 | cnx = mysql.connector.connect(**config.myems_system_db) |
||
202 | cursor = cnx.cursor() |
||
203 | query_tariffs = (" SELECT t.id, t.valid_from_datetime_utc, t.valid_through_datetime_utc " |
||
204 | " FROM tbl_tariffs t, tbl_cost_centers_tariffs cct " |
||
205 | " WHERE t.energy_category_id = %s AND " |
||
206 | " t.id = cct.tariff_id AND " |
||
207 | " cct.cost_center_id = %s AND " |
||
208 | " t.valid_through_datetime_utc >= %s AND " |
||
209 | " t.valid_from_datetime_utc <= %s " |
||
210 | " ORDER BY t.valid_from_datetime_utc ") |
||
211 | cursor.execute(query_tariffs, (energy_category_id, cost_center_id, start_datetime_utc, end_datetime_utc,)) |
||
212 | rows_tariffs = cursor.fetchall() |
||
213 | except Exception as e: |
||
214 | print(str(e)) |
||
215 | if cnx: |
||
216 | cnx.close() |
||
217 | if cursor: |
||
218 | cursor.close() |
||
219 | return dict() |
||
220 | |||
221 | if rows_tariffs is None or len(rows_tariffs) == 0: |
||
222 | if cursor: |
||
223 | cursor.close() |
||
224 | if cnx: |
||
225 | cnx.close() |
||
226 | return dict() |
||
227 | |||
228 | for row in rows_tariffs: |
||
229 | tariff_dict[row[0]] = {'valid_from_datetime_utc': row[1], |
||
230 | 'valid_through_datetime_utc': row[2], |
||
231 | 'rates': list()} |
||
232 | |||
233 | try: |
||
234 | query_timeofuse_tariffs = (" SELECT tariff_id, start_time_of_day, end_time_of_day, price " |
||
235 | " FROM tbl_tariffs_timeofuses " |
||
236 | " WHERE tariff_id IN ( " + ', '.join(map(str, tariff_dict.keys())) + ")" |
||
237 | " ORDER BY tariff_id, start_time_of_day ") |
||
238 | cursor.execute(query_timeofuse_tariffs, ) |
||
239 | rows_timeofuse_tariffs = cursor.fetchall() |
||
240 | except Exception as e: |
||
241 | print(str(e)) |
||
242 | if cnx: |
||
243 | cnx.close() |
||
244 | if cursor: |
||
245 | cursor.close() |
||
246 | return dict() |
||
247 | |||
248 | if cursor: |
||
249 | cursor.close() |
||
250 | if cnx: |
||
251 | cnx.close() |
||
252 | |||
253 | if rows_timeofuse_tariffs is None or len(rows_timeofuse_tariffs) == 0: |
||
254 | return dict() |
||
255 | |||
256 | for row in rows_timeofuse_tariffs: |
||
257 | tariff_dict[row[0]]['rates'].append({'start_time_of_day': row[1], |
||
258 | 'end_time_of_day': row[2], |
||
259 | 'price': row[3]}) |
||
260 | |||
261 | result = dict() |
||
262 | for tariff_id, tariff_value in tariff_dict.items(): |
||
263 | current_datetime_utc = tariff_value['valid_from_datetime_utc'] |
||
264 | while current_datetime_utc < tariff_value['valid_through_datetime_utc']: |
||
265 | for rate in tariff_value['rates']: |
||
266 | current_datetime_local = current_datetime_utc + timedelta(minutes=timezone_offset) |
||
267 | seconds_since_midnight = (current_datetime_local - |
||
268 | current_datetime_local.replace(hour=0, |
||
269 | second=0, |
||
270 | microsecond=0, |
||
271 | tzinfo=None)).total_seconds() |
||
272 | if rate['start_time_of_day'].total_seconds() <= \ |
||
273 | seconds_since_midnight < rate['end_time_of_day'].total_seconds(): |
||
274 | result[current_datetime_utc] = rate['price'] |
||
275 | break |
||
276 | |||
277 | # start from the next time slot |
||
278 | current_datetime_utc += timedelta(minutes=config.minutes_to_count) |
||
279 | |||
280 | return {k: v for k, v in result.items() if start_datetime_utc <= k <= end_datetime_utc} |
||
281 | |||
282 | |||
283 | ######################################################################################################################## |
||
284 | # Get peak types of tariff by energy category |
||
285 | # peak types: toppeak, onpeak, midpeak, offpeak, deep |
||
286 | ######################################################################################################################## |
||
287 | View Code Duplication | def get_energy_category_peak_types(cost_center_id, energy_category_id, start_datetime_utc, end_datetime_utc): |
|
288 | # todo: validate parameters |
||
289 | if cost_center_id is None: |
||
290 | return dict() |
||
291 | |||
292 | start_datetime_utc = start_datetime_utc.replace(tzinfo=None) |
||
293 | end_datetime_utc = end_datetime_utc.replace(tzinfo=None) |
||
294 | |||
295 | # get timezone offset in minutes, this value will be returned to client |
||
296 | timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6]) |
||
297 | if config.utc_offset[0] == '-': |
||
298 | timezone_offset = -timezone_offset |
||
299 | |||
300 | tariff_dict = collections.OrderedDict() |
||
301 | |||
302 | cnx = None |
||
303 | cursor = None |
||
304 | try: |
||
305 | cnx = mysql.connector.connect(**config.myems_system_db) |
||
306 | cursor = cnx.cursor() |
||
307 | query_tariffs = (" SELECT t.id, t.valid_from_datetime_utc, t.valid_through_datetime_utc " |
||
308 | " FROM tbl_tariffs t, tbl_cost_centers_tariffs cct " |
||
309 | " WHERE t.energy_category_id = %s AND " |
||
310 | " t.id = cct.tariff_id AND " |
||
311 | " cct.cost_center_id = %s AND " |
||
312 | " t.valid_through_datetime_utc >= %s AND " |
||
313 | " t.valid_from_datetime_utc <= %s " |
||
314 | " ORDER BY t.valid_from_datetime_utc ") |
||
315 | cursor.execute(query_tariffs, (energy_category_id, cost_center_id, start_datetime_utc, end_datetime_utc,)) |
||
316 | rows_tariffs = cursor.fetchall() |
||
317 | except Exception as e: |
||
318 | print(str(e)) |
||
319 | if cnx: |
||
320 | cnx.close() |
||
321 | if cursor: |
||
322 | cursor.close() |
||
323 | return dict() |
||
324 | |||
325 | if rows_tariffs is None or len(rows_tariffs) == 0: |
||
326 | if cursor: |
||
327 | cursor.close() |
||
328 | if cnx: |
||
329 | cnx.close() |
||
330 | return dict() |
||
331 | |||
332 | for row in rows_tariffs: |
||
333 | tariff_dict[row[0]] = {'valid_from_datetime_utc': row[1], |
||
334 | 'valid_through_datetime_utc': row[2], |
||
335 | 'rates': list()} |
||
336 | |||
337 | try: |
||
338 | query_timeofuse_tariffs = (" SELECT tariff_id, start_time_of_day, end_time_of_day, peak_type " |
||
339 | " FROM tbl_tariffs_timeofuses " |
||
340 | " WHERE tariff_id IN ( " + ', '.join(map(str, tariff_dict.keys())) + ")" |
||
341 | " ORDER BY tariff_id, start_time_of_day ") |
||
342 | cursor.execute(query_timeofuse_tariffs, ) |
||
343 | rows_timeofuse_tariffs = cursor.fetchall() |
||
344 | except Exception as e: |
||
345 | print(str(e)) |
||
346 | if cnx: |
||
347 | cnx.close() |
||
348 | if cursor: |
||
349 | cursor.close() |
||
350 | return dict() |
||
351 | |||
352 | if cursor: |
||
353 | cursor.close() |
||
354 | if cnx: |
||
355 | cnx.close() |
||
356 | |||
357 | if rows_timeofuse_tariffs is None or len(rows_timeofuse_tariffs) == 0: |
||
358 | return dict() |
||
359 | |||
360 | for row in rows_timeofuse_tariffs: |
||
361 | tariff_dict[row[0]]['rates'].append({'start_time_of_day': row[1], |
||
362 | 'end_time_of_day': row[2], |
||
363 | 'peak_type': row[3]}) |
||
364 | |||
365 | result = dict() |
||
366 | for tariff_id, tariff_value in tariff_dict.items(): |
||
367 | current_datetime_utc = tariff_value['valid_from_datetime_utc'] |
||
368 | while current_datetime_utc < tariff_value['valid_through_datetime_utc']: |
||
369 | for rate in tariff_value['rates']: |
||
370 | current_datetime_local = current_datetime_utc + timedelta(minutes=timezone_offset) |
||
371 | seconds_since_midnight = (current_datetime_local - |
||
372 | current_datetime_local.replace(hour=0, |
||
373 | second=0, |
||
374 | microsecond=0, |
||
375 | tzinfo=None)).total_seconds() |
||
376 | if rate['start_time_of_day'].total_seconds() <= \ |
||
377 | seconds_since_midnight < rate['end_time_of_day'].total_seconds(): |
||
378 | result[current_datetime_utc] = rate['peak_type'] |
||
379 | break |
||
380 | |||
381 | # start from the next time slot |
||
382 | current_datetime_utc += timedelta(minutes=config.minutes_to_count) |
||
383 | |||
384 | return {k: v for k, v in result.items() if start_datetime_utc <= k <= end_datetime_utc} |
||
385 | |||
386 | |||
387 | ######################################################################################################################## |
||
388 | # Averaging calculator of hourly data by period |
||
389 | # rows_hourly: list of (start_datetime_utc, actual_value), should belong to one energy_category_id |
||
390 | # start_datetime_utc: start datetime in utc |
||
391 | # end_datetime_utc: end datetime in utc |
||
392 | # period_type: use one of the period types, 'hourly', 'daily', 'weekly', 'monthly' and 'yearly' |
||
393 | # Returns: periodically data of average and maximum |
||
394 | # Note: this procedure doesn't work with multiple energy categories |
||
395 | ######################################################################################################################## |
||
396 | def averaging_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetime_utc, period_type): |
||
397 | # todo: validate parameters |
||
398 | if start_datetime_utc is None or \ |
||
399 | end_datetime_utc is None or \ |
||
400 | start_datetime_utc >= end_datetime_utc or \ |
||
401 | period_type not in ('hourly', 'daily', 'weekly', 'monthly', 'yearly'): |
||
402 | return list(), None, None |
||
403 | |||
404 | start_datetime_utc = start_datetime_utc.replace(tzinfo=None) |
||
405 | end_datetime_utc = end_datetime_utc.replace(tzinfo=None) |
||
406 | |||
407 | if period_type == "hourly": |
||
408 | result_rows_hourly = list() |
||
409 | # todo: add config.working_day_start_time_local |
||
410 | # todo: add config.minutes_to_count |
||
411 | total = Decimal(0.0) |
||
412 | maximum = None |
||
413 | counter = 0 |
||
414 | current_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None) |
||
415 | View Code Duplication | while current_datetime_utc <= end_datetime_utc: |
|
416 | sub_total = Decimal(0.0) |
||
417 | sub_maximum = None |
||
418 | sub_counter = 0 |
||
419 | for row in rows_hourly: |
||
420 | if current_datetime_utc <= row[0] < current_datetime_utc + \ |
||
421 | timedelta(minutes=config.minutes_to_count): |
||
422 | sub_total += row[1] |
||
423 | if sub_maximum is None: |
||
424 | sub_maximum = row[1] |
||
425 | elif sub_maximum < row[1]: |
||
426 | sub_maximum = row[1] |
||
427 | sub_counter += 1 |
||
428 | |||
429 | sub_average = (sub_total / sub_counter) if sub_counter > 0 else None |
||
430 | result_rows_hourly.append((current_datetime_utc, sub_average, sub_maximum)) |
||
431 | |||
432 | total += sub_total |
||
433 | counter += sub_counter |
||
434 | if sub_maximum is None: |
||
435 | pass |
||
436 | elif maximum is None: |
||
437 | maximum = sub_maximum |
||
438 | elif maximum < sub_maximum: |
||
439 | maximum = sub_maximum |
||
440 | |||
441 | current_datetime_utc += timedelta(minutes=config.minutes_to_count) |
||
442 | |||
443 | average = total / counter if counter > 0 else None |
||
444 | return result_rows_hourly, average, maximum |
||
445 | |||
446 | elif period_type == "daily": |
||
447 | result_rows_daily = list() |
||
448 | # todo: add config.working_day_start_time_local |
||
449 | # todo: add config.minutes_to_count |
||
450 | total = Decimal(0.0) |
||
451 | maximum = None |
||
452 | counter = 0 |
||
453 | # calculate the start datetime in utc of the first day in local |
||
454 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
455 | current_datetime_utc = start_datetime_local.replace(hour=0) - timedelta(hours=int(config.utc_offset[1:3])) |
||
456 | View Code Duplication | while current_datetime_utc <= end_datetime_utc: |
|
457 | sub_total = Decimal(0.0) |
||
458 | sub_maximum = None |
||
459 | sub_counter = 0 |
||
460 | for row in rows_hourly: |
||
461 | if current_datetime_utc <= row[0] < current_datetime_utc + timedelta(days=1): |
||
462 | sub_total += row[1] |
||
463 | if sub_maximum is None: |
||
464 | sub_maximum = row[1] |
||
465 | elif sub_maximum < row[1]: |
||
466 | sub_maximum = row[1] |
||
467 | sub_counter += 1 |
||
468 | |||
469 | sub_average = (sub_total / sub_counter) if sub_counter > 0 else None |
||
470 | result_rows_daily.append((current_datetime_utc, sub_average, sub_maximum)) |
||
471 | total += sub_total |
||
472 | counter += sub_counter |
||
473 | if sub_maximum is None: |
||
474 | pass |
||
475 | elif maximum is None: |
||
476 | maximum = sub_maximum |
||
477 | elif maximum < sub_maximum: |
||
478 | maximum = sub_maximum |
||
479 | current_datetime_utc += timedelta(days=1) |
||
480 | |||
481 | average = total / counter if counter > 0 else None |
||
482 | return result_rows_daily, average, maximum |
||
483 | |||
484 | elif period_type == 'weekly': |
||
485 | result_rows_weekly = list() |
||
486 | # todo: add config.working_day_start_time_local |
||
487 | # todo: add config.minutes_to_count |
||
488 | total = Decimal(0.0) |
||
489 | maximum = None |
||
490 | counter = 0 |
||
491 | # calculate the start datetime in utc of the monday in the first week in local |
||
492 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
493 | weekday = start_datetime_local.weekday() |
||
494 | current_datetime_utc = \ |
||
495 | start_datetime_local.replace(hour=0) - timedelta(days=weekday, hours=int(config.utc_offset[1:3])) |
||
496 | View Code Duplication | while current_datetime_utc <= end_datetime_utc: |
|
497 | sub_total = Decimal(0.0) |
||
498 | sub_maximum = None |
||
499 | sub_counter = 0 |
||
500 | for row in rows_hourly: |
||
501 | if current_datetime_utc <= row[0] < current_datetime_utc + timedelta(days=7): |
||
502 | sub_total += row[1] |
||
503 | if sub_maximum is None: |
||
504 | sub_maximum = row[1] |
||
505 | elif sub_maximum < row[1]: |
||
506 | sub_maximum = row[1] |
||
507 | sub_counter += 1 |
||
508 | |||
509 | sub_average = (sub_total / sub_counter) if sub_counter > 0 else None |
||
510 | result_rows_weekly.append((current_datetime_utc, sub_average, sub_maximum)) |
||
511 | total += sub_total |
||
512 | counter += sub_counter |
||
513 | if sub_maximum is None: |
||
514 | pass |
||
515 | elif maximum is None: |
||
516 | maximum = sub_maximum |
||
517 | elif maximum < sub_maximum: |
||
518 | maximum = sub_maximum |
||
519 | current_datetime_utc += timedelta(days=7) |
||
520 | |||
521 | average = total / counter if counter > 0 else None |
||
522 | return result_rows_weekly, average, maximum |
||
523 | |||
524 | elif period_type == "monthly": |
||
525 | result_rows_monthly = list() |
||
526 | # todo: add config.working_day_start_time_local |
||
527 | # todo: add config.minutes_to_count |
||
528 | total = Decimal(0.0) |
||
529 | maximum = None |
||
530 | counter = 0 |
||
531 | # calculate the start datetime in utc of the first day in the first month in local |
||
532 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
533 | current_datetime_utc = \ |
||
534 | start_datetime_local.replace(day=1, hour=0) - timedelta(hours=int(config.utc_offset[1:3])) |
||
535 | |||
536 | while current_datetime_utc <= end_datetime_utc: |
||
537 | # calculate the next datetime in utc |
||
538 | View Code Duplication | if current_datetime_utc.month == 1: |
|
539 | temp_day = 28 |
||
540 | ny = current_datetime_utc.year |
||
541 | if (ny % 100 != 0 and ny % 4 == 0) or (ny % 100 == 0 and ny % 400 == 0): |
||
542 | temp_day = 29 |
||
543 | |||
544 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
545 | month=current_datetime_utc.month + 1, |
||
546 | day=temp_day, |
||
547 | hour=current_datetime_utc.hour, |
||
548 | minute=current_datetime_utc.minute, |
||
549 | second=0, |
||
550 | microsecond=0, |
||
551 | tzinfo=None) |
||
552 | elif current_datetime_utc.month == 2: |
||
553 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
554 | month=current_datetime_utc.month + 1, |
||
555 | day=31, |
||
556 | hour=current_datetime_utc.hour, |
||
557 | minute=current_datetime_utc.minute, |
||
558 | second=0, |
||
559 | microsecond=0, |
||
560 | tzinfo=None) |
||
561 | elif current_datetime_utc.month in [3, 5, 8, 10]: |
||
562 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
563 | month=current_datetime_utc.month + 1, |
||
564 | day=30, |
||
565 | hour=current_datetime_utc.hour, |
||
566 | minute=current_datetime_utc.minute, |
||
567 | second=0, |
||
568 | microsecond=0, |
||
569 | tzinfo=None) |
||
570 | elif current_datetime_utc.month == 7: |
||
571 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
572 | month=current_datetime_utc.month + 1, |
||
573 | day=31, |
||
574 | hour=current_datetime_utc.hour, |
||
575 | minute=current_datetime_utc.minute, |
||
576 | second=0, |
||
577 | microsecond=0, |
||
578 | tzinfo=None) |
||
579 | elif current_datetime_utc.month in [4, 6, 9, 11]: |
||
580 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
581 | month=current_datetime_utc.month + 1, |
||
582 | day=31, |
||
583 | hour=current_datetime_utc.hour, |
||
584 | minute=current_datetime_utc.minute, |
||
585 | second=0, |
||
586 | microsecond=0, |
||
587 | tzinfo=None) |
||
588 | elif current_datetime_utc.month == 12: |
||
589 | next_datetime_utc = datetime(year=current_datetime_utc.year + 1, |
||
590 | month=1, |
||
591 | day=31, |
||
592 | hour=current_datetime_utc.hour, |
||
593 | minute=current_datetime_utc.minute, |
||
594 | second=0, |
||
595 | microsecond=0, |
||
596 | tzinfo=None) |
||
597 | |||
598 | sub_total = Decimal(0.0) |
||
599 | sub_maximum = None |
||
600 | sub_counter = 0 |
||
601 | for row in rows_hourly: |
||
602 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
603 | sub_total += row[1] |
||
604 | if sub_maximum is None: |
||
605 | sub_maximum = row[1] |
||
606 | elif sub_maximum < row[1]: |
||
607 | sub_maximum = row[1] |
||
608 | sub_counter += 1 |
||
609 | |||
610 | sub_average = (sub_total / sub_counter) if sub_counter > 0 else None |
||
611 | result_rows_monthly.append((current_datetime_utc, sub_average, sub_maximum)) |
||
612 | total += sub_total |
||
613 | counter += sub_counter |
||
614 | if sub_maximum is None: |
||
615 | pass |
||
616 | elif maximum is None: |
||
617 | maximum = sub_maximum |
||
618 | elif maximum < sub_maximum: |
||
619 | maximum = sub_maximum |
||
620 | current_datetime_utc = next_datetime_utc |
||
621 | |||
622 | average = total / counter if counter > 0 else None |
||
623 | return result_rows_monthly, average, maximum |
||
624 | |||
625 | elif period_type == "yearly": |
||
626 | result_rows_yearly = list() |
||
627 | # todo: add config.working_day_start_time_local |
||
628 | # todo: add config.minutes_to_count |
||
629 | total = Decimal(0.0) |
||
630 | maximum = None |
||
631 | counter = 0 |
||
632 | # calculate the start datetime in utc of the first day in the first month in local |
||
633 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
634 | current_datetime_utc = start_datetime_local.replace(month=1, day=1, hour=0) - timedelta( |
||
635 | hours=int(config.utc_offset[1:3])) |
||
636 | |||
637 | while current_datetime_utc <= end_datetime_utc: |
||
638 | # calculate the next datetime in utc |
||
639 | # todo: timedelta of year |
||
640 | next_datetime_utc = datetime(year=current_datetime_utc.year + 2, |
||
641 | month=1, |
||
642 | day=1, |
||
643 | hour=current_datetime_utc.hour, |
||
644 | minute=current_datetime_utc.minute, |
||
645 | second=current_datetime_utc.second, |
||
646 | microsecond=current_datetime_utc.microsecond, |
||
647 | tzinfo=current_datetime_utc.tzinfo) - timedelta(days=1) |
||
648 | sub_total = Decimal(0.0) |
||
649 | sub_maximum = None |
||
650 | sub_counter = 0 |
||
651 | for row in rows_hourly: |
||
652 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
653 | sub_total += row[1] |
||
654 | if sub_maximum is None: |
||
655 | sub_maximum = row[1] |
||
656 | elif sub_maximum < row[1]: |
||
657 | sub_maximum = row[1] |
||
658 | sub_counter += 1 |
||
659 | |||
660 | sub_average = (sub_total / sub_counter) if sub_counter > 0 else None |
||
661 | result_rows_yearly.append((current_datetime_utc, sub_average, sub_maximum)) |
||
662 | total += sub_total |
||
663 | counter += sub_counter |
||
664 | if sub_maximum is None: |
||
665 | pass |
||
666 | elif maximum is None: |
||
667 | maximum = sub_maximum |
||
668 | elif maximum < sub_maximum: |
||
669 | maximum = sub_maximum |
||
670 | current_datetime_utc = next_datetime_utc |
||
671 | |||
672 | average = total / counter if counter > 0 else None |
||
673 | return result_rows_yearly, average, maximum |
||
674 | else: |
||
675 | return list(), None, None |
||
676 | |||
677 | |||
678 | ######################################################################################################################## |
||
679 | # Statistics calculator of hourly data by period |
||
680 | # rows_hourly: list of (start_datetime_utc, actual_value), should belong to one energy_category_id |
||
681 | # start_datetime_utc: start datetime in utc |
||
682 | # end_datetime_utc: end datetime in utc |
||
683 | # period_type: use one of the period types, 'hourly', 'daily', 'weekly', 'monthly' and 'yearly' |
||
684 | # Returns: periodically data of values and statistics of mean, median, minimum, maximum, stdev and variance |
||
685 | # Note: this procedure doesn't work with multiple energy categories |
||
686 | ######################################################################################################################## |
||
687 | def statistics_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetime_utc, period_type): |
||
688 | # todo: validate parameters |
||
689 | if start_datetime_utc is None or \ |
||
690 | end_datetime_utc is None or \ |
||
691 | start_datetime_utc >= end_datetime_utc or \ |
||
692 | period_type not in ('hourly', 'daily', 'weekly', 'monthly', 'yearly'): |
||
693 | return list(), None, None, None, None, None, None |
||
694 | |||
695 | start_datetime_utc = start_datetime_utc.replace(tzinfo=None) |
||
696 | end_datetime_utc = end_datetime_utc.replace(tzinfo=None) |
||
697 | |||
698 | if period_type == "hourly": |
||
699 | result_rows_hourly = list() |
||
700 | sample_data = list() |
||
701 | # todo: add config.working_day_start_time_local |
||
702 | # todo: add config.minutes_to_count |
||
703 | counter = 0 |
||
704 | mean = None |
||
705 | median = None |
||
706 | minimum = None |
||
707 | maximum = None |
||
708 | stdev = None |
||
709 | variance = None |
||
710 | current_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None) |
||
711 | View Code Duplication | while current_datetime_utc <= end_datetime_utc: |
|
712 | sub_total = Decimal(0.0) |
||
713 | for row in rows_hourly: |
||
714 | if current_datetime_utc <= row[0] < current_datetime_utc + \ |
||
715 | timedelta(minutes=config.minutes_to_count): |
||
716 | sub_total += row[1] |
||
717 | |||
718 | result_rows_hourly.append((current_datetime_utc, sub_total)) |
||
719 | sample_data.append(sub_total) |
||
720 | |||
721 | counter += 1 |
||
722 | if minimum is None: |
||
723 | minimum = sub_total |
||
724 | elif minimum > sub_total: |
||
725 | minimum = sub_total |
||
726 | |||
727 | if maximum is None: |
||
728 | maximum = sub_total |
||
729 | elif maximum < sub_total: |
||
730 | maximum = sub_total |
||
731 | |||
732 | current_datetime_utc += timedelta(minutes=config.minutes_to_count) |
||
733 | |||
734 | if len(sample_data) > 1: |
||
735 | mean = statistics.mean(sample_data) |
||
736 | median = statistics.median(sample_data) |
||
737 | stdev = statistics.stdev(sample_data) |
||
738 | variance = statistics.variance(sample_data) |
||
739 | |||
740 | return result_rows_hourly, mean, median, minimum, maximum, stdev, variance |
||
741 | |||
742 | elif period_type == "daily": |
||
743 | result_rows_daily = list() |
||
744 | sample_data = list() |
||
745 | # todo: add config.working_day_start_time_local |
||
746 | # todo: add config.minutes_to_count |
||
747 | counter = 0 |
||
748 | mean = None |
||
749 | median = None |
||
750 | minimum = None |
||
751 | maximum = None |
||
752 | stdev = None |
||
753 | variance = None |
||
754 | # calculate the start datetime in utc of the first day in local |
||
755 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
756 | current_datetime_utc = start_datetime_local.replace(hour=0) - timedelta(hours=int(config.utc_offset[1:3])) |
||
757 | View Code Duplication | while current_datetime_utc <= end_datetime_utc: |
|
758 | sub_total = Decimal(0.0) |
||
759 | for row in rows_hourly: |
||
760 | if current_datetime_utc <= row[0] < current_datetime_utc + timedelta(days=1): |
||
761 | sub_total += row[1] |
||
762 | |||
763 | result_rows_daily.append((current_datetime_utc, sub_total)) |
||
764 | sample_data.append(sub_total) |
||
765 | |||
766 | counter += 1 |
||
767 | if minimum is None: |
||
768 | minimum = sub_total |
||
769 | elif minimum > sub_total: |
||
770 | minimum = sub_total |
||
771 | |||
772 | if maximum is None: |
||
773 | maximum = sub_total |
||
774 | elif maximum < sub_total: |
||
775 | maximum = sub_total |
||
776 | current_datetime_utc += timedelta(days=1) |
||
777 | |||
778 | if len(sample_data) > 1: |
||
779 | mean = statistics.mean(sample_data) |
||
780 | median = statistics.median(sample_data) |
||
781 | stdev = statistics.stdev(sample_data) |
||
782 | variance = statistics.variance(sample_data) |
||
783 | |||
784 | return result_rows_daily, mean, median, minimum, maximum, stdev, variance |
||
785 | |||
786 | elif period_type == "weekly": |
||
787 | result_rows_weekly = list() |
||
788 | sample_data = list() |
||
789 | # todo: add config.working_day_start_time_local |
||
790 | # todo: add config.minutes_to_count |
||
791 | counter = 0 |
||
792 | mean = None |
||
793 | median = None |
||
794 | minimum = None |
||
795 | maximum = None |
||
796 | stdev = None |
||
797 | variance = None |
||
798 | # calculate the start datetime in utc of the monday in the first week in local |
||
799 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
800 | weekday = start_datetime_local.weekday() |
||
801 | current_datetime_utc = \ |
||
802 | start_datetime_local.replace(hour=0) - timedelta(days=weekday, hours=int(config.utc_offset[1:3])) |
||
803 | View Code Duplication | while current_datetime_utc <= end_datetime_utc: |
|
804 | sub_total = Decimal(0.0) |
||
805 | for row in rows_hourly: |
||
806 | if current_datetime_utc <= row[0] < current_datetime_utc + timedelta(days=7): |
||
807 | sub_total += row[1] |
||
808 | |||
809 | result_rows_weekly.append((current_datetime_utc, sub_total)) |
||
810 | sample_data.append(sub_total) |
||
811 | |||
812 | counter += 1 |
||
813 | if minimum is None: |
||
814 | minimum = sub_total |
||
815 | elif minimum > sub_total: |
||
816 | minimum = sub_total |
||
817 | |||
818 | if maximum is None: |
||
819 | maximum = sub_total |
||
820 | elif maximum < sub_total: |
||
821 | maximum = sub_total |
||
822 | current_datetime_utc += timedelta(days=7) |
||
823 | |||
824 | if len(sample_data) > 1: |
||
825 | mean = statistics.mean(sample_data) |
||
826 | median = statistics.median(sample_data) |
||
827 | stdev = statistics.stdev(sample_data) |
||
828 | variance = statistics.variance(sample_data) |
||
829 | |||
830 | return result_rows_weekly, mean, median, minimum, maximum, stdev, variance |
||
831 | |||
832 | elif period_type == "monthly": |
||
833 | result_rows_monthly = list() |
||
834 | sample_data = list() |
||
835 | # todo: add config.working_day_start_time_local |
||
836 | # todo: add config.minutes_to_count |
||
837 | counter = 0 |
||
838 | mean = None |
||
839 | median = None |
||
840 | minimum = None |
||
841 | maximum = None |
||
842 | stdev = None |
||
843 | variance = None |
||
844 | # calculate the start datetime in utc of the first day in the first month in local |
||
845 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
846 | current_datetime_utc = \ |
||
847 | start_datetime_local.replace(day=1, hour=0) - timedelta(hours=int(config.utc_offset[1:3])) |
||
848 | |||
849 | while current_datetime_utc <= end_datetime_utc: |
||
850 | # calculate the next datetime in utc |
||
851 | View Code Duplication | if current_datetime_utc.month == 1: |
|
852 | temp_day = 28 |
||
853 | ny = current_datetime_utc.year |
||
854 | if (ny % 100 != 0 and ny % 4 == 0) or (ny % 100 == 0 and ny % 400 == 0): |
||
855 | temp_day = 29 |
||
856 | |||
857 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
858 | month=current_datetime_utc.month + 1, |
||
859 | day=temp_day, |
||
860 | hour=current_datetime_utc.hour, |
||
861 | minute=current_datetime_utc.minute, |
||
862 | second=0, |
||
863 | microsecond=0, |
||
864 | tzinfo=None) |
||
865 | elif current_datetime_utc.month == 2: |
||
866 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
867 | month=current_datetime_utc.month + 1, |
||
868 | day=31, |
||
869 | hour=current_datetime_utc.hour, |
||
870 | minute=current_datetime_utc.minute, |
||
871 | second=0, |
||
872 | microsecond=0, |
||
873 | tzinfo=None) |
||
874 | elif current_datetime_utc.month in [3, 5, 8, 10]: |
||
875 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
876 | month=current_datetime_utc.month + 1, |
||
877 | day=30, |
||
878 | hour=current_datetime_utc.hour, |
||
879 | minute=current_datetime_utc.minute, |
||
880 | second=0, |
||
881 | microsecond=0, |
||
882 | tzinfo=None) |
||
883 | elif current_datetime_utc.month == 7: |
||
884 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
885 | month=current_datetime_utc.month + 1, |
||
886 | day=31, |
||
887 | hour=current_datetime_utc.hour, |
||
888 | minute=current_datetime_utc.minute, |
||
889 | second=0, |
||
890 | microsecond=0, |
||
891 | tzinfo=None) |
||
892 | elif current_datetime_utc.month in [4, 6, 9, 11]: |
||
893 | next_datetime_utc = datetime(year=current_datetime_utc.year, |
||
894 | month=current_datetime_utc.month + 1, |
||
895 | day=31, |
||
896 | hour=current_datetime_utc.hour, |
||
897 | minute=current_datetime_utc.minute, |
||
898 | second=0, |
||
899 | microsecond=0, |
||
900 | tzinfo=None) |
||
901 | elif current_datetime_utc.month == 12: |
||
902 | next_datetime_utc = datetime(year=current_datetime_utc.year + 1, |
||
903 | month=1, |
||
904 | day=31, |
||
905 | hour=current_datetime_utc.hour, |
||
906 | minute=current_datetime_utc.minute, |
||
907 | second=0, |
||
908 | microsecond=0, |
||
909 | tzinfo=None) |
||
910 | |||
911 | sub_total = Decimal(0.0) |
||
912 | for row in rows_hourly: |
||
913 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
914 | sub_total += row[1] |
||
915 | |||
916 | result_rows_monthly.append((current_datetime_utc, sub_total)) |
||
917 | sample_data.append(sub_total) |
||
918 | |||
919 | counter += 1 |
||
920 | if minimum is None: |
||
921 | minimum = sub_total |
||
922 | elif minimum > sub_total: |
||
923 | minimum = sub_total |
||
924 | |||
925 | if maximum is None: |
||
926 | maximum = sub_total |
||
927 | elif maximum < sub_total: |
||
928 | maximum = sub_total |
||
929 | current_datetime_utc = next_datetime_utc |
||
930 | |||
931 | if len(sample_data) > 1: |
||
932 | mean = statistics.mean(sample_data) |
||
933 | median = statistics.median(sample_data) |
||
934 | stdev = statistics.stdev(sample_data) |
||
935 | variance = statistics.variance(sample_data) |
||
936 | |||
937 | return result_rows_monthly, mean, median, minimum, maximum, stdev, variance |
||
938 | |||
939 | elif period_type == "yearly": |
||
940 | result_rows_yearly = list() |
||
941 | sample_data = list() |
||
942 | # todo: add config.working_day_start_time_local |
||
943 | # todo: add config.minutes_to_count |
||
944 | mean = None |
||
945 | median = None |
||
946 | minimum = None |
||
947 | maximum = None |
||
948 | stdev = None |
||
949 | variance = None |
||
950 | # calculate the start datetime in utc of the first day in the first month in local |
||
951 | start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3])) |
||
952 | current_datetime_utc = start_datetime_local.replace(month=1, day=1, hour=0) - timedelta( |
||
953 | hours=int(config.utc_offset[1:3])) |
||
954 | |||
955 | while current_datetime_utc <= end_datetime_utc: |
||
956 | # calculate the next datetime in utc |
||
957 | # todo: timedelta of year |
||
958 | next_datetime_utc = datetime(year=current_datetime_utc.year + 2, |
||
959 | month=1, |
||
960 | day=1, |
||
961 | hour=current_datetime_utc.hour, |
||
962 | minute=current_datetime_utc.minute, |
||
963 | second=current_datetime_utc.second, |
||
964 | microsecond=current_datetime_utc.microsecond, |
||
965 | tzinfo=current_datetime_utc.tzinfo) - timedelta(days=1) |
||
966 | sub_total = Decimal(0.0) |
||
967 | for row in rows_hourly: |
||
968 | if current_datetime_utc <= row[0] < next_datetime_utc: |
||
969 | sub_total += row[1] |
||
970 | |||
971 | result_rows_yearly.append((current_datetime_utc, sub_total)) |
||
972 | sample_data.append(sub_total) |
||
973 | |||
974 | if minimum is None: |
||
975 | minimum = sub_total |
||
976 | elif minimum > sub_total: |
||
977 | minimum = sub_total |
||
978 | if maximum is None: |
||
979 | maximum = sub_total |
||
980 | elif maximum < sub_total: |
||
981 | maximum = sub_total |
||
982 | |||
983 | current_datetime_utc = next_datetime_utc |
||
984 | |||
985 | if len(sample_data) > 1: |
||
986 | mean = statistics.mean(sample_data) |
||
987 | median = statistics.median(sample_data) |
||
988 | stdev = statistics.stdev(sample_data) |
||
989 | variance = statistics.variance(sample_data) |
||
990 | |||
991 | return result_rows_yearly, mean, median, minimum, maximum, stdev, variance |
||
992 | |||
993 | else: |
||
994 | return list(), None, None, None, None, None, None |
||
995 | |||
996 | |||
997 | def get_translation(language): |
||
998 | if language is None or not isinstance(language, str) or len(language) == 0: |
||
999 | return gettext.translation('myems', './i18n/', languages=['en']) |
||
1000 | |||
1001 | if language not in ['zh_CN', 'en', 'de', 'fr', 'es', 'ru', 'ar', 'vi', 'th', 'tr', 'ms', 'id', 'zh_TW', 'pt']: |
||
1002 | return gettext.translation('myems', './i18n/', languages=['en']) |
||
1003 | else: |
||
1004 | language_list = [language] |
||
1005 | return gettext.translation('myems', './i18n/', languages=language_list) |
||
1006 | |||
1007 | |||
1008 | def int16_to_hhmm(actual_value): |
||
1009 | """Convert int16 to time in HH:mm""" |
||
1010 | hh = int(actual_value / 256) |
||
1011 | if hh < 10: |
||
1012 | hh = '0' + str(hh) |
||
1013 | elif hh < 24: |
||
1014 | hh = str(hh) |
||
1015 | else: |
||
1016 | return None |
||
1017 | mm = actual_value % 256 |
||
1018 | if mm < 10: |
||
1019 | mm = '0' + str(mm) |
||
1020 | elif mm < 60: |
||
1021 | mm = str(mm) |
||
1022 | else: |
||
1023 | return None |
||
1024 | return hh + ':' + mm |
||
1025 | |||
1026 | |||
1027 | def round2(actual_value, precision): |
||
1028 | if actual_value is not None: |
||
1029 | try: |
||
1030 | result = round(actual_value, precision) |
||
1031 | except (TypeError, NameError, SyntaxError): |
||
1032 | return "-" |
||
1033 | return result |
||
1034 | else: |
||
1035 | return "-" |
||
1036 |