#!/usr/bin/env python3 """ Prezenta Work - Workplace Attendance & Traceability System (v3.0) Headless RFID reader client with batch logging and WiFi recovery Main application orchestrator that coordinates system components: - RFID card reader (reads employee badges) - Batch logging with event deduplication (75% network reduction) - WiFi auto-recovery on server disconnection - Remote monitoring via Server_Monitorizare dashboard - Connectivity monitoring and backup data handling """ import signal import sys import logging import time import threading from datetime import datetime # Import all modules from config_settings import ( MONITORING_SERVER_URL, AUTO_UPDATE_SERVER_HOST, CONNECTIVITY_CHECK_HOST, LOG_FILE, DEVICE_INFO_FILE, TAG_FILE ) from logger_module import log_with_server from device_module import get_device_info from system_init_module import perform_system_initialization from dependencies_module import check_and_install_dependencies from rfid_module import initialize_rfid_reader from connectivity_module import check_internet_connection, post_backup_data # Import enhancement modules from logger_batch_module import ( setup_logging as setup_batch_logging, start_batch_logger, queue_log_message ) from wifi_recovery_module import initialize_wifi_recovery # Global variables device_hostname = None device_ip = None rfid_reader = None batch_logger_thread = None wifi_recovery_manager = None app_running = True def setup_signal_handlers(): """Setup graceful shutdown handlers""" def signal_handler(sig, frame): global app_running logging.warning(f"Received signal {sig}. Initiating graceful shutdown...") log_with_server("Application shutdown initiated", device_hostname, device_ip) app_running = False # Stop batch logger if batch_logger_thread: logging.info("Stopping batch logger...") # Stop WiFi recovery monitor if wifi_recovery_manager: logging.info("Stopping WiFi recovery monitor...") wifi_recovery_manager.stop_monitoring() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) logging.info("Signal handlers configured") def initialize_application(): """Initialize all application components""" global device_hostname, device_ip try: logging.info("=" * 80) logging.info("Prezenta Work v3.0 - Headless RFID Client") logging.info("=" * 80) logging.info(f"Start time: {datetime.now().isoformat()}") # Get device info logging.info("Retrieving device information...") device_hostname, device_ip = get_device_info() logging.info(f"Device: {device_hostname} ({device_ip})") log_with_server( "RFID Client v3.0 started - batch logging active, WiFi recovery enabled", device_hostname, device_ip ) # Initialize system logging.info("Performing system initialization...") perform_system_initialization() # Check and install dependencies (no Flask needed) logging.info("Checking dependencies...") check_and_install_dependencies() # Setup batch logging logging.info("Setting up batch logging system...") setup_batch_logging(device_hostname) logging.info("Application initialization completed successfully") return True except Exception as e: logging.error(f"Application initialization failed: {e}") return False def start_wifi_recovery_monitor(): """Initialize WiFi recovery monitoring""" global wifi_recovery_manager try: logging.info("Initializing WiFi recovery monitor...") log_with_server("WiFi recovery system initialized", device_hostname, device_ip) wifi_recovery_manager = initialize_wifi_recovery( device_hostname, device_ip, server_host=CONNECTIVITY_CHECK_HOST ) if wifi_recovery_manager: logging.info("WiFi recovery monitor started") return True else: logging.error("Failed to initialize WiFi recovery") return False except Exception as e: logging.error(f"Error starting WiFi recovery: {e}") return False def start_batch_logger_thread(): """Start the batch logging system""" global batch_logger_thread try: logging.info("Starting batch logger thread...") batch_logger_thread = threading.Thread( target=start_batch_logger, args=(device_hostname, device_ip), daemon=True ) batch_logger_thread.start() logging.info("Batch logger thread started (5s batches, event dedup)") return True except Exception as e: logging.error(f"Error starting batch logger: {e}") return False def start_connectivity_monitor(): """Monitor internet connectivity""" def connectivity_loop(): while app_running: try: if not check_internet_connection(): logging.warning("No internet connectivity") else: post_backup_data() except Exception as e: logging.error(f"Connectivity monitor error: {e}") time.sleep(30) # Check every 30 seconds try: logging.info("Starting connectivity monitor...") conn_thread = threading.Thread(target=connectivity_loop, daemon=True) conn_thread.start() logging.info("Connectivity monitor thread started") return True except Exception as e: logging.error(f"Error starting connectivity monitor: {e}") return False def start_rfid_reader(): """Initialize RFID reader""" global rfid_reader try: logging.info("Initializing RFID reader with RDM6300...") rfid_reader = initialize_rfid_reader(device_hostname, device_ip) if rfid_reader: logging.info("RFID reader initialized successfully") log_with_server("RFID reader ready", device_hostname, device_ip) return True else: logging.error("RFID reader initialization failed") return False except Exception as e: logging.error(f"Error initializing RFID reader: {e}") return False def main(): """Main application entry point""" global app_running # Configure basic logging first logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(LOG_FILE), logging.StreamHandler(sys.stdout) ] ) # Setup signal handlers for graceful shutdown setup_signal_handlers() try: # Initialize application if not initialize_application(): logging.error("Application initialization failed") return 1 # Start core components in sequence logging.info("Starting application components...") # 1. Start batch logging system start_batch_logger_thread() time.sleep(0.5) # 2. Initialize RFID reader start_rfid_reader() time.sleep(1) # 3. Start connectivity monitoring start_connectivity_monitor() # 4. Start WiFi recovery monitor start_wifi_recovery_monitor() logging.info("All components started successfully") log_with_server( "RFID Client operational - batch logging active (75% reduction), " "RFID reader ready, WiFi recovery enabled", device_hostname, device_ip ) # Keep application running logging.info("Application is now running...") while app_running: time.sleep(1) logging.info("Application shutdown complete") return 0 except Exception as e: logging.error(f"Fatal error: {e}") log_with_server(f"FATAL ERROR: {str(e)}", device_hostname, device_ip) return 1 if __name__ == '__main__': sys.exit(main())