mudassarrafique commited on
Commit
fc3614e
·
verified ·
1 Parent(s): fcad067

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -118
app.py CHANGED
@@ -1,150 +1,109 @@
1
  import streamlit as st
2
  import pandas as pd
3
  import plotly.graph_objects as go
4
- from PIL import Image, ImageDraw, ImageFilter, ImageColor # Added ImageColor import
5
-
6
- # Function to create a 3D-like glowing circular indicator
7
- def create_glowing_indicator(color):
8
- size = 100 # Size of the indicator
9
- img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
10
- draw = ImageDraw.Draw(img)
11
- glow_color = tuple(map(lambda x: int(x * 0.7), ImageColor.getrgb(color))) + (100,)
12
-
13
- # Outer glow
14
- for i in range(20, 0, -1):
15
- draw.ellipse(
16
- (i, i, size - i, size - i),
17
- fill=glow_color,
18
- outline=None
19
- )
20
- glow_color = tuple(map(lambda x: min(x + 10, 255), glow_color[:3])) + (100,)
21
-
22
- # Main circle
23
- draw.ellipse(
24
- (20, 20, size - 20, size - 20),
25
- fill=color,
26
- outline=None
27
- )
28
- return img
29
-
30
- # Function to load data
31
  @st.cache_data
32
  def load_data():
 
33
  df = pd.read_excel("grid_load_data.xlsx")
34
-
35
- # Identify 'Time' column
36
  time_column = next((col for col in df.columns if "time" in col.lower() or "date" in col.lower()), None)
37
- if time_column:
38
- df["Time"] = pd.to_datetime(df[time_column])
39
- else:
40
- raise KeyError("Time column is missing in the dataset.")
41
-
42
- # Identify 'Grid Load (kW)' column
43
  load_column = next((col for col in df.columns if "grid" in col.lower() and "load" in col.lower()), None)
44
- if load_column:
 
 
45
  df["Grid Load (kW)"] = df[load_column]
46
  else:
47
- raise KeyError("Grid Load (kW) column is missing in the dataset.")
48
-
49
  return df
50
 
51
- # Function to calculate available EV charging slots
52
- def calculate_ev_slots(grid_load, threshold=3000, ev_capacity=50):
53
- if grid_load < threshold:
54
- return (threshold - grid_load) // ev_capacity
55
- return 0
56
-
57
- # Function to calculate EVs needed to stabilize the grid
58
- def calculate_evs_needed(grid_load, threshold=3000, ev_capacity=50):
59
- if grid_load > threshold:
60
- return (grid_load - threshold) // ev_capacity
61
- return 0
62
-
63
- # Main function
64
  def main():
65
- st.set_page_config(layout="wide") # Optimize for a wide screen
66
-
 
67
  # Title
68
- st.title("Grid Load and EV Management Dashboard")
69
-
70
- # Alarm Indicators
71
- st.sidebar.write("**Alarm Indicators**")
72
- st.sidebar.write("Green: Normal Load")
73
- st.sidebar.write("Red: Overload")
74
-
75
  # Load dataset
76
  try:
77
  df = load_data()
78
  except KeyError as e:
79
  st.error(f"Error loading data: {e}")
80
  return
81
-
82
- # Grid Load Slider
83
- grid_load = st.slider("Select Grid Load (kW)", 0, 5000, 2000, step=50)
84
-
85
- # Alarm Status
86
- is_overloaded = grid_load > 3000
87
- alarm_color = "red" if is_overloaded else "green"
88
- left_alarm = create_glowing_indicator(alarm_color)
89
- right_alarm = create_glowing_indicator(alarm_color)
90
-
91
- # Layout with alarms and meter
92
- col1, col2, col3 = st.columns([1, 2, 1])
93
-
94
- with col1:
95
- st.image(left_alarm, caption="Alarm", use_column_width=True)
96
-
97
- with col2:
98
- # Meter Visualization for Grid Load
 
 
 
 
 
 
 
 
99
  fig = go.Figure(go.Indicator(
100
  mode="gauge+number",
101
- value=grid_load,
102
  title={'text': "Grid Load (kW)"},
103
  gauge={
104
  'axis': {'range': [0, 5000]},
105
- 'bar': {'color': "blue"},
106
  'steps': [
107
- {'range': [0, 3000], 'color': "green"},
108
  {'range': [3000, 3200], 'color': "orange"},
109
- {'range': [3200, 5000], 'color': "red"}]
 
110
  }
111
  ))
112
  st.plotly_chart(fig, use_container_width=True)
113
-
114
- with col3:
115
- st.image(right_alarm, caption="Alarm", use_column_width=True)
116
-
117
- # Interactive ON/OFF for V2G Connectivity
118
- v2g_enabled = st.sidebar.checkbox("Enable V2G Connectivity")
119
-
120
- if v2g_enabled:
121
- st.sidebar.write("V2G is enabled.")
122
- else:
123
- st.sidebar.write("V2G is disabled.")
124
-
125
- # Status Messages
126
- if grid_load < 3000:
127
- st.success("Grid is stable. Slots available for EV charging.")
128
- ev_slots = calculate_ev_slots(grid_load)
129
- st.write(f"Available EV charging slots: {ev_slots}")
130
- elif 3000 <= grid_load < 3200:
131
- st.warning("Grid is under load. Monitoring EV connectivity.")
132
- if v2g_enabled:
133
- st.write("EVs can support the grid if needed.")
 
 
 
 
 
 
 
 
 
 
 
134
  else:
135
- st.error("Grid is overloaded. Connect EVs to stabilize.")
136
- evs_needed = calculate_evs_needed(grid_load)
137
- st.write(f"EVs needed to stabilize the grid: {evs_needed}")
138
-
139
- # Connect EVs Bar
140
- num_evs = st.number_input("Number of EVs to connect to grid", min_value=0, max_value=evs_needed, step=1)
141
- if st.button("Connect EVs"):
142
- reduced_load = grid_load - (num_evs * 50)
143
- if reduced_load < 3000:
144
- reduced_load = 3000 # Set to minimum threshold
145
- st.success(f"Grid stabilized. Updated load: {reduced_load} kW")
146
- st.write(f"Number of EVs connected: {num_evs}")
147
-
148
- # Run app
149
  if __name__ == "__main__":
150
- main()
 
1
  import streamlit as st
2
  import pandas as pd
3
  import plotly.graph_objects as go
4
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  @st.cache_data
6
  def load_data():
7
+ """Load grid data from the dataset."""
8
  df = pd.read_excel("grid_load_data.xlsx")
 
 
9
  time_column = next((col for col in df.columns if "time" in col.lower() or "date" in col.lower()), None)
 
 
 
 
 
 
10
  load_column = next((col for col in df.columns if "grid" in col.lower() and "load" in col.lower()), None)
11
+
12
+ if time_column and load_column:
13
+ df["Time"] = pd.to_datetime(df[time_column])
14
  df["Grid Load (kW)"] = df[load_column]
15
  else:
16
+ raise KeyError("Dataset must contain 'Time' and 'Grid Load (kW)' columns.")
 
17
  return df
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def main():
20
+ # Page Layout
21
+ st.set_page_config(layout="wide")
22
+
23
  # Title
24
+ st.title("Interactive Grid and EV Management Dashboard")
25
+
 
 
 
 
 
26
  # Load dataset
27
  try:
28
  df = load_data()
29
  except KeyError as e:
30
  st.error(f"Error loading data: {e}")
31
  return
32
+
33
+ # Sidebar Input Mode
34
+ st.sidebar.header("Input Mode")
35
+ input_mode = st.sidebar.radio("Choose Input Mode", ["Automatic Fetch", "Manual Input"])
36
+ current_grid_load = 0
37
+
38
+ if input_mode == "Automatic Fetch":
39
+ current_time = st.sidebar.selectbox("Select Time", df["Time"].dt.strftime("%Y-%m-%d %H:%M:%S"))
40
+ current_time = pd.to_datetime(current_time)
41
+ current_grid_load = df[df["Time"] == current_time]["Grid Load (kW)"].values[0]
42
+ else:
43
+ current_grid_load = st.sidebar.slider("Select Grid Load (kW)", 0, 5000, 2500, step=50)
44
+
45
+ # Layout: Grid Details (Left) | EV Details (Right)
46
+ col1, col2 = st.columns([1, 1])
47
+
48
+ with col1: # Grid Details
49
+ st.subheader("Grid Details")
50
+
51
+ # Status Indicator
52
+ grid_status = "Normal" if current_grid_load <= 3000 else "Overloaded"
53
+ status_color = "green" if grid_status == "Normal" else "red"
54
+
55
+ st.markdown(f"**Status**: <span style='color:{status_color}; font-size:20px;'>{grid_status}</span>", unsafe_allow_html=True)
56
+
57
+ # Gauge for Grid Load
58
  fig = go.Figure(go.Indicator(
59
  mode="gauge+number",
60
+ value=current_grid_load,
61
  title={'text': "Grid Load (kW)"},
62
  gauge={
63
  'axis': {'range': [0, 5000]},
64
+ 'bar': {'color': status_color},
65
  'steps': [
66
+ {'range': [0, 3000], 'color': "lightgreen"},
67
  {'range': [3000, 3200], 'color': "orange"},
68
+ {'range': [3200, 5000], 'color': "red"}
69
+ ]
70
  }
71
  ))
72
  st.plotly_chart(fig, use_container_width=True)
73
+
74
+ # Suggestions
75
+ if current_grid_load < 3000:
76
+ st.success("Grid is stable. No action needed.")
77
+ elif 3000 <= current_grid_load < 3200:
78
+ st.warning("Grid is under moderate load. Monitor EV connectivity.")
79
+ else:
80
+ st.error("Grid is overloaded. Immediate action required!")
81
+
82
+ with col2: # EV Details
83
+ st.subheader("EV Details")
84
+
85
+ ev_capacity = 50 # Each EV contributes or consumes 50 kW
86
+ if current_grid_load < 3000:
87
+ # Calculate EV charging slots
88
+ ev_slots = (3000 - current_grid_load) // ev_capacity
89
+ st.write(f"Available EV charging slots: **{ev_slots}**")
90
+ elif current_grid_load > 3200:
91
+ # Calculate EVs needed to stabilize grid
92
+ evs_needed = (current_grid_load - 3000) // ev_capacity
93
+ st.write(f"Number of EVs needed to stabilize the grid: **{evs_needed}**")
94
+
95
+ # Button to simulate EV connection
96
+ num_evs = st.slider("Number of EVs to connect", 0, int(evs_needed), step=1)
97
+ if st.button("Connect EVs to Grid"):
98
+ reduced_load = current_grid_load - (num_evs * ev_capacity)
99
+ st.success(f"EVs connected! New Grid Load: {reduced_load} kW")
100
+
101
+ # Alarm Lights
102
+ st.sidebar.header("Alarms")
103
+ if current_grid_load > 3000:
104
+ st.sidebar.markdown("**Alarm Status**: <span style='color:red;'>Overloaded</span>", unsafe_allow_html=True)
105
  else:
106
+ st.sidebar.markdown("**Alarm Status**: <span style='color:green;'>Normal</span>", unsafe_allow_html=True)
107
+
 
 
 
 
 
 
 
 
 
 
 
 
108
  if __name__ == "__main__":
109
+ main()