def from_data(cls, wall_code: element.Element) -> 'WallCode': structure_type_english = wall_code.findtext( 'Layers/StructureType/English') structure_type_french = wall_code.findtext( 'Layers/StructureType/French') component_type_size_english = wall_code.findtext( 'Layers/ComponentTypeSize/English') component_type_size_french = wall_code.findtext( 'Layers/ComponentTypeSize/French') try: return WallCode(identifier=wall_code.get('@id', str), label=wall_code.get_text('Label'), tags={ WallCodeTag.STRUCTURE_TYPE: bilingual.Bilingual( english=structure_type_english, french=structure_type_french, ) if structure_type_english and structure_type_french else None, WallCodeTag.COMPONENT_TYPE_SIZE: bilingual.Bilingual( english=component_type_size_english, french=component_type_size_french, ) if component_type_size_english and component_type_size_french else None, }) except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError( WallCode, 'Unable to get identifier attributes') from exc
def from_data(cls, node: element.Element) -> 'Heating': try: label = node.get_text('Label') efficiency = node.get('Type1/*/Specifications/@efficiency', float) except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError( Heating, 'Invalid/missing Heating values') from exc heating_type = cls._get_heating_type(node) output_size = cls._get_output_size(node) if heating_type is HeatingType.BASEBOARD: steady_state = 'Steady State' energy_source = EnergySource.ELECTRIC equipment_type = cls._HEATING_TYPE_TRANSLATIONS[ HeatingType.BASEBOARD] else: steady_state = cls._get_steady_state(node) energy_source = cls._get_energy_source(node) equipment_type = cls._get_equipment_type(node) return Heating( label=label, output_size=output_size, efficiency=efficiency, steady_state=steady_state, heating_type=heating_type, energy_source=energy_source, equipment_type=equipment_type, )
def from_data(cls, door: element.Element) -> 'Door': try: return Door( label=door.get_text('Label'), door_type=bilingual.Bilingual( english=door.get_text('Construction/Type/English'), french=door.get_text('Construction/Type/French'), ), door_insulation=insulation.Insulation( door.get('Construction/Type/@value', float)), height=distance.Distance( door.get('Measurements/@height', float)), width=distance.Distance(door.get('Measurements/@width', float)), ) except (ElementGetValueError) as exc: raise InvalidEmbeddedDataTypeError(Door) from exc
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 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, water_heating: element.Element) -> 'WaterHeating': drain_water_efficiency: typing.Optional[float] = None if water_heating.get('@hasDrainWaterHeatRecovery', str) == 'true': drain_water_efficiency = water_heating.get( 'DrainWaterHeatRecovery/@effectivenessAt9.5', float) try: energy_type = water_heating.get_text('EnergySource/English') tank_type = water_heating.get_text('TankType/English') water_heater_type = cls._TYPE_MAP[(energy_type.lower(), tank_type.lower())] volume = water_heating.get('TankVolume/@value', float) except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError( WaterHeating, 'Missing/invalid attribue or text') from exc except KeyError as exc: raise InvalidEmbeddedDataTypeError( WaterHeating, 'Invlaid energy and tank type combination') from exc efficiency_ef_node = water_heating.xpath('EnergyFactor/@value') efficiency_percent_node = water_heating.xpath( 'EnergyFactor/@thermalEfficiency') if not efficiency_ef_node and not efficiency_percent_node: raise InvalidEmbeddedDataTypeError(WaterHeating, 'No efficiency values') return WaterHeating( water_heater_type=water_heater_type, tank_volume=volume, efficiency_ef=float(efficiency_ef_node[0]) if efficiency_ef_node else None, efficiency_percentage=float(efficiency_percent_node[0]) if efficiency_percent_node else None, drain_water_heat_recovery_efficiency_percentage= drain_water_efficiency, )
def from_data(cls, basement: element.Element) -> 'Basement': foundation_type = cls._derive_foundation_type(basement.tag) if foundation_type is FoundationType.UNKNOWN: raise InvalidEmbeddedDataTypeError(Basement, f'Invalid foundation type: {basement.tag}') if foundation_type is FoundationType.BASEMENT: floor_from_data = BasementFloor.from_basement wall_from_data = BasementWall.from_basement header_from_data = BasementHeader.from_data elif foundation_type is FoundationType.CRAWLSPACE: floor_from_data = BasementFloor.from_crawlspace wall_from_data = BasementWall.from_crawlspace header_from_data = BasementHeader.from_data else: floor_from_data = BasementFloor.from_slab wall_from_data = lambda *args: [] header_from_data = lambda *args: None floor_nodes = basement.xpath('Floor') header_nodes = basement.xpath('Components/FloorHeader') wall_nodes = basement.xpath('Wall') floors = floor_from_data(floor_nodes[0] if floor_nodes else None) walls = wall_from_data(wall_nodes[0], floors[0].perimeter.metres) if wall_nodes else [] header = header_from_data(header_nodes[0]) if header_nodes else None try: configuration_type = basement.get('Configuration/@type', str) label = basement.get_text('Label') except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError(Basement, 'Missing/invalid foundation attributes') from exc if not configuration_type: raise InvalidEmbeddedDataTypeError(Basement, 'Empty configuration type') return Basement( foundation_type=foundation_type, label=label, configuration_type=configuration_type, walls=walls, floors=floors, header=header, )
def from_data(cls, wall: element.Element, wall_codes: typing.Dict[str, code.WallCode]) -> 'Wall': code_id = wall.xpath('Construction/Type/@idref') wall_code = wall_codes[code_id[0]] if code_id else None try: return Wall( label=wall.get_text('Label'), wall_code=wall_code, nominal_insulation=insulation.Insulation( wall.get('Construction/Type/@nominalInsulation', float)), effective_insulation=insulation.Insulation( wall.get('Construction/Type/@rValue', float)), perimeter=distance.Distance( wall.get('Measurements/@perimeter', float)), height=distance.Distance( wall.get('Measurements/@height', float)), ) except (ElementGetValueError) as exc: raise InvalidEmbeddedDataTypeError(Wall) from exc
def from_data(cls, window: element.Element, window_codes: typing.Dict[str, code.WindowCode]) -> 'Window': code_id = window.xpath('Construction/Type/@idref') window_code = window_codes[code_id[0]] if code_id else None try: return Window( label=window.get_text('Label'), window_code=window_code, window_insulation=insulation.Insulation( window.get('Construction/Type/@rValue', float)), width=distance.Distance( window.get('Measurements/@width', float) / _MILLIMETRES_TO_METRES), height=distance.Distance( window.get('Measurements/@height', float) / _MILLIMETRES_TO_METRES), ) except (ElementGetValueError) as exc: raise InvalidEmbeddedDataTypeError(Window) from exc
def _get_equipment_type(cls, node: element.Element) -> bilingual.Bilingual: english_text = node.get_text('Type1/*/Equipment/EquipmentType/English') french_text = node.get_text('Type1/*/Equipment/EquipmentType/French') return bilingual.Bilingual(english=english_text, french=french_text)
def from_data(cls, window_code: element.Element) -> 'WindowCode': glazing_type_english = window_code.findtext( 'Layers/GlazingTypes/English') glazing_type_french = window_code.findtext( 'Layers/GlazingTypes/French') coating_tint_english = window_code.findtext( 'Layers/CoatingsTints/English') coating_tint_french = window_code.findtext( 'Layers/CoatingsTints/French') fill_type_english = window_code.findtext('Layers/FillType/English') fill_type_french = window_code.findtext('Layers/FillType/French') spacer_type_english = window_code.findtext('Layers/SpacerType/English') spacer_type_french = window_code.findtext('Layers/SpacerType/French') window_code_type_english = window_code.findtext('Layers/Type/English') window_code_type_french = window_code.findtext('Layers/Type/French') frame_material_english = window_code.findtext( 'Layers/FrameMaterial/English') frame_material_french = window_code.findtext( 'Layers/FrameMaterial/French') try: return WindowCode( identifier=window_code.get('@id', str), label=window_code.get_text('Label'), tags={ WindowCodeTag.GLAZING_TYPE: bilingual.Bilingual( english=glazing_type_english, french=glazing_type_french, ) if glazing_type_english and glazing_type_french else None, WindowCodeTag.COATING_TINTS: bilingual.Bilingual( english=coating_tint_english, french=coating_tint_french, ) if coating_tint_english and coating_tint_french else None, WindowCodeTag.FILL_TYPE: bilingual.Bilingual( english=fill_type_english, french=fill_type_french, ) if fill_type_english and fill_type_french else None, WindowCodeTag.SPACER_TYPE: bilingual.Bilingual( english=spacer_type_english, french=spacer_type_french, ) if spacer_type_english and spacer_type_french else None, WindowCodeTag.CODE_TYPE: bilingual.Bilingual( english=window_code_type_english, french=window_code_type_french, ) if window_code_type_english and window_code_type_french else None, WindowCodeTag.FRAME_MATERIAL: bilingual.Bilingual( english=frame_material_english, french=frame_material_french, ) if frame_material_english and frame_material_french else None, }) except ElementGetValueError as exc: raise InvalidEmbeddedDataTypeError( WindowCode, 'Unable to get identifier attributes') from exc
def test_get_text_raises_when_not_found( fragment_node: element.Element) -> None: with pytest.raises(ElementGetValueError): fragment_node.get_text('Baz')
def test_get_text(fragment_node: element.Element) -> None: assert fragment_node.get_text('Bar') == 'baz'