From 4bd5b175f4f4274c8020de766e3161f508df281e Mon Sep 17 00:00:00 2001 From: "13621160019@163.com" <13621160019@163.com> Date: Wed, 31 Mar 2021 14:58:24 +0800 Subject: [PATCH] added associated equipment data to combinedequipmentsaving report in API --- .../excelexporters/combinedequipmentsaving.py | 61 +++++++- myems-api/reports/combinedequipmentsaving.py | 130 ++++++++++++++++-- 2 files changed, 176 insertions(+), 15 deletions(-) diff --git a/myems-api/excelexporters/combinedequipmentsaving.py b/myems-api/excelexporters/combinedequipmentsaving.py index abfcdf5f..64de6521 100644 --- a/myems-api/excelexporters/combinedequipmentsaving.py +++ b/myems-api/excelexporters/combinedequipmentsaving.py @@ -1,6 +1,8 @@ import base64 import uuid import os +from decimal import Decimal + from openpyxl.chart import ( PieChart, LineChart, @@ -557,6 +559,63 @@ def generate_excel(report, chart_start_row_number += 6 ws.add_chart(line, chart_cell) + ##################################### + + has_associated_equipment_flag = True + + if "associated_equipment" not in report.keys() or \ + "energy_category_names" not in report['associated_equipment'].keys() or \ + len(report['associated_equipment']["energy_category_names"]) == 0 \ + or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \ + or report['associated_equipment']['associated_equipment_names_array'] is None \ + or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \ + or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0: + has_associated_equipment_flag = False + + if has_associated_equipment_flag: + associated_equipment = report['associated_equipment'] + + ws['B' + str(current_row_number)].font = title_font + ws['B' + str(current_row_number)] = name + ' 相关设备数据' + + current_row_number += 1 + table_start_row_number = current_row_number + + ws.row_dimensions[current_row_number].height = 60 + ws['B' + str(current_row_number)].fill = table_fill + ws['B' + str(current_row_number)].font = name_font + ws['B' + str(current_row_number)].alignment = c_c_alignment + ws['B' + str(current_row_number)].border = f_border + ws['B' + str(current_row_number)] = '相关设备' + ca_len = len(associated_equipment['energy_category_names']) + + for i in range(0, ca_len): + row = chr(ord('C') + i) + ws[row + str(current_row_number)].fill = table_fill + ws[row + str(current_row_number)].font = name_font + ws[row + str(current_row_number)].alignment = c_c_alignment + ws[row + str(current_row_number)].border = f_border + ws[row + str(current_row_number)] = \ + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")" + + associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0]) + + for i in range(0, associated_equipment_len): + current_row_number += 1 + row = str(current_row_number) + + ws['B' + row].font = title_font + ws['B' + row].alignment = c_c_alignment + ws['B' + row] = associated_equipment['associated_equipment_names_array'][0][i] + ws['B' + row].border = f_border + + for j in range(0, ca_len): + col = chr(ord('C') + j) + ws[col + row].font = title_font + ws[col + row].alignment = c_c_alignment + ws[col + row] = round(associated_equipment['subtotals_saving_array'][j][i], 2) + ws[col + row].border = f_border + filename = str(uuid.uuid4()) + '.xlsx' wb.save(filename) @@ -564,7 +623,7 @@ def generate_excel(report, def sum_list(lists): - total = 0 + total = Decimal(0.0) for i in range(0, len(lists)): total += lists[i] diff --git a/myems-api/reports/combinedequipmentsaving.py b/myems-api/reports/combinedequipmentsaving.py index b55dbcbc..5ccfe447 100644 --- a/myems-api/reports/combinedequipmentsaving.py +++ b/myems-api/reports/combinedequipmentsaving.py @@ -23,11 +23,13 @@ class Reporting: # Step 2: query the combined equipment # Step 3: query energy categories # Step 4: query associated points - # Step 5: query base period energy saving - # Step 6: query reporting period energy saving - # Step 7: query tariff data - # Step 8: query associated points data - # Step 10: construct the report + # Step 5: query associated equipments + # Step 6: query base period energy saving + # Step 7: query reporting period energy saving + # Step 8: query tariff data + # Step 9: query associated points data + # Step 10: query associated equipments energy saving + # Step 11: construct the report #################################################################################################################### @staticmethod def on_get(req, resp): @@ -70,7 +72,7 @@ class Reporting: try: base_start_datetime_utc = datetime.strptime(base_start_datetime_local, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \ - timedelta(minutes=timezone_offset) + timedelta(minutes=timezone_offset) except ValueError: raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description="API.INVALID_BASE_PERIOD_START_DATETIME") @@ -81,7 +83,7 @@ class Reporting: try: base_end_datetime_utc = datetime.strptime(base_end_datetime_local, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \ - timedelta(minutes=timezone_offset) + timedelta(minutes=timezone_offset) except ValueError: raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description="API.INVALID_BASE_PERIOD_END_DATETIME") @@ -99,7 +101,7 @@ class Reporting: try: reporting_start_datetime_utc = datetime.strptime(reporting_start_datetime_local, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \ - timedelta(minutes=timezone_offset) + timedelta(minutes=timezone_offset) except ValueError: raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description="API.INVALID_REPORTING_PERIOD_START_DATETIME") @@ -112,7 +114,7 @@ class Reporting: try: reporting_end_datetime_utc = datetime.strptime(reporting_end_datetime_local, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \ - timedelta(minutes=timezone_offset) + timedelta(minutes=timezone_offset) except ValueError: raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description="API.INVALID_REPORTING_PERIOD_END_DATETIME") @@ -248,7 +250,20 @@ class Reporting: point_list.append({"id": row[0], "name": row[1], "units": row[2], "object_type": row[3]}) ################################################################################################################ - # Step 5: query base period energy saving + # Step 5: query associated equipments + ################################################################################################################ + associated_equipment_list = list() + cursor_system.execute(" SELECT e.id, e.name " + " FROM tbl_equipments e,tbl_combined_equipments_equipments ee" + " WHERE ee.combined_equipment_id = %s AND e.id = ee.equipment_id" + " ORDER BY id ", (combined_equipment['id'],)) + rows_associated_equipments = cursor_system.fetchall() + if rows_associated_equipments is not None and len(rows_associated_equipments) > 0: + for row in rows_associated_equipments: + associated_equipment_list.append({"id": row[0], "name": row[1]}) + + ################################################################################################################ + # Step 6: query base period energy saving ################################################################################################################ base = dict() if energy_category_set is not None and len(energy_category_set) > 0: @@ -363,7 +378,7 @@ class Reporting: base[energy_category_id]['subtotal_in_kgco2e_baseline'] - \ base[energy_category_id]['subtotal_in_kgco2e_actual'] ################################################################################################################ - # Step 5: query reporting period energy saving + # Step 7: query reporting period energy saving ################################################################################################################ reporting = dict() if energy_category_set is not None and len(energy_category_set) > 0: @@ -478,7 +493,7 @@ class Reporting: reporting[energy_category_id]['subtotal_in_kgco2e_baseline'] - \ reporting[energy_category_id]['subtotal_in_kgco2e_actual'] ################################################################################################################ - # Step 6: query tariff data + # Step 8: query tariff data ################################################################################################################ parameters_data = dict() parameters_data['names'] = list() @@ -504,7 +519,7 @@ class Reporting: parameters_data['values'].append(tariff_value_list) ################################################################################################################ - # Step 7: query associated points data + # Step 9: query associated points data ################################################################################################################ for point in point_list: point_values = [] @@ -569,7 +584,78 @@ class Reporting: parameters_data['values'].append(point_values) ################################################################################################################ - # Step 8: construct the report + # Step 10: query associated equipments energy saving + ################################################################################################################ + associated_equipment_data = dict() + + if energy_category_set is not None and len(energy_category_set) > 0: + for energy_category_id in energy_category_set: + associated_equipment_data[energy_category_id] = dict() + associated_equipment_data[energy_category_id]['associated_equipment_names'] = list() + associated_equipment_data[energy_category_id]['subtotal_saving'] = list() + + for associated_equipment in associated_equipment_list: + subtotal_baseline = Decimal(0.0) + subtotal_actual = Decimal(0.0) + associated_equipment_data[energy_category_id]['associated_equipment_names'].append( + associated_equipment['name']) + + cursor_energy_baseline.execute(" SELECT start_datetime_utc, actual_value " + " FROM tbl_equipment_input_category_hourly " + " WHERE equipment_id = %s " + " AND energy_category_id = %s " + " AND start_datetime_utc >= %s " + " AND start_datetime_utc < %s " + " ORDER BY start_datetime_utc ", + (associated_equipment['id'], + energy_category_id, + reporting_start_datetime_utc, + reporting_end_datetime_utc)) + rows_associated_equipment_hourly = cursor_energy_baseline.fetchall() + + rows_associated_equipment_periodically = \ + utilities.aggregate_hourly_data_by_period(rows_associated_equipment_hourly, + reporting_start_datetime_utc, + reporting_end_datetime_utc, + period_type) + + for row_associated_equipment_periodically in rows_associated_equipment_periodically: + + baseline_value = Decimal(0.0) if row_associated_equipment_periodically[1] is None \ + else row_associated_equipment_periodically[1] + subtotal_baseline += baseline_value + + # query reporting period's energy actual + cursor_energy.execute(" SELECT start_datetime_utc, actual_value " + " FROM tbl_equipment_input_category_hourly " + " WHERE equipment_id = %s " + " AND energy_category_id = %s " + " AND start_datetime_utc >= %s " + " AND start_datetime_utc < %s " + " ORDER BY start_datetime_utc ", + (associated_equipment['id'], + energy_category_id, + reporting_start_datetime_utc, + reporting_end_datetime_utc)) + rows_associated_equipment_hourly = cursor_energy.fetchall() + + rows_associated_equipment_periodically = \ + utilities.aggregate_hourly_data_by_period(rows_associated_equipment_hourly, + reporting_start_datetime_utc, + reporting_end_datetime_utc, + period_type) + + for row_associated_equipment_periodically in rows_associated_equipment_periodically: + + actual_value = Decimal(0.0) if row_associated_equipment_periodically[1] is None \ + else row_associated_equipment_periodically[1] + subtotal_actual += actual_value + + associated_equipment_data[energy_category_id]['subtotal_saving'].append( + subtotal_baseline - subtotal_actual) + + ################################################################################################################ + # Step 11: construct the report ################################################################################################################ if cursor_system: cursor_system.close() @@ -672,6 +758,22 @@ class Reporting: "values": parameters_data['values'] } + result['associated_equipment'] = dict() + result['associated_equipment']['energy_category_names'] = list() + result['associated_equipment']['units'] = list() + result['associated_equipment']['associated_equipment_names_array'] = list() + result['associated_equipment']['subtotals_saving_array'] = list() + if energy_category_set is not None and len(energy_category_set) > 0: + for energy_category_id in energy_category_set: + result['associated_equipment']['energy_category_names'].append( + energy_category_dict[energy_category_id]['name']) + result['associated_equipment']['units'].append( + energy_category_dict[energy_category_id]['unit_of_measure']) + result['associated_equipment']['associated_equipment_names_array'].append( + associated_equipment_data[energy_category_id]['associated_equipment_names']) + result['associated_equipment']['subtotals_saving_array'].append( + associated_equipment_data[energy_category_id]['subtotal_saving']) + # export result to Excel file and then encode the file to base64 string result['excel_bytes_base64'] = excelexporters.combinedequipmentsaving.export(result, combined_equipment['name'],