survey-extraction/etl/fileReader/sitenotes.py
2025-08-19 12:05:40 +00:00

1602 lines
No EOL
69 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from etl.fileReader.reportType import ReportType
from etl.transform.preSiteNoteTypes import (
CompanyInfo, PreSiteNotesSummaryInfo, AssessorInfo,
PropertyDescription, PropertyDetail, Dimension,
Walls, Roofs, Floors, Door, VentilationAndCooling,
Lighting, WaterHeating, HotWaterCylinder, SolarWaterHeating,
ShowerAndBaths, FlueGasHeatRecoverySystem, PhotovoltaicPanel,
WindTurbine, OtherDetails, Windows, HeatingFromPreSiteNotes, HeatingSystemControls,
HeatingType, Insulation
)
from etl.transform.conditionReportTypes import (
ConditionReportModel, AssessorDetails, InspectionAndProject, TheProperty,
MainElevation, Elevation, ElevationInfo, PropertyAccess, ExternalElevation, ExternalElevationFront,
ExternalElevationGableOne, ExternalElevationGableTwo, ExternalElevationRear, ConservatoryOrOutbuilding,
AccessAndElevations, Hallway, RoomInfo, WindowsInfo, VentilationInfo, LivingRoom, DiningRoom, Kitchen, Rooms,
Utility, WC, Landing, Bedroom, Bathroom, LoftSpace, RoomInRoof, HeatingSystem, GeneralConditionHeatingSystem,
MainHeatingOne, MainHeatingTwo, SecondaryHeating, HeatingByRoom, Renewables, Occupant, EnergyUse, HeatingFromConditionReport, ShowerAndBath, FridgeAndFreezers, Cooker, TumbleDryer,
GeneralInformation, OccupantAssessment
)
from datetime import datetime
from pprint import pprint
class SiteNotesExtractor():
def __init__(self, data_list):
self.raw_data = data_list
def get_x_occurance(self, lst, value, x=1):
try:
return [i for i, v in enumerate(lst) if v == value][x]
except IndexError:
return None # Return None if the value does not occur twice
def get_x_value(self, lst, value, x=1):
index = self.get_x_occurance(lst, value, x)
return lst[index+1]
def get_next_value(self, lst, value, avoid=[]):
get_value = lambda key: None if lst[lst.index(value) + 1] in avoid else lst[lst.index(key) + 1]
return get_value(value)
def get_next_value_greedy(self, lst, value, upto):
index = lst.index(value) + 1
str = ""
for i in range(upto):
str += lst[index+i]
str += " "
return str[:-1]
def two_columns_processor(self, data, sub_titles_to_gather, avoid, indexAdd = 1):
def get_value(key):
try:
index = data.index(key)
value = data[index + indexAdd]
return None if value in avoid else value
except (ValueError, IndexError):
return None
dict_ = {}
for items in data:
if items in avoid:
continue
elif items in sub_titles_to_gather:
dict_.update({f"{items.lower().replace('-', '_').replace(' ','_')}":get_value(items)})
return dict_
def get_data_between(self, a, b):
return self.raw_data[self.raw_data.index(a):self.raw_data.index(b)]
class CSR(SiteNotesExtractor):
def __init__(self, data_list):
super().__init__(data_list)
self.type = ReportType.CHARTED_SURVEYOR_REPORT
self.insulation_info = None
self.setup()
def setup(self):
self.get_materials()
def get_materials(self):
lst = self.get_data_between("Detailed description of existing Cavity Wall Insulation ", "Detailed description of Defects in existing Cavity Wall Insulation")
if len(lst) > 2:
self.insulation_info = Insulation(type=lst[-1])
else:
dict_ = self.two_columns_processor(lst, ["Detailed description of existing Cavity Wall Insulation "], ["Detailed description of Defects in existing Cavity Wall Insulation"])
self.insulation_info = Insulation(
type=dict_.get('detailed_description_of_existing_cavity_wall_insulation_', "")
) if dict_ is not None else None
class ECOConditionReport(SiteNotesExtractor):
def __init__(self, data_list):
super().__init__(data_list)
self.type = ReportType.ECO_CONDITION_REPORT
self.master_obj = self.setup_condition_report()
def setup_condition_report(self):
pass
class WarmHomesConditionReport(SiteNotesExtractor):
def __init__(self, data_list):
super().__init__(data_list)
self.type = ReportType.WARM_HOMES_CONDITION_REPORT
room, heating_system = self.setup_condition_report()
self.master_obj = room, heating_system
def setup_condition_report(self):
# general_information = self.get_section_1()
# access_and_elevations = self.get_section_2()
rooms = self.get_section_3()
heating_system = self.get_section_4()
# occupant_assessment = self.get_section_5()
# site_name, reference_code, address, postcode = self.get_section_0()
return rooms, heating_system
def get_section_0(self):
data = self.get_data_between("Project Site Name", "1. General Information")
site_name = self.get_next_value(data, "Project Site Name")
# reference_code = self.get_next_value(data, "Property Reference Code")
reference_code = "Place holder, please delete me for prod"
address = self.get_next_value(data, "Property Address")
postcode = self.get_data_between("Postcode", "Main Image")[1:]
postcode = " ".join(postcode)
return site_name, reference_code, address, postcode
def get_section_1(self):
assessor_details = self.get_assessor_details()
inspection_and_project = self.get_inspection_and_project()
the_property = self.get_the_property()
main_elevation = self.get_main_elevation()
elevations = self.get_all_elevations()
return GeneralInformation(
assessor_details=assessor_details,
inspection_and_project=inspection_and_project,
the_property=the_property,
main_elevation=main_elevation,
elevations=elevations
)
def get_assessor_details(self):
data = self.get_data_between("1.1 Assessor details","1.2 Inspection & Project")
assessor_name = self.get_next_value(data, "Assessor Name & ID")
# elmhirst_id = self.get_next_value(data, "Property Reference Code")
elmhirst_id = "please remove me in prod"
return AssessorDetails(assessor_name_and_id=assessor_name, elmhurst_id=elmhirst_id)
def get_inspection_and_project(self):
data = self.get_data_between("1.2 Inspection & Project", "1.3 The property")
date = self.get_next_value(data, "Inspection Date")
return InspectionAndProject(inspection_date=date)
def get_the_property(self):
data = self.get_data_between("1.3 The property", "3. Rooms")
return TheProperty(
house_type=self.get_next_value(data, "House Type"),
on_which_floor_is_the_flat_located = self.get_next_value(data, "On which floor is the flat located?"),
is_there_a_corridor = True if self.get_next_value(data, "Is there a corridor?").lower() == "yes" else False,
is_it_heated = True if self.get_next_value(data, "Is it heated?").lower() == "yes" else False,
it_there_a_balcony = True if self.get_next_value(data, "Is there a balcony?").lower() == "yes" else False,
classification_type = self.get_next_value(data, "Classification Type"),
orientation_front_elevation = self.get_next_value(data, "Orientation (front elevation)"),
orientation_in_degrees_front_elevation = self.get_next_value(data, "Orientation in degrees (front elevation)"),
exposure_zone = self.get_next_value(data, "Exposure Zone"),
main_wall_construction = self.get_next_value(data, "Main Wall Construction")
)
def get_main_elevation(self):
data = self.get_data_between("Main elevation", "Elevation")
elevation = ElevationInfo(
elevation_type=self.get_next_value(data, "Elevation type"),
cavity_wall_depth=self.get_next_value(data, "Cavity wall depth (in mm)"),
is_insulation_present=True if self.get_next_value(data, "Is insulation present?").lower() == "yes" else False,
insulation_type= self.get_next_value(data, "Insulation type"),
)
return MainElevation(
elevation_info=elevation
)
def get_all_elevations(self):
elevations = []
i = 1
while(f"Elevation {i}" in self.raw_data):
i += 1
no_of_elevation = i-1
print(f"There are {no_of_elevation} elevation")
for i in range(no_of_elevation):
data = self.get_data_between(f"Elevation {i+1}", "2. Access & Elevations")
elevations.append(ElevationInfo(
elevation_type=self.get_next_value(data, "Elevation type"),
cavity_wall_depth=self.get_next_value(data, "Cavity wall depth (in mm)"),
is_insulation_present=True if self.get_next_value(data, "Is insulation present?").lower() == "yes" else False,
insulation_type= self.get_next_value(data, "Insulation type"),
))
return Elevation(
info=elevations,
protected_conservatory_or_aonb=self.get_next_value(data, "the Significance Survey below is required."),
material_type=self.get_next_value(data, "Material Type"),
are_there_any_visible_signs_of_existing_wall_insulation=self.get_next_value(data, "Are there any visible signs of existing wall insulation?"),
does_the_existing_ground_level_on_any_elevation_bridge_the_dpc=True if self.get_next_value(data, "DPC?").lower() == "yes" else False,
)
def get_section_2(self):
pa = self.get_property_access()
front,one,back, two = self.get_external_elevation()
co = self.get_conservatory_or_outbuilding()
return AccessAndElevations(
property_access=pa,
external_elevation_front=front,
external_elevation_back=back,
external_elevation_gable_one=one,
external_elevation_gable_two=two,
conservatory_or_out_building=co,
)
def get_property_access(self):
data = self.get_data_between("2.1 Property Access", "2.2 External Elevations")
property_access = PropertyAccess(
are_there_any_road_restriction_in_the_locality=True if self.get_next_value(data, "locality?").lower() == "yes" else False,
is_on_street_parking_available=True if self.get_next_value(data, "Is on-street parking available?").lower() == "yes" else False,
are_there_any_overhead_wires_or_cables=True if self.get_next_value(data, "Are there any overhead wires or cables?") == "yes" else False,
is_the_access_gated=True if self.get_next_value(data, "Is the access gated?").lower() == "yes" else False,
is_there_restricted_space_for_contractors_to_access_the_wall_area=True if self.get_next_value(data, "area?").lower() == "yes" else False,
is_there_restricted_space_for_contractors_to_access_the_roof_area=True if self.get_x_value(data, "area?", 1).lower() == "yes" else False,
is_there_more_than_1_point_5_meters_in_width_to_fence_or_neighbouring_boundary_along_the_full_gable_elevation=True if self.get_next_value(data, "boundary along the full gable elevation?").lower() == "yes" else False,
is_access_to_the_rear_provided_by_use_of_a_ginnel=True if self.get_next_value(data, "Is access to the rear provided by use of a ginnel?").lower() == "yes" else False,
is_access_to_the_rear_provided_by_use_of_a_secured_alleyway=True if self.get_next_value(data, "Is access to the rear provided by use of a secured alleyway?").lower() == "yes" else False,
)
return property_access
def get_external_elevation(self):
# Front
data = self.get_data_between("2.2.1. External Elevation - Front", '2.2.2. External Elevation - Gable 1')
ee = ExternalElevation(
structural_defects_of_elevation=self.get_next_value(data, "Structural defects of elevation"),
does_any_structural_defect_need_resolving_before_retrofit=True if self.get_next_value(data,"Does any structural defect need resolving before retrofit?").lower() == "yes" else False,
are_there_any_signs_of_water_penetration_caused_by_failed_rainwater_goods_or_pipework=True if self.get_next_value(data, "rainwater goods or pipework?").lower() == "yes" else False,
are_there_any_visible_signs_of_movement=True if self.get_next_value(data, "Are there any visible signs of movement?").lower() == "yes" else False,
are_there_any_visible_signs_of_cracking_to_the_existing_external_finish=True if self.get_next_value(data, "external finish?").lower() == "yes" else False,
)
front = ExternalElevationFront(
external_elevation=ee
)
# Gable 1
data = self.get_data_between("2.2.2. External Elevation - Gable 1", "2.2.3. External Elevation - Rear")
state = True if self.get_next_value(data, "cracking)").lower() == "yes" else False
if state:
gable_one = ExternalElevationGableOne(
do_all_answers_for_the_front_elevation_apply_to_this_wall=state
)
else:
gable_one_elevation = ExternalElevation(
structural_defects_of_elevation=self.get_next_value(data, "Structural defects of elevation"),
does_any_structural_defect_need_resolving_before_retrofit=True if self.get_next_value(data,"Does any structural defect need resolving before retrofit?").lower() == "yes" else False,
are_there_any_signs_of_water_penetration_caused_by_failed_rainwater_goods_or_pipework=True if self.get_next_value(data, "rainwater goods or pipework?").lower() == "yes" else False,
are_there_any_visible_signs_of_movement=True if self.get_next_value(data, "Are there any visible signs of movement?").lower() == "yes" else False,
are_there_any_visible_signs_of_cracking_to_the_existing_external_finish=True if self.get_next_value(data, "external finish?").lower() == "yes" else False,
)
gable_one = ExternalElevationGableOne(
do_all_answers_for_the_front_elevation_apply_to_this_wall=state,
external_elevation=gable_one_elevation
)
# Rear
data = self.get_data_between("2.2.3. External Elevation - Rear", "2.2.4. External Elevation - Gable 2")
state = True if self.get_next_value(data, "cracking)").lower() == "yes" else False
if state:
rear = ExternalElevationRear(do_all_answers_for_the_front_elevation_apply_to_this_wall=state)
else:
elevation = ExternalElevation(
structural_defects_of_elevation=self.get_next_value(data, "Structural defects of elevation"),
does_any_structural_defect_need_resolving_before_retrofit=True if self.get_next_value(data,"Does any structural defect need resolving before retrofit?").lower() == "yes" else False,
are_there_any_signs_of_water_penetration_caused_by_failed_rainwater_goods_or_pipework=True if self.get_next_value(data, "rainwater goods or pipework?").lower() == "yes" else False,
are_there_any_visible_signs_of_movement=True if self.get_next_value(data, "Are there any visible signs of movement?").lower() == "yes" else False,
are_there_any_visible_signs_of_cracking_to_the_existing_external_finish=True if self.get_next_value(data, "external finish?").lower() == "yes" else False,
)
rear = ExternalElevationRear(
do_all_answers_for_the_front_elevation_apply_to_this_wall=state,
external_elevation=elevation
)
# Gable 2
data = self.get_data_between("2.2.4. External Elevation - Gable 2", "2.3. Conservatory or Outbuilding")
state = True if self.get_next_value(data, "Is there a 4th external elevation?").lower() == "yes" else False
if state is False:
gable_two = ExternalElevationGableTwo(is_there_a_fourth_external_elevation=state)
else:
gable_two_elevation = ExternalElevation(
structural_defects_of_elevation=self.get_next_value(data, "Structural defects of elevation"),
does_any_structural_defect_need_resolving_before_retrofit=True if self.get_next_value(data,"Does any structural defect need resolving before retrofit?").lower() == "yes" else False,
are_there_any_signs_of_water_penetration_caused_by_failed_rainwater_goods_or_pipework=True if self.get_next_value(data, "rainwater goods or pipework?").lower() == "yes" else False,
are_there_any_visible_signs_of_movement=True if self.get_next_value(data, "Are there any visible signs of movement?").lower() == "yes" else False,
are_there_any_visible_signs_of_cracking_to_the_existing_external_finish=True if self.get_next_value(data, "external finish?").lower() == "yes" else False,
)
gable_two = ExternalElevationGableTwo(
is_there_a_fourth_external_elevation=state,
external_elevation=gable_two_elevation
)
return front, gable_one, rear, gable_two
def get_conservatory_or_outbuilding(self):
data = self.get_data_between("2.3. Conservatory or Outbuilding", "3. Rooms")
return ConservatoryOrOutbuilding(
is_there_a_conservatory=True if self.get_next_value(data, "Is there a Conservatory?").lower() == "yes" else False,
is_there_a_cellar_present=True if self.get_next_value(data, "Is there a cellar present?").lower() == "yes" else False,
is_there_an_outbuilding=True if self.get_next_value(data, "Is there an Outbuilding?").lower() == "yes" else False,
)
def get_section_3(self):
hallway = self.get_hallway()
living_room = self.get_living_room()
dining_room = self.get_dining_room()
kitchen = self.get_kitchen()
utility = self.get_utility()
wc = self.get_wc()
landing = self.get_landing()
bedrooms = self.get_bedrooms()
bathrooms = self.get_bathroom()
loft_space = self.get_loft_space()
room_in_roof = self.get_room_in_roof()
return Rooms(
hallway=hallway,
living_room=living_room,
dining_room=dining_room,
kitchen=kitchen,
utility=utility,
wash_chamber=wc,
landing=landing,
bedrooms=bedrooms,
bathrooms=bathrooms,
loft_space=loft_space,
room_in_roof=room_in_roof,
)
def get_room_info(self, data):
ventilation = VentilationInfo(
is_there_a_ventilation_system_present_in_the_room=True if self.get_next_value(data, "Is there a ventilation system present in the room?").lower() == "yes" else False,
are_there_any_visible_or_reported_signs_of_damp_mould_or_excessive_condensation_within_the_room=True if self.get_next_value(data, "excessive condensation within the room?").lower() == "yes" else False,
are_there_sufficient_undercuts_on_the_closed_door=self.get_next_value(data, "- min 10mm)?"),
is_there_any_open_flue_heating_appliances_within_the_room=True if self.get_next_value(data, "Is there any open flue heating appliances within the room?").lower() == "yes" else False,
)
windows_state = True if self.get_next_value(data, "Does the room have any windows?").lower() == "yes" else False
if windows_state:
windows = WindowsInfo(
does_the_room_have_any_windows=windows_state,
condition_of_the_windows=self.get_next_value(data, "Condition of the windows"),
do_the_windows_have_trickle_vents=True if self.get_next_value(data, "Do the windows have trickle vents?").lower() == "yes" else False,
input_trickle_vent_product_code_or_measurement=self.get_next_value(data, "in both cases."),
are_the_windows_openable=True if self.get_next_value(data, "Are the windows openable?").lower() == "yes" else False,
)
else:
windows = WindowsInfo(
does_the_room_have_any_windows=windows_state
)
return RoomInfo(
overall_condition_of_the_room=self.get_next_value(data, "Overall condition of the room"),
does_the_room_have_any_defects=self.get_next_value(data, "cracking in walls, etc.)"),
windows_info=windows,
ventilation_info=ventilation,
)
def get_hallway(self):
data = self.get_data_between("Hallway", "Living Room")
room = self.get_room_info(data)
return Hallway(
is_there_a_hallway=True if self.get_next_value(data, "Is there a hallway?").lower() == "yes" else False,
room_info=room,
)
def get_living_room(self):
data = self.get_data_between("Living Room", "Dining Room")
room = self.get_room_info(data)
return LivingRoom(
room_info=room,
)
def get_dining_room(self):
data = self.get_data_between("Dining Room", "Kitchen")
dining_room_state = True if self.get_next_value(data, "Is there a dining room?").lower() == "yes" else False
if dining_room_state:
room = self.get_room_info(data)
else:
room = None
return DiningRoom(
is_there_a_dining_room=dining_room_state,
room_info=room,
)
def get_kitchen(self):
data = self.get_data_between("Kitchen", "Utility")
room = self.get_room_info(data)
return Kitchen(
room_info=room,
is_there_a_cooker_hood_present_in_the_room=True if self.get_next_value(data, "Is there a cooker hood present in the room?").lower() == "yes" else False,
)
def get_utility(self):
data = self.get_data_between("Utility", "WC")
utility_state = True if self.get_next_value(data, "Is there a utility room?").lower() == "yes" else False
if utility_state:
room = self.get_room_info(data)
else:
room = None
return Utility(
is_there_a_utility_room=utility_state,
room_info=room
)
def get_wc(self):
data = self.get_data_between("WC", "Landing")
wc_state = True if self.get_next_value(data, "Is there a separated WC?").lower() == "yes" else False
if wc_state:
room = self.get_room_info(data)
else:
room = None
return WC(
is_there_a_seperated_wc=wc_state,
room_info=room
)
def get_landing(self):
data = self.get_data_between("Landing", "Bedroom")
landing_state = True if self.get_next_value(data, "Is there a landing?").lower() == "yes" else False
if landing_state:
room_info = self.get_room_info(data)
else:
room_info = None
return Landing(
is_there_a_landing=landing_state,
room_info=room_info
)
def get_bedrooms(self):
bedrooms = []
i = 1
while(f"Bedroom {i}" in self.raw_data):
i += 1
no_of_bedrooms = i-1
print(f"There are {no_of_bedrooms} bedrooms")
for i in range(no_of_bedrooms):
data = self.get_data_between(f"Bedroom {i+1}", "Bathroom")
roominfo = self.get_room_info(data)
bedrooms.append(Bedroom(
double_or_single_bedroom=self.get_next_value(data, "Double or Single Bedroom?"),
room_info=roominfo
))
return bedrooms
def get_bathroom(self):
bathrooms = []
i = 1
while(f"Bathroom {i}" in self.raw_data):
i += 1
no_of_bathrooms = i-1
print(f"There are {no_of_bathrooms} bathrooms")
for i in range(no_of_bathrooms):
data = self.get_data_between(f"Bathroom {i+1}", "Loft Space")
roominfo = self.get_room_info(data)
bathrooms.append(Bathroom(
is_this_an_ensuite_bathroom=self.get_next_value(data, "Is this an ensuite bathroom?"),
room_info=roominfo
))
return bathrooms
def get_loft_space(self):
data = self.get_data_between("Loft Space", "Room in Roof")
return LoftSpace(
is_the_main_loft_space_accessible=self.get_next_value(data, "Is the main loft space accessible?"),
is_there_more_than_one_loft_space=True if self.get_next_value(data, "extension)?").lower() == "yes" else False,
)
def get_room_in_roof(self):
data = self.get_data_between("Room in Roof", "4. Heating System")
room_in_roof_state = True if self.get_next_value(data, "Is there a room in roof?").lower() == "yes" else False
room_info = None
if room_in_roof_state:
room_info = self.get_room_info(data)
return RoomInRoof(
is_there_a_room_in_roof=room_in_roof_state,
room_info=room_info
)
def get_section_4(self):
general_condition_of_heating_system = self.get_general_condition_of_heating_system()
main_heating_one = self.get_main_heating_one()
main_heating_two = self.get_main_heating_two()
# secondary_heating = self.get_secondary_heating()
heating_by_room = self.get_heating_by_room()
renewables = self.get_renewables()
return HeatingSystem(
general_condition=general_condition_of_heating_system,
main_heating_one=main_heating_one,
main_heating_two=main_heating_two,
# secondary_heating=secondary_heating,
heating_by_room=heating_by_room,
renewables=renewables
)
def get_main_heating_one(self):
data = self.get_data_between("Main Heating 1", "Main Heating 2")
return MainHeatingOne(
as_defined_by=self.get_next_value(data, "As defined by"),
fuel=self.get_next_value(data, "Fuel:"),
type=self.get_next_value_greedy(data, "Type", 2)
)
def get_main_heating_two(self):
data = self.get_data_between("Main Heating 2", "Secondary Heating")
return MainHeatingTwo(
is_there_a_main_heating_two=True if self.get_next_value(data, "Is there a Main Heating 2?").lower() == "yes" else False,
)
# def get_secondary_heating(self):
# data = self.get_data_between("Secondary Heating", "Heating by room")
# return SecondaryHeating(
# is_there_a_secondary_heating=True if self.get_next_value(data, "Is there a Secondary Heating?").lower() == "yes" else False,
# fuel=self.get_next_value(data, "Fuel:"),
# electric_heating_type=self.get_next_value_greedy(data, "Type", 2),
# gas_heating_type=self.get_x_value(data, "Type", 1),
# )
def get_heating_by_room(self):
data = self.get_data_between("Heating by room", "Renewables")
list_of_main_heating_system_by_one = self.get_data_between("Rooms heated by Main System 1:", "Rooms heated by Main System 2:")[1:]
list_of_main_heating_system_by_two = self.get_data_between("Rooms heated by Main System 2:", "Rooms heated by Secondary Heating:")[1:]
list_of_rooms_heated_by_secondary_heating = self.get_data_between("Rooms heated by Secondary Heating:", "Are there any partially heated rooms?")[1:]
are_there_any_partially_heated_rooms = True if self.get_next_value(data, "Are there any partially heated rooms?").lower() == "yes" else False
are_there_any_unheated_rooms = True if self.get_next_value(data, "Are there any unheated rooms?").lower() == "yes" else False
list_of_partially_heated_rooms = self.get_data_between("Are there any partially heated rooms?", "Are there any unheated rooms?")[2:]
list_of_unheated_rooms = self.get_data_between("Are there any unheated rooms?", "Renewables")[2:]
def remove_special_character(lst):
return_lst = []
for i, item in enumerate(lst):
if '\xa0' in item or 'Rooms' in item or len(item) == 1 or item.lower() == "None".lower():
pass
else:
return_lst.append(item)
return return_lst
return HeatingByRoom(
rooms_heated_by_main_system_one=remove_special_character(list_of_main_heating_system_by_one),
rooms_heated_by_main_system_two=remove_special_character(list_of_main_heating_system_by_two),
rooms_heated_by_secondary_heating=remove_special_character(list_of_rooms_heated_by_secondary_heating),
are_there_any_partially_heated_rooms=are_there_any_partially_heated_rooms,
are_there_any_unheated_rooms=are_there_any_unheated_rooms,
list_of_partially_heated_rooms=remove_special_character(list_of_partially_heated_rooms),
unheated_rooms=remove_special_character(list_of_unheated_rooms),
)
def get_renewables(self):
data = self.get_data_between("Renewables", "5. Occupancy Assessment")
return Renewables(
is_there_any_renewable_energy_system_in_place=True if self.get_next_value(data, "Is there any renewable energy system in place?").lower() == "yes" else False,
suitable_roof_orientation_for_solar_pv_water=self.get_next_value(data, "Suitable roof orientation for Solar PV/water:"),
is_there_a_water_tank=True if self.get_next_value(data, "Is there a Water Tank?").lower() == "yes" else False,
type=self.get_next_value(data, "Type"),
size=self.get_next_value(data, "Size"),
tank_location=self.get_next_value(data, "Tank Location"),
is_the_tank_insulated=True if self.get_next_value(data, "Is the tank Insulated") else False,
type_of_insulation=self.get_next_value(data, "Type of Insulation"),
thickness_of_insulation_in_mm=int(self.get_next_value(data, "Thickness of Insulation (mm)")),
)
def get_general_condition_of_heating_system(self):
data = self.get_data_between("4. Heating System", "Main Heating 1")
return GeneralConditionHeatingSystem(
is_the_heating_system_in_working_order=True if self.get_next_value(data, "Is the Heating System in working order?") else False,
does_the_occupant_have_a_smart_meter=True if self.get_next_value(data, "Does the occupant have a Smart Meter?") else False,
are_there_any_smart_monitoring_devices=True if self.get_next_value(data, "Are there any smart monitoring devices (Switchee etc)?") else False,
are_the_electricity_meters_accessible=True if self.get_next_value(data, "Is the Electricity Meter accessible?") else False,
are_the_gas_meters_accessible=True if self.get_next_value(data, "Is the Gas Meter accessible?") else False,
# dual_or_single_electric_meter=self.get_next_value(data, "Dual or single electric meter?"),
)
def get_section_5(self):
occupants = self.get_occupants()
energy_use = self.get_energy_use()
heating = self.get_heating()
shower_and_bath = self.get_shower_and_bath()
appliances = self.get_appliances()
fridge_and_freezers = self.get_fridge_and_freezers()
cooker = self.get_cooker()
tumble_dryer = self.get_tumble_dryer()
return OccupantAssessment(
occupant=occupants,
energy_use=energy_use,
heating=heating,
shower_and_bath=shower_and_bath,
appliances=appliances,
fridge_and_freezers=fridge_and_freezers,
cooker=cooker,
tumble_dryer=tumble_dryer
)
def get_occupants(self):
data = self.get_data_between("Occupants", "Energy use")
second_data = self.get_data_between("Tumble dryer", "Media summary")
return Occupant(
name=self.get_next_value(second_data, "Name of the occupant:"),
have_evidence_of_12_months_of_fuel_bill_data= True if self.get_next_value(second_data, "Have you evidenced 12 months of fuel bill data?").lower() == "yes" else False,
total_number_of_occupants=int(self.get_next_value(data, "Total number of occupants:")),
no_of_adult_occupants=int(self.get_next_value(data, "No. of Adult Occupants (18+)")),
no_of_child_occupants=int(self.get_next_value(data, "No. of Child Occupants (Under 18)")),
no_of_occupant_of_a_pensionable_age=int(self.get_next_value(data, "No. of occupant of a pensionable age")),
are_there_any_vulnerable_people=True if self.get_next_value(data, "Are there any vulnerable people?").lower() == "yes" else False,
is_there_anyone_with_a_disability=True if self.get_next_value(data, "Is there anyone with a disability?").lower() == "yes" else False,
status_of_occupant=self.get_next_value(data, "Status of the occupant:"),
landlord_has_written_confirmation_that_the_tenent_agrees_to_the_assessment_been_supplied=True if self.get_next_value(data, "the assessment been supplied").lower() == "yes" else False,
)
def get_energy_use(self):
data = self.get_data_between("Energy use", "Heating")
return EnergyUse(
property_tenure=self.get_next_value(data, "Property tenure:"),
who_is_the_electricity_payer=self.get_next_value(data, "Who is the electricity bill payer?")
)
def get_heating(self):
data = self.get_data_between("Heating", "Shower & bath")
return HeatingFromConditionReport(
room_stat_in_temperature_in_celsius=self.get_next_value(data, "Room Stat Temperature (in °C)", avoid=["Room Stat Location", '\xa0']),
room_stat_location=self.get_next_value(data, "Room Stat Location", avoid = ["Is the heating pattern known?", '\xa0']),
is_the_heating_pattern_known=self.get_next_value(data, "Is the heating pattern known?", avoid=["Shower & bath", '\xa0']),
)
def get_shower_and_bath(self):
data = self.get_data_between("Shower & bath", "Appliances")
return ShowerAndBath(
shower_type=self.get_next_value(data, "Shower Type:"),
do_you_know_the_no_of_showers_per_day_per_week=True if self.get_next_value(data, "Do you know the number of showers per day or per week?").lower() == "yes" else False,
please_input_no_of_showers_and_specify_a_day_or_a_week=self.get_next_value(data, '"per week"'),
do_you_know_the_number_of_baths_per_day_or_per_week=self.get_next_value(data, "Do you know the number of baths per day or per week?"),
)
def get_appliances(self):
print("Skipped appliances due to not having this example yet")
def get_fridge_and_freezers(self):
data = self.get_data_between("Fridge & freezers", "Cooker")
return FridgeAndFreezers(
no_of_stand_alone_seperate_fridges=int(self.get_next_value(data,"No. of Standalone (separate) Fridges:")),
no_of_stand_alone_seperate_freezers=int(self.get_next_value(data, "No. of Standalone (separate) Freezers:")),
no_of_stand_alone_or_integrated_fridge_freezers=int(self.get_next_value(data, "No. of Standalone or Integrated Fridge Freezers:"))
)
def get_cooker(self):
data = self.get_data_between("Cooker", "Tumble dryer")
return Cooker(
cooker_type=self.get_next_value(data, "Cooker Type:"),
normal_large_range=self.get_next_value(data, "Normal - Large - Range"),
range_fuel=self.get_next_value(data, "Range Fuel:")
)
def get_tumble_dryer(self):
data = self.get_data_between("Tumble dryer", "Have you evidenced 12 months of fuel bill data?")
return TumbleDryer(
percentage_of_annual_use=int(self.get_next_value(data, "Percentage of annual use:")),
space_for_outdoor_drying=True if self.get_next_value(data,"Space for outdoor drying?").lower() == "yes" else False,
)
class QuidosSiteNotesExtractor(SiteNotesExtractor):
def __init__(self, data_list):
super().__init__(data_list)
self.type = ReportType.QUIDOS_PRESITE_NOTE
self.company_information = None
self.survey_information = None
self.property_description = None
self.setup()
def setup(self):
"""
A function to read QUIDOS SITE REPORT and get all data
"""
self.transform_summary_information()
self.transform_sections()
# Heaters require thought so will complete later
# self.get_section_14()
# self.get_section_14_1()
# self.get_section_14_2()
def transform_summary_information(self):
# Summary Information
avoid = [
"Reference Number",
"EPC Language",
"UPRN",
"Postcode",
"Region",
"Address",
"Town",
"County",
"Property Tenure",
"Transaction Type",
"Inspection Date",
'Assessors accreditation number',
'Assessors name',
'Company name/trading name',
'Address',
'POST CODE',
'Phone number',
'Fax number',
'E-mail address',
'Related party disclosure',
'Current SAP rating',
'Potential SAP rating',
'Current EI rating',
'Current annual emissions',
'Current annual energy costs',
'Emission figures including 9.92 emission factor of 0.925',
]
get_value = lambda key: None if self.raw_data[self.raw_data.index(key) + 1] in avoid else self.raw_data[self.raw_data.index(key) + 1]
index = self.get_x_occurance(self.raw_data, "Current annual emissions")
if index:
including_9_92_emission_factor = self.raw_data[index + 1]
else:
including_9_92_emission_factor = None
self.survey_information = PreSiteNotesSummaryInfo(
reference_number = get_value('Reference Number'),
epc_language = get_value('EPC Language'),
uprn = get_value('UPRN').lstrip('0'),
postcode = get_value('Postcode'),
region = get_value('Region'),
address = ','.join(get_value('Address').split(',')[:-1]).strip(),
town = get_value('Town'),
county = get_value('County'),
property_tenure = get_value('Property Tenure'),
transaction_type = get_value('Transaction Type'),
inspection_date = datetime.strptime(get_value('Inspection Date'), '%d %B %Y'),
current_sap = get_value('Current SAP rating'),
potential_sap = get_value('Potential SAP rating'),
current_ei = get_value('Current EI rating'),
potential_ei = get_value('Potential EI rating'),
current_annual_emissions = get_value('Current annual emissions'),
current_annual_energy_costs = get_value('Current annual energy costs'),
current_annual_emission_including_0925_multiplayer=including_9_92_emission_factor,
)
self.company_information = CompanyInfo(
address=self.raw_data[self.get_x_occurance(self.raw_data,'Address', 1) + 1],
trading_name = get_value('Company name/trading name'),
post_code = get_value('POST CODE'),
fax_number = get_value('Fax number'),
related_party_disclosure = get_value("Related party disclosure")
)
self.assessor_information = AssessorInfo(
accreditation_number = get_value("Assessors accreditation number"),
name = get_value("Assessors name"),
phone_number = get_value("Phone number"),
email_address = get_value("E-mail address"),
)
index = self.get_x_occurance(self.raw_data, "Address")
if index:
assessor_address = self.raw_data[index + 1]
else:
assessor_address = None
self.assessor_information = AssessorInfo(
accreditation_number = get_value("Assessors accreditation number"),
name = get_value("Assessors name"),
phone_number = get_value("Phone number"),
email_address = get_value("E-mail address"),
address = assessor_address,
)
def transform_sections(self):
# Section 1
data = self.get_data_between("1.0 Property Type","2.0 Number Of")
avoid = [
"1.0 Property Type",
"Built Form",
"Detachment/Position",
"2.0 Number Of"
]
get_value = lambda key: None if self.raw_data[self.raw_data.index(key) + 1] in avoid else self.raw_data[self.raw_data.index(key) + 1]
# Section 2
data = self.get_data_between("2.0 Number Of","3.0 Date Built")
avoid = [
'2.0 Number Of',
'Main Property',
'Extension 1',
'Extension 2',
'Extension 3',
'Extension 4',
'Number of Habitable Rooms',
'Number of Heated Habitable Rooms',
'Heated Basement',
'Conservatory Type',
'Terrain Type',
'Percentage of Draught Proofed(%)',
"3.0 Date Built",
]
# Section 3
age_bands = self.get_age_band()
# Section 4
no_of_main_property = int(get_value("Main Property"))
no_of_extension_1 = int(get_value('Extension 1') or 0)
no_of_extension_2 = int(get_value('Extension 2') or 0)
no_of_extension_3 = int(get_value('Extension 3') or 0)
no_of_extension_4 = int(get_value('Extension 4') or 0)
dimensions = self.get_dimensions(
no_of_main_property,
no_of_extension_1,
no_of_extension_2,
no_of_extension_3,
no_of_extension_4,
)
# Section 5
conservatory = self.is_there_a_conservatory()
# Section 7
walls = self.get_walls()
# Section 8
roofs = self.get_roof()
# Section 9
floors = self.get_floors()
# Section 10
door = self.get_door()
windows = self.get_windows()
# Section 12
ventilationAndCooling = self.get_ventilation_and_cooling()
# Section 13
lighting = self.get_lighting()
# Section 14.0
main_heating = self.get_main_heating()
# Section 14.1
secondary_heating = self.get_secondary_heating()
# Section 14.2
secondary_heating_type = self.get_secondary_heating_type()
# Section 15.0 Water Heating
waterHeating = self.get_water_heating()
# Section 15.1 Hot Water Cylinder
hotWaterCylinder = self.get_hot_water_cylinder()
# Section 16 Solar Water Heating
solarWaterHeating = self.get_solar_water_heating()
# Section 17.0
# ignored as it has nothing in the copy i'm using. Future todo clarity
# Section 18.0
showerAndBaths = self.get_shower_and_baths()
# Section 19.0
fghrs = self.get_fghrs()
# Section 20.0
photovoltaicPanel = self.get_photovoltaic_panel()
# Section 21.0
windTurbine = self.get_wind_turbine()
# Section 22.0
otherDetails = self.get_other_details()
self.property_description = PropertyDescription(
built_form = get_value("Built Form"),
detachment_or_position = get_value("Detachment/Position"),
no_of_main_property = no_of_main_property,
no_of_extension_1 = no_of_extension_1,
no_of_extension_2 = no_of_extension_2,
no_of_extension_3 = no_of_extension_3,
no_of_extension_4 = no_of_extension_4,
no_of_habitable_rooms = int(get_value('Number of Habitable Rooms')),
no_of_heated_rooms = int(get_value('Number of Heated Habitable Rooms')),
heated_basement = False if get_value('Heated Basement') == "NO" else True,
conservatory_type = get_value('Conservatory Type'),
percentage_of_draught_proofed= int(get_value('Percentage of Draught Proofed(%)')),
main_property=PropertyDetail(
age_band=age_bands[0],
dimensions=dimensions["main"] if "main" in dimensions else [],
wall=walls[0],
roof=roofs[0],
floor=floors[0],
windows=windows.get("main_property", []),
)if no_of_main_property > 0 else None,
ex1_property=PropertyDetail(
age_band= age_bands[1],
dimensions= dimensions["ex1"] if "ex1" in dimensions else [],
wall=walls[1],
roof=roofs[1],
floor=floors[1],
windows=windows.get("extension_1", []),
)if no_of_extension_1 > 0 else None,
ex2_property=PropertyDetail(
age_band= age_bands[2],
dimensions= dimensions["ex2"] if "ex2" in dimensions else [],
wall=walls[2],
roof=roofs[2],
floor=floors[2],
windows=windows.get("extension_2", []),
)if no_of_extension_2 > 0 else None,
ex3_property=PropertyDetail(
age_band= age_bands[3],
dimensions=dimensions["ex3"] if "ex3" in dimensions else [],
wall=walls[3],
roof=roofs[3],
floor=floors[3],
windows=windows.get("extension_3", []),
)if no_of_extension_4 > 0 else None,
conservatory=conservatory,
door=door,
ventilationAndCooling=ventilationAndCooling,
lighting=lighting,
waterHeating=waterHeating,
hotWaterCylinder=hotWaterCylinder,
solarWaterHeating=solarWaterHeating,
showerAndBaths=showerAndBaths,
flueGasHeatRecoverySystem=fghrs,
photovoltaicPanel=photovoltaicPanel,
windTurbine=windTurbine,
otherDetails=otherDetails,
mainHeating=main_heating,
secondaryHeatingType=secondary_heating_type,
mainHeating2=secondary_heating,
)
def get_age_band(self):
data = self.raw_data[self.raw_data.index('3.0 Date Built'):self.raw_data.index('4.0 Dimensions')]
avoid = [
'3.0 Date Built',
'Age Band',
'Main Property',
'Extension 1',
'Extension 2',
'Extension 3',
'Extension 4',
'4.0 Dimensions',
]
property_age = []
get_value = lambda x: None if data[data.index(x) + 1] in avoid else data[data.index(x) + 1]
age = (get_value("Main Property"))
if age:
property_age.append(age)
else:
property_age.append(None)
for i in range(1,4):
if f"Extension {i}" in data:
property_age.append(get_value(f"Extension {i}"))
else:
property_age.append(None)
return property_age
def get_dimensions(self, main, ext1=0, ext2=0, ext3=0, ext4=0):
data = self.get_data_between('4.0 Dimensions','5.0 Conservatory')
avoid = [
'4.0 Dimensions',
'5.0 Conservatory',
'Dimension Type internal',
'Part',
'Floor Area (m2)',
'Room Height (m)',
'Loss Perimeter (m)',
'Party Wall Length (m)',
'Main Property',
'Extension 1 Property',
'Extension 2 Property',
'Extension 3 Property',
'Extension 4 Property',
]
def create_dimensions_array(key, no_of_property):
index = data.index(key) + 1
allNumbers = []
for propertyNo in range(no_of_property):
numbers = []
for i in range(4):
numbers.append(data[i + propertyNo*4 + index])
details = Dimension(
floor_area_m2=float(numbers[0]),
room_height_m=float(numbers[1]),
loss_perimeter_m=float(numbers[2]),
party_wall_length_m=float(numbers[3]),
)
allNumbers.append(details)
return allNumbers
return_dict = {}
return_dict.update({"main": create_dimensions_array("Main Property", main)})
ext = [ext1, ext2, ext3, ext4]
for i in range(1,5):
if f"Extension {i} Property" in data:
return_dict.update({f"ex{i}" : create_dimensions_array(f"Extension {i} Property", ext[i-1])})
return return_dict
def is_there_a_conservatory(self):
data = self.raw_data[self.raw_data.index('5.0 Conservatory'):self.raw_data.index('7.0 Walls')]
avoid = [
'Is there a conservatory?',
'7.0 Walls'
]
get_value = lambda key: None if self.raw_data[self.raw_data.index(key) + 1] in avoid else self.raw_data[self.raw_data.index(key) + 1]
return True if get_value("Is there a conservatory?").upper() == "YES" else False
def get_section_6(self):
pass
def get_walls(self):
data = self.get_data_between('7.0 Walls','8.0 Roofs')
sub_titles = [
"Construction",
"Insulation",
"Insulation Thickness(mm)",
"Wall Thickness Measured?",
"Wall Thickness Measured",
"Wall Thickness(mm)",
"U-value Known?",
"U-value Known",
"U-value (W/m²K)",
"Dry-lining?",
"Alternative Wall Present?",
"Alternative Wall Present",
]
main_titles = [
"Main Property",
"Extension 1",
"Extension 2",
"Extension 3",
"Extension 4",
]
lst = self.two_column_with_extension_processor(data, sub_titles, main_titles)
walls = []
for ext in lst:
walls.append(Walls(
construction=ext["construction"] if ext["construction"] is not None else "",
insulation=str(ext["insulation"]),
insulation_thickness_mm=str(ext["insulation_thickness(mm)"]),
wall_thickness_measured=True if ext["wall_thickness_measured"].upper() == "YES" else False,
wall_thickness_mm=int(ext.get("wall_thickness(mm)",-1)),
u_value_known=True if ext["u_value_known"].upper() == "YES" else False,
u_value_w_m2_k=float(ext.get("u_value_(w/m²k)", -1.0)),
dry_lining=True if ext.get("dry_lining", "NO").upper() == "YES" else False,
alternative_wall_present=True if ext.get("alternative_wall_present", "NO").upper() == "YES" else False,
))
return walls
def get_roof(self):
data = self.raw_data[self.raw_data.index('8.0 Roofs'): self.raw_data.index('9.0 Floors')]
sub_titles = [
"Construction",
"Insulation Type",
"Insulation Thickness",
"U-value Known",
]
titles = [
"Main Property",
"Extension 1",
"Extension 2",
"Extension 3",
"Extension 4",
]
lst = self.two_column_with_extension_processor(data, sub_titles, titles)
roofs = []
for roof in lst:
roofs.append(Roofs(
construction=roof["construction"] if roof["construction"] is not None else "",
insulation_type=str(roof["insulation_type"]),
insulation_thickness=str(roof["insulation_thickness"]),
u_value_known=True if roof["u_value_known"].upper() == "YES" else False,
))
return roofs
def two_column_with_extension_processor(self, data, sub_titles, main_titles):
def get_value(key):
try:
index = proc_data.index(key)
value = proc_data[index + 1]
return None if value in sub_titles else value
except (ValueError, IndexError):
return None
title = None
proc_data = data
return_dict = {}
group_data = []
for items in data:
if items in main_titles:
title = items.lower().replace(" ", "_").replace("-", "_")
index = main_titles.index(items)
if main_titles[index] in data:
if return_dict:
group_data.append(return_dict)
return_dict = {}
proc_data = data[data.index(main_titles[index]):]
continue
else:
if return_dict:
group_data.append(return_dict)
break
if title is None:
continue
if items in sub_titles:
return_dict.update({f"{items.lower().replace("?", "").replace(' ', '_').replace('-','_')}": get_value(items)})
if return_dict:
group_data.append(return_dict)
return group_data
def get_floors(self):
data = self.raw_data[self.raw_data.index('9.0 Floors'): self.raw_data.index('10.0 Doors')]
sub_titles = [
"Floor Type",
"Ground Floor Construction",
"Ground Floor Insulation Type",
"Floor Insulation Thickness (mm)",
"U-value Known",
]
titles = [
"Main Property",
"Extension 1",
"Extension 2",
"Extension 3",
"Extension 4",
]
lst = self.two_column_with_extension_processor(data, sub_titles, titles)
floors = []
for floor in lst:
floors.append(Floors(
floor_type=floor.get("floor_type", ""),
ground_floor_construction=floor.get("get_floor_construction", ""),
ground_floor_insulation_type=floor.get("ground_floor_insulation_type", ""),
floor_insulation_thickness_mm=floor.get("floor_insulation_thickness_(mm)", -1) if floor.get("floor_insulation_thickness_(mm)", -1) is not None else -1,
u_value_known=True if floor.get("u_value_known").upper() == "YES" else False,
))
return floors
def get_door(self):
data = self.raw_data[self.raw_data.index("10.0 Doors"): self.raw_data.index("11.0 Windows")]
avoid = [
"10.0 Doors",
"11.0 Windows",
]
sub_titles = [
"Number of Doors",
"Number of Insulated Doors",
"U-value (W/m²K)",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return Door(
no_of_doors=int(dict_.get("no_of_doors", -1)),
no_of_insulated_doors=int(dict_.get("number_of_insulated_doors", -1)),
u_value_w_m2_k=dict_.get("u_value_(w/m²k)", "") if dict_.get("u_value_(w/m²k), '')") is not None else "",
)
def get_windows(self):
data = self.get_data_between("11.0 Windows", "12.0 Ventilation & Cooling")
headers = data[:8]
data_entries = data[8:]
num_attributes = 5
subtitles=[
"Main Property",
"Extension 1",
"Extension 2",
"Extension 3",
"Extension 4",
]
orientation = [
"north",
"east",
"west",
"south",
"n",
"w",
"s",
"e",
"nw",
"ne",
"sw",
"se",
"south west",
"south east",
"north west",
"north east",
]
def find_compose_index(lst, compose):
for i, item in enumerate(lst):
if item.lower() in compose:
return i
return None
title = None
until = 0
dict_to_return = {}
for i, items in enumerate(data_entries):
if data_entries[i] in subtitles:
title = data_entries[i].lower().replace(" ", "_").replace("-", "_")
dict_to_return.update({f"{title}":[]})
if title and until == i:
entry = data_entries[i:]
index = find_compose_index(entry,orientation)
new_entry = entry[index-3:index+3]
window = Windows(
glazing_type= new_entry[0],
area_m2=float(new_entry[1]),
roof_window=True if new_entry[2].upper() == "YES" else False,
orientation=new_entry[3].upper(),
u_value_w_m2_k=int(new_entry[4]),
g_value=int(new_entry[5]),
)
dict_to_return[f"{title}"].append(window)
until = index + 3 + i
return dict_to_return
def get_ventilation_and_cooling(self):
data = self.raw_data[self.raw_data.index('12.0 Ventilation & Cooling'): self.raw_data.index('13.0 Lighting')]
avoid = [
'12.0 Ventilation & Cooling',
'13.0 Lighting'
]
sub_titles = [
"Number of Open Fireplaces",
"Ventilation Type",
"Space Cooling System Present",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return VentilationAndCooling(
no_of_open_fireplaces=int(dict_.get("number_of_open_fireplaces", -1)),
ventilation_type=str(dict_.get("ventilation_type", "")),
space_cooling_system_present=True if dict_.get("space_cooling_system_present").upper() == "YES" else False
)
def get_lighting(self):
data = self.raw_data[self.raw_data.index('13.0 Lighting'): self.raw_data.index('14.0 Main Heating1')]
avoid = [
"13.0 Lighting",
"14.0 Main Heating1"
]
sub_titles = [
"Total number of light fittings",
"Total number of L.E.L. fittings",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid = avoid)
return Lighting(
total_no_of_light_fittings=int(dict_["total_number_of_light_fittings"]),
total_no_of_lel_fittings=int(dict_["total_number_of_l.e.l._fittings"]),
)
def get_main_heating(self):
data = self.raw_data[self.raw_data.index('14.0 Main Heating1'): self.raw_data.index('14.1 Main Heating2')]
main_titles = [
"Main Heating Type",
"Product Database"
"Main Heating System Controls",
]
sub_titles = [
"Heating Source",
"Efficiency Source",
"Heating Fuel",
"Brand Name",
"Model Name",
"Model Qualifier",
"Control Type",
"Flue Type",
"Fan Assisted Flue",
"Heat Emitter Type",
"Electricity Meter Type",
"Mains Gas Available",
]
lst_ = self.two_column_with_extension_processor(data, sub_titles, main_titles)
dict_ = lst_[0]
return Heating(
type="main",
heating_source=dict_.get("heating_source", ""),
efficiency_source=dict_.get("efficiency_source", ""),
heating_fuel=dict_.get("heating_fuel", ""),
brand_name=dict_.get("brand_name", ""),
model_name=dict_.get("model_name", ""),
model_qualifer=dict_.get("model_qualifier", ""),
controls=HeatingSystemControls(
control_type=dict_.get("control_type", "") if dict_.get("control_type", "") is not None else "",
flue_type=dict_.get("flue_type","") if dict_.get("flue_type", "") is not None else "",
fan_assisted_flue=True if dict_.get("fan_assisted_flue", "NO").upper() == "YES" else False,
heat_emitter_type=dict_.get("heat_emitter_type", "") if dict_.get("heat_emitter_type") is not None else "",
electricity_meter_type=dict_.get("electricity_meter_type", ""),
mains_gas_available=True if dict_.get("mains_gas_available", "NO").upper() == "YES" else False,
)
)
# def get_secondary_heating(self):
# data = self.raw_data[self.raw_data.index("14.1 Main Heating2"):self.raw_data.index("14.2 Secondary Heating Type")]
# main_titles = [
# "Second Main Heating Type",
# "Main Heating System Controls",
# ]
# sub_titles = [
# "Percentage of Heated Floor Area Served (%)",
# "Heating Source",
# "Efficiency Source",
# "Heating Fuel",
# "SAP 2009 Table 4a/4b",
# "Heating Type",
# "Heating Description",
# "Control Type",
# "Flue Type",
# "Fan Assisted Flue",
# "Heat Emitter Type",
# ]
# list = self.two_column_with_extension_processor(data, sub_titles, main_titles)
# dict_ = list[0]
# return Heating(
# type="secondary",
# percentage_of_heated_floor_area_served=dict_.get("percentage_of_heated_floor_area_served_(%)", ""),
# heating_source=dict_.get("heating_source", "") if dict_["heating_source"] is not None else "",
# efficiency_source=dict_.get("efficiency_source", "") if dict_["efficiency_source"] is not None else "",
# heating_fuel=dict_.get("heating_fuel", "") if dict_.get("heating_fuel") is not None else "",
# brand_name=dict_.get("brand_name", ""),
# model_name=dict_.get("model_name", ""),
# model_qualifer=dict_.get("model_qualifier", ""),
# controls=HeatingSystemControls(
# control_type=dict_.get("control_type", "") if dict_.get("control_type", "") is not None else "",
# flue_type=dict_.get("flue_type","") if dict_.get("flue_type", "") is not None else "",
# fan_assisted_flue=True if dict_.get("fan_assisted_flue", "NO").upper() == "YES" else False,
# heat_emitter_type=dict_.get("heat_emitter_type", "") if dict_.get("heat_emitter_type") is not None else "",
# electricity_meter_type=dict_.get("electricity_meter_type", "") if dict_.get("electricity_meter_type", "") is not None else "",
# mains_gas_available=True if dict_.get("mains_gas_available", "NO").upper() == "YES" else False,
# )
# )
# def get_secondary_heating_type(self):
# data = self.raw_data[self.raw_data.index("14.2 Secondary Heating Type"):self.raw_data.index("15.0 Water Heating")]
# avoid = [
# "14.2 Secondary Heating Type",
# "15.0 Water Heating",
# ]
# sub_titles = [
# "Heating Type",
# "Fuel Type",
# ]
# dict_ = self.two_columns_processor(data, sub_titles, avoid)
# return HeatingType(
# heating_type=dict_.get("heating_type", ""),
# fuel_type=dict_.get("fuel_type", ""),
# )
def get_water_heating(self):
data = self.raw_data[self.raw_data.index("15.0 Water Heating"):self.raw_data.index("15.1 Hot Water Cylinder")]
sub_titles = [
"Heating Type",
"Fuel Type",
]
avoid = [
"15.0 Water Heating",
"15.1 Hot Water Cylinder",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return WaterHeating(
heating_type=dict_.get("heating_type", ""),
fuel_type=dict_.get("fuel_type", ""),
)
def get_hot_water_cylinder(self):
data = self.raw_data[self.raw_data.index("15.1 Hot Water Cylinder"):self.raw_data.index("16.0 Solar Water Heating")]
sub_tites = [
"Volume",
"Insulation Type",
"Insulation Thickness",
"Thermostat",
]
avoid = [
"16.0 Solar Water Heating",
"15.1 Hot Water Cylinder"
]
dict_ = self.two_columns_processor(data, sub_tites, avoid)
return HotWaterCylinder(
volume=dict_.get("volume", ""),
insulation_type=dict_.get("insulation_type", ""),
insulation_thickness=dict_.get("insulation_thickness", ""),
thermostat=True if dict_.get("thermostat", "NO").upper() == "YES" else False,
)
def get_solar_water_heating(self):
data = self.raw_data[self.raw_data.index("16.0 Solar Water Heating"):self.raw_data.index("17.0 Waste Water Heat Recovery System")]
avoid = [
"16.0 Solar Water Heating",
"17.0 Waste Water Heat Recovery System",
]
sub_titles = [
"Solar Water Heating Details Known?"
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return SolarWaterHeating(
solar_water_heating_details_known=True if dict_.get("solar_water_heating_details_known", "NO").upper() == "YES" else False
)
def get_section_17(self):
"""
Furture todo
"""
raise NotImplemented("Please contact Jun-te Kim to implement this")
def get_shower_and_baths(self):
data = self.get_data_between("18.0 Showers And Baths", "19.0 Flue Gas Heat Recovery System")
sub_titles = [
"Number of Rooms with Bath and/or Shower",
]
avoid = [
"18.0 Showers And Baths",
"19.0 Flue Gas Heat Recovery System",
]
dict_1 = self.two_columns_processor(data, sub_titles, avoid)
avoid = [
"18.0 Showers And Baths",
"19.0 Flue Gas Heat Recovery System",
]
sub_titles = [
"Number of Rooms with Mixer Shower and no", # Number of Rooms with Mixer Shower and no Bath
"Number of Rooms with Mixer Shower and", # Number of Rooms with Mixer Shower and Bath
]
dict_2 = self.two_columns_processor(data, sub_titles, avoid, 2)
return ShowerAndBaths(
no_of_rooms_with_baths_and_or_shower=int(dict_1.get("number_of_rooms_with_bath_and/or_shower", -1)),
no_of_rooms_with_mixer_shower_and_no_baths=int(dict_2.get("number_of_rooms_with_mixer_shower_and_no", -1)),
no_of_rooms_with_mixer_shower_and_baths=int(dict_2.get("number_of_rooms_with_mixer_shower_and", -1)),
)
def get_fghrs(self):
data = self.get_data_between("19.0 Flue Gas Heat Recovery System","20.0 Photovoltaic Panel")
sub_titles = [
"FGHRS Present",
]
avoid = [
"19.0 Flue Gas Heat Recovery System",
"20.0 Photovoltaic Panel",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return FlueGasHeatRecoverySystem(
fghrs_present=True if dict_.get("fghrs_present", "NO").upper() == "YES" else False
)
def get_photovoltaic_panel(self):
data = self.get_data_between("20.0 Photovoltaic Panel","21.0 Wind Turbine")
sub_titles = [
"Percentage of External Roof Area with PVs"
]
avoid = [
"20.0 Photovoltaic Panel",
"21.0 Wind Turbine",
]
dict_1 = self.two_columns_processor(data, sub_titles, avoid)
sub_titles = [
"PVs are connected to dwelling electricity" # PVs are connected to dwelling electricity meter
]
dict_2 = self.two_columns_processor(data, sub_titles, avoid, 2)
return PhotovoltaicPanel(
pvs_are_connected_to_dwelling_electricity_meter=True if dict_2.get("pvs_are_connected_to_dwelling_electricity", "NO").upper() == "YES" else False,
percentage_of_external_roof_area_with_pvs=dict_1.get("percentage_of_external_roof_area_with_pvs")
)
def get_wind_turbine(self):
data = self.get_data_between("21.0 Wind Turbine","22.0 Other Details")
sub_titles = [
"Wind Turbine",
]
avoid = [
"21.0 Wind Turbine",
"22.0 Other Details",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return WindTurbine(
wind_turbine=True if dict_.get("wind_turbine", "NO").upper()=="YES" else False
)
def get_other_details(self):
data = self.get_data_between("22.0 Other Details","Recommendations (Carbon Saving Figures Are For Guidance Only)")
sub_titles = [
"Electricity Meter Type",
"Mains Gas Available",
]
avoid = [
"22.0 Other Details",
"Recommendations (Carbon Saving Figures Are For Guidance Only)",
]
dict_ = self.two_columns_processor(data, sub_titles, avoid)
return OtherDetails(
electricity_meter_type=dict_.get("electricity_meter_type", ""),
main_gas_avalible=True if dict_.get("main_gas_available", "NO").upper() == "YES" else False,
)
class EnergyPerformanceReportWithData(SiteNotesExtractor):
def __init__(self, data_list):
super().__init__(data_list)
self.type = ReportType.ENERGY_PERFORMANCE_REPORT_WITH_DATA
self.master_obj = self.setup()
def setup(self):
pass
class EnergyPerformanceReportSummaryInformation(SiteNotesExtractor):
def __init__(self, data_list):
self.raw_data = data_list
self.type = ReportType.ENERGY_PERFORMANCE_REPORT_SUMMARY_INFORMATION
self.setup()
def setup(self):
pass