262 lines
13 KiB
Python
262 lines
13 KiB
Python
import streamlit as st
|
||
|
||
# Page setup must be first
|
||
st.set_page_config(page_title="Airport Announcement System", page_icon="✈️")
|
||
|
||
import time
|
||
import requests
|
||
import api_client
|
||
|
||
# Initialize session state for configuration
|
||
if "endpoint_groups" not in st.session_state:
|
||
try:
|
||
st.session_state.endpoint_groups = api_client.get_groups()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to load endpoint groups: {str(e)}")
|
||
st.session_state.endpoint_groups = []
|
||
|
||
# Initialize session state for available languages
|
||
if "available_languages" not in st.session_state:
|
||
try:
|
||
st.session_state.available_languages = api_client.get_available_languages()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to load available languages: {str(e)}")
|
||
st.session_state.available_languages = ["German", "English"] # Fallback languages
|
||
|
||
# Initialize session state for announcement text and status tracking
|
||
if "announcement_text" not in st.session_state:
|
||
st.session_state.announcement_text = "Hallo Welt."
|
||
if "show_success_message" not in st.session_state:
|
||
st.session_state.show_success_message = False
|
||
if "announcement_id" not in st.session_state:
|
||
st.session_state.announcement_id = 0
|
||
if "status_container_key" not in st.session_state:
|
||
st.session_state.status_container_key = 0
|
||
|
||
|
||
def show_announcement_status():
|
||
try:
|
||
status_data = api_client.get_announcement_status()
|
||
if status_data["state"] != "Ready":
|
||
# Create a container with a unique key for each announcement
|
||
# This ensures we get a fresh container for each new announcement
|
||
with st.container(key=f"status_container_{st.session_state.status_container_key}"):
|
||
# Create the status without a key parameter
|
||
status = st.status("**Airport PA System Status**", expanded=True)
|
||
|
||
with status:
|
||
# Progress elements
|
||
progress_bar = st.progress(status_data["progress"])
|
||
time_col, stage_col = st.columns([1, 3])
|
||
|
||
# Track last displayed state
|
||
last_state = None
|
||
|
||
# Update loop
|
||
while status_data["state"] not in ["Complete", "Error"]:
|
||
# Update time elapsed continuously
|
||
|
||
# Only update stage display if state changed
|
||
if status_data["state"] != last_state:
|
||
stage_col.write(f"**Stage:** {status_data['state']}")
|
||
last_state = status_data["state"]
|
||
time_col.write(f"⏱️ Time elapsed: {time.time() - status_data['details']['start_time']:.1f}s")
|
||
|
||
# Update progress bar
|
||
progress_bar.progress(status_data["progress"])
|
||
time.sleep(0.3)
|
||
|
||
# Refresh status data
|
||
status_data = api_client.get_announcement_status()
|
||
|
||
# Make sure to update the progress bar one final time with the final state's progress value
|
||
progress_bar.progress(status_data["progress"])
|
||
|
||
# Final state
|
||
if status_data["state"] == "Error":
|
||
st.error(f"❌ Error: {status_data['error']}")
|
||
else:
|
||
st.success("✅ Announcement completed successfully")
|
||
st.write(f"📢 Announcement made to group {status_data['details']['group']['name']}:")
|
||
st.write(f"📡 Endpoints: {', '.join(status_data['details']['group']['endpoints'])}")
|
||
st.write(f"🗣️ '{status_data['details']['text']}'")
|
||
st.write(f"🌐 Languages: {', '.join(status_data['details']['languages'])}")
|
||
|
||
# Clear the success message when announcement completes
|
||
st.session_state.show_success_message = False
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to get announcement status: {str(e)}")
|
||
|
||
|
||
# Main interface
|
||
st.title("Airport Announcement System ✈️")
|
||
|
||
# Announcements section
|
||
with st.container():
|
||
st.header("Announcements")
|
||
|
||
# Predefined announcements
|
||
st.write("**Predefined Announcements** (click to autofill)")
|
||
col1, col2, col3 = st.columns(3)
|
||
with col1:
|
||
if st.button("Final Boarding Call"):
|
||
st.session_state.announcement_text = "This is the final boarding call for flight LX-380 to New York"
|
||
with col2:
|
||
if st.button("Security Reminder"):
|
||
st.session_state.announcement_text = "Please keep your luggage with you at all times"
|
||
with col3:
|
||
if st.button("Delay Notice"):
|
||
st.session_state.announcement_text = "We regret to inform you of a 30-minute delay"
|
||
|
||
# Custom announcement
|
||
with st.form("custom_announcement"):
|
||
# Get all groups with their names and IDs
|
||
group_options = [(g["name"], g["id"]) for g in st.session_state.endpoint_groups]
|
||
selected_group_name = st.selectbox(
|
||
"Select announcement area",
|
||
options=[g[0] for g in group_options]
|
||
)
|
||
message = st.text_area("Enter announcement text", st.session_state.announcement_text)
|
||
|
||
if st.form_submit_button("Make Announcement"):
|
||
try:
|
||
selected_group_id = next(g[1] for g in group_options if g[0] == selected_group_name)
|
||
api_client.start_announcement(message, selected_group_id)
|
||
|
||
# Set flag to show success message
|
||
st.session_state.show_success_message = True
|
||
|
||
# Increment announcement ID to ensure a fresh status container
|
||
st.session_state.announcement_id += 1
|
||
st.session_state.status_container_key = st.session_state.announcement_id
|
||
|
||
# Clear the announcement text after successful submission
|
||
st.session_state.announcement_text = ""
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to start announcement: {str(e)}")
|
||
|
||
# Display success message if flag is set
|
||
#if st.session_state.show_success_message:
|
||
# st.success("Announcement started successfully")
|
||
|
||
# Configuration section in sidebar
|
||
with st.sidebar:
|
||
st.header("Configuration")
|
||
|
||
with st.expander("Endpoint Groups"):
|
||
for i, group in enumerate(st.session_state.endpoint_groups):
|
||
cols = st.columns([4, 1])
|
||
with cols[0]:
|
||
# Use a unique key for the text input
|
||
input_key = f"group_name_{i}"
|
||
|
||
# Initialize the previous value in session state if not present
|
||
if f"prev_{input_key}" not in st.session_state:
|
||
st.session_state[f"prev_{input_key}"] = group["name"]
|
||
|
||
new_name = st.text_input(
|
||
f"Group Name",
|
||
value=group["name"],
|
||
key=input_key,
|
||
on_change=lambda: None # Prevent automatic callbacks
|
||
)
|
||
|
||
# Only update if the name has changed and it's different from the previous value
|
||
if new_name != group["name"] and new_name != st.session_state[f"prev_{input_key}"]:
|
||
try:
|
||
updated_group = group.copy()
|
||
updated_group["name"] = new_name
|
||
api_client.update_group(group["id"], updated_group)
|
||
# Update the session state with the latest groups
|
||
st.session_state.endpoint_groups = api_client.get_groups()
|
||
# Update the previous value before rerunning
|
||
st.session_state[f"prev_{input_key}"] = new_name
|
||
st.rerun()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to update group name: {str(e)}")
|
||
|
||
try:
|
||
available_endpoints = api_client.get_available_endpoints()
|
||
# Use a unique key for the endpoints multiselect
|
||
endpoints_key = f"endpoints_select_{i}"
|
||
|
||
# Initialize the previous value in session state if not present
|
||
if f"prev_{endpoints_key}" not in st.session_state:
|
||
st.session_state[f"prev_{endpoints_key}"] = group["endpoints"]
|
||
|
||
selected_endpoints = st.multiselect(
|
||
f"Endpoints",
|
||
options=available_endpoints,
|
||
default=group["endpoints"],
|
||
key=endpoints_key
|
||
)
|
||
|
||
# Only update if endpoints have changed and they're different from previous value
|
||
if selected_endpoints != group["endpoints"] and selected_endpoints != st.session_state[f"prev_{endpoints_key}"]:
|
||
updated_group = group.copy()
|
||
updated_group["endpoints"] = selected_endpoints
|
||
api_client.update_group(group["id"], updated_group)
|
||
# Update the previous value before rerunning
|
||
st.session_state[f"prev_{endpoints_key}"] = selected_endpoints
|
||
st.rerun()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to update endpoints: {str(e)}")
|
||
|
||
with cols[1]:
|
||
if st.button("❌", key=f"remove_{i}"):
|
||
try:
|
||
api_client.delete_group(group["id"])
|
||
del st.session_state.endpoint_groups[i]
|
||
st.rerun()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to delete group: {str(e)}")
|
||
|
||
try:
|
||
# Use a unique key for the languages multiselect
|
||
languages_key = f"languages_select_{i}"
|
||
|
||
# Initialize the previous value in session state if not present
|
||
if f"prev_{languages_key}" not in st.session_state:
|
||
st.session_state[f"prev_{languages_key}"] = group["languages"]
|
||
|
||
selected_languages = st.multiselect(
|
||
f"Languages {i+1}",
|
||
options=st.session_state.available_languages,
|
||
default=group["languages"],
|
||
key=languages_key
|
||
)
|
||
|
||
# Only update if languages have changed and they're different from previous value
|
||
if selected_languages != group["languages"] and selected_languages != st.session_state[f"prev_{languages_key}"]:
|
||
updated_group = group.copy()
|
||
updated_group["languages"] = selected_languages
|
||
api_client.update_group(group["id"], updated_group)
|
||
# Update the previous value before rerunning
|
||
st.session_state[f"prev_{languages_key}"] = selected_languages
|
||
st.rerun()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to update languages: {str(e)}")
|
||
st.markdown("---")
|
||
|
||
if st.button("➕ Add Group"):
|
||
try:
|
||
new_id = max(g["id"] for g in st.session_state.endpoint_groups) + 1 if st.session_state.endpoint_groups else 1
|
||
# Get the default languages from the backend (first two languages)
|
||
default_languages = st.session_state.available_languages[:2] if len(st.session_state.available_languages) >= 2 else st.session_state.available_languages
|
||
new_group = {
|
||
"id": new_id,
|
||
"name": f"Group {len(st.session_state.endpoint_groups)+1}",
|
||
"endpoints": [],
|
||
"languages": default_languages
|
||
}
|
||
created_group = api_client.create_group(new_group)
|
||
st.session_state.endpoint_groups.append(created_group)
|
||
st.rerun()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Failed to create group: {str(e)}")
|
||
|
||
# Display announcement status
|
||
st.write("---")
|
||
show_announcement_status()
|