mabuseif commited on
Commit
ef5a882
·
verified ·
1 Parent(s): fc5d8bf

Update app/component_selection.py

Browse files
Files changed (1) hide show
  1. app/component_selection.py +168 -37
app/component_selection.py CHANGED
@@ -331,7 +331,49 @@ class ComponentSelectionInterface:
331
  self.shading_system = shading_system
332
  self.reference_data = reference_data
333
 
334
- # ... other methods like display_component_selection, _display_component_tab, etc. ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
 
336
  def _display_add_component_form(self, session_state: Any, component_type: ComponentType) -> None:
337
  type_name = component_type.value.lower()
@@ -456,7 +498,131 @@ class ComponentSelectionInterface:
456
  if session_state[f"add_{type_name}_submitted"]:
457
  session_state[f"add_{type_name}_submitted"] = False
458
 
459
- # ... other methods ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
 
461
  def _display_u_value_calculator_tab(self, session_state: Any) -> None:
462
  st.subheader("U-Value Calculator")
@@ -546,41 +712,6 @@ class ComponentSelectionInterface:
546
  session_state.material_layers.pop()
547
  st.rerun()
548
 
549
- # ... other methods like _display_components_table, _save_components, etc. ...
550
-
551
- with st.form("material_layer_form"):
552
- col1, col2 = st.columns(2)
553
- with col1:
554
- material_selection = st.radio("Material Selection", ["Select from Presets", "Custom Material"])
555
- if material_selection == "Select from Presets":
556
- preset_materials = self.u_value_calculator.get_preset_materials()
557
- material_options = {m["name"]: m for m in preset_materials}
558
- material_name = st.selectbox("Material", options=list(material_options.keys()))
559
- conductivity = material_options[material_name]["conductivity"]
560
- st.number_input("Conductivity (W/m·K)", value=conductivity, disabled=True)
561
- else:
562
- material_name = st.text_input("Material Name", "Custom Material")
563
- conductivity = st.number_input("Conductivity (W/m·K)", min_value=0.0, value=1.0, step=0.01)
564
-
565
- with col2:
566
- thickness = st.number_input("Thickness (mm)", min_value=0.0, value=100.0, step=1.0)
567
- if conductivity > 0:
568
- r_value = thickness / 1000 / conductivity
569
- st.metric("Layer R-Value", f"{r_value:.3f} m²·K/W")
570
-
571
- submitted = st.form_submit_button("Add Layer")
572
- if submitted:
573
- if not material_name:
574
- st.error("Material name is required!")
575
- elif thickness <= 0:
576
- st.error("Thickness must be greater than zero!")
577
- elif conductivity <= 0:
578
- st.error("Conductivity must be greater than zero!")
579
- else:
580
- session_state.material_layers.append({"name": material_name, "thickness": thickness, "conductivity": conductivity})
581
- st.success(f"Added layer: {material_name}")
582
- st.rerun()
583
-
584
  def _save_components(self, session_state: Any) -> None:
