Source code for agents.House

"""
Defines the House agent for the simulation.

This module contains the `House` class, a GeoAgent that represents a physical 
building in the model. It holds attributes like construction year, area, and 
energy demand, and is directly linked to a `Houseowner` agent and a 
`Heating_system`. It also includes an Enum for different heating terminal types.

:Authors:
 - Ivan Digel <ivan.digel@uni-kassel.de>
 - Sascha Holzhauer <sascha.holzhauer@uni-kassel.de>

"""
import mesa_geo as mg
import numpy as np
import pandas as pd
import logging
from modules.Rng import rng_house_init
from enum import Enum, auto
from modules.Excel_input_read import Milieu_table
from helpers.config import settings

logger = logging.getLogger("ahoi")
logger.setLevel(logging.INFO)

[docs] class House(mg.GeoAgent): """A GeoAgent representing a single residential building in the model. This agent models the physical characteristics of a building, including its geographical footprint, age, size, and energy requirements. Each house is associated with a `Houseowner` agent and contains the currently installed heating system. Attributes ---------- milieu_table : Milieu_table A table containing parameters for different socio-economic milieus. milieu : Milieu The milieu associated with the house's owner. year : int The year the house was constructed. area : float The living area of the house in square meters. energy_demand : float The annual energy demand for heating in kWh per sq.m. per year. current_heating : Heating_system The heating system currently installed in the house. houseowner : Houseowner The `Houseowner` agent who owns and lives in the house. subarea : str The name of the geographical subarea where the house is located. heat_load : float The heating load of the house in kW. """ def __init__(self, unique_id, model, geometry, crs, current_heating=None): """Initializes a House agent. Parameters ---------- unique_id : int A unique identifier for the agent, typically provided by MESA-Geo. model : mesa.Model The main model instance. geometry : shapely.geometry.BaseGeometry A Shapely object representing the house's geographical footprint. crs : str or pyproj.CRS The coordinate reference system of the geometry. current_heating : Heating_system, optional The heating system to be installed initially. Defaults to None. """ super().__init__(unique_id, model, geometry, crs) self.milieu_table = Milieu_table() self.milieu = None self.year = None self.area = None self.energy_demand = None self.current_heating = current_heating self.houseowner = None self.subarea = None self.heat_load = None
[docs] def set_house_owner(self, houseowner): """Assigns a Houseowner agent to this house. Parameters ---------- houseowner : Houseowner The `Houseowner` agent to be linked to this house. """ self.houseowner = houseowner
[docs] def knockknock(self): """Returns the owner of the house. Returns ------- Houseowner The `Houseowner` agent associated with this house. """ return self.houseowner
[docs] def generate_area_distribution(self, mean, deviation): """Generates a living area value from a normal distribution. This method is used for initializing house areas when specific data is not available. Parameters ---------- mean : float The mean living area in square meters. deviation : float The standard deviation from the mean in square meters. Returns ------- float A randomly generated value for the living area. """ return rng_house_init().normal(mean, deviation)
[docs] def generate_energy_demand_distribution(self, mean, deviation): """Generates an energy demand value from a normal distribution. This method is used for initializing energy demand when specific data is not available. Parameters ---------- mean : float The mean energy demand in kWh per square meter per year. deviation : float The standard deviation from the mean. Returns ------- float A randomly generated value for the energy demand. """ return rng_house_init().normal(mean, deviation)
[docs] def define_energy_demand(self, year, heat_demand): """Sets the specific energy demand based on construction year and data source. This method calculates the energy demand (in kWh/m²/a) based on one of two modes defined in the model settings: - 'eqcity': Uses a predefined lookup table based on building age classes. - 'ubem': Calculates the demand by dividing the total annual heat demand by the house's area. Parameters ---------- year : int The construction year of the house. heat_demand : float The total annual heat demand of the house in kWh, used in 'ubem' mode. Returns ------- float The calculated specific energy demand in kWh per square meter per year. """ if settings.data.heat_demand == "eqcity": classes_df = pd.DataFrame( { "Start": [ 1860, 1919, 1949, 1958, 1969, 1979, 1984, 1995, 2002, 2010, ], "End": [1918, 1948, 1957, 1968, 1978, 1983, 1994, 2001, 2009, 2050], "Demand": [181, 164, 182, 180, 153, 120, 132, 122, 87, 50], } ) for _, row in classes_df.iterrows(): if row["Start"] <= year <= row["End"]: return row["Demand"] break elif settings.data.heat_demand == "ubem": demand = heat_demand / self.area return demand