Add scripts for autoconfig system

This commit is contained in:
2026-01-26 21:30:50 +03:00
parent 9f38bbcf9d
commit 9cfc348965
9 changed files with 877 additions and 3 deletions

View File

@@ -49,9 +49,11 @@ pip install -r requirements.txt
# Проверка доступных интерфейсов
ip link show
# Настройка интерфейса (пример)
sudo ip link set can0 type can bitrate 500000
# Настройка интерфейса (пример для 1Mbps)
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up
sudo ip link set can1 type can bitrate 1000000
sudo ip link set can1 up
```
### 4. Конфигурация
@@ -82,7 +84,33 @@ sudo ip link set can0 up
}
```
## 🎮 Использование
## Deployment (Raspberry Pi 5)
Для автоматического запуска на Raspberry Pi 5 с 2-CH CAN HAT используйте скрипты из `deploy/`:
```bash
# Установка с автозапуском через systemd
cd deploy
sudo ./install.sh
```
Установщик автоматически:
- Настроит CAN интерфейсы при загрузке (`can-setup.service`)
- Запустит sniffer как systemd сервис (`can-sniffer.service`)
- Создаст директории для данных и логов в `/opt/can_sniffer/`
Подробная документация: [deploy/README.md](deploy/README.md)
```bash
# Управление сервисом
sudo systemctl status can-sniffer
sudo journalctl -u can-sniffer -f
# Диагностика
sudo ./deploy/diagnose.sh
```
## Использование
### Базовый запуск

View File

@@ -0,0 +1,238 @@
# CAN Sniffer Deployment for Raspberry Pi 5
Автоматическое развёртывание CAN Sniffer с systemd на Raspberry Pi 5 с 2-CH CAN HAT.
## Архитектура
```
Boot
systemd-modules-load (SPI модули)
can-setup.service (OneShot)
│ - ip link set can0 type can bitrate 1000000
│ - ip link set can0 up
│ - ip link set can1 type can bitrate 1000000
│ - ip link set can1 up
can-sniffer.service
│ - python main.py
│ - Чтение CAN → SQLite → PostgreSQL
Running...
```
## Требования
### Hardware
- Raspberry Pi 5
- 2-CH CAN HAT (MCP2515 или MCP251xFD)
### Software
- Raspberry Pi OS Bookworm (64-bit recommended)
- Python 3.11+
- Настроенный overlay для CAN HAT
## Настройка CAN HAT
Перед установкой убедитесь, что CAN HAT настроен в `/boot/firmware/config.txt`:
### Для MCP2515 (стандартный CAN):
```ini
# Enable SPI
dtparam=spi=on
# Waveshare 2-CH CAN HAT (MCP2515)
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=mcp2515-can1,oscillator=16000000,interrupt=24
```
### Для MCP251xFD (CAN FD):
```ini
# Enable SPI
dtparam=spi=on
# Waveshare 2-CH CAN FD HAT (MCP251xFD)
dtoverlay=mcp251xfd,spi0-0,oscillator=40000000,interrupt=25
dtoverlay=mcp251xfd,spi0-1,oscillator=40000000,interrupt=24
```
После изменения config.txt требуется перезагрузка:
```bash
sudo reboot
```
Проверка после перезагрузки:
```bash
ip link show | grep can
# Должны появиться can0 и can1
```
## Установка
### 1. Клонирование репозитория
```bash
cd /home/pi
git clone https://github.com/your-repo/carpibord.git
cd carpibord/can_sniffer/deploy
```
### 2. Запуск установщика
```bash
sudo ./install.sh
```
Установщик автоматически:
- Проверит зависимости (python3, can-utils)
- Создаст директории `/opt/can_sniffer/{data,logs}`
- Установит Python venv и зависимости
- Скопирует production конфиг
- Установит systemd сервисы
- Включит автозапуск
### 3. Проверка статуса
```bash
sudo systemctl status can-setup
sudo systemctl status can-sniffer
```
## Конфигурация
### Основной конфиг
```bash
sudo nano /opt/can_sniffer/src/config.json
```
### Переопределение через environment
Редактируйте `/etc/default/can-sniffer`:
```bash
# CAN interfaces (для can-setup.service)
CAN_INTERFACES="can0 can1"
CAN_BITRATE=1000000
# Переопределение config.json (для can-sniffer.service)
CAN_SNIFFER_CAN__INTERFACES="can0,can1"
CAN_SNIFFER_POSTGRESQL__HOST="192.168.1.100"
CAN_SNIFFER_LOGGING__LEVEL="DEBUG"
```
После изменений:
```bash
sudo systemctl restart can-sniffer
```
## Управление сервисами
```bash
# Статус
sudo systemctl status can-sniffer
sudo systemctl status can-setup
# Запуск/остановка
sudo systemctl start can-sniffer
sudo systemctl stop can-sniffer
# Перезапуск
sudo systemctl restart can-sniffer
# Просмотр логов
sudo journalctl -u can-sniffer -f
sudo journalctl -u can-sniffer --since "1 hour ago"
# Логи приложения
tail -f /opt/can_sniffer/logs/can_edge.log
```
## Диагностика
### Проверка CAN интерфейсов
```bash
# Статус интерфейсов
ip -details link show can0
ip -details link show can1
# Статистика
ip -s link show can0
# Прослушивание (can-utils)
candump can0 can1
```
### Частые проблемы
#### 1. CAN интерфейсы не появляются
```bash
# Проверить overlay
dmesg | grep -i can
dmesg | grep -i mcp
# Проверить SPI
ls /dev/spidev*
```
#### 2. Ошибка "Network is down"
```bash
# Перезапустить can-setup
sudo systemctl restart can-setup
sudo ip link show can0
```
#### 3. Ошибка доступа к CAN сокету
```bash
# Проверить capabilities в systemd
sudo journalctl -u can-sniffer | grep -i denied
# Или запустить вручную для теста
sudo /opt/can_sniffer/venv/bin/python /opt/can_sniffer/src/main.py
```
#### 4. PostgreSQL недоступен
```bash
# Sniffer работает offline-first, данные сохраняются локально
# Проверить SQLite
ls -la /opt/can_sniffer/data/
# Синхронизация произойдёт автоматически когда PostgreSQL станет доступен
```
## Удаление
```bash
sudo ./uninstall.sh
```
## Структура файлов
```
/opt/can_sniffer/
├── src/
│ ├── main.py # Entry point
│ ├── config.py # Configuration
│ ├── config.json # Production config
│ └── ...
├── venv/ # Python virtual environment
├── data/
│ └── can_offline.db # SQLite database
├── logs/
│ └── can_edge.log # Application logs
└── requirements.txt
/etc/systemd/system/
├── can-setup.service # CAN interface setup (OneShot)
└── can-sniffer.service # Main application service
/etc/default/
└── can-sniffer # Environment overrides
```
## Security Notes
- Сервис запускается от пользователя `pi` (не root)
- Используется `ProtectSystem=strict` для защиты файловой системы
- Capabilities ограничены `CAP_NET_RAW` и `CAP_NET_ADMIN` для CAN
- Пароль PostgreSQL в config.json - рассмотрите использование secrets

