From faa3d4f9be84b0c84f73bf07fca6f88ab96dd579 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 25 Jan 2024 14:02:53 -0500 Subject: [PATCH 1/3] cache worksheets --- PHX/xl/xl_app.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/PHX/xl/xl_app.py b/PHX/xl/xl_app.py index ebef306..8c5a3de 100644 --- a/PHX/xl/xl_app.py +++ b/PHX/xl/xl_app.py @@ -116,8 +116,12 @@ def __init__( self._output: Callable[[str], Any] = output self.xl_file_path: Optional[pathlib.Path] = xl_file_path + # A dict with sheet names as keys, and XL data as values + self.sheet_cache: Dict[str, xl_Sheet_Protocol] = {} + self._wb: Optional[xl_Book_Protocol] = None self.output(f"> connected to excel doc: '{self.wb.fullname}'") + self.worksheet_names: Set[str] = self.get_worksheet_names() def activate_new_workbook(self) -> xl_Book_Protocol: """Create a new blank workbook and set as the 'Active' book. Returns the new book.""" @@ -297,11 +301,15 @@ def get_sheet_by_name(self, _sheet_name: Union[str, int]) -> xl_Sheet_Protocol: -------- * (xw.main.Sheet): The excel sheet found. """ - if str(_sheet_name).upper() not in self.get_worksheet_names(): + if str(_sheet_name).upper() not in self.worksheet_names: msg = f"Error: Key '{_sheet_name}' was not found in the Workbook '{self.wb.name}' Sheets?" raise KeyError(msg) - return self.wb.sheets[_sheet_name] + # if the sheet dict doesn't exist, create it in the cache + if _sheet_name not in self.sheet_cache: + self.sheet_cache[_sheet_name] = self.wb.sheets[_sheet_name] + + return self.sheet_cache[_sheet_name] def get_last_sheet(self) -> xl_Sheet_Protocol: """Return the last Worksheet in the Workbook. From 1536e2d852671fce5153daf57d7235b344fc8006 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 25 Jan 2024 14:16:23 -0500 Subject: [PATCH 2/3] allow for slightly easier testing --- _testing_HBJSON_to_PHPP.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/_testing_HBJSON_to_PHPP.py b/_testing_HBJSON_to_PHPP.py index f0261e4..91a8426 100644 --- a/_testing_HBJSON_to_PHPP.py +++ b/_testing_HBJSON_to_PHPP.py @@ -12,11 +12,17 @@ from PHX.PHPP import phpp_app from PHX.xl import xl_app -# --- Input file Path +sys.argv = sys.argv[1:] +# --- Input file Path; optionally provided as first argument # ------------------------------------------------------------------------- -SOURCE_FILE = pathlib.Path( - "/Users/em/Dropbox/bldgtyp-00/00_PH_Tools/PHX/sample/hbjson/LEVINE_240106.hbjson" -) +if len(sys.argv) < 1: + SOURCE_FILE = pathlib.Path( + "/Users/em/Dropbox/bldgtyp-00/00_PH_Tools/PHX/sample/hbjson/LEVINE_240106.hbjson" + ).resolve() +else: + SOURCE_FILE = pathlib.Path(str(sys.argv[0])).resolve() + + if __name__ == "__main__": # --- Read in an existing HB_JSON and re-build the HB Objects From b1d1fc1cf2ab1753b5a09c4d273c4a415440a53c Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 25 Jan 2024 14:15:51 -0500 Subject: [PATCH 3/3] async/await everything --- PHX/PHPP/phpp_app.py | 144 +++++++++++++++------------ PHX/PHPP/sheet_io/io_addnl_vent.py | 16 +-- PHX/PHPP/sheet_io/io_areas.py | 28 +++--- PHX/PHPP/sheet_io/io_climate.py | 10 +- PHX/PHPP/sheet_io/io_components.py | 26 ++--- PHX/PHPP/sheet_io/io_elec_non_res.py | 4 +- PHX/PHPP/sheet_io/io_electricity.py | 10 +- PHX/PHPP/sheet_io/io_hot_water.py | 12 +-- PHX/PHPP/sheet_io/io_shading.py | 4 +- PHX/PHPP/sheet_io/io_u_values.py | 36 ++++--- PHX/PHPP/sheet_io/io_variants.py | 12 ++- PHX/PHPP/sheet_io/io_ventilation.py | 28 +++--- PHX/PHPP/sheet_io/io_verification.py | 6 +- PHX/PHPP/sheet_io/io_windows.py | 26 ++--- PHX/hbjson_to_phpp.py | 62 ++++++------ PHX/xl/xl_app.py | 4 +- _testing_HBJSON_to_PHPP.py | 66 ++++++------ 17 files changed, 270 insertions(+), 224 deletions(-) diff --git a/PHX/PHPP/phpp_app.py b/PHX/PHPP/phpp_app.py index c5abcc4..d6cb826 100644 --- a/PHX/PHPP/phpp_app.py +++ b/PHX/PHPP/phpp_app.py @@ -177,7 +177,7 @@ def phpp_version_equals_phx_phi_cert_version( return False return True - def write_certification_config(self, phx_project: project.PhxProject) -> None: + async def write_certification_config(self, phx_project: project.PhxProject) -> None: for phx_variant in phx_project.variants: # TODO: how to handle multiple variants? @@ -193,28 +193,28 @@ def write_certification_config(self, phx_project: project.PhxProject) -> None: return # --- Building Type / Use - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_building_category_type", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_building_category_type, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_building_use_type", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_building_use_type, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_building_ihg_type", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_building_ihg_type, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_building_occupancy_type", @@ -223,35 +223,35 @@ def write_certification_config(self, phx_project: project.PhxProject) -> None: ) # --- Certification Config - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_certification_type", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_certification_type, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_certification_class", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_certification_class, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_pe_type", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_pe_type, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_enerphit_type", input_enum_value=phx_variant.phi_cert.phi_certification_settings.phi_enerphit_type, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.enum( shape=self.shape.VERIFICATION, input_type="phi_retrofit_type", @@ -262,14 +262,14 @@ def write_certification_config(self, phx_project: project.PhxProject) -> None: # ---- Model Parameters if not phx_variant.phius_cert.ph_building_data: continue - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.item( shape=self.shape.VERIFICATION, input_type="num_of_units", input_data=phx_variant.phius_cert.ph_building_data.num_of_units, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.item( shape=self.shape.VERIFICATION, input_type="setpoint_winter", @@ -278,7 +278,7 @@ def write_certification_config(self, phx_project: project.PhxProject) -> None: target_unit=self.shape.VERIFICATION.setpoint_winter.unit, ) ) - self.verification.write_item( + await self.verification.write_item( verification_data.VerificationInput.item( shape=self.shape.VERIFICATION, input_type="setpoint_summer", @@ -290,7 +290,7 @@ def write_certification_config(self, phx_project: project.PhxProject) -> None: return None - def write_climate_data(self, phx_project: project.PhxProject) -> None: + async def write_climate_data(self, phx_project: project.PhxProject) -> None: """Write the variant's weather-station data to the PHPP 'Climate' worksheet.""" for phx_variant in phx_project.variants: @@ -298,16 +298,18 @@ def write_climate_data(self, phx_project: project.PhxProject) -> None: weather_station_data = climate_entry.ClimateDataBlock( shape=self.shape.CLIMATE, phx_site=phx_variant.site ) - self.climate.write_climate_block(weather_station_data) + await self.climate.write_climate_block(weather_station_data) # -- Set the active weather station active_climate_data = climate_entry.ClimateSettings( shape=self.shape.CLIMATE, phx_site=phx_variant.site ) - self.climate.write_active_climate(active_climate_data) + await self.climate.write_active_climate(active_climate_data) return None - def write_project_constructions(self, phx_project: project.PhxProject) -> None: + async def write_project_constructions( + self, phx_project: project.PhxProject + ) -> None: """Write all of the opaque constructions to the PHPP 'U-Values' worksheet.""" construction_blocks: List[uvalues_constructor.ConstructorBlock] = [] @@ -318,10 +320,12 @@ def write_project_constructions(self, phx_project: project.PhxProject) -> None: ) ) - self.u_values.write_constructor_blocks(construction_blocks) + await self.u_values.write_constructor_blocks(construction_blocks) return None - def write_project_window_components(self, phx_project: project.PhxProject) -> None: + async def write_project_window_components( + self, phx_project: project.PhxProject + ) -> None: """Write all of the frame and glass constructions from a PhxProject to the PHPP 'Components' worksheet.""" glazing_component_rows: List[component_glazing.GlazingRow] = [] @@ -337,11 +341,11 @@ def write_project_window_components(self, phx_project: project.PhxProject) -> No shape=self.shape.COMPONENTS, phx_construction=phx_construction ) ) - self.components.write_glazings(glazing_component_rows) - self.components.write_frames(frame_component_rows) + await self.components.write_glazings(glazing_component_rows) + await self.components.write_frames(frame_component_rows) return None - def write_project_ventilation_components( + async def write_project_ventilation_components( self, phx_project: project.PhxProject ) -> None: """Write all of the ventilators from a PhxProject to the PHPP 'Components' worksheet.""" @@ -355,12 +359,12 @@ def write_project_ventilation_components( phx_vent_sys=phx_ventilator, ) phpp_ventilator_rows.append(new_vent_row) - self.components.write_ventilators(phpp_ventilator_rows) + await self.components.write_ventilators(phpp_ventilator_rows) return None - def write_project_tfa(self, phx_project: project.PhxProject) -> None: + async def write_project_tfa(self, phx_project: project.PhxProject) -> None: for phx_variant in phx_project.variants: - self.areas.write_item( + await self.areas.write_item( areas_data.AreasInput( shape=self.shape.AREAS, input_type="tfa_input", @@ -371,7 +375,9 @@ def write_project_tfa(self, phx_project: project.PhxProject) -> None: ) return None - def write_project_opaque_surfaces(self, phx_project: project.PhxProject) -> None: + async def write_project_opaque_surfaces( + self, phx_project: project.PhxProject + ) -> None: """Write all of the opaque surfaces from a PhxProject to the PHPP 'Areas' worksheet.""" surfaces: List[areas_surface.SurfaceRow] = [] @@ -396,10 +402,12 @@ def write_project_opaque_surfaces(self, phx_project: project.PhxProject) -> None "By default the PHPP can only have 100 surfaces input." ) - self.areas.write_surfaces(surfaces) + await self.areas.write_surfaces(surfaces) return None - def write_project_thermal_bridges(self, phx_project: project.PhxProject) -> None: + async def write_project_thermal_bridges( + self, phx_project: project.PhxProject + ) -> None: """Write all of the thermal-bridge elements of a PhxProject to the PHPP 'Areas' worksheet.""" thermal_bridges: List[areas_thermal_bridges.ThermalBridgeRow] = [] @@ -417,10 +425,12 @@ def write_project_thermal_bridges(self, phx_project: project.PhxProject) -> None "By default the PHPP can only have 100 thermal bridges input." ) - self.areas.write_thermal_bridges(thermal_bridges) + await self.areas.write_thermal_bridges(thermal_bridges) return None - def write_project_window_surfaces(self, phx_project: project.PhxProject) -> None: + async def write_project_window_surfaces( + self, phx_project: project.PhxProject + ) -> None: """Write all of the window surfaces from a PhxProject to the PHPP 'Windows' worksheet.""" # -- First, populate the Variant types @@ -431,7 +441,7 @@ def write_project_window_surfaces(self, phx_project: project.PhxProject) -> None for phx_aperture in phx_component.apertures ] for i, variant_type_name in enumerate(sorted(variant_type_names)): - self.variants.write_window_type(variant_type_name, i) + await self.variants.write_window_type(variant_type_name, i) # -- Get the variant types in a dict window_type_phpp_ids = self.variants.get_window_type_phpp_ids() @@ -482,10 +492,12 @@ def write_project_window_surfaces(self, phx_project: project.PhxProject) -> None "By default the PHPP can only have 150 windows input." ) - self.windows.write_windows(phpp_windows) + await self.windows.write_windows(phpp_windows) return None - def write_project_window_shading(self, phx_project: project.PhxProject) -> None: + async def write_project_window_shading( + self, phx_project: project.PhxProject + ) -> None: def _get_ap_element_from_dict( _window_name: str, _dict: Dict[str, components.PhxApertureElement] ) -> components.PhxApertureElement: @@ -538,13 +550,13 @@ def _get_ap_element_from_dict( phx_aperture_element.summer_shading_factor, ) ) - self.shading.write_shading(phpp_shading_rows) + await self.shading.write_shading(phpp_shading_rows) # TODO: option to clear all the dimensional info? return None - def write_project_ventilators(self, phx_project: project.PhxProject) -> None: + async def write_project_ventilators(self, phx_project: project.PhxProject) -> None: """Write all of the used Ventilator Units from a PhxProject to the PHPP 'Additional Vent' worksheet.""" phpp_vent_unit_rows: List[vent_units.VentUnitRow] = [] @@ -563,10 +575,10 @@ def write_project_ventilators(self, phx_project: project.PhxProject) -> None: ) phpp_vent_unit_rows.append(new_vent_row) - self.addnl_vent.write_vent_units(phpp_vent_unit_rows) + await self.addnl_vent.write_vent_units(phpp_vent_unit_rows) return None - def write_project_spaces(self, phx_project: project.PhxProject) -> None: + async def write_project_spaces(self, phx_project: project.PhxProject) -> None: """Write all of the PH-Spaces from a PhxProject to the PHPP 'Additional Vent' worksheet.""" phpp_vent_rooms: List[vent_space.VentSpaceRow] = [] @@ -609,28 +621,30 @@ def write_project_spaces(self, phx_project: project.PhxProject) -> None: "By default the PHPP can only have 30 spaces input." ) - self.addnl_vent.write_spaces(phpp_vent_rooms) + await self.addnl_vent.write_spaces(phpp_vent_rooms) return None - def write_project_ventilation_type(self, phx_project: project.PhxProject) -> None: + async def write_project_ventilation_type( + self, phx_project: project.PhxProject + ) -> None: """Set the Ventilation-Type to the PHPP 'Ventilation' worksheet.""" for variant in phx_project.variants: - self.ventilation.write_ventilation_type( + await self.ventilation.write_ventilation_type( # TODO: Get the actual type from the model someplace? # TODO: How to combine Variants? ventilation_data.VentilationInputItem.vent_type( self.shape.VENTILATION, "1-Balanced PH ventilation with HR" ) ) - self.ventilation.write_multi_vent_worksheet_on( + await self.ventilation.write_multi_vent_worksheet_on( ventilation_data.VentilationInputItem.multi_unit_on( self.shape.VENTILATION, "x" ) ) return None - def write_project_volume(self, phx_project: project.PhxProject) -> None: + async def write_project_volume(self, phx_project: project.PhxProject) -> None: """Write the Vn50 and Vv to the PHPP 'Ventilation Worksheet.""" for variant in phx_project.variants: # TODO: How to handle multiple variants? @@ -639,13 +653,13 @@ def write_project_volume(self, phx_project: project.PhxProject) -> None: continue bldg: building.PhxBuilding = variant.building - self.ventilation.write_Vn50_volume( + await self.ventilation.write_Vn50_volume( ventilation_data.VentilationInputItem.airtightness_Vn50( self.shape.VENTILATION, bldg.net_volume ) ) - def write_project_airtightness(self, phx_project: project.PhxProject) -> None: + async def write_project_airtightness(self, phx_project: project.PhxProject) -> None: """Write the Airtightness data to the PHPP 'Ventilation' worksheet.""" for variant in phx_project.variants: @@ -656,28 +670,28 @@ def write_project_airtightness(self, phx_project: project.PhxProject) -> None: ph_bldg: certification.PhxPhBuildingData = variant.phius_cert.ph_building_data # TODO: Get the actual values from the Model somehow - self.ventilation.write_wind_coeff_e( + await self.ventilation.write_wind_coeff_e( ventilation_data.VentilationInputItem.wind_coeff_e( self.shape.VENTILATION, ph_bldg.wind_coefficient_e ) ) - self.ventilation.write_wind_coeff_f( + await self.ventilation.write_wind_coeff_f( ventilation_data.VentilationInputItem.wind_coeff_f( self.shape.VENTILATION, ph_bldg.wind_coefficient_f ) ) - self.ventilation.write_airtightness_n50( + await self.ventilation.write_airtightness_n50( ventilation_data.VentilationInputItem.airtightness_n50( self.shape.VENTILATION, ph_bldg.airtightness_n50 ) ) return None - def write_project_hot_water(self, phx_project: project.PhxProject) -> None: + async def write_project_hot_water(self, phx_project: project.PhxProject) -> None: """Write the Hot Water data to the PHPP 'DHW+Distribution' worksheet.""" for variant in phx_project.variants: mech_collection = variant.default_mech_collection - + # -- Tanks # Use only the first 2 tanks for PHPP if len(mech_collection.dhw_tank_devices) > 2: @@ -698,7 +712,7 @@ def write_project_hot_water(self, phx_project: project.PhxProject) -> None: i, ) ) - self.hot_water.write_tanks(tank_inputs) + await self.hot_water.write_tanks(tank_inputs) # -- Branch Piping branch_piping_inputs = [] @@ -722,7 +736,7 @@ def write_project_hot_water(self, phx_project: project.PhxProject) -> None: mech_collection._distribution_num_hw_tap_points, ) ) - self.hot_water.write_branch_piping(branch_piping_inputs) + await self.hot_water.write_branch_piping(branch_piping_inputs) # -- Recirculation Piping recirc_piping_inputs = [] @@ -743,11 +757,13 @@ def write_project_hot_water(self, phx_project: project.PhxProject) -> None: i, ) ) - self.hot_water.write_recirc_piping(recirc_piping_inputs) + await self.hot_water.write_recirc_piping(recirc_piping_inputs) return None - def write_project_res_elec_appliances(self, phx_project: project.PhxProject) -> None: + async def write_project_res_elec_appliances( + self, phx_project: project.PhxProject + ) -> None: """Write out all of the detailed residential appliances to the "Electricity" Worksheet.""" equipment_inputs = [] for phx_variant in phx_project.variants: @@ -756,25 +772,29 @@ def write_project_res_elec_appliances(self, phx_project: project.PhxProject) -> equipment_inputs.append( electricity_item.ElectricityItemXLWriter(phx_equip) ) - self.electricity.write_equipment(equipment_inputs) + await self.electricity.write_equipment(equipment_inputs) return None - def write_non_res_utilization_profiles(self, phx_project: project.PhxProject) -> None: + async def write_non_res_utilization_profiles( + self, phx_project: project.PhxProject + ) -> None: """Write out all of the Utilization patterns to the "Use non-res" Worksheet.""" # TODO: build this.... # for pattern in phx_project.utilization_patterns_occupancy: # print(pattern) - def write_non_res_space_lighting(self, phx_project: project.PhxProject) -> None: + async def write_non_res_space_lighting( + self, phx_project: project.PhxProject + ) -> None: """Write out all of the Space Lighting values to the "Electricity non-res" Worksheet.""" return - def write_non_res_IHG(self, phx_project: project.PhxProject) -> None: + async def write_non_res_IHG(self, phx_project: project.PhxProject) -> None: """Write out all of the Occupancy patterns to the "IHG non-res" Worksheet.""" return - def activate_variant_assemblies(self) -> None: + async def activate_variant_assemblies(self) -> None: """Remove all existing U-Value information and link assemblies to the Variants worksheet.""" # -- Collect all the assemblies from the U-Values page @@ -788,7 +808,7 @@ def activate_variant_assemblies(self) -> None: "You will have to set up the assembly-layer Variants links manually." ) continue - self.variants.write_assembly_layer(assembly_name, i) + await self.variants.write_assembly_layer(assembly_name, i) # -- Get all the Variant assembly names with prefix assembly_phpp_ids = self.variants.get_assembly_layer_phpp_ids() @@ -798,21 +818,21 @@ def activate_variant_assemblies(self) -> None: return None - def activate_variant_windows(self) -> None: + async def activate_variant_windows(self) -> None: """Set the Frame and Glass Components to link to the Variants worksheet for all windows.""" self.windows.activate_variants() return None - def activate_variant_ventilation(self) -> None: + async def activate_variant_ventilation(self) -> None: """Set the ACH, Ventilation type to link to the Variants worksheet.""" self.ventilation.activate_variants() return None - def activate_variant_additional_vent(self) -> None: + async def activate_variant_additional_vent(self) -> None: """Set the Ventilator, duct length and insulation to link to the Variants worksheet.""" # -- Find the locations of the Ventilation input items diff --git a/PHX/PHPP/sheet_io/io_addnl_vent.py b/PHX/PHPP/sheet_io/io_addnl_vent.py index fd6a5b0..eec0077 100644 --- a/PHX/PHPP/sheet_io/io_addnl_vent.py +++ b/PHX/PHPP/sheet_io/io_addnl_vent.py @@ -358,7 +358,7 @@ def __init__(self, _xl: xl_app.XLConnection, _shape: shape_model.AddnlVent) -> N self.vent_units = VentUnits(self.xl, self.shape) self.vent_ducts = VentDucts(self.xl, self.shape) - def write_spaces(self, _spaces: List[vent_space.VentSpaceRow]) -> None: + async def write_spaces(self, _spaces: List[vent_space.VentSpaceRow]) -> None: if not self.spaces.section_first_entry_row: self.spaces.section_first_entry_row = ( self.spaces.find_section_first_entry_row() @@ -366,16 +366,16 @@ def write_spaces(self, _spaces: List[vent_space.VentSpaceRow]) -> None: for i, space in enumerate(_spaces, start=self.spaces.section_first_entry_row): for item in space.create_xl_items(self.shape.name, _row_num=i): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_vent_units(self, _vent_units: List[vent_units.VentUnitRow]) -> None: + async def write_vent_units(self, _vent_units: List[vent_units.VentUnitRow]) -> None: for i, vent_unit in enumerate( _vent_units, start=self.vent_units.section_first_entry_row ): for item in vent_unit.create_xl_items(self.shape.name, _row_num=i): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_vent_ducts(self, _vent_ducts: List) -> None: + async def write_vent_ducts(self, _vent_ducts: List) -> None: if not self.vent_ducts.section_first_entry_row: self.vent_ducts.section_first_entry_row = ( self.vent_ducts.find_section_first_entry_row() @@ -385,9 +385,9 @@ def write_vent_ducts(self, _vent_ducts: List) -> None: _vent_ducts, start=self.vent_ducts.section_first_entry_row ): for item in vent_duct.create_xl_items(self.shape.name, _row_num=i): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def activate_variants( + async def activate_variants( self, variants_worksheet_name: str, vent_unit_range: str ) -> None: """Link the Vent unit to the Variants worksheet.""" @@ -396,7 +396,7 @@ def activate_variants( start_row = self.vent_units.find_section_first_entry_row() end_row = self.vent_units.find_section_last_entry_row() for i in range(start_row, end_row + 1): - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.units.inputs.unit_selected.column}{i}", diff --git a/PHX/PHPP/sheet_io/io_areas.py b/PHX/PHPP/sheet_io/io_areas.py index 5aaa250..c60792e 100644 --- a/PHX/PHPP/sheet_io/io_areas.py +++ b/PHX/PHPP/sheet_io/io_areas.py @@ -318,21 +318,21 @@ def __init__(self, _xl: xl_app.XLConnection, _shape: shape_model.Areas) -> None: self.surfaces = Surfaces(self.xl, self.shape, self.group_type_exposures) self.thermal_bridges = ThermalBridges(self.xl, self.shape) - def write_thermal_bridges( + async def write_thermal_bridges( self, _tbs: List[areas_thermal_bridges.ThermalBridgeRow] ) -> None: """Write all of the the thermal bridge data to the PHPP Areas worksheet.""" for i, tb in enumerate(_tbs, start=self.thermal_bridges.section_first_entry_row): for item in tb.create_xl_items(self.shape.name, _row_num=i): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_surfaces(self, _surfaces: List[areas_surface.SurfaceRow]) -> None: + async def write_surfaces(self, _surfaces: List[areas_surface.SurfaceRow]) -> None: """Write all of the the surface data to the PHPP Areas worksheet.""" start = self.surfaces.section_first_entry_row for i, surface in enumerate(_surfaces, start=start): for item in surface.create_xl_items(self.shape.name, _row_num=i): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) def _create_input_location_object( self, _phpp_model_obj: areas_data.AreasInput @@ -349,12 +349,12 @@ def _create_input_location_object( _input_row_offset=phpp_obj_shape.input_row_offset, ) - def write_item(self, _phpp_model_obj: areas_data.AreasInput) -> None: + async def write_item(self, _phpp_model_obj: areas_data.AreasInput) -> None: """Write the VerificationInputItem item out to the PHPP Areas Worksheet.""" input_object = self._create_input_location_object(_phpp_model_obj) input_row = input_object.find_input_row() xl_item = _phpp_model_obj.create_xl_item(self.shape.name, input_row) - self.xl.write_xl_item(xl_item) + await self.xl.write_xl_item(xl_item) def get_group_type_exposures(self) -> Dict[int, str]: """Return the group type exposures dictionary from the PHPP Areas worksheet.""" @@ -425,26 +425,28 @@ def get_total_horizontal_window_area(self) -> Unit: value = self.xl.get_single_data_item(self.shape.name, f"{item.column}{item.row}") return Unit(float(value or 0.0), str(item.unit)) - def set_surface_row_construction( + async def set_surface_row_construction( self, _row_num: int, _phpp_constriction_id: str ) -> None: """Set the construction-id for the surface row in the PHPP Areas worksheet.""" col = self.shape.surface_rows.inputs.assembly_id.column - item = xl_data.XlItem(self.shape.name, f"{col}{_row_num}", _phpp_constriction_id) - self.xl.write_xl_item(item) + item = xl_data.XlItem( + self.shape.name, f"{col}{_row_num}", _phpp_constriction_id + ) + await self.xl.write_xl_item(item) - def set_surface_row_solar_absorptivity( + async def set_surface_row_solar_absorptivity( self, _row_num: int, _absorptivity: float = 0.75 ) -> None: """Set the solar absorptivity for the surface row in the PHPP Areas worksheet.""" col = self.shape.surface_rows.inputs.absorptivity.column item = xl_data.XlItem(self.shape.name, f"{col}{_row_num}", _absorptivity) - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def set_surface_row_emissivity( + async def set_surface_row_emissivity( self, _row_num: int, _emissivity: float = 0.90 ) -> None: """Set the emissivity for the surface row in the PHPP Areas worksheet.""" col = self.shape.surface_rows.inputs.emissivity.column item = xl_data.XlItem(self.shape.name, f"{col}{_row_num}", _emissivity) - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) diff --git a/PHX/PHPP/sheet_io/io_climate.py b/PHX/PHPP/sheet_io/io_climate.py index 57c8af8..b8ae271 100644 --- a/PHX/PHPP/sheet_io/io_climate.py +++ b/PHX/PHPP/sheet_io/io_climate.py @@ -23,7 +23,9 @@ def get_start_rows(self) -> List[int]: # TODO: make this find the right starting rows. return [self.shape.ud_block.start_row] - def write_climate_block(self, _climate_entry: climate_entry.ClimateDataBlock) -> None: + async def write_climate_block( + self, _climate_entry: climate_entry.ClimateDataBlock + ) -> None: if not self.weather_data_start_rows: self.weather_data_start_rows = self.get_start_rows() @@ -32,14 +34,14 @@ def write_climate_block(self, _climate_entry: climate_entry.ClimateDataBlock) -> start_row = self.weather_data_start_rows[0] for item in _climate_entry.create_xl_items(self.shape.name, start_row): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_active_climate( + async def write_active_climate( self, _active_climate: climate_entry.ClimateSettings ) -> None: start_row = 9 for item in _active_climate.create_xl_items(self.shape.name, start_row): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) def read_active_country(self) -> str: return str( diff --git a/PHX/PHPP/sheet_io/io_components.py b/PHX/PHPP/sheet_io/io_components.py index 4236594..a84911f 100644 --- a/PHX/PHPP/sheet_io/io_components.py +++ b/PHX/PHPP/sheet_io/io_components.py @@ -503,7 +503,9 @@ def first_empty_frame_row_num(self) -> int: """Return the row number of the first empty row in the Frames section.""" return self.frames.find_first_empty_row() - def write_single_glazing(self, _row_num: int, _glazing_row: GlazingRow) -> str: + async def write_single_glazing( + self, _row_num: int, _glazing_row: GlazingRow + ) -> str: """Write a single GlazingRow object to the PHPP "Components" worksheet. Return: @@ -512,17 +514,17 @@ def write_single_glazing(self, _row_num: int, _glazing_row: GlazingRow) -> str: """ for item in _glazing_row.create_xl_items(self.shape.name, _row_num=_row_num): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) return self.glazings.get_glazing_phpp_id_by_row_num(_row_num) - def write_glazings(self, _glazing_rows: List[GlazingRow]) -> None: + async def write_glazings(self, _glazing_rows: List[GlazingRow]) -> None: """Write a list of GlazingRow objects to the PHPP "Components" worksheet.""" for i, glazing_row in enumerate( _glazing_rows, start=self.glazings.section_first_entry_row ): - self.write_single_glazing(i, glazing_row) + await self.write_single_glazing(i, glazing_row) - def write_single_frame(self, _row_num: int, _frame_row: FrameRow) -> str: + async def write_single_frame(self, _row_num: int, _frame_row: FrameRow) -> str: """Write a single FrameRow object to the PHPP "Components" worksheet. Return: @@ -530,16 +532,16 @@ def write_single_frame(self, _row_num: int, _frame_row: FrameRow) -> str: * (str): The PHPP ID-name of the frame component written to the PHPP. """ for item in _frame_row.create_xl_items(self.shape.name, _row_num=_row_num): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) return self.frames.get_frame_phpp_id_by_row_num(_row_num) - def write_frames(self, _frame_row: List[FrameRow]) -> None: + async def write_frames(self, _frame_row: List[FrameRow]) -> None: """Write a list of FrameRow objects to the PHPP "Components" worksheet.""" start = self.frames.section_first_entry_row for i, frame_row in enumerate(_frame_row, start=start): - self.write_single_frame(i, frame_row) + await self.write_single_frame(i, frame_row) - def write_single_ventilator( + async def write_single_ventilator( self, _row_num: int, _ventilator_row: VentilatorRow ) -> str: """Write a single VentilatorRow object to the PHPP "Components" worksheet. @@ -549,11 +551,11 @@ def write_single_ventilator( * (str): The PHPP ID-name of the ventilator component written to the PHPP. """ for item in _ventilator_row.create_xl_items(self.shape.name, _row_num=_row_num): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) return self.ventilators.get_ventilator_phpp_id_by_row_num(_row_num) - def write_ventilators(self, _ventilator_row: List[VentilatorRow]) -> None: + async def write_ventilators(self, _ventilator_row: List[VentilatorRow]) -> None: """Write a list of VentilatorRow objects to the PHPP "Components" worksheet.""" start = self.ventilators.section_first_entry_row for i, ventilator_row in enumerate(_ventilator_row, start): - self.write_single_ventilator(i, ventilator_row) + await self.write_single_ventilator(i, ventilator_row) diff --git a/PHX/PHPP/sheet_io/io_elec_non_res.py b/PHX/PHPP/sheet_io/io_elec_non_res.py index 3dc4246..b4b09d0 100644 --- a/PHX/PHPP/sheet_io/io_elec_non_res.py +++ b/PHX/PHPP/sheet_io/io_elec_non_res.py @@ -144,12 +144,12 @@ def _get_target_unit(self, _field_name: str) -> str: "Return the right target unit for the PHPP item writing (IP | SI)" return getattr(self.shape.lighting_rows.inputs, _field_name).unit - def set_lighting_power_density( + async def set_lighting_power_density( self, _row_num: int, _power_density: float, _unit: str = "W/M2" ) -> None: """Set the lighting power density for the given row number.""" _range = f"{self.shape.lighting_rows.inputs.installed_power.column}{_row_num}" - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( sheet_name=self.shape.name, xl_range=_range, diff --git a/PHX/PHPP/sheet_io/io_electricity.py b/PHX/PHPP/sheet_io/io_electricity.py index 158c904..1a9d390 100644 --- a/PHX/PHPP/sheet_io/io_electricity.py +++ b/PHX/PHPP/sheet_io/io_electricity.py @@ -21,7 +21,7 @@ def __init__(self, _xl: xl_app.XLConnection, shape: shape_model.Electricity) -> self.shape = shape self.device_map = elec_equip.get_device_type_map() - def _turn_off_all_equipment(self) -> None: + async def _turn_off_all_equipment(self) -> None: """Sets all the 'used' values to 0 to reset the sheet before writing new equipment.""" for item in self.shape.input_rows: # Some items cannot be turned off.... @@ -35,21 +35,21 @@ def _turn_off_all_equipment(self) -> None: if item[0] in excluded: continue - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.input_columns.used}{item[1].data}", 0 ) ) - def write_equipment( + async def write_equipment( self, _equipment_inputs: List[electricity_item.ElectricityItemXLWriter] ) -> None: """Write a list of equipment-input objects to the Worksheet.""" - self._turn_off_all_equipment() + await self._turn_off_all_equipment() for equip_input in _equipment_inputs: for item in equip_input.create_xl_items(self.shape): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) def build_phx_device_from_phpp( self, _reader: electricity_item.ReaderDataItem diff --git a/PHX/PHPP/sheet_io/io_hot_water.py b/PHX/PHPP/sheet_io/io_hot_water.py index 312b2d5..b6e1b78 100644 --- a/PHX/PHPP/sheet_io/io_hot_water.py +++ b/PHX/PHPP/sheet_io/io_hot_water.py @@ -233,15 +233,15 @@ def __init__(self, _xl: xl_app.XLConnection, _shape: shape_model.Dhw): self.tanks = Tanks(self.xl, self.shape) self.dhw_piping = DHWPiping(self.xl, self.shape) - def write_tanks(self, _phpp_hw_tanks: List[hot_water_tank.TankInput]) -> None: + async def write_tanks(self, _phpp_hw_tanks: List[hot_water_tank.TankInput]) -> None: """Write the tank data to the spreadsheet.""" for phpp_Tank_input in _phpp_hw_tanks: for item in phpp_Tank_input.create_xl_items( self.shape.name, self.tanks.tank_1.entry_row_start ): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_branch_piping( + async def write_branch_piping( self, _phpp_branch_piping: List[hot_water_piping.BranchPipingInput] ) -> None: """Write the branch piping data to the spreadsheet.""" @@ -249,9 +249,9 @@ def write_branch_piping( for item in pipe_inputs.create_xl_items( self.shape.name, self.dhw_piping.branch_piping.header_row ): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_recirc_piping( + async def write_recirc_piping( self, _phpp_recirc_piping: List[hot_water_piping.BranchPipingInput] ) -> None: """Write the recirc piping data to the spreadsheet.""" @@ -259,7 +259,7 @@ def write_recirc_piping( for item in pipe_inputs.create_xl_items( self.shape.name, self.dhw_piping.recirc_piping.header_row ): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) def get_all_tank_device_data(self) -> List[TankData]: """Get all the tank data from the PHPP worksheet.""" diff --git a/PHX/PHPP/sheet_io/io_shading.py b/PHX/PHPP/sheet_io/io_shading.py index 1d29302..c0b6758 100644 --- a/PHX/PHPP/sheet_io/io_shading.py +++ b/PHX/PHPP/sheet_io/io_shading.py @@ -104,9 +104,9 @@ def find_entry_block_end(self, _start_row: int = 1, _read_length: int = 100) -> f"marker on the '{self.shape.name}' sheet, column {self.shape.shading_rows_end.locator_col_entry}?" ) - def write_shading(self, _shading_rows: List[shading_rows.ShadingRow]) -> None: + async def write_shading(self, _shading_rows: List[shading_rows.ShadingRow]) -> None: """Write a list of ShadingRow objects to the Shading worksheet.""" for i, shading_row in enumerate(_shading_rows, start=self.entry_row_start): for item in shading_row.create_xl_items(self.shape.name, _row_num=i): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) diff --git a/PHX/PHPP/sheet_io/io_u_values.py b/PHX/PHPP/sheet_io/io_u_values.py index 6f72ef6..975a648 100644 --- a/PHX/PHPP/sheet_io/io_u_values.py +++ b/PHX/PHPP/sheet_io/io_u_values.py @@ -231,19 +231,19 @@ def write_single_PHX_construction(self, _phx_construction, _start_row) -> None: ) self.write_single_constructor_block(new_constructor, _start_row) - def write_single_constructor_block( + async def write_single_constructor_block( self, _construction: uvalues_constructor.ConstructorBlock, _start_row: int ) -> None: """Write a single Construction with all the layers to the PHPP worksheet.""" for item in _construction.create_xl_items(self.shape.name, _start_row): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_constructor_blocks( + async def write_constructor_blocks( self, _const_blocks: List[uvalues_constructor.ConstructorBlock] ) -> None: """Write a list of ConstructorBlocks to the U-Values worksheet.""" - self.clear_all_constructor_data(_clear_name=True) + await self.clear_all_constructor_data(_clear_name=True) assert len(_const_blocks) <= len( self.all_constructor_start_rows @@ -252,7 +252,7 @@ def write_constructor_blocks( for construction, start_row in zip( _const_blocks, self.all_constructor_start_rows ): - self.write_single_constructor_block(construction, start_row) + await self.write_single_constructor_block(construction, start_row) def add_new_phx_construction(self, _phx_construction: PhxConstructionOpaque) -> str: """Add a new PHX Construction to the PHPP worksheet in the first empty slot found. @@ -273,16 +273,20 @@ def add_new_phx_construction(self, _phx_construction: PhxConstructionOpaque) -> # ------------------------------------------------------------------------- # -- Removers - def clear_single_constructor_data(self, _row_num, _clear_name: bool = False) -> None: + async def clear_single_constructor_data( + self, _row_num, _clear_name: bool = False + ) -> None: """Clears the existing data from a single constructor block.""" # -- main body data data_block_start = f"{self.shape.constructor.inputs.sec_1_description.column}{_row_num + self.shape.constructor.inputs.first_layer_row_offset}" data_block_end = f"{self.shape.constructor.inputs.thickness.column}{_row_num + self.shape.constructor.inputs.last_layer_row_offset}" data_block_range = f"{data_block_start}:{data_block_end}" - self.xl.write_xl_item(xl_data.XlItem(self.shape.name, data_block_range, None)) + await self.xl.write_xl_item( + xl_data.XlItem(self.shape.name, data_block_range, None) + ) # -- surface films - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.constructor.inputs.r_si.column}{_row_num + 4}:{self.shape.constructor.inputs.r_se.column}{_row_num + 5}", @@ -292,7 +296,7 @@ def clear_single_constructor_data(self, _row_num, _clear_name: bool = False) -> # -- Assembly Name (Sometimes, like with Variants, will want to keep this) if _clear_name: - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.constructor.inputs.display_name.column}{_row_num + self.shape.constructor.inputs.name_row_offset}", @@ -300,14 +304,14 @@ def clear_single_constructor_data(self, _row_num, _clear_name: bool = False) -> ) ) - def clear_all_constructor_data(self, _clear_name: bool = True) -> None: + async def clear_all_constructor_data(self, _clear_name: bool = True) -> None: """Remove all of the existing input data from all of the constructors in the PHPP.""" for row_num in self.all_constructor_start_rows: - self.clear_single_constructor_data(row_num, _clear_name) + await self.clear_single_constructor_data(row_num, _clear_name) # ------------------------------------------------------------------------- - def activate_variants( + async def activate_variants( self, _assembly_phpp_ids: List[VariantAssemblyLayerName] ) -> None: """Connect all the links to make the 'Variants' page drive the input values.""" @@ -327,7 +331,7 @@ def activate_variants( for variant_layer_id in _assembly_phpp_ids: if variant_layer_id.display_name == assembly_name: # -- Link to the variants layer name - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.constructor.inputs.variants_layer_name}{row_num + self.shape.constructor.inputs.first_layer_row_offset}", @@ -336,7 +340,7 @@ def activate_variants( ) # -- Link the variants layer conductivity - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.constructor.inputs.sec_1_conductivity.column}{row_num + self.shape.constructor.inputs.first_layer_row_offset}", @@ -345,7 +349,7 @@ def activate_variants( ) # -- Link the variants layer thickness - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.constructor.inputs.thickness.column}{row_num + self.shape.constructor.inputs.first_layer_row_offset}", @@ -354,7 +358,7 @@ def activate_variants( ) # -- Set the surface films to zero - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.constructor.inputs.r_si.column}{row_num + self.shape.constructor.inputs.rse_row_offset}:{self.shape.constructor.inputs.r_se.column}{row_num + self.shape.constructor.inputs.rsi_row_offset}", diff --git a/PHX/PHPP/sheet_io/io_variants.py b/PHX/PHPP/sheet_io/io_variants.py index f50b59f..99c3ab5 100644 --- a/PHX/PHPP/sheet_io/io_variants.py +++ b/PHX/PHPP/sheet_io/io_variants.py @@ -162,7 +162,9 @@ def get_ventilation_input_item_rows(self) -> Dict[str, int]: str(_): i for i, _ in enumerate(read_data, start=self.start_ventilation + 1) } - def write_assembly_layer(self, _assembly_name: str, _assembly_num: int) -> None: + async def write_assembly_layer( + self, _assembly_name: str, _assembly_num: int + ) -> None: """Write a new assembly layer to the Variants worksheet.""" if not self.start_assembly_layers: @@ -170,7 +172,7 @@ def write_assembly_layer(self, _assembly_name: str, _assembly_num: int) -> None: # -- Variants assemblies are input every other row row_offset = (_assembly_num * 2) + 1 - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.assemblies.input_col}{self.start_assembly_layers + row_offset}", @@ -180,14 +182,16 @@ def write_assembly_layer(self, _assembly_name: str, _assembly_num: int) -> None: return None - def write_window_type(self, _window_type_name: str, _window_type_num: int) -> None: + async def write_window_type( + self, _window_type_name: str, _window_type_num: int + ) -> None: """Write a new Window Type name to the Variants worksheet.""" if not self.start_window_types: self.start_window_types = self.get_window_types_start() # -- Window types are input every 8th row row_offset = (_window_type_num * 8) + 1 - self.xl.write_xl_item( + await self.xl.write_xl_item( xl_data.XlItem( self.shape.name, f"{self.shape.assemblies.input_col}{self.start_window_types + row_offset}", diff --git a/PHX/PHPP/sheet_io/io_ventilation.py b/PHX/PHPP/sheet_io/io_ventilation.py index d2b146c..a3c78f1 100644 --- a/PHX/PHPP/sheet_io/io_ventilation.py +++ b/PHX/PHPP/sheet_io/io_ventilation.py @@ -90,7 +90,7 @@ def __init__(self, _xl: xl_app.XLConnection, _shape: shape_model.Ventilation): self.shape.multi_unit_on.locator_string, ) - def _write_input( + async def _write_input( self, _input_item: VentilationInputLocation, _phpp_model_item: ventilation_data.VentilationInputItem, @@ -99,37 +99,37 @@ def _write_input( input_row = _input_item.find_input_row() xl_item = _phpp_model_item.create_xl_item(self.shape.name, input_row) - self.xl.write_xl_item(xl_item) + await self.xl.write_xl_item(xl_item) - def write_ventilation_type( + async def write_ventilation_type( self, _phpp_model_obj: ventilation_data.VentilationInputItem ) -> None: - self._write_input(self.io_vent_type, _phpp_model_obj) + await self._write_input(self.io_vent_type, _phpp_model_obj) - def write_wind_coeff_e( + async def write_wind_coeff_e( self, _phpp_model_obj: ventilation_data.VentilationInputItem ) -> None: - self._write_input(self.io_wind_coeff_e, _phpp_model_obj) + await self._write_input(self.io_wind_coeff_e, _phpp_model_obj) - def write_wind_coeff_f( + async def write_wind_coeff_f( self, _phpp_model_obj: ventilation_data.VentilationInputItem ) -> None: - self._write_input(self.io_wind_coeff_f, _phpp_model_obj) + await self._write_input(self.io_wind_coeff_f, _phpp_model_obj) - def write_airtightness_n50( + async def write_airtightness_n50( self, _phpp_model_obj: ventilation_data.VentilationInputItem ) -> None: - self._write_input(self.io_air_change_rate, _phpp_model_obj) + await self._write_input(self.io_air_change_rate, _phpp_model_obj) - def write_Vn50_volume( + async def write_Vn50_volume( self, _phpp_model_obj: ventilation_data.VentilationInputItem ) -> None: - self._write_input(self.io_net_volume, _phpp_model_obj) + await self._write_input(self.io_net_volume, _phpp_model_obj) - def write_multi_vent_worksheet_on( + async def write_multi_vent_worksheet_on( self, _phpp_model_obj: ventilation_data.VentilationInputItem ) -> None: - self._write_input(self.io_multi_vent_worksheet_on, _phpp_model_obj) + await self._write_input(self.io_multi_vent_worksheet_on, _phpp_model_obj) def activate_variants(self): """Link Ventilation Type and Airtightness to the Variants worksheet.""" diff --git a/PHX/PHPP/sheet_io/io_verification.py b/PHX/PHPP/sheet_io/io_verification.py index f531343..2b1f168 100644 --- a/PHX/PHPP/sheet_io/io_verification.py +++ b/PHX/PHPP/sheet_io/io_verification.py @@ -107,12 +107,14 @@ def _create_input_location_object( _input_row_offset=phpp_obj_shape.input_row_offset, ) - def write_item(self, _phpp_model_obj: verification_data.VerificationInput) -> None: + async def write_item( + self, _phpp_model_obj: verification_data.VerificationInput + ) -> None: """Write the VerificationInputItem item out to the PHPP Verification Worksheet.""" input_object = self._create_input_location_object(_phpp_model_obj) input_row = input_object.find_input_row() xl_item = _phpp_model_obj.create_xl_item(self.shape.name, input_row) - self.xl.write_xl_item(xl_item) + await self.xl.write_xl_item(xl_item) def read_architect(self) -> TeamMemberData: """Return a TeamMemberData object with the architect info from PHPP.""" diff --git a/PHX/PHPP/sheet_io/io_windows.py b/PHX/PHPP/sheet_io/io_windows.py index 076f4fb..4430bc4 100644 --- a/PHX/PHPP/sheet_io/io_windows.py +++ b/PHX/PHPP/sheet_io/io_windows.py @@ -148,7 +148,7 @@ def find_last_entry_row(self, _start_row: Optional[int] = None) -> int: else: return self.find_last_entry_row(_row_end) - def set_single_window_construction_ids( + async def set_single_window_construction_ids( self, _row_num: int, _glazing_construction_id: str, @@ -171,25 +171,25 @@ def set_single_window_construction_ids( """ glazing_col = str(self.shape.window_rows.inputs.glazing_id.column) glazing_range = f"{glazing_col}{_row_num}" - self.xl.write_xl_item( + await self.xl.write_xl_item( XlItem(self.shape.name, glazing_range, _glazing_construction_id) ) frame_col = str(self.shape.window_rows.inputs.frame_id.column) frame_range = f"{frame_col}{_row_num}" - self.xl.write_xl_item( + await self.xl.write_xl_item( XlItem(self.shape.name, frame_range, _frame_construction_id) ) - def write_single_window(self, _row_num: int, _window_row: WindowRow) -> None: + async def write_single_window(self, _row_num: int, _window_row: WindowRow) -> None: """Write a single WindowRow object to the Windows worksheet.""" for item in _window_row.create_xl_items(self.shape.name, _row_num=_row_num): - self.xl.write_xl_item(item) + await self.xl.write_xl_item(item) - def write_windows(self, _window_rows: List[WindowRow]) -> None: + async def write_windows(self, _window_rows: List[WindowRow]) -> None: """Write a list of WindowRow objects to the Windows worksheet.""" for i, window_row in enumerate(_window_rows, start=self.first_entry_row): - self.write_single_window(i, window_row) + await self.write_single_window(i, window_row) def get_all_window_names(self) -> List[str]: """Return a list of all the window names found in the worksheet.""" @@ -262,12 +262,12 @@ def get_all_glazing_names(self) -> set[str]: ) return {get_name_from_glazing_id(_d) for _d in glazing_data} - def activate_variants(self) -> None: + async def activate_variants(self) -> None: """Set the frame and glass values to link to the Variants worksheet.""" for row_num in range(self.first_entry_row, self.last_entry_row): # -- Link Glazing to the variants type - self.xl.write_xl_item( + await self.xl.write_xl_item( XlItem( self.shape.name, f"{self.shape.window_rows.inputs.glazing_id.column}{row_num}", @@ -276,7 +276,7 @@ def activate_variants(self) -> None: ) # -- Link Frame to the variants type - self.xl.write_xl_item( + await self.xl.write_xl_item( XlItem( self.shape.name, f"{self.shape.window_rows.inputs.frame_id.column}{row_num}", @@ -284,7 +284,7 @@ def activate_variants(self) -> None: ) ) - def scale_window_size(self, _row_num: int, _scale_factor: float) -> None: + async def scale_window_size(self, _row_num: int, _scale_factor: float) -> None: """Scale the size of a single window based on an overall scale-factor. This is used during baseline model generation to scale the size of the windows @@ -324,14 +324,14 @@ def scale_window_size(self, _row_num: int, _scale_factor: float) -> None: new_height = height * edge_scaling_factor # -- Set the new dimensions - self.xl.write_xl_item( + await self.xl.write_xl_item( XlItem( self.shape.name, f"{self.shape.window_rows.inputs.width.column}{_row_num}", new_width, ) ) - self.xl.write_xl_item( + await self.xl.write_xl_item( XlItem( self.shape.name, f"{self.shape.window_rows.inputs.height.column}{_row_num}", diff --git a/PHX/hbjson_to_phpp.py b/PHX/hbjson_to_phpp.py index 8d6124c..2a8a95c 100755 --- a/PHX/hbjson_to_phpp.py +++ b/PHX/hbjson_to_phpp.py @@ -3,24 +3,51 @@ """Export an HBJSON file to a PHPP excel document.""" -import sys +import asyncio import pathlib +import sys import xlwings as xw -from PHX.from_HBJSON import read_HBJSON_file, create_project +from PHX.from_HBJSON import create_project, read_HBJSON_file from PHX.PHPP import phpp_app -from PHX.PHPP.phpp_localization.shape_model import PhppShape from PHX.xl import xl_app +async def run(phx_project): + with phpp_conn.xl.in_silent_mode(): + await phpp_conn.xl.unprotect_all_sheets() + await phpp_conn.write_certification_config(phx_project) + await phpp_conn.write_climate_data(phx_project) + await phpp_conn.write_project_constructions(phx_project) + await phpp_conn.write_project_tfa(phx_project) + await phpp_conn.write_project_opaque_surfaces(phx_project) + await phpp_conn.write_project_thermal_bridges(phx_project) + await phpp_conn.write_project_window_components(phx_project) + await phpp_conn.write_project_window_surfaces(phx_project) + await phpp_conn.write_project_window_shading(phx_project) + await phpp_conn.write_project_ventilation_components(phx_project) + await phpp_conn.write_project_ventilators(phx_project) + await phpp_conn.write_project_spaces(phx_project) + await phpp_conn.write_project_ventilation_type(phx_project) + await phpp_conn.write_project_airtightness(phx_project) + await phpp_conn.write_project_volume(phx_project) + await phpp_conn.write_project_hot_water(phx_project) + await phpp_conn.write_project_res_elec_appliances(phx_project) + + if ACTIVATE_VARIANTS == "True": + await phpp_conn.activate_variant_assemblies() + await phpp_conn.activate_variant_windows() + await phpp_conn.activate_variant_ventilation() + await phpp_conn.activate_variant_additional_vent() + + if __name__ == "__main__": # --- Command line arguments # ------------------------------------------------------------------------- SOURCE_FILE = pathlib.Path(str(sys.argv[1])).resolve() ACTIVATE_VARIANTS = pathlib.Path(sys.argv[2]).resolve() - # --- Read in an existing HB_JSON and re-build the HB Objects # ------------------------------------------------------------------------- print("- " * 50) @@ -43,29 +70,6 @@ xl.output(f"> connected to excel doc: {phpp_conn.xl.wb.name}") except xl_app.NoActiveExcelRunningError as e: raise e - - with phpp_conn.xl.in_silent_mode(): - phpp_conn.xl.unprotect_all_sheets() - phpp_conn.write_certification_config(phx_project) - phpp_conn.write_climate_data(phx_project) - phpp_conn.write_project_constructions(phx_project) - phpp_conn.write_project_tfa(phx_project) - phpp_conn.write_project_opaque_surfaces(phx_project) - phpp_conn.write_project_thermal_bridges(phx_project) - phpp_conn.write_project_window_components(phx_project) - phpp_conn.write_project_window_surfaces(phx_project) - phpp_conn.write_project_window_shading(phx_project) - phpp_conn.write_project_ventilation_components(phx_project) - phpp_conn.write_project_ventilators(phx_project) - phpp_conn.write_project_spaces(phx_project) - phpp_conn.write_project_ventilation_type(phx_project) - phpp_conn.write_project_airtightness(phx_project) - phpp_conn.write_project_volume(phx_project) - phpp_conn.write_project_hot_water(phx_project) - phpp_conn.write_project_res_elec_appliances(phx_project) - if ACTIVATE_VARIANTS == "True": - phpp_conn.activate_variant_assemblies() - phpp_conn.activate_variant_windows() - phpp_conn.activate_variant_ventilation() - phpp_conn.activate_variant_additional_vent() + loop = asyncio.get_event_loop() + loop.run_until_complete(run(phx_project)) diff --git a/PHX/xl/xl_app.py b/PHX/xl/xl_app.py index 8c5a3de..1b1ea1f 100644 --- a/PHX/xl/xl_app.py +++ b/PHX/xl/xl_app.py @@ -582,7 +582,7 @@ def output(self, _input): # If _input=None, ignore... pass - def unprotect_all_sheets(self) -> None: + async def unprotect_all_sheets(self) -> None: """Walk through all the sheets and unprotect them all.""" for sheet in self.wb.sheets: if self.os_is_windows: @@ -590,7 +590,7 @@ def unprotect_all_sheets(self) -> None: else: sheet.api.unprotect() - def write_xl_item( + async def write_xl_item( self, _xl_item: Union[xl_data.XlItem, xl_data.XLItem_List], _transpose: bool = False, diff --git a/_testing_HBJSON_to_PHPP.py b/_testing_HBJSON_to_PHPP.py index 91a8426..01cdcfb 100644 --- a/_testing_HBJSON_to_PHPP.py +++ b/_testing_HBJSON_to_PHPP.py @@ -3,12 +3,14 @@ """DEV SANDBOX: export a specified HBJSON file to a PHPP XL file.""" +import asyncio import pathlib +import sys import xlwings as xw from rich import print -from PHX.from_HBJSON import read_HBJSON_file, create_project +from PHX.from_HBJSON import create_project, read_HBJSON_file from PHX.PHPP import phpp_app from PHX.xl import xl_app @@ -23,6 +25,37 @@ SOURCE_FILE = pathlib.Path(str(sys.argv[0])).resolve() +async def run(phx_project): + with phpp_conn.xl.in_silent_mode(): + await phpp_conn.xl.unprotect_all_sheets() + await phpp_conn.write_certification_config(phx_project) + await phpp_conn.write_climate_data(phx_project) + await phpp_conn.write_project_constructions(phx_project) + await phpp_conn.write_project_tfa(phx_project) + await phpp_conn.write_project_opaque_surfaces(phx_project) + await phpp_conn.write_project_thermal_bridges(phx_project) + await phpp_conn.write_project_window_components(phx_project) + await phpp_conn.write_project_window_surfaces(phx_project) + await phpp_conn.write_project_window_shading(phx_project) + await phpp_conn.write_project_ventilation_components(phx_project) + await phpp_conn.write_project_ventilators(phx_project) + await phpp_conn.write_project_spaces(phx_project) + await phpp_conn.write_project_ventilation_type(phx_project) + await phpp_conn.write_project_airtightness(phx_project) + await phpp_conn.write_project_volume(phx_project) + await phpp_conn.write_project_hot_water(phx_project) + await phpp_conn.write_project_res_elec_appliances(phx_project) + await phpp_conn.write_non_res_utilization_profiles(phx_project) + await phpp_conn.write_non_res_space_lighting(phx_project) + await phpp_conn.write_non_res_IHG(phx_project) + + # TODO: add custom any-range writer (User-Determined) + + await phpp_conn.activate_variant_assemblies() + await phpp_conn.activate_variant_windows() + await phpp_conn.activate_variant_ventilation() + await phpp_conn.activate_variant_additional_vent() + if __name__ == "__main__": # --- Read in an existing HB_JSON and re-build the HB Objects @@ -50,32 +83,5 @@ except xl_app.NoActiveExcelRunningError as e: raise e - with phpp_conn.xl.in_silent_mode(): - phpp_conn.xl.unprotect_all_sheets() - phpp_conn.write_certification_config(phx_project) - phpp_conn.write_climate_data(phx_project) - phpp_conn.write_project_constructions(phx_project) - phpp_conn.write_project_tfa(phx_project) - phpp_conn.write_project_opaque_surfaces(phx_project) - phpp_conn.write_project_thermal_bridges(phx_project) - phpp_conn.write_project_window_components(phx_project) - phpp_conn.write_project_window_surfaces(phx_project) - phpp_conn.write_project_window_shading(phx_project) - phpp_conn.write_project_ventilation_components(phx_project) - phpp_conn.write_project_ventilators(phx_project) - phpp_conn.write_project_spaces(phx_project) - phpp_conn.write_project_ventilation_type(phx_project) - phpp_conn.write_project_airtightness(phx_project) - phpp_conn.write_project_volume(phx_project) - phpp_conn.write_project_hot_water(phx_project) - phpp_conn.write_project_res_elec_appliances(phx_project) - phpp_conn.write_non_res_utilization_profiles(phx_project) - phpp_conn.write_non_res_space_lighting(phx_project) - phpp_conn.write_non_res_IHG(phx_project) - - # TODO: add custom any-range writer (User-Determined) - - phpp_conn.activate_variant_assemblies() - phpp_conn.activate_variant_windows() - phpp_conn.activate_variant_ventilation() - phpp_conn.activate_variant_additional_vent() + loop = asyncio.get_event_loop() + loop.run_until_complete(run(phx_project))