Werkzeug zur Echtzeit-Datenanalyse von BM6 pro Sekunde

Unterstützung für Echtzeit-Datenextraktion bei 1 Hz und CSV-Export
Dieses Tool sucht automatisch nach dem Paket d15507 in den Protokolldateien, wandelt die hexadezimalen Daten in eine pro Sekunde aktualisierte Aufzeichnung von Spannung und Temperatur um und bietet einen dynamischen Chart-Vorschau mit synchroner Skalierung sowie Funktionen zum Herunterladen der Daten.
Bitte wählen Sie eine Datei mit Echtzeit-Broadcast-Daten aus
Es liegen keine Textpassagen vor, die in Klammern ([alt](url) oder [![alt](img)](url)) enthalten sind und übersetzt werden müssen. Die angegebenen URLs wurden gemäß den Regeln unverändert belassen. Der Code bleibt wie folgt: ```html ``` ```html ``` lassen Sie `vChart`, `tChart`; lassen Sie `parsedData` = []; lassen Sie `isResetting` = false; // --- Konfiguration für die Initialisierung von Chart.js --- Chart.defaults.color = '#8b949e'; Chart.defaults.borderColor = '#30363d'; const crosshairPlugin = { id: 'crosshair', beforeDraw: chart => { if (chart.tooltip._active && chart.tooltip._active.length) { const ctx = chart.ctx; const activePoint = chart.tooltip._active[0]; const x = activePoint.element.x; const topY = chart.scales.y.top; const bottomY = chart.scales.y.bottom; ctx.save(); ctx.beginPath(); ctx.moveTo(x, topY); ctx.lineTo(x, bottomY); ctx.lineWidth = 1; ctx.strokeStyle = 'rgba(139, 148, 158, 0.8)'; ctx.setLineDash([4, 4]); ctx.stroke(); ctx.restore(); } } }; function autoScaleY(chart) { const xScale = chart.scales.x, dataset = chart.data.datasets[0].data; let minV = Infinity, maxV = -Infinity, found = false; for (let i = 0; i < dataset.length; i++) { const xVal = new Date(dataset[i].x).getTime(); if (xVal >= xScale.min && xVal <= xScale.max) { if (dataset[i].y < minV) minV = dataset[i].y; if (dataset[i].y > maxV) maxV = dataset[i].y; found = true; } } if (found) { const padding = (maxV - minV) * 0.15 || 0.15; charts.options.scales.y.min = minV - padding; charts.options.scales.y.max = maxV + padding; } } function syncCharts({chart}) { if (isResetting) return; const other = (chart === vChart) ? tChart : vChart; other.options.scales.x.min = chart.scales.x.min; other.options.scales.x.max = chart.scales.x.max; autoScaleY(chart); autoScaleY(other); chart.update('none'); other.update('none'); } function createChartConfig(label, color, yTitle) { return { type: 'line', data: { datasets: [{ label: label, data: [], borderColor: color, backgroundColor: color + '20', borderWidth: 2, pointRadius: 0, tension: 0.2, fill: true }] }, options: { responsive: true, maintainAspectRatio: false, interaction: { mode: 'index', intersect: false, }, scales: { x: { type: 'time', time: { displayFormats: { second: 'HH:mm:ss', minute: 'HH:mm:ss', hour: 'HH:mm:ss' }, tooltipFormat: 'HH:mm:ss' } }, y: { title: { display: true, text: yTitle } } }, plugins: { tooltip: { enabled: true, backgroundColor: 'rgba(22, 27, 34, 0.9)', titleColor: '#c9d1d9', bodyColor: '#c9d1d9', borderColor: '#30363d', borderWidth: 1, padding: 10, displayColors: false }, zoom: { pan: { enabled: true, mode: 'x', onPan: syncCharts }, zoom: { wheel: { enabled: true }, mode: 'x', onZoom: syncCharts } } } }, plugins: [crosshairPlugin] }; } // Erstellen Sie zwei Diagramm-Entitäten vChart = new Chart(document.getElementById('voltageChart'), createChartConfig('Spannung (V)', '#58a6ff', 'Spannung (V)')); tChart = new Chart(document.getElementById('tempChart'), createChartConfig('Temperatur (°C)', '#f85149', 'Temperatur (°C)')); // --- Datei-Verarbeitung verarbeiten --- uploadTrigger.onclick = () => fileInput.click(); fileInput.onchange = function(e) { const datei = e.target.files[0]; if (!datei) return; statusText.innerHTML = `Wird ${file.name} analysiert...`; const reader = new FileReader(); reader.onload = function(e) { processData(e.target.result); }; reader.readAsText(file); function processData(text) { const lines = text.split('\n'); // d15507 + TempHex(2) + Other(2) + SOCHex(2) + VolHex(4) const pattern = /^(\d{2}:\d{2}:\d{2}):receive:d1550700([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]{2})([0-9a-fA-F]{4})/; const vData = []; const tData = []; parsedData = []; let currentDay = 1; let lastTimeObj = null; lines.forEach(line => { const match = line.trim().match(pattern); if (match) { const timeStr = match[1]; // "HH:MM:SS" const tempC = parseInt(match[2], 16); const voltage = parseInt(match[4], 16) / 100.0; // Logik zur Behandlung von nächtlichen Übergängen (z.B. von 23:59:59 auf 00:00:00) const [h, m, s] = timeStr.split(':').map(Number); const currentTimeObj = new Date(2026, 0, currentDay, h, m, s); if (lastTimeObj && currentTimeObj < lastTimeObj) { currentDay++; currentTimeObj.setDate(currentDay); } lastTimeObj = currentTimeObj; // Abrufen des Timestamps für Chart.js const timeVal = currentTimeObj.getTime(); vData.push({ x: timeVal, y: voltage }); tData.push({ x: timeVal, y: tempC }); // Speichert den ursprünglichen String für die CSV-Exportfunktion parsedData.push([timeStr, voltage, tempC]); }); if (parsedData.length > 0) { statusText.innerHTML = `✅ Analyse erfolgreich! Es wurden ${parsedData.length} Echtzeitdaten extrahiert.`; downloadBtn.style.display = 'inline-block'; isResetting = true; [vChart, tChart].forEach(chart => { if (chart.resetZoom) chart.resetZoom('keine'); }); // Daten aktualisieren vChart.data.datasets[0].data = vData; tChart.data.datasets[0].data = tData; // Vorkalkulieren des Y-Achsenbereichs, um ein unvollständiges Diagramm zu verhindern const vValues = vData.map(d => d.y); const tValues = tData.map(d => d.y); const minV = Math.min(...vValues), maxV = Math.max(...vValues); const minT = Math.min(...tValues), maxT = Math.max(...tValues); const vPad = (maxV - minV) * 0.15 || 0.5; const tPad = (maxT - minT) * 0.15 || 2; vChart.options.scales.y.min = minV - vPad; vChart.options.scales.y.max = maxV + vPad; tChart.options.scales.y.min = minT - tPad; tChart.options.scales.y.max = maxT + vPad; vChart.update('keine Werte anzeigen'); tChart.update('keine Werte anzeigen'); setInterval(() => { isResetting = false; }, 200); } else { statusText.innerHTML = `❌ Keine gültigen Daten gefunden. Bitte überprüfen Sie, ob das Log die Paket-ID d15507 enthält.`; downloadBtn.style.display = 'none'; } } ```javascript downloadBtn.onclick = function() { if (parsedData.length === 0) return; let csvContent = "Time,Voltage(V),Temperature(°C)\n"; parsedData.forEach(row => { csvContent += row.join(",") + "\n"; }); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", "bm6_per_second_data.csv"); link.click(); }; })(); </script> ```