import streamlit as st import yaml import time import os from opcua_connector import opcua_connector class app: def __init__(self): self.app_cfg = yaml.safe_load(open('./cfg.yaml')) or {} self.OPCon = opcua_connector(self.app_cfg) def initialize_connection(self): """Initialize OPC UA connection""" try: self.OPCon.connect() if self.OPCon.check_connection() == 1: st.session_state.connection_status = "Connected" print("đ Connection initialized successfully") return True st.session_state.connection_status = "Disconnected" return False except Exception as e: print(f"â Failed to initialize connection: {e}") st.session_state.connection_status = "Disconnected" return False def execute_button_action(self, button_name): """Execute button action with proper error handling""" if button_name == 'INIT': self.OPCon.adapt_access_rights() print(f"đ§ INIT button pressed - Access rights adapted") else: self.OPCon.press_btn(button_name) print(f"đ {button_name} button pressed") return True # Load config early for password if present app = app() # Page configuration st.set_page_config( page_title="OPC UA Robot Control Dashboard", page_icon="đ¤", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for better styling (external stylesheet) with open('styles.css') as f: st.markdown(f"", unsafe_allow_html=True) # Initialize session state if 'connection_status' not in st.session_state: st.session_state.connection_status = "Disconnected" if 'authenticated' not in st.session_state: st.session_state.authenticated = False # Re-validate connection status each render (do this before rendering UI) def is_opcua_connected(conn) -> bool: try: return bool(conn and conn.check_connection() == 1) except Exception: return False st.session_state.connection_status = ( "Connected" if is_opcua_connected(app.OPCon) else "Disconnected" ) # Sidebar with st.sidebar: st.write(f"Status: {st.session_state.connection_status}") # Initialize button if st.button("đ Initialize Connection", use_container_width=True): with st.spinner("Initializing connection..."): app.initialize_connection() st.rerun() # Disconnect button if st.button("đ Disconnect", use_container_width=True): try: app.OPCon.disconnect() print("đ Disconnected from OPC UA server") except Exception as e: print(f"â ī¸ Warning during disconnect: {e}") st.session_state.connection_status = "Disconnected" print("đ Connection reset") st.rerun() st.divider() # Password gate # Prefer cfg.yaml cred.dashboard.password, else env DASHBOARD_PASSWORD, else 'admin' expected_password = ( (app.app_cfg.get('cred', {}).get('dashboard', {}) or {}).get('password') or 'admin' ) ui_locked = not st.session_state.authenticated if ui_locked: pwd = st.text_input("Enter Dashboard Password", type="password") if st.button("Login", use_container_width=True): if pwd == expected_password: st.session_state.authenticated = True st.rerun() else: st.error("Wrong password") if not ui_locked: # Button container st.markdown('
', unsafe_allow_html=True) # Footer removed for minimal UI