Spaces:
Sleeping
Sleeping
| """ | |
| 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. | |
| """ | |
| def name(self): | |
| """ | |
| Get the name of the calculation method. | |
| Returns: | |
| str: Name of the calculation method | |
| """ | |
| pass | |
| def description(self): | |
| """ | |
| Get the description of the calculation method. | |
| Returns: | |
| str: Description of the calculation method | |
| """ | |
| pass | |
| def version(self): | |
| """ | |
| Get the version of the calculation method. | |
| Returns: | |
| str: Version of the calculation method | |
| """ | |
| pass | |
| def calculate(self, input_data): | |
| """ | |
| Perform the calculation. | |
| Args: | |
| input_data (dict): Input data for the calculation | |
| Returns: | |
| dict: Calculation results | |
| """ | |
| pass | |
| def get_input_schema(self): | |
| """ | |
| Get the input schema for the calculation method. | |
| Returns: | |
| dict: JSON schema for input validation | |
| """ | |
| pass | |
| 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. | |
| """ | |
| def name(self): | |
| return "ASHRAE Cooling Load Method" | |
| def description(self): | |
| return "Calculates cooling loads using the ASHRAE method for residential buildings." | |
| 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() | |
| # Extract input data | |
| building_components = input_data.get('building_components', []) | |
| windows = input_data.get('windows', []) | |
| infiltration = input_data.get('infiltration', {}) | |
| internal_gains = input_data.get('internal_gains', {}) | |
| # Perform calculation | |
| 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. | |
| """ | |
| def name(self): | |
| return "ASHRAE Heating Load Method" | |
| def description(self): | |
| return "Calculates heating loads using the ASHRAE method for residential buildings." | |
| 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() | |
| # Extract input data | |
| building_components = input_data.get('building_components', []) | |
| infiltration = input_data.get('infiltration', {}) | |
| # Perform calculation | |
| results = calculator.calculate_total_heating_load( | |
| building_components=building_components, | |
| infiltration=infiltration | |
| ) | |
| # Calculate annual heating requirement if location and occupancy data are provided | |
| 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 | |
| ) | |
| # Combine results | |
| 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 | |
| # Create a global registry instance | |
| registry = CalculationMethodRegistry() | |
| # Register the built-in calculation methods | |
| registry.register_method('ashrae_cooling', ASHRAECoolingMethod) | |
| registry.register_method('ashrae_heating', ASHRAEHeatingMethod) | |
| # Example of how to add a new calculation method | |
| """ | |
| 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) | |
| """ | |