| | """ |
| | Calculation Method Interface for HVAC Load Calculator |
| | |
| | This module defines the interface for calculation methods in the HVAC Load Calculator. |
| | It provides a base class that all calculation methods should inherit from. |
| | """ |
| |
|
| | from abc import ABC, abstractmethod |
| |
|
| |
|
| | class CalculationMethod(ABC): |
| | """ |
| | Abstract base class for HVAC load calculation methods. |
| | |
| | All calculation methods should inherit from this class and implement |
| | the required methods. |
| | """ |
| | |
| | @property |
| | @abstractmethod |
| | def name(self): |
| | """ |
| | Get the name of the calculation method. |
| | |
| | Returns: |
| | str: Name of the calculation method |
| | """ |
| | pass |
| | |
| | @property |
| | @abstractmethod |
| | def description(self): |
| | """ |
| | Get the description of the calculation method. |
| | |
| | Returns: |
| | str: Description of the calculation method |
| | """ |
| | pass |
| | |
| | @property |
| | @abstractmethod |
| | def version(self): |
| | """ |
| | Get the version of the calculation method. |
| | |
| | Returns: |
| | str: Version of the calculation method |
| | """ |
| | pass |
| | |
| | @abstractmethod |
| | def calculate(self, input_data): |
| | """ |
| | Perform the calculation. |
| | |
| | Args: |
| | input_data (dict): Input data for the calculation |
| | |
| | Returns: |
| | dict: Calculation results |
| | """ |
| | pass |
| | |
| | @abstractmethod |
| | def get_input_schema(self): |
| | """ |
| | Get the input schema for the calculation method. |
| | |
| | Returns: |
| | dict: JSON schema for input validation |
| | """ |
| | pass |
| | |
| | @abstractmethod |
| | def get_output_schema(self): |
| | """ |
| | Get the output schema for the calculation method. |
| | |
| | Returns: |
| | dict: JSON schema for output validation |
| | """ |
| | pass |
| |
|
| |
|
| | class ASHRAECoolingMethod(CalculationMethod): |
| | """ |
| | ASHRAE method for cooling load calculation. |
| | """ |
| | |
| | @property |
| | def name(self): |
| | return "ASHRAE Cooling Load Method" |
| | |
| | @property |
| | def description(self): |
| | return "Calculates cooling loads using the ASHRAE method for residential buildings." |
| | |
| | @property |
| | def version(self): |
| | return "1.0" |
| | |
| | def calculate(self, input_data): |
| | """ |
| | Calculate cooling load using the ASHRAE method. |
| | |
| | Args: |
| | input_data (dict): Input data for the calculation |
| | |
| | Returns: |
| | dict: Calculation results |
| | """ |
| | from cooling_load import CoolingLoadCalculator |
| | |
| | calculator = CoolingLoadCalculator() |
| | |
| | |
| | building_components = input_data.get('building_components', []) |
| | windows = input_data.get('windows', []) |
| | infiltration = input_data.get('infiltration', {}) |
| | internal_gains = input_data.get('internal_gains', {}) |
| | |
| | |
| | results = calculator.calculate_total_cooling_load( |
| | building_components=building_components, |
| | windows=windows, |
| | infiltration=infiltration, |
| | internal_gains=internal_gains |
| | ) |
| | |
| | return results |
| | |
| | def get_input_schema(self): |
| | """ |
| | Get the input schema for the ASHRAE cooling load method. |
| | |
| | Returns: |
| | dict: JSON schema for input validation |
| | """ |
| | return { |
| | "type": "object", |
| | "properties": { |
| | "building_components": { |
| | "type": "array", |
| | "items": { |
| | "type": "object", |
| | "properties": { |
| | "name": {"type": "string"}, |
| | "area": {"type": "number", "minimum": 0}, |
| | "u_value": {"type": "number", "minimum": 0}, |
| | "temp_diff": {"type": "number"} |
| | }, |
| | "required": ["area", "u_value", "temp_diff"] |
| | } |
| | }, |
| | "windows": { |
| | "type": "array", |
| | "items": { |
| | "type": "object", |
| | "properties": { |
| | "name": {"type": "string"}, |
| | "area": {"type": "number", "minimum": 0}, |
| | "u_value": {"type": "number", "minimum": 0}, |
| | "orientation": {"type": "string", "enum": ["north", "east", "south", "west", "horizontal"]}, |
| | "glass_type": {"type": "string"}, |
| | "shading": {"type": "string"}, |
| | "shade_factor": {"type": "number", "minimum": 0, "maximum": 1}, |
| | "temp_diff": {"type": "number"} |
| | }, |
| | "required": ["area", "u_value", "orientation", "temp_diff"] |
| | } |
| | }, |
| | "infiltration": { |
| | "type": "object", |
| | "properties": { |
| | "volume": {"type": "number", "minimum": 0}, |
| | "air_changes": {"type": "number", "minimum": 0}, |
| | "temp_diff": {"type": "number"} |
| | }, |
| | "required": ["volume", "air_changes", "temp_diff"] |
| | }, |
| | "internal_gains": { |
| | "type": "object", |
| | "properties": { |
| | "num_people": {"type": "integer", "minimum": 0}, |
| | "has_kitchen": {"type": "boolean"}, |
| | "equipment_watts": {"type": "number", "minimum": 0} |
| | }, |
| | "required": ["num_people"] |
| | } |
| | }, |
| | "required": ["building_components", "infiltration", "internal_gains"] |
| | } |
| | |
| | def get_output_schema(self): |
| | """ |
| | Get the output schema for the ASHRAE cooling load method. |
| | |
| | Returns: |
| | dict: JSON schema for output validation |
| | """ |
| | return { |
| | "type": "object", |
| | "properties": { |
| | "conduction_gain": {"type": "number"}, |
| | "window_conduction_gain": {"type": "number"}, |
| | "window_solar_gain": {"type": "number"}, |
| | "infiltration_gain": {"type": "number"}, |
| | "internal_gain": {"type": "number"}, |
| | "sensible_load": {"type": "number"}, |
| | "latent_load": {"type": "number"}, |
| | "total_load": {"type": "number"} |
| | }, |
| | "required": ["sensible_load", "latent_load", "total_load"] |
| | } |
| |
|
| |
|
| | class ASHRAEHeatingMethod(CalculationMethod): |
| | """ |
| | ASHRAE method for heating load calculation. |
| | """ |
| | |
| | @property |
| | def name(self): |
| | return "ASHRAE Heating Load Method" |
| | |
| | @property |
| | def description(self): |
| | return "Calculates heating loads using the ASHRAE method for residential buildings." |
| | |
| | @property |
| | def version(self): |
| | return "1.0" |
| | |
| | def calculate(self, input_data): |
| | """ |
| | Calculate heating load using the ASHRAE method. |
| | |
| | Args: |
| | input_data (dict): Input data for the calculation |
| | |
| | Returns: |
| | dict: Calculation results |
| | """ |
| | from heating_load import HeatingLoadCalculator |
| | |
| | calculator = HeatingLoadCalculator() |
| | |
| | |
| | building_components = input_data.get('building_components', []) |
| | infiltration = input_data.get('infiltration', {}) |
| | |
| | |
| | results = calculator.calculate_total_heating_load( |
| | building_components=building_components, |
| | infiltration=infiltration |
| | ) |
| | |
| | |
| | if 'location' in input_data and 'occupancy_type' in input_data: |
| | location = input_data.get('location') |
| | occupancy_type = input_data.get('occupancy_type') |
| | base_temp = input_data.get('base_temp', 18) |
| | |
| | annual_results = calculator.calculate_annual_heating_requirement( |
| | results['total_load'], |
| | location, |
| | occupancy_type, |
| | base_temp |
| | ) |
| | |
| | |
| | results.update(annual_results) |
| | |
| | return results |
| | |
| | def get_input_schema(self): |
| | """ |
| | Get the input schema for the ASHRAE heating load method. |
| | |
| | Returns: |
| | dict: JSON schema for input validation |
| | """ |
| | return { |
| | "type": "object", |
| | "properties": { |
| | "building_components": { |
| | "type": "array", |
| | "items": { |
| | "type": "object", |
| | "properties": { |
| | "name": {"type": "string"}, |
| | "area": {"type": "number", "minimum": 0}, |
| | "u_value": {"type": "number", "minimum": 0}, |
| | "temp_diff": {"type": "number", "minimum": 0} |
| | }, |
| | "required": ["area", "u_value", "temp_diff"] |
| | } |
| | }, |
| | "infiltration": { |
| | "type": "object", |
| | "properties": { |
| | "volume": {"type": "number", "minimum": 0}, |
| | "air_changes": {"type": "number", "minimum": 0}, |
| | "temp_diff": {"type": "number", "minimum": 0} |
| | }, |
| | "required": ["volume", "air_changes", "temp_diff"] |
| | }, |
| | "location": {"type": "string"}, |
| | "occupancy_type": {"type": "string"}, |
| | "base_temp": {"type": "number"} |
| | }, |
| | "required": ["building_components", "infiltration"] |
| | } |
| | |
| | def get_output_schema(self): |
| | """ |
| | Get the output schema for the ASHRAE heating load method. |
| | |
| | Returns: |
| | dict: JSON schema for output validation |
| | """ |
| | return { |
| | "type": "object", |
| | "properties": { |
| | "component_losses": { |
| | "type": "object", |
| | "additionalProperties": {"type": "number"} |
| | }, |
| | "total_conduction_loss": {"type": "number"}, |
| | "infiltration_loss": {"type": "number"}, |
| | "total_load": {"type": "number"}, |
| | "heating_degree_days": {"type": "number"}, |
| | "correction_factor": {"type": "number"}, |
| | "annual_energy_kwh": {"type": "number"}, |
| | "annual_energy_mj": {"type": "number"} |
| | }, |
| | "required": ["total_load"] |
| | } |
| |
|
| |
|
| | class CalculationMethodRegistry: |
| | """ |
| | Registry for calculation methods. |
| | |
| | This class maintains a registry of available calculation methods |
| | and provides methods to access them. |
| | """ |
| | |
| | def __init__(self): |
| | """Initialize the registry.""" |
| | self._methods = {} |
| | |
| | def register_method(self, method_id, method_class): |
| | """ |
| | Register a calculation method. |
| | |
| | Args: |
| | method_id (str): Unique identifier for the method |
| | method_class (type): Class implementing the CalculationMethod interface |
| | |
| | Returns: |
| | bool: True if registration was successful, False otherwise |
| | """ |
| | if method_id in self._methods: |
| | return False |
| | |
| | if not issubclass(method_class, CalculationMethod): |
| | return False |
| | |
| | self._methods[method_id] = method_class |
| | return True |
| | |
| | def get_method(self, method_id): |
| | """ |
| | Get a calculation method by ID. |
| | |
| | Args: |
| | method_id (str): Unique identifier for the method |
| | |
| | Returns: |
| | CalculationMethod: Instance of the calculation method, or None if not found |
| | """ |
| | if method_id not in self._methods: |
| | return None |
| | |
| | return self._methods[method_id]() |
| | |
| | def get_available_methods(self): |
| | """ |
| | Get a list of available calculation methods. |
| | |
| | Returns: |
| | list: List of dictionaries with method information |
| | """ |
| | methods = [] |
| | for method_id, method_class in self._methods.items(): |
| | method = method_class() |
| | methods.append({ |
| | 'id': method_id, |
| | 'name': method.name, |
| | 'description': method.description, |
| | 'version': method.version |
| | }) |
| | |
| | return methods |
| |
|
| |
|
| | |
| | registry = CalculationMethodRegistry() |
| |
|
| | |
| | registry.register_method('ashrae_cooling', ASHRAECoolingMethod) |
| | registry.register_method('ashrae_heating', ASHRAEHeatingMethod) |
| |
|
| |
|
| | |
| | """ |
| | class CustomCoolingMethod(CalculationMethod): |
| | @property |
| | def name(self): |
| | return "Custom Cooling Method" |
| | |
| | @property |
| | def description(self): |
| | return "A custom method for calculating cooling loads." |
| | |
| | @property |
| | def version(self): |
| | return "1.0" |
| | |
| | def calculate(self, input_data): |
| | # Custom calculation logic |
| | pass |
| | |
| | def get_input_schema(self): |
| | # Custom input schema |
| | pass |
| | |
| | def get_output_schema(self): |
| | # Custom output schema |
| | pass |
| | |
| | # Register the custom method |
| | registry.register_method('custom_cooling', CustomCoolingMethod) |
| | """ |
| |
|