import streamlit as st import plotly.express as px import pandas as pd import streamlit_authenticator as stauth import yaml from yaml.loader import SafeLoader import datetime # from langchain.chat_models import ChatAnthropic # from langchain.callbacks.base import BaseCallbackHandler # from langchain.prompts import PromptTemplate # from langchain.chains import LLMChain # Function to fetch simulated fly situation data def get_fly_situation(canteen): if canteen == "Deck": # Sample fly situation data fly_situation = { "temperature": 28, "humidity": 60, "fly_count": 9, "last_updated": "2023-11-10 12:00:00" } delta1 = '0.2' delta2 = '2' delta3 = '1' elif canteen == "Frontier": # Sample fly situation data fly_situation = { "temperature": 28.1, "humidity": 62, "fly_count": 21, "last_updated": "2023-11-10 12:00:00" } delta1 = '0.1' delta2 = '1' delta3 = '3' return fly_situation, delta1, delta2, delta3 # Function to generate a sample fly situation dataset with time series def get_fly_situation_history(canteen): if canteen == "Deck": # Sample fly situation time series data fly_situation_history = [ {"timestamp": "2023-11-10 11:00:00", "fly_count": 2, "sensor":1}, {"timestamp": "2023-11-10 11:05:00", "fly_count": 1, "sensor": 1}, {"timestamp": "2023-11-10 11:10:00", "fly_count": 2, "sensor": 1}, {"timestamp": "2023-11-10 11:15:00", "fly_count": 2, "sensor": 1}, {"timestamp": "2023-11-10 11:20:00", "fly_count": 3, "sensor": 1}, {"timestamp": "2023-11-10 11:25:00", "fly_count": 1, "sensor": 1}, {"timestamp": "2023-11-10 11:30:00", "fly_count": 2, "sensor": 1}, {"timestamp": "2023-11-10 11:35:00", "fly_count": 1, "sensor": 1}, {"timestamp": "2023-11-10 11:40:00", "fly_count": 3, "sensor": 1}, {"timestamp": "2023-11-10 11:45:00", "fly_count": 1, "sensor": 1}, {"timestamp": "2023-11-10 11:50:00", "fly_count": 2, "sensor": 1}, {"timestamp": "2023-11-10 11:55:00", "fly_count": 3, "sensor": 1}, {"timestamp": "2023-11-10 12:00:00", "fly_count": 1, "sensor": 1}, {"timestamp": "2023-11-10 11:00:00", "fly_count": 1, "sensor": 2}, {"timestamp": "2023-11-10 11:05:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:10:00", "fly_count": 3, "sensor": 2}, {"timestamp": "2023-11-10 11:15:00", "fly_count": 1, "sensor": 2}, {"timestamp": "2023-11-10 11:20:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:25:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:30:00", "fly_count": 1, "sensor": 2}, {"timestamp": "2023-11-10 11:35:00", "fly_count": 3, "sensor": 2}, {"timestamp": "2023-11-10 11:40:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:45:00", "fly_count": 1, "sensor": 2}, {"timestamp": "2023-11-10 11:50:00", "fly_count": 3, "sensor": 2}, {"timestamp": "2023-11-10 11:55:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 12:00:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:00:00", "fly_count": 3, "sensor": 3}, {"timestamp": "2023-11-10 11:05:00", "fly_count": 1, "sensor": 3}, {"timestamp": "2023-11-10 11:10:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:15:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:20:00", "fly_count": 1, "sensor": 3}, {"timestamp": "2023-11-10 11:25:00", "fly_count": 3, "sensor": 3}, {"timestamp": "2023-11-10 11:30:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:35:00", "fly_count": 1, "sensor": 3}, {"timestamp": "2023-11-10 11:40:00", "fly_count": 1, "sensor": 3}, {"timestamp": "2023-11-10 11:45:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:50:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:55:00", "fly_count": 3, "sensor": 3}, {"timestamp": "2023-11-10 12:00:00", "fly_count": 6, "sensor": 3}, ] elif canteen == "Frontier": # Sample fly situation time series data fly_situation_history = [ {"timestamp": "2023-11-10 11:00:00", "fly_count": 2, "sensor":1}, {"timestamp": "2023-11-10 11:05:00", "fly_count": 5, "sensor": 1}, {"timestamp": "2023-11-10 11:10:00", "fly_count": 6, "sensor": 1}, {"timestamp": "2023-11-10 11:15:00", "fly_count": 4, "sensor": 1}, {"timestamp": "2023-11-10 11:20:00", "fly_count": 5, "sensor": 1}, {"timestamp": "2023-11-10 11:25:00", "fly_count": 2, "sensor": 1}, {"timestamp": "2023-11-10 11:30:00", "fly_count": 5, "sensor": 1}, {"timestamp": "2023-11-10 11:35:00", "fly_count": 6, "sensor": 1}, {"timestamp": "2023-11-10 11:40:00", "fly_count": 7, "sensor": 1}, {"timestamp": "2023-11-10 11:45:00", "fly_count": 8, "sensor": 1}, {"timestamp": "2023-11-10 11:50:00", "fly_count": 10, "sensor": 1}, {"timestamp": "2023-11-10 11:55:00", "fly_count": 9, "sensor": 1}, {"timestamp": "2023-11-10 12:00:00", "fly_count": 8, "sensor": 1}, {"timestamp": "2023-11-10 11:00:00", "fly_count": 1, "sensor": 2}, {"timestamp": "2023-11-10 11:05:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:10:00", "fly_count": 3, "sensor": 2}, {"timestamp": "2023-11-10 11:15:00", "fly_count": 2, "sensor": 2}, {"timestamp": "2023-11-10 11:20:00", "fly_count": 3, "sensor": 2}, {"timestamp": "2023-11-10 11:25:00", "fly_count": 4, "sensor": 2}, {"timestamp": "2023-11-10 11:30:00", "fly_count": 6, "sensor": 2}, {"timestamp": "2023-11-10 11:35:00", "fly_count": 7, "sensor": 2}, {"timestamp": "2023-11-10 11:40:00", "fly_count": 8, "sensor": 2}, {"timestamp": "2023-11-10 11:45:00", "fly_count": 10, "sensor": 2}, {"timestamp": "2023-11-10 11:50:00", "fly_count": 9, "sensor": 2}, {"timestamp": "2023-11-10 11:55:00", "fly_count": 8, "sensor": 2}, {"timestamp": "2023-11-10 12:00:00", "fly_count": 6, "sensor": 2}, {"timestamp": "2023-11-10 11:00:00", "fly_count": 3, "sensor": 3}, {"timestamp": "2023-11-10 11:05:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:10:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:15:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:20:00", "fly_count": 1, "sensor": 3}, {"timestamp": "2023-11-10 11:25:00", "fly_count": 3, "sensor": 3}, {"timestamp": "2023-11-10 11:30:00", "fly_count": 5, "sensor": 3}, {"timestamp": "2023-11-10 11:35:00", "fly_count": 7, "sensor": 3}, {"timestamp": "2023-11-10 11:40:00", "fly_count": 6, "sensor": 3}, {"timestamp": "2023-11-10 11:45:00", "fly_count": 3, "sensor": 3}, {"timestamp": "2023-11-10 11:50:00", "fly_count": 2, "sensor": 3}, {"timestamp": "2023-11-10 11:55:00", "fly_count": 1, "sensor": 3}, {"timestamp": "2023-11-10 12:00:00", "fly_count": 7, "sensor": 3}, ] return fly_situation_history # Function to get dataframe of camera locations def get_camera_locations(canteen): if canteen == 'Frontier': camera_locations = pd.DataFrame({ "latitude": [1.2963134225592299, 1.2965099487866827, 1.296561127489237], "longitude": [103.78033553238319, 103.78067954132742, 103.7807614482189], "size": [1 for i in range(3)] }) elif canteen == 'Deck': camera_locations = pd.DataFrame({ "latitude": [1.2948580016451805, 1.2947091254796532, 1.2944617283028779], "longitude": [103.77238596429575, 103.77266955821814, 103.77246151634456], "size": [1 for i in range(3)] }) return camera_locations def get_pheremone_levels(sensor): pheremone_levels_history = [ {"timestamp": "2023-11-10 11:00:00", "pheremone_level": 75, "sensor":1}, {"timestamp": "2023-11-10 11:05:00", "pheremone_level": 75, "sensor": 1}, {"timestamp": "2023-11-10 11:10:00", "pheremone_level": 74, "sensor": 1}, {"timestamp": "2023-11-10 11:15:00", "pheremone_level": 74, "sensor": 1}, {"timestamp": "2023-11-10 11:20:00", "pheremone_level": 74, "sensor": 1}, {"timestamp": "2023-11-10 11:25:00", "pheremone_level": 74, "sensor": 1}, {"timestamp": "2023-11-10 11:30:00", "pheremone_level": 73, "sensor": 1}, {"timestamp": "2023-11-10 11:35:00", "pheremone_level": 72, "sensor": 1}, {"timestamp": "2023-11-10 11:40:00", "pheremone_level": 71, "sensor": 1}, {"timestamp": "2023-11-10 11:45:00", "pheremone_level": 65, "sensor": 1}, {"timestamp": "2023-11-10 11:50:00", "pheremone_level": 63, "sensor": 1}, {"timestamp": "2023-11-10 11:55:00", "pheremone_level": 62, "sensor": 1}, {"timestamp": "2023-11-10 12:00:00", "pheremone_level": 58, "sensor": 1}, {"timestamp": "2023-11-10 11:00:00", "pheremone_level": 95, "sensor": 2}, {"timestamp": "2023-11-10 11:05:00", "pheremone_level": 91, "sensor": 2}, {"timestamp": "2023-11-10 11:10:00", "pheremone_level": 91, "sensor": 2}, {"timestamp": "2023-11-10 11:15:00", "pheremone_level": 90, "sensor": 2}, {"timestamp": "2023-11-10 11:20:00", "pheremone_level": 90, "sensor": 2}, {"timestamp": "2023-11-10 11:25:00", "pheremone_level": 90, "sensor": 2}, {"timestamp": "2023-11-10 11:30:00", "pheremone_level": 90, "sensor": 2}, {"timestamp": "2023-11-10 11:35:00", "pheremone_level": 90, "sensor": 2}, {"timestamp": "2023-11-10 11:40:00", "pheremone_level": 87, "sensor": 2}, {"timestamp": "2023-11-10 11:45:00", "pheremone_level": 84, "sensor": 2}, {"timestamp": "2023-11-10 11:50:00", "pheremone_level": 80, "sensor": 2}, {"timestamp": "2023-11-10 11:55:00", "pheremone_level": 73, "sensor": 2}, {"timestamp": "2023-11-10 12:00:00", "pheremone_level": 72, "sensor": 2}, {"timestamp": "2023-11-10 11:00:00", "pheremone_level": 41, "sensor": 3}, {"timestamp": "2023-11-10 11:05:00", "pheremone_level": 41, "sensor": 3}, {"timestamp": "2023-11-10 11:10:00", "pheremone_level": 40, "sensor": 3}, {"timestamp": "2023-11-10 11:15:00", "pheremone_level": 40, "sensor": 3}, {"timestamp": "2023-11-10 11:20:00", "pheremone_level": 39, "sensor": 3}, {"timestamp": "2023-11-10 11:25:00", "pheremone_level": 38, "sensor": 3}, {"timestamp": "2023-11-10 11:30:00", "pheremone_level": 38, "sensor": 3}, {"timestamp": "2023-11-10 11:35:00", "pheremone_level": 35, "sensor": 3}, {"timestamp": "2023-11-10 11:40:00", "pheremone_level": 34, "sensor": 3}, {"timestamp": "2023-11-10 11:45:00", "pheremone_level": 33, "sensor": 3}, {"timestamp": "2023-11-10 11:50:00", "pheremone_level": 33, "sensor": 3}, {"timestamp": "2023-11-10 11:55:00", "pheremone_level": 30, "sensor": 3}, {"timestamp": "2023-11-10 12:00:00", "pheremone_level": 26, "sensor": 3}, ] return pheremone_levels_history # # Streaming LLM output class # class StreamHandler(BaseCallbackHandler): # # Referenced from: https://discuss.streamlit.io/t/langchain-stream/43782 # def __init__(self, container, initial_text='', display_method='markdown'): # self.container = container # self.text = initial_text # self.display_method = display_method # def on_llm_new_token(self, token: str, **kwargs) -> None: # self.text += token # display_function = getattr(self.container, self.display_method, None) # if display_function is not None: # display_function(self.text) # else: # raise ValueError(f'Invalid display_method: {self.display_method}') # Start of Streamlit Apps st.set_page_config(layout="centered") hide_streamlit_style = ''' ''' st.markdown(hide_streamlit_style, unsafe_allow_html=True) # Import configuration file for user authentication with open('credentials.yaml') as file: config = yaml.load(file, Loader=SafeLoader) # Create an authentication object. authenticator = stauth.Authenticate( config['credentials'], config['cookie']['name'], config['cookie']['key'], config['cookie']['expiry_days'] ) # List of advanced users advanced_users = ['advanced'] # Landing page if user not logged in if st.session_state['authentication_status'] is None: # Landing page copy and banner st.markdown('

