| """ |
| ASHRAE tables integration module for HVAC Load Calculator. |
| This module provides functions to integrate ASHRAE tables with the calculator. |
| """ |
|
|
| import pandas as pd |
| import numpy as np |
| from data.ashrae_tables import ashrae_tables |
|
|
| def get_daily_range_percentage(hour): |
| """ |
| Get percentage of daily range for a specific hour. |
| |
| Args: |
| hour: Hour of the day (1-24) |
| |
| Returns: |
| Percentage of daily range (0-100) |
| """ |
| return ashrae_tables.get_daily_range_percentage(hour) |
|
|
| def get_cltd_flat_roof(roof_group, hour): |
| """ |
| Get Cooling Load Temperature Difference (CLTD) for flat roof. |
| |
| Args: |
| roof_group: Roof construction group (1-13) |
| hour: Hour of the day (1-24) |
| |
| Returns: |
| CLTD value in °C |
| """ |
| return ashrae_tables.get_cltd_flat_roof(roof_group, hour) |
|
|
| def get_cltd_wall(wall_group, orientation, hour): |
| """ |
| Get Cooling Load Temperature Difference (CLTD) for wall. |
| |
| Args: |
| wall_group: Wall construction group (A-G) |
| orientation: Wall orientation (N, NE, E, SE, S, SW, W, NW, Horizontal) |
| hour: Hour of the day (1-24) |
| |
| Returns: |
| CLTD value in °C |
| """ |
| return ashrae_tables.get_cltd_wall(wall_group, orientation, hour) |
|
|
| def get_cltd_glass(hour): |
| """ |
| Get Cooling Load Temperature Difference (CLTD) for glass conduction. |
| |
| Args: |
| hour: Hour of the day (1-24) |
| |
| Returns: |
| CLTD value in °C |
| """ |
| return ashrae_tables.get_cltd_glass(hour) |
|
|
| def get_clf_glass_no_shade(orientation, hour): |
| """ |
| Get Cooling Load Factor (CLF) for glass with no interior shading. |
| |
| Args: |
| orientation: Glass orientation (N, NE, E, SE, S, SW, W, NW, Horizontal) |
| hour: Hour of the day (1-24) |
| |
| Returns: |
| CLF value (0-1) |
| """ |
| return ashrae_tables.get_clf_glass_no_shade(orientation, hour) |
|
|
| def get_clf_people(hour, hours_occupancy): |
| """ |
| Get Cooling Load Factor (CLF) for people. |
| |
| Args: |
| hour: Hour of the day (1-24) |
| hours_occupancy: Hours of occupancy (8h, 10h, 12h, 14h, 16h, 18h, 24h) |
| |
| Returns: |
| CLF value (0-1) |
| """ |
| return ashrae_tables.get_clf_people(hour, hours_occupancy) |
|
|
| def get_clf_lights(hour, hours_operation): |
| """ |
| Get Cooling Load Factor (CLF) for lights. |
| |
| Args: |
| hour: Hour of the day (1-24) |
| hours_operation: Hours of operation (8h, 10h, 12h, 14h, 16h, 18h, 24h) |
| |
| Returns: |
| CLF value (0-1) |
| """ |
| return ashrae_tables.get_clf_lights(hour, hours_operation) |
|
|
| def get_clf_equipment(hour, hours_operation): |
| """ |
| Get Cooling Load Factor (CLF) for equipment. |
| |
| Args: |
| hour: Hour of the day (1-24) |
| hours_operation: Hours of operation (8h, 10h, 12h, 14h, 16h, 18h, 24h) |
| |
| Returns: |
| CLF value (0-1) |
| """ |
| return ashrae_tables.get_clf_equipment(hour, hours_operation) |
|
|
| def calculate_corrected_cltd_wall(wall_group, orientation, hour, color, month, latitude, indoor_temp, outdoor_temp): |
| """ |
| Calculate corrected CLTD for wall. |
| |
| Args: |
| wall_group: Wall construction group (A-G) |
| orientation: Wall orientation (N, NE, E, SE, S, SW, W, NW, Horizontal) |
| hour: Hour of the day (1-24) |
| color: Surface color (Dark, Medium, Light) |
| month: Month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) |
| latitude: Latitude (24N, 32N, 40N, 48N, 56N) |
| indoor_temp: Indoor temperature in °C |
| outdoor_temp: Outdoor temperature in °C |
| |
| Returns: |
| Corrected CLTD value in °C |
| """ |
| return ashrae_tables.calculate_corrected_cltd_wall( |
| wall_group, orientation, hour, color, month, latitude, indoor_temp, outdoor_temp |
| ) |
|
|
| def calculate_corrected_cltd_roof(roof_group, hour, color, month, latitude, indoor_temp, outdoor_temp): |
| """ |
| Calculate corrected CLTD for roof. |
| |
| Args: |
| roof_group: Roof construction group (1-13) |
| hour: Hour of the day (1-24) |
| color: Surface color (Dark, Medium, Light) |
| month: Month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) |
| latitude: Latitude (24N, 32N, 40N, 48N, 56N) |
| indoor_temp: Indoor temperature in °C |
| outdoor_temp: Outdoor temperature in °C |
| |
| Returns: |
| Corrected CLTD value in °C |
| """ |
| return ashrae_tables.calculate_corrected_cltd_roof( |
| roof_group, hour, color, month, latitude, indoor_temp, outdoor_temp |
| ) |
|
|
| def get_scl(orientation, hour, latitude_month): |
| """ |
| Get Solar Cooling Load (SCL) for glass. |
| |
| Args: |
| orientation: Glass orientation (N, NE, E, SE, S, SW, W, NW, Horizontal) |
| hour: Hour of the day (1-24) |
| latitude_month: Latitude and month key (e.g., "40N_JUL") |
| |
| Returns: |
| SCL value in W/m² |
| """ |
| return ashrae_tables.get_scl(orientation, hour, latitude_month) |
|
|
| def calculate_monthly_cooling_load(building_data, weather_data): |
| """ |
| Calculate monthly cooling load based on ASHRAE methods. |
| |
| Args: |
| building_data: Dictionary containing building information |
| weather_data: Dictionary containing weather information for each month |
| |
| Returns: |
| Dictionary containing monthly cooling loads |
| """ |
| monthly_loads = {} |
| |
| for month, weather in weather_data.items(): |
| |
| outdoor_temp = weather.get('avg_temp', 29.4) |
| |
| |
| indoor_temp = building_data.get('indoor_temp', 24) |
| |
| |
| latitude = building_data.get('latitude', '40N') |
| |
| |
| peak_load = 0 |
| peak_hour = 0 |
| |
| |
| hourly_loads = [] |
| for hour in range(1, 25): |
| |
| |
| roof_group = building_data.get('roof_group', 1) |
| roof_area = building_data.get('roof_area', 0) |
| roof_u_value = building_data.get('roof_u_value', 0) |
| roof_color = building_data.get('roof_color', 'Medium') |
| |
| roof_cltd = calculate_corrected_cltd_roof( |
| roof_group, hour, roof_color, month[:3], latitude, indoor_temp, outdoor_temp |
| ) |
| roof_load = roof_area * roof_u_value * roof_cltd |
| |
| |
| wall_loads = 0 |
| for wall in building_data.get('walls', []): |
| wall_group = wall.get('wall_group', 'B') |
| wall_area = wall.get('area', 0) |
| wall_u_value = wall.get('u_value', 0) |
| wall_orientation = wall.get('orientation', 'N') |
| wall_color = wall.get('color', 'Medium') |
| |
| wall_cltd = calculate_corrected_cltd_wall( |
| wall_group, wall_orientation, hour, wall_color, month[:3], latitude, indoor_temp, outdoor_temp |
| ) |
| wall_loads += wall_area * wall_u_value * wall_cltd |
| |
| |
| glass_loads_conduction = 0 |
| for glass in building_data.get('glass', []): |
| glass_area = glass.get('area', 0) |
| glass_u_value = glass.get('u_value', 0) |
| |
| glass_cltd = get_cltd_glass(hour) |
| glass_loads_conduction += glass_area * glass_u_value * glass_cltd |
| |
| |
| glass_loads_solar = 0 |
| for glass in building_data.get('glass', []): |
| glass_area = glass.get('area', 0) |
| glass_orientation = glass.get('orientation', 'N') |
| glass_shgc = glass.get('shgc', 0.7) |
| |
| latitude_month_key = f"{latitude}_{month[:3].upper()}" |
| scl = get_scl(glass_orientation, hour, latitude_month_key) |
| glass_loads_solar += glass_area * glass_shgc * scl |
| |
| |
| |
| people_count = building_data.get('people_count', 0) |
| people_activity = building_data.get('people_activity', 'Seated, light work') |
| people_sensible_heat = building_data.get('people_sensible_heat', 75) |
| people_hours = building_data.get('people_hours', '8h') |
| |
| people_clf = get_clf_people(hour, people_hours) |
| people_load = people_count * people_sensible_heat * people_clf |
| |
| |
| lighting_power = building_data.get('lighting_power', 0) |
| lighting_type = building_data.get('lighting_type', 'LED') |
| lighting_hours = building_data.get('lighting_hours', '8h') |
| |
| |
| if lighting_type == 'LED': |
| lighting_factor = 0.8 |
| elif lighting_type == 'Fluorescent': |
| lighting_factor = 0.85 |
| elif lighting_type == 'Halogen': |
| lighting_factor = 0.95 |
| else: |
| lighting_factor = 0.98 |
| |
| lighting_clf = get_clf_lights(hour, lighting_hours) |
| lighting_load = lighting_power * lighting_factor * lighting_clf |
| |
| |
| equipment_power = building_data.get('equipment_power', 0) |
| equipment_type = building_data.get('equipment_type', 'General') |
| equipment_hours = building_data.get('equipment_hours', '8h') |
| |
| |
| if equipment_type == 'General': |
| equipment_factor = 1.0 |
| elif equipment_type == 'Computer': |
| equipment_factor = 0.95 |
| elif equipment_type == 'Kitchen': |
| equipment_factor = 0.85 |
| elif equipment_type == 'Medical': |
| equipment_factor = 0.9 |
| else: |
| equipment_factor = 0.8 |
| |
| equipment_clf = get_clf_equipment(hour, equipment_hours) |
| equipment_load = equipment_power * equipment_factor * equipment_clf |
| |
| |
| hourly_load = ( |
| roof_load + wall_loads + glass_loads_conduction + glass_loads_solar + |
| people_load + lighting_load + equipment_load |
| ) |
| |
| hourly_loads.append(hourly_load) |
| |
| |
| if hourly_load > peak_load: |
| peak_load = hourly_load |
| peak_hour = hour |
| |
| |
| daily_total = sum(hourly_loads) |
| daily_average = daily_total / 24 |
| |
| |
| monthly_loads[month] = { |
| 'peak_load': peak_load, |
| 'peak_hour': peak_hour, |
| 'daily_total': daily_total, |
| 'daily_average': daily_average, |
| 'hourly_loads': hourly_loads |
| } |
| |
| return monthly_loads |
|
|
| def get_roof_group_description(roof_group): |
| """ |
| Get description for roof construction group. |
| |
| Args: |
| roof_group: Roof construction group (1-13) |
| |
| Returns: |
| Description of the roof construction |
| """ |
| descriptions = { |
| 1: "Steel sheet with 25.4mm (or 50.8mm) insulation", |
| 2: "25.4mm wood with 25.4mm insulation", |
| 3: "101.6mm light weight concrete", |
| 4: "50.8mm heavy weight concrete with 25.4mm insulation (or 50.8mm insulation)", |
| 5: "25.4mm wood with 50.8mm insulation", |
| 6: "152.4mm Light Weight Concrete", |
| 7: "63.5mm wood with 25.4mm insulation", |
| 8: "203.2mm light weight concrete", |
| 9: "101.6mm heavy weight concrete with 25.4mm insulation (or 50.8mm insulation)", |
| 10: "152.4mm heavy weight concrete", |
| 11: "Roof terrace system", |
| 12: "101.6mm heavy weight concrete with 25.4mm insulation (or 50.8mm insulation)", |
| 13: "152.4mm wood with 25.4mm insulation (or 50.8mm insulation)" |
| } |
| |
| return descriptions.get(roof_group, "Unknown roof construction") |
|
|
| def get_wall_group_description(wall_group): |
| """ |
| Get description for wall construction group. |
| |
| Args: |
| wall_group: Wall construction group (A-G) |
| |
| Returns: |
| Description of the wall construction |
| """ |
| descriptions = { |
| "A": "100mm concrete wall", |
| "B": "200mm concrete wall with 50mm insulation outside", |
| "C": "300mm concrete wall", |
| "D": "200mm concrete wall with 50mm insulation inside", |
| "E": "100mm concrete wall with 50mm insulation outside", |
| "F": "100mm concrete wall with 50mm insulation inside", |
| "G": "300mm brick wall" |
| } |
| |
| return descriptions.get(wall_group, "Unknown wall construction") |
|
|