atodorov284 commited on
Commit
b2381d4
·
1 Parent(s): 6eaab06

Setup MVC and basic userdashboard with dummy data.

Browse files
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
 
streamlit_src/admin_dashboard.py DELETED
@@ -1,14 +0,0 @@
1
- import streamlit as st
2
-
3
- def ask_for_admin_password():
4
- password = st.text_input("Enter admin password", type="password")
5
- if password == "admin":
6
- return True
7
- else:
8
- return False
9
-
10
- def start_admin_dashboard():
11
- if ask_for_admin_password():
12
- st.title("Admin Dashboard")
13
- else:
14
- st.error("Invalid password. Please try again.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
streamlit_src/app.py CHANGED
@@ -1,4 +1,4 @@
1
- import streamlit as st
2
- from user_dashboard import *
3
-
4
- show_user_dashboard()
 
1
+ from controllers.home_controller import HomeController
2
+
3
+ if __name__ == "__main__":
4
+ HomeController()
streamlit_src/controllers/admin_controller.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from models.air_quality_model import AirQualityModel
2
+ from views.admin_view import AdminView
3
+
4
+ class AdminController:
5
+ def __init__(self):
6
+ self.model = AirQualityModel()
7
+ self.view = AdminView()
8
+
9
+ def show_dashboard(self):
10
+ return
11
+ # Get today's data and predictions
12
+ today_data = self.model.get_today_data()
13
+ next_three_days = self.model.next_three_day_predictions()
14
+
15
+ # WHO Guidelines
16
+ who_guidelines = {
17
+ "Pollutant": ["NO2 (µg/m³)", "O3 (µg/m³)"],
18
+ "WHO Guideline": [self.model.WHO_NO2_LEVEL, self.model.WHO_O3_LEVEL]
19
+ }
20
+
21
+ # Display current data and predictions
22
+ self.view.show_current_data(today_data, who_guidelines)
23
+ self.view.display_predictions(next_three_days)
24
+
25
+ # Compare to WHO guidelines
26
+ self.view.compare_to_who(today_data, self.model.WHO_NO2_LEVEL, self.model.WHO_O3_LEVEL)
27
+
28
+ def welcome_back(self):
29
+ self.view.welcome_back()
streamlit_src/controllers/home_controller.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import time
3
+ from controllers.user_controller import UserController
4
+ from controllers.admin_controller import AdminController
5
+ from views.home_view import HomeView
6
+ import hashlib
7
+
8
+ class HomeController:
9
+ __ADMIN_PASSWORD_HASH = '240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9'
10
+
11
+ def __init__(self):
12
+ self.home_view = HomeView()
13
+ self.user_controller = UserController()
14
+ self.admin_controller = AdminController()
15
+ self._run()
16
+
17
+ def _hash_password(self, password):
18
+ """Hash the input password using SHA-256."""
19
+ return hashlib.sha256(password.encode()).hexdigest()
20
+
21
+ def _run(self):
22
+ if "is_admin_logged_in" not in st.session_state:
23
+ st.session_state.is_admin_logged_in = False
24
+
25
+ # Show the sidebar switch
26
+ switch = self.home_view.show_dashboard_switch()
27
+
28
+ if switch == "User Dashboard":
29
+ self.user_controller.show_dashboard()
30
+
31
+ elif switch == "Admin Dashboard":
32
+ # Check if the admin is already logged in
33
+ if st.session_state.is_admin_logged_in:
34
+ self.admin_controller.welcome_back()
35
+ self.admin_controller.show_dashboard()
36
+ else:
37
+ password = self.home_view.prompt_admin_password()
38
+
39
+ if self._hash_password(password) == self.__ADMIN_PASSWORD_HASH:
40
+ st.session_state.is_admin_logged_in = True
41
+ self.admin_controller.show_dashboard()
42
+ else:
43
+ time.sleep(5)
44
+ self.user_controller.show_dashboard()
streamlit_src/controllers/user_controller.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from models.air_quality_model import AirQualityModel
2
+ from views.user_view import UserView
3
+
4
+ class UserController:
5
+ def __init__(self):
6
+ self.model = AirQualityModel()
7
+ self.view = UserView()
8
+
9
+ def show_dashboard(self):
10
+
11
+ # Get today's data and predictions
12
+ today_data = self.model.get_today_data()
13
+ next_three_days = self.model.next_three_day_predictions()
14
+
15
+ # WHO Guidelines
16
+ who_guidelines = {
17
+ "Pollutant": ["NO2 (µg/m³)", "O3 (µg/m³)"],
18
+ "WHO Guideline": [self.model.WHO_NO2_LEVEL, self.model.WHO_O3_LEVEL]
19
+ }
20
+
21
+ # Display current data and predictions
22
+ self.view.show_current_data(today_data, who_guidelines)
23
+ self.view.display_predictions(next_three_days)
24
+
25
+ # Compare to WHO guidelines
26
+ self.view.compare_to_who(today_data, self.model.WHO_NO2_LEVEL, self.model.WHO_O3_LEVEL)
streamlit_src/model_utils.py DELETED
@@ -1,36 +0,0 @@
1
- import os
2
- import sys
3
- import pandas as pd
4
- import joblib
5
-
6
- project_root = os.path.dirname(__file__)
7
- parent_dir = os.path.dirname(project_root)
8
- sys.path.append(parent_dir)
9
- from air_quality_forecast.prediction import PredictorModels
10
-
11
- def predictions_xgb_from_datapath(data_path):
12
- updated_data_path = os.path.join(parent_dir, data_path) #"data", "inference", "x_test.csv"
13
- data = pd.read_csv(updated_data_path)
14
- return predictions_xgb_from_data(data)
15
-
16
- def load_normalizer():
17
- saved_models_path = os.path.join(parent_dir, "saved_models")
18
- normalizer = joblib.load(os.path.join(saved_models_path, "normalizer.joblib"))
19
- return normalizer
20
-
21
- def predictions_xgb_from_data(data, normalized=False):
22
-
23
- if data.columns[0] == "date":
24
- data.set_index("date", inplace=True)
25
-
26
-
27
- if not normalized: normalizer = load_normalizer()
28
- data = normalizer.transform(data)
29
-
30
- predictor = Predic
31
- els()
32
- return predictor.xgb_predictions(data)
33
-
34
-
35
- if __name__ == "__main__":
36
- print(predictions_xgb_from_datapath("data/inference/x_test.csv"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
streamlit_src/models/air_quality_model.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+
4
+ class AirQualityModel():
5
+ def __init__(self) -> None:
6
+
7
+ self.WHO_NO2_LEVEL = 25
8
+ self.WHO_O3_LEVEL = 100
9
+ pass
10
+
11
+ def get_today_data(self):
12
+ today_data = {
13
+ "NO2 (µg/m³)": np.random.uniform(20, 60), # Simulated data
14
+ "O3 (µg/m³)": np.random.uniform(50, 120) # Simulated data
15
+ }
16
+ return today_data
17
+
18
+ # Function to retrieve predictions for the next three days (replace with actual model predictions)
19
+ def next_three_day_predictions(self):
20
+ next_three_days = pd.DataFrame({
21
+ "Day": ["Day 1", "Day 2", "Day 3"],
22
+ "NO2 (µg/m³)": np.random.uniform(20, 60, 3),
23
+ "O3 (µg/m³)": np.random.uniform(50, 120, 3)
24
+ })
25
+ return next_three_days
streamlit_src/user_dashboard.py DELETED
@@ -1,110 +0,0 @@
1
- import streamlit as st
2
- import pandas as pd
3
- from datetime import date
4
- import numpy as np
5
-
6
- # Constants for WHO guideline levels
7
- WHO_NO2_LEVEL = 25
8
- WHO_O3_LEVEL = 100
9
-
10
- # Main function to display user dashboard
11
- def show_user_dashboard():
12
- # Set layout and sidebar
13
- set_layout()
14
- set_sidebar()
15
-
16
- # Main content layout
17
- set_columns()
18
-
19
- # Function to set the layout of the app
20
- def set_layout():
21
- st.set_page_config(page_title="Air Quality Monitoring Dashboard", layout="wide")
22
- st.sidebar.title("Air Quality Monitoring")
23
-
24
- # Function to retrieve current air quality data (replace with actual predictions)
25
- def get_today_data():
26
- today_data = {
27
- "NO2 (µg/m³)": np.random.uniform(20, 60), # Simulated data
28
- "O3 (µg/m³)": np.random.uniform(50, 120) # Simulated data
29
- }
30
- return today_data
31
-
32
- # Function to retrieve predictions for the next three days (replace with actual model predictions)
33
- def next_three_day_predictions():
34
- next_three_days = pd.DataFrame({
35
- "Day": ["Day 1", "Day 2", "Day 3"],
36
- "NO2 (µg/m³)": np.random.uniform(20, 60, 3),
37
- "O3 (µg/m³)": np.random.uniform(50, 120, 3)
38
- })
39
- return next_three_days
40
-
41
- # Function to compare current data to WHO guidelines
42
- def compare_to_who(today_data):
43
- if today_data["NO2 (µg/m³)"] > WHO_NO2_LEVEL:
44
- st.sidebar.error("⚠️ NO2 levels are above WHO guidelines!")
45
- else:
46
- st.sidebar.success("✅ NO2 levels are within safe limits.")
47
-
48
- if today_data["O3 (µg/m³)"] > WHO_O3_LEVEL:
49
- st.sidebar.error("⚠️ O3 levels are above WHO guidelines!")
50
- else:
51
- st.sidebar.success("✅ O3 levels are within safe limits.")
52
-
53
- # Sidebar setup to display today's data and WHO guidelines
54
- def set_sidebar():
55
- today_data = get_today_data()
56
- st.sidebar.markdown(f"Today's Date: **{date.today().strftime('%B %d, %Y')}**")
57
-
58
- # Current Pollutant Concentrations
59
- st.sidebar.markdown("### Current Pollutant Concentrations")
60
- today_data_df = pd.DataFrame([today_data]) # Create a DataFrame without index
61
- st.sidebar.dataframe(today_data_df.style.hide(axis="index")) # Hide the index
62
-
63
- # WHO guideline values
64
- who_guidelines = {
65
- "Pollutant": ["NO2 (µg/m³)", "O3 (µg/m³)"],
66
- "WHO Guideline": [WHO_NO2_LEVEL, WHO_O3_LEVEL]
67
- }
68
- st.sidebar.markdown("### WHO Guidelines")
69
- who_guidelines_df = pd.DataFrame(who_guidelines)
70
- st.sidebar.dataframe(who_guidelines_df.style.hide(axis="index")) # Hide the index
71
-
72
- # WHO guideline alerts
73
- compare_to_who(today_data)
74
-
75
- # Function to handle the admin dashboard button (placeholder for now)
76
- def start_admin_dashboard():
77
- st.info("Navigating to admin dashboard...")
78
-
79
- # Set right column to include navigation to admin dashboard
80
- def set_right_column(column):
81
- with column:
82
- st.button(label="Admin Dashboard",
83
- help="Navigate to the admin dashboard.",
84
- on_click=start_admin_dashboard,
85
- icon="🔧")
86
-
87
- # Middle column for future use (e.g., prediction graphs)
88
- def set_middle_column(column):
89
- with column:
90
- next_three_days = next_three_day_predictions()
91
- st.markdown("### Predictions for the Next 3 Days")
92
- st.line_chart(next_three_days.set_index("Day"))
93
-
94
- st.markdown("### About Air Pollution")
95
- st.write("""
96
- **Air pollution** is harmful to human health and the environment. NO2 and O3 are key pollutants monitored
97
- to assess air quality. The World Health Organization (WHO) provides guidelines on safe levels of these
98
- pollutants to minimize health risks.
99
- """)
100
-
101
- # Left column for any additional content (e.g., awareness information)
102
- def set_left_column(column):
103
- pass
104
-
105
- # Function to set the column layout for the main dashboard
106
- def set_columns():
107
- col = st.columns((1, 3, 1), gap="medium")
108
- set_right_column(col[2])
109
- set_middle_column(col[1])
110
- set_left_column(col[0])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
streamlit_src/views/admin_view.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # views/user_view.py
2
+ import streamlit as st
3
+ import pandas as pd
4
+ from datetime import date
5
+ import time
6
+
7
+ class AdminView:
8
+ def show_current_data(self, today_data, who_guidelines):
9
+ return
10
+ st.sidebar.markdown(f"ADMIN Today's Date: **{date.today().strftime('%B %d, %Y')}**")
11
+ st.sidebar.markdown("### Current Pollutant Concentrations")
12
+ today_data_df = pd.DataFrame([today_data])
13
+ st.sidebar.dataframe(today_data_df.style.hide(axis="index"))
14
+
15
+ st.sidebar.markdown("### WHO Guidelines")
16
+ who_guidelines_df = pd.DataFrame(who_guidelines)
17
+ st.sidebar.dataframe(who_guidelines_df.style.hide(axis="index"))
18
+
19
+ def display_predictions(self, next_three_days):
20
+ return
21
+ st.markdown("### Predictions for the Next 3 Days")
22
+ st.line_chart(next_three_days.set_index("Day"))
23
+
24
+ def compare_to_who(self, today_data, no2_level, o3_level):
25
+ return
26
+ if today_data["NO2 (µg/m³)"] > no2_level:
27
+ st.sidebar.error("⚠️ NO2 levels are above WHO guidelines!")
28
+ else:
29
+ st.sidebar.success("✅ NO2 levels are within safe limits.")
30
+
31
+ if today_data["O3 (µg/m³)"] > o3_level:
32
+ st.sidebar.error("⚠️ O3 levels are above WHO guidelines!")
33
+ else:
34
+ st.sidebar.success("✅ O3 levels are within safe limits.")
35
+
36
+ def welcome_back(self):
37
+ st.empty()
38
+ placeholder = st.empty()
39
+ placeholder.success("Welcome back!")
40
+ time.sleep(2)
41
+ placeholder.empty()
streamlit_src/views/home_view.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ class HomeView:
4
+
5
+ def __init__(self):
6
+ self.set_layout()
7
+
8
+ def set_layout(self):
9
+ st.set_page_config(page_title="Air Quality Monitoring Dashboard", layout="wide")
10
+ st.sidebar.title("Air Quality Monitoring")
11
+
12
+ def show_dashboard_switch(self):
13
+ page = st.sidebar.radio("Go to", ["User Dashboard", "Admin Dashboard"])
14
+ return page
15
+
16
+ def prompt_admin_password(self):
17
+ st.sidebar.markdown("### Admin Access Required")
18
+ return st.sidebar.text_input("Enter Admin Password:", type="password")
streamlit_src/views/user_view.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # views/user_view.py
2
+ import streamlit as st
3
+ import pandas as pd
4
+ from datetime import date
5
+
6
+ class UserView:
7
+ def show_current_data(self, today_data, who_guidelines):
8
+ st.sidebar.markdown(f"Today's Date: **{date.today().strftime('%B %d, %Y')}**")
9
+ st.sidebar.markdown("### Current Pollutant Concentrations")
10
+ today_data_df = pd.DataFrame([today_data])
11
+ st.sidebar.dataframe(today_data_df.style.hide(axis="index"))
12
+
13
+ st.sidebar.markdown("### WHO Guidelines")
14
+ who_guidelines_df = pd.DataFrame(who_guidelines)
15
+ st.sidebar.dataframe(who_guidelines_df.style.hide(axis="index"))
16
+
17
+ def display_predictions(self, next_three_days):
18
+ st.markdown("### Predictions for the Next 3 Days")
19
+ st.line_chart(next_three_days.set_index("Day"))
20
+
21
+ def compare_to_who(self, today_data, no2_level, o3_level):
22
+ if today_data["NO2 (µg/m³)"] > no2_level:
23
+ st.sidebar.error("⚠️ NO2 levels are above WHO guidelines!")
24
+ else:
25
+ st.sidebar.success("✅ NO2 levels are within safe limits.")
26
+
27
+ if today_data["O3 (µg/m³)"] > o3_level:
28
+ st.sidebar.error("⚠️ O3 levels are above WHO guidelines!")
29
+ else:
30
+ st.sidebar.success("✅ O3 levels are within safe limits.")