Fly Situation Monitoring App 🪰

', unsafe_allow_html=True) st.markdown('

Keeping You Informed, Keeping Flies at Bay

', unsafe_allow_html=True) st.write('\n') st.write('\n') # Loging log-in details name, authentication_status, username = authenticator.login('', 'main') # If log-in failed if st.session_state['authentication_status'] is False: st.error('Username/password is incorrect.') st.write('\n') st.write('\n') # App if user is logged in and authenticated if st.session_state['authentication_status']: # Streamlit app start st.title("Fly Situation Monitoring App 🪰") st.markdown("Keeping You Informed, Keeping Flies at Bay") st.write('\n') # User selects a canteen canteen = st.selectbox("Select a Canteen:", options=["Deck", "Frontier"]) st.write('\n') # If user is a student, show basic app layout if not st.session_state['username'] in advanced_users: # Tabs tab1, tab2 = st.tabs(["Current", "History"]) # Tab 1: Fly Situation with tab1: st.header("Current Fly Situation") # Get data fly_situation, delta1, delta2, delta3 = get_fly_situation(canteen) # Display key information using cards col1_fly_curr, col2_fly_curr, col3_fly_curr = st.columns(3) col1_fly_curr.metric("Temperature", str(fly_situation["temperature"]) + " °C", delta=delta1) col2_fly_curr.metric("Humidty", str(fly_situation["humidity"]) + " %", delta=delta2) col3_fly_curr.metric("Fly Count", str(fly_situation["fly_count"]), delta=delta3, delta_color="inverse") st.caption("Last updated at " + fly_situation["last_updated"] + " (5 min intervals)") # Alert level if fly_situation["fly_count"] > 20: alert_level = "High 🔴" alert_colour = "red" elif fly_situation["fly_count"] > 10: alert_level = "Moderate 🟠" alert_colour = "orange" else: alert_level = "Low 🟢" alert_colour = "green" st.markdown(f"

