mabuseif commited on
Commit
3832384
·
verified ·
1 Parent(s): 0294d90

Update app/internal_loads.py

Browse files
Files changed (1) hide show
  1. app/internal_loads.py +141 -127
app/internal_loads.py CHANGED
@@ -25,6 +25,31 @@ from typing import Dict, List, Any, Optional, Tuple, Union
25
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
26
  logger = logging.getLogger(__name__)
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  # Define constants
29
  LOAD_TYPES = ["People", "Lighting", "Equipment", "Ventilation & Infiltration", "Schedules"]
30
 
@@ -923,16 +948,15 @@ def display_ventilation_infiltration_tab():
923
  st.rerun()
924
 
925
  def display_schedules_tab():
926
- """Display the schedules tab content with comprehensive schedule management."""
 
 
927
  # Split the display into two columns
928
  col1, col2 = st.columns([3, 2])
929
 
930
  with col1:
931
  st.subheader("Saved Schedules")
932
-
933
- # Get schedules from session state
934
  schedules = st.session_state.project_data["internal_loads"]["schedules"]
935
-
936
  if schedules:
937
  display_schedules_table(schedules)
938
  else:
@@ -941,140 +965,130 @@ def display_schedules_tab():
941
  with col2:
942
  st.subheader("Schedule Editor/Creator")
943
 
944
- # Check if we have an editor state for schedules
945
  if "schedule_editor" not in st.session_state:
946
  st.session_state.schedule_editor = {}
947
 
948
- # Display the schedule editor form
949
- with st.form("schedule_editor_form", clear_on_submit=True):
950
- editor_state = st.session_state.get("schedule_editor", {})
951
- is_edit = editor_state.get("is_edit", False)
952
-
953
- # Schedule name
954
- name = st.text_input(
955
- "Schedule Name",
956
- value=editor_state.get("name", ""),
957
- help="Enter a unique name for this schedule."
958
- )
959
-
960
- # Description
961
- description = st.text_area(
962
- "Description",
963
- value=editor_state.get("description", ""),
964
- help="Brief description of this schedule."
 
 
 
 
 
965
  )
966
-
967
- # Template selection for new schedules
968
- if not is_edit:
969
- template = st.selectbox(
970
- "Start from Template",
971
- ["Custom"] + list(DEFAULT_SCHEDULE_TEMPLATES.keys()),
972
- help="Select a template to start with, or choose Custom for blank schedule."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
973
  )
974
- else:
975
- template = "Custom"
976
-
977
- # Schedule values
978
- st.write("**Hourly Schedule Values (0.0 - 1.0):**")
979
-
980
- # Initialize schedule values
981
- if template != "Custom" and not is_edit:
982
- weekday_values = DEFAULT_SCHEDULE_TEMPLATES[template]["weekday"]
983
- weekend_values = DEFAULT_SCHEDULE_TEMPLATES[template]["weekend"]
984
- else:
985
- weekday_values = editor_state.get("weekday", [0.0] * 24)
986
- weekend_values = editor_state.get("weekend", [0.0] * 24)
987
-
988
- # Weekday schedule
989
- st.write("**Weekday Schedule:**")
990
- weekday_cols = st.columns(6)
991
- weekday_schedule = []
992
-
993
- for hour in range(24):
994
- col_idx = hour % 6
995
- with weekday_cols[col_idx]:
996
- value = st.number_input(
997
- f"H{hour:02d}",
998
- min_value=0.0,
999
- max_value=1.0,
1000
- value=float(weekday_values[hour]),
1001
- format="%.2f",
1002
- key=f"weekday_{hour}",
1003
- help=f"Hour {hour}:00 weekday value"
1004
- )
1005
- weekday_schedule.append(value)
1006
-
1007
- # Weekend schedule
1008
- st.write("**Weekend Schedule:**")
1009
- weekend_cols = st.columns(6)
1010
- weekend_schedule = []
1011
-
1012
- for hour in range(24):
1013
- col_idx = hour % 6
1014
- with weekend_cols[col_idx]:
1015
- value = st.number_input(
1016
- f"H{hour:02d}",
1017
- min_value=0.0,
1018
- max_value=1.0,
1019
- value=float(weekend_values[hour]),
1020
- format="%.2f",
1021
- key=f"weekend_{hour}",
1022
- help=f"Hour {hour}:00 weekend value"
1023
- )
1024
- weekend_schedule.append(value)
1025
-
1026
- # Submit buttons
1027
- col1, col2 = st.columns(2)
1028
- with col1:
1029
- submit_label = "Update Schedule" if is_edit else "Add Schedule"
1030
- submit = st.form_submit_button(submit_label)
1031
-
1032
- with col2:
1033
- cancel = st.form_submit_button("Cancel")
1034
 
