197 lines
6.1 KiB
JavaScript
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);
|
|
}
|
|
}
|