import streamlit as st import pandas as pd import random from datetime import datetime, timedelta import folium from streamlit_folium import folium_static import groq import time # --- 📂 Load Bus Data --- data_path = "pdp.csv" df = pd.read_csv(data_path) # --- 🔐 Dummy User Credentials --- USER_CREDENTIALS = { "Muthuraja": "virat", "Praveen": "dhoni", "Pandi": "kabadi", "admin": "password123", "user": "buspass2025" } # --- 🔑 Groq API Key --- GROQ_API_KEY = "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" groq.api_key = GROQ_API_KEY # --- 🔓 Authenticate User --- def authenticate(username, password): """Authenticate user.""" return USER_CREDENTIALS.get(username) == password # --- 🔮 Predict Bus Status using Groq API --- def predict_bus_status(bus_number, city, source_area, destination_area): """Predict bus arrival and status with Groq API.""" prompt = f"Predict the status, route, and arrival time for bus {bus_number} from {source_area} to {destination_area} in {city}." try: client = groq.Client(api_key=GROQ_API_KEY) response = client.chat.completions.create( model="llama3-70b-8192", messages=[{"role": "system", "content": prompt}] ) return response.choices[0].message.content.strip() except Exception as e: return f"Error: {e}" # --- 🕰️ Add Random Delay to Predicted Time --- def add_random_delay(arrival_time_str): """Add 1 to 10 minutes delay to arrival time.""" try: arrival_time = datetime.strptime(arrival_time_str, "%d-%m-%Y %H:%M") except ValueError: arrival_time = datetime.strptime(arrival_time_str, "%Y-%m-%d %H:%M:%S") delay_minutes = random.randint(1, 10) new_arrival_time = arrival_time + timedelta(minutes=delay_minutes) return new_arrival_time.strftime("%Y-%m-%d %H:%M:%S") # --- 🚍 Predict Upcoming Buses on Same Route / Nearby Area --- def predict_upcoming_buses(bus_number, city, source_area, destination_area, area_df): """Predict upcoming buses on the same route or nearby areas.""" # Filter buses on the same route same_route_df = area_df[ (area_df["bus_route"] == area_df[area_df["bus_number"] == bus_number]["bus_route"].values[0]) & (area_df["arrival_time"] > datetime.now().strftime("%Y-%m-%d %H:%M:%S")) ] if not same_route_df.empty: upcoming_buses = [] for _, row in same_route_df.iterrows(): delayed_time = add_random_delay(row['arrival_time']) upcoming_buses.append(f"🚌 Bus {row['bus_number']} → {row['bus_route']} arriving at {delayed_time}") return "\n".join(upcoming_buses) # Fallback: Suggest nearby same-area buses nearby_buses_df = area_df[ (area_df["area"] == source_area) | (area_df["area"] == destination_area) ] if not nearby_buses_df.empty: nearby_buses = [] for _, row in nearby_buses_df.iterrows(): delayed_time = add_random_delay(row['arrival_time']) nearby_buses.append(f"🚌 Nearby Bus {row['bus_number']} → {row['bus_route']} arriving at {delayed_time}") return "\n".join(nearby_buses) return "⚠️ No upcoming buses available for the same route or nearby areas." # --- 🗺️ Plot Bus Route Map --- def plot_bus_route(source_area, destination_area, area_df): """Plot bus route between source and destination.""" source_df = area_df[area_df["area"] == source_area] dest_df = area_df[area_df["area"] == destination_area] if source_df.empty or dest_df.empty: st.warning("❌ Invalid source or destination. Please try again.") return source_lat, source_lon = source_df.iloc[0]["latitude"], source_df.iloc[0]["longitude"] dest_lat, dest_lon = dest_df.iloc[0]["latitude"], dest_df.iloc[0]["longitude"] m = folium.Map(location=[(source_lat + dest_lat) / 2, (source_lon + dest_lon) / 2], zoom_start=12) folium.Marker([source_lat, source_lon], popup=f"🚌 Source: {source_area}", icon=folium.Icon(color="green")).add_to(m) folium.Marker([dest_lat, dest_lon], popup=f"🏁 Destination: {destination_area}", icon=folium.Icon(color="red")).add_to(m) folium.PolyLine([(source_lat, source_lon), (dest_lat, dest_lon)], color="blue", weight=5, opacity=0.8).add_to(m) folium_static(m) # --- ⏰ Stable Real-Time Clock on Top --- def update_clock(clock_placeholder): """Continuously update and display a real-time clock after login.""" now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") clock_placeholder.markdown( f"""

⏰ Live Time: {now}

""", unsafe_allow_html=True ) # --- 🚀 Streamlit App Interface --- st.title("🚍 Tamil Nadu Bus Tracking & Prediction System") # --- 🔐 Login System --- if "authenticated" not in st.session_state: st.session_state.authenticated = False if not st.session_state.authenticated: username = st.text_input("Username") password = st.text_input("Password", type="password") if st.button("Login"): if authenticate(username, password): st.session_state.authenticated = True st.success("✅ Login successful!") st.rerun() else: st.error("❌ Invalid username or password") # --- 🗺️ Main Content after Login --- if st.session_state.authenticated: # --- ⏰ Live Clock after Login --- clock_placeholder = st.empty() update_clock(clock_placeholder) st.sidebar.header("🌆 City, Source & Destination Selection") city = st.sidebar.selectbox("Select City", df["city"].unique()) area_df = df[df["city"] == city] # Select Source & Destination Area source_area = st.sidebar.selectbox("Select Source Area", area_df["area"].unique()) destination_area = st.sidebar.selectbox("Select Destination Area", area_df["area"].unique()) # --- 🚌 Show Bus Details --- st.subheader(f"🚌 Bus Details for Route: {source_area} ➡️ {destination_area} in {city}") filtered_df = area_df[(area_df["area"] == source_area) | (area_df["area"] == destination_area)] st.dataframe(filtered_df) # --- 🗺️ Show Live Route Map --- st.subheader("🗺️ Live Bus Route Map") plot_bus_route(source_area, destination_area, area_df) # --- 🔮 Predict Bus and Same Route Buses --- st.subheader("🔮 Bus Prediction & Same Route/Area Upcoming Buses") if not filtered_df.empty: for _, row in filtered_df.iterrows(): bus_number = row['bus_number'] prediction = predict_bus_status(bus_number, city, source_area, destination_area) st.success(f"🔮 Prediction for Bus {bus_number}: {prediction}") upcoming_buses_info = predict_upcoming_buses(bus_number, city, source_area, destination_area, area_df) st.info(upcoming_buses_info) # --- 🔓 Logout Option --- if st.button("Logout"): st.session_state.authenticated = False st.rerun()