def sample_basement_walls() -> typing.List[basement.BasementWall]: return [ basement.BasementWall( wall_type=basement.WallType.INTERIOR, nominal_insulation=insulation.Insulation(rsi=1.3), effective_insulation=insulation.Insulation(rsi=1.2), composite_percentage=50.0, wall_area=area.Area(9.7536)), basement.BasementWall( wall_type=basement.WallType.INTERIOR, nominal_insulation=insulation.Insulation(rsi=1.7), effective_insulation=insulation.Insulation(rsi=1.5), composite_percentage=50.0, wall_area=area.Area(9.7536)), basement.BasementWall( wall_type=basement.WallType.EXTERIOR, nominal_insulation=insulation.Insulation(rsi=0.0), effective_insulation=insulation.Insulation(rsi=0.0), composite_percentage=100.0, wall_area=area.Area(19.5072)), basement.BasementWall( wall_type=basement.WallType.PONY, nominal_insulation=insulation.Insulation(rsi=0.0), effective_insulation=insulation.Insulation(rsi=0.0), composite_percentage=100.0, wall_area=area.Area(7.3152)), ]
def from_data(cls, heated_floor_area: element.Element) -> 'HeatedFloorArea': try: return HeatedFloorArea( area_above_grade=area.Area( float(heated_floor_area.attrib['aboveGrade'])), area_below_grade=area.Area( float(heated_floor_area.attrib['belowGrade'])), ) except (KeyError, ValueError) as exc: raise InvalidEmbeddedDataTypeError(HeatedFloorArea) from exc
def sample() -> floor.Floor: return floor.Floor( label='Rm over garage', nominal_insulation=insulation.Insulation(2.46), effective_insulation=insulation.Insulation(2.9181), floor_area=area.Area(9.2903), floor_length=distance.Distance(3.048), )
def sample_crawlspace_walls() -> typing.List[basement.BasementWall]: return [ basement.BasementWall( wall_type=basement.WallType.NOT_APPLICABLE, nominal_insulation=insulation.Insulation(rsi=1.432), effective_insulation=insulation.Insulation(rsi=1.7968), composite_percentage=100.0, wall_area=area.Area(21.333012959999998)) ]
def sample() -> ceiling.Ceiling: return ceiling.Ceiling( label='Main attic', ceiling_type=bilingual.Bilingual(english='Attic/gable', french='Combles/pignon'), nominal_insulation=insulation.Insulation(2.864), effective_insulation=insulation.Insulation(2.9463), ceiling_area=area.Area(46.4515), ceiling_length=distance.Distance(23.875), )
def from_data(cls, floor: element.Element) -> 'Floor': try: return Floor( label=floor.get_text('Label'), nominal_insulation=insulation.Insulation(floor.get('Construction/Type/@nominalInsulation', float)), effective_insulation=insulation.Insulation(floor.get('Construction/Type/@rValue', float)), floor_area=area.Area(floor.get('Measurements/@area', float)), floor_length=distance.Distance(floor.get('Measurements/@length', float)), ) except (ElementGetValueError) as exc: raise InvalidEmbeddedDataTypeError(Floor) from exc
def _empty_floor(cls, floor_type: FloorType) -> 'BasementFloor': return BasementFloor( floor_type=floor_type, rectangular=False, nominal_insulation=None, effective_insulation=None, length=None, width=None, perimeter=distance.Distance(0.0), floor_area=area.Area(0.0), )
def sample_basement_floors() -> typing.List[basement.BasementFloor]: return [ basement.BasementFloor( floor_type=basement.FloorType.SLAB, rectangular=True, nominal_insulation=insulation.Insulation(rsi=0.2), effective_insulation=insulation.Insulation(rsi=0.1), length=distance.Distance(distance_metres=2.0), width=distance.Distance(distance_metres=2.0), perimeter=distance.Distance(distance_metres=8.0), floor_area=area.Area(4.0)) ]
def sample_slab_floors() -> typing.List[basement.BasementFloor]: return [ basement.BasementFloor( floor_type=basement.FloorType.SLAB, rectangular=True, nominal_insulation=None, effective_insulation=None, width=distance.Distance(distance_metres=3.048), length=distance.Distance(distance_metres=6.096), perimeter=distance.Distance(distance_metres=18.288), floor_area=area.Area(18.580608)) ]
def sample_crawlspace_floors() -> typing.List[basement.BasementFloor]: return [ basement.BasementFloor( floor_type=basement.FloorType.SLAB, rectangular=True, nominal_insulation=None, effective_insulation=None, width=distance.Distance(distance_metres=4.9987), length=distance.Distance(distance_metres=4.9999), perimeter=distance.Distance(distance_metres=19.9972), floor_area=area.Area(24.993000130000002)), basement.BasementFloor( floor_type=basement.FloorType.FLOOR_ABOVE_CRAWLSPACE, rectangular=True, nominal_insulation=insulation.Insulation(rsi=0.0), effective_insulation=insulation.Insulation(rsi=0.468), width=distance.Distance(distance_metres=4.9987), length=distance.Distance(distance_metres=4.9999), perimeter=distance.Distance(distance_metres=19.9972), floor_area=area.Area(24.993000130000002)) ]
def _from_data(cls, floor: element.Element, construction_type: str, floor_type: FloorType) -> 'BasementFloor': length: typing.Optional[float] = None width: typing.Optional[float] = None try: rectangular = floor.get('Measurements/@isRectangular', str) == 'true' if rectangular: length = floor.get('Measurements/@length', float) width = floor.get('Measurements/@width', float) perimeter = (2 * length) + (2 * width) floor_area = length * width else: floor_area = floor.get('Measurements/@area', float) perimeter = floor.get('Measurements/@perimeter', float) nominal_insulation_node = floor.xpath(f'Construction/{construction_type}/@nominalInsulation') effective_insulation_node = floor.xpath(f'Construction/{construction_type}/@rValue') nominal_insulation = float(nominal_insulation_node[0]) if nominal_insulation_node else None effective_insulation = float(effective_insulation_node[0]) if effective_insulation_node else None except ValueError as exc: raise InvalidEmbeddedDataTypeError(BasementFloor, 'Invalid insulation attribute values') from exc except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError(BasementFloor, 'Invalid attributes') from exc return BasementFloor( floor_type=floor_type, rectangular=rectangular, nominal_insulation=insulation.Insulation(nominal_insulation) if nominal_insulation is not None else None, effective_insulation=insulation.Insulation(effective_insulation) if effective_insulation is not None else None, length=distance.Distance(length) if length is not None else None, width=distance.Distance(width) if width is not None else None, perimeter=distance.Distance(perimeter), floor_area=area.Area(floor_area), )
def from_data(cls, ceiling: element.Element) -> 'Ceiling': try: return Ceiling( label=ceiling.get_text('Label'), ceiling_type=bilingual.Bilingual( english=ceiling.get_text('Construction/Type/English'), french=ceiling.get_text('Construction/Type/French'), ), nominal_insulation=insulation.Insulation( ceiling.get('Construction/CeilingType/@nominalInsulation', float)), effective_insulation=insulation.Insulation( ceiling.get('Construction/CeilingType/@rValue', float)), ceiling_area=area.Area(ceiling.get('Measurements/@area', float)), ceiling_length=distance.Distance( ceiling.get('Measurements/@length', float)), ) except (ElementGetValueError) as exc: raise InvalidEmbeddedDataTypeError(Ceiling) from exc
def _from_data(cls, wall: element.Element, wall_perimeter: float, wall_height: float, tag: WallType, backup_percentage: float) -> 'BasementWall': maybe_percentage = wall.attrib.get('percentage') percentage = float(maybe_percentage) if maybe_percentage else backup_percentage try: nominal_insulation = wall.get('@nominalRsi', float) effective_insulation = wall.get('@rsi', float) except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError(BasementWall, 'Invalid insulation attributes') from exc return BasementWall( wall_type=tag, nominal_insulation=insulation.Insulation(nominal_insulation), effective_insulation=insulation.Insulation(effective_insulation), composite_percentage=percentage, wall_area=area.Area(wall_perimeter * wall_height * (percentage / 100)) )
def _door_area(self) -> area.Area: return area.Area(self.height.metres * self.width.metres)
def _wall_area(self) -> area.Area: return area.Area(self.perimeter.metres * self.height.metres)
def test_equality() -> None: version1 = area.Area(1) version2 = area.Area(1) assert version1 == version2
def test_area() -> None: output = area.Area(1) assert output.square_metres == 1.0 assert output.square_feet == pytest.approx(10.763911)
def test_from_row(self, sample_input_d: typing.Dict[str, typing.Any]) -> None: output = dwelling.ParsedDwellingDataRow.from_row(sample_input_d) wall_code = code.WallCode( identifier='Code 1', label='1201101121', tags={ code.WallCodeTag.STRUCTURE_TYPE: bilingual.Bilingual( english='Wood frame', french='Ossature de bois', ), code.WallCodeTag.COMPONENT_TYPE_SIZE: bilingual.Bilingual( english='38x89 mm (2x4 in)', french='38x89 (2x4)', ) }, ) window_code = code.WindowCode( identifier='Code 12', label='234002', tags={ code.WindowCodeTag.GLAZING_TYPE: bilingual.Bilingual( english='Double/double with 1 coat', french='Double/double, 1 couche', ), code.WindowCodeTag.COATING_TINTS: bilingual.Bilingual(english='Low-E .20 (hard1)', french='Faible E .20 (Dur 1)'), code.WindowCodeTag.FILL_TYPE: bilingual.Bilingual(english='9 mm Argon', french="9 mm d'argon"), code.WindowCodeTag.SPACER_TYPE: bilingual.Bilingual(english='Metal', french='Métal'), code.WindowCodeTag.CODE_TYPE: bilingual.Bilingual(english='Picture', french='Fixe'), code.WindowCodeTag.FRAME_MATERIAL: bilingual.Bilingual(english='Wood', french='Bois'), }) assert output == dwelling.ParsedDwellingDataRow( eval_id=123, eval_type=dwelling.EvaluationType.PRE_RETROFIT, entry_date=datetime.date(2018, 1, 1), creation_date=datetime.datetime(2018, 1, 8, 9), modification_date=datetime.datetime(2018, 6, 1, 9), year_built=2000, city='Ottawa', region=dwelling.Region.ONTARIO, forward_sortation_area='K1P', ers_rating=567, file_id='4K13D01404', ceilings=[ ceiling.Ceiling( label='Main attic', ceiling_type=bilingual.Bilingual(english='Attic/gable', french='Combles/pignon'), nominal_insulation=insulation.Insulation(2.864), effective_insulation=insulation.Insulation(2.9463), ceiling_area=area.Area(46.4515), ceiling_length=distance.Distance(23.875), ) ], floors=[ floor.Floor( label='Rm over garage', nominal_insulation=insulation.Insulation(2.46), effective_insulation=insulation.Insulation(2.9181), floor_area=area.Area(9.2903), floor_length=distance.Distance(3.048), ) ], walls=[ wall.Wall( label='Second level', wall_code=wall_code, nominal_insulation=insulation.Insulation(1.432), effective_insulation=insulation.Insulation(1.8016), perimeter=distance.Distance(42.9768), height=distance.Distance(2.4384), ) ], doors=[ door.Door( label='Front door', door_type=bilingual.Bilingual(english='Solid wood', french='Bois massif'), door_insulation=insulation.Insulation(0.39), height=distance.Distance(1.9799), width=distance.Distance(0.8499), ) ], windows=[ window.Window( label='East0001', window_code=window_code, window_insulation=insulation.Insulation(0.4779), width=distance.Distance(1.967738), height=distance.Distance(1.3220699), ) ], heated_floor=heated_floor_area.HeatedFloorArea( area_above_grade=area.Area(92.9), area_below_grade=area.Area(185.8), ), ventilations=[ ventilation.Ventilation( ventilation_type=ventilation.VentilationType. NOT_ENERGY_STAR_NOT_INSTITUTE_CERTIFIED, air_flow_rate=220.0, efficiency=55.0, ) ], water_heatings=[ water_heating.WaterHeating( water_heater_type=water_heating.WaterHeaterType. ELECTRICITY_CONVENTIONAL_TANK, tank_volume=189.3001, efficiency_ef=0.8217, efficiency_percentage=None, drain_water_heat_recovery_efficiency_percentage=None, ) ], heating_system=heating.Heating( heating_type=heating.HeatingType.FURNACE, energy_source=heating.EnergySource.NATURAL_GAS, equipment_type=bilingual.Bilingual( english='Furnace w/ continuous pilot', french='Fournaise avec veilleuse permanente'), label='Heating/Cooling System', output_size=0.009671344275824395, efficiency=78.0, steady_state='Steady State', ), foundations=[ basement.Basement( foundation_type=basement.FoundationType.BASEMENT, label='Basement', configuration_type='BCCB', walls=[ basement.BasementWall( wall_type=basement.WallType.INTERIOR, nominal_insulation=insulation.Insulation( rsi=1.432), effective_insulation=insulation.Insulation( rsi=1.4603), composite_percentage=100.0, wall_area=area.Area(97.36458048)) ], floors=[ basement.BasementFloor( floor_type=basement.FloorType.SLAB, rectangular=False, nominal_insulation=insulation.Insulation(rsi=0.0), effective_insulation=insulation.Insulation( rsi=0.0), length=None, width=None, perimeter=distance.Distance( distance_metres=39.9297), floor_area=area.Area(92.903)) ], header=basement.BasementHeader( nominal_insulation=insulation.Insulation(rsi=3.87), effective_insulation=insulation.Insulation(rsi=4.0777), height=distance.Distance(distance_metres=0.23), perimeter=distance.Distance(distance_metres=39.9288)), ), basement.Basement( foundation_type=basement.FoundationType.CRAWLSPACE, label='Crawl', configuration_type='SCN', walls=[ basement.BasementWall( wall_type=basement.WallType.NOT_APPLICABLE, nominal_insulation=insulation.Insulation( rsi=1.432), effective_insulation=insulation.Insulation( rsi=1.7968), composite_percentage=100.0, wall_area=area.Area(21.333012959999998)) ], floors=[ basement.BasementFloor( floor_type=basement.FloorType.SLAB, rectangular=True, nominal_insulation=None, effective_insulation=None, width=distance.Distance(distance_metres=4.9987), length=distance.Distance(distance_metres=4.9999), perimeter=distance.Distance( distance_metres=19.9972), floor_area=area.Area(24.993000130000002)), basement.BasementFloor( floor_type=basement.FloorType. FLOOR_ABOVE_CRAWLSPACE, rectangular=True, nominal_insulation=insulation.Insulation(rsi=0.0), effective_insulation=insulation.Insulation( rsi=0.468), width=distance.Distance(distance_metres=4.9987), length=distance.Distance(distance_metres=4.9999), perimeter=distance.Distance( distance_metres=19.9972), floor_area=area.Area(24.993000130000002)) ], header=None, ), basement.Basement( foundation_type=basement.FoundationType.SLAB, label='Slab', configuration_type='SCN', walls=[], floors=[ basement.BasementFloor( floor_type=basement.FloorType.SLAB, rectangular=True, nominal_insulation=None, effective_insulation=None, width=distance.Distance(distance_metres=3.048), length=distance.Distance(distance_metres=6.096), perimeter=distance.Distance( distance_metres=18.288), floor_area=area.Area(18.580608)) ], header=None, ), ], energy_upgrades=[ upgrade.Upgrade( upgrade_type='Ceilings', cost=0, priority=12, ), upgrade.Upgrade( upgrade_type='MainWalls', cost=1, priority=2, ), upgrade.Upgrade( upgrade_type='Foundation', cost=2, priority=3, ), ])
def _window_area(self) -> area.Area: return area.Area(self.width.metres * self.height.metres)