mabuseif commited on
Commit
00ba1a9
·
verified ·
1 Parent(s): 9ddc180

Update app/internal_loads.py

Browse files
Files changed (1) hide show
  1. app/internal_loads.py +81 -87
app/internal_loads.py CHANGED
@@ -927,51 +927,63 @@ def display_schedules_tab():
927
  """
928
  Display the schedules tab content with vertical sliders for hourly schedules.
929
  """
 
 
 
930
  st.subheader("Schedules Editor")
931
 
932
- # Initialise editor state if not present
933
  if "schedule_editor" not in st.session_state:
934
  st.session_state.schedule_editor = {}
935
 
 
 
 
936
  editor_state = st.session_state.schedule_editor
937
  is_edit = editor_state.get("is_edit", False)
938
 
939
- # Schedule name and description
940
- name = st.text_input(
941
- "Schedule Name",
942
- value=editor_state.get("name", ""),
943
- help="Enter a unique name for this schedule."
944
- )
945
 
946
- description = st.text_area(
947
- "Description",
948
- value=editor_state.get("description", ""),
949
- help="Describe the schedule's purpose or usage."
950
- )
951
 
952
- # Template selection
953
- template_options = list(DEFAULT_SCHEDULE_TEMPLATES.keys())
954
  selected_template = st.selectbox(
955
  "Select Template",
956
  options=["None"] + template_options,
957
  index=template_options.index(editor_state.get("template", "custom")) + 1
958
- if editor_state.get("template") in template_options else 0,
959
- help="Select a template to prefill the schedule, or 'None' to start from scratch."
960
  )
961
 
962
- # Load or initialise weekday/weekend values
963
- if is_edit and editor_state.get("weekday") and editor_state.get("weekend"):
964
- weekday_values = editor_state["weekday"]
965
- weekend_values = editor_state["weekend"]
966
- elif selected_template != "None":
967
- template_data = DEFAULT_SCHEDULE_TEMPLATES.get(selected_template, DEFAULT_SCHEDULE_TEMPLATES["custom"])
968
- weekday_values = template_data.get("weekday", [0.0] * 24)
969
- weekend_values = template_data.get("weekend", [0.0] * 24)
970
- else:
971
- weekday_values = [0.0] * 24
972
- weekend_values = [0.0] * 24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
973
 
974
- # CSS for layout and styling
975
  st.markdown("""
976
  <style>
977
  .slider-container {
@@ -983,15 +995,12 @@ def display_schedules_tab():
983
  padding: 10px;
984
  overflow-x: auto;
985
  min-width: 100%;
986
- box-sizing: border-box;
987
  }
988
  .slider-item {
989
  display: flex;
990
  flex-direction: column;
991
  align-items: center;
992
  width: 45px;
993
- min-width: 45px;
994
- margin: 0 2px;
995
  }
996
  .hour-label {
997
  text-align: center;
@@ -1003,68 +1012,51 @@ def display_schedules_tab():
1003
  .stVerticalSlider {
1004
  height: 150px !important;
1005
  }
1006
- .stVerticalSlider .slider-track {
1007
- background: #e0e0e0 !important;
1008
- }
1009
- .stVerticalSlider .slider-thumb {
1010
- background: #333 !important;
1011
- border: 2px solid #fff !important;
1012
- }
1013
  </style>
1014
  """, unsafe_allow_html=True)
1015
 
1016
- # Reusable block for rendering vertical sliders
1017
- def render_hourly_slider_block(prefix: str, values: list[float], slider_colour: str) -> list[float]:
1018
- sliders = []
1019
  st.markdown('<div class="slider-container">', unsafe_allow_html=True)
 
1020
  for hour in range(24):
1021
- with st.container():
1022
- st.markdown('<div class="slider-item">', unsafe_allow_html=True)
1023
- val = vertical_slider(
1024
- label="",
1025
- key=f"{prefix}_{hour}",
1026
- height=150,
1027
- thumb_shape="circle",
1028
- step=0.01,
1029
- default_value=float(values[hour]) if hour < len(values) else 0.0,
1030
- min_value=0.0,
1031
- max_value=1.0,
1032
- track_color="#e0e0e0",
1033
- slider_color=slider_colour,
1034
- thumb_color="#333",
1035
- value_always_visible=False
1036
- )
1037
- st.markdown(f'<div class="hour-label">{hour:02d}:00</div>', unsafe_allow_html=True)
1038
- st.markdown('</div>', unsafe_allow_html=True)
1039
- sliders.append(val if val is not None else float(values[hour]))
1040
  st.markdown('</div>', unsafe_allow_html=True)
