HVAC-03 / data /reference_data.py
mabuseif's picture
Upload 27 files
845939b verified
"""
Reference data structures for HVAC Load Calculator.
This module contains reference data for materials, construction types, and other HVAC-related data.
"""
from typing import Dict, List, Any, Optional
import pandas as pd
import json
import os
import logging
from uuid import uuid4
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Define paths
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
DEFAULT_DATA_FILE = os.path.join(DATA_DIR, "reference_data.json")
class ReferenceData:
"""Class for managing reference data for the HVAC calculator."""
def __init__(self):
"""Initialize reference data structures."""
self.materials = {}
self.wall_types = {}
self.roof_types = {}
self.floor_types = {}
self.window_types = {}
self.door_types = {}
self.internal_loads = {}
try:
self._load_all_data()
except Exception as e:
logger.error(f"Error initializing reference data: {str(e)}")
raise
def _load_all_data(self) -> None:
"""Load all reference data, attempting to load from JSON first."""
try:
if os.path.exists(DEFAULT_DATA_FILE):
self._load_from_json(DEFAULT_DATA_FILE)
else:
self._load_default_data()
self.export_to_json(DEFAULT_DATA_FILE)
except Exception as e:
logger.error(f"Error loading reference data: {str(e)}")
self._load_default_data() # Fallback to default data
def _load_default_data(self) -> None:
"""Load default reference data."""
self.materials = self._load_materials()
self.wall_types = self._load_wall_types()
self.roof_types = self._load_roof_types()
self.floor_types = self._load_floor_types()
self.window_types = self._load_window_types()
self.door_types = self._load_door_types()
self.internal_loads = self._load_internal_loads()
def _load_materials(self) -> Dict[str, Dict[str, Any]]:
"""
Load material properties.
Returns:
Dictionary of material properties
"""
return {
"brick": {
"id": str(uuid4()),
"name": "Common Brick",
"conductivity": 0.72, # W/(m·K)
"density": 1920, # kg/m³
"specific_heat": 840, # J/(kg·K)
"typical_thickness": 0.1, # m
"emissivity": 0.9,
"solar_absorptance": 0.7
},
"concrete": {
"id": str(uuid4()),
"name": "Concrete",
"conductivity": 1.4, # W/(m·K)
"density": 2300, # kg/m³
"specific_heat": 880, # J/(kg·K)
"typical_thickness": 0.2, # m
"emissivity": 0.92,
"solar_absorptance": 0.65
},
"mineral_wool": {
"id": str(uuid4()),
"name": "Mineral Wool Insulation",
"conductivity": 0.04, # W/(m·K)
"density": 30, # kg/m³
"specific_heat": 840, # J/(kg·K)
"typical_thickness": 0.1, # m
"emissivity": 0.9,
"solar_absorptance": 0.6
},
# Additional materials
"polyurethane_foam": {
"id": str(uuid4()),
"name": "Polyurethane Foam",
"conductivity": 0.025, # W/(m·K)
"density": 40, # kg/m³
"specific_heat": 1500, # J/(kg·K)
"typical_thickness": 0.05, # m
"emissivity": 0.9,
"solar_absorptance": 0.6
},
"fiberglass_insulation": {
"id": str(uuid4()),
"name": "Fiberglass Insulation",
"conductivity": 0.045, # W/(m·K)
"density": 12, # kg/m³
"specific_heat": 850, # J/(kg·K)
"typical_thickness": 0.15, # m
"emissivity": 0.9,
"solar_absorptance": 0.6
},
"stucco": {
"id": str(uuid4()),
"name": "Stucco",
"conductivity": 0.7, # W/(m·K)
"density": 1850, # kg/m³
"specific_heat": 900, # J/(kg·K)
"typical_thickness": 0.025, # m
"emissivity": 0.92,
"solar_absorptance": 0.5
}
# Add more materials as needed
}
def _load_wall_types(self) -> Dict[str, Dict[str, Any]]:
"""
Load predefined wall types.
Returns:
Dictionary of wall types with properties
"""
return {
"brick_veneer_wood_frame": {
"id": str(uuid4()),
"name": "Brick Veneer with Wood Frame",
"description": "Brick veneer with wood frame, insulation, and gypsum board",
"u_value": 0.35, # W/(m²·K)
"wall_group": "B",
"layers": [
{"material": "brick", "thickness": 0.1},
{"material": "air_gap", "thickness": 0.025},
{"material": "wood", "thickness": 0.038},
{"material": "mineral_wool", "thickness": 0.089},
{"material": "gypsum_board", "thickness": 0.0125}
],
"thermal_mass": 180, # kg/m²
"color": "Medium"
},
"insulated_concrete_form": {
"id": str(uuid4()),
"name": "Insulated Concrete Form",
"description": "ICF with EPS insulation and concrete core",
"u_value": 0.25, # W/(m²·K)
"wall_group": "C",
"layers": [
{"material": "eps_insulation", "thickness": 0.05},
{"material": "concrete", "thickness": 0.15},
{"material": "eps_insulation", "thickness": 0.05},
{"material": "gypsum_board", "thickness": 0.0125}
],
"thermal_mass": 220, # kg/m²
"color": "Light"
},
# Additional wall types
"sip_panel": {
"id": str(uuid4()),
"name": "Structural Insulated Panel",
"description": "SIP with OSB and EPS core",
"u_value": 0.28, # W/(m²·K)
"wall_group": "A",
"layers": [
{"material": "wood", "thickness": 0.012},
{"material": "eps_insulation", "thickness": 0.15},
{"material": "wood", "thickness": 0.012},
{"material": "gypsum_board", "thickness": 0.0125}
],
"thermal_mass": 80, # kg/m²
"color": "Light"
}
}
def _load_roof_types(self) -> Dict[str, Dict[str, Any]]:
"""
Load predefined roof types.
Returns:
Dictionary of roof types with properties
"""
return {
"flat_roof_concrete": {
"id": str(uuid4()),
"name": "Flat Concrete Roof with Insulation",
"description": "Flat concrete roof with insulation and ceiling",
"u_value": 0.25, # W/(m²·K)
"roof_group": "B",
"layers": [
{"material": "concrete", "thickness": 0.15},
{"material": "eps_insulation", "thickness": 0.15},
{"material": "gypsum_board", "thickness": 0.0125}
],
"solar_absorptance": 0.7,
"emissivity": 0.9
},
"green_roof": {
"id": str(uuid4()),
"name": "Green Roof",
"description": "Vegetated roof with insulation and drainage",
"u_value": 0.22, # W/(m²·K)
"roof_group": "A",
"layers": [
{"material": "soil", "thickness": 0.1},
{"material": "eps_insulation", "thickness": 0.1},
{"material": "concrete", "thickness": 0.1},
{"material": "gypsum_board", "thickness": 0.0125}
],
"solar_absorptance": 0.5,
"emissivity": 0.95
}
}
def _load_floor_types(self) -> Dict[str, Dict[str, Any]]:
"""
Load predefined floor types.
Returns:
Dictionary of floor types with properties
"""
return {
"concrete_slab_on_grade": {
"id": str(uuid4()),
"name": "Concrete Slab on Grade",
"description": "Concrete slab on grade with insulation",
"u_value": 0.3, # W/(m²·K)
"is_ground_contact": True,
"layers": [
{"material": "concrete", "thickness": 0.1},
{"material": "eps_insulation", "thickness": 0.05}
],
"thermal_mass": 230 # kg/m²
},
"radiant_floor": {
"id": str(uuid4()),
"name": "Radiant Floor",
"description": "Concrete floor with radiant heating and insulation",
"u_value": 0.27, # W/(m²·K)
"is_ground_contact": True,
"layers": [
{"material": "tile", "thickness": 0.015},
{"material": "concrete", "thickness": 0.1},
{"material": "eps_insulation", "thickness": 0.075}
],
"thermal_mass": 240 # kg/m²
}
}
def _load_window_types(self) -> Dict[str, Dict[str, Any]]:
"""
Load predefined window types.
Returns:
Dictionary of window types with properties
"""
return {
"double_glazed_argon_low_e": {
"id": str(uuid4()),
"name": "Double Glazed with Argon and Low-E",
"description": "Double glazed window with argon fill, low-e coating, and vinyl frame",
"u_value": 1.4, # W/(m²·K)
"shgc": 0.4,
"vt": 0.7,
"glazing_layers": 2,
"gas_fill": "Argon",
"frame_type": "Vinyl",
"low_e_coating": True,
"frame_factor": 0.15
},
"electrochromic_window": {
"id": str(uuid4()),
"name": "Electrochromic Window",
"description": "Smart window with dynamic tinting",
"u_value": 1.2, # W/(m²·K)
"shgc": 0.35,
"vt": 0.65,
"glazing_layers": 2,
"gas_fill": "Argon",
"frame_type": "Fiberglass",
"low_e_coating": True,
"frame_factor": 0.12
}
}
def _load_door_types(self) -> Dict[str, Dict[str, Any]]:
"""
Load predefined door types.
Returns:
Dictionary of door types with properties
"""
return {
"insulated_steel_door": {
"id": str(uuid4()),
"name": "Insulated Steel Door",
"description": "Insulated steel door with no glazing",
"u_value": 1.2, # W/(m²·K)
"glazing_percentage": 0,
"door_type": "Solid",
"thermal_mass": 50 # kg/m²
},
"insulated_fiberglass_door": {
"id": str(uuid4()),
"name": "Insulated Fiberglass Door",
"description": "Insulated fiberglass door with small glazing",
"u_value": 1.5, # W/(m²·K)
"glazing_percentage": 10,
"door_type": "Partially glazed",
"shgc": 0.7,
"vt": 0.8,
"thermal_mass": 40 # kg/m²
}
}
def _load_internal_loads(self) -> Dict[str, Dict[str, Any]]:
"""
Load internal load data.
Returns:
Dictionary of internal load types with properties
"""
return {
"occupancy": {
"office_typing": {
"id": str(uuid4()),
"name": "Office Typing",
"sensible_heat": 75, # W per person
"latent_heat": 55, # W per person
"metabolic_rate": 1.2 # met
},
"retail_sales": {
"id": str(uuid4()),
"name": "Retail Sales",
"sensible_heat": 80, # W per person
"latent_heat": 70, # W per person
"metabolic_rate": 1.4 # met
}
},
"lighting": {
"led_high_efficiency": {
"id": str(uuid4()),
"name": "High Efficiency LED",
"power_density_range": [4, 8], # W/m²
"heat_to_space": 0.85,
"efficacy": 120 # lm/W
}
},
"equipment": {
"computer_workstation": {
"id": str(uuid4()),
"name": "Computer Workstation",
"power_density_range": [15, 25], # W/m²
"sensible_fraction": 0.95,
"latent_fraction": 0.05
}
}
}
def _load_from_json(self, file_path: str) -> None:
"""
Load reference data from JSON file.
Args:
file_path: Path to JSON file
"""
try:
with open(file_path, 'r') as f:
data = json.load(f)
self.materials = data.get("materials", self.materials)
self.wall_types = data.get("wall_types", self.wall_types)
self.roof_types = data.get("roof_types", self.roof_types)
self.floor_types = data.get("floor_types", self.floor_types)
self.window_types = data.get("window_types", self.window_types)
self.door_types = data.get("door_types", self.door_types)
self.internal_loads = data.get("internal_loads", self.internal_loads)
logger.info(f"Successfully loaded reference data from {file_path}")
except Exception as e:
logger.error(f"Error loading JSON data from {file_path}: {str(e)}")
raise
def export_to_json(self, file_path: str) -> None:
"""
Export all reference data to a JSON file.
Args:
file_path: Path to the output JSON file
"""
try:
data = {
"materials": self.materials,
"wall_types": self.wall_types,
"roof_types": self.roof_types,
"floor_types": self.floor_types,
"window_types": self.window_types,
"door_types": self.door_types,
"internal_loads": self.internal_loads
}
with open(file_path, 'w') as f:
json.dump(data, f, indent=4)
logger.info(f"Successfully exported reference data to {file_path}")
except Exception as e:
logger.error(f"Error exporting to JSON: {str(e)}")
raise
# Getter methods with validation
def get_material(self, material_id: str) -> Optional[Dict[str, Any]]:
return self.materials.get(material_id)
def get_wall_type(self, wall_type_id: str) -> Optional[Dict[str, Any]]:
return self.wall_types.get(wall_type_id)
def get_roof_type(self, roof_type_id: str) -> Optional[Dict[str, Any]]:
return self.roof_types.get(roof_type_id)
def get_floor_type(self, floor_type_id: str) -> Optional[Dict[str, Any]]:
return self.floor_types.get(floor_type_id)
def get_window_type(self, window_type_id: str) -> Optional[Dict[str, Any]]:
return self.window_types.get(window_type_id)
def get_door_type(self, door_type_id: str) -> Optional[Dict[str, Any]]:
return self.door_types.get(door_type_id)
def get_internal_load(self, load_type: str, load_id: str) -> Optional[Dict[str, Any]]:
return self.internal_loads.get(load_type, {}).get(load_id)
# Singleton instance
try:
reference_data = ReferenceData()
except Exception as e:
logger.error(f"Failed to create ReferenceData instance: {str(e)}")
raise
if __name__ == "__main__":
try:
reference_data.export_to_json(DEFAULT_DATA_FILE)
except Exception as e:
logger.error(f"Error exporting default data: {str(e)}")