mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
feat(modelling): solid-wall generator offers IWI-only for timber frame
Slice 2b. Timber frame (wall_construction=5) takes internal wall insulation but not external (not constructable — ADR-0019), so the generator offers IWI only. Cascade pin: the IWI Option reproduces the re-lodged timber-frame after at abs(diff) <= 1e-4 (general Table 6 insulation-thickness bucket, not the solid- brick documentary path). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1c7997c471
commit
ac78771258
4 changed files with 28 additions and 3 deletions
|
|
@ -29,8 +29,9 @@ from repositories.product.product_repository import ProductRepository
|
|||
_EXTERNAL_MEASURE_TYPE: Final[str] = "external_wall_insulation"
|
||||
_INTERNAL_MEASURE_TYPE: Final[str] = "internal_wall_insulation"
|
||||
|
||||
# RdSAP `wall_construction` code for solid brick (consistent across paths).
|
||||
# RdSAP `wall_construction` codes (consistent across paths for 1-5).
|
||||
_WALL_SOLID_BRICK: Final[int] = 3
|
||||
_WALL_TIMBER_FRAME: Final[int] = 5
|
||||
# `wall_insulation_type`: 4 = as-built / assumed (uninsulated) — the trigger.
|
||||
_WALL_AS_BUILT: Final[int] = 4
|
||||
# `wall_insulation_type` the overlay lodges: 1 = external, 3 = internal.
|
||||
|
|
@ -41,10 +42,11 @@ _WALL_INSULATION_INTERNAL: Final[int] = 3
|
|||
_SOLID_WALL_INSULATION_MM: Final[int] = 100
|
||||
|
||||
# Which solid-wall Options each construction can take (ADR-0019). Solid brick
|
||||
# takes both; timber-frame (IWI only), system-built, and the breathable
|
||||
# cob/stone exclusions land in later slices.
|
||||
# takes both; timber-frame takes IWI only (EWI not constructable). System-built
|
||||
# and the breathable cob/stone exclusions land in a later slice.
|
||||
_CONSTRUCTABLE_OPTIONS: Final[dict[int, tuple[str, ...]]] = {
|
||||
_WALL_SOLID_BRICK: (_EXTERNAL_MEASURE_TYPE, _INTERNAL_MEASURE_TYPE),
|
||||
_WALL_TIMBER_FRAME: (_INTERNAL_MEASURE_TYPE,),
|
||||
}
|
||||
|
||||
_INSULATION_TYPE: Final[dict[str, int]] = {
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -171,6 +171,29 @@ def test_solid_brick_generator_offers_ewi_and_iwi_each_pinning_its_after() -> No
|
|||
)
|
||||
|
||||
|
||||
def test_timber_frame_generator_offers_iwi_only_pinning_its_after() -> None:
|
||||
# Arrange — timber frame takes IWI but EWI is not constructable (ADR-0019).
|
||||
before: EpcPropertyData = parse_recommendation_summary(
|
||||
"timber_frame_iwi_001431_before.pdf"
|
||||
)
|
||||
iwi_after: EpcPropertyData = parse_recommendation_summary(
|
||||
"timber_frame_iwi_001431_after.pdf"
|
||||
)
|
||||
|
||||
# Act
|
||||
recommendation: Recommendation | None = recommend_solid_wall(before, _AnyProduct())
|
||||
assert recommendation is not None
|
||||
options: dict[str, MeasureOption] = {
|
||||
option.measure_type: option for option in recommendation.options
|
||||
}
|
||||
|
||||
# Assert — IWI only, and it reproduces the re-lodged after.
|
||||
assert set(options) == {"internal_wall_insulation"}
|
||||
_assert_overlay_reproduces_after(
|
||||
before, iwi_after, options["internal_wall_insulation"].overlay
|
||||
)
|
||||
|
||||
|
||||
def test_loft_overlay_reproduces_the_relodged_after() -> None:
|
||||
# Arrange
|
||||
before: EpcPropertyData = parse_recommendation_summary(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue