398 lines
12 KiB
Markdown
398 lines
12 KiB
Markdown
# 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
|
||
```
|
||
|
||
### 2. Клонирование и сборка
|
||
|
||
```bash
|
||
git clone <your-repo>
|
||
cd ~/work/golang
|
||
|
||
# Сборка TypeScript + Go
|
||
./build.sh
|
||
```
|
||
|
||
### 3. Настройка systemd сервиса
|
||
|
||
```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 камеры |
|
||
|
||
---
|
||
|
||
## Dashboard
|
||
|
||
Открывайте в браузере:
|
||
|
||
- **Через Ethernet:** `http://10.1.1.33:8080` (или ваш IP)
|
||
- **Через Wi-Fi AP:** `http://192.168.77.1:8080`
|
||
- **Локально:** `http://localhost:8080`
|
||
|
||
### Страницы
|
||
|
||
- `http://<IP>:8080/` - Перенаправление на dashboard
|
||
- `http://<IP>:8080/dashboard.html` - Главная панель мониторинга
|
||
- `http://<IP>:8080/logs.html` - Просмотр исторических логов
|
||
|
||
---
|
||
|
||
## API
|
||
|
||
### Основные эндпоинты
|
||
|
||
```bash
|
||
GET /api/health
|
||
# Статус сервера, uptime, статистика
|
||
|
||
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
|
||
```
|
||
|
||
---
|
||
|
||
## 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://<IP>:1984/api/stream.mjpeg?src=cam_mjpeg`
|
||
- Встроенный интерфейс: `http://<IP>:1984`
|
||
|
||
---
|
||
|
||
### Сборка пакета
|
||
```bash
|
||
make deb
|