Organize project: Move old code and documentation to oldcode folder, add comprehensive README
This commit is contained in:
253
system_init_module.py
Normal file
253
system_init_module.py
Normal file
@@ -0,0 +1,253 @@
|
||||
"""
|
||||
System initialization and hardware checks
|
||||
Handles first-run setup and hardware validation
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import stat
|
||||
import pwd
|
||||
import grp
|
||||
from config_settings import SERIAL_DEVICES, GPIO_DEVICES
|
||||
|
||||
|
||||
def check_system_requirements():
|
||||
"""Check basic system requirements"""
|
||||
print("Checking system requirements...")
|
||||
|
||||
try:
|
||||
# Check if running on supported OS
|
||||
if sys.platform not in ['linux', 'linux2']:
|
||||
print("⚠ Warning: This application is designed for Linux systems")
|
||||
return False
|
||||
|
||||
# Check Python version
|
||||
if sys.version_info < (3, 7):
|
||||
print("✗ Python 3.7+ required")
|
||||
return False
|
||||
|
||||
print(f"✓ Python {sys.version_info.major}.{sys.version_info.minor} detected")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Error checking system requirements: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def check_port_capabilities():
|
||||
"""Check if the application can bind to port 80"""
|
||||
print("Checking port 80 capabilities...")
|
||||
|
||||
try:
|
||||
# Check if we're running as root
|
||||
if os.geteuid() == 0:
|
||||
print("✓ Running as root - port 80 access available")
|
||||
return True
|
||||
|
||||
# Check if capabilities are set
|
||||
python_path = sys.executable
|
||||
result = subprocess.run(['getcap', python_path], capture_output=True, text=True)
|
||||
|
||||
if 'cap_net_bind_service=ep' in result.stdout:
|
||||
print("✓ Port binding capabilities already set")
|
||||
return True
|
||||
|
||||
# Try to set capabilities
|
||||
print("Setting up port 80 binding capabilities...")
|
||||
setup_script = './setup_port_capability.sh'
|
||||
|
||||
if os.path.exists(setup_script):
|
||||
result = subprocess.run(['sudo', 'bash', setup_script], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
print("✓ Port capabilities set successfully")
|
||||
return True
|
||||
else:
|
||||
print(f"✗ Failed to set capabilities: {result.stderr}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not check port capabilities: {e}")
|
||||
|
||||
print("Warning: Port 80 may not be accessible. App will try to run on default port.")
|
||||
return False
|
||||
|
||||
|
||||
def check_hardware_interfaces():
|
||||
"""Check hardware interfaces (UART/Serial) for RFID reader"""
|
||||
print("Checking hardware interfaces...")
|
||||
|
||||
available_devices = []
|
||||
|
||||
for device in SERIAL_DEVICES:
|
||||
if os.path.exists(device):
|
||||
try:
|
||||
with open(device, 'r'):
|
||||
pass
|
||||
available_devices.append(device)
|
||||
print(f"✓ Serial device available: {device}")
|
||||
except PermissionError:
|
||||
print(f"✗ Permission denied for {device}. Adding user to dialout group...")
|
||||
try:
|
||||
username = pwd.getpwuid(os.getuid()).pw_name
|
||||
subprocess.run(['sudo', 'usermod', '-a', '-G', 'dialout', username],
|
||||
capture_output=True, text=True)
|
||||
print(f"✓ User {username} added to dialout group (reboot may be required)")
|
||||
available_devices.append(device)
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to add user to dialout group: {e}")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not test {device}: {e}")
|
||||
|
||||
if not available_devices:
|
||||
print("✗ No serial devices found. RFID reader may not work.")
|
||||
try:
|
||||
config_file = '/boot/config.txt'
|
||||
if os.path.exists(config_file):
|
||||
print("Attempting to enable UART in Raspberry Pi config...")
|
||||
result = subprocess.run(['sudo', 'raspi-config', 'nonint', 'do_serial', '0'],
|
||||
capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
print("✓ UART enabled in config (reboot required)")
|
||||
else:
|
||||
print("Warning: Could not enable UART automatically")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not configure UART: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def initialize_gpio_permissions():
|
||||
"""Set up GPIO permissions for LED control"""
|
||||
print("Setting up GPIO permissions...")
|
||||
|
||||
try:
|
||||
username = pwd.getpwuid(os.getuid()).pw_name
|
||||
|
||||
# Check if gpio group exists
|
||||
try:
|
||||
grp.getgrnam('gpio')
|
||||
subprocess.run(['sudo', 'usermod', '-a', '-G', 'gpio', username],
|
||||
capture_output=True, text=True)
|
||||
print(f"✓ User {username} added to gpio group")
|
||||
except KeyError:
|
||||
print("Warning: gpio group not found - GPIO access may be limited")
|
||||
|
||||
# Set up GPIO access via /dev/gpiomem if available
|
||||
for device in GPIO_DEVICES:
|
||||
if os.path.exists(device):
|
||||
print(f"✓ GPIO device available: {device}")
|
||||
return True
|
||||
|
||||
print("Warning: No GPIO devices found")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not set up GPIO permissions: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def check_network_connectivity():
|
||||
"""Check network connectivity and DNS resolution"""
|
||||
print("Checking network connectivity...")
|
||||
|
||||
try:
|
||||
# Test basic connectivity
|
||||
result = subprocess.run(['ping', '-c', '1', '8.8.8.8'],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0:
|
||||
print("✓ Internet connectivity available")
|
||||
|
||||
# Test DNS resolution
|
||||
try:
|
||||
import socket
|
||||
socket.gethostbyname('google.com')
|
||||
print("✓ DNS resolution working")
|
||||
return True
|
||||
except socket.gaierror:
|
||||
print("✗ DNS resolution failed")
|
||||
return False
|
||||
else:
|
||||
print("✗ No internet connectivity")
|
||||
return False
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
print("✗ Network timeout")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not test network: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def create_required_files():
|
||||
"""Create required data files with defaults if they don't exist"""
|
||||
print("Checking required files...")
|
||||
|
||||
from config_settings import ID_MASA_FILE, TAG_FILE, DATA_DIR
|
||||
|
||||
required_files = {
|
||||
str(ID_MASA_FILE): "unknown",
|
||||
str(TAG_FILE): ""
|
||||
}
|
||||
|
||||
for file_path, default_content in required_files.items():
|
||||
try:
|
||||
if not os.path.exists(file_path):
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(default_content)
|
||||
print(f"✓ Created default file: {file_path}")
|
||||
else:
|
||||
print(f"✓ File exists: {file_path}")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to create file {file_path}: {e}")
|
||||
|
||||
# Set file permissions
|
||||
try:
|
||||
for file_path in required_files.keys():
|
||||
if os.path.exists(file_path):
|
||||
os.chmod(file_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||
print("✓ File permissions set correctly")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not set file permissions: {e}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def perform_system_initialization():
|
||||
"""Perform complete system initialization for first run"""
|
||||
print("=" * 60)
|
||||
print("SYSTEM INITIALIZATION - Preparing for first run")
|
||||
print("=" * 60)
|
||||
|
||||
initialization_steps = [
|
||||
("System Requirements", check_system_requirements),
|
||||
("File Creation", create_required_files),
|
||||
("Port Capabilities", check_port_capabilities),
|
||||
("Hardware Interfaces", check_hardware_interfaces),
|
||||
("GPIO Permissions", initialize_gpio_permissions),
|
||||
("Network Connectivity", check_network_connectivity)
|
||||
]
|
||||
|
||||
success_count = 0
|
||||
total_steps = len(initialization_steps)
|
||||
|
||||
for step_name, step_function in initialization_steps:
|
||||
print(f"\n--- {step_name} ---")
|
||||
try:
|
||||
if step_function():
|
||||
success_count += 1
|
||||
print(f"✓ {step_name} completed successfully")
|
||||
else:
|
||||
print(f"⚠ {step_name} completed with warnings")
|
||||
except Exception as e:
|
||||
print(f"✗ {step_name} failed: {e}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"INITIALIZATION COMPLETE: {success_count}/{total_steps} steps successful")
|
||||
print("=" * 60)
|
||||
|
||||
if success_count < total_steps:
|
||||
print("Warning: Some initialization steps failed. Application may have limited functionality.")
|
||||
|
||||
return success_count >= (total_steps - 1) # Allow one failure
|
||||
Reference in New Issue
Block a user