import streamlit as st import plotly.graph_objects as go import plotly.express as px import pandas as pd import numpy as np import requests from datetime import datetime, timedelta import time # API URL API_URL = 'http://localhost:5000/api' # Load dataset @st.cache_data def load_data(): data = pd.read_csv("dataset.csv", parse_dates=["PACKAGEDATE"]) data.set_index("PACKAGEDATE", inplace=True) # Rename columns for clarity column_mapping = { "ODA3 CLIMATE_Co2": "CO2", "ODA3 CLIMATE_Nem": "Humidity", "ODA3 CLIMATE_Temp": "Temperature", "ODA3 DOSE_EC_EC": "EC", "ODA3 DOSE_EC_Wtemp": "Water Temperature", "ODA3 DOSE_PH_PH": "pH" } data = data.rename(columns=column_mapping) return data # Optimal ranges for each metric OPTIMAL_RANGES = { 'temp': {'min': 20, 'max': 25, 'unit': '°C'}, 'humidity': {'min': 60, 'max': 80, 'unit': '%'}, 'co2': {'min': 400, 'max': 1000, 'unit': 'ppm'}, 'ph': {'min': 6.0, 'max': 7.0, 'unit': ''}, 'ec': {'min': 500, 'max': 1500, 'unit': 'μS/cm'}, 'wtemp': {'min': 18, 'max': 23, 'unit': '°C'} } # Page config st.set_page_config( page_title="Climate Metrics Dashboard", page_icon="🌡️", layout="wide" ) # Title and description st.title("AGRIDL AI Analysis/Predicted Metrics Dashboard") st.markdown("Real-time monitoring and prediction system") # Load the dataset data = load_data() # Create columns for metrics def get_status_color(value, metric): range_data = OPTIMAL_RANGES[metric] if range_data['min'] <= value <= range_data['max']: return "green" elif (value < range_data['min'] - (range_data['max'] - range_data['min']) * 0.2 or value > range_data['max'] + (range_data['max'] - range_data['min']) * 0.2): return "red" return "yellow" def format_metric_value(value, metric): unit = OPTIMAL_RANGES[metric]['unit'] return f"{value}{unit}" def display_metric_card(title, value, metric_key): color = get_status_color(value, metric_key) st.metric( label=title, value=format_metric_value(value, metric_key), delta=f"Optimal: {OPTIMAL_RANGES[metric_key]['min']}-{OPTIMAL_RANGES[metric_key]['max']}{OPTIMAL_RANGES[metric_key]['unit']}" ) return st.number_input(f"New {title}", key=f"input_{metric_key}") # Create tabs for different views tab1, tab2, tab3, tab4, tab5 = st.tabs(["Current Metrics", "Historical Data", "Time Analysis", "Data Analysis", "Correlation Matrix"]) with tab1: # Buttons row col1, col2, col3 = st.columns(3) with col1: refresh_metrics = st.button("Refresh Metrics") with col2: update_metrics = st.button("Update Metrics") with col3: update_predictions = st.button("Update Predictions") # Metrics grid try: if refresh_metrics: with st.spinner("Loading current metrics..."): response = requests.get(f"{API_URL}/current-metrics") if response.ok: metrics_data = response.json() st.success("Metrics refreshed successfully!") else: st.error("Failed to load metrics") metrics_data = {} else: # Dummy data for demonstration metrics_data = { 'temp': 22, 'humidity': 70, 'co2': 800, 'ph': 6.5, 'ec': 1000, 'wtemp': 20 } # Display metrics in a grid col1, col2, col3 = st.columns(3) new_metrics = {} with col1: new_metrics['temp'] = display_metric_card("Temperature", metrics_data['temp'], 'temp') new_metrics['ph'] = display_metric_card("pH", metrics_data['ph'], 'ph') with col2: new_metrics['humidity'] = display_metric_card("Humidity", metrics_data['humidity'], 'humidity') new_metrics['ec'] = display_metric_card("EC", metrics_data['ec'], 'ec') with col3: new_metrics['co2'] = display_metric_card("CO2", metrics_data['co2'], 'co2') new_metrics['wtemp'] = display_metric_card("Water Temperature", metrics_data['wtemp'], 'wtemp') if update_metrics: updated_metrics = {k: v for k, v in new_metrics.items() if v is not None} if updated_metrics: with st.spinner("Updating metrics..."): response = requests.post(f"{API_URL}/update-metrics", json=updated_metrics) if response.ok: st.success("Metrics updated successfully!") else: st.error("Failed to update metrics") except Exception as e: st.error(f"An error occurred: {str(e)}") with tab2: st.header("Historical Data Visualization") # Select metric for visualization metric = st.selectbox("Select Metric", data.columns) # Date range selector date_range = st.date_input( "Select Date Range", value=(data.index.min(), data.index.max()), min_value=data.index.min().date(), max_value=data.index.max().date() ) # Create interactive plot fig = px.line(data, y=metric, title=f"{metric} Over Time") fig.update_layout( xaxis_title="Date", yaxis_title=metric, showlegend=True ) st.plotly_chart(fig, use_container_width=True) # Show raw data if st.checkbox("Show Raw Data"): st.dataframe(data[metric].head(100)) with tab3: st.header("Time-based Analysis") # Calculate time-based aggregations data_hourly = data.resample("H").mean() data_daily = data.resample("D").mean() data_monthly = data.resample("M").mean() analysis_type = st.radio("Select Analysis Type", ["Hourly", "Daily", "Monthly"]) metric = st.selectbox("Select Metric for Analysis", data.columns, key="time_analysis") if analysis_type == "Hourly": plot_data = data_hourly title = "Hourly Average" elif analysis_type == "Daily": plot_data = data_daily title = "Daily Average" else: plot_data = data_monthly title = "Monthly Average" fig = px.line(plot_data, y=metric, title=f"{title}: {metric}") st.plotly_chart(fig, use_container_width=True) # Show statistics st.subheader("Statistical Summary") st.write(plot_data[metric].describe()) with tab4: st.header("Data Analysis") # Statistical analysis st.subheader("Statistical Summary") st.write(data.describe()) # Distribution plots st.subheader("Distribution Analysis") metric = st.selectbox("Select Metric for Distribution", data.columns, key="dist_analysis") fig = px.histogram(data, x=metric, title=f"Distribution of {metric}") st.plotly_chart(fig, use_container_width=True) # Box plot fig = px.box(data, y=metric, title=f"Box Plot of {metric}") st.plotly_chart(fig, use_container_width=True) with tab5: st.header("Correlation Analysis") # Calculate correlation matrix correlation_matrix = data.corr() # Create heatmap using plotly fig = go.Figure(data=go.Heatmap( z=correlation_matrix, x=correlation_matrix.columns, y=correlation_matrix.columns, colorscale='RdBu', zmin=-1, zmax=1 )) fig.update_layout( title="Correlation Matrix", xaxis_title="Metrics", yaxis_title="Metrics" ) st.plotly_chart(fig, use_container_width=True) # Show detailed correlation values if st.checkbox("Show Detailed Correlation Values"): st.write(correlation_matrix) # Auto-refresh functionality if st.sidebar.checkbox("Enable Auto-refresh", value=False): refresh_interval = st.sidebar.slider("Refresh interval (seconds)", min_value=30, max_value=300, value=60) st.sidebar.info(f"Dashboard will refresh every {refresh_interval} seconds") time.sleep(refresh_interval) st.experimental_rerun()