Initial commit: полный проект my_speaker
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user