Spaces:
Sleeping
Sleeping
Update data/building_components.py
Browse files- data/building_components.py +26 -2
data/building_components.py
CHANGED
@@ -93,7 +93,7 @@ class BuildingComponent:
|
|
93 |
u_value: float # W/(m²·K)
|
94 |
area: float # m²
|
95 |
orientation: Orientation = Orientation.NOT_APPLICABLE
|
96 |
-
|
97 |
material_layers: List[MaterialLayer] = field(default_factory=list)
|
98 |
|
99 |
def __post_init__(self):
|
@@ -102,6 +102,13 @@ class BuildingComponent:
|
|
102 |
raise ValueError("Area must be greater than zero")
|
103 |
if self.u_value < 0:
|
104 |
raise ValueError("U-value cannot be negative")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
@property
|
107 |
def r_value(self) -> float:
|
@@ -152,7 +159,7 @@ class BuildingComponent:
|
|
152 |
"u_value": self.u_value,
|
153 |
"area": self.area,
|
154 |
"orientation": self.orientation.value,
|
155 |
-
"
|
156 |
"r_value": self.r_value,
|
157 |
"material_layers": [layer.to_dict() for layer in self.material_layers],
|
158 |
"calculated_u_value": self.calculated_u_value,
|
@@ -532,6 +539,23 @@ class BuildingComponentFactory:
|
|
532 |
if isinstance(component_type, str):
|
533 |
component_type = ComponentType[component_type]
|
534 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
535 |
# Handle drapery for Window components
|
536 |
if component_type == ComponentType.WINDOW:
|
537 |
drapery_data = component_data.pop("drapery", None)
|
|
|
93 |
u_value: float # W/(m²·K)
|
94 |
area: float # m²
|
95 |
orientation: Orientation = Orientation.NOT_APPLICABLE
|
96 |
+
solar_absorptivity: float = 0.6 # Solar absorptivity (0-1), default Medium
|
97 |
material_layers: List[MaterialLayer] = field(default_factory=list)
|
98 |
|
99 |
def __post_init__(self):
|
|
|
102 |
raise ValueError("Area must be greater than zero")
|
103 |
if self.u_value < 0:
|
104 |
raise ValueError("U-value cannot be negative")
|
105 |
+
# Enforce solar_absorptivity to be one of the five allowed values
|
106 |
+
valid_absorptivities = [0.3, 0.45, 0.6, 0.75, 0.9]
|
107 |
+
if not 0 <= self.solar_absorptivity <= 1:
|
108 |
+
raise ValueError("Solar absorptivity must be between 0 and 1")
|
109 |
+
if self.solar_absorptivity not in valid_absorptivities:
|
110 |
+
# Find the closest valid value
|
111 |
+
self.solar_absorptivity = min(valid_absorptivities, key=lambda x: abs(x - self.solar_absorptivity))
|
112 |
|
113 |
@property
|
114 |
def r_value(self) -> float:
|
|
|
159 |
"u_value": self.u_value,
|
160 |
"area": self.area,
|
161 |
"orientation": self.orientation.value,
|
162 |
+
"solar_absorptivity": self.solar_absorptivity,
|
163 |
"r_value": self.r_value,
|
164 |
"material_layers": [layer.to_dict() for layer in self.material_layers],
|
165 |
"calculated_u_value": self.calculated_u_value,
|
|
|
539 |
if isinstance(component_type, str):
|
540 |
component_type = ComponentType[component_type]
|
541 |
|
542 |
+
# Handle legacy 'color' field for backward compatibility
|
543 |
+
if "color" in component_data and "solar_absorptivity" not in component_data:
|
544 |
+
color_map = {
|
545 |
+
"Light": 0.3, # Maps to Light
|
546 |
+
"Light to Medium": 0.45, # Maps to Light to Medium
|
547 |
+
"Light-Medium": 0.45, # Alternative spelling for legacy data
|
548 |
+
"Medium": 0.6, # Maps to Medium
|
549 |
+
"Medium to Dark": 0.75, # Maps to Medium to Dark
|
550 |
+
"Medium-Dark": 0.75, # Alternative spelling for legacy data
|
551 |
+
"Dark": 0.9 # Maps to Dark
|
552 |
+
}
|
553 |
+
# Use the mapped value or default to 0.6 (Medium) for unrecognized colors
|
554 |
+
color = component_data["color"]
|
555 |
+
component_data["solar_absorptivity"] = color_map.get(color, 0.6)
|
556 |
+
if color not in color_map:
|
557 |
+
print(f"Warning: Unrecognized legacy color '{color}' in component data. Defaulting to solar_absorptivity = 0.6 (Medium).")
|
558 |
+
|
559 |
# Handle drapery for Window components
|
560 |
if component_type == ComponentType.WINDOW:
|
561 |
drapery_data = component_data.pop("drapery", None)
|