diff --git a/cmd/server/web/js/app.ts b/cmd/server/web/js/app.ts index b05742b..cc8b9b1 100644 --- a/cmd/server/web/js/app.ts +++ b/cmd/server/web/js/app.ts @@ -1,7 +1,24 @@ // app.js (оркестратор) -import { fetchHealth, fetchHistory } from "./data.js"; -import { state, addSignals, resetBufferTracking, updatePeakHolder, forceResetPeak, getPeakInfo } from "./state.js"; -import { initDOM, setStatus, setMeta, setBars, setSignal, DOM } from "./ui.js"; +import { + fetchHealth, + fetchHistory +} from "./data.js"; +import { + state, + addSignals, + resetBufferTracking, + updatePeakHolder, + updateSignalPeakHolder, + forceResetPeak +} from "./state.js"; +import { + initDOM, + setStatus, + setMeta, + setBars, + setSignal, + DOM +} from "./ui.js"; import { initAccordion } from "./accordion.js"; import { drawChart } from "./chart.js"; import { initResize } from "./layout.js"; @@ -88,11 +105,12 @@ async function update(): Promise { if (isOnline) { const displayValue = updatePeakHolder(percent); setBars(displayValue); - setSignal(level); + + const displaySignalLevel = updateSignalPeakHolder(level); + setSignal(displaySignalLevel); } else { - // Сервер НЕ на связи - сбрасываем индикаторы в 0 и делаем серыми - setBars(0, true); // true = режим "нет соединения" - setSignal(0, true); // true = режим "нет соединения" + setBars(0, true); + setSignal(0, true); } if (DOM.lastByte) { diff --git a/cmd/server/web/js/state.ts b/cmd/server/web/js/state.ts index 6fb6d4e..ef5da20 100644 --- a/cmd/server/web/js/state.ts +++ b/cmd/server/web/js/state.ts @@ -5,11 +5,16 @@ interface AppState { signalHistory: number[]; lastBufferSize: number; - // Peak Holder параметры - peakValue: number; // Текущее удерживаемое пиковое значение - currentValue: number; // Текущее реальное значение (без сглаживания) - peakTimer: number | null; // Таймер для сброса пика + // Peak Holder + peakValue: number; // Текущее удерживаемое пиковое значение амплитуды + currentValue: number; // Текущее реальное значение амплитуды + peakTimer: number | null; // Таймер для сброса пика амплитуды peakHoldTime: number; // Время удержания пика в миллисекундах + + peakSignalLevel: number; // Текущий удерживаемый пиковый уровень сигнала (0-3) + currentSignalLevel: number; // Текущий реальный уровень сигнала + signalPeakTimer: number | null; // Таймер для сброса пика сигнала + signalPeakHoldTime: number; // Время удержания пика сигнала } export const state: AppState = { @@ -20,14 +25,16 @@ export const state: AppState = { peakValue: 0, currentValue: 0, peakTimer: null, - peakHoldTime: 3000, // миллисекунды удержания пика + peakHoldTime: 3000, // 3 секунды + + peakSignalLevel: 0, + currentSignalLevel: 0, + signalPeakTimer: null, + signalPeakHoldTime: 3000, // 3 секунды }; -/** - * Основная функция peak holder - * @param target - новое значение (0-63) - * @returns значение для отображения (пик, если таймер активен) - */ +// ========== ФУНКЦИИ ДЛЯ АМПЛИТУДЫ ========== + export function updatePeakHolder(target: number): number { // Обновляем текущее значение state.currentValue = target; @@ -75,41 +82,106 @@ function resetPeakTimer(): void { function resetPeak(): void { state.peakValue = state.currentValue; state.peakTimer = null; - - // Опционально: лог для отладки - // console.log(`[PeakHolder] Reset to: ${state.peakValue}`); } /** - * Принудительный сброс пика (например, при потере связи) + * Обновление пикового уровня сигнала (peak holder для strength) + * @param level - новый уровень сигнала (0-3) + * @returns пиковый уровень для отображения */ +export function updateSignalPeakHolder(level: number): number { + // Обновляем текущее значение + state.currentSignalLevel = level; + + // Если новый уровень выше текущего пика + if (level > state.peakSignalLevel) { + // Устанавливаем новый пик + state.peakSignalLevel = level; + + // Сбрасываем и перезапускаем таймер + resetSignalPeakTimer(); + startSignalPeakTimer(); + + // Опционально: лог для отладки + // console.log(`[SignalPeak] Новый пик сигнала: ${state.peakSignalLevel}`); + } + + // Возвращаем текущий пик для отображения + return state.peakSignalLevel; +} + +/** + * Запуск таймера сброса пика сигнала + */ +function startSignalPeakTimer(): void { + if (state.signalPeakTimer !== null) { + clearTimeout(state.signalPeakTimer); + } + + state.signalPeakTimer = window.setTimeout(() => { + resetSignalPeak(); + }, state.signalPeakHoldTime); +} + +/** + * Сброс таймера пика сигнала + */ +function resetSignalPeakTimer(): void { + if (state.signalPeakTimer !== null) { + clearTimeout(state.signalPeakTimer); + state.signalPeakTimer = null; + } +} + +/** + * Сброс пикового уровня сигнала до текущего уровня + */ +function resetSignalPeak(): void { + state.peakSignalLevel = state.currentSignalLevel; + state.signalPeakTimer = null; + + // Опционально: лог для отладки + // console.log(`[SignalPeak] Сброс пика сигнала до: ${state.peakSignalLevel}`); +} + +/** + * Принудительный сброс пика сигнала (например, при потере связи) + */ +export function forceResetSignalPeak(): void { + resetSignalPeakTimer(); + state.peakSignalLevel = 0; + state.currentSignalLevel = 0; +} + +/** + * Обновление времени удержания пика сигнала + * @param ms - время в миллисекундах + */ +export function setSignalPeakHoldTime(ms: number): void { + state.signalPeakHoldTime = ms; +} + +/** + * Получение текущего состояния пика сигнала (для отладки) + */ +export function getSignalPeakInfo(): { peak: number; current: number; timerActive: boolean } { + return { + peak: state.peakSignalLevel, + current: state.currentSignalLevel, + timerActive: state.signalPeakTimer !== null, + }; +} + +// ========== ОБНОВЛЕННЫЕ ФУНКЦИИ ДЛЯ СБРОСА ========== + export function forceResetPeak(): void { resetPeakTimer(); state.peakValue = 0; state.currentValue = 0; -} -/** - * Обновление времени удержания пика - * @param ms - время в миллисекундах - */ -export function setPeakHoldTime(ms: number): void { - state.peakHoldTime = ms; + forceResetSignalPeak(); } -/** - * Получение текущего состояния пика (для отладки) - */ -export function getPeakInfo(): { peak: number; current: number; timerActive: boolean } { - return { - peak: state.peakValue, - current: state.currentValue, - timerActive: state.peakTimer !== null, - }; -} - -// ===== ОСТАВЛЯЕМ СУЩЕСТВУЮЩИЕ ФУНКЦИИ БЕЗ ИЗМЕНЕНИЙ ===== - export function addSignal(value: number): void { state.signalHistory.push(value); if (state.signalHistory.length > state.maxPoints) { @@ -137,5 +209,5 @@ export function addSignals(values: number[], bufferSize: number): void { export function resetBufferTracking(): void { state.lastBufferSize = 0; - forceResetPeak(); // Также сбрасываем пик при потере связи + forceResetPeak(); // Сбрасываем оба пика } \ No newline at end of file diff --git a/scripts/go2monitor.service b/scripts/go2monitor.service index 18577c3..44f59a7 100644 --- a/scripts/go2monitor.service +++ b/scripts/go2monitor.service @@ -9,8 +9,15 @@ User=user Group=user WorkingDirectory=/home/user/temp/golang -# Запуск сервера -ExecStart=/home/user/temp/golang/build/gpio-monitor-server -pipe /tmp/gpio_pipe +# Запуск сервера с параметрами для 72-часового хранения +ExecStart=/home/user/temp/golang/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 # Перезапуск при падении Restart=on-failure @@ -26,4 +33,4 @@ StandardError=journal SyslogIdentifier=gpio-monitor [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target \ No newline at end of file