Files
my_speaker_RPi3/webapp/modules/dashboard.js
T
2025-12-25 12:01:35 +03:00

197 lines
6.1 KiB
JavaScript

import {
getSpeechData,
getSysMonitor,
getRecentPhrases,
getSettings,
} from "../api.js";
let speechChart;
let energyChart;
let historyMaxLen = 20; // Значение по умолчанию в области видимости модуля
export async function loadDashboard() {
const content = document.getElementById("content");
const dashboardHtml = await fetch("pages/dashboard.html").then((res) =>
res.text()
);
content.innerHTML = dashboardHtml;
// Инициализация графика речи
const speechCtx = document.getElementById("speech-chart").getContext("2d");
speechChart = new Chart(speechCtx, {
type: "line",
data: {
labels: [],
datasets: [
{
label: "Speech Prob",
data: [],
borderColor: "#0f0",
backgroundColor: "rgba(0, 255, 0, 0.1)",
borderWidth: 2,
pointRadius: 0,
fill: false,
},
{
label: "Speech Threshold",
data: [],
borderColor: "#ffcc00",
borderWidth: 1,
pointRadius: 0,
borderDash: [5, 5],
fill: false,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 1,
title: {
display: true,
text: "Speech Probability",
},
},
},
},
});
// Инициализация графика энергии
const energyCtx = document.getElementById("energy-chart").getContext("2d");
energyChart = new Chart(energyCtx, {
type: "line",
data: {
labels: [],
datasets: [
{
label: "Energy",
data: [],
borderColor: "#ff00ff",
backgroundColor: "rgba(255, 0, 255, 0.1)",
borderWidth: 2,
pointRadius: 0,
fill: false,
},
{
label: "Energy Threshold",
data: [],
borderColor: "#ff6600",
borderWidth: 1,
pointRadius: 0,
borderDash: [5, 5],
fill: false,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: "Energy Level",
},
},
},
},
});
// Получение и обработка настроек
let settings;
try {
settings = await getSettings();
} catch (error) {
console.error("Failed to load settings:", error);
settings = { system: { polling_interval_ms: 1000, history_maxlen: 20 } }; // Значения по умолчанию
}
const pollingIntervalMs = settings.system.polling_interval_ms || 1000;
historyMaxLen = settings.system.history_maxlen || 20; // Обновляем глобальную переменную
// Установка интервала опроса и передача значения в хедер
setInterval(updateDashboard, pollingIntervalMs);
updateDashboard();
window.dispatchEvent(
new CustomEvent("updateHeader", { detail: pollingIntervalMs })
);
}
async function updateDashboard() {
try {
const [speech, sys, phrases] = await Promise.all([
getSpeechData(),
getSysMonitor(),
getRecentPhrases(5),
]);
// Update main-params
document.getElementById("status").textContent = `Status: ${speech.state}`;
// Обновление карточки речи
document.getElementById("speech-value").textContent =
speech.speech_prob.toFixed(2);
document.getElementById("speech-max").textContent =
speech.speech_threshold.toFixed(2);
document.getElementById("sp-detect").textContent = speech.speech_detected
? "True"
: "False";
// Обновление карточки энергии
document.getElementById("energy-value").textContent = Math.round(
speech.energy
);
document.getElementById("energy-max").textContent = Math.round(
speech.energy_threshold
);
document.getElementById("noise-floor").textContent = Math.round(
speech.noise_floor
);
// Обновление системного монитора
document.getElementById("cpu").textContent = `${sys.cpu_percent}%`;
document.getElementById("mem").textContent = `${sys.memory_percent}%`;
document.getElementById("temp").textContent = `${sys.temperature}°C`;
// Update speech chart
const now = new Date();
const timestamp =
now.toLocaleTimeString() +
"." +
now.getMilliseconds().toString().padStart(3, "0");
speechChart.data.labels.push(timestamp);
speechChart.data.datasets[0].data.push(speech.speech_prob);
speechChart.data.datasets[1].data.push(speech.speech_threshold);
if (speechChart.data.labels.length > historyMaxLen) {
speechChart.data.labels.shift();
speechChart.data.datasets.forEach((ds) => ds.data.shift());
}
speechChart.update("none"); // Используем 'none' для оптимизации при частых обновлениях
// Update energy chart
energyChart.data.labels.push(timestamp);
energyChart.data.datasets[0].data.push(speech.energy);
energyChart.data.datasets[1].data.push(speech.energy_threshold);
if (energyChart.data.labels.length > historyMaxLen) {
energyChart.data.labels.shift();
energyChart.data.datasets.forEach((ds) => ds.data.shift());
}
energyChart.update("none"); // Используем 'none' для оптимизации при частых обновлениях
// Update footer
const footer = document.getElementById("footer");
footer.innerHTML = phrases
.map(
(p) =>
`<p class="history-item">${p.timestamp} - ${
p.action || "неизвестно"
} - ${p.text}</p>`
)
.join("");
} catch (error) {
console.error("Error updating dashboard:", error);
}
}