mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
fixing wall recommendations testss
This commit is contained in:
parent
f288d47e38
commit
5146e6e0b4
6 changed files with 44 additions and 73 deletions
|
|
@ -3,6 +3,7 @@ import re
|
|||
from epc_api.client import EpcClient
|
||||
from model_data.config import EPC_AUTH_TOKEN
|
||||
from model_data.BaseUtility import Definitions
|
||||
from recommendations.rdsap_tables import england_wales_age_band_lookup
|
||||
|
||||
|
||||
class Property(Definitions):
|
||||
|
|
@ -29,6 +30,7 @@ class Property(Definitions):
|
|||
lighting = None
|
||||
|
||||
coordinates = None
|
||||
age_band = None
|
||||
|
||||
def __init__(self, id, postcode, address1, epc_client=None, data=None):
|
||||
self.id = id
|
||||
|
|
@ -245,6 +247,7 @@ class Property(Definitions):
|
|||
self.set_floor_height()
|
||||
self.set_wall_area()
|
||||
self.set_floor_area()
|
||||
self.set_age_band()
|
||||
|
||||
for description, attribute in cleaned.items():
|
||||
|
||||
|
|
@ -263,6 +266,17 @@ class Property(Definitions):
|
|||
raise ValueError("Either No attributes or multiple found for %s" % description)
|
||||
setattr(self, self.ATTRIBUTE_MAP[description], attributes[0])
|
||||
|
||||
def set_age_band(self):
|
||||
"""
|
||||
Sets a cleaned version of the age band of the property given the EPC data
|
||||
:return:
|
||||
"""
|
||||
|
||||
if not self.data:
|
||||
raise ValueError("Property does not contain data")
|
||||
|
||||
self.age_band = england_wales_age_band_lookup[self.data["construction-age-band"]]
|
||||
|
||||
def set_is_in_conservation_area(self, in_conservation_area):
|
||||
"""
|
||||
Sets whether the property is in a conservation area given the output of the ConservationAreaClient
|
||||
|
|
|
|||
|
|
@ -539,8 +539,6 @@ def app():
|
|||
if pd.isnull(data_by_urpn_df).sum().sum():
|
||||
raise ValueError("Null values found in dataset after process_and_prune_desriptions")
|
||||
|
||||
data_by_urpn_df = DataProcessor.difference_data(data_by_urpn_df)
|
||||
|
||||
dataset.append(data_by_urpn_df)
|
||||
|
||||
cleaning_averages["LOCAL_AUTHORITY"] = df["LOCAL_AUTHORITY"].values[0]
|
||||
|
|
@ -555,6 +553,9 @@ def app():
|
|||
)
|
||||
|
||||
output = pd.concat(dataset)
|
||||
|
||||
output = DataProcessor.difference_data(output)
|
||||
|
||||
save_dataframe_to_s3_parquet(
|
||||
df=output,
|
||||
bucket_name="retrofit-data-dev",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ from typing import List
|
|||
from model_data.BaseUtility import Definitions
|
||||
from datatypes.enums import QuantityUnits
|
||||
from backend.Property import Property
|
||||
from recommendations.rdsap_tables import england_wales_age_band_lookup
|
||||
from recommendations.recommendation_utils import (
|
||||
r_value_per_mm_to_u_value, calculate_u_value_uplift, is_diminishing_returns, update_lowest_selected_u_value,
|
||||
get_recommended_part, estimate_perimeter, estimate_perimeter_2_rooms, get_wall_type,
|
||||
|
|
@ -40,12 +39,10 @@ class FloorRecommendations(Definitions):
|
|||
def __init__(
|
||||
self,
|
||||
property_instance: Property,
|
||||
uvalue_estimates: List,
|
||||
total_floor_area_group_decile: str,
|
||||
materials: List,
|
||||
):
|
||||
self.property = property_instance
|
||||
self.uvalue_estimates = uvalue_estimates
|
||||
self.total_floor_area_group_decile = total_floor_area_group_decile
|
||||
# For audit purposes, when estimating u values we'll store it
|
||||
self.estimated_u_value = None
|
||||
|
|
@ -119,14 +116,13 @@ class FloorRecommendations(Definitions):
|
|||
else:
|
||||
estimated_perimeter = estimate_perimeter(total_floor_area / num_floors, scaled_num_rooms)
|
||||
|
||||
age_band = england_wales_age_band_lookup[self.property.data["construction-age-band"]]
|
||||
wall_type = get_wall_type(**self.property.walls)
|
||||
|
||||
self.estimated_u_value = get_floor_u_value(
|
||||
floor_type="suspended" if is_suspended else "solid",
|
||||
area=total_floor_area,
|
||||
perimeter=estimated_perimeter,
|
||||
age_band=age_band,
|
||||
age_band=self.property.age_band,
|
||||
insulation_thickness=insulation_thickness,
|
||||
wall_type=wall_type
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from backend.Property import Property
|
|||
from model_data.BaseUtility import Definitions
|
||||
from recommendations.recommendation_utils import (
|
||||
r_value_per_mm_to_u_value, calculate_u_value_uplift, is_diminishing_returns, update_lowest_selected_u_value,
|
||||
get_recommended_part, get_uvalue_estimate
|
||||
get_recommended_part, get_wall_u_value
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -44,13 +44,12 @@ class WallRecommendations(Definitions):
|
|||
}
|
||||
|
||||
def __init__(
|
||||
self, property_instance: Property,
|
||||
uvalue_estimates: List,
|
||||
self,
|
||||
property_instance: Property,
|
||||
total_floor_area_group_decile: str,
|
||||
materials: List
|
||||
):
|
||||
self.property = property_instance
|
||||
self.uvalue_estimates = uvalue_estimates
|
||||
self.total_floor_area_group_decile = total_floor_area_group_decile
|
||||
# For audit purposes, when estimating u values we'll store it
|
||||
self.estimated_u_value = None
|
||||
|
|
@ -116,18 +115,15 @@ class WallRecommendations(Definitions):
|
|||
|
||||
raise NotImplementedError("Not implemented yet")
|
||||
|
||||
if is_solid_brick:
|
||||
u_value = get_wall_u_value(
|
||||
clean_description=self.property.walls["clean_description"],
|
||||
age_band=self.property.age_band,
|
||||
is_granite_or_whinstone=self.property.walls["is_granite_or_whinstone"],
|
||||
is_sandstone_or_limestone=self.property.walls["is_sandstone_or_limestone"],
|
||||
)
|
||||
self.estimated_u_value = u_value
|
||||
|
||||
if insulation_thickness == "none":
|
||||
# This is an estimated figure based on industry standards
|
||||
u_value = self.DEFAULT_U_VALUES["solid_brick"]
|
||||
else:
|
||||
u_value = get_uvalue_estimate(
|
||||
uvalue_estimates=self.uvalue_estimates,
|
||||
property=self.property,
|
||||
total_floor_area_group_decile=self.total_floor_area_group_decile
|
||||
)
|
||||
self.estimated_u_value = u_value
|
||||
if is_solid_brick:
|
||||
|
||||
if u_value >= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
|
||||
self.find_insulation(u_value)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -206,13 +206,6 @@ class TestWallRecommendations:
|
|||
) as f:
|
||||
return pickle.load(f)
|
||||
|
||||
@pytest.fixture
|
||||
def uvalue_estimates(self):
|
||||
with open(
|
||||
os.path.abspath(os.path.dirname(__file__)) + "/test_data/uvalue_estimates.pkl", "rb"
|
||||
) as f:
|
||||
return pickle.load(f)
|
||||
|
||||
@pytest.fixture
|
||||
def mock_wall_rec_instance(self):
|
||||
# Creating a mock instance of WallRecommendations with the necessary attributes
|
||||
|
|
@ -220,26 +213,22 @@ class TestWallRecommendations:
|
|||
property_mock.full_sap_epc = {"lodgement-date": "2000-01-01"} # or any date you want
|
||||
property_mock.data = {"construction-age-band": "1950"} # or any other data that fits your tests
|
||||
|
||||
uvalue_estimates_mock = Mock()
|
||||
|
||||
mock_wall_rec_instance = WallRecommendations(
|
||||
property_mock, uvalue_estimates_mock, "Decile 1", materials=wall_parts
|
||||
property_mock, "Decile 1", materials=wall_parts
|
||||
)
|
||||
return mock_wall_rec_instance
|
||||
|
||||
def test_init(self, input_properties, uvalue_estimates):
|
||||
def test_init(self, input_properties):
|
||||
obj = WallRecommendations(
|
||||
property_instance=input_properties[0],
|
||||
uvalue_estimates=uvalue_estimates,
|
||||
total_floor_area_group_decile="Decile 1",
|
||||
materials=wall_parts
|
||||
)
|
||||
assert obj
|
||||
assert obj.property
|
||||
assert obj.uvalue_estimates
|
||||
assert obj.total_floor_area_group_decile == "Decile 1"
|
||||
|
||||
def test_uvalue_0_16(self, input_properties, uvalue_estimates):
|
||||
def test_uvalue_0_16(self, input_properties):
|
||||
"""
|
||||
This tests the wall description Average thermal transmittance 0.16 W/m-¦K
|
||||
The important data for this recommendation is:
|
||||
|
|
@ -251,7 +240,6 @@ class TestWallRecommendations:
|
|||
input_properties[0].year_built = 2014
|
||||
recommender = WallRecommendations(
|
||||
property_instance=input_properties[0],
|
||||
uvalue_estimates=uvalue_estimates,
|
||||
total_floor_area_group_decile="Decile 1",
|
||||
materials=wall_parts
|
||||
)
|
||||
|
|
@ -260,7 +248,7 @@ class TestWallRecommendations:
|
|||
# This should be empty
|
||||
assert recommender.recommendations == []
|
||||
|
||||
def test_solid_brick_no_insulation(self, input_properties, uvalue_estimates):
|
||||
def test_solid_brick_no_insulation(self, input_properties):
|
||||
"""
|
||||
This tests a property with a wall description of Solid brick, as built, no insulation (assumed)
|
||||
The property was built in 1930, right on the threshold for when cavity walls were introduced
|
||||
|
|
@ -271,10 +259,12 @@ class TestWallRecommendations:
|
|||
"""
|
||||
input_properties[1].year_built = 1930
|
||||
input_properties[1].insulation_wall_area = 100
|
||||
input_properties[1].walls["clean_description"] = "Solid brick, as built, no insulation"
|
||||
input_properties[1].walls["is_sandstone_or_limestone"] = False
|
||||
input_properties[1].age_band = "A"
|
||||
|
||||
recommender = WallRecommendations(
|
||||
property_instance=input_properties[1],
|
||||
uvalue_estimates=uvalue_estimates,
|
||||
total_floor_area_group_decile="Decile 1",
|
||||
materials=wall_parts
|
||||
)
|
||||
|
|
@ -296,7 +286,7 @@ class TestWallRecommendations:
|
|||
recommender.recommendations
|
||||
)
|
||||
|
||||
def test_solid_brick_insulation(self, input_properties, uvalue_estimates):
|
||||
def test_solid_brick_insulation(self, input_properties):
|
||||
"""
|
||||
This tests a property with a wall description of Solid brick, as built, insulation (assumed)
|
||||
The property was built in 1991, after cavity walls were introduced
|
||||
|
|
@ -311,7 +301,6 @@ class TestWallRecommendations:
|
|||
input_properties[6].year_built = 1991
|
||||
recommender = WallRecommendations(
|
||||
property_instance=input_properties[6],
|
||||
uvalue_estimates=uvalue_estimates.walls.to_dict("records"),
|
||||
total_floor_area_group_decile="Decile 1",
|
||||
materials=wall_parts
|
||||
)
|
||||
|
|
@ -390,39 +379,10 @@ class TestWallRecommendationsBase:
|
|||
return property_mock
|
||||
|
||||
@pytest.fixture
|
||||
def uvalue_estimations_mock(self):
|
||||
uvalue_estimations_mock = MagicMock(spec=UvalueEstimations)
|
||||
|
||||
uvalue_estimations_mock.walls = pd.DataFrame([
|
||||
{
|
||||
'local-authority': 'E09000012',
|
||||
'property-type': 'Bungalow',
|
||||
'walls-energy-eff': 'Very Good',
|
||||
'walls-env-eff': 'Very Good',
|
||||
'built-form': 'End-Terrace',
|
||||
'number-habitable-rooms': '', 'number-heated-rooms': '', 'total-floor-area_group': 'Decile 1',
|
||||
'median_thermal_transmittance': 0.15, 'n_samples': 1
|
||||
}
|
||||
])
|
||||
|
||||
uvalue_estimations_mock.walls_decile_data = {
|
||||
'decile_labels': ['Decile 1', 'Decile 2', 'Decile 3', 'Decile 4', 'Decile 5', 'Decile 6', 'Decile 7',
|
||||
'Decile 8', 'Decile 9', 'Decile 10'],
|
||||
'decile_boundaries': np.array([11., 49., 52., 56., 63., 70., 74., 79.,
|
||||
90., 103.8, 1936.])}
|
||||
|
||||
uvalue_estimations_mock.classify_decile_newvalues.return_value = ["Decile 1"]
|
||||
return uvalue_estimations_mock
|
||||
|
||||
@pytest.fixture
|
||||
def wall_recommendations_instance(self, property_mock, uvalue_estimations_mock):
|
||||
def wall_recommendations_instance(self, property_mock):
|
||||
wall_recommendations_instance = WallRecommendations(
|
||||
property_mock, uvalue_estimations_mock, "Decile 1", materials=wall_parts
|
||||
property_mock, "Decile 1", materials=wall_parts
|
||||
)
|
||||
wall_recommendations_instance.uvalue_estimates.walls_decile_data = {
|
||||
"decile_labels": MagicMock(),
|
||||
"decile_boundaries": MagicMock()
|
||||
}
|
||||
return wall_recommendations_instance
|
||||
|
||||
def test_ewi_valid_in_conservation_area(self, wall_recommendations_instance):
|
||||
|
|
@ -443,7 +403,11 @@ class TestWallRecommendationsBase:
|
|||
"thermal_transmittance": None,
|
||||
"is_solid_brick": False,
|
||||
"is_cavity_wall": False,
|
||||
"insulation_thickness": "none"
|
||||
"insulation_thickness": "none",
|
||||
"clean_description": "Solid brick, as built, no insulation",
|
||||
"is_granite_or_whinstone": False,
|
||||
"is_sandstone_or_limestone": False,
|
||||
}
|
||||
wall_recommendations_instance.property.age_band = "A"
|
||||
with pytest.raises(NotImplementedError):
|
||||
wall_recommendations_instance.recommend()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue