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
"""
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)
- Chrome browser in fullscreen kiosk mode
- WiFi auto-recovery on server disconnection
- RFID card reader integration
- Remote monitoring and logging
- Remote monitoring via Server_Monitorizare dashboard
- Connectivity monitoring and backup data handling
"""
import signal
@@ -21,33 +21,31 @@ from datetime import datetime
# Import all modules
from config_settings import (
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 device_module import get_device_info
from system_init_module import perform_system_initialization
from dependencies_module import check_and_install_dependencies
from api_routes_module import create_api_routes
from rfid_module import initialize_rfid_reader
from connectivity_module import check_internet_connection, post_backup_data
# Import new enhancement modules
# Import enhancement modules
from logger_batch_module import (
setup_logging as setup_batch_logging,
start_batch_logger,
queue_log_message
)
from chrome_launcher_module import launch_chrome_app, get_chrome_path
from wifi_recovery_module import initialize_wifi_recovery
# Flask app
from flask import Flask
# Global variables
app = None
device_hostname = None
device_ip = None
rfid_reader = None
batch_logger_thread = None
wifi_recovery_manager = None
app_running = True
def setup_signal_handlers():
@@ -76,23 +74,21 @@ def setup_signal_handlers():
def initialize_application():
"""Initialize all application components"""
global device_hostname, device_ip, app, logger
global device_hostname, device_ip
try:
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(f"Start time: {datetime.now().isoformat()}")
# Get device info
logging.info("Retrieving device information...")
device_info = get_device_info()
device_hostname = device_info['hostname']
device_ip = device_info['ip']
device_hostname, device_ip = get_device_info()
logging.info(f"Device: {device_hostname} ({device_ip})")
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_ip
)
@@ -101,7 +97,7 @@ def initialize_application():
logging.info("Performing system initialization...")
perform_system_initialization()
# Check and install dependencies
# Check and install dependencies (no Flask needed)
logging.info("Checking dependencies...")
check_and_install_dependencies()
@@ -109,11 +105,6 @@ def initialize_application():
logging.info("Setting up batch logging system...")
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")
return True
@@ -122,52 +113,6 @@ def initialize_application():
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():
"""Initialize WiFi recovery monitoring"""
global wifi_recovery_manager
@@ -245,8 +190,8 @@ def start_rfid_reader():
global rfid_reader
try:
logging.info("Initializing RFID reader...")
rfid_reader = initialize_rfid_reader()
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")
@@ -287,31 +232,24 @@ def main():
# Start core components in sequence
logging.info("Starting application components...")
# 1. Start Flask web server (provides UI endpoint)
start_flask_server()
time.sleep(1)
# 2. Start batch logging system
# 1. Start batch logging system
start_batch_logger_thread()
time.sleep(0.5)
# 3. Launch Chrome fullscreen UI
start_chrome_app()
time.sleep(2)
# 4. Initialize RFID reader
# 2. Initialize RFID reader
start_rfid_reader()
time.sleep(1)
# 5. Start connectivity monitoring
# 3. Start connectivity monitoring
start_connectivity_monitor()
# 6. Start WiFi recovery monitor
# 4. Start WiFi recovery monitor
start_wifi_recovery_monitor()
logging.info("All components started successfully")
log_with_server(
"System fully operational - batch logging active (75% reduction), "
"Chrome UI fullscreen, WiFi recovery enabled",
"RFID Client operational - batch logging active (75% reduction), "
"RFID reader ready, WiFi recovery enabled",
device_hostname,
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
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_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:
Reader object or None if initialization fails
"""
try:
from rdm6300 import Reader
from rdm6300 import BaseReader
except ImportError:
logging.error("✗ rdm6300 module not installed")
print("✗ rdm6300 module not installed")
log_with_server("ERROR: rdm6300 not installed", device_hostname, device_ip)
return None
logging.info("Initializing RFID reader with RDM6300...")
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:
try:
logging.info(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}")
return r
log_with_server(f"RFID reader started on {device}", device_hostname, device_ip)
return reader
except FileNotFoundError:
logging.warning(f"✗ Device {device} not found")
print(f"✗ Device {device} not found")
continue
except PermissionError:
logging.warning(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")
continue
except Exception as e:
logging.warning(f"✗ Failed to initialize on {device}: {e}")
print(f"✗ Failed to initialize on {device}: {e}")
continue
# 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("Available solutions:")
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(" 4. Reboot the system after making changes")
log_with_server("ERROR: RFID reader initialization failed on all devices", device_hostname, device_ip)
return None