476 lines
14 KiB
Bash
476 lines
14 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"
|
|
}
|
|
|
|
# System update
|
|
update_system() {
|
|
print_step "Updating system packages..."
|
|
sudo apt update -y
|
|
print_success "System packages updated"
|
|
}
|
|
|
|
# Install dependencies
|
|
install_dependencies() {
|
|
print_step "Installing system dependencies..."
|
|
|
|
local packages=(
|
|
"git"
|
|
"apache2"
|
|
"php"
|
|
"sqlite3"
|
|
"python3"
|
|
"python3-pip"
|
|
"python3-dev"
|
|
"build-essential"
|
|
"cmake"
|
|
"libsqlite3-dev"
|
|
"i2c-tools"
|
|
"python3-smbus"
|
|
"python3-serial"
|
|
"python3-requests"
|
|
"python3-schedule"
|
|
)
|
|
|
|
for package in "${packages[@]}"; do
|
|
print_status "Installing $package..."
|
|
if sudo apt install -y "$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"
|
|
"RPi.GPIO"
|
|
"gpiozero"
|
|
"smbus2"
|
|
"adafruit-circuitpython-bme280"
|
|
"sensirion-shdlc-sfa3x"
|
|
"crcmod"
|
|
"psutil"
|
|
)
|
|
|
|
for package in "${pip_packages[@]}"; do
|
|
print_status "Installing Python package: $package..."
|
|
if 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"
|
|
}
|
|
|
|
# Setup directory structure
|
|
setup_directories() {
|
|
print_step "Setting up additional directories and files..."
|
|
|
|
# Create additional directories
|
|
local dirs=(
|
|
"sqlite"
|
|
"logs"
|
|
"matrix/input"
|
|
)
|
|
|
|
for dir in "${dirs[@]}"; do
|
|
sudo mkdir -p "/var/www/moduleair_pro_4g/$dir"
|
|
print_success "Created directory: $dir"
|
|
done
|
|
|
|
# Create required log files
|
|
local files=(
|
|
"logs/app.log"
|
|
"logs/loop.log"
|
|
"matrix/input_NPM.txt"
|
|
"matrix/input_MHZ16.txt"
|
|
"wifi_list.csv"
|
|
)
|
|
|
|
for file in "${files[@]}"; do
|
|
sudo touch "/var/www/moduleair_pro_4g/$file"
|
|
print_success "Created file: $file"
|
|
done
|
|
|
|
# Copy config template if it exists
|
|
if [ -f "/var/www/moduleair_pro_4g/config.json.dist" ]; then
|
|
sudo cp /var/www/moduleair_pro_4g/config.json.dist /var/www/moduleair_pro_4g/config.json
|
|
print_success "Configuration file created from template"
|
|
else
|
|
print_warning "config.json.dist not found - skipping config file creation"
|
|
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 "Directory permissions updated"
|
|
}
|
|
|
|
# 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"
|
|
}
|
|
|
|
# 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"
|
|
}
|
|
|
|
# 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"
|
|
}
|
|
|
|
# Check matrix binaries
|
|
check_matrix_binaries() {
|
|
print_step "Checking matrix display binaries..."
|
|
|
|
local programs=(
|
|
"screenNetwork/network_status"
|
|
"screenSensors/displayAll4_v2"
|
|
"screenSensors/displayCO2_PM_Network"
|
|
"screenSensors/blank_screen"
|
|
"welcomeScreen/welcome_screen"
|
|
)
|
|
|
|
for program in "${programs[@]}"; do
|
|
local binary_file="/var/www/moduleair_pro_4g/matrix/${program}"
|
|
|
|
if [ -f "$binary_file" ] && [ -x "$binary_file" ]; then
|
|
print_success "Matrix binary found: $program"
|
|
else
|
|
print_warning "Matrix binary missing or not executable: $program"
|
|
fi
|
|
done
|
|
|
|
# Check matrix library
|
|
if [ -f "/var/www/moduleair_pro_4g/matrix/lib/librgbmatrix.a" ]; then
|
|
print_success "Matrix library found: librgbmatrix.a"
|
|
else
|
|
print_warning "Matrix library missing: librgbmatrix.a"
|
|
fi
|
|
|
|
print_success "Matrix binaries check completed"
|
|
}
|
|
|
|
# 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"
|
|
)
|
|
|
|
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} Device permissions set"
|
|
echo -e "${GREEN}✓${NC} Matrix binaries verified"
|
|
echo -e "${GREEN}✓${NC} Systemd services configured"
|
|
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 ""
|
|
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 ""
|
|
print_warning "I2C and UART devices will NOT work until after reboot!"
|
|
}
|
|
|
|
# Main installation function
|
|
main() {
|
|
print_header "MODULEAIR PRO 4G INSTALLATION"
|
|
print_status "Starting automated installation..."
|
|
|
|
check_root
|
|
check_sudo
|
|
update_system
|
|
install_dependencies
|
|
install_python_packages
|
|
clone_repository
|
|
setup_directories
|
|
configure_apache
|
|
enable_hardware
|
|
set_permissions
|
|
check_matrix_binaries
|
|
setup_services
|
|
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 "$@" |