|
|
""" |
|
|
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 |
|
|
|
|
|
|
|
|
DATA_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
|
|
|
|
|
|
|
class ReferenceData: |
|
|
"""Class for managing reference data for the HVAC calculator.""" |
|
|
|
|
|
def __init__(self): |
|
|
"""Initialize reference data structures.""" |
|
|
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 from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of material properties |
|
|
""" |
|
|
|
|
|
|
|
|
return { |
|
|
"brick": { |
|
|
"name": "Common Brick", |
|
|
"conductivity": 0.72, |
|
|
"density": 1920, |
|
|
"specific_heat": 840, |
|
|
"typical_thickness": 0.1 |
|
|
}, |
|
|
"concrete": { |
|
|
"name": "Concrete", |
|
|
"conductivity": 1.4, |
|
|
"density": 2300, |
|
|
"specific_heat": 880, |
|
|
"typical_thickness": 0.2 |
|
|
}, |
|
|
"mineral_wool": { |
|
|
"name": "Mineral Wool Insulation", |
|
|
"conductivity": 0.04, |
|
|
"density": 30, |
|
|
"specific_heat": 840, |
|
|
"typical_thickness": 0.1 |
|
|
}, |
|
|
"eps_insulation": { |
|
|
"name": "EPS Insulation", |
|
|
"conductivity": 0.035, |
|
|
"density": 25, |
|
|
"specific_heat": 1400, |
|
|
"typical_thickness": 0.1 |
|
|
}, |
|
|
"gypsum_board": { |
|
|
"name": "Gypsum Board", |
|
|
"conductivity": 0.25, |
|
|
"density": 900, |
|
|
"specific_heat": 1000, |
|
|
"typical_thickness": 0.0125 |
|
|
}, |
|
|
"wood": { |
|
|
"name": "Wood (Pine)", |
|
|
"conductivity": 0.14, |
|
|
"density": 500, |
|
|
"specific_heat": 1600, |
|
|
"typical_thickness": 0.025 |
|
|
}, |
|
|
"steel": { |
|
|
"name": "Steel", |
|
|
"conductivity": 50, |
|
|
"density": 7800, |
|
|
"specific_heat": 450, |
|
|
"typical_thickness": 0.005 |
|
|
}, |
|
|
"glass": { |
|
|
"name": "Glass", |
|
|
"conductivity": 1.0, |
|
|
"density": 2500, |
|
|
"specific_heat": 840, |
|
|
"typical_thickness": 0.006 |
|
|
}, |
|
|
"air_gap": { |
|
|
"name": "Air Gap", |
|
|
"conductivity": 0.024, |
|
|
"density": 1.2, |
|
|
"specific_heat": 1000, |
|
|
"typical_thickness": 0.025 |
|
|
}, |
|
|
"concrete_block": { |
|
|
"name": "Concrete Block", |
|
|
"conductivity": 0.51, |
|
|
"density": 1400, |
|
|
"specific_heat": 1000, |
|
|
"typical_thickness": 0.2 |
|
|
}, |
|
|
"asphalt_shingle": { |
|
|
"name": "Asphalt Shingle", |
|
|
"conductivity": 0.7, |
|
|
"density": 1100, |
|
|
"specific_heat": 1260, |
|
|
"typical_thickness": 0.006 |
|
|
}, |
|
|
"carpet": { |
|
|
"name": "Carpet", |
|
|
"conductivity": 0.06, |
|
|
"density": 200, |
|
|
"specific_heat": 1300, |
|
|
"typical_thickness": 0.01 |
|
|
}, |
|
|
"vinyl_flooring": { |
|
|
"name": "Vinyl Flooring", |
|
|
"conductivity": 0.17, |
|
|
"density": 1200, |
|
|
"specific_heat": 1460, |
|
|
"typical_thickness": 0.003 |
|
|
} |
|
|
} |
|
|
|
|
|
def _load_wall_types(self) -> Dict[str, Dict[str, Any]]: |
|
|
""" |
|
|
Load predefined wall types from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of wall types with properties |
|
|
""" |
|
|
return { |
|
|
"brick_veneer_wood_frame": { |
|
|
"name": "Brick veneer with wood frame", |
|
|
"description": "Brick veneer with wood frame, insulation, and gypsum board", |
|
|
"u_value": 0.35, |
|
|
"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} |
|
|
] |
|
|
}, |
|
|
"concrete_block_insulated": { |
|
|
"name": "Concrete block with interior insulation", |
|
|
"description": "Concrete block wall with interior insulation and gypsum board", |
|
|
"u_value": 0.48, |
|
|
"wall_group": "C", |
|
|
"layers": [ |
|
|
{"material": "concrete_block", "thickness": 0.2}, |
|
|
{"material": "eps_insulation", "thickness": 0.05}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"precast_concrete_panel": { |
|
|
"name": "Precast concrete panel", |
|
|
"description": "Precast concrete panel with insulation and gypsum board", |
|
|
"u_value": 0.45, |
|
|
"wall_group": "D", |
|
|
"layers": [ |
|
|
{"material": "concrete", "thickness": 0.1}, |
|
|
{"material": "eps_insulation", "thickness": 0.075}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"metal_panel_insulated": { |
|
|
"name": "Metal panel with insulation", |
|
|
"description": "Metal panel wall with insulation and interior finish", |
|
|
"u_value": 0.4, |
|
|
"wall_group": "E", |
|
|
"layers": [ |
|
|
{"material": "steel", "thickness": 0.001}, |
|
|
{"material": "mineral_wool", "thickness": 0.1}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"wood_frame_wall": { |
|
|
"name": "Wood frame wall", |
|
|
"description": "Wood frame wall with insulation and gypsum board", |
|
|
"u_value": 0.3, |
|
|
"wall_group": "A", |
|
|
"layers": [ |
|
|
{"material": "wood", "thickness": 0.019}, |
|
|
{"material": "air_gap", "thickness": 0.025}, |
|
|
{"material": "wood", "thickness": 0.038}, |
|
|
{"material": "mineral_wool", "thickness": 0.14}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
def _load_roof_types(self) -> Dict[str, Dict[str, Any]]: |
|
|
""" |
|
|
Load predefined roof types from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of roof types with properties |
|
|
""" |
|
|
return { |
|
|
"flat_roof_concrete": { |
|
|
"name": "Flat concrete roof with insulation", |
|
|
"description": "Flat concrete roof with insulation and ceiling", |
|
|
"u_value": 0.25, |
|
|
"roof_group": "B", |
|
|
"layers": [ |
|
|
{"material": "concrete", "thickness": 0.15}, |
|
|
{"material": "eps_insulation", "thickness": 0.15}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"pitched_roof_wood": { |
|
|
"name": "Pitched wood roof with insulation", |
|
|
"description": "Pitched wood roof with insulation and ceiling", |
|
|
"u_value": 0.2, |
|
|
"roof_group": "A", |
|
|
"layers": [ |
|
|
{"material": "asphalt_shingle", "thickness": 0.006}, |
|
|
{"material": "wood", "thickness": 0.019}, |
|
|
{"material": "air_gap", "thickness": 0.025}, |
|
|
{"material": "mineral_wool", "thickness": 0.2}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"metal_deck_roof": { |
|
|
"name": "Metal deck roof with insulation", |
|
|
"description": "Metal deck roof with insulation and ceiling", |
|
|
"u_value": 0.3, |
|
|
"roof_group": "C", |
|
|
"layers": [ |
|
|
{"material": "steel", "thickness": 0.001}, |
|
|
{"material": "eps_insulation", "thickness": 0.1}, |
|
|
{"material": "air_gap", "thickness": 0.1}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
def _load_floor_types(self) -> Dict[str, Dict[str, Any]]: |
|
|
""" |
|
|
Load predefined floor types from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of floor types with properties |
|
|
""" |
|
|
return { |
|
|
"concrete_slab_on_grade": { |
|
|
"name": "Concrete slab on grade", |
|
|
"description": "Concrete slab on grade with insulation", |
|
|
"u_value": 0.3, |
|
|
"is_ground_contact": True, |
|
|
"layers": [ |
|
|
{"material": "concrete", "thickness": 0.1}, |
|
|
{"material": "eps_insulation", "thickness": 0.05} |
|
|
] |
|
|
}, |
|
|
"suspended_concrete_floor": { |
|
|
"name": "Suspended concrete floor", |
|
|
"description": "Suspended concrete floor with insulation", |
|
|
"u_value": 0.25, |
|
|
"is_ground_contact": False, |
|
|
"layers": [ |
|
|
{"material": "concrete", "thickness": 0.15}, |
|
|
{"material": "eps_insulation", "thickness": 0.1}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"wood_joist_floor": { |
|
|
"name": "Wood joist floor", |
|
|
"description": "Wood joist floor with insulation", |
|
|
"u_value": 0.22, |
|
|
"is_ground_contact": False, |
|
|
"layers": [ |
|
|
{"material": "wood", "thickness": 0.025}, |
|
|
{"material": "air_gap", "thickness": 0.15}, |
|
|
{"material": "mineral_wool", "thickness": 0.15}, |
|
|
{"material": "gypsum_board", "thickness": 0.0125} |
|
|
] |
|
|
}, |
|
|
"carpet_on_concrete": { |
|
|
"name": "Carpet on concrete", |
|
|
"description": "Carpet on concrete slab with insulation", |
|
|
"u_value": 0.28, |
|
|
"is_ground_contact": True, |
|
|
"layers": [ |
|
|
{"material": "carpet", "thickness": 0.01}, |
|
|
{"material": "concrete", "thickness": 0.1}, |
|
|
{"material": "eps_insulation", "thickness": 0.05} |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
def _load_window_types(self) -> Dict[str, Dict[str, Any]]: |
|
|
""" |
|
|
Load predefined window types from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of window types with properties |
|
|
""" |
|
|
return { |
|
|
"single_glazed": { |
|
|
"name": "Single glazed window", |
|
|
"description": "Single glazed window with aluminum frame", |
|
|
"u_value": 5.8, |
|
|
"shgc": 0.86, |
|
|
"vt": 0.9, |
|
|
"glazing_layers": 1, |
|
|
"gas_fill": "Air", |
|
|
"frame_type": "Aluminum", |
|
|
"low_e_coating": False |
|
|
}, |
|
|
"double_glazed_air": { |
|
|
"name": "Double glazed window with air", |
|
|
"description": "Double glazed window with air gap and aluminum frame", |
|
|
"u_value": 2.8, |
|
|
"shgc": 0.76, |
|
|
"vt": 0.81, |
|
|
"glazing_layers": 2, |
|
|
"gas_fill": "Air", |
|
|
"frame_type": "Aluminum", |
|
|
"low_e_coating": False |
|
|
}, |
|
|
"double_glazed_argon_low_e": { |
|
|
"name": "Double glazed window with argon and low-e coating", |
|
|
"description": "Double glazed window with argon fill, low-e coating, and vinyl frame", |
|
|
"u_value": 1.4, |
|
|
"shgc": 0.4, |
|
|
"vt": 0.7, |
|
|
"glazing_layers": 2, |
|
|
"gas_fill": "Argon", |
|
|
"frame_type": "Vinyl", |
|
|
"low_e_coating": True |
|
|
}, |
|
|
"triple_glazed_argon_low_e": { |
|
|
"name": "Triple glazed window with argon and low-e coating", |
|
|
"description": "Triple glazed window with argon fill, low-e coating, and vinyl frame", |
|
|
"u_value": 0.8, |
|
|
"shgc": 0.3, |
|
|
"vt": 0.6, |
|
|
"glazing_layers": 3, |
|
|
"gas_fill": "Argon", |
|
|
"frame_type": "Vinyl", |
|
|
"low_e_coating": True |
|
|
} |
|
|
} |
|
|
|
|
|
def _load_door_types(self) -> Dict[str, Dict[str, Any]]: |
|
|
""" |
|
|
Load predefined door types from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of door types with properties |
|
|
""" |
|
|
return { |
|
|
"solid_wood_door": { |
|
|
"name": "Solid wood door", |
|
|
"description": "Solid wood door with no glazing", |
|
|
"u_value": 2.2, |
|
|
"glazing_percentage": 0, |
|
|
"door_type": "Solid" |
|
|
}, |
|
|
"insulated_steel_door": { |
|
|
"name": "Insulated steel door", |
|
|
"description": "Insulated steel door with no glazing", |
|
|
"u_value": 1.2, |
|
|
"glazing_percentage": 0, |
|
|
"door_type": "Solid" |
|
|
}, |
|
|
"partially_glazed_door": { |
|
|
"name": "Partially glazed door", |
|
|
"description": "Wood door with 25% glazing", |
|
|
"u_value": 2.8, |
|
|
"glazing_percentage": 25, |
|
|
"door_type": "Partially glazed", |
|
|
"shgc": 0.76, |
|
|
"vt": 0.81 |
|
|
}, |
|
|
"glass_door": { |
|
|
"name": "Glass door", |
|
|
"description": "Full glass door with aluminum frame", |
|
|
"u_value": 3.8, |
|
|
"glazing_percentage": 90, |
|
|
"door_type": "Glass", |
|
|
"shgc": 0.76, |
|
|
"vt": 0.81 |
|
|
} |
|
|
} |
|
|
|
|
|
def _load_internal_loads(self) -> Dict[str, Dict[str, Any]]: |
|
|
""" |
|
|
Load internal load data from reference data. |
|
|
|
|
|
Returns: |
|
|
Dictionary of internal load types with properties |
|
|
""" |
|
|
return { |
|
|
"occupancy": { |
|
|
"seated_very_light_work": { |
|
|
"name": "Seated, very light work", |
|
|
"sensible_heat": 70, |
|
|
"latent_heat": 45 |
|
|
}, |
|
|
"office_work_standing": { |
|
|
"name": "Office work, standing", |
|
|
"sensible_heat": 75, |
|
|
"latent_heat": 55 |
|
|
}, |
|
|
"light_physical_work": { |
|
|
"name": "Light physical work", |
|
|
"sensible_heat": 80, |
|
|
"latent_heat": 140 |
|
|
}, |
|
|
"medium_physical_work": { |
|
|
"name": "Medium physical work", |
|
|
"sensible_heat": 90, |
|
|
"latent_heat": 185 |
|
|
}, |
|
|
"heavy_physical_work": { |
|
|
"name": "Heavy physical work", |
|
|
"sensible_heat": 170, |
|
|
"latent_heat": 255 |
|
|
} |
|
|
}, |
|
|
"lighting": { |
|
|
"led": { |
|
|
"name": "LED", |
|
|
"power_density_range": [5, 10], |
|
|
"heat_to_space": 0.9 |
|
|
}, |
|
|
"fluorescent": { |
|
|
"name": "Fluorescent", |
|
|
"power_density_range": [10, 15], |
|
|
"heat_to_space": 0.95 |
|
|
}, |
|
|
"incandescent": { |
|
|
"name": "Incandescent", |
|
|
"power_density_range": [15, 25], |
|
|
"heat_to_space": 0.98 |
|
|
}, |
|
|
"halogen": { |
|
|
"name": "Halogen", |
|
|
"power_density_range": [12, 20], |
|
|
"heat_to_space": 0.97 |
|
|
} |
|
|
}, |
|
|
"equipment": { |
|
|
"office_equipment": { |
|
|
"name": "Office Equipment", |
|
|
"power_density_range": [10, 20], |
|
|
"sensible_fraction": 0.9, |
|
|
"latent_fraction": 0.1 |
|
|
}, |
|
|
"kitchen_equipment": { |
|
|
"name": "Kitchen Equipment", |
|
|
"power_density_range": [30, 200], |
|
|
"sensible_fraction": 0.6, |
|
|
"latent_fraction": 0.4 |
|
|
}, |
|
|
"manufacturing_equipment": { |
|
|
"name": "Manufacturing Equipment", |
|
|
"power_density_range": [20, 100], |
|
|
"sensible_fraction": 0.8, |
|
|
"latent_fraction": 0.2 |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
def get_material(self, material_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get material properties by ID. |
|
|
|
|
|
Args: |
|
|
material_id: Material identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of material properties or None if not found |
|
|
""" |
|
|
return self.materials.get(material_id) |
|
|
|
|
|
def get_wall_type(self, wall_type_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get wall type properties by ID. |
|
|
|
|
|
Args: |
|
|
wall_type_id: Wall type identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of wall type properties or None if not found |
|
|
""" |
|
|
return self.wall_types.get(wall_type_id) |
|
|
|
|
|
def get_roof_type(self, roof_type_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get roof type properties by ID. |
|
|
|
|
|
Args: |
|
|
roof_type_id: Roof type identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of roof type properties or None if not found |
|
|
""" |
|
|
return self.roof_types.get(roof_type_id) |
|
|
|
|
|
def get_floor_type(self, floor_type_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get floor type properties by ID. |
|
|
|
|
|
Args: |
|
|
floor_type_id: Floor type identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of floor type properties or None if not found |
|
|
""" |
|
|
return self.floor_types.get(floor_type_id) |
|
|
|
|
|
def get_window_type(self, window_type_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get window type properties by ID. |
|
|
|
|
|
Args: |
|
|
window_type_id: Window type identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of window type properties or None if not found |
|
|
""" |
|
|
return self.window_types.get(window_type_id) |
|
|
|
|
|
def get_door_type(self, door_type_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get door type properties by ID. |
|
|
|
|
|
Args: |
|
|
door_type_id: Door type identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of door type properties or None if not found |
|
|
""" |
|
|
return self.door_types.get(door_type_id) |
|
|
|
|
|
def get_internal_load(self, load_type: str, load_id: str) -> Optional[Dict[str, Any]]: |
|
|
""" |
|
|
Get internal load properties by type and ID. |
|
|
|
|
|
Args: |
|
|
load_type: Type of internal load (occupancy, lighting, equipment) |
|
|
load_id: Internal load identifier |
|
|
|
|
|
Returns: |
|
|
Dictionary of internal load properties or None if not found |
|
|
""" |
|
|
if load_type in self.internal_loads: |
|
|
return self.internal_loads[load_type].get(load_id) |
|
|
return None |
|
|
|
|
|
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 |
|
|
""" |
|
|
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) |
|
|
|
|
|
@classmethod |
|
|
def from_json(cls, file_path: str) -> 'ReferenceData': |
|
|
""" |
|
|
Create a ReferenceData instance from a JSON file. |
|
|
|
|
|
Args: |
|
|
file_path: Path to the input JSON file |
|
|
|
|
|
Returns: |
|
|
A new ReferenceData instance |
|
|
""" |
|
|
with open(file_path, 'r') as f: |
|
|
data = json.load(f) |
|
|
|
|
|
ref_data = cls() |
|
|
ref_data.materials = data.get("materials", ref_data.materials) |
|
|
ref_data.wall_types = data.get("wall_types", ref_data.wall_types) |
|
|
ref_data.roof_types = data.get("roof_types", ref_data.roof_types) |
|
|
ref_data.floor_types = data.get("floor_types", ref_data.floor_types) |
|
|
ref_data.window_types = data.get("window_types", ref_data.window_types) |
|
|
ref_data.door_types = data.get("door_types", ref_data.door_types) |
|
|
ref_data.internal_loads = data.get("internal_loads", ref_data.internal_loads) |
|
|
|
|
|
return ref_data |
|
|
|
|
|
|
|
|
|
|
|
reference_data = ReferenceData() |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
reference_data.export_to_json(os.path.join(DATA_DIR, "reference_data.json")) |
|
|
|