Доработка документации
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
// gpio-monitor-server — HTTP-сервер мониторинга GPIO-шины Raspberry Pi.
|
||||
// Читает поток байт из FIFO pipe, хранит их в кольцевом буфере и бинарных
|
||||
// почасовых логах, отдаёт JSON API и встроенный веб-дашборд на :8080.
|
||||
// Конфигурация — только флагами командной строки (см. main или docs/operations.md).
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -28,6 +32,8 @@ import (
|
||||
//go:embed web/dist web/css web/fonts web/*.html web/*.png
|
||||
var webFiles embed.FS
|
||||
|
||||
// API — состояние HTTP-хендлеров: кольцевой буфер, время старта сервера
|
||||
// и монитор звука. Спецификация ответов — docs/api.md.
|
||||
type API struct {
|
||||
buf *adapter.RingBuffer
|
||||
startTime time.Time
|
||||
@@ -39,7 +45,8 @@ func writeJSON(w http.ResponseWriter, v any) {
|
||||
json.NewEncoder(w).Encode(v)
|
||||
}
|
||||
|
||||
// HandleLogFiles - список доступных лог-файлов
|
||||
// HandleLogFiles отдаёт список бинарных лог-файлов gpio-*.bin,
|
||||
// отсортированный по времени изменения (новые первыми).
|
||||
func (a *API) HandleLogFiles(w http.ResponseWriter, r *http.Request) {
|
||||
dataDir, err := logger.GetDataLogsDir()
|
||||
if err != nil {
|
||||
@@ -105,7 +112,8 @@ func (a *API) HandleLogFiles(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, result)
|
||||
}
|
||||
|
||||
// HandleLogEvents - чтение событий с пагинацией
|
||||
// HandleLogEvents отдаёт события из events_human.log с пагинацией
|
||||
// (page, page_size; страница 1 — самые новые).
|
||||
func (a *API) HandleLogEvents(w http.ResponseWriter, r *http.Request) {
|
||||
// Параметры пагинации
|
||||
page := 1
|
||||
@@ -220,7 +228,9 @@ func (a *API) HandleLogEvents(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
|
||||
// HandleLogData - чтение данных из конкретного bin файла с пагинацией
|
||||
// HandleLogData отдаёт сэмплы одного .bin-файла (параметр file) с пагинацией
|
||||
// (page, page_size; страница 1 — самые новые). Формат записи — 9 байт,
|
||||
// см. docs/data-formats.md. Файл читается в память целиком.
|
||||
func (a *API) HandleLogData(w http.ResponseWriter, r *http.Request) {
|
||||
filename := r.URL.Query().Get("file")
|
||||
if filename == "" {
|
||||
@@ -400,6 +410,8 @@ func (a *API) HandleLogData(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// HandleHealth отдаёт статус сервера: связь с pipe (пороги 15 с и 3 с),
|
||||
// uptime, статистику буфера и уровень звука.
|
||||
func (a *API) HandleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
latest, ok := a.buf.GetLatest()
|
||||
idle := time.Since(a.buf.LastWriteTime())
|
||||
@@ -429,6 +441,7 @@ func (a *API) HandleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// HandleLatest отдаёт последний байт и до 10 предыдущих (от старых к новым).
|
||||
func (a *API) HandleLatest(w http.ResponseWriter, r *http.Request) {
|
||||
latest, ok := a.buf.GetLatest()
|
||||
if !ok {
|
||||
@@ -442,6 +455,7 @@ func (a *API) HandleLatest(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// HandleHistory отдаёт до 300 последних байт для графика (от старых к новым).
|
||||
func (a *API) HandleHistory(w http.ResponseWriter, r *http.Request) {
|
||||
raw := a.buf.GetLast(300)
|
||||
|
||||
@@ -455,6 +469,9 @@ func (a *API) HandleHistory(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// HandleStream отдаёт статус видеопотока камеры. Внимание: доступность
|
||||
// проверяется по захардкоженному localhost:1984 без учёта флага -camera-url
|
||||
// (известное поведение, docs/tech-debt.md).
|
||||
func (a *API) HandleStream(w http.ResponseWriter, r *http.Request) {
|
||||
// Проверяем доступность MJPEG потока в go2rtc
|
||||
resp, err := http.Get("http://localhost:1984/api/streams?src=cam_mjpeg")
|
||||
@@ -470,7 +487,8 @@ func (a *API) HandleStream(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// Прокси для MJPEG потока — просто ретранслирует готовый поток из go2rtc
|
||||
// handleCamProxy — НЕ ИСПОЛЬЗУЕТСЯ: роутер вызывает handleCamProxyWithURL,
|
||||
// этот вариант с захардкоженным URL остался как мёртвый код (docs/tech-debt.md).
|
||||
func handleCamProxy(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("[cam] запрос от %s", r.RemoteAddr)
|
||||
|
||||
@@ -519,6 +537,8 @@ func handleCamProxy(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// cors разрешает кросс-доменные GET-запросы с любых источников
|
||||
// (рассчитано на доверенную локальную сеть).
|
||||
func cors(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
@@ -703,7 +723,8 @@ func main() {
|
||||
log.Fatal(http.ListenAndServe(*serverPort, nil))
|
||||
}
|
||||
|
||||
// handleCamProxyWithURL проксирует MJPEG поток с указанным URL
|
||||
// handleCamProxyWithURL проксирует MJPEG-поток с cameraURL (флаг -camera-url),
|
||||
// ретранслируя заголовки и сбрасывая буфер после каждого чанка 32 КБ.
|
||||
func handleCamProxyWithURL(w http.ResponseWriter, r *http.Request, cameraURL string) {
|
||||
log.Printf("[cam] запрос от %s к %s", r.RemoteAddr, cameraURL)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user