from backend.Property import Property from typing import List from recommendations.Costs import Costs class LightingRecommendations: # We introduce a SAP limit to lighting, which is based on empirical findings. We do see cases where lighting is # worth more than 2 points, but this is unlikely in the context of other upgrades that can be made to the property SAP_LIMIT = 2 def __init__(self, property_instance: Property, materials: List): """ :param property_instance: Instance of the Property class, for the home associated to property_id :param materials: List of materials to be used in the recommendations """ self.property = property_instance self.costs = Costs(self.property) material = [ material for material in materials if material["type"] == "low_energy_lighting_installation" ] if len(material) != 1: raise ValueError("Incorrect number of low energy lighting materials specified") self.material = material[0] self.recommendation = [] @staticmethod def estimate_lighting_impact(number_of_bulbs: int): """ Placeholder function to estimate the actual energy savings of LEDs vs traditional lighting :return: """ wattage_incandescent = 60 # wattage of typical incandescent bulb in watts wattage_led = 10 # wattage of typical LED bulb in watts hours_per_day = 3 # average usage in hours per day days_per_year = 365 # days in a year national_grid_carbon_intensity = 162 # gCO2/kWh, average for 2023 in the UK # Energy usage per year for incandescent and LED bulbs (in kWh) energy_usage_incandescent_per_year = (wattage_incandescent / 1000) * hours_per_day * days_per_year energy_usage_led_per_year = (wattage_led / 1000) * hours_per_day * days_per_year # Energy savings per bulb per year energy_savings_per_bulb_per_year = energy_usage_incandescent_per_year - energy_usage_led_per_year # Total energy savings for all bulbs total_energy_savings_per_year = energy_savings_per_bulb_per_year * number_of_bulbs carbon_reduction_grams = total_energy_savings_per_year * national_grid_carbon_intensity carbon_reduction_tonnes = carbon_reduction_grams / 1_000_000 # converting grams to tonnes return total_energy_savings_per_year, carbon_reduction_tonnes def recommend(self, phase=0): """ This method will check if there are any lighting fittings that aren't low energy. If there are, the will recommend fitting the rest of the outlets with low energy lighting fittings :return: """ if self.property.lighting["low_energy_proportion"] == 100: return number_lighting_outlets = self.property.number_lighting_outlets # Number non lel outlets number_non_lel_outlets = number_lighting_outlets - ( self.property.lighting["low_energy_proportion"] * number_lighting_outlets ) number_non_lel_outlets = round(number_non_lel_outlets) if number_non_lel_outlets == 0: return # Get the cost of the fittings cost_result = self.costs.low_energy_lighting( number_of_lights=number_non_lel_outlets, number_current_lel_lights=number_lighting_outlets - number_non_lel_outlets, material=self.material ) if number_non_lel_outlets == 1: description = "Install low energy lighting in 1 remaining outlet" else: description = "Install low energy lighting in %s outlets" % str(number_non_lel_outlets) heat_demand_change, carbon_change = self.estimate_lighting_impact(number_non_lel_outlets) self.recommendation = [ { "phase": phase, "parts": [], "type": "low_energy_lighting", "description": description, "starting_u_value": None, "new_u_value": None, # For SAP points, we use the fact that lighting is usually worth 2 points and we scale this to # the proportion of lights that will be set to low energy "sap_points": round(2 * (number_non_lel_outlets / number_lighting_outlets), 2), "heat_demand": heat_demand_change, "co2_equivalent_savings": carbon_change, **cost_result } ]