Alert Level: {alert_level}

", unsafe_allow_html=True) st.markdown('---') # Camera locations st.header("Smart Sensor Locations") camera_locations = get_camera_locations(canteen) st.map(camera_locations, size='size', zoom=18) st.markdown('---') # Feedback st.header("Feedback") # Gather feedback feedback_col1, feedback_col2 = st.columns(2) with feedback_col1: user_feedback = st.text_area("Provide Feedback on the Fly Situation:") with feedback_col2: uploaded_files = st.file_uploader("Upload a Photo", accept_multiple_files=True, type=['jpg', 'png']) for uploaded_file in uploaded_files: st.image(uploaded_file) if st.button("Submit Feedback"): st.success("Feedback submitted successfully!") st.write('\n') st.write('\n') st.write('\n') # Tab 2: History with tab2: st.subheader("Fly Count Over Time") # Get history data fly_situation_history = get_fly_situation_history(canteen) # Create a DataFrame for the time series data df = pd.DataFrame(fly_situation_history) sum_by_timestamp = df.groupby('timestamp')['fly_count'].sum().reset_index() sum_by_timestamp["timestamp"] = pd.to_datetime(sum_by_timestamp["timestamp"]) # Plot the time series using Plotly Express fig = px.line(sum_by_timestamp, x="timestamp", y="fly_count", labels={"fly_count": "Fly Count", "timestamp": "Timestamp"}) st.plotly_chart(fig) # Question-and-Answer with st.form("form"): prompt = st.text_input("Ask a Question:") submit = st.form_submit_button("Submit") if prompt: with st.spinner("Generating..."): pass # Logout logout_col1, logout_col2 = st.columns([6,1]) with logout_col2: st.write('\n') st.write('\n') st.write('\n') authenticator.logout('Logout', 'main') # Footer Credits st.markdown('##') st.markdown("---") st.markdown("Created with ❤️ by HS2912 W4 Group 2") else: # Tabs tab1, tab2, tab3 = st.tabs(["Current", "History", "Control System"]) # Tab 1: Fly Situation with tab1: st.header("Current Fly Situation") # Get current data fly_situation, delta1, delta2, delta3 = get_fly_situation(canteen) # Display key information using cards col1_fly_curr, col2_fly_curr, col3_fly_curr = st.columns(3) col1_fly_curr.metric("Temperature", str(fly_situation["temperature"]) + " °C", delta=delta1) col2_fly_curr.metric("Humidty", str(fly_situation["humidity"]) + " %", delta=delta2) col3_fly_curr.metric("Fly Count", str(fly_situation["fly_count"]), delta=delta3, delta_color="inverse") st.caption("Last updated at " + fly_situation["last_updated"] + " (5 min intervals)") # Alert if fly_situation["fly_count"] > 20: alert_level = "High 🔴" alert_colour = "red" elif fly_situation["fly_count"] > 10: alert_level = "Moderate 🟠" alert_colour = "orange" else: alert_level = "Low 🟢" alert_colour = "green" st.markdown(f"

