# GPIO Monitor Dashboard for Raspberry Pi Реалтайм мониторинг параллельной GPIO-шины Raspberry Pi через C + Go + Web Dashboard. Проект читает входящие сигналы с GPIO-пинов Raspberry Pi по прерыванию, передаёт данные через FIFO pipe в Go-сервер и отображает всё в браузере в реальном времени с возможностью просмотра исторических данных. --- ## Возможности ✅ Захват данных по GPIO interrupt (C + WiringPi) ✅ FIFO pipe, а также stdin/stdout между C + WiringPi и Go Service ✅ Реализация кольцевого буфера чтения ✅ HTTP API + Web Dashboard ✅ **Автоматическая ротация** лог-файлов ✅ **Retention** (автоматическая очистка старых логов) ✅ **Watchdog** мониторинг активности ✅ **MJPEG камера** через go2rtc ✅ TypeScript фронтенд ✅ Работа через Wi-Fi Access Point --- ## Архитектура ```text GPIO BUS (8 bit) ↓ gpio-interrupt.c (C + WiringPi) ↓ stdout FIFO pipe (/tmp/gpio_pipe) ↓ Go Server (gpio-monitor-server) ├── RingBuffer (RAM) ├── Data Logger (бинарные .bin файлы) ├── Human Logger (текстовые логи) ├── Event Logger (события системы) ├── Watchdog (мониторинг) └── Retention (очистка старых логов) ↓ HTTP API (:8080) ├── /api/health - статус сервера ├── /api/latest - последние данные ├── /api/history - история (последние 100) ├── /api/stream - статус камеры ├── /api/cam - MJPEG поток ├── /api/log/files - список лог-файлов ├── /api/log/data - данные из лог-файла └── /api/log/events - события системы ↓ Web Dashboard (Embedded) ├── index.html ├── dashboard.html (главная) ├── logs.html (просмотр логов) ├── css/style.css ├── js/*.ts (TypeScript исходники) └── dist/*.js (скомпилированный JS) ``` --- ## Структура проекта ``` . ├── build/ │ └── gpio-monitor-server # Скомпилированный бинарник ├── build.sh # Скрипт сборки (Go + TypeScript) ├── cmd/server/ │ ├── main.go # Go HTTP сервер │ └── web/ # Веб-интерфейс │ ├── css/style.css │ ├── dist/ # Скомпилированный JS │ │ ├── app.js │ │ ├── chart.js │ │ ├── data.js │ │ └── ... │ ├── js/ # TypeScript исходники │ │ ├── app.ts │ │ ├── chart.ts │ │ ├── data.ts │ │ └── ... │ ├── dashboard.html │ ├── index.html │ ├── logs.html │ ├── favicon.png │ ├── package.json │ ├── tsconfig.json │ └── README.md ├── internal/ │ ├── adapter/buffer.go # RingBuffer │ ├── logger/ # Система логирования │ │ ├── config.go │ │ ├── data_logger.go # Бинарные логи │ │ ├── event_logger.go # События │ │ ├── human_logger.go # Человекочитаемые логи │ │ ├── monitor.go # Watchdog │ │ ├── parser.go # Парсер данных GPIO │ │ ├── paths.go # Пути к файлам │ │ ├── retention.go # Очистка старых логов │ │ └── rotation.go # Ротация файлов │ └── pipe/reader.go # Чтение из FIFO pipe ├── scripts/ │ ├── monitor-gpio.service # Systemd сервис │ ├── monitor-gpio.socket # Systemd socket │ ├── go2rtc # Бинарник go2rtc │ ├── go2rtc.yaml # Конфиг go2rtc │ ├── view_logs.sh # Скрипт просмотра логов │ ├── emulator.py # Эмулятор GPIO │ └── imi_wire.py # IMI Wire эмулятор ├── SDR/ # SDR компоненты │ ├── common.c/h │ ├── reciever.c │ ├── transmitter.c │ └── makefile ├── go.mod ├── start-server.sh └── README.md ``` ## GPIO пины ``` WR/STROBE = GPIO27 DATA BUS: D0 = GPIO21 D1 = GPIO7 D2 = GPIO6 D3 = GPIO5 D4 = GPIO25 D5 = GPIO24 D6 = GPIO23 D7 = GPIO22 ``` --- ## Установка ### 1. Установка зависимостей ```bash sudo apt update sudo apt install -y golang git build-essential wiringpi nodejs npm alsa-utils ``` > `alsa-utils` нужен для монитора уровня звука (использует `arecord`). Проверить, что микрофон виден системе: > ```bash > arecord -l > # **** List of CAPTURE Hardware Devices **** > # card 3: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio] > ``` > Если список пуст — микрофон не подключён или не определился, монитор звука будет отдавать `sound_level: 0`. ### 2. Клонирование и сборка ```bash git clone cd ~/work/golang # Полная подготовка окружения (проверка Node.js, скачивание Go-модулей и npm-пакетов) make init ``` ### 3. Сборка проекта ``` Bash # Скомпилируйте TypeScript-фронтенд и Go-сервер одной командой: make build ``` ### 4. Настройка systemd сервиса Для постоянной работы сервера в фоновом режиме настройте систему инициализации. Поскольку сервер пишет логи в защищенную директорию /var/log/, его запуск и управление осуществляются через systemctl с правами администратора ```bash # Копировать сервисные файлы sudo cp scripts/monitor-gpio.service /etc/systemd/system/ sudo cp scripts/monitor-gpio.socket /etc/systemd/system/ # Перезагрузить systemd sudo systemctl daemon-reload # Включить автозапуск sudo systemctl enable monitor-gpio.socket sudo systemctl enable monitor-gpio.service # Запустить сервис sudo systemctl start monitor-gpio.service ``` ### 4. Проверка статуса ```bash sudo systemctl status monitor-gpio.service journalctl -u monitor-gpio.service -f ``` --- ## Настройка firewall (nftables) **Важно:** На Raspberry Pi OS Bookworm по умолчанию активен nftables, который блокирует все входящие порты, кроме SSH (22). ### Разрешить порт 8080: ```bash # Добавить правило для порта 8080 sudo nft add rule inet filter input tcp dport 8080 accept # Проверить правила sudo nft list ruleset # Сохранить правила (для сохранения после перезагрузки) sudo nft list ruleset | sudo tee /etc/nftables.conf > /dev/null sudo systemctl enable nftables sudo systemctl restart nftables ``` ### Для доступа только с локальной сети: ```bash # Разрешить только с сети 10.1.1.0/24 sudo nft add rule inet filter input ip saddr 10.1.1.0/24 tcp dport 8080 accept # Или только с конкретного IP sudo nft add rule inet filter input ip saddr 192.168.1.100 tcp dport 8080 accept ``` ### Для доступа через Wi-Fi AP: ```bash # Разрешить с Wi-Fi сети (192.168.77.0/24) sudo nft add rule inet filter input iifname "wlan0" tcp dport 8080 accept ``` --- ## Запуск ### Ручной запуск ```bash ./build/gpio-monitor-server \ -pipe /tmp/gpio_pipe \ -retention-hours=72 \ -retention-mb=2000 \ -retention-interval=60 \ -rotation-check-interval=1 \ -buffer-size=10240 \ -human-log-interval=5 ``` ### Параметры командной строки | Параметр | По умолчанию | Описание | |----------|------------------|--------------------| | `-pipe` | `/tmp/gpio_pipe` | Путь к FIFO pipe | | `-port` | `:8080` | Порт веб-сервера | | `-retention-hours` | `48` | Часы хранения логов (0 = отключено) | | `-retention-mb` | `5000` | Максимальный размер логов в MB | | `-retention-interval` | `15` | Интервал проверки retention (мин) | | `-rotation-check-interval` | `1` | Интервал проверки ротации (мин)| | `-buffer-size` | `10240`| Размер кольцевого буфера | | `-human-log-interval` | `5` | Интервал записи human-логов (сек) | | `-alert-cooldown` | `10` | Задержка между алертами (сек) | | `-camera-url` | `http://127.0.0.1:1984/api/stream.mjpeg?src=cam_mjpeg` | URL MJPEG камеры | --- ## Ротация и хранение логов (Retention) Бинарные данные GPIO пишутся в почасовые файлы вида `gpio-YYYY-MM-DD-HH.bin` в директории `internal/logger` (`GetDataLogsDir()`). За это отвечают два независимых механизма: - **Ротация** (`internal/logger/rotation.go`) — каждую минуту (`-rotation-check-interval`) проверяет текущий час и, если он изменился, закрывает старый `.bin`-файл и открывает новый. Ротация только создаёт новые файлы, старые она не трогает. - **Retention** (`internal/logger/retention.go`) — раз в `-retention-interval` минут (плюс один прогон через минуту после старта) удаляет лишние файлы по двум независимым лимитам: возрасту (`-retention-hours`) и суммарному размеру (`-retention-mb`). Любой из лимитов можно отключить, выставив `0`. ### Как работает удаление (FIFO) Очистка идёт по правилам: 1. Все `gpio-*.bin` сортируются от самого старого к самому новому (FIFO-порядок). 2. Файлы удаляются строго с "старого" конца списка, по одному, пока выполняются оба условия: - файл старше порога **и по времени в имени файла, и по реальному времени последней записи (ModTime)** — если файл был записан недавно, но у него "старое" имя (или наоборот), он не считается кандидатом на удаление; - файлов в директории больше `minKeepFiles` (сейчас — 2). 3. Как только встречается первый файл, который не удовлетворяет условиям, очистка останавливается — все файлы правее (более новые) заведомо тоже не подходят под удаление. Итог: Очистка по размеру (`cleanBySize`): удаляет самые старые файлы, пока суммарный объём превышает `-retention-mb`, но тоже не опускается ниже `minKeepFiles`. Дополнительная защита — при разборе имени файла (`parseFilenameTime`) любая ошибка парсинга (битое или неожиданное имя) не считается "нулевым/древним" временем, а приводит к откату на реальный `ModTime` файла с диска, чтобы повреждённое или нестандартное имя не привело к ошибочному удалению. --- ## Dashboard Открывайте в браузере: - **Через Ethernet:** `http://10.1.1.33:8080` (или ваш IP) - **Через Wi-Fi AP:** `http://192.168.77.1:8080` - **Локально:** `http://localhost:8080` ### Страницы - `http://:8080/` - Перенаправление на dashboard - `http://:8080/dashboard.html` - Главная панель мониторинга - `http://:8080/logs.html` - Просмотр исторических логов --- ## API ### Основные эндпоинты ```bash GET /api/health # Статус сервера, uptime, статистика, sound_level (0-100, уровень с микрофона) GET /api/latest # Последние данные и история (10 записей) GET /api/history # Последние 100 записей GET /api/stream # Статус камеры GET /api/cam # MJPEG поток камеры (прокси на go2rtc) ``` ### Работа с логами ```bash GET /api/log/files # Список доступных лог-файлов GET /api/log/data?file=gpio-2026-06-17-11.bin # Данные из конкретного бинарного лога GET /api/log/events?limit=100 # Последние события системы ``` --- ## Диагностика проблем ### Если Dashboard не открывается: 1. **Проверьте, что сервер запущен:** ```bash ps aux | grep gpio-monitor-server sudo systemctl status monitor-gpio.service ``` 2. **Проверьте firewall:** ```bash sudo nft list ruleset | grep 8080 ``` 3. **Проверьте, на каком интерфейсе слушает сервер:** ```bash sudo ss -tlnp | grep 8080 # Должно быть *:8080 или 0.0.0.0:8080 ``` 4. **Проверьте маршрутизацию:** ```bash ip route show ``` 5. **Посмотрите логи:** ```bash sudo journalctl -u monitor-gpio.service -f tail -f /home/user/logs/gpio-events.log tail -f /home/user/logs/gpio-human.log ``` 6. **Проверьте наличие pipe:** ```bash ls -la /tmp/gpio_pipe ``` ### Если индикатор "🔊 ЗВУК" на dashboard не реагирует на микрофон: 1. **Проверьте, что arecord установлен и видит микрофон:** ```bash which arecord arecord -l ``` 2. **Проверьте лог сервера при запуске** — если микрофон не найден, будет строка: ``` Аудио-монитор не запущен (микрофон недоступен?): ... ``` 3. **Проверьте права доступа к аудио-устройству** (сервис должен работать от пользователя из группы `audio`): ```bash groups sudo usermod -aG audio ``` --- ## Wi-Fi режим Raspberry Pi SSID: `fix_me` IP: `192.168.77.1` Подключение: `ssh user@192.168.77.1` --- ### Запуск Go сервера в режиме разработки: ```bash go run cmd/server/main.go \ -pipe /tmp/gpio_pipe \ -retention-hours=1 \ -human-log-interval=1 ``` ### Эмуляция GPIO сигналов: ```bash python3 scripts/emulator.py ``` ### Просмотр логов: ```bash ./scripts/view_logs.sh ``` --- ## Камера (go2rtc) Для работы камеры установите go2rtc: ```bash # Запуск go2rtc ./scripts/go2rtc -config scripts/go2rtc.yaml ``` Камера будет доступна по адресу: - MJPEG поток: `http://:1984/api/stream.mjpeg?src=cam_mjpeg` - Встроенный интерфейс: `http://:1984` --- ## Сборка и управление DEB-пакетом В проект добавлена возможность сборки нативного `.deb` пакета для Raspberry Pi OS. Пакет автоматически упаковывает скомпилированный Go-сервер, собранный TypeScript-фронтенд, скрипты логов, конфигурационные файлы и systemd-сервисы. Сборка пакета выполняется одной командой. **Запуск от обычного пользователя (без sudo):** ```bash make deb ``` После завершения файл пакета будет доступен по пути: ./build/gpio-monitor-server.deb Установка собранного пакета После того как пакет собран, его можно установить в систему с помощью менеджера пакетов apt (он автоматически подтянет системные зависимости, если они требуются): ```Bash cd ./build sudo dpkg -i gpio-monitor-server_1.0.0-1_arm64.deb ``` Полезные команды для работы с пакетом В Makefile предусмотрены дополнительные команды для проверки и очистки пакета перед деплоем: Просмотр информации о пакете (версия, архитектура, зависимости, описание): ```Bash # Просмотр содержимого пакета, список файлов и папок: make deb-info ``` ```Bash # Очистка временных файлов сборки пакета: make deb-contents ``` ```Bash make deb-clean sudo apt purge gpio-monitor-server ``` ---