# Calejo Control Adapter - Installation & Configuration Guide ## Overview This guide provides comprehensive instructions for installing and configuring the Calejo Control Adapter for municipal wastewater pump station optimization. ## System Requirements ### Hardware Requirements #### Minimum Requirements - **CPU**: 2 cores (x86-64) - **RAM**: 4 GB - **Storage**: 10 GB SSD - **Network**: 1 Gbps Ethernet #### Recommended Requirements - **CPU**: 4 cores (x86-64) - **RAM**: 8 GB - **Storage**: 50 GB SSD - **Network**: 1 Gbps Ethernet with redundancy #### Production Requirements - **CPU**: 8+ cores (x86-64) - **RAM**: 16+ GB - **Storage**: 100+ GB SSD with RAID - **Network**: Dual 1 Gbps Ethernet ### Software Requirements #### Operating Systems - **Linux**: Ubuntu 20.04+, CentOS 8+, RHEL 8+ - **Container**: Docker 20.10+, Podman 3.0+ - **Virtualization**: VMware ESXi 7.0+, Hyper-V 2019+ #### Dependencies - **Python**: 3.9+ - **PostgreSQL**: 13+ - **Redis**: 6.0+ (optional, for caching) ## Installation Methods ### Method 1: Docker Container (Recommended) #### Prerequisites - Docker Engine 20.10+ - Docker Compose 2.0+ #### Quick Start 1. **Clone the repository**: ```bash git clone https://github.com/calejo/control-adapter.git cd control-adapter ``` 2. **Configure environment**: ```bash cp config/.env.example .env # Edit .env with your configuration nano .env ``` 3. **Start the application**: ```bash docker-compose up -d ``` 4. **Verify installation**: ```bash docker-compose logs -f control-adapter ``` #### Docker Compose Configuration ```yaml version: '3.8' services: control-adapter: image: calejo/control-adapter:latest container_name: calejo-control-adapter restart: unless-stopped ports: - "4840:4840" # OPC UA - "502:502" # Modbus TCP - "8080:8080" # REST API - "8081:8081" # Health Monitor environment: - DATABASE_URL=${DATABASE_URL} - JWT_SECRET_KEY=${JWT_SECRET_KEY} - LOG_LEVEL=${LOG_LEVEL} volumes: - ./config:/app/config - ./logs:/app/logs - ./certs:/app/certs networks: - calejo-network database: image: postgres:15 container_name: calejo-database restart: unless-stopped environment: - POSTGRES_DB=calejo - POSTGRES_USER=control_reader - POSTGRES_PASSWORD=${DB_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data networks: - calejo-network volumes: postgres_data: networks: calejo-network: driver: bridge ``` ### Method 2: Manual Installation #### Step 1: Install Dependencies **Ubuntu/Debian**: ```bash # Update system sudo apt update && sudo apt upgrade -y # Install Python and dependencies sudo apt install python3.9 python3.9-pip python3.9-venv postgresql postgresql-contrib # Install system dependencies sudo apt install build-essential libssl-dev libffi-dev ``` **CentOS/RHEL**: ```bash # Install Python and dependencies sudo yum install python39 python39-pip postgresql postgresql-server # Install system dependencies sudo yum install gcc openssl-devel libffi-devel ``` #### Step 2: Set Up PostgreSQL ```bash # Initialize PostgreSQL sudo postgresql-setup initdb sudo systemctl start postgresql sudo systemctl enable postgresql # Create database and user sudo -u postgres psql -c "CREATE DATABASE calejo;" sudo -u postgres psql -c "CREATE USER control_reader WITH PASSWORD 'secure_password';" sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE calejo TO control_reader;" ``` #### Step 3: Install Application ```bash # Clone repository git clone https://github.com/calejo/control-adapter.git cd control-adapter # Create virtual environment python3.9 -m venv venv source venv/bin/activate # Install dependencies pip install --upgrade pip pip install -r requirements.txt # Install application in development mode pip install -e . ``` #### Step 4: Configure Application ```bash # Copy configuration template cp config/.env.example .env # Edit configuration nano .env ``` #### Step 5: Run Application ```bash # Run in development mode python -m src.main # Or run with production settings python -m src.main --config production.yml ``` ### Method 3: Kubernetes Deployment #### Prerequisites - Kubernetes cluster 1.24+ - Helm 3.8+ - Persistent volume provisioner #### Helm Chart Installation 1. **Add Helm repository**: ```bash helm repo add calejo https://charts.calejo.com helm repo update ``` 2. **Create values file**: ```yaml # values-production.yaml image: repository: calejo/control-adapter tag: latest pullPolicy: Always database: enabled: true postgresql: auth: username: control_reader password: "${DB_PASSWORD}" service: type: LoadBalancer ports: - name: opcua port: 4840 targetPort: 4840 - name: modbus port: 502 targetPort: 502 - name: rest-api port: 8080 targetPort: 8080 ingress: enabled: true hosts: - host: control-adapter.calejo.com paths: - path: / pathType: Prefix ``` 3. **Install chart**: ```bash helm install calejo-control-adapter calejo/control-adapter \ --namespace calejo \ --create-namespace \ --values values-production.yaml ``` ## Configuration ### Environment Variables #### Database Configuration ```bash # Database connection DATABASE_URL=postgresql://control_reader:secure_password@localhost:5432/calejo DB_MIN_CONNECTIONS=5 DB_MAX_CONNECTIONS=20 DB_QUERY_TIMEOUT=30 ``` #### Protocol Configuration ```bash # OPC UA Server OPC_UA_ENDPOINT=opc.tcp://0.0.0.0:4840 OPC_UA_SECURITY_POLICY=Basic256Sha256 # Modbus TCP Server MODBUS_HOST=0.0.0.0 MODBUS_PORT=502 MODBUS_MAX_CONNECTIONS=100 # REST API Server REST_API_HOST=0.0.0.0 REST_API_PORT=8080 REST_API_CORS_ORIGINS=https://dashboard.calejo.com ``` #### Safety Configuration ```bash # Safety framework SAFETY_TIMEOUT_SECONDS=1200 EMERGENCY_STOP_TIMEOUT=300 MAX_SPEED_CHANGE_HZ_PER_MIN=30 # Default safety limits DEFAULT_MIN_SPEED_HZ=20.0 DEFAULT_MAX_SPEED_HZ=50.0 ``` #### Security Configuration ```bash # Authentication JWT_SECRET_KEY=your-secure-secret-key-change-in-production JWT_ALGORITHM=HS256 JWT_TOKEN_EXPIRE_MINUTES=60 # Audit logging AUDIT_LOG_ENABLED=true AUDIT_LOG_RETENTION_DAYS=365 ``` #### Monitoring Configuration ```bash # Health monitoring HEALTH_MONITOR_PORT=8081 HEALTH_CHECK_INTERVAL=30 # Alert system ALERT_EMAIL_ENABLED=true ALERT_SMS_ENABLED=false ALERT_WEBHOOK_ENABLED=true ``` ### Configuration Files #### YAML Configuration ```yaml # config/production.yml app: name: "Calejo Control Adapter" version: "2.0.0" environment: "production" database: url: "${DATABASE_URL}" pool_size: 10 max_overflow: 20 pool_timeout: 30 protocols: opcua: endpoint: "opc.tcp://0.0.0.0:4840" security_policies: - "Basic256Sha256" - "Aes256Sha256RsaPss" modbus: host: "0.0.0.0" port: 502 max_connections: 100 rest_api: host: "0.0.0.0" port: 8080 cors_origins: - "https://dashboard.calejo.com" safety: timeout_seconds: 1200 emergency_stop_timeout: 300 default_limits: min_speed_hz: 20.0 max_speed_hz: 50.0 max_speed_change: 30.0 security: jwt_secret: "${JWT_SECRET_KEY}" token_expire_minutes: 60 audit_log_enabled: true ``` #### Database Schema Configuration ```sql -- Safety limits table CREATE TABLE safety_limits ( station_id VARCHAR(50) NOT NULL, pump_id VARCHAR(50) NOT NULL, hard_min_speed_hz DECIMAL(5,2) NOT NULL, hard_max_speed_hz DECIMAL(5,2) NOT NULL, hard_min_level_m DECIMAL(6,2), hard_max_level_m DECIMAL(6,2), hard_max_power_kw DECIMAL(8,2), max_speed_change_hz_per_min DECIMAL(5,2) NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (station_id, pump_id) ); -- Emergency stop status table CREATE TABLE emergency_stop_status ( station_id VARCHAR(50) NOT NULL, pump_id VARCHAR(50), active BOOLEAN NOT NULL DEFAULT FALSE, activated_at TIMESTAMP, activated_by VARCHAR(100), reason TEXT, PRIMARY KEY (station_id, COALESCE(pump_id, 'STATION')) ); -- Audit log table CREATE TABLE compliance_audit_log ( id SERIAL PRIMARY KEY, timestamp TIMESTAMP NOT NULL, event_type VARCHAR(50) NOT NULL, severity VARCHAR(20) NOT NULL, user_id VARCHAR(100), station_id VARCHAR(50), pump_id VARCHAR(50), ip_address INET, protocol VARCHAR(20), action VARCHAR(100), resource VARCHAR(200), result VARCHAR(50), reason TEXT, compliance_standard TEXT[], event_data JSONB, app_name VARCHAR(100), app_version VARCHAR(20), environment VARCHAR(20) ); ``` ## Security Configuration ### Certificate Management #### Generate SSL Certificates ```bash # Generate private key openssl genrsa -out server.key 2048 # Generate certificate signing request openssl req -new -key server.key -out server.csr # Generate self-signed certificate openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt # Combine for OPC UA cat server.crt server.key > server.pem ``` #### OPC UA Certificate Configuration ```yaml opcua: certificate: server_cert: "/app/certs/server.pem" server_key: "/app/certs/server.key" ca_cert: "/app/certs/ca.crt" security: mode: "SignAndEncrypt" policy: "Basic256Sha256" ``` ### User Management #### Default Users ```python # Default user configuration default_users = [ { "user_id": "admin_001", "username": "admin", "email": "admin@calejo.com", "role": "administrator", "password": "${ADMIN_PASSWORD}" }, { "user_id": "operator_001", "username": "operator", "email": "operator@calejo.com", "role": "operator", "password": "${OPERATOR_PASSWORD}" } ] ``` #### Password Policy ```yaml security: password_policy: min_length: 12 require_uppercase: true require_lowercase: true require_numbers: true require_special_chars: true max_age_days: 90 ``` ## Network Configuration ### Firewall Configuration #### Required Ports | Port | Protocol | Purpose | Security | |------|----------|---------|----------| | 4840 | TCP | OPC UA Server | Internal/Trusted | | 502 | TCP | Modbus TCP | Internal/Trusted | | 8080 | TCP | REST API | Internal/Trusted | | 8081 | TCP | Health Monitor | Internal | | 5432 | TCP | PostgreSQL | Internal | #### Example iptables Rules ```bash # Allow OPC UA iptables -A INPUT -p tcp --dport 4840 -s 192.168.1.0/24 -j ACCEPT # Allow Modbus TCP iptables -A INPUT -p tcp --dport 502 -s 10.0.0.0/8 -j ACCEPT # Allow REST API iptables -A INPUT -p tcp --dport 8080 -s 172.16.0.0/12 -j ACCEPT # Default deny iptables -A INPUT -j DROP ``` ### Network Segmentation #### Recommended Architecture ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ SCADA Zone │ │ Control Adapter │ │ Database Zone │ │ │ │ │ │ │ │ - Siemens WinCC │◄──►│ - OPC UA Server │◄──►│ - PostgreSQL │ │ - EcoStruxure │ │ - Modbus Server │ │ - Redis Cache │ │ - FactoryTalk │ │ - REST API │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ ▼ ▼ ▼ 192.168.1.0/24 172.16.1.0/24 10.0.1.0/24 ``` ## Performance Tuning ### Database Optimization #### PostgreSQL Configuration ```sql -- Performance tuning ALTER SYSTEM SET shared_buffers = '2GB'; ALTER SYSTEM SET work_mem = '64MB'; ALTER SYSTEM SET maintenance_work_mem = '512MB'; ALTER SYSTEM SET effective_cache_size = '6GB'; ALTER SYSTEM SET random_page_cost = 1.1; -- Restart PostgreSQL SELECT pg_reload_conf(); ``` #### Index Optimization ```sql -- Create performance indexes CREATE INDEX idx_audit_log_timestamp ON compliance_audit_log(timestamp); CREATE INDEX idx_audit_log_event_type ON compliance_audit_log(event_type); CREATE INDEX idx_safety_limits_station ON safety_limits(station_id, pump_id); ``` ### Application Tuning #### Connection Pooling ```yaml database: pool_size: 20 max_overflow: 40 pool_recycle: 3600 pool_timeout: 30 ``` #### Protocol Performance ```yaml protocols: opcua: subscription_interval: 1000 # ms publishing_interval: 1000 # ms modbus: response_timeout: 5 # seconds byte_timeout: 1 # seconds rest_api: compression_enabled: true cache_timeout: 60 # seconds ``` ## Verification & Testing ### Health Checks #### Application Health ```bash # Check REST API health curl http://localhost:8080/api/v1/health # Check OPC UA connectivity opcua-client connect opc.tcp://localhost:4840 # Check Modbus connectivity modbus-tcp read 127.0.0.1 502 40001 10 ``` #### Database Connectivity ```bash # Test database connection psql "${DATABASE_URL}" -c "SELECT version();" # Check database health psql "${DATABASE_URL}" -c "SELECT count(*) FROM safety_limits;" ``` ### Smoke Tests #### Run Basic Tests ```bash # Run smoke tests python -m pytest tests/deployment/smoke_tests.py -v # Run all tests python -m pytest tests/ -v ``` #### Verify Protocols ```bash # Test OPC UA server python tests/integration/test_opcua_integration.py # Test Modbus server python tests/integration/test_modbus_integration.py # Test REST API python tests/integration/test_rest_api_integration.py ``` ## Troubleshooting ### Common Issues #### Database Connection Issues - **Error**: "Connection refused" - **Solution**: Verify PostgreSQL is running and accessible - **Check**: `systemctl status postgresql` #### Protocol Server Issues - **Error**: "Port already in use" - **Solution**: Check for conflicting services - **Check**: `netstat -tulpn | grep :4840` #### Security Issues - **Error**: "JWT token invalid" - **Solution**: Verify JWT_SECRET_KEY is set correctly - **Check**: Environment variable configuration ### Log Analysis #### Application Logs ```bash # View application logs docker-compose logs control-adapter # View specific component logs docker-compose logs control-adapter | grep "safety" # Monitor real-time logs docker-compose logs -f control-adapter ``` #### Database Logs ```bash # View PostgreSQL logs sudo tail -f /var/log/postgresql/postgresql-*.log # Check database performance psql "${DATABASE_URL}" -c "SELECT * FROM pg_stat_activity;" ``` --- *This installation and configuration guide provides comprehensive instructions for deploying the Calejo Control Adapter in various environments. Always test configurations in a staging environment before deploying to production.*