710 lines
22 KiB
Bash
710 lines
22 KiB
Bash
#!/bin/bash
|
|
|
|
# ModuleAir Pro 4G - Complete Installation Script
|
|
# Author: ModuleAir Team
|
|
# Description: Automated deployment script for Raspberry Pi with colored output
|
|
|
|
set -e # Exit on any error
|
|
|
|
# Color codes for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
PURPLE='\033[0;35m'
|
|
CYAN='\033[0;36m'
|
|
WHITE='\033[1;37m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Function to print colored messages
|
|
print_status() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
print_header() {
|
|
echo -e "${PURPLE}================================${NC}"
|
|
echo -e "${WHITE}$1${NC}"
|
|
echo -e "${PURPLE}================================${NC}"
|
|
}
|
|
|
|
print_step() {
|
|
echo -e "${CYAN}[STEP]${NC} $1"
|
|
}
|
|
|
|
# Check if running as root
|
|
check_root() {
|
|
if [[ $EUID -eq 0 ]]; then
|
|
print_error "This script should not be run as root. Run as regular user with sudo privileges."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Check if sudo is available
|
|
check_sudo() {
|
|
print_step "Checking sudo privileges..."
|
|
if ! sudo -n true 2>/dev/null; then
|
|
print_error "This script requires sudo privileges. Please run: sudo visudo"
|
|
exit 1
|
|
fi
|
|
print_success "Sudo privileges confirmed"
|
|
}
|
|
|
|
# Pre-configure packages to avoid prompts
|
|
pre_configure_packages() {
|
|
print_step "Pre-configuring packages to avoid prompts..."
|
|
|
|
# Pre-configure common package questions
|
|
|
|
# For any package that uses debconf
|
|
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
|
|
|
|
# For timezone data (if tzdata gets updated)
|
|
echo 'tzdata tzdata/Areas select Europe' | sudo debconf-set-selections
|
|
echo 'tzdata tzdata/Zones/Europe select Paris' | sudo debconf-set-selections
|
|
|
|
# For keyboard configuration
|
|
echo 'keyboard-configuration keyboard-configuration/layoutcode string us' | sudo debconf-set-selections
|
|
|
|
# For any service restart prompts
|
|
echo '* libraries/restart-without-asking boolean true' | sudo debconf-set-selections
|
|
|
|
print_success "Package pre-configuration completed"
|
|
}
|
|
|
|
# System update
|
|
update_system() {
|
|
print_step "Updating system packages..."
|
|
# Set non-interactive mode for apt
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
sudo apt update -y
|
|
print_success "System packages updated"
|
|
}
|
|
|
|
# Install dependencies
|
|
install_dependencies() {
|
|
print_step "Installing system dependencies..."
|
|
|
|
# Ensure non-interactive mode
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
local packages=(
|
|
"git"
|
|
"apache2"
|
|
"php"
|
|
"php-sqlite3"
|
|
"sqlite3"
|
|
"python3"
|
|
"python3-pip"
|
|
"python3-dev"
|
|
"build-essential"
|
|
"cmake"
|
|
"libsqlite3-dev"
|
|
"i2c-tools"
|
|
"python3-smbus"
|
|
"python3-serial"
|
|
"python3-requests"
|
|
"python3-schedule"
|
|
"python3-rpi.gpio"
|
|
)
|
|
|
|
for package in "${packages[@]}"; do
|
|
print_status "Installing $package..."
|
|
if sudo DEBIAN_FRONTEND=noninteractive apt install -y -q "$package"; then
|
|
print_success "$package installed"
|
|
else
|
|
print_error "Failed to install $package"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
print_success "All system dependencies installed"
|
|
}
|
|
|
|
# Install Python packages
|
|
install_python_packages() {
|
|
print_step "Installing Python packages..."
|
|
|
|
local pip_packages=(
|
|
"pymodbus"
|
|
"pyserial"
|
|
"requests"
|
|
"schedule"
|
|
"gpiozero"
|
|
"smbus2"
|
|
"adafruit-circuitpython-bme280"
|
|
"sensirion-shdlc-sfa3x"
|
|
"crcmod"
|
|
"psutil"
|
|
)
|
|
|
|
for package in "${pip_packages[@]}"; do
|
|
print_status "Installing Python package: $package..."
|
|
if sudo pip3 install "$package" --break-system-packages; then
|
|
print_success "$package installed"
|
|
else
|
|
print_warning "Failed to install $package (may already be installed)"
|
|
fi
|
|
done
|
|
|
|
print_success "Python packages installation completed"
|
|
}
|
|
|
|
# Clone repository
|
|
clone_repository() {
|
|
print_step "Cloning ModuleAir Pro 4G repository..."
|
|
|
|
# Remove existing directory if it exists
|
|
if [ -d "/var/www/moduleair_pro_4g" ]; then
|
|
print_warning "Directory /var/www/moduleair_pro_4g already exists - removing..."
|
|
sudo rm -rf /var/www/moduleair_pro_4g
|
|
fi
|
|
|
|
# Clone the repository
|
|
if sudo git clone http://gitea.aircarto.fr/PaulVua/moduleair_pro_4g.git /var/www/moduleair_pro_4g; then
|
|
print_success "Repository cloned successfully"
|
|
else
|
|
print_error "Failed to clone repository"
|
|
exit 1
|
|
fi
|
|
|
|
# Set proper permissions
|
|
sudo chown -R www-data:www-data /var/www/moduleair_pro_4g
|
|
sudo chmod -R 755 /var/www/moduleair_pro_4g
|
|
print_success "Repository permissions set"
|
|
}
|
|
|
|
|
|
# Configure Apache
|
|
configure_apache() {
|
|
print_step "Configuring Apache web server..."
|
|
|
|
# Backup original config
|
|
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf.backup
|
|
print_status "Original Apache config backed up"
|
|
|
|
# Update DocumentRoot
|
|
sudo sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/moduleair_pro_4g|' /etc/apache2/sites-available/000-default.conf
|
|
|
|
# Enable PHP if not already enabled
|
|
sudo a2enmod php* 2>/dev/null || true
|
|
|
|
# Restart Apache
|
|
sudo systemctl restart apache2
|
|
sudo systemctl enable apache2
|
|
|
|
print_success "Apache configured and restarted"
|
|
}
|
|
|
|
# System optimizations (disable audio, isolate CPU)
|
|
system_optimizations() {
|
|
print_step "Applying system optimizations..."
|
|
|
|
# Find config.txt location
|
|
local config_file="/boot/firmware/config.txt"
|
|
if [ ! -f "$config_file" ]; then
|
|
config_file="/boot/config.txt"
|
|
fi
|
|
|
|
if [ ! -f "$config_file" ]; then
|
|
print_error "Could not find config.txt file"
|
|
return 1
|
|
fi
|
|
|
|
# Disable onboard audio
|
|
print_status "Disabling onboard audio..."
|
|
if grep -q "^dtparam=audio=" "$config_file"; then
|
|
# Replace existing audio parameter
|
|
sudo sed -i 's/^dtparam=audio=.*/dtparam=audio=off/' "$config_file"
|
|
print_success "Audio parameter updated to off"
|
|
else
|
|
# Add audio parameter if not exists
|
|
echo "dtparam=audio=off" | sudo tee -a "$config_file" > /dev/null
|
|
print_success "Audio disabled in config.txt"
|
|
fi
|
|
|
|
# Blacklist audio module
|
|
print_status "Blacklisting audio module..."
|
|
echo "blacklist snd_bcm2835" | sudo tee /etc/modprobe.d/blacklist.conf > /dev/null
|
|
print_success "Audio module blacklisted"
|
|
|
|
# Find cmdline.txt location
|
|
local cmdline_file="/boot/firmware/cmdline.txt"
|
|
if [ ! -f "$cmdline_file" ]; then
|
|
cmdline_file="/boot/cmdline.txt"
|
|
fi
|
|
|
|
if [ ! -f "$cmdline_file" ]; then
|
|
print_error "Could not find cmdline.txt file"
|
|
return 1
|
|
fi
|
|
|
|
# Add CPU isolation
|
|
print_status "Setting up CPU isolation..."
|
|
if ! grep -q "isolcpus=3" "$cmdline_file"; then
|
|
# Read current cmdline and append isolcpus
|
|
local current_cmdline=$(cat "$cmdline_file")
|
|
echo "${current_cmdline} isolcpus=3" | sudo tee "$cmdline_file" > /dev/null
|
|
print_success "CPU core 3 isolated"
|
|
else
|
|
print_warning "CPU isolation already configured"
|
|
fi
|
|
|
|
# Check if audio module is currently loaded
|
|
if lsmod | grep -q snd_bcm2835; then
|
|
print_warning "Audio module is currently loaded. It will be disabled after reboot."
|
|
else
|
|
print_success "Audio module is not loaded"
|
|
fi
|
|
|
|
print_success "System optimizations completed"
|
|
}
|
|
|
|
# Enable hardware interfaces
|
|
enable_hardware() {
|
|
print_step "Enabling hardware interfaces..."
|
|
|
|
# Enable I2C using raspi-config
|
|
print_status "Enabling I2C interface..."
|
|
if sudo raspi-config nonint do_i2c 0; then
|
|
print_success "I2C enabled via raspi-config"
|
|
else
|
|
print_warning "Failed to enable I2C via raspi-config"
|
|
fi
|
|
|
|
# Enable SPI using raspi-config
|
|
print_status "Enabling SPI interface..."
|
|
if sudo raspi-config nonint do_spi 0; then
|
|
print_success "SPI enabled via raspi-config"
|
|
else
|
|
print_warning "Failed to enable SPI via raspi-config"
|
|
fi
|
|
|
|
# Enable Serial/UART using raspi-config
|
|
print_status "Enabling Serial interface..."
|
|
if sudo raspi-config nonint do_serial 0; then
|
|
print_success "Serial enabled via raspi-config"
|
|
else
|
|
print_warning "Failed to enable Serial via raspi-config"
|
|
fi
|
|
|
|
# Check if config.txt exists for additional UART configurations
|
|
local config_file="/boot/firmware/config.txt"
|
|
if [ ! -f "$config_file" ]; then
|
|
config_file="/boot/config.txt"
|
|
fi
|
|
|
|
if [ ! -f "$config_file" ]; then
|
|
print_error "Could not find config.txt file"
|
|
exit 1
|
|
fi
|
|
|
|
print_status "Using config file: $config_file"
|
|
|
|
# Add additional UART configurations for multiple ports
|
|
local uart_configs=(
|
|
"dtoverlay=uart2"
|
|
"dtoverlay=uart3"
|
|
"dtoverlay=uart4"
|
|
"dtoverlay=uart5"
|
|
)
|
|
|
|
for config in "${uart_configs[@]}"; do
|
|
if ! grep -q "^$config" "$config_file"; then
|
|
echo "$config" | sudo tee -a "$config_file"
|
|
print_success "Added: $config"
|
|
else
|
|
print_warning "$config already configured"
|
|
fi
|
|
done
|
|
|
|
print_success "Hardware interfaces configuration completed"
|
|
}
|
|
|
|
# Setup sudo authorization
|
|
setup_sudo_authorization() {
|
|
print_step "Setting up sudo authorization..."
|
|
|
|
SUDOERS_FILE="/etc/sudoers"
|
|
|
|
# First, fix any existing syntax errors
|
|
if sudo visudo -c 2>&1 | grep -q "syntax error"; then
|
|
print_warning "Syntax error detected in sudoers file. Attempting to fix..."
|
|
# Remove the problematic line if it exists
|
|
sudo sed -i '/www-data ALL=(ALL) NOPASSWD: \/usr\/bin\/python3 \* www-data/d' "$SUDOERS_FILE"
|
|
fi
|
|
|
|
# Add proper sudo rules (each on a separate line)
|
|
if ! sudo grep -q "/usr/bin/nmcli" "$SUDOERS_FILE"; then
|
|
# Create a temporary file with the new rules
|
|
cat <<EOF | sudo tee /tmp/sudoers_additions > /dev/null
|
|
# ModuleAir Pro 4G sudo rules
|
|
ALL ALL=(ALL) NOPASSWD: /usr/bin/nmcli, /usr/sbin/reboot
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/git pull
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/ssh
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/python3 *
|
|
www-data ALL=(ALL) NOPASSWD: /bin/systemctl *
|
|
www-data ALL=(ALL) NOPASSWD: /var/www/moduleair_pro_4g/*
|
|
EOF
|
|
|
|
# Validate the temporary file
|
|
if sudo visudo -c -f /tmp/sudoers_additions; then
|
|
# Append to sudoers if valid using tee with sudo
|
|
cat /tmp/sudoers_additions | sudo EDITOR='tee -a' visudo >/dev/null 2>&1
|
|
print_success "Sudo authorization added"
|
|
else
|
|
print_error "Failed to add sudo rules - syntax validation failed"
|
|
sudo rm -f /tmp/sudoers_additions
|
|
return 1
|
|
fi
|
|
|
|
# Clean up
|
|
sudo rm -f /tmp/sudoers_additions
|
|
else
|
|
print_warning "Sudo authorization already set. Skipping."
|
|
fi
|
|
|
|
# Validate sudoers file after changes
|
|
if ! sudo visudo -c; then
|
|
print_error "Sudoers file has syntax errors! Please fix manually with 'sudo visudo'"
|
|
return 1
|
|
fi
|
|
|
|
print_success "Sudo authorization configured successfully"
|
|
}
|
|
|
|
# Set device permissions
|
|
set_permissions() {
|
|
print_step "Setting device permissions..."
|
|
|
|
# Set UART permissions
|
|
sudo chmod 666 /dev/ttyAMA* 2>/dev/null || print_warning "Some UART devices may not be available yet"
|
|
|
|
# Set I2C permissions
|
|
sudo chmod 666 /dev/i2c-* 2>/dev/null || print_warning "I2C devices may not be available yet"
|
|
|
|
# Add user to dialout group for serial access
|
|
sudo usermod -a -G dialout "$USER"
|
|
sudo usermod -a -G i2c "$USER"
|
|
sudo usermod -a -G gpio "$USER"
|
|
|
|
print_success "Device permissions set"
|
|
}
|
|
|
|
# Setup RTC save to DB service
|
|
setup_rtc_service() {
|
|
print_step "Setting up RTC save to DB service..."
|
|
|
|
# Create the service file
|
|
cat << 'EOF' | sudo tee /etc/systemd/system/rtc_save_to_db.service > /dev/null
|
|
[Unit]
|
|
Description=RTC Save to DB Script
|
|
After=network.target
|
|
|
|
[Service]
|
|
ExecStart=/usr/bin/python3 /var/www/moduleair_pro_4g/RTC/save_to_db.py
|
|
Restart=always
|
|
RestartSec=1
|
|
User=root
|
|
WorkingDirectory=/var/www/moduleair_pro_4g
|
|
StandardOutput=append:/var/www/moduleair_pro_4g/logs/rtc_save_to_db.log
|
|
StandardError=append:/var/www/moduleair_pro_4g/logs/rtc_save_to_db_errors.log
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
print_success "RTC service file created"
|
|
|
|
# Create logs directory if it doesn't exist
|
|
sudo mkdir -p /var/www/moduleair_pro_4g/logs
|
|
sudo chown -R www-data:www-data /var/www/moduleair_pro_4g/logs
|
|
print_status "Logs directory created/verified"
|
|
|
|
# Reload systemd daemon
|
|
print_status "Reloading systemd daemon..."
|
|
sudo systemctl daemon-reload
|
|
|
|
# Enable the service
|
|
print_status "Enabling RTC service..."
|
|
if sudo systemctl enable rtc_save_to_db.service; then
|
|
print_success "RTC service enabled"
|
|
else
|
|
print_error "Failed to enable RTC service"
|
|
return 1
|
|
fi
|
|
|
|
# Start the service
|
|
print_status "Starting RTC service..."
|
|
if sudo systemctl start rtc_save_to_db.service; then
|
|
print_success "RTC service started"
|
|
else
|
|
print_warning "Failed to start RTC service - may need reboot"
|
|
fi
|
|
|
|
# Check service status
|
|
print_status "Checking RTC service status..."
|
|
if systemctl is-active --quiet rtc_save_to_db.service; then
|
|
print_success "RTC service is running"
|
|
else
|
|
print_warning "RTC service is not running - will start after reboot"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Setup cron jobs
|
|
setup_cron_jobs() {
|
|
print_step "Setting up cron jobs..."
|
|
|
|
if [ -f "/var/www/moduleair_pro_4g/cron_jobs" ]; then
|
|
if sudo crontab "/var/www/moduleair_pro_4g/cron_jobs"; then
|
|
print_success "Cron jobs set up successfully"
|
|
else
|
|
print_error "Failed to set up cron jobs"
|
|
return 1
|
|
fi
|
|
else
|
|
print_warning "Cron jobs file not found. Skipping."
|
|
fi
|
|
}
|
|
|
|
# Create databases
|
|
create_databases() {
|
|
print_step "Creating databases..."
|
|
|
|
if [ -f "/var/www/moduleair_pro_4g/sqlite/create_db.py" ]; then
|
|
if sudo /usr/bin/python3 "/var/www/moduleair_pro_4g/sqlite/create_db.py"; then
|
|
print_success "Databases created successfully"
|
|
else
|
|
print_error "Failed to create databases"
|
|
return 1
|
|
fi
|
|
else
|
|
print_warning "Database creation script not found"
|
|
fi
|
|
}
|
|
|
|
# Fix database permissions
|
|
fix_database_permissions() {
|
|
print_step "Fixing database permissions..."
|
|
|
|
# Set full permissions for sqlite directory
|
|
if [ -d "/var/www/moduleair_pro_4g/sqlite" ]; then
|
|
sudo chmod 777 /var/www/moduleair_pro_4g/sqlite/
|
|
print_success "Set permissions for sqlite directory"
|
|
else
|
|
print_warning "sqlite directory not found"
|
|
fi
|
|
|
|
# Set full permissions for sensors.db
|
|
if [ -f "/var/www/moduleair_pro_4g/sqlite/sensors.db" ]; then
|
|
sudo chmod 777 /var/www/moduleair_pro_4g/sqlite/sensors.db
|
|
print_success "Set permissions for sensors.db"
|
|
else
|
|
print_warning "sensors.db not found"
|
|
fi
|
|
|
|
print_success "Database permissions fixed"
|
|
}
|
|
|
|
# Set configuration
|
|
set_configuration() {
|
|
print_step "Setting configuration..."
|
|
|
|
if [ -f "/var/www/moduleair_pro_4g/sqlite/set_config_smart.py" ]; then
|
|
if sudo /usr/bin/python3 "/var/www/moduleair_pro_4g/sqlite/set_config_smart.py"; then
|
|
print_success "Configuration set successfully"
|
|
else
|
|
print_error "Failed to set configuration"
|
|
return 1
|
|
fi
|
|
else
|
|
print_warning "Configuration script not found"
|
|
fi
|
|
}
|
|
|
|
# Setup systemd services
|
|
setup_services() {
|
|
print_step "Setting up systemd services..."
|
|
|
|
if [ -f "/var/www/moduleair_pro_4g/services/setup_services.sh" ]; then
|
|
sudo chmod +x /var/www/moduleair_pro_4g/services/setup_services.sh
|
|
if sudo /var/www/moduleair_pro_4g/services/setup_services.sh; then
|
|
print_success "Systemd services configured"
|
|
else
|
|
print_error "Failed to setup systemd services"
|
|
exit 1
|
|
fi
|
|
else
|
|
print_warning "setup_services.sh not found - services will need to be configured manually"
|
|
fi
|
|
}
|
|
|
|
# Create startup script for permissions (runs at boot)
|
|
create_boot_script() {
|
|
print_step "Creating boot permission script..."
|
|
|
|
cat << 'EOF' | sudo tee /usr/local/bin/moduleair-permissions.sh > /dev/null
|
|
#!/bin/bash
|
|
# ModuleAir Pro 4G Boot Permissions Script
|
|
sleep 5 # Wait for devices to initialize
|
|
chmod 666 /dev/ttyAMA* 2>/dev/null || true
|
|
chmod 666 /dev/i2c-* 2>/dev/null || true
|
|
EOF
|
|
|
|
sudo chmod +x /usr/local/bin/moduleair-permissions.sh
|
|
|
|
# Create systemd service for boot permissions
|
|
cat << 'EOF' | sudo tee /etc/systemd/system/moduleair-permissions.service > /dev/null
|
|
[Unit]
|
|
Description=ModuleAir Pro 4G Device Permissions
|
|
After=multi-user.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/bin/moduleair-permissions.sh
|
|
RemainAfterExit=yes
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo systemctl enable moduleair-permissions.service
|
|
print_success "Boot permission script created and enabled"
|
|
}
|
|
|
|
# Final status check
|
|
final_status() {
|
|
print_header "INSTALLATION COMPLETE"
|
|
|
|
print_step "Checking service status..."
|
|
|
|
# Check Apache
|
|
if systemctl is-active --quiet apache2; then
|
|
print_success "Apache2 is running"
|
|
else
|
|
print_warning "Apache2 is not running"
|
|
fi
|
|
|
|
# Check for ModuleAir services
|
|
local services=(
|
|
"moduleair-npm-data.timer"
|
|
"moduleair-co2-data.timer"
|
|
"moduleair-sara-data.timer"
|
|
"moduleair-bme-data.timer"
|
|
"moduleair-boot.service"
|
|
"rtc_save_to_db.service"
|
|
)
|
|
|
|
for service in "${services[@]}"; do
|
|
if systemctl is-enabled --quiet "$service" 2>/dev/null; then
|
|
print_success "Service enabled: $service"
|
|
else
|
|
print_warning "Service not found: $service"
|
|
fi
|
|
done
|
|
|
|
print_header "INSTALLATION SUMMARY"
|
|
echo -e "${GREEN}✓${NC} System packages installed"
|
|
echo -e "${GREEN}✓${NC} Python packages installed"
|
|
echo -e "${GREEN}✓${NC} Repository cloned"
|
|
echo -e "${GREEN}✓${NC} Directory structure created"
|
|
echo -e "${GREEN}✓${NC} Apache web server configured"
|
|
echo -e "${GREEN}✓${NC} Hardware interfaces enabled"
|
|
echo -e "${GREEN}✓${NC} System optimizations applied"
|
|
echo -e "${GREEN}✓${NC} Device permissions set"
|
|
echo -e "${GREEN}✓${NC} Sudo authorization configured"
|
|
echo -e "${GREEN}✓${NC} Databases created"
|
|
echo -e "${GREEN}✓${NC} Configuration set"
|
|
echo -e "${GREEN}✓${NC} Cron jobs configured"
|
|
echo -e "${GREEN}✓${NC} Matrix binaries verified"
|
|
echo -e "${GREEN}✓${NC} Systemd services configured"
|
|
echo -e "${GREEN}✓${NC} RTC save to DB service installed"
|
|
echo -e "${GREEN}✓${NC} Boot scripts created"
|
|
|
|
print_header "NEXT STEPS"
|
|
echo -e "${YELLOW}1.${NC} ${RED}REBOOT REQUIRED${NC} - Hardware interfaces need reboot to activate:"
|
|
echo -e " ${CYAN}sudo reboot${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}2.${NC} After reboot, verify I2C and UART devices:"
|
|
echo -e " ${CYAN}ls -la /dev/i2c-* /dev/ttyAMA*${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}3.${NC} Check service status:"
|
|
echo -e " ${CYAN}systemctl list-timers | grep moduleair${NC}"
|
|
echo -e " ${CYAN}systemctl status rtc_save_to_db.service${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}4.${NC} Test RTC module (after reboot):"
|
|
echo -e " ${CYAN}python3 /var/www/moduleair_pro_4g/RTC/read.py${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}5.${NC} Access web interface at:"
|
|
echo -e " ${CYAN}http://$(hostname -I | awk '{print $1}')${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}6.${NC} Check logs if needed:"
|
|
echo -e " ${CYAN}tail -f /var/www/moduleair_pro_4g/logs/*.log${NC}"
|
|
echo -e " ${CYAN}tail -f /var/www/moduleair_pro_4g/logs/rtc_save_to_db.log${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}7.${NC} Check cron jobs:"
|
|
echo -e " ${CYAN}sudo crontab -l${NC}"
|
|
echo -e ""
|
|
echo -e "${YELLOW}8.${NC} Verify audio is disabled (after reboot):"
|
|
echo -e " ${CYAN}lsmod | grep snd_bcm2835${NC} (should return nothing)"
|
|
echo -e ""
|
|
echo -e "${YELLOW}9.${NC} Verify CPU isolation (after reboot):"
|
|
echo -e " ${CYAN}cat /proc/cmdline | grep isolcpus${NC}"
|
|
echo -e ""
|
|
print_warning "I2C and UART devices will NOT work until after reboot!"
|
|
print_warning "Audio and CPU isolation changes require reboot to take effect!"
|
|
}
|
|
|
|
# Main installation function
|
|
main() {
|
|
print_header "MODULEAIR PRO 4G INSTALLATION"
|
|
print_status "Starting automated installation..."
|
|
|
|
# Set non-interactive mode globally
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
export NEEDRESTART_MODE=a
|
|
|
|
check_root
|
|
check_sudo
|
|
pre_configure_packages
|
|
update_system
|
|
install_dependencies
|
|
install_python_packages
|
|
clone_repository
|
|
configure_apache
|
|
enable_hardware
|
|
system_optimizations
|
|
set_permissions
|
|
setup_sudo_authorization
|
|
|
|
# Database and configuration setup
|
|
create_databases
|
|
set_configuration
|
|
fix_database_permissions # Fix permissions after database creation
|
|
setup_cron_jobs
|
|
|
|
setup_services
|
|
setup_rtc_service # New function for RTC service
|
|
create_boot_script
|
|
final_status
|
|
|
|
print_header "INSTALLATION COMPLETED SUCCESSFULLY"
|
|
print_success "ModuleAir Pro 4G has been installed successfully!"
|
|
print_warning "Please reboot the system to complete the installation."
|
|
}
|
|
|
|
# Run main function
|
|
main "$@" |