1035
- # Handle form submission
1036
- if submit:
1037
- # Validate inputs
1038
- if not name.strip():
1039
- st.error("Schedule name is required.")
1040
- elif name in schedules and not is_edit:
1041
- st.error("A schedule with this name already exists.")
1042
- else:
1043
- # Create schedule data
1044
- schedule_data = {
1045
- "description": description,
1046
- "weekday": weekday_schedule,
1047
- "weekend": weekend_schedule
1048
- }
1049
-
1050
- # Check if editing or adding new
1051
- if is_edit and st.session_state.schedule_editor.get("original_name"):
1052
- # Update existing schedule
1053
- original_name = st.session_state.schedule_editor["original_name"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1054
 
1055
- # If name changed, remove old and add new
1056
- if original_name != name and original_name in schedules:
1057
- del schedules[original_name]
 
 
 
 
 
 
 
1058
 
1059
- schedules[name] = schedule_data
1060
- st.success(f"Schedule '{name}' updated successfully!")
1061
- else:
1062
- # Add new schedule
1063
- schedules[name] = schedule_data
1064
- st.success(f"Schedule '{name}' added successfully!")
1065
-
1066
- # Clear editor state
1067
  st.session_state.schedule_editor = {}
1068
- # [FIX]: Use module_rerun_flags instead of internal_loads_rerun_pending
1069
  st.session_state.module_rerun_flags["internal_loads"] = True
1070
  st.rerun()
1071
-
1072
- if cancel:
1073
- # Clear editor state
1074
- st.session_state.schedule_editor = {}
1075
- # [FIX]: Use module_rerun_flags instead of internal_loads_rerun_pending
1076
- st.session_state.module_rerun_flags["internal_loads"] = True
1077
- st.rerun()
1078
 
1079
  def is_schedule_in_use(schedule_name: str) -> bool:
1080
  """
 
25
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
26
  logger = logging.getLogger(__name__)
27
 
28
+ # Custom CSS for vertical sliders
29
+ st.markdown("""
30
+ <style>
31
+ .slider-container {
32
+ display: flex;
33
+ flex-direction: row;
34
+ align-items: flex-end;
35
+ justify-content: center;
36
+ gap: 8px;
37
+ padding-top: 30px;
38
+ }
39
+ .slider-item {
40
+ writing-mode: bt-lr;
41
+ transform: rotate(-90deg);
42
+ height: 150px;
43
+ width: 30px;
44
+ }
45
+ .hour-label {
46
+ text-align: center;
47
+ font-size: 12px;
48
+ margin-top: 5px;
49
+ }
50
+ </style>
51
+ """, unsafe_allow_html=True)
52
+
53
  # Define constants
54
  LOAD_TYPES = ["People", "Lighting", "Equipment", "Ventilation & Infiltration", "Schedules"]
55
 
 
948
  st.rerun()
949
 
950
  def display_schedules_tab():
951
+ """Display the schedules tab content with responsive vertical slider interface."""
952
+ st.subheader("Schedule Management")
953
+
954
  # Split the display into two columns
955
  col1, col2 = st.columns([3, 2])
956
 
957
  with col1:
958
  st.subheader("Saved Schedules")
 
 
959
  schedules = st.session_state.project_data["internal_loads"]["schedules"]
 
960
  if schedules:
961
  display_schedules_table(schedules)
962
  else:
 
965
  with col2:
966
  st.subheader("Schedule Editor/Creator")
967
 
968
+ # Initialize editor state
969
  if "schedule_editor" not in st.session_state:
970
  st.session_state.schedule_editor = {}
971
 
972
+ editor_state = st.session_state.get("schedule_editor", {})
973
+ is_edit = editor_state.get("is_edit", False)
974
+
975
+ # Schedule name and description
976
+ name = st.text_input(
977
+ "Schedule Name",
978
+ value=editor_state.get("name", ""),
979
+ help="Enter a unique name for this schedule."
980
+ )
981
+
982
+ description = st.text_area(
983
+ "Description",
984
+ value=editor_state.get("description", ""),
985
+ help="Brief description of this schedule."
986
+ )
987
+
988
+ # Template selection for new schedules
989
+ if not is_edit:
990
+ template = st.selectbox(
991
+ "Start from Template",
992
+ ["Custom"] + list(DEFAULT_SCHEDULE_TEMPLATES.keys()),
993
+ help="Select a template to start with, or choose Custom for blank schedule."
994
  )
995
+ else:
996
+ template = "Custom"
997
+
998
+ # Initialize schedule values
999
+ if template != "Custom" and not is_edit:
1000
+ weekday_values = DEFAULT_SCHEDULE_TEMPLATES[template]["weekday"]
1001
+ weekend_values = DEFAULT_SCHEDULE_TEMPLATES[template]["weekend"]
1002
+ else:
1003
+ weekday_values = editor_state.get("weekday", [0.0] * 24)
1004
+ weekend_values = editor_state.get("weekend", [0.0] * 24)
1005
+
1006
+ # Weekday schedule
1007
+ st.write("**Weekday Schedule**")
1008
+ st.markdown('<div class="slider-container">', unsafe_allow_html=True)
1009
+ weekday_schedule = []
1010
+ for hour in range(24):
1011
+ with st.container():
1012
+ val = st.slider(
1013
+ label=f"{hour:02d}:00",
1014
+ min_value=0.0,
1015
+ max_value=1.0,
1016
+ step=0.01,
1017
+ value=float(weekday_values[hour]),
1018
+ key=f"weekday_{hour}",
1019
+ help=f"Hour {hour}:00 weekday value",
1020
+ format="%.2f"
1021
  )
1022
+ st.markdown(f'<div class="hour-label">{hour:02d}:00</div>', unsafe_allow_html=True)
1023
+ weekday_schedule.append(val)
1024
+ st.markdown('</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1025
 
1026
+ # Weekend schedule
1027
+ st.write("**Weekend Schedule**")
1028
+ st.markdown('<div class="slider-container">', unsafe_allow_html=True)
1029
+ weekend_schedule = []
1030
+ for hour in range(24):
1031
+ with st.container():
1032
+ val = st.slider(
1033
+ label=f"{hour:02d}:00",
1034
+ min_value=0.0,
1035
+ max_value=1.0,
1036
+ step=0.01,
1037
+ value=float(weekend_values[hour]),
1038
+ key=f"weekend_{hour}",
1039
+ help=f"Hour {hour}:00 weekend value",
1040
+ format="%.2f"
1041
+ )
1042
+ st.markdown(f'<div class="hour-label">{hour:02d}:00</div>', unsafe_allow_html=True)
1043
+ weekend_schedule.append(val)
1044
+ st.markdown('</div>', unsafe_allow_html=True)
1045
+
1046
+ # Preview chart
1047
+ st.write("**Schedule Preview**")
1048
+ display_schedule_chart(f"Preview: {name or 'New Schedule'}", {
1049
+ "weekday": weekday_schedule,
1050
+ "weekend": weekend_schedule
1051
+ })
1052
+
1053
+ # Action buttons
1054
+ col1, col2 = st.columns(2)
1055
+ with col1:
1056
+ submit_label = "Update Schedule" if is_edit else "Add Schedule"
1057
+ if st.button(submit_label):
1058
+ # Validate inputs
1059
+ if not name.strip():
1060
+ st.error("Schedule name is required.")
1061
+ elif name in schedules and not is_edit:
1062
+ st.error("A schedule with this name already exists.")
1063
+ else:
1064
+ # Create schedule data
1065
+ schedule_data = {
1066
+ "description": description,
1067
+ "weekday": weekday_schedule,
1068
+ "weekend": weekend_schedule
1069
+ }
1070
 
1071
+ # Update or add schedule
1072
+ if is_edit and st.session_state.schedule_editor.get("original_name"):
1073
+ original_name = st.session_state.schedule_editor["original_name"]
1074
+ if original_name != name and original_name in schedules:
1075
+ del schedules[original_name]
1076
+ schedules[name] = schedule_data
1077
+ st.success(f"Schedule '{name}' updated successfully!")
1078
+ else:
1079
+ schedules[name] = schedule_data
1080
+ st.success(f"Schedule '{name}' added successfully!")
1081
 
1082
+ # Clear editor state
1083
+ st.session_state.schedule_editor = {}
1084
+ st.session_state.module_rerun_flags["internal_loads"] = True
1085
+ st.rerun()
1086
+
1087
+ with col2:
1088
+ if st.button("Cancel"):
 
1089
  st.session_state.schedule_editor = {}
 
1090
  st.session_state.module_rerun_flags["internal_loads"] = True
1091
  st.rerun()
 
 
 
 
 
 
 
1092
 
1093
  def is_schedule_in_use(schedule_name: str) -> bool:
1094
  """