View File

@@ -0,0 +1,49 @@
[Unit]
Description=Setup CAN bus interfaces for 2ch CAN HAT
Documentation=https://github.com/carpibord
After=network-pre.target
Before=network.target
Wants=network-pre.target
# Ждём пока kernel загрузит модули для CAN HAT
# MCP2515/MCP251xFD появляются после загрузки SPI overlay
After=systemd-modules-load.service
Requires=systemd-modules-load.service
[Service]
Type=oneshot
RemainAfterExit=yes
# Настройка CAN интерфейсов
# Bitrate: 1000000 (1Mbps) - стандарт для автомобильной CAN шины
# Можно изменить через /etc/default/can-sniffer
EnvironmentFile=-/etc/default/can-sniffer
ExecStartPre=/usr/bin/sleep 2
ExecStart=/bin/bash -c '\
for iface in ${CAN_INTERFACES:-can0 can1}; do \
if ip link show "$iface" > /dev/null 2>&1; then \
/sbin/ip link set "$iface" down 2>/dev/null || true; \
/sbin/ip link set "$iface" type can bitrate ${CAN_BITRATE:-1000000}; \
/sbin/ip link set "$iface" up; \
echo "CAN interface $iface configured at ${CAN_BITRATE:-1000000} bps"; \
else \
echo "Warning: CAN interface $iface not found"; \
fi; \
done'
ExecStop=/bin/bash -c '\
for iface in ${CAN_INTERFACES:-can0 can1}; do \
if ip link show "$iface" > /dev/null 2>&1; then \
/sbin/ip link set "$iface" down 2>/dev/null || true; \
echo "CAN interface $iface stopped"; \
fi; \
done'
# Логирование через journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=can-setup
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,24 @@
# /etc/default/can-sniffer
# Переменные окружения для can-setup.service и can-sniffer.service
# === CAN Interface Setup ===
# Список интерфейсов через пробел
CAN_INTERFACES="can0 can1"
# Bitrate (бит/с) - должен совпадать с настройками автомобиля
# 500000 - стандартный CAN
# 1000000 - CAN FD / High-speed CAN
CAN_BITRATE=1000000
# === CAN Sniffer Overrides ===
# Эти переменные переопределяют config.json
# Формат: CAN_SNIFFER_<SECTION>__<KEY>
# Переопределение интерфейсов (через запятую)
# CAN_SNIFFER_CAN__INTERFACES="can0,can1"
# Переопределение PostgreSQL хоста
# CAN_SNIFFER_POSTGRESQL__HOST="192.168.1.100"
# Переопределение уровня логирования
# CAN_SNIFFER_LOGGING__LEVEL="DEBUG"

