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:
@@ -96,7 +96,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"state\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"state\")\n |> group(columns:[\"_field\"])\n |> last()\n |> keep(columns:[\"_value\"])",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -146,7 +146,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"mode\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"mode\")\n |> group(columns:[\"_field\"])\n |> last()\n |> keep(columns:[\"_value\"])",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -210,7 +210,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"ctrl\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"ctrl\")\n |> group(columns:[\"_field\"])\n |> last()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -260,7 +260,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"runtime\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"runtime\")\n |> group(columns:[\"_field\"])\n |> last()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -324,7 +324,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"NCogPercent\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"NCogPercent\")\n |> group(columns:[\"_field\"])\n |> last()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -431,7 +431,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^flow\\.predicted\\.(downstream|atequipment)/)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^flow\\.predicted\\.(downstream|atequipment)/)\n |> group(columns:[\"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -528,7 +528,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and (r._field==\"cog\" or r._field==\"NCogPercent\"))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and (r._field==\"cog\" or r._field==\"NCogPercent\"))\n |> group(columns:[\"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -637,7 +637,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^pressure\\.(predicted|measured)\\.(upstream|downstream)/)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^pressure\\.(predicted|measured)\\.(upstream|downstream)/)\n |> group(columns:[\"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -734,7 +734,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^temperature/)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field =~ /^temperature/)\n |> group(columns:[\"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -803,7 +803,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"predictionQuality\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"predictionQuality\")\n |> group(columns:[\"_field\"])\n |> last()\n |> keep(columns:[\"_value\"])",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -860,7 +860,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"predictionConfidence\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"predictionConfidence\")\n |> group(columns:[\"_field\"])\n |> last()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -917,7 +917,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"pressureDriftLevel\")\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and r._field==\"pressureDriftLevel\")\n |> group(columns:[\"_field\"])\n |> last()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -974,7 +974,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and (r._field==\"effDistFromPeak\" or r._field==\"effRelDistFromPeak\"))\n |> last()",
|
||||
"query": "from(bucket: \"${bucket}\")\n |> range(start: -7d)\n |> filter(fn:(r) => r._measurement==\"${measurement}\" and (r._field==\"effDistFromPeak\" or r._field==\"effRelDistFromPeak\"))\n |> group(columns:[\"_field\"])\n |> last()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user