585
  components_dict = {
586
  "walls": [c.to_dict() for c in session_state.components["walls"]],
 
331
  self.shading_system = shading_system
332
  self.reference_data = reference_data
333
 
334
+ def display_component_selection(self, session_state: Any) -> None:
335
+ st.title("Building Components")
336
+
337
+ if 'components' not in session_state:
338
+ session_state.components = {'walls': [], 'roofs': [], 'floors': [], 'windows': [], 'doors': []}
339
+
340
+ tabs = st.tabs(["Walls", "Roofs", "Floors", "Windows", "Doors", "U-Value Calculator"])
341
+
342
+ with tabs[0]:
343
+ self._display_component_tab(session_state, ComponentType.WALL)
344
+ with tabs[1]:
345
+ self._display_component_tab(session_state, ComponentType.ROOF)
346
+ with tabs[2]:
347
+ self._display_component_tab(session_state, ComponentType.FLOOR)
348
+ with tabs[3]:
349
+ self._display_component_tab(session_state, ComponentType.WINDOW)
350
+ with tabs[4]:
351
+ self._display_component_tab(session_state, ComponentType.DOOR)
352
+ with tabs[5]:
353
+ self._display_u_value_calculator_tab(session_state)
354
+
355
+ col1, col2 = st.columns(2)
356
+ with col1:
357
+ if st.button("Save Components"):
358
+ self._save_components(session_state)
359
+ with col2:
360
+ uploaded_file = st.file_uploader("Load Components", type=["json"])
361
+ if uploaded_file and st.button("Load Uploaded Components"):
362
+ self._load_components(session_state, uploaded_file)
363
+
364
+ def _display_component_tab(self, session_state: Any, component_type: ComponentType) -> None:
365
+ type_name = component_type.value.lower()
366
+ st.subheader(f"{type_name.capitalize()} Components")
367
+
368
+ with st.expander(f"Add {type_name.capitalize()}", expanded=False):
369
+ self._display_add_component_form(session_state, component_type)
370
+
371
+ components = session_state.components.get(type_name + 's', [])
372
+ if components:
373
+ st.subheader(f"Existing {type_name.capitalize()} Components")
374
+ self._display_components_table(session_state, component_type, components)
375
+ else:
376
+ st.info(f"No {type_name} components defined yet.")
377
 
378
  def _display_add_component_form(self, session_state: Any, component_type: ComponentType) -> None:
379
  type_name = component_type.value.lower()
 
498
  if session_state[f"add_{type_name}_submitted"]:
499
  session_state[f"add_{type_name}_submitted"] = False
500
 
501
+ def _display_components_table(self, session_state: Any, component_type: ComponentType, components: List[BuildingComponent]) -> None:
502
+ type_name = component_type.value.lower()
503
+ data = []
504
+ for comp in components:
505
+ row = {"Name": comp.name, "Area (m²)": comp.area, "U-Value (W/m²·K)": comp.u_value, "Orientation": comp.orientation.value, "ID": comp.id}
506
+ if component_type == ComponentType.WALL:
507
+ row.update({"Wall Type": comp.wall_type, "Wall Group": comp.wall_group})
508
+ elif component_type == ComponentType.ROOF:
509
+ row.update({"Roof Type": comp.roof_type, "Roof Group": comp.roof_group})
510
+ elif component_type == ComponentType.FLOOR:
511
+ row.update({"Floor Type": comp.floor_type})
512
+ elif component_type == ComponentType.WINDOW:
513
+ row.update({"SHGC": comp.shgc, "VT": comp.vt, "Window Type": comp.window_type,
514
+ "Effective SHGC": self.shading_system.calculate_effective_shgc(comp.shgc, comp.shading_device_id)})
515
+ elif component_type == ComponentType.DOOR:
516
+ row.update({"Door Type": comp.door_type})
517
+ data.append(row)
518
+
519
+ df = pd.DataFrame(data)
520
+ display_cols = [col for col in df.columns if col != "ID"]
521
+ st.dataframe(df[display_cols], use_container_width=True)
522
+
523
+ for i, row in df.iterrows():
524
+ col1, col2 = st.columns(2)
525
+ with col1:
526
+ if st.button("Edit", key=f"edit_{row['ID']}"):
527
+ session_state[f"edit_{type_name}"] = row["ID"]
528
+ st.rerun()
529
+ with col2:
530
+ if st.button("Delete", key=f"delete_{row['ID']}"):
531
+ if not row["ID"].startswith("preset_"):
532
+ self.component_library.remove_component(row["ID"])
533
+ session_state.components[type_name + 's'] = [c for c in components if c.id != row["ID"]]
534
+ st.success(f"Deleted {row['Name']}")
535
+ st.rerun()
536
+ else:
537
+ st.warning("Cannot delete preset components.")
538
+
539
+ if f"edit_{type_name}" in session_state:
540
+ self._display_edit_component_form(session_state, component_type, session_state[f"edit_{type_name}"])
541
+ del session_state[f"edit_{type_name}"]
542
+
543
+ def _display_edit_component_form(self, session_state: Any, component_type: ComponentType, component_id: str) -> None:
544
+ type_name = component_type.value.lower()
545
+ component = next((c for c in session_state.components[type_name + 's'] if c.id == component_id), None)
546
+ if not component:
547
+ st.error("Component not found.")
548
+ return
549
+
550
+ with st.form(f"edit_{component_id}_form"):
551
+ col1, col2 = st.columns(2)
552
+ with col1:
553
+ name = st.text_input("Name", value=component.name)
554
+ area = st.number_input("Area (m²)", min_value=0.0, value=component.area, step=0.1)
555
+ if component_type not in [ComponentType.ROOF, ComponentType.FLOOR]:
556
+ orientation = st.selectbox("Orientation", [o.value for o in Orientation],
557
+ index=[o.value for o in Orientation].index(component.orientation.value))
558
+ else:
559
+ orientation = Orientation.HORIZONTAL.value
560
+
561
+ with col2:
562
+ u_value = st.number_input("U-Value (W/m²·K)", min_value=0.0, value=component.u_value, step=0.01)
563
+ if component_type == ComponentType.WALL:
564
+ wall_type = st.text_input("Wall Type", value=component.wall_type)
565
+ wall_group = st.selectbox("Wall Group", ["A", "B", "C", "D", "E", "F", "G", "H"],
566
+ index=["A", "B", "C", "D", "E", "F", "G", "H"].index(component.wall_group))
567
+ elif component_type == ComponentType.ROOF:
568
+ roof_type = st.text_input("Roof Type", value=component.roof_type)
569
+ roof_group = st.selectbox("Roof Group", ["A", "B", "C", "D", "E", "F", "G"],
570
+ index=["A", "B", "C", "D", "E", "F", "G"].index(component.roof_group))
571
+ elif component_type == ComponentType.FLOOR:
572
+ floor_type = st.text_input("Floor Type", value=component.floor_type)
573
+ elif component_type == ComponentType.WINDOW:
574
+ shgc = st.number_input("SHGC", min_value=0.0, max_value=1.0, value=component.shgc, step=0.01)
575
+ vt = st.number_input("VT", min_value=0.0, max_value=1.0, value=component.vt, step=0.01)
576
+ window_type = st.text_input("Window Type", value=component.window_type)
577
+ glazing_layers = st.selectbox("Glazing Layers", [1, 2, 3], index=[1, 2, 3].index(component.glazing_layers))
578
+ gas_fill = st.selectbox("Gas Fill", ["Air", "Argon", "Krypton"],
579
+ index=["Air", "Argon", "Krypton"].index(component.gas_fill))
580
+ low_e_coating = st.checkbox("Low-E Coating", value=component.low_e_coating)
581
+ shading_options = {d.name: d.id for d in self.shading_system.shading_devices.values()}
582
+ shading_device = st.selectbox("Shading Device", options=list(shading_options.keys()),
583
+ index=list(shading_options.keys()).index(self.shading_system.get_device(component.shading_device_id).name))
584
+ coverage = st.number_input("Coverage (%)", min_value=0.0, max_value=100.0,
585
+ value=self.shading_system.get_device(component.shading_device_id).coverage_percentage, step=5.0)
586
+ device = self.shading_system.get_device(shading_options[shading_device])
587
+ device.coverage_percentage = coverage
588
+ st.write(f"Effective SHGC: {self.shading_system.calculate_effective_shgc(shgc, shading_options[shading_device]):.2f}")
589
+ elif component_type == ComponentType.DOOR:
590
+ door_type = st.text_input("Door Type", value=component.door_type)
591
+
592
+ submitted = st.form_submit_button("Update Component")
593
+ if submitted:
594
+ if not name:
595
+ st.error(f"{type_name.capitalize()} name is required!")
596
+ elif area <= 0:
597
+ st.error(f"{type_name.capitalize()} area must be greater than zero!")
598
+ elif u_value <= 0:
599
+ st.error(f"{type_name.capitalize()} U-value must be greater than zero!")
600
+ else:
601
+ component.name = name
602
+ component.area = area
603
+ component.u_value = u_value
604
+ component.orientation = Orientation(orientation)
605
+ if component_type == ComponentType.WALL:
606
+ component.wall_type = wall_type
607
+ component.wall_group = wall_group
608
+ elif component_type == ComponentType.ROOF:
609
+ component.roof_type = roof_type
610
+ component.roof_group = roof_group
611
+ elif component_type == ComponentType.FLOOR:
612
+ component.floor_type = floor_type
613
+ elif component_type == ComponentType.WINDOW:
614
+ component.shgc = shgc
615
+ component.vt = vt
616
+ component.window_type = window_type
617
+ component.glazing_layers = glazing_layers
618
+ component.gas_fill = gas_fill
619
+ component.low_e_coating = low_e_coating
620
+ component.shading_device_id = shading_options[shading_device]
621
+ elif component_type == ComponentType.DOOR:
622
+ component.door_type = door_type
623
+ self.component_library.update_component(component_id, component)
624
+ st.success(f"Updated {name}")
625
+ st.rerun()
626
 
627
  def _display_u_value_calculator_tab(self, session_state: Any) -> None:
628
  st.subheader("U-Value Calculator")
 
712
  session_state.material_layers.pop()
713
  st.rerun()
714
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  def _save_components(self, session_state: Any) -> None:
716
  components_dict = {
717
  "walls": [c.to_dict() for c in session_state.components["walls"]],