diff --git a/meshview/lang/en.json b/meshview/lang/en.json index 8454fc0..065e5aa 100644 --- a/meshview/lang/en.json +++ b/meshview/lang/en.json @@ -244,7 +244,6 @@ "battery_voltage": "Battery & Voltage", "air_channel": "Air & Channel Utilization", "environment": "Environment Metrics", - "power": "Power Metrics", "neighbors_chart": "Neighbors (Signal-to-Noise)", "neighbors_chart_subtitle": "Last {days} days — {n} neighbors", "neighbors_chart_subtitle_capped": "Last {days} days — the {n} neighbors with the most data points, of {total}", @@ -445,8 +444,6 @@ "Channel:": "Channel:", "Chat messages API": "Chat messages API", "Chat uses": "Chat uses", - "Ch{n} current (mA)": "Ch{n} current (mA)", - "Ch{n} voltage (V)": "Ch{n} voltage (V)", "Click to view text packets": "Click to view text packets", "Close": "Close", "Close expanded chart": "Close expanded chart", @@ -474,8 +471,6 @@ "Drag nodes to rearrange · Scroll to zoom": "Drag nodes to rearrange · Scroll to zoom", "Elevated": "Elevated", "Enter a valid node ID or select a node.": "Enter a valid node ID or select a node.", - "Environment current (mA)": "Environment current (mA)", - "Environment voltage (V)": "Environment voltage (V)", "Error": "Error", "Error Details": "Error Details", "Error loading nodes": "Error loading nodes", diff --git a/meshview/lang/es.json b/meshview/lang/es.json index 855af55..b2ad527 100644 --- a/meshview/lang/es.json +++ b/meshview/lang/es.json @@ -252,7 +252,6 @@ "battery_voltage": "Batería y voltaje", "air_channel": "Utilización del aire y del canal", "environment": "Métricas Ambientales", - "power": "Métricas de potencia", "neighbors_chart": "Vecinos (Relación Señal/Ruido)", "neighbors_chart_subtitle": "Últimos {days} días — {n} vecinos", "neighbors_chart_subtitle_capped": "Últimos {days} días — los {n} vecinos con más datos, de {total}", @@ -453,8 +452,6 @@ "Channel:": "Canal:", "Chat messages API": "API de mensajes de chat", "Chat uses": "El chat usa", - "Ch{n} current (mA)": "Corriente Ch{n} (mA)", - "Ch{n} voltage (V)": "Voltaje Ch{n} (V)", "Click to view text packets": "Pulse para ver los paquetes de texto", "Close": "Cerrar", "Close expanded chart": "Cerrar gráfico ampliado", @@ -482,8 +479,6 @@ "Drag nodes to rearrange · Scroll to zoom": "Arrastre los nodos para reorganizar · Desplace para ampliar", "Elevated": "Elevada", "Enter a valid node ID or select a node.": "Introduzca un ID válido o seleccione un nodo.", - "Environment current (mA)": "Corriente ambiental (mA)", - "Environment voltage (V)": "Voltaje ambiental (V)", "Error": "Error", "Error Details": "Detalles del error", "Error loading nodes": "Error al cargar nodos", diff --git a/meshview/lang/ru.json b/meshview/lang/ru.json index fe64b89..24a128d 100644 --- a/meshview/lang/ru.json +++ b/meshview/lang/ru.json @@ -244,7 +244,6 @@ "battery_voltage": "Батарея и напряжение", "air_channel": "Использование сети и каналов", "environment": "Метрики среды", - "power": "Метрики питания", "neighbors_chart": "Соседи (Соотношение сигнал/шум)", "neighbors_chart_subtitle": "Последние {days} дн. — {n} соседей", "neighbors_chart_subtitle_capped": "Последние {days} дн. — {n} соседей с наибольшим числом точек, из {total}", @@ -445,8 +444,6 @@ "Channel:": "Канал:", "Chat messages API": "API сообщений чата", "Chat uses": "Чат использует", - "Ch{n} current (mA)": "Ток Ch{n} (мА)", - "Ch{n} voltage (V)": "Напряжение Ch{n} (В)", "Click to view text packets": "Нажмите для просмотра текстовых пакетов", "Close": "Закрыть", "Close expanded chart": "Закрыть развёрнутый график", @@ -474,8 +471,6 @@ "Drag nodes to rearrange · Scroll to zoom": "Перетаскивайте узлы · Масштабируйте прокруткой", "Elevated": "Повышенная", "Enter a valid node ID or select a node.": "Введите корректный ID или выберите узел.", - "Environment current (mA)": "Ток (среда) (мА)", - "Environment voltage (V)": "Напряжение (среда) (В)", "Error": "Ошибка", "Error Details": "Подробности ошибки", "Error loading nodes": "Ошибка загрузки нод", diff --git a/meshview/templates/node.html b/meshview/templates/node.html index 2888603..00e9c61 100644 --- a/meshview/templates/node.html +++ b/meshview/templates/node.html @@ -139,18 +139,6 @@
- - -
@@ -886,30 +874,7 @@ async function loadTelemetryCharts(){ times: [], battery: [], voltage: [], airUtil: [], chanUtil: [], - temperature: [], humidity: [], pressure: [], - // power_metrics channels (ch1..ch8) plus the legacy voltage/current - // that INA sensors report inside environment_metrics. - power: {}, powerSeries: [] - }; - const POWER_CHANNELS = [1, 2, 3, 4, 5, 6, 7, 8]; - for (const ch of POWER_CHANNELS) { - chartData.power[`ch${ch}_voltage`] = []; - chartData.power[`ch${ch}_current`] = []; - } - chartData.power.env_voltage = []; - chartData.power.env_current = []; - - // Return the body of a "name { ... }" block from the text-format payload. - // Several telemetry variants share field names (voltage, temperature...), - // so each value must be read only from its own block. - const metricsBlock = (pl, name) => - pl.match(new RegExp(`(?:^|\\n)\\s*${name}\\s*\\{([^}]*)\\}`))?.[1] || ""; - - // Read a numeric field by its exact name (line-anchored, so "voltage" - // does not match "ch1_voltage"). - const metricField = (block, name) => { - const m = block.match(new RegExp(`(?:^|\\n)\\s*${name}:\\s*(-?[\\d.]+(?:[eE][-+]?\\d+)?)`)); - return m ? parseFloat(m[1]) : NaN; + temperature: [], humidity: [], pressure: [] }; for (const pkt of packets.reverse()) { @@ -919,24 +884,28 @@ async function loadTelemetryCharts(){ t.toLocaleString(MeshI18n.language, { month:"2-digit", day:"2-digit", hour:"2-digit", minute:"2-digit" }) ); - const dev = metricsBlock(pl, "device_metrics"); - const env = metricsBlock(pl, "environment_metrics"); - const pwr = metricsBlock(pl, "power_metrics"); - - for (const ch of POWER_CHANNELS) { - chartData.power[`ch${ch}_voltage`].push(metricField(pwr, `ch${ch}_voltage`)); - chartData.power[`ch${ch}_current`].push(metricField(pwr, `ch${ch}_current`)); - } - chartData.power.env_voltage.push(metricField(env, "voltage")); - chartData.power.env_current.push(metricField(env, "current")); - - chartData.battery.push(metricField(dev, "battery_level")); - chartData.voltage.push(metricField(dev, "voltage")); - chartData.airUtil.push(metricField(dev, "air_util_tx")); - chartData.chanUtil.push(metricField(dev, "channel_utilization")); - chartData.temperature.push(metricField(env, "temperature")); - chartData.humidity.push(metricField(env, "relative_humidity")); - chartData.pressure.push(metricField(env, "barometric_pressure")); + // Matches your payload exactly (inside device_metrics {}) + chartData.battery.push( + parseFloat(pl.match(/battery_level:\s*([\d.]+)/)?.[1] || NaN) + ); + chartData.voltage.push( + parseFloat(pl.match(/voltage:\s*([\d.]+)/)?.[1] || NaN) + ); + chartData.airUtil.push( + parseFloat(pl.match(/air_util_tx:\s*([\d.]+)/)?.[1] || NaN) + ); + chartData.chanUtil.push( + parseFloat(pl.match(/channel_utilization:\s*([\d.]+)/)?.[1] || NaN) + ); + chartData.temperature.push( + parseFloat(pl.match(/temperature:\s*([\d.]+)/)?.[1] || NaN) + ); + chartData.humidity.push( + parseFloat(pl.match(/relative_humidity:\s*([\d.]+)/)?.[1] || NaN) + ); + chartData.pressure.push( + parseFloat(pl.match(/barometric_pressure:\s*([\d.]+)/)?.[1] || NaN) + ); } const hasBattery = chartData.battery.some(v => !isNaN(v)); @@ -1046,73 +1015,9 @@ async function loadTelemetryCharts(){ envContainer.style.display = "none"; } - // Power chart: one voltage (left axis) and one current (right axis) series - // per channel that reported data. Current is dashed and unfilled so up to - // 18 series stay readable. - const POWER_COLORS = [ - 'rgba(79,155,255,1)', 'rgba(255,214,82,1)', 'rgba(138,255,108,1)', - 'rgba(255,102,204,1)', 'rgba(255,138,82,1)', 'rgba(0,212,212,1)', - 'rgba(178,132,255,1)', 'rgba(200,200,200,1)' - ]; - const ENV_POWER_COLOR = 'rgba(255,80,80,1)'; - const powerSources = [ - ...POWER_CHANNELS.map(ch => ({ - key: `ch${ch}`, - color: POWER_COLORS[ch - 1], - voltageLabel: MeshI18n.t("Ch{n} voltage (V)", {n: ch}), - currentLabel: MeshI18n.t("Ch{n} current (mA)", {n: ch}) - })), - { - key: "env", - color: ENV_POWER_COLOR, - voltageLabel: MeshI18n.t("Environment voltage (V)"), - currentLabel: MeshI18n.t("Environment current (mA)") - } - ]; - const hasData = values => values.some(v => !isNaN(v)); - for (const src of powerSources) { - const voltage = chartData.power[`${src.key}_voltage`]; - const current = chartData.power[`${src.key}_current`]; - if (hasData(voltage)) - chartData.powerSeries.push({ label: src.voltageLabel, color: src.color, data: voltage, axis: 0 }); - if (hasData(current)) - chartData.powerSeries.push({ label: src.currentLabel, color: src.color, data: current, axis: 1 }); - } - - const powerContainer = document.getElementById("power_chart_container"); - let chart4 = null; - if (chartData.powerSeries.length) { - powerContainer.style.display = "block"; - chart4 = initMeshChart(document.getElementById('chart_power')); - chart4.setOption({ - tooltip: { trigger:'axis' }, - legend: { - type: 'scroll', - data: chartData.powerSeries.map(s => s.label), - textStyle:{ color:'#64748b' } - }, - xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#64748b' } }, - yAxis: [ - { type:'value', name:'Voltage (V)', axisLabel:{ color:'#64748b' } }, - { type:'value', name:'Current (mA)', axisLabel:{ color:'#64748b' } } - ], - series: chartData.powerSeries.map(s => { - const line = makeLine(s.label, s.color, s.data, s.axis); - if (s.axis === 1) { - delete line.areaStyle; - line.lineStyle = { ...line.lineStyle, type: 'dashed' }; - line.symbol = 'triangle'; - } - return line; - }) - }); - } else { - powerContainer.style.display = "none"; - } - // Resize charts that exist window.addEventListener("resize", () => { - [chart1, chart2, chart3, chart4].forEach(c => { if (c) c.resize(); }); + [chart1, chart2, chart3].forEach(c => { if (c) c.resize(); }); }); } @@ -1485,11 +1390,6 @@ function exportCSV(type){ chartData.pressure[i] ]); } - else if (type === "power") { - rows[0].push(...chartData.powerSeries.map(s => s.label)); - for (let i = 0; i < chartData.times.length; i++) - rows.push([chartData.times[i], ...chartData.powerSeries.map(s => isNaN(s.data[i]) ? null : s.data[i])]); - } else if (type === "neighbors") { rows[0] = [MeshI18n.t("Neighbor Node ID"), MeshI18n.t("Neighbor Name"), "SNR (dB)"]; for (let i = 0; i < neighborData.ids.length; i++) {