fix(dashboardAPI): clean stat panels — dedup stray-tag series, value-only text, meter units
Three display defects surfaced when rendering the live PS/pump/MGC dashboards: 1. Doubled values everywhere. EVOLV telemetry historically carried stray tags (tagcode="undefined"/uuid="null") that newer writes dropped, so InfluxDB holds two series per field and last() returned two of everything (e.g. Time Left, Runtime, Heights). Add |> group(columns:["_field"]) before last()/aggregateWindow in every template query so each field collapses to one value/line regardless of tag-set history. 2. fields:"/.*/" also rendered the _time column as a stat value. For single-field string panels (Direction, Flow Source, Mode, State, Prediction Quality) append |> keep(columns:["_value"]); for mixed string+numeric panels (valve/vgc/monster) drop _time/_start/_stop instead. 3. Level/Heights showed "0.12 min" — Grafana unit id "m" means minutes, not meters. Change to lengthm; normalize m³->m3, m³/h->m3/h on pumpingStation. Verified live via headless screenshots: PS, pump, and measurement dashboards now show single clean values with correct units. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
"id": 2,
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value", "graphMode": "area" },
|
||||
"targets": [
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^S_O/)\n |> last()", "refId": "A" }
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^S_O/)\n |> group(columns:[\"_field\"])\n |> last()", "refId": "A" }
|
||||
],
|
||||
"title": "DO (S_O)",
|
||||
"type": "stat"
|
||||
@@ -37,7 +37,7 @@
|
||||
"id": 3,
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value", "graphMode": "area" },
|
||||
"targets": [
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^S_NH/)\n |> last()", "refId": "A" }
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^S_NH/)\n |> group(columns:[\"_field\"])\n |> last()", "refId": "A" }
|
||||
],
|
||||
"title": "NH\u2084 (S_NH)",
|
||||
"type": "stat"
|
||||
@@ -49,7 +49,7 @@
|
||||
"id": 4,
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value", "graphMode": "area" },
|
||||
"targets": [
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^S_NO/)\n |> last()", "refId": "A" }
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^S_NO/)\n |> group(columns:[\"_field\"])\n |> last()", "refId": "A" }
|
||||
],
|
||||
"title": "NO\u2083 (S_NO)",
|
||||
"type": "stat"
|
||||
@@ -61,7 +61,7 @@
|
||||
"id": 5,
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value", "graphMode": "area" },
|
||||
"targets": [
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^X_TS/)\n |> last()", "refId": "A" }
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^X_TS/)\n |> group(columns:[\"_field\"])\n |> last()", "refId": "A" }
|
||||
],
|
||||
"title": "TSS (X_TS)",
|
||||
"type": "stat"
|
||||
@@ -74,7 +74,7 @@
|
||||
"id": 7,
|
||||
"options": { "legend": { "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "multi" } },
|
||||
"targets": [
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\")\n |> filter(fn:(r) => r._field =~ /^(F|S_O|S_NH|S_NO|S_S|X_TS)/)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)", "refId": "A" }
|
||||
{ "query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\")\n |> filter(fn:(r) => r._field =~ /^(F|S_O|S_NH|S_NO|S_S|X_TS)/)\n |> group(columns:[\"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)", "refId": "A" }
|
||||
],
|
||||
"title": "Core Process Signals",
|
||||
"type": "timeseries"
|
||||
|
||||
Reference in New Issue
Block a user