View File

@@ -0,0 +1,55 @@
[Unit]
Description=CAN Bus Sniffer - Offline-first CAN data collector
Documentation=https://github.com/carpibord
After=can-setup.service network.target
Requires=can-setup.service
Wants=postgresql.service
# Restart при падении, но не слишком часто
StartLimitIntervalSec=300
StartLimitBurst=5
[Service]
Type=simple
User=pi
Group=pi
# Рабочая директория - где будут создаваться логи и БД
WorkingDirectory=/opt/can_sniffer
Environment=PYTHONUNBUFFERED=1
Environment=PYTHONPATH=/opt/can_sniffer/src
# Загрузка переменных окружения для переопределения конфига
EnvironmentFile=-/etc/default/can-sniffer
# Запуск через venv
ExecStart=/opt/can_sniffer/venv/bin/python /opt/can_sniffer/src/main.py
# Graceful shutdown - отправляем SIGTERM, ждём 30 секунд
# main.py уже обрабатывает SIGTERM через signal handler
TimeoutStopSec=30
KillSignal=SIGTERM
KillMode=mixed
# Автоматический рестарт при падении (но не при ручной остановке)
Restart=on-failure
RestartSec=5
# Логирование через journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=can-sniffer
# Security hardening (RPI5 совместимо)
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=read-only
PrivateTmp=yes
ReadWritePaths=/opt/can_sniffer/data /opt/can_sniffer/logs
# Разрешаем доступ к CAN сокетам
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,50 @@
{
"can": {
"interfaces": ["can0", "can1"],
"listen_only": true,
"bitrate": 1000000,
"filters": []
},
"storage": {
"type": "sqlite",
"database_path": "/opt/can_sniffer/data/can_offline.db",
"wal_mode": true,
"sync_mode": "NORMAL",
"retention_days": 7
},
"postgresql": {
"enabled": true,
"host": "100.74.164.1",
"port": 5433,
"database": "carpibord",
"user": "carpibord",
"password": "carpibord",
"batch_size": 10000,
"flush_interval": 5,
"max_retries": 3,
"retry_backoff": 1.0,
"connection_pool_size": 5,
"connection_timeout": 10,
"sync_interval": 30.0
},
"flipper": {
"enabled": false,
"device": "/dev/ttyAMA0",
"baudrate": 115200,
"send_interval": 1.0
},
"logging": {
"level": "INFO",
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
"file": "/opt/can_sniffer/logs/can_edge.log",
"max_bytes": 10485760,
"backup_count": 5
},
"general": {
"buffer_size": 100000,
"batch_size": 10000,
"batch_interval": 0.1,
"max_retries": 3,
"retry_delay": 1.0
}
}

View File