Alert Level: {alert_level}

", unsafe_allow_html=True) st.markdown('---') # Camera locations st.header("Smart Sensor Locations") camera_locations = get_camera_locations(canteen) st.map(camera_locations, size='size', zoom=18) st.markdown('---') # Feedback st.header("Feedback") # Gather feedback feedback_col1, feedback_col2 = st.columns(2) with feedback_col1: user_feedback = st.text_area("Provide Feedback on the Fly Situation:") with feedback_col2: uploaded_files = st.file_uploader("Upload a Photo", accept_multiple_files=True, type=['jpg', 'png']) for uploaded_file in uploaded_files: st.image(uploaded_file) if st.button("Submit Feedback"): st.success("Feedback submitted successfully!") st.write('\n') st.write('\n') st.write('\n') # Tab 2: History with tab2: # Fly count over time st.subheader("Fly Count Over Time") # Select sensor selected_sensor = st.selectbox("Select Sensor:", ["All", "Sensor 1", "Sensor 2", "Sensor 3"]) # Get history data fly_situation_history = get_fly_situation_history(canteen) # Create a DataFrame for the time series data df = pd.DataFrame(fly_situation_history) if selected_sensor != "All": df = df[df["sensor"]==int(selected_sensor[-1])] sum_by_timestamp = df.groupby('timestamp')['fly_count'].sum().reset_index() sum_by_timestamp["timestamp"] = pd.to_datetime(sum_by_timestamp["timestamp"]) # Plot the time series using Plotly Express fig = px.line(sum_by_timestamp, x="timestamp", y="fly_count", labels={"fly_count": "Fly Count", "timestamp": "Timestamp"}) st.plotly_chart(fig) # Pheremones level st.subheader("Pheremone Level Over Time") selected_sensor_level = st.selectbox("Select Sensor:", ["Sensor 1", "Sensor 2", "Sensor 3"]) # Get history data sensor_pheremone_history = get_pheremone_levels(selected_sensor_level) pheremone_df = pd.DataFrame(sensor_pheremone_history) pheremone_df = pheremone_df[pheremone_df["sensor"] == int(selected_sensor_level[-1])] pheremone_df['timestamp'] = pd.to_datetime(pheremone_df['timestamp']) # Plot the time series using Plotly Express fig = px.line(pheremone_df, x="timestamp", y="pheremone_level", labels={"pheremone_level": "Pheremone Level", "timestamp": "Timestamp"}) st.plotly_chart(fig) # Question-and-Answer with st.form("form"): prompt = st.text_input("Ask a Question:") submit = st.form_submit_button("Submit") if prompt: with st.spinner("Generating..."): pass # Tab 3: Control System with tab3: # Enable/disable automatic pest control system st.header("System Settings") automatic_control_enabled = st.toggle("Enable Automatic Pest Control", value=True) st.write('\n') st.write('\n') if not automatic_control_enabled: disabled = False else: disabled = True # Camera st.subheader("Smart Camera/Sensors") sensor1 = st.toggle("Enable Sensor 1", value=True, disabled=disabled, key='deck_sensor_1') sensor2 = st.toggle("Enable Sensor 2", value=True, disabled=disabled, key='deck_sensor_2') sensor3 = st.toggle("Enable Sensor 3", value=True, disabled=disabled, key='deck_sensor_3') st.write('\n') # Audio st.subheader("Audio") # Accoustic accoustic = st.selectbox("Accoustic Audio", ["Audio 1", "Audio 2", "Audio 3"], disabled=disabled) st.write('\n') # Pheremones # Time interval for pheremones discharge in minutes) st.subheader("Pheremones") pheremones_interval = st.slider("Pheremones Discharge Interval (minutes)", min_value=5, max_value=60, value=15, step=5, disabled=disabled) st.write('\n') # Alerts st.subheader('Alerts') # Pest activity threshold for alerts pest_activity_threshold = st.slider("Fly Count Threshold to Send Out Alerts", min_value=0, max_value=100, value=30, step=5, disabled=disabled) st.write('\n') # Instant alerts for pest sightings or unusual activity st.markdown('
Instant alert
', unsafe_allow_html=True) if st.button("Send Pest Alert", disabled=disabled): st.success("Pest alert sent!") st.write('\n') # Notifications for upcoming preventive measures or scheduled treatments st.markdown('
Schedule notification for upcoming treatment day
', unsafe_allow_html=True) upcoming_event_date = st.date_input("Schedule Date", disabled=disabled) upcoming_event_time = st.time_input("Set time for alert", disabled=disabled) if st.button("Schedule Notification", disabled=disabled): st.success(f"Notification scheduled for {upcoming_event_date} {upcoming_event_time}") # Logout logout_col1, logout_col2 = st.columns([6,1]) with logout_col2: st.write('\n') st.write('\n') st.write('\n') authenticator.logout('Logout', 'main') # Footer Credits st.markdown('##') st.markdown("---") st.markdown("Created with ❤️ by HS2912 W4 Group 2")