Source code for modules.Heating_systems

"""
Defines the classes and methods for all heating systems in the simulation.

This module provides the core data structures for representing heating systems.
It includes a generic `Heating_system` base class that defines the common
attributes and functionalities shared by all systems.

Specific heating technologies are implemented as subclasses. 
These subclasses inherit the common framework from the base class 
but are initialised with their own unique parameters 
loaded from external data files.

:Authors:
 - Ivan Digel <ivan.digel@uni-kassel.de>
 - Sascha Holzhauer <sascha.holzhauer@uni-kassel.de>
"""
import sys
import os
import pandas as pd
import ast
import uuid
import math
from modules.Rng import rng_heating_init
from modules.Excel_input_read import Heating_params_table
#from statsmodels.discrete.tests.results.results_count_robust_cluster import params_table
current_dir = os.path.dirname(os.path.abspath(__file__))
src_dir = os.path.dirname(current_dir)
if src_dir not in sys.path:
    sys.path.insert(0, src_dir)
from helpers.config import settings

params_table = None

[docs] def init_param_table(): """ Initialises the global heating system parameter table. This function must be called once at the beginning of a simulation run before any `Heating_system` objects are created. It creates an instance of `Heating_params_table`, loading the data from the input file and making it globally accessible for all heating system instances. """ global params_table params_table = Heating_params_table()
[docs] class Heating_system: """ A base class representing a generic heating system. This class serves as the blueprint for all heating system types in the model. It defines the core attributes and perceived characteristics. It also contains the methods for calculating key performance and cost indicators, including installation costs, fuel costs, operating costs, and emissions. Attributes ---------- unique_id : uuid.UUID A unique identifier for the system instance. table : pandas.Series The row from the parameters table corresponding to the system type. age : int The number of steps (weeks) since the system was installed. breakdown : bool A flag indicating if the system has broken down. investment : float or None The remaining investment cost to be paid back. rating : float or None An agent's calculated attitude (rating) towards this system. params : dict A dictionary holding the core parameters of the system. Each key maps to a list of two values: the parameter's point value and its associated uncertainty (e.g., `[value, uncertainty]`). riskiness : float A calculated score from 0 to 1 representing the perceived riskiness of installing this system. weibull_lifetime : bool Defines whether the lifetime will be calculated using Weibull or Uniform """ def __init__(self): """ Initializes a new Heating_system instance with default values. """ # Seed control part self.unique_id = uuid.uuid4() # Data table self.table = None # Other params self.age = 0 # Counter of HS's lifetime after installation self.breakdown = False # Marks a broken system self.total_energy_demand = None # House and system-specific demand self.investment = None self.payback = None self.subsidised = False self.loan = None self.availability = None self.power = None self.fuel_price_contract_term = None self.heat_delivery_contract = None # The part used for the Theory of Planned Behaviour self.rating = None # Attitude of a houseowner towards certain HS self.neighbours_opinions = {} # Storage of neighbours' opinions self.social_norm = None # Perceived social "norm", mean of the opinions self.behavioural_control = None # PERCEIVED behavioural control self.weibull_lifetime = None self.source = None # The part used for the rating calculation self.params = { "operation_effort": [None, None], # Operational effort, hours per year "fuel_cost": [None, None], # Fuel/energy cost, EUR per year "emissions": [None, None], # Emissions, grams of CO2 equivalent per kWh "price": [None, None], # Installation price, EUR "installation_effort": [None, None], # Working hours "opex": [None, None], # Operating expenses, EUR per Year } self.riskiness = 0 #The higher, the worse [0, 1] # Methods part
[docs] def generate_lifetime(self, min_weeks, max_weeks, shape=None, scale=None): """ Generates a random lifetime for the system, using one of two modes. Mode 1: Uniform (Default) If 'shape' and 'scale' are NOT provided (or are None), this generates a uniform random integer between 'min_weeks' and 'max_weeks' (inclusive). Mode 2: Weibull If 'shape' and 'scale' ARE provided, this generates a random lifetime from a Weibull distribution. In this mode, 'min_weeks' and 'max_weeks' are IGNORED. The final lifetime is rounded to the nearest integer. Parameters ---------- min_weeks : int The minimum possible lifetime (inclusive) for the uniform distribution. Ignored if 'shape' and 'scale' are provided. max_weeks : int The maximum possible lifetime (inclusive) for the uniform distribution. Ignored if 'shape' and 'scale' are provided. shape : float, optional The shape parameter (k) for the Weibull distribution. If provided, 'scale' must also be provided. scale : float, optional The scale parameter (lambda) for the Weibull distribution. If provided, 'shape' must also be provided. Returns ------- int The generated lifetime in weeks. """ rng = rng_heating_init() # Get the random number generator if self.weibull_lifetime: # --- Mode 1: Unrestricted Weibull Distribution --- # 'min_weeks' and 'max_weeks' are ignored, as requested. lifetime = max(min_weeks, scale * rng.weibull(shape)) else: # --- Mode 2: Uniform Integer Distribution --- # We use 'max_weeks + 1' because rng.integers is exclusive # of the upper bound (i.e., [low, high) ) lifetime = rng.integers(min_weeks, max_weeks + 1) # Round to the nearest integer for both cases return round(lifetime)
[docs] def get_name(self): """ Returns the name of the heating system class. Returns ------- str The class name as a string. """ return type(self).__name__
[docs] def breakdown_check(self): """ Check if the system's age has exceeded its lifetime. If the age is greater than the system's generated lifetime, the `breakdown` flag is set to True. """ if self.lifetime < self.age: self.breakdown = True self.investment = 0
[docs] def payback_check(self): """ Reduce the remaining investment value. This method is called periodically to simulate the payback of the initial investment. """ if self.investment != 0: leftovers = self.investment - self.payback self.investment = leftovers if leftovers >= 0 else 0
[docs] def calculate_all_attributes(self, area=None, energy_demand=None, house=None, heat_load = None): """ Calculates all cost and performance attributes for the system. This is a convenience method that runs all individual calculation methods to populate the system's `params` dictionary based on the properties of a given house. Parameters ---------- area : float, optional The living area of the house in square meters. energy_demand : float, optional The specific energy demand of the house in kWh per square meter per year. house : House, optional A House object from which to derive area, energy_demand, and heat_load. If provided, it overrides other parameters. heat_load : float, optional The heat load of the house in kW. """ if house: area = house.area energy_demand=house.energy_demand heat_load=house.heat_load """Perform all calculations in one method""" self.total_energy_demand = self.calculate_energy_demand( energy_demand=energy_demand, area=area ) self.params["price"][0] = self.calculate_installation_costs(area=area, heat_load=heat_load) self.params["fuel_cost"][0] = self.calculate_fuel_costs( energy_demand=self.total_energy_demand ) self.params["opex"][0] = self.calculate_operating_costs(area = area, heat_load=heat_load) self.params["emissions"][0] = self.calculate_emissions( energy_demand=self.total_energy_demand )
[docs] def calculate_installation_costs(self, area=None, heat_load=None): """ Calculates the installation cost for the heating system. The calculation logic depends on the system type. Some systems are priced based on the house's area, while others are priced based on the required heat load. Parameters ---------- area : float, optional The living area of the house in square meters. heat_load : float, optional The heat load of the house in kW. Returns ------- float The total installation cost in EUR. """ area_based = ["Heating_system_network_local", "Heating_system_GP_Joule", "Heating_system_district"] if self.heat_delivery_contract: return 0 elif type(self).__name__ == "Heating_system_electricity": price = self.table["price"] factor_area = self.table["factor_area"] factor_oppendorf = self.table["factor_oppendorf"] price_index = self.table["price_index"] sidecosts_index = self.table["sidecosts_index"] cost = ( price * area**factor_area * area * factor_oppendorf * price_index * sidecosts_index ) return math.floor(cost) elif type(self).__name__ in area_based: price = self.table["price"] factor_area = self.table["factor_area"] factor_oppendorf = self.table["factor_oppendorf"] price_index = self.table["price_index"] sidecosts_index = self.table["sidecosts_index"] correction_factor = self.table["heat_load_correction"] cost = ( price * area**factor_area * area * factor_oppendorf * price_index * sidecosts_index * correction_factor ) return math.floor(cost) else: price = float(self.table["heat_load_price"]) factor = float(self.table["heat_load_factor"]) correction_factor = float(self.table["heat_load_correction"]) cost = ( price * ((heat_load)**factor) * heat_load ) #Adjustments for network options, the same otherwise cost = cost * correction_factor return math.floor(cost)
[docs] def calculate_operating_costs(self, area, heat_load): """ Calculates the annual operating and maintenance costs (OPEX). Calculates the OPEX as a fraction of the initial installation cost. For systems with a heat delivery contract, the amortised installation cost is included in the annual OPEX. Parameters ---------- area : float The living area of the house in square meters. heat_load : float The heat load of the house in kW. Returns ------- float The total annual operating costs in EUR. """ price = self.calculate_installation_costs(area = area, heat_load = heat_load) if self.heat_delivery_contract: price_distributed = 52*(price / self.lifetime) factor_opex = self.table["factor_opex"] opex = price * factor_opex total_opex = opex + price_distributed return math.floor(total_opex) else: factor_opex = float(self.table["factor_opex"]) cost = price * factor_opex return math.floor(cost)
[docs] def calculate_fuel_costs(self, energy_demand): """ Calculates the annual energy costs. Parameters ---------- energy_demand : float The total final energy demand of the house in kWh per year. Returns ------- float The total annual fuel costs in EUR. """ fuel_cost = self.table["fuel_cost"] cost = fuel_cost * energy_demand return math.floor(cost)
[docs] def calculate_emissions(self, energy_demand): """ Calculate the annual CO2 equivalent emissions. Parameters ---------- energy_demand : float The total final energy demand of the house in kWh per year. Returns ------- float The total annual emissions in grams of CO2 equivalent. """ emissions = self.table["emissions"] total_emissions = emissions * energy_demand return math.floor(total_emissions)
[docs] def calculate_energy_demand(self, energy_demand, area): """ Calculates the final energy demand. This method adjusts a house's specific energy demand by applying a system-specific efficiency factor. The factor is chosen from a list based on which predefined energy demand class is closest to the house's demand. Parameters ---------- energy_demand : float The specific energy demand of the house in kWh per square meter per year. area : float The living area of the house in square meters. Returns ------- float The total final energy demand in kWh per year. """ # Create a DataFrame of demand and factor classes demand_classes = [50, 100, 150, 200, 250] factor_classes = ast.literal_eval(self.table["factor_energy"]) classes_df = pd.DataFrame({ "Demand": demand_classes, "Factor": factor_classes, }) # Identify the factor corresponding to the closest demand class factor = classes_df.loc[(classes_df["Demand"] - energy_demand).abs().idxmin(), "Factor"] # Calculate the processed area with a fixed scaling formula processed_area = area * (2.3 * 1.5 + 0.75) * 0.32 # Compute total energy demand total_demand = processed_area * energy_demand * factor return math.floor(total_demand)
[docs] def calculate_risk(self, agent): """ This method computes a 'riskiness' score between 0 and 1. The score is an average of several factors, including the financial risk from a potential loan and the system-specific uncertainty mitigated by the share of neighbours that have adopted the same system. Parameters ---------- agent : Houseowner The agent for whom the risk is being calculated. """ factors = {} # --- 1. Loan Risk --- price = self.params["price"][0] if self.loan and price > 0: loan_risk = min(1, self.loan.loan_amount / price) factors["loan_risk"] = loan_risk else: factors["loan_risk"] = 0 """ if self.fuel_price_contract_term: price_ratio = min(self.fuel_price_contract_term / self.lifetime, 1) price_risk = 1 - price_ratio factors["price_risk"] = price_risk else: factors["price_risk"] = 1 """ # --- 2. Uncertainty Risk --- graph = agent.model.grid.G successors_ids = set(graph.successors(agent.unique_id)) n_total_neighbors = len(successors_ids) n_dissatisfied = 0 n_known = 0 target_system_name = self.get_name() for neighbour_id, opinion_data in agent.neighbours_satisfaction.items(): if neighbour_id in successors_ids: if target_system_name in opinion_data: n_known += 1 if opinion_data[target_system_name] == "Dissatisfied": n_dissatisfied += 1 n_unknown = n_total_neighbors - n_known weight = agent.uncertainty_factor weighted_dissatisfaction = n_dissatisfied + (weight * n_unknown) """ if n_dissatisfied > 0: factors["uncertainty_risk"] = 1 - n_known / n_total_neighbors) else: factors["uncertainty_risk"] = 0""" factors["uncertainty_risk"] = weighted_dissatisfaction / n_total_neighbors final_risk = sum(factors.values()) / int(len(factors)) self.riskiness = final_risk
[docs] def count_neighbours(self, agent): """ This helper method counts the fraction of an agent's neighbours who have installed the same type of heating system. It returns a value representing the inverse of this fraction, where 1 indicates maximum uncertainty (no neighbours have the system) and 0 indicates minimum uncertainty (all neighbours have the system). Parameters ---------- agent : Houseowner The agent whose neighbours are being checked. Returns ------- float A value between 0 and 1 representing social uncertainty. """ total_systems = 0 target_systems = 0 for neighbour_system in agent.neighbours_systems.values(): total_systems += 1 if self.get_name() == neighbour_system: target_systems += 1 if total_systems != 0: target_share = target_systems / total_systems return 1 - target_share else: return 1
def __repr__(self): return f"{self.number}: {type(self)} | Price: {self.params['price']} | Rating: {self.rating}\n" def __str__(self): return self.__repr__()
[docs] class Heating_system_oil(Heating_system): """ Represents an oil-fired heating system. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the oil heating system with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 0 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [ self.table["operation_effort"], 0, ], # Operational effort, hours per year "fuel_cost": [None, 0], # Fuel/energy cost, EUR per year "emissions": [None, 0], # Emissions, grams of CO2 equivalent per kWh "price": [None, 0], # Installation price, EUR "installation_effort": [ self.table["installation_effort"], 0, ], # Working hours "opex": [None, 0], # Operating price, EUR per Year } # The part used by AHID self.conversion_params = { "es": "oil", "heat_sys": "cond_boiler", "ht": "flat", "ns": "no", }
[docs] class Heating_system_gas(Heating_system): """ Represents a gas-fired heating system. This class inherits from `Heating_system` and sets the specific parameters for a gas heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the gas heating system with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 1 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "gas", "heat_sys": "cond_boiler", "ht": "flat", "ns": "no", }
[docs] class Heating_system_heat_pump(Heating_system): """ Represents an independent heat pump. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the heat pump heating system with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 2 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "heat_re", "heat_sys": "hp_air", "ht": "flat", "ns": "no", }
[docs] class Heating_system_electricity(Heating_system): """ Represents an electricity-based heating system. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the electricity-based heating with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 3 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "electricity", "heat_sys": "cond_boiler_sol", "ht": "flat", "ns": "no", }
[docs] class Heating_system_pellet(Heating_system): """ Represents a pellet heating system. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the pellet heating system with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 4 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "wood", "heat_sys": "cond_boiler_sol", "ht": "flat", "ns": "no", }
[docs] class Heating_system_network_district(Heating_system): """ Represents a district grid-based heating system. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the district heating with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 5 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "wood", "heat_sys": "cond_boiler_sol", "ht": "dh", "ns": "no", }
[docs] class Heating_system_network_local(Heating_system): """ Represents a hot local network heating system. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the hot local network heating with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 6 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "wood", "heat_sys": "cond_boiler_sol", "ht": "dh", "ns": "no", }
[docs] class Heating_system_heat_pump_brine(Heating_system): """ Represents a heat pump-based cold local network heating system. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the heat pump-based cold local network with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 7 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "heat_re", "heat_sys": "hp_brine", "ht": "flat", "ns": "no", }
[docs] class Heating_system_GP_Joule(Heating_system): """ Represents a hot local network heating system provided by the firm "GP Joule". This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the hot local network provided by the firm GP Joule with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 6 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [None, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "wood", "heat_sys": "cond_boiler_sol", "ht": "dh", "ns": "no", }
[docs] class Heating_system_vacuum_tube(Heating_system): """ Represents a vacuum tube heating system. Not actually a heating system and is not used anywhere in the model. This class inherits from `Heating_system` and sets the specific parameters for an oil heating system by loading them from the global `params_table`. """ def __init__(self, table = None): """ Initialises the vacuum tube heating system with its specific parameters. Parameters ---------- table : Heating_params_table, optional The parameter table to use. If None, the global `params_table` is used, by default None. """ super().__init__() # Data table if table is None: table = params_table self.table = table.content.loc[type(self).__name__] # Used for the data collection and visualization self.number = 8 # Expected lifetime of a system self.weibull_lifetime = settings.data.heat_sys_weibull_generation self.lifetime = self.generate_lifetime( min_weeks = self.table["lifetime_lower"], max_weeks = self.table["lifetime_upper"], shape = self.table["weibull_shape"], scale = self.table["weibull_scale"] ) self.availability = self.table["availability"] # Used by plumber to install self.installation_time = self.table["installation_time"] # Satisfied/dissatisfied known neighbour owners ratio self.satisfied_ratio = None self.power = self.table["power"] self.fuel_price_contract_term = self.table["contract"] self.heat_delivery_contract = True if self.table["heat_delivery"] == 1 else False # The part used for the rating calculation self.params = { "operation_effort": [self.table["operation_effort"], 0], "fuel_cost": [None, 0], "emissions": [0, 0], "price": [None, 0], "installation_effort": [self.table["installation_effort"], 0], "opex": [None, 0], } self.conversion_params = { "es": "heat_re", "heat_sys": "cond_boiler_sol", "ht": "flat", "ns": "no", }
"""AHID Compatibility parameters es = energy source("gas", "oil", "wood", "electricity", "heat_re", "district_chp_mix", "district_steam_mix") heat_sys = heating system ("cond_boiler", "cond_boiler_sol", "low_temp_boiler", "low_temp_boiler_sol", "const_temp_boiler", "const_temp_boiler_sol", "pellet, pellet_sol", "hp_air", "hp_air_vent", "hp_brine", "hp_brine_vent", "dh") ht = heating type ("district", "central", "flat") ns = night setback ("yes", "no") """