1041
- return sliders
1042
 
1043
- # Weekday schedule
1044
  st.write("**Weekday Schedule**")
1045
- weekday_schedule = render_hourly_slider_block("weekday", weekday_values, "#4CAF50")
1046
 
1047
- # Weekend schedule
1048
  st.write("**Weekend Schedule**")
1049
- weekend_schedule = render_hourly_slider_block("weekend", weekend_values, "#2196F3")
1050
 
1051
- # Display saved schedules
1052
- st.write("**Saved Schedules**")
1053
  schedules = st.session_state.project_data["internal_loads"]["schedules"]
1054
- if schedules:
1055
- display_schedules_table(schedules)
1056
- else:
1057
- st.write("No schedules available.")
1058
-
1059
- # Action buttons
1060
  col1, col2 = st.columns(2)
 
1061
  with col1:
1062
- submit_label = "Update Schedule" if is_edit else "Add Schedule"
1063
- if st.button(submit_label):
1064
  if not name.strip():
1065
  st.error("Schedule name is required.")
1066
  elif name in schedules and not is_edit:
1067
- st.error("A schedule with this name already exists.")
1068
  else:
1069
  schedule_data = {
1070
  "description": description,
@@ -1072,28 +1064,30 @@ def display_schedules_tab():
1072
  "weekend": weekend_schedule
1073
  }
1074
 
1075
- # Update or add
1076
- if is_edit and editor_state.get("original_name"):
1077
- original_name = editor_state["original_name"]
1078
- if original_name != name and original_name in schedules:
1079
  del schedules[original_name]
1080
- schedules[name] = schedule_data
1081
- st.success(f"Schedule '{name}' updated successfully!")
1082
- else:
1083
- schedules[name] = schedule_data
1084
- st.success(f"Schedule '{name}' added successfully!")
1085
 
1086
- # Reset
1087
  st.session_state.schedule_editor = {}
1088
  st.session_state.module_rerun_flags["internal_loads"] = True
 
1089
  st.rerun()
1090
 
1091
  with col2:
1092
  if st.button("Cancel"):
1093
  st.session_state.schedule_editor = {}
1094
- st.session_state.module_rerun_flags["internal_loads"] = True
1095
  st.rerun()
1096
 
 
 
 
 
 
 
 
1097
  def is_schedule_in_use(schedule_name: str) -> bool:
1098
  """
1099
  Check if a schedule is in use by any people, lighting, equipment, or ventilation/infiltration systems.
 
927
  """
928
  Display the schedules tab content with vertical sliders for hourly schedules.
929
  """
930
+ import streamlit as st
931
+ from streamlit_vertical_slider import vertical_slider
932
+
933
  st.subheader("Schedules Editor")
934
 
935
+ # Initialise schedule editor state
936
  if "schedule_editor" not in st.session_state:
937
  st.session_state.schedule_editor = {}
938
 
939
+ if "template_selected" not in st.session_state:
940
+ st.session_state.template_selected = False
941
+
942
  editor_state = st.session_state.schedule_editor
943
  is_edit = editor_state.get("is_edit", False)
944
 
945
+ # Load available templates
946
+ template_options = list(DEFAULT_SCHEDULE_TEMPLATES.keys())
 
 
 
 
947
 
948
+ # Text inputs
949
+ name = st.text_input("Schedule Name", value=editor_state.get("name", ""))
950
+ description = st.text_area("Description", value=editor_state.get("description", ""))
 
 
951
 
 
 
952
  selected_template = st.selectbox(
953
  "Select Template",
954
  options=["None"] + template_options,
955
  index=template_options.index(editor_state.get("template", "custom")) + 1
956
+ if editor_state.get("template") in template_options else 0
 
957
  )
958
 
959
+ # Set flag and rerun if new template is selected
960
+ if selected_template != editor_state.get("template", "None"):
961
+ if selected_template != "None":
962
+ template_data = DEFAULT_SCHEDULE_TEMPLATES[selected_template]
963
+ st.session_state.schedule_editor = {
964
+ "template": selected_template,
965
+ "weekday": template_data["weekday"],
966
+ "weekend": template_data["weekend"],
967
+ "name": name,
968
+ "description": description,
969
+ "is_edit": is_edit,
970
+ }
971
+ else:
972
+ st.session_state.schedule_editor = {
973
+ "template": "None",
974
+ "weekday": [0.0] * 24,
975
+ "weekend": [0.0] * 24,
976
+ "name": name,
977
+ "description": description,
978
+ "is_edit": is_edit,
979
+ }
980
+ st.rerun()
981
+
982
+ # Get values from editor state
983
+ weekday_values = editor_state.get("weekday", [0.0] * 24)
984
+ weekend_values = editor_state.get("weekend", [0.0] * 24)
985
 
986
+ # CSS styling
987
  st.markdown("""
