Spaces:
Sleeping
Sleeping
Update app/main.py
Browse files- app/main.py +48 -18
app/main.py
CHANGED
|
@@ -179,7 +179,9 @@ class HVACCalculator:
|
|
| 179 |
'relative_humidity': climate_data.get('summer_outdoor_rh', 50.0),
|
| 180 |
'ground_temperature': climate_data.get('ground_temperature', 20.0),
|
| 181 |
'month': climate_data.get('design_month', 'Jul'),
|
| 182 |
-
'latitude': climate_data.get('latitude', '40N')
|
|
|
|
|
|
|
| 183 |
}
|
| 184 |
indoor_conditions = {
|
| 185 |
'temperature': building_info.get('indoor_temp', 24.0),
|
|
@@ -191,7 +193,7 @@ class HVACCalculator:
|
|
| 191 |
'people': {
|
| 192 |
'number': sum(load['num_people'] for load in internal_loads.get('people', [])),
|
| 193 |
'activity_level': internal_loads.get('people', [{}])[0].get('activity_level', 'Seated/Resting'),
|
| 194 |
-
'
|
| 195 |
},
|
| 196 |
'lights': {
|
| 197 |
'power': sum(load['power'] for load in internal_loads.get('lighting', [])),
|
|
@@ -205,8 +207,15 @@ class HVACCalculator:
|
|
| 205 |
'radiation_factor': internal_loads.get('equipment', [{}])[0].get('radiation_fraction', 0.3),
|
| 206 |
'hours_operation': f"{internal_loads.get('equipment', [{}])[0].get('hours_in_operation', 8)}h"
|
| 207 |
},
|
| 208 |
-
'infiltration': {
|
| 209 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
}
|
| 211 |
|
| 212 |
# Calculate hourly loads
|
|
@@ -214,7 +223,8 @@ class HVACCalculator:
|
|
| 214 |
building_components=building_components,
|
| 215 |
outdoor_conditions=outdoor_conditions,
|
| 216 |
indoor_conditions=indoor_conditions,
|
| 217 |
-
internal_loads=formatted_internal_loads
|
|
|
|
| 218 |
)
|
| 219 |
|
| 220 |
# Get design loads
|
|
@@ -324,18 +334,22 @@ class HVACCalculator:
|
|
| 324 |
indoor_temp=indoor_conditions['temperature'],
|
| 325 |
month=outdoor_conditions['month'],
|
| 326 |
hour=design_loads['design_hour'],
|
| 327 |
-
latitude=
|
|
|
|
| 328 |
)
|
|
|
|
| 329 |
results['detailed_loads']['windows'].append({
|
| 330 |
'name': window.name,
|
| 331 |
'orientation': window.orientation.value,
|
| 332 |
'area': window.area,
|
| 333 |
'u_value': window.u_value,
|
| 334 |
'shgc': window.shgc,
|
|
|
|
|
|
|
| 335 |
'scl': self.cooling_calculator.ashrae_tables.get_scl(
|
| 336 |
window.orientation.value,
|
| 337 |
design_loads['design_hour'],
|
| 338 |
-
|
| 339 |
),
|
| 340 |
'load': load_dict['total'] / 1000
|
| 341 |
})
|
|
@@ -361,7 +375,6 @@ class HVACCalculator:
|
|
| 361 |
load_dict = self.cooling_calculator.calculate_people_cooling_load(
|
| 362 |
num_people=load['num_people'],
|
| 363 |
activity_level=load['activity_level'],
|
| 364 |
-
hours_occupancy=f"{load['hours_in_operation']}h",
|
| 365 |
hour=design_loads['design_hour']
|
| 366 |
)
|
| 367 |
elif load_type == 'lighting':
|
|
@@ -369,7 +382,6 @@ class HVACCalculator:
|
|
| 369 |
power=load['power'],
|
| 370 |
use_factor=load['usage_factor'],
|
| 371 |
special_allowance=0.1,
|
| 372 |
-
hours_operation=f"{load['hours_in_operation']}h",
|
| 373 |
hour=design_loads['design_hour']
|
| 374 |
)}
|
| 375 |
else:
|
|
@@ -377,7 +389,6 @@ class HVACCalculator:
|
|
| 377 |
power=load['power'],
|
| 378 |
use_factor=load['usage_factor'],
|
| 379 |
radiation_factor=load['radiation_fraction'],
|
| 380 |
-
hours_operation=f"{load['hours_in_operation']}h",
|
| 381 |
hour=design_loads['design_hour']
|
| 382 |
)
|
| 383 |
results['detailed_loads']['internal'].append({
|
|
@@ -444,21 +455,39 @@ class HVACCalculator:
|
|
| 444 |
formatted_internal_loads = {
|
| 445 |
'people': {
|
| 446 |
'number': sum(load['num_people'] for load in internal_loads.get('people', [])),
|
| 447 |
-
'sensible_gain': 70
|
|
|
|
| 448 |
},
|
| 449 |
'lights': {
|
| 450 |
'power': sum(load['power'] for load in internal_loads.get('lighting', [])),
|
| 451 |
-
'use_factor': internal_loads.get('lighting', [{}])[0].get('usage_factor', 0.8)
|
|
|
|
| 452 |
},
|
| 453 |
'equipment': {
|
| 454 |
'power': sum(load['power'] for load in internal_loads.get('equipment', [])),
|
| 455 |
-
'use_factor': internal_loads.get('equipment', [{}])[0].get('usage_factor', 0.7)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
},
|
| 457 |
-
'
|
| 458 |
-
|
| 459 |
-
|
|
|
|
|
|
|
| 460 |
}
|
| 461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
# Calculate design loads
|
| 463 |
design_loads = self.heating_calculator.calculate_design_heating_load(
|
| 464 |
building_components=building_components,
|
|
@@ -584,6 +613,7 @@ class HVACCalculator:
|
|
| 584 |
|
| 585 |
return True, "Heating calculation completed.", results
|
| 586 |
except Exception as e:
|
|
|
|
| 587 |
return False, f"Heating calculation error: {str(e)}", {}
|
| 588 |
|
| 589 |
def display_calculation_results(self):
|
|
@@ -605,7 +635,7 @@ class HVACCalculator:
|
|
| 605 |
|
| 606 |
if debug:
|
| 607 |
st.write("Cooling Inputs:", {
|
| 608 |
-
'components': st.session_state.get('components', {}),
|
| 609 |
'internal_loads': st.session_state.get('internal_loads', {}),
|
| 610 |
'climate_data': st.session_state.get('climate_data', {}),
|
| 611 |
'building_info': st.session_state.get('building_info', {})
|
|
@@ -629,7 +659,7 @@ class HVACCalculator:
|
|
| 629 |
|
| 630 |
if debug:
|
| 631 |
st.write("Heating Inputs:", {
|
| 632 |
-
'components': st.session_state.get('components', {}),
|
| 633 |
'internal_loads': st.session_state.get('internal_loads', {}),
|
| 634 |
'climate_data': st.session_state.get('climate_data', {}),
|
| 635 |
'building_info': st.session_state.get('building_info', {})
|
|
|
|
| 179 |
'relative_humidity': climate_data.get('summer_outdoor_rh', 50.0),
|
| 180 |
'ground_temperature': climate_data.get('ground_temperature', 20.0),
|
| 181 |
'month': climate_data.get('design_month', 'Jul'),
|
| 182 |
+
'latitude': climate_data.get('latitude', '40N'),
|
| 183 |
+
'wind_speed': climate_data.get('wind_speed', 4.0),
|
| 184 |
+
'day_of_year': climate_data.get('day_of_year', 204)
|
| 185 |
}
|
| 186 |
indoor_conditions = {
|
| 187 |
'temperature': building_info.get('indoor_temp', 24.0),
|
|
|
|
| 193 |
'people': {
|
| 194 |
'number': sum(load['num_people'] for load in internal_loads.get('people', [])),
|
| 195 |
'activity_level': internal_loads.get('people', [{}])[0].get('activity_level', 'Seated/Resting'),
|
| 196 |
+
'operating_hours': f"{internal_loads.get('people', [{}])[0].get('hours_in_operation', 8)}:00-{internal_loads.get('people', [{}])[0].get('hours_in_operation', 8)+10}:00"
|
| 197 |
},
|
| 198 |
'lights': {
|
| 199 |
'power': sum(load['power'] for load in internal_loads.get('lighting', [])),
|
|
|
|
| 207 |
'radiation_factor': internal_loads.get('equipment', [{}])[0].get('radiation_fraction', 0.3),
|
| 208 |
'hours_operation': f"{internal_loads.get('equipment', [{}])[0].get('hours_in_operation', 8)}h"
|
| 209 |
},
|
| 210 |
+
'infiltration': {
|
| 211 |
+
'flow_rate': building_info.get('infiltration_rate', 0.05),
|
| 212 |
+
'height': building_info.get('building_height', 3.0),
|
| 213 |
+
'crack_length': building_info.get('crack_length', 10.0)
|
| 214 |
+
},
|
| 215 |
+
'ventilation': {
|
| 216 |
+
'flow_rate': building_info.get('ventilation_rate', 0.1)
|
| 217 |
+
},
|
| 218 |
+
'operating_hours': building_info.get('operating_hours', '8:00-18:00')
|
| 219 |
}
|
| 220 |
|
| 221 |
# Calculate hourly loads
|
|
|
|
| 223 |
building_components=building_components,
|
| 224 |
outdoor_conditions=outdoor_conditions,
|
| 225 |
indoor_conditions=indoor_conditions,
|
| 226 |
+
internal_loads=formatted_internal_loads,
|
| 227 |
+
building_volume=building_info.get('floor_area', 100.0) * building_info.get('building_height', 3.0)
|
| 228 |
)
|
| 229 |
|
| 230 |
# Get design loads
|
|
|
|
| 334 |
indoor_temp=indoor_conditions['temperature'],
|
| 335 |
month=outdoor_conditions['month'],
|
| 336 |
hour=design_loads['design_hour'],
|
| 337 |
+
latitude=outdoor_conditions['latitude'], # Fixed latitude format
|
| 338 |
+
shading_coefficient=window.shading_coefficient
|
| 339 |
)
|
| 340 |
+
scl_latitude = f"{float(outdoor_conditions['latitude'][:-1])}_{outdoor_conditions['month'].upper()}" # Adjusted for ASHRAE SCL tables
|
| 341 |
results['detailed_loads']['windows'].append({
|
| 342 |
'name': window.name,
|
| 343 |
'orientation': window.orientation.value,
|
| 344 |
'area': window.area,
|
| 345 |
'u_value': window.u_value,
|
| 346 |
'shgc': window.shgc,
|
| 347 |
+
'shading_device': window.shading_device,
|
| 348 |
+
'shading_coefficient': window.shading_coefficient,
|
| 349 |
'scl': self.cooling_calculator.ashrae_tables.get_scl(
|
| 350 |
window.orientation.value,
|
| 351 |
design_loads['design_hour'],
|
| 352 |
+
scl_latitude
|
| 353 |
),
|
| 354 |
'load': load_dict['total'] / 1000
|
| 355 |
})
|
|
|
|
| 375 |
load_dict = self.cooling_calculator.calculate_people_cooling_load(
|
| 376 |
num_people=load['num_people'],
|
| 377 |
activity_level=load['activity_level'],
|
|
|
|
| 378 |
hour=design_loads['design_hour']
|
| 379 |
)
|
| 380 |
elif load_type == 'lighting':
|
|
|
|
| 382 |
power=load['power'],
|
| 383 |
use_factor=load['usage_factor'],
|
| 384 |
special_allowance=0.1,
|
|
|
|
| 385 |
hour=design_loads['design_hour']
|
| 386 |
)}
|
| 387 |
else:
|
|
|
|
| 389 |
power=load['power'],
|
| 390 |
use_factor=load['usage_factor'],
|
| 391 |
radiation_factor=load['radiation_fraction'],
|
|
|
|
| 392 |
hour=design_loads['design_hour']
|
| 393 |
)
|
| 394 |
results['detailed_loads']['internal'].append({
|
|
|
|
| 455 |
formatted_internal_loads = {
|
| 456 |
'people': {
|
| 457 |
'number': sum(load['num_people'] for load in internal_loads.get('people', [])),
|
| 458 |
+
'sensible_gain': 70,
|
| 459 |
+
'operating_hours': f"{internal_loads.get('people', [{}])[0].get('hours_in_operation', 8)}:00-{internal_loads.get('people', [{}])[0].get('hours_in_operation', 8)+10}:00"
|
| 460 |
},
|
| 461 |
'lights': {
|
| 462 |
'power': sum(load['power'] for load in internal_loads.get('lighting', [])),
|
| 463 |
+
'use_factor': internal_loads.get('lighting', [{}])[0].get('usage_factor', 0.8),
|
| 464 |
+
'hours_operation': f"{internal_loads.get('lighting', [{}])[0].get('hours_in_operation', 8)}h"
|
| 465 |
},
|
| 466 |
'equipment': {
|
| 467 |
'power': sum(load['power'] for load in internal_loads.get('equipment', [])),
|
| 468 |
+
'use_factor': internal_loads.get('equipment', [{}])[0].get('usage_factor', 0.7),
|
| 469 |
+
'hours_operation': f"{internal_loads.get('equipment', [{}])[0].get('hours_in_operation', 8)}h"
|
| 470 |
+
},
|
| 471 |
+
'infiltration': {
|
| 472 |
+
'flow_rate': building_info.get('infiltration_rate', 0.05),
|
| 473 |
+
'height': building_info.get('building_height', 3.0),
|
| 474 |
+
'crack_length': building_info.get('crack_length', 10.0)
|
| 475 |
},
|
| 476 |
+
'ventilation': {
|
| 477 |
+
'flow_rate': building_info.get('ventilation_rate', 0.1)
|
| 478 |
+
},
|
| 479 |
+
'usage_factor': 0.7,
|
| 480 |
+
'operating_hours': building_info.get('operating_hours', '8:00-18:00')
|
| 481 |
}
|
| 482 |
|
| 483 |
+
# Debug: Log inputs to verify
|
| 484 |
+
st.write("Debug: Heating Inputs", {
|
| 485 |
+
'building_components': {k: len(v) for k, v in building_components.items()},
|
| 486 |
+
'outdoor_conditions': outdoor_conditions,
|
| 487 |
+
'indoor_conditions': indoor_conditions,
|
| 488 |
+
'internal_loads': formatted_internal_loads
|
| 489 |
+
})
|
| 490 |
+
|
| 491 |
# Calculate design loads
|
| 492 |
design_loads = self.heating_calculator.calculate_design_heating_load(
|
| 493 |
building_components=building_components,
|
|
|
|
| 613 |
|
| 614 |
return True, "Heating calculation completed.", results
|
| 615 |
except Exception as e:
|
| 616 |
+
st.error(f"Heating calculation error: {str(e)}")
|
| 617 |
return False, f"Heating calculation error: {str(e)}", {}
|
| 618 |
|
| 619 |
def display_calculation_results(self):
|
|
|
|
| 635 |
|
| 636 |
if debug:
|
| 637 |
st.write("Cooling Inputs:", {
|
| 638 |
+
'components': {k: len(v) for k, v in st.session_state.get('components', {}).items()},
|
| 639 |
'internal_loads': st.session_state.get('internal_loads', {}),
|
| 640 |
'climate_data': st.session_state.get('climate_data', {}),
|
| 641 |
'building_info': st.session_state.get('building_info', {})
|
|
|
|
| 659 |
|
| 660 |
if debug:
|
| 661 |
st.write("Heating Inputs:", {
|
| 662 |
+
'components': {k: len(v) for k, v in st.session_state.get('components', {}).items()},
|
| 663 |
'internal_loads': st.session_state.get('internal_loads', {}),
|
| 664 |
'climate_data': st.session_state.get('climate_data', {}),
|
| 665 |
'building_info': st.session_state.get('building_info', {})
|