Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion comcheck_api/ai/skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ print(result["performanceRating"])
offer building-area / envelope / lighting / mechanical / renewable / credits / simulation instead.
`comcheck_api.list_operations()` enumerates the `building_area`,
`envelope`, `interior_lighting`, `exterior_lighting`, `mechanical`,
`renewable`, and `credits` groups.
`credits`, and `renewable` groups.

## Common patterns

Expand Down
6 changes: 4 additions & 2 deletions comcheck_api/api/api_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def update_project(
self._handle_api_error(error)

def assemblies_uvalue(
self, envelope_data: Dict[str, Any], energy_code
self, envelope_data: Dict[str, Any], energy_code: str
) -> Dict[str, Any]:
"""get assemblies u values

Expand Down Expand Up @@ -672,7 +672,9 @@ def fan_maximum_allowable_hp(
"""Calculate maximum allowable horsepower for a fan.

Args:
fan_data: Fan data
fan_data: A single object with ``designBrakeHp`` and ``brakeHp``.
Both keys are required; the endpoint returns a server error
if ``brakeHp`` is absent or if a list is sent.
energy_code: The energy code for the endpoint path

Returns:
Expand Down
1,028 changes: 545 additions & 483 deletions comcheck_api/client/comcheck_client.py

Large diffs are not rendered by default.

64 changes: 43 additions & 21 deletions comcheck_api/defaults.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Module for project default templates/values."""

import copy
from typing import NoReturn
from uuid import uuid4

from comcheck_api.constants.building_area_constants import DEFAULT_BUILDING_AREA
Expand Down Expand Up @@ -34,11 +35,32 @@
)

from comcheck_api.constants.common_constants import PROJECT_TEMPLATE
from comcheck_api.types.common_types import ExteriorArea, InteriorSpace
from comcheck_api.types.core_types import (
AgWall,
BgWall,
ComBuilding,
Door,
Fan,
FanSystem,
Fixture,
Floor,
HVACPlant,
HVACSystem,
OffsiteRenewableProcurement,
RenewableSystem,
Roof,
ServiceWaterHeatingSystem,
Skylight,
ThermalBridge,
WholeBldgUse,
Window,
)

# from comcheck_api.constants.lighting_constants import DEFAULT_FIXTURE_SCHEDULE


def get_default_project_template():
def get_default_project_template() -> ComBuilding:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.ComBuilding` template.

The template is pre-populated with sensible defaults for location
Expand All @@ -50,7 +72,7 @@ def get_default_project_template():
return copy.deepcopy(PROJECT_TEMPLATE)


def get_default_building_area_template():
def get_default_building_area_template() -> WholeBldgUse:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.WholeBldgUse` template.

Defaults to an *Automotive Facility* with 1 000 sq ft floor area and
Expand All @@ -68,7 +90,7 @@ def get_default_building_area_template():
return area


def get_default_roof_template():
def get_default_roof_template() -> Roof:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.Roof` template.

Defaults to an above-deck roof with 6 000 sq ft gross area and
Expand All @@ -80,7 +102,7 @@ def get_default_roof_template():
return copy.deepcopy(DEFAULT_ROOF)


def get_default_ag_wall_template():
def get_default_ag_wall_template() -> AgWall:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.AgWall` template.

Defaults to a metal-frame 24-inch above-grade wall with 4 800 sq ft
Expand All @@ -92,7 +114,7 @@ def get_default_ag_wall_template():
return copy.deepcopy(DEFAULT_AG_WALL)


def get_default_floor_template():
def get_default_floor_template() -> Floor:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.Floor` template.

Defaults to a heated slab-on-grade floor with 320 sq ft gross area
Expand All @@ -104,7 +126,7 @@ def get_default_floor_template():
return copy.deepcopy(DEFAULT_FLOOR)


def get_default_bg_wall_template():
def get_default_bg_wall_template() -> BgWall:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.BgWall` template.

Defaults to a concrete below-grade wall with 3 000 sq ft gross area,
Expand All @@ -116,7 +138,7 @@ def get_default_bg_wall_template():
return copy.deepcopy(DEFAULT_BG_WALL)


def get_default_skylight_template():
def get_default_skylight_template() -> Skylight:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.Skylight` template.

Defaults to a no-curb, double-pane low-E skylight with 100 sq ft
Expand All @@ -128,7 +150,7 @@ def get_default_skylight_template():
return copy.deepcopy(DEFAULT_SKYLIGHT)


def get_default_window_template():
def get_default_window_template() -> Window:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.Window` template.

Defaults to a triple-pane, non-operable, metal-frame window with
Expand All @@ -140,7 +162,7 @@ def get_default_window_template():
return copy.deepcopy(DEFAULT_WINDOW)


def get_default_door_template():
def get_default_door_template() -> Door:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.Door` template.

Defaults to a swinging, insulated metal entrance door with 23 sq ft
Expand All @@ -152,7 +174,7 @@ def get_default_door_template():
return copy.deepcopy(DEFAULT_DOOR)


def get_default_thermal_bridge_template():
def get_default_thermal_bridge_template() -> ThermalBridge:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.ThermalBridge` template.

Defaults to a prescriptive linear floor-to-wall intersection thermal
Expand All @@ -164,7 +186,7 @@ def get_default_thermal_bridge_template():
return copy.deepcopy(DEFAULT_THERMAL_BRIDGE)


def get_default_interior_space_template():
def get_default_interior_space_template() -> InteriorSpace:
"""Return a deep copy of the default interior lighting space template.

In the COMcheck API schema, an interior lighting space is represented by
Expand All @@ -182,7 +204,7 @@ def get_default_interior_space_template():
return copy.deepcopy(DEFAULT_INTERIOR_SPACE_AREA)


def get_default_fixture_template():
def get_default_fixture_template() -> Fixture:
"""Return a deep copy of the default :class:`~comcheck_api.types.core_types.Fixture` template.

Defaults to an LED fixture at 32 W, quantity 1, with no lighting controls.
Expand All @@ -193,7 +215,7 @@ def get_default_fixture_template():
return copy.deepcopy(DEFAULT_FIXTURE)


def get_default_exterior_area_template():
def get_default_exterior_area_template() -> ExteriorArea:
"""Return a deep copy of the default exterior lighting area template.

In the COMcheck API schema, an exterior lighting area is represented by
Expand All @@ -210,7 +232,7 @@ def get_default_exterior_area_template():
return copy.deepcopy(DEFAULT_EXTERIOR_AREA)


def get_default_fixture_schedule_template():
def get_default_fixture_schedule_template() -> NoReturn:
"""Return a default fixture schedule template with a unique key.

.. warning::
Expand All @@ -221,7 +243,7 @@ def get_default_fixture_schedule_template():
raise NotImplementedError("DEFAULT_FIXTURE_SCHEDULE constant not yet implemented")


def get_default_renewable_system_template():
def get_default_renewable_system_template() -> RenewableSystem:
"""Return a deep copy of the default renewable system template.

Defaults to a Solar PV system with 0.0 capacity in Watts.
Expand All @@ -232,7 +254,7 @@ def get_default_renewable_system_template():
return copy.deepcopy(DEFAULT_RENEWABLE_SYSTEM)


def get_default_offsite_renewable_procurement_template():
def get_default_offsite_renewable_procurement_template() -> OffsiteRenewableProcurement:
"""Return a deep copy of the default offsite renewable procurement template.

Defaults to an unspecified procurement type with 0.0 kWh annual energy.
Expand All @@ -243,7 +265,7 @@ def get_default_offsite_renewable_procurement_template():
return copy.deepcopy(DEFAULT_OFFSITE_RENEWABLE_PROCUREMENT)


def get_default_hvac_system_template():
def get_default_hvac_system_template() -> HVACSystem:
"""Return a deep copy of the default HVAC system template.

Defaults to an unknown cooling and heating equipment with no economizer,
Expand All @@ -255,7 +277,7 @@ def get_default_hvac_system_template():
return copy.deepcopy(DEFAULT_HVAC_SYSTEM)


def get_default_fan_system_template():
def get_default_fan_system_template() -> FanSystem:
"""Return a deep copy of the default fan system template.

Defaults to motor nameplate HP compliance method with no fans and no
Expand All @@ -267,7 +289,7 @@ def get_default_fan_system_template():
return copy.deepcopy(DEFAULT_FAN_SYSTEM)


def get_default_fan_template():
def get_default_fan_template() -> Fan:
"""Return a deep copy of the default fan template.

Defaults to an unspecified fan type with 0.0 volume and no efficiency data.
Expand All @@ -278,7 +300,7 @@ def get_default_fan_template():
return copy.deepcopy(DEFAULT_FAN)


def get_default_hvac_plant_template():
def get_default_hvac_plant_template() -> HVACPlant:
"""Return a deep copy of the default HVAC plant template.

Defaults to a heating plant with hot water boiler (100 kBtu/hr capacity)
Expand All @@ -290,7 +312,7 @@ def get_default_hvac_plant_template():
return copy.deepcopy(DEFAULT_HVAC_PLANT)


def get_default_water_heater_template():
def get_default_water_heater_template() -> ServiceWaterHeatingSystem:
"""Return a deep copy of the default service water heating system template.

Defaults to a storage water heater with unknown fuel type, 1 quantity,
Expand Down
11 changes: 8 additions & 3 deletions comcheck_api/introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
"interior_lighting": project_interior_lighting_operations,
"exterior_lighting": project_exterior_lighting_operations,
"mechanical": project_mechanical_operations,
"renewable": project_renewable_operations,
"credits": project_credit_operations,
"renewable": project_renewable_operations,
}


