HVAC-03 / data /reference_data.py
mabuseif's picture
Upload 27 files
845939b verified
Raw
History Blame Contribute Delete
17 kB
"""
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)}")