Implement: Remove Flask and Chrome, simplify to headless RFID client with RDM6300

- Remove Flask web server from client device
- Remove Chrome fullscreen UI launch
- Simplify app.py to focus on core functionality only:
  * RFID reader with RDM6300 library
  * Batch logging with event deduplication (75% reduction)
  * WiFi recovery monitoring
  * Connectivity tracking
- Update rfid_module.py with custom Reader class:
  * Extends rdm6300.BaseReader for event handling
  * card_inserted and card_removed event handlers
  * Integration with batch logging system
  * Proper error handling and device detection
- Dashboard and UI now served from Server_Monitorizare only
- Device acts as pure data collector, reducing overhead
This commit is contained in:
Developer
2025-12-18 14:23:28 +02:00
parent a50197a9d6
commit 081938afb1
2 changed files with 116 additions and 95 deletions

112
app.py
View File

@@ -1,14 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Prezenta Work - Workplace Attendance & Traceability System (v3.0) Prezenta Work - Workplace Attendance & Traceability System (v3.0)
Enhanced with batch logging, Chrome fullscreen UI, and WiFi recovery Headless RFID reader client with batch logging and WiFi recovery
Main application orchestrator that coordinates all system components: Main application orchestrator that coordinates system components:
- RFID card reader (reads employee badges)
- Batch logging with event deduplication (75% network reduction) - Batch logging with event deduplication (75% network reduction)
- Chrome browser in fullscreen kiosk mode
- WiFi auto-recovery on server disconnection - WiFi auto-recovery on server disconnection
- RFID card reader integration - Remote monitoring via Server_Monitorizare dashboard
- Remote monitoring and logging - Connectivity monitoring and backup data handling
""" """
import signal import signal
@@ -21,33 +21,31 @@ from datetime import datetime
# Import all modules # Import all modules
from config_settings import ( from config_settings import (
MONITORING_SERVER_URL, AUTO_UPDATE_SERVER_HOST, CONNECTIVITY_CHECK_HOST, MONITORING_SERVER_URL, AUTO_UPDATE_SERVER_HOST, CONNECTIVITY_CHECK_HOST,
FLASK_PORT, LOG_FILE, DEVICE_INFO_FILE, TAG_FILE LOG_FILE, DEVICE_INFO_FILE, TAG_FILE
) )
from logger_module import log_with_server from logger_module import log_with_server
from device_module import get_device_info from device_module import get_device_info
from system_init_module import perform_system_initialization from system_init_module import perform_system_initialization
from dependencies_module import check_and_install_dependencies from dependencies_module import check_and_install_dependencies
from api_routes_module import create_api_routes
from rfid_module import initialize_rfid_reader from rfid_module import initialize_rfid_reader
from connectivity_module import check_internet_connection, post_backup_data from connectivity_module import check_internet_connection, post_backup_data
# Import new enhancement modules # Import enhancement modules
from logger_batch_module import ( from logger_batch_module import (
setup_logging as setup_batch_logging, setup_logging as setup_batch_logging,
start_batch_logger, start_batch_logger,
queue_log_message queue_log_message
) )
from chrome_launcher_module import launch_chrome_app, get_chrome_path
from wifi_recovery_module import initialize_wifi_recovery from wifi_recovery_module import initialize_wifi_recovery
# Flask app
from flask import Flask
# Global variables # Global variables
app = None
device_hostname = None device_hostname = None
device_ip = None device_ip = None
rfid_reader = None
batch_logger_thread = None
wifi_recovery_manager = None
app_running = True
def setup_signal_handlers(): def setup_signal_handlers():
@@ -76,23 +74,21 @@ def setup_signal_handlers():
def initialize_application(): def initialize_application():
"""Initialize all application components""" """Initialize all application components"""
global device_hostname, device_ip, app, logger global device_hostname, device_ip
try: try:
logging.info("=" * 80) logging.info("=" * 80)
logging.info("Prezenta Work v3.0 - Workplace Attendance System") logging.info("Prezenta Work v3.0 - Headless RFID Client")
logging.info("=" * 80) logging.info("=" * 80)
logging.info(f"Start time: {datetime.now().isoformat()}") logging.info(f"Start time: {datetime.now().isoformat()}")
# Get device info # Get device info
logging.info("Retrieving device information...") logging.info("Retrieving device information...")
device_info = get_device_info() device_hostname, device_ip = get_device_info()
device_hostname = device_info['hostname']
device_ip = device_info['ip']
logging.info(f"Device: {device_hostname} ({device_ip})") logging.info(f"Device: {device_hostname} ({device_ip})")
log_with_server( log_with_server(
"Application started - v3.0 with batch logging and WiFi recovery", "RFID Client v3.0 started - batch logging active, WiFi recovery enabled",
device_hostname, device_hostname,
device_ip device_ip
) )
@@ -101,7 +97,7 @@ def initialize_application():
logging.info("Performing system initialization...") logging.info("Performing system initialization...")
perform_system_initialization() perform_system_initialization()
# Check and install dependencies # Check and install dependencies (no Flask needed)
logging.info("Checking dependencies...") logging.info("Checking dependencies...")
check_and_install_dependencies() check_and_install_dependencies()
@@ -109,11 +105,6 @@ def initialize_application():
logging.info("Setting up batch logging system...") logging.info("Setting up batch logging system...")
setup_batch_logging(device_hostname) setup_batch_logging(device_hostname)
# Create Flask app
logging.info("Initializing Flask application...")
app = Flask(__name__)
create_api_routes(app)
logging.info("Application initialization completed successfully") logging.info("Application initialization completed successfully")
return True return True
@@ -122,52 +113,6 @@ def initialize_application():
return False return False
def start_flask_server():
"""Start Flask web server"""
try:
logging.info(f"Starting Flask server on port {FLASK_PORT}...")
log_with_server(f"Flask server starting on port {FLASK_PORT}", device_hostname, device_ip)
# Run Flask in a separate thread
flask_thread = threading.Thread(
target=lambda: app.run(host='0.0.0.0', port=FLASK_PORT, debug=False, use_reloader=False),
daemon=True
)
flask_thread.start()
logging.info("Flask server thread started")
return True
except Exception as e:
logging.error(f"Failed to start Flask server: {e}")
log_with_server(f"ERROR: Flask server failed: {str(e)}", device_hostname, device_ip)
return False
def start_chrome_app():
"""Launch Chrome in fullscreen with traceability application"""
try:
if get_chrome_path():
logging.info("Starting Chrome fullscreen application...")
log_with_server("Launching Chrome fullscreen UI", device_hostname, device_ip)
# Launch Chrome with local Flask server
chrome_thread = threading.Thread(
target=lambda: launch_chrome_app(device_hostname, device_ip, f"http://localhost:{FLASK_PORT}"),
daemon=True
)
chrome_thread.start()
logging.info("Chrome launch thread started")
return True
else:
logging.warning("Chrome not found - skipping fullscreen launch")
return False
except Exception as e:
logging.error(f"Failed to start Chrome app: {e}")
log_with_server(f"ERROR: Chrome launch failed: {str(e)}", device_hostname, device_ip)
return False
def start_wifi_recovery_monitor(): def start_wifi_recovery_monitor():
"""Initialize WiFi recovery monitoring""" """Initialize WiFi recovery monitoring"""
global wifi_recovery_manager global wifi_recovery_manager
@@ -245,8 +190,8 @@ def start_rfid_reader():
global rfid_reader global rfid_reader
try: try:
logging.info("Initializing RFID reader...") logging.info("Initializing RFID reader with RDM6300...")
rfid_reader = initialize_rfid_reader() rfid_reader = initialize_rfid_reader(device_hostname, device_ip)
if rfid_reader: if rfid_reader:
logging.info("RFID reader initialized successfully") logging.info("RFID reader initialized successfully")
@@ -287,31 +232,24 @@ def main():
# Start core components in sequence # Start core components in sequence
logging.info("Starting application components...") logging.info("Starting application components...")
# 1. Start Flask web server (provides UI endpoint) # 1. Start batch logging system
start_flask_server()
time.sleep(1)
# 2. Start batch logging system
start_batch_logger_thread() start_batch_logger_thread()
time.sleep(0.5) time.sleep(0.5)
# 3. Launch Chrome fullscreen UI # 2. Initialize RFID reader
start_chrome_app()
time.sleep(2)
# 4. Initialize RFID reader
start_rfid_reader() start_rfid_reader()
time.sleep(1)
# 5. Start connectivity monitoring # 3. Start connectivity monitoring
start_connectivity_monitor() start_connectivity_monitor()
# 6. Start WiFi recovery monitor # 4. Start WiFi recovery monitor
start_wifi_recovery_monitor() start_wifi_recovery_monitor()
logging.info("All components started successfully") logging.info("All components started successfully")
log_with_server( log_with_server(
"System fully operational - batch logging active (75% reduction), " "RFID Client operational - batch logging active (75% reduction), "
"Chrome UI fullscreen, WiFi recovery enabled", "RFID reader ready, WiFi recovery enabled",
device_hostname, device_hostname,
device_ip device_ip
) )

