From fdb6e5d1819c0b6bcf7a49f494916a42f9f868b9 Mon Sep 17 00:00:00 2001 From: weilixu Date: Sat, 27 Jun 2026 08:56:44 -0700 Subject: [PATCH 1/2] add workflow for assemblies u factor --- comcheck_api/api/api_services.py | 25 +++++++++++++++++ comcheck_api/client/comcheck_client.py | 38 +++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/comcheck_api/api/api_services.py b/comcheck_api/api/api_services.py index dbf349f..83bf35d 100644 --- a/comcheck_api/api/api_services.py +++ b/comcheck_api/api/api_services.py @@ -187,6 +187,31 @@ def update_project( except Exception as error: self._handle_api_error(error) + def assemblies_uvalue(self, envelope_data: Dict[str, Any], energy_code) -> Dict[str, Any]: + """get assemblies u values + + Args: + envelope_data: The envelope data to send in the request body + energy_code: The energy code for the api end point path + + Returns: + RunSimulationResponse with session information + + Raises: + COMCheckHTTPError: If the API returns an error status + COMCheckConnectionError: If the request fails + """ + try: + client = self._get_client() + response = client.post( + f"/{energy_code}/assemblies/uvalues", json=envelope_data + ) + response.raise_for_status() + # may need validation here. + return response.json() + except Exception as error: + self._handle_api_error(error) + def start_run_simulation( self, project_data: Dict[str, Any] ) -> RunSimulationResponse: diff --git a/comcheck_api/client/comcheck_client.py b/comcheck_api/client/comcheck_client.py index 896280e..69e02e6 100644 --- a/comcheck_api/client/comcheck_client.py +++ b/comcheck_api/client/comcheck_client.py @@ -244,6 +244,38 @@ def _parse_data(self, data, mode): return ComBuilding(**data) return data + def assemblie_uvalues(self, project: ComBuilding) -> Any: + """ + + Args: + project: + + Returns: + + """ + logger = logging.getLogger(__name__) + # update assemblies uvalue + energy_code = str(project.control.code) + envelope_data = project.envelope.model_dump(mode="json", exclude_unset=True) + + def fill_empty_description(assemblies: list[dict]) -> list[dict]: + for assembly in assemblies: + if not assembly.get("description", ""): + assembly["description"] = assembly.get("assemblyType") + return assemblies + + # need to refactor this part to ensure the data integrity + reformatted_envelope_data = { + "agWall": fill_empty_description(envelope_data["agWall"]), + "roof": fill_empty_description(envelope_data["roof"]), + "skylight": fill_empty_description(envelope_data["skylight"]), + "window": fill_empty_description(envelope_data["window"]), + "door": fill_empty_description(envelope_data["door"]), + "floor": fill_empty_description(envelope_data["floor"]) + } + assemblie_uvalue = self._service.assemblies_uvalue(reformatted_envelope_data, energy_code) + return assemblie_uvalue + def start_run_simulation( self, project: ComBuilding, project_id: Optional[int] = None ) -> str: @@ -268,7 +300,11 @@ def start_run_simulation( if project_id: logger.info("Updating project: %s", project_id) - self.update_project(str(project_id), project) + project = self.update_project(str(project_id), project) + else: + # update assemblies uvalue in the project + assemblie_uvalue = self.assemblie_uvalues(project) + # Need to glue this back to the assemblies in the project before dump for simulation project_data = project.model_dump(mode="json", exclude_unset=True) run_result = self._service.start_run_simulation(project_data) From c9593bc3ceea25d9f71c7c136723f3af70357de1 Mon Sep 17 00:00:00 2001 From: weilixu Date: Sat, 27 Jun 2026 10:16:50 -0700 Subject: [PATCH 2/2] add glue code to update u factors --- comcheck_api/client/comcheck_client.py | 30 ++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/comcheck_api/client/comcheck_client.py b/comcheck_api/client/comcheck_client.py index 69e02e6..eec566f 100644 --- a/comcheck_api/client/comcheck_client.py +++ b/comcheck_api/client/comcheck_client.py @@ -264,6 +264,11 @@ def fill_empty_description(assemblies: list[dict]) -> list[dict]: assembly["description"] = assembly.get("assemblyType") return assemblies + def transform_floor(floors: list[dict]) -> list[dict]: + for floor in floors: + floor.pop('slabFullInsulBelowMinRValue', None) + return floors + # need to refactor this part to ensure the data integrity reformatted_envelope_data = { "agWall": fill_empty_description(envelope_data["agWall"]), @@ -271,10 +276,10 @@ def fill_empty_description(assemblies: list[dict]) -> list[dict]: "skylight": fill_empty_description(envelope_data["skylight"]), "window": fill_empty_description(envelope_data["window"]), "door": fill_empty_description(envelope_data["door"]), - "floor": fill_empty_description(envelope_data["floor"]) + "floor": transform_floor(fill_empty_description(envelope_data["floor"])) } assemblie_uvalue = self._service.assemblies_uvalue(reformatted_envelope_data, energy_code) - return assemblie_uvalue + return assemblie_uvalue["data"] def start_run_simulation( self, project: ComBuilding, project_id: Optional[int] = None @@ -298,13 +303,30 @@ def start_run_simulation( """ logger = logging.getLogger(__name__) + project_data = None if project_id: logger.info("Updating project: %s", project_id) project = self.update_project(str(project_id), project) else: # update assemblies uvalue in the project - assemblie_uvalue = self.assemblie_uvalues(project) - # Need to glue this back to the assemblies in the project before dump for simulation + updated_assembly_uvalues = self.assemblie_uvalues(project) + # still missing + ag_Walls = project.envelope.agWall + roofs = project.envelope.roof + floors = project.envelope.floor + for wall in ag_Walls: + for uvalue in updated_assembly_uvalues.get("agWall", []): + if wall.assemblyType == uvalue["description"]: + wall.effectiveUFactor = float(uvalue["propUValue"]) + wall.propUValue = float(uvalue["propUValue"]) + for roof in roofs: + for uvalue in updated_assembly_uvalues.get("roof", []): + if roof.assemblyType == uvalue["description"]: + roof.propUValue = float(uvalue["propUValue"]) + for floor in floors: + for uvalue in updated_assembly_uvalues.get("floor", []): + if floor.assemblyType == uvalue["description"]: + floor.propUValue = float(uvalue["propUValue"]) project_data = project.model_dump(mode="json", exclude_unset=True) run_result = self._service.start_run_simulation(project_data)