mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
adding materials to recommender
This commit is contained in:
parent
b7c913ec3f
commit
8e5388b1ea
5 changed files with 41 additions and 20 deletions
|
|
@ -60,7 +60,7 @@ class GoogleSolarApi:
|
||||||
# Error Messages
|
# Error Messages
|
||||||
ENTITY_NOT_FOUND_ERROR = 'Requested entity was not found.'
|
ENTITY_NOT_FOUND_ERROR = 'Requested entity was not found.'
|
||||||
|
|
||||||
def __init__(self, api_key, max_retries=5):
|
def __init__(self, api_key, solar_materials: list, max_retries=5):
|
||||||
"""
|
"""
|
||||||
Initialize the GoogleSolarApi class with the provided API key and maximum retries.
|
Initialize the GoogleSolarApi class with the provided API key and maximum retries.
|
||||||
|
|
||||||
|
|
@ -87,6 +87,7 @@ class GoogleSolarApi:
|
||||||
|
|
||||||
# Indicates if we think we have both units attached to a semi-detached property
|
# Indicates if we think we have both units attached to a semi-detached property
|
||||||
self.double_property = False
|
self.double_property = False
|
||||||
|
self.solar_materials = solar_materials
|
||||||
|
|
||||||
def get_building_insights(self, longitude, latitude, required_quality="MEDIUM", max_retries=None):
|
def get_building_insights(self, longitude, latitude, required_quality="MEDIUM", max_retries=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -208,13 +209,13 @@ class GoogleSolarApi:
|
||||||
self.optimise_solar_configuration(
|
self.optimise_solar_configuration(
|
||||||
energy_consumption=energy_consumption,
|
energy_consumption=energy_consumption,
|
||||||
is_building=is_building,
|
is_building=is_building,
|
||||||
property_instance=property_instance
|
property_instance=property_instance,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Finally, if we have a double property, we half the data we stored area
|
# Finally, if we have a double property, we half the data we stored area
|
||||||
if self.double_property:
|
if self.double_property:
|
||||||
self.roof_area = self.roof_area / 2
|
self.roof_area = self.roof_area / 2
|
||||||
self.floor_area = self.floor_area / 2
|
self.floor_area = float(self.floor_area) / 2
|
||||||
|
|
||||||
def save_to_db(self, session, uprns_to_location, scenario_type):
|
def save_to_db(self, session, uprns_to_location, scenario_type):
|
||||||
if self.insights_data is None:
|
if self.insights_data is None:
|
||||||
|
|
@ -279,7 +280,9 @@ class GoogleSolarApi:
|
||||||
installation_life_span)) /
|
installation_life_span)) /
|
||||||
(1 - efficiency_depreciation_factor))
|
(1 - efficiency_depreciation_factor))
|
||||||
|
|
||||||
def optimise_solar_configuration(self, energy_consumption, is_building=False, property_instance=None):
|
def optimise_solar_configuration(
|
||||||
|
self, energy_consumption, is_building=False, property_instance=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Optimise the solar panel configuration for the building.
|
Optimise the solar panel configuration for the building.
|
||||||
:return:
|
:return:
|
||||||
|
|
@ -321,9 +324,25 @@ class GoogleSolarApi:
|
||||||
if roi_summary["n_panels"].sum() < min_panels:
|
if roi_summary["n_panels"].sum() < min_panels:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
total_panels = roi_summary["n_panels"].sum()
|
||||||
|
# find a product which is suitable for the ROI calc, without a battery. 400 Watts for the baseline
|
||||||
|
solar_product = next(
|
||||||
|
(m for m in self.solar_materials if m["type"] == "solar_pv" and
|
||||||
|
abs(m["size"] - (400 * total_panels) / 1000) < 0.1 and not m["includes_battery"]),
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
if solar_product is None:
|
||||||
|
logger.info("No suitable solar product found for the configuration with %d panels.", total_panels)
|
||||||
|
continue
|
||||||
|
|
||||||
total_cost = Costs.solar_pv(
|
total_cost = Costs.solar_pv(
|
||||||
n_panels=roi_summary["n_panels"].sum(),
|
solar_product=solar_product,
|
||||||
has_battery=False,
|
# We don't actually need scaffolding for the ROI calc
|
||||||
|
scaffolding_options=[
|
||||||
|
{"total_cost": 1000, "size": property_instance.number_of_floors},
|
||||||
|
{"total_cost": 1000, "size": 3}
|
||||||
|
],
|
||||||
# Assume the most amount of scaffolding
|
# Assume the most amount of scaffolding
|
||||||
n_floors=3 if property_instance is None else property_instance.number_of_floors
|
n_floors=3 if property_instance is None else property_instance.number_of_floors
|
||||||
)["total"]
|
)["total"]
|
||||||
|
|
@ -805,7 +824,8 @@ class GoogleSolarApi:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def unit_solar_analysis(
|
def unit_solar_analysis(
|
||||||
cls, unit_solar_config: List, input_properties: List[Property], session, body, google_solar_api_key: str
|
cls, unit_solar_config: List, input_properties: List[Property], session, body, google_solar_api_key: str,
|
||||||
|
solar_materials: list
|
||||||
):
|
):
|
||||||
|
|
||||||
if not unit_solar_config:
|
if not unit_solar_config:
|
||||||
|
|
@ -844,7 +864,7 @@ class GoogleSolarApi:
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
solar_api_client = cls(api_key=google_solar_api_key)
|
solar_api_client = cls(api_key=google_solar_api_key, solar_materials=solar_materials)
|
||||||
solar_api_client.get(
|
solar_api_client.get(
|
||||||
longitude=unit["longitude"],
|
longitude=unit["longitude"],
|
||||||
latitude=unit["latitude"],
|
latitude=unit["latitude"],
|
||||||
|
|
@ -852,7 +872,7 @@ class GoogleSolarApi:
|
||||||
is_building=False,
|
is_building=False,
|
||||||
session=session,
|
session=session,
|
||||||
uprn=unit["uprn"],
|
uprn=unit["uprn"],
|
||||||
property_instance=property_instance
|
property_instance=property_instance,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Store the data in the database
|
# Store the data in the database
|
||||||
|
|
|
||||||
|
|
@ -689,7 +689,7 @@ async def model_engine(body: PlanTriggerRequest):
|
||||||
building_solar_config=building_solar_config,
|
building_solar_config=building_solar_config,
|
||||||
input_properties=input_properties,
|
input_properties=input_properties,
|
||||||
session=session,
|
session=session,
|
||||||
google_solar_api_key=get_settings().GOOGLE_SOLAR_API_KEY
|
google_solar_api_key=get_settings().GOOGLE_SOLAR_API_KEY,
|
||||||
)
|
)
|
||||||
|
|
||||||
input_properties = GoogleSolarApi.unit_solar_analysis(
|
input_properties = GoogleSolarApi.unit_solar_analysis(
|
||||||
|
|
@ -697,7 +697,8 @@ async def model_engine(body: PlanTriggerRequest):
|
||||||
input_properties=input_properties,
|
input_properties=input_properties,
|
||||||
session=session,
|
session=session,
|
||||||
body=body,
|
body=body,
|
||||||
google_solar_api_key=get_settings().GOOGLE_SOLAR_API_KEY
|
solar_materials=[m for m in materials if m["type"] == "solar_pv"],
|
||||||
|
google_solar_api_key=get_settings().GOOGLE_SOLAR_API_KEY,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info("Identifying property recommendations")
|
logger.info("Identifying property recommendations")
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class FireplaceRecommendations(Definitions):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
property_instance: Property,
|
property_instance: Property,
|
||||||
materials: list = None,
|
materials: list,
|
||||||
):
|
):
|
||||||
self.property = property_instance
|
self.property = property_instance
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import re
|
import re
|
||||||
import backend.app.assumptions as assumptions
|
import backend.app.assumptions as assumptions
|
||||||
from recommendations.Costs import Costs, BOILER_UPGRADE_SCHEME_ASHP_VALUE
|
|
||||||
from recommendations.recommendation_utils import (
|
from recommendations.recommendation_utils import (
|
||||||
check_simulation_difference, override_costs, combine_recommendation_configs
|
check_simulation_difference, override_costs, combine_recommendation_configs
|
||||||
)
|
)
|
||||||
from backend.Property import Property
|
from backend.Property import Property
|
||||||
from backend.app.plan.schemas import MEASURE_MAP
|
from backend.app.plan.schemas import MEASURE_MAP
|
||||||
|
from recommendations.Costs import Costs
|
||||||
from etl.epc_clean.epc_attributes.MainheatAttributes import MainHeatAttributes
|
from etl.epc_clean.epc_attributes.MainheatAttributes import MainHeatAttributes
|
||||||
from etl.epc_clean.epc_attributes.HotWaterAttributes import HotWaterAttributes
|
from etl.epc_clean.epc_attributes.HotWaterAttributes import HotWaterAttributes
|
||||||
from etl.epc_clean.epc_attributes.MainFuelAttributes import MainFuelAttributes
|
from etl.epc_clean.epc_attributes.MainFuelAttributes import MainFuelAttributes
|
||||||
|
|
@ -85,7 +85,7 @@ class HeatingRecommender:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, property_instance: Property, materials: list = None):
|
def __init__(self, property_instance: Property, materials: list):
|
||||||
self.property = property_instance
|
self.property = property_instance
|
||||||
self.costs = Costs(self.property)
|
self.costs = Costs(self.property)
|
||||||
|
|
||||||
|
|
@ -573,12 +573,12 @@ class HeatingRecommender:
|
||||||
if has_cavity_or_loft_recommendations:
|
if has_cavity_or_loft_recommendations:
|
||||||
description = description + (
|
description = description + (
|
||||||
f" You must ensure that the property has an insulated cavity and "
|
f" You must ensure that the property has an insulated cavity and "
|
||||||
f"270mm+ loft insulation to qualify for the grant, to claim £"
|
f"270mm+ loft insulation to qualify for the grant, to claim £7,500"
|
||||||
f"{BOILER_UPGRADE_SCHEME_ASHP_VALUE} of funding from the boiler upgrade scheme grant. "
|
f" of funding from the boiler upgrade scheme grant. "
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
description = description + (
|
description = description + (
|
||||||
f" £{BOILER_UPGRADE_SCHEME_ASHP_VALUE} of funding can be claimed from the boiler upgrade scheme"
|
f" £7,500 of funding can be claimed from the boiler upgrade scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
simulation_config = {
|
simulation_config = {
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,11 @@ class Recommendations:
|
||||||
property_instance=property_instance, materials=materials
|
property_instance=property_instance, materials=materials
|
||||||
)
|
)
|
||||||
self.draught_proofing_recommender = DraughtProofingRecommendations(property_instance=property_instance)
|
self.draught_proofing_recommender = DraughtProofingRecommendations(property_instance=property_instance)
|
||||||
self.fireplace_recommender = FireplaceRecommendations(property_instance=property_instance)
|
self.fireplace_recommender = FireplaceRecommendations(property_instance=property_instance, materials=materials)
|
||||||
self.lighting_recommender = LightingRecommendations(property_instance=property_instance, materials=materials)
|
self.lighting_recommender = LightingRecommendations(property_instance=property_instance, materials=materials)
|
||||||
self.windows_recommender = WindowsRecommendations(property_instance=property_instance, materials=materials)
|
self.windows_recommender = WindowsRecommendations(property_instance=property_instance, materials=materials)
|
||||||
self.solar_recommender = SolarPvRecommendations(property_instance=property_instance)
|
self.solar_recommender = SolarPvRecommendations(property_instance=property_instance, materials=materials)
|
||||||
self.heating_recommender = HeatingRecommender(property_instance=property_instance)
|
self.heating_recommender = HeatingRecommender(property_instance=property_instance, materials=materials)
|
||||||
self.hotwater_recommender = HotwaterRecommendations(property_instance=property_instance)
|
self.hotwater_recommender = HotwaterRecommendations(property_instance=property_instance)
|
||||||
self.secondary_heating_recommender = SecondaryHeating(property_instance=property_instance)
|
self.secondary_heating_recommender = SecondaryHeating(property_instance=property_instance)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue