|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import plotly.graph_objects as go |
|
|
import datetime |
|
|
|
|
|
|
|
|
def load_data(): |
|
|
|
|
|
df = pd.read_excel("grid_load_data.xlsx") |
|
|
return df |
|
|
|
|
|
|
|
|
def calculate_grid_load(df, current_time): |
|
|
current_hour = current_time.hour |
|
|
hourly_load = df[df["Time"].dt.hour == current_hour]["Grid Load (kW)"].mean() |
|
|
return hourly_load |
|
|
|
|
|
|
|
|
def create_gauge(load_value): |
|
|
|
|
|
ranges = [0, 2000, 3000, 4000] |
|
|
colors = ['lightgreen', 'green', 'red'] |
|
|
labels = ['Low', 'Normal', 'High'] |
|
|
|
|
|
|
|
|
if load_value < 2000: |
|
|
color = colors[0] |
|
|
range_label = labels[0] |
|
|
elif load_value < 3000: |
|
|
color = colors[1] |
|
|
range_label = labels[1] |
|
|
else: |
|
|
color = colors[2] |
|
|
range_label = labels[2] |
|
|
|
|
|
|
|
|
fig = go.Figure(go.Indicator( |
|
|
mode="gauge+number+delta", |
|
|
value=load_value, |
|
|
domain={'x': [0, 1], 'y': [0, 1]}, |
|
|
gauge={ |
|
|
'axis': {'range': [0, 5000]}, |
|
|
'bar': {'color': color}, |
|
|
'steps': [ |
|
|
{'range': [0, 2000], 'color': 'lightgreen'}, |
|
|
{'range': [2000, 3000], 'color': 'green'}, |
|
|
{'range': [3000, 5000], 'color': 'red'} |
|
|
], |
|
|
}, |
|
|
title={'text': f"Grid Load Status: {range_label}"}, |
|
|
delta={'reference': 2000} |
|
|
)) |
|
|
return fig |
|
|
|
|
|
|
|
|
def calculate_ev_requirements(grid_load, ev_capacity=80, ev_efficiency=0.85): |
|
|
|
|
|
|
|
|
evs_needed = grid_load / (ev_capacity * ev_efficiency) |
|
|
return np.ceil(evs_needed) |
|
|
|
|
|
|
|
|
def calculate_ev_power_consumption(ev_capacity=80, charge_rate=0.85): |
|
|
|
|
|
power_consumed = ev_capacity * charge_rate |
|
|
return power_consumed |
|
|
|
|
|
|
|
|
def display_grid_load_prediction_and_ev_info(): |
|
|
st.header("Grid Load Prediction and EV Charging Info") |
|
|
|
|
|
|
|
|
grid_load = st.slider( |
|
|
"Select Grid Load (kW):", |
|
|
min_value=0, |
|
|
max_value=5000, |
|
|
value=2000, |
|
|
step=100, |
|
|
help="Drag the slider to set the desired grid load." |
|
|
) |
|
|
|
|
|
|
|
|
st.plotly_chart(create_gauge(grid_load), use_container_width=True) |
|
|
|
|
|
|
|
|
if grid_load > 3500: |
|
|
st.markdown('<p style="color: red; font-size: 24px;">🔹 Left LED: Overload! Grid is in danger.</p>', unsafe_allow_html=True) |
|
|
else: |
|
|
st.markdown('<p style="color: green; font-size: 24px;">🔹 Right LED: Normal. Grid is stable.</p>', unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
if grid_load < 3000: |
|
|
st.markdown('<p style="color: green;">Green: Charging allowed. EVs can charge.</p>', unsafe_allow_html=True) |
|
|
|
|
|
evs_connected = calculate_ev_requirements(grid_load) |
|
|
st.write(f"Approximately {evs_connected} EVs can be connected to the grid for charging.") |
|
|
|
|
|
else: |
|
|
st.markdown('<p style="color: red;">Red: Grid overload! Disconnecting EV from grid.</p>', unsafe_allow_html=True) |
|
|
|
|
|
if grid_load > 3500: |
|
|
energy_required = grid_load - 3500 |
|
|
evs_needed = calculate_ev_requirements(energy_required) |
|
|
st.write(f"To stabilize the grid, {energy_required} kWh of energy is required.") |
|
|
st.write(f"Approximately {evs_needed} EVs are needed to supply this energy to the grid.") |
|
|
|
|
|
|
|
|
if st.button("Connect EVs to Stabilize Grid"): |
|
|
grid_load -= energy_required |
|
|
st.write(f"Grid load reduced to {grid_load} kW. EVs are stabilizing the grid.") |
|
|
|
|
|
|
|
|
if grid_load > 3000: |
|
|
st.button("Disconnect EV from Grid", key="disconnect_charge", help="Grid load is too high. Disconnect EV.") |
|
|
else: |
|
|
st.button("Allow EV to Charge", key="allow_charge", help="Grid load is normal. EVs can charge.") |
|
|
|
|
|
|
|
|
def main(): |
|
|
st.sidebar.title("EV Charging Optimization") |
|
|
|
|
|
|
|
|
display_grid_load_prediction_and_ev_info() |
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|