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++) {