988
  <style>
989
  .slider-container {
 
995
  padding: 10px;
996
  overflow-x: auto;
997
  min-width: 100%;
 
998
  }
999
  .slider-item {
1000
  display: flex;
1001
  flex-direction: column;
1002
  align-items: center;
1003
  width: 45px;
 
 
1004
  }
1005
  .hour-label {
1006
  text-align: center;
 
1012
  .stVerticalSlider {
1013
  height: 150px !important;
1014
  }
 
 
 
 
 
 
 
1015
  </style>
1016
  """, unsafe_allow_html=True)
1017
 
1018
+ # Reusable vertical slider row
1019
+ def render_sliders(prefix, values, colour):
 
1020
  st.markdown('<div class="slider-container">', unsafe_allow_html=True)
1021
+ results = []
1022
  for hour in range(24):
1023
+ st.markdown('<div class="slider-item">', unsafe_allow_html=True)
1024
+ val = vertical_slider(
1025
+ label="",
1026
+ key=f"{prefix}_{hour}",
1027
+ height=150,
1028
+ step=0.01,
1029
+ min_value=0.0,
1030
+ max_value=1.0,
1031
+ default_value=values[hour],
1032
+ slider_color=colour,
1033
+ track_color="#e0e0e0",
1034
+ thumb_color="#333",
1035
+ value_always_visible=False
1036
+ )
1037
+ st.markdown(f'<div class="hour-label">{hour:02d}:00</div>', unsafe_allow_html=True)
1038
+ st.markdown('</div>', unsafe_allow_html=True)
1039
+ results.append(val)
 
 
1040
  st.markdown('</div>', unsafe_allow_html=True)
1041
+ return results
1042
 
1043
+ # Render sliders
1044
  st.write("**Weekday Schedule**")
1045
+ weekday_schedule = render_sliders("weekday", weekday_values, "#4CAF50")
1046
 
 
1047
  st.write("**Weekend Schedule**")
1048
+ weekend_schedule = render_sliders("weekend", weekend_values, "#2196F3")
1049
 
1050
+ # Save or update
 
1051
  schedules = st.session_state.project_data["internal_loads"]["schedules"]
 
 
 
 
 
 
1052
  col1, col2 = st.columns(2)
1053
+
1054
  with col1:
1055
+ if st.button("Save" if is_edit else "Add"):
 
1056
  if not name.strip():
1057
  st.error("Schedule name is required.")
1058
  elif name in schedules and not is_edit:
1059
+ st.error("Schedule already exists.")
1060
  else:
1061
  schedule_data = {
1062
  "description": description,
 
1064
  "weekend": weekend_schedule
1065
  }
1066
 
1067
+ if is_edit:
1068
+ original_name = editor_state.get("original_name", name)
1069
+ if original_name in schedules:
 
1070
  del schedules[original_name]
1071
+ schedules[name] = schedule_data
 
 
 
 
1072
 
1073
+ # Reset state
1074
  st.session_state.schedule_editor = {}
1075
  st.session_state.module_rerun_flags["internal_loads"] = True
1076
+ st.success(f"Schedule '{name}' saved.")
1077
  st.rerun()
1078
 
1079
  with col2:
1080
  if st.button("Cancel"):
1081
  st.session_state.schedule_editor = {}
 
1082
  st.rerun()
1083
 
1084
+ # Show saved schedules (optional)
1085
+ st.write("**Saved Schedules**")
1086
+ if schedules:
1087
+ display_schedules_table(schedules)
1088
+ else:
1089
+ st.info("No schedules saved yet.")
1090
+
1091
  def is_schedule_in_use(schedule_name: str) -> bool:
1092
  """
1093
  Check if a schedule is in use by any people, lighting, equipment, or ventilation/infiltration systems.