Files
auracaster-webui/auracaster-webui.py

262 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()