adding minimums for the number of SAP points solar PV will deliver

This commit is contained in:
Khalim Conn-Kowlessar 2025-02-15 22:33:01 +00:00
parent 846cd99631
commit ebed7027ac
3 changed files with 30 additions and 2 deletions

View file

@ -1259,7 +1259,9 @@ class Property:
if (self.building_id is not None) and (self.solar_panel_configuration is not None):
return True
# If the property is in a conservation area, don't recommend
# If the property is in a conservation area, is listed or is a heriage building, solar panels
# become a difficult measure to generally get through planning restrictions and so we do not recommend
# solar panels
if self.restricted_measures:
return False

View file

@ -623,6 +623,13 @@ class Recommendations:
if li_sap_limit is not None:
property_phase_impact["sap"] = min(property_phase_impact["sap"], li_sap_limit)
if rec["type"] == "solar_pv":
# We use the SAP points in the recommendation as a minimum
property_phase_impact["sap"] = (
rec["sap_points"] if property_phase_impact["sap"] < rec["sap_points"] else
property_phase_impact["sap"]
)
# Insert this information into the recommendation.
if not rec.get("survey", False):
rec["sap_points"] = property_phase_impact["sap"]

View file

@ -14,11 +14,16 @@ class SolarPvRecommendations:
# This was previously set to 250w, but has been upped to 400 based on the systems used by Cotswolrd Energy Group
SOLAR_PANEL_WATTAGE = 400
# For domestic properties, we don't recommend a solar PV system with wattage outside of these
# bounds
MAX_SYSTEM_WATTAGE = 6000
MIN_SYSTEM_WATTAGE = 1000
# the maximum area of root we allow to be covered in solar panels for our recommendations.
MAX_ROOF_AREA_PERCENTAGE = 0.7
SAP_POINTS_PER_5_PERCENT_ROOF_COVERAGE = 1
def __init__(self, property_instance):
"""
:param property_instance: Instance of the Property class, for the home associated to property_id
@ -212,6 +217,20 @@ class SolarPvRecommendations:
roof_coverage_percent = round(recommendation_config["panneled_roof_area"] / roof_area * 100)
# We round up to the nearest 5
roof_coverage_percent = np.ceil(roof_coverage_percent / 5) * 5
# Typically, we've observed that every 5% of additional roof coverage will result in at least
# an additional 1 SAP points (though often 2 points) Given this, we can add a reasonable minimum
# for the number of SAP points we might expect. We've observed that for some cases where properties
# are hitting the higher SAP scores (e.g. EPC A and above), the model can sometimes under-predict
# the number of SAP points. This appears to be due to a relatively small number of properties
# actually achieving the upper echelons of EPC rating. This can be the case if we're simulating a
# whole house retrofit where the home is getting complete insulation, a heat pump and solar panels.
# Because panels are the final recommendation, they are often the measure that takes the home
# into the medium to high EPC A ranges and so because of a lack of training data, this means that
# we might sometime under-predict. This minimum is intended to try and reduce the negative impact
# of this. This minimum is used in Recommendations.calculate_recommendation_impact
minimum_sap_points = (roof_coverage_percent / 5) * self.SAP_POINTS_PER_5_PERCENT_ROOF_COVERAGE
for has_battery in [False, True]:
cost_result = self.costs.solar_pv(
has_battery=has_battery,
@ -240,7 +259,7 @@ class SolarPvRecommendations:
"description": description,
"starting_u_value": None,
"new_u_value": None,
"sap_points": None,
"sap_points": minimum_sap_points,
"already_installed": already_installed,
**cost_result,
# This is required for simulating the SAP impact. solar_pv_percentage is between 0 & 1 so we