View File

@@ -1,47 +1,129 @@
""" """
RFID reader initialization and handling RFID reader initialization and handling using RDM6300 library
Extends rdm6300.BaseReader to handle card events (insert/remove)
and integrate with batch logging system
""" """
import logging import logging
from config_settings import SERIAL_DEVICES, CONFIG_CARD_ID import time
from config_settings import SERIAL_DEVICES, CONFIG_CARD_ID, DEVICE_INFO_FILE
from logger_module import log_with_server from logger_module import log_with_server
from logger_batch_module import queue_log_message
def initialize_rfid_reader(): class RFIDReaderHandler:
"""Custom RFID Reader extending rdm6300.BaseReader for event handling"""
def __init__(self, device_hostname, device_ip):
"""Initialize the reader handler"""
self.device_hostname = device_hostname
self.device_ip = device_ip
self.reader = None
def card_inserted(self, card):
"""Handle RFID card insertion event"""
try:
# Special handling for config card
if card.value == CONFIG_CARD_ID:
logging.info(f"Config card detected: {card.value}")
queue_log_message("CONFIG_CARD_DETECTED", self.device_hostname)
return
# Log card insertion
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
msg = f"Card inserted - ID: {card.value}"
logging.info(msg)
queue_log_message(msg, self.device_hostname)
except Exception as e:
logging.error(f"Error handling card insertion: {e}")
def card_removed(self, card):
"""Handle RFID card removal event"""
try:
# Special handling for config card
if card.value == CONFIG_CARD_ID:
logging.info(f"Config card removed: {card.value}")
queue_log_message("CONFIG_CARD_REMOVED", self.device_hostname)
return
# Log card removal
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
msg = f"Card removed - ID: {card.value}"
logging.info(msg)
queue_log_message(msg, self.device_hostname)
except Exception as e:
logging.error(f"Error handling card removal: {e}")
def initialize_rfid_reader(device_hostname=None, device_ip=None):
""" """
Initialize RFID reader with multiple device attempts and error handling Initialize RFID reader with RDM6300 library and multiple device attempts
Args:
device_hostname: Device hostname for logging
device_ip: Device IP for logging
Returns: Returns:
Reader object or None if initialization fails Reader object or None if initialization fails
""" """
try: try:
from rdm6300 import Reader from rdm6300 import BaseReader
except ImportError: except ImportError:
logging.error("✗ rdm6300 module not installed")
print("✗ rdm6300 module not installed") print("✗ rdm6300 module not installed")
log_with_server("ERROR: rdm6300 not installed", device_hostname, device_ip)
return None return None
logging.info("Initializing RFID reader with RDM6300...")
print("Initializing RFID reader...") print("Initializing RFID reader...")
# Create handler for card events
handler = RFIDReaderHandler(device_hostname or "unknown", device_ip or "0.0.0.0")
for device in SERIAL_DEVICES: for device in SERIAL_DEVICES:
try: try:
logging.info(f"Attempting to initialize RFID reader on {device}...")
print(f"Attempting to initialize RFID reader on {device}...") print(f"Attempting to initialize RFID reader on {device}...")
r = Reader(device)
r.start() # Create custom reader class that extends BaseReader
class CustomReader(BaseReader):
def card_inserted(self, card):
handler.card_inserted(card)
def card_removed(self, card):
handler.card_removed(card)
# Initialize reader
reader = CustomReader(device)
reader.start()
logging.info(f"✓ RFID reader successfully initialized on {device}")
print(f"✓ RFID reader successfully initialized on {device}") print(f"✓ RFID reader successfully initialized on {device}")
return r log_with_server(f"RFID reader started on {device}", device_hostname, device_ip)
return reader
except FileNotFoundError: except FileNotFoundError:
logging.warning(f"✗ Device {device} not found")
print(f"✗ Device {device} not found") print(f"✗ Device {device} not found")
continue continue
except PermissionError: except PermissionError:
logging.warning(f"✗ Permission denied for {device}")
print(f"✗ Permission denied for {device}") print(f"✗ Permission denied for {device}")
print(f" Hint: Try adding user to dialout group: sudo usermod -a -G dialout $USER") print(f" Hint: Try adding user to dialout group: sudo usermod -a -G dialout $USER")
continue continue
except Exception as e: except Exception as e:
logging.warning(f"✗ Failed to initialize on {device}: {e}")
print(f"✗ Failed to initialize on {device}: {e}") print(f"✗ Failed to initialize on {device}: {e}")
continue continue
# If we get here, all devices failed # If we get here, all devices failed
logging.error("✗ Could not initialize RFID reader on any device")
print("✗ Could not initialize RFID reader on any device") print("✗ Could not initialize RFID reader on any device")
print("Available solutions:") print("Available solutions:")
print(" 1. Check hardware connections") print(" 1. Check hardware connections")
@@ -49,4 +131,5 @@ def initialize_rfid_reader():
print(" 3. Add user to dialout group: sudo usermod -a -G dialout $USER") print(" 3. Add user to dialout group: sudo usermod -a -G dialout $USER")
print(" 4. Reboot the system after making changes") print(" 4. Reboot the system after making changes")
log_with_server("ERROR: RFID reader initialization failed on all devices", device_hostname, device_ip)
return None return None