@@ -0,0 +1,173 @@
#!/bin/bash
#
# CAN Sniffer Diagnostic Script
# Проверяет состояние системы и выводит полезную информацию для отладки
#
set -e
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
section() { echo -e "\n${BLUE}=== $1 ===${NC}"; }
ok() { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
fail() { echo -e "${RED}[FAIL]${NC} $1"; }
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ CAN Sniffer Diagnostic Report ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
echo "Date: $(date)"
echo "Host: $(hostname)"
section "System Info"
echo "OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "Kernel: $(uname -r)"
echo "Architecture: $(uname -m)"
if [[ -f /proc/device-tree/model ]]; then
echo "Model: $(cat /proc/device-tree/model)"
fi
section "CAN Kernel Modules"
if lsmod | grep -q "can"; then
lsmod | grep can
ok "CAN modules loaded"
else
fail "No CAN modules loaded"
echo " Try: modprobe can can_raw"
fi
section "SPI Status"
if ls /dev/spidev* 2>/dev/null; then
ok "SPI devices found"
else
warn "No SPI devices found"
echo " Check: dtparam=spi=on in /boot/firmware/config.txt"
fi
section "CAN Interfaces"
CAN_FOUND=0
for iface in can0 can1; do
if ip link show "$iface" &>/dev/null; then
CAN_FOUND=1
STATE=$(ip link show "$iface" | grep -oP '(?<=state )\w+')
if [[ "$STATE" == "UP" ]]; then
ok "$iface: UP"
else
warn "$iface: $STATE"
fi
# Детали интерфейса
ip -details link show "$iface" 2>/dev/null | grep -E "bitrate|state|mtu" | head -3 | sed 's/^/ /'
else
fail "$iface: NOT FOUND"
fi
done
if [[ $CAN_FOUND -eq 0 ]]; then
warn "No CAN interfaces found"
echo " Check CAN HAT overlay in /boot/firmware/config.txt"
echo " Run: dmesg | grep -i mcp"
fi
section "CAN Statistics"
for iface in can0 can1; do
if ip link show "$iface" &>/dev/null; then
echo "$iface:"
ip -s link show "$iface" 2>/dev/null | grep -E "RX:|TX:|errors" | sed 's/^/ /'
fi
done
section "Systemd Services"
for svc in can-setup can-sniffer; do
if systemctl is-enabled "$svc" &>/dev/null; then
STATUS=$(systemctl is-active "$svc" 2>/dev/null || echo "inactive")
if [[ "$STATUS" == "active" ]]; then
ok "$svc: $STATUS (enabled)"
else
warn "$svc: $STATUS (enabled)"
fi
else
fail "$svc: not installed or disabled"
fi
done
section "Application Status"
INSTALL_DIR="/opt/can_sniffer"
if [[ -d "$INSTALL_DIR" ]]; then
ok "Installation directory exists: $INSTALL_DIR"
# Check venv
if [[ -f "$INSTALL_DIR/venv/bin/python" ]]; then
ok "Python venv exists"
PYTHON_VERSION=$("$INSTALL_DIR/venv/bin/python" --version 2>&1)
echo " $PYTHON_VERSION"
else
fail "Python venv missing"
fi
# Check config
if [[ -f "$INSTALL_DIR/src/config.json" ]]; then
ok "Config file exists"
else
fail "Config file missing"
fi
# Check data directory
if [[ -d "$INSTALL_DIR/data" ]]; then
ok "Data directory exists"
if [[ -f "$INSTALL_DIR/data/can_offline.db" ]]; then
DB_SIZE=$(du -h "$INSTALL_DIR/data/can_offline.db" | cut -f1)
echo " SQLite DB size: $DB_SIZE"
fi
else
warn "Data directory missing"
fi
# Check logs
if [[ -d "$INSTALL_DIR/logs" ]]; then
ok "Logs directory exists"
if [[ -f "$INSTALL_DIR/logs/can_edge.log" ]]; then
LOG_SIZE=$(du -h "$INSTALL_DIR/logs/can_edge.log" | cut -f1)
echo " Log file size: $LOG_SIZE"
fi
fi
else
fail "Installation directory not found: $INSTALL_DIR"
fi
section "Recent Logs (last 10 lines)"
if systemctl is-active can-sniffer &>/dev/null; then
journalctl -u can-sniffer --no-pager -n 10 2>/dev/null || echo " (no logs available)"
else
echo " Service not running"
fi
section "Process Check"
if pgrep -f "can_sniffer.*main.py" > /dev/null; then
ok "CAN Sniffer process running"
ps aux | grep "[c]an_sniffer.*main.py" | sed 's/^/ /'
else
warn "CAN Sniffer process not running"
fi
section "Network (PostgreSQL target)"
# Извлекаем хост из конфига
if [[ -f "$INSTALL_DIR/src/config.json" ]]; then
PG_HOST=$(grep -oP '"host":\s*"\K[^"]+' "$INSTALL_DIR/src/config.json" | head -1)
PG_PORT=$(grep -oP '"port":\s*\K\d+' "$INSTALL_DIR/src/config.json" | head -1)
if [[ -n "$PG_HOST" ]]; then
echo "PostgreSQL target: $PG_HOST:${PG_PORT:-5432}"
if timeout 2 bash -c "echo >/dev/tcp/$PG_HOST/${PG_PORT:-5432}" 2>/dev/null; then
ok "PostgreSQL port reachable"
else
warn "PostgreSQL port not reachable (offline mode active)"
fi
fi
fi
section "dmesg CAN/SPI Errors (last 5)"
dmesg | grep -iE "(can|mcp|spi).*error" | tail -5 || echo " (no errors found)"
echo -e "\n${BLUE}=== Diagnostic Complete ===${NC}\n"

View File

@@ -0,0 +1,198 @@
#!/bin/bash
#
# CAN Sniffer Installation Script for Raspberry Pi 5
# Устанавливает сервисы автозапуска для can_sniffer
#
set -e
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Проверка root прав
if [[ $EUID -ne 0 ]]; then
log_error "Этот скрипт должен запускаться с правами root"
echo "Используйте: sudo $0"
exit 1
fi
# Определение директорий
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
INSTALL_DIR="/opt/can_sniffer"
DATA_DIR="$INSTALL_DIR/data"
LOGS_DIR="$INSTALL_DIR/logs"
SYSTEMD_DIR="/etc/systemd/system"
log_info "=== CAN Sniffer Installation ==="
log_info "Source: $PROJECT_DIR"
log_info "Target: $INSTALL_DIR"
# === 1. Проверка системных зависимостей ===
log_info "Checking system dependencies..."
# Проверка python3
if ! command -v python3 &> /dev/null; then
log_error "Python3 not found. Installing..."
apt-get update && apt-get install -y python3 python3-pip python3-venv
fi
# Проверка can-utils (для диагностики)
if ! command -v candump &> /dev/null; then
log_warn "can-utils not found. Installing..."
apt-get update && apt-get install -y can-utils
fi
# === 2. Проверка CAN overlay в config.txt ===
log_info "Checking CAN HAT overlay configuration..."
CONFIG_TXT="/boot/firmware/config.txt"
if [[ ! -f "$CONFIG_TXT" ]]; then
CONFIG_TXT="/boot/config.txt"
fi
if [[ -f "$CONFIG_TXT" ]]; then
# Проверяем наличие MCP2515 overlay (типичный для 2ch CAN HAT)
if ! grep -q "mcp2515" "$CONFIG_TXT" && ! grep -q "mcp251xfd" "$CONFIG_TXT"; then
log_warn "CAN HAT overlay not found in $CONFIG_TXT"
log_warn "You may need to add overlay for your CAN HAT. Example for MCP2515:"
echo ""
echo " # For Waveshare 2-CH CAN HAT:"
echo " dtparam=spi=on"
echo " dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25"
echo " dtoverlay=mcp2515-can1,oscillator=16000000,interrupt=24"
echo ""
echo " # Or for MCP251xFD (CAN FD):"
echo " dtparam=spi=on"
echo " dtoverlay=mcp251xfd,spi0-0,oscillator=40000000,interrupt=25"
echo " dtoverlay=mcp251xfd,spi0-1,oscillator=40000000,interrupt=24"
echo ""
read -p "Continue installation anyway? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
else
log_info "CAN HAT overlay found in config.txt"
fi
fi
# === 3. Создание директорий ===
log_info "Creating directories..."
mkdir -p "$INSTALL_DIR"
mkdir -p "$DATA_DIR"
mkdir -p "$LOGS_DIR"
# === 4. Копирование файлов проекта ===
log_info "Copying project files..."
# Копируем src
cp -r "$PROJECT_DIR/src" "$INSTALL_DIR/"
# Копируем requirements.txt
cp "$PROJECT_DIR/requirements.txt" "$INSTALL_DIR/"
# Копируем production config как основной
cp "$SCRIPT_DIR/config.production.json" "$INSTALL_DIR/src/config.json"
# === 5. Создание виртуального окружения ===
log_info "Creating Python virtual environment..."
if [[ ! -d "$INSTALL_DIR/venv" ]]; then
python3 -m venv "$INSTALL_DIR/venv"
fi
# Устанавливаем зависимости
log_info "Installing Python dependencies..."
"$INSTALL_DIR/venv/bin/pip" install --upgrade pip
"$INSTALL_DIR/venv/bin/pip" install -r "$INSTALL_DIR/requirements.txt"
# === 6. Настройка прав доступа ===
log_info "Setting permissions..."
# Определяем пользователя (pi или текущий sudo user)
if id "pi" &>/dev/null; then
SERVICE_USER="pi"
else
SERVICE_USER="${SUDO_USER:-root}"
fi
log_info "Service will run as user: $SERVICE_USER"
chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
chmod -R 755 "$INSTALL_DIR"
chmod 700 "$DATA_DIR"
chmod 755 "$LOGS_DIR"
# Добавляем пользователя в группы для доступа к CAN и UART
usermod -aG dialout "$SERVICE_USER" 2>/dev/null || true
usermod -aG plugdev "$SERVICE_USER" 2>/dev/null || true
# === 7. Установка systemd сервисов ===
log_info "Installing systemd services..."
# Обновляем user в service файле
sed "s/User=pi/User=$SERVICE_USER/g; s/Group=pi/Group=$SERVICE_USER/g" \
"$SCRIPT_DIR/can-sniffer.service" > "$SYSTEMD_DIR/can-sniffer.service"
# Копируем can-setup service
cp "$SCRIPT_DIR/can-setup.service" "$SYSTEMD_DIR/"
# Копируем environment file
cp "$SCRIPT_DIR/can-sniffer.env" "/etc/default/can-sniffer"
# Перезагрузка systemd
systemctl daemon-reload
# === 8. Включение сервисов ===
log_info "Enabling services..."
systemctl enable can-setup.service
systemctl enable can-sniffer.service
# === 9. Итоговая информация ===
echo ""
log_info "=== Installation Complete ==="
echo ""
echo "Installed components:"
echo " - CAN Setup Service: $SYSTEMD_DIR/can-setup.service"
echo " - CAN Sniffer Service: $SYSTEMD_DIR/can-sniffer.service"
echo " - Environment config: /etc/default/can-sniffer"
echo " - Application: $INSTALL_DIR"
echo " - Data directory: $DATA_DIR"
echo " - Logs directory: $LOGS_DIR"
echo ""
echo "Configuration:"
echo " - Main config: $INSTALL_DIR/src/config.json"
echo " - Edit /etc/default/can-sniffer to override settings"
echo ""
echo "Commands:"
echo " sudo systemctl start can-setup # Start CAN interfaces"
echo " sudo systemctl start can-sniffer # Start sniffer"
echo " sudo systemctl status can-sniffer # Check status"
echo " sudo journalctl -u can-sniffer -f # View logs"
echo ""
echo "To start now (without reboot):"
echo " sudo systemctl start can-setup && sudo systemctl start can-sniffer"
echo ""
# Спрашиваем о немедленном запуске
read -p "Start services now? [y/N] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "Starting services..."
systemctl start can-setup
sleep 2
systemctl start can-sniffer
sleep 1
systemctl status can-sniffer --no-pager
fi
log_info "Done!"

View File

@@ -0,0 +1,59 @@
#!/bin/bash
#
# CAN Sniffer Uninstallation Script
#
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}[ERROR]${NC} Run with sudo"
exit 1
fi
INSTALL_DIR="/opt/can_sniffer"
SYSTEMD_DIR="/etc/systemd/system"
log_info "=== CAN Sniffer Uninstallation ==="
# Остановка сервисов
log_info "Stopping services..."
systemctl stop can-sniffer 2>/dev/null || true
systemctl stop can-setup 2>/dev/null || true
# Отключение сервисов
log_info "Disabling services..."
systemctl disable can-sniffer 2>/dev/null || true
systemctl disable can-setup 2>/dev/null || true
# Удаление systemd файлов
log_info "Removing systemd files..."
rm -f "$SYSTEMD_DIR/can-sniffer.service"
rm -f "$SYSTEMD_DIR/can-setup.service"
rm -f "/etc/default/can-sniffer"
systemctl daemon-reload
# Спрашиваем про удаление данных
echo ""
read -p "Remove application data ($INSTALL_DIR/data)? [y/N] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_warn "Removing data directory..."
rm -rf "$INSTALL_DIR/data"
fi
read -p "Remove entire installation ($INSTALL_DIR)? [y/N] " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_warn "Removing installation directory..."
rm -rf "$INSTALL_DIR"
fi
log_info "Uninstallation complete!"