Expand All @@ -64,12 +64,14 @@ class FieldSchema(BaseModel):


class EnumMember(BaseModel):
"""One member of an enum: its Python name and its value."""

name: str
value: str


class TypeSchema(BaseModel):
"""Reflected schema of a Pydantic model or StrEnum."""
"""Reflected schema of a Pydantic model or enum."""

name: str
kind: Literal["model", "enum"]
Expand All @@ -82,7 +84,10 @@ def list_operations() -> list[OperationInfo]:
"""Discover public functions in the project operation modules.

Discovered live via :mod:`inspect` so the list always matches the
installed SDK version.
installed SDK version. Groups are returned in the order
``building_area``, ``envelope``, ``interior_lighting``,
``exterior_lighting``, ``mechanical``, ``credits``, ``renewable``.
``COMcheckClient`` methods (API calls) are not included.
"""
out: list[OperationInfo] = []
for group, mod in _OP_MODULES.items():
Expand Down
21 changes: 12 additions & 9 deletions comcheck_api/project_operations/project_envelope_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def add_bg_wall_to_project(
def update_bg_wall_in_project(
project: ComBuilding, bg_wall_assembly_type: str, updates: dict[str, Any] | BgWall
) -> ComBuilding:
"""Update an bgWall in the project's envelope.
"""Update a bgWall in the project's envelope.

Args:
project: The project object to modify
Expand All @@ -225,7 +225,7 @@ def update_bg_wall_in_project(
def remove_bg_wall_from_project(
project: ComBuilding, bg_wall_assembly_type: str
) -> ComBuilding:
"""Remove an bgWall from the envelope in any project object.
"""Remove a bgWall from the envelope in any project object.

Args:
project: The project object to modify
Expand Down Expand Up @@ -275,7 +275,7 @@ def add_floor_to_project(
def update_floor_in_project(
project: ComBuilding, floor_assembly_type: str, updates: dict[str, Any] | Floor
) -> ComBuilding:
"""Update an floor in the project's envelope.
"""Update a floor in the project's envelope.

Args:
project: The project object to modify
Expand All @@ -299,7 +299,7 @@ def update_floor_in_project(
def remove_floor_from_project(
project: ComBuilding, floor_assembly_type: str
) -> ComBuilding:
"""Remove an bgWall from the envelope in any project object.
"""Remove a floor from the envelope in any project object.

Args:
project: The project object to modify
Expand Down Expand Up @@ -378,17 +378,20 @@ def remove_skylight_from_project(
project: ComBuilding,
skylight_assembly_type: str,
) -> ComBuilding:
"""Add a new skylight to a specific roof in the envelope.
"""Remove a skylight from the project.

Looks for the skylight on the roofs, or in the orphaned
``envelope.skylight`` list for alteration projects.

Args:
project: ComBuilding,
skylight_assembly_type: str
project: The project object to modify
skylight_assembly_type: The assemblyType of the skylight to remove

Returns:
Updated project object with the skylight added to the specified roof
Updated project object with the skylight removed

Raises:
ValueError: If buildingAreaKey is not found or if roof's bldgUseKey doesn't match buildingAreaKey
ValueError: If no skylight with the given assemblyType is found
"""
updated_project = project.model_copy(deep=True)

Expand Down
Loading
Loading