Files
mg4/k8s/grafana/dashboards/live.json
T
nilsandClaude Opus 5.5 582c084b35 Live dashboard: show what the car sends, compute pack energy
The car publishes no battery, cabin or outside temperature and no pack
energy (checked against the fields that reached InfluxDB). Instead of
panels that stay empty:

- Battery temperature tile -> Climate setpoint.
- Outside temperature tile -> Last update ("2 minutes ago").
- Energy in pack = SOC x usable capacity, from the hidden dashboard
  constant usableKwh = 50.8 (51 kWh battery).
- Temperatures chart -> Battery voltage and current.

Checked with a simulated drive carrying exactly the car's fields: all
11 panels return data, energy matches 61 % x 50.8 kWh. SPECS.md lists
the missing signals and why.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 22:17:41 +02:00

648 lines
17 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"uid": "mg4-live",
"title": "MG4 - Live",
"description": "Live telemetry from the car, as stored before it is forwarded to ABRP.",
"tags": [
"mg4"
],
"timezone": "browser",
"editable": false,
"graphTooltip": 1,
"schemaVersion": 39,
"version": 1,
"time": {
"from": "now-24h",
"to": "now"
},
"refresh": "30s",
"templating": {
"list": [
{
"name": "installationId",
"label": "Car",
"type": "query",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "import \"influxdata/influxdb/schema\"\nschema.tagValues(bucket: \"mg4\", tag: \"installationId\", start: -400d)",
"definition": "installationId tag values",
"refresh": 1,
"includeAll": false,
"multi": false,
"current": {},
"hide": 0,
"sort": 1
},
{
"name": "usableKwh",
"label": "Usable battery capacity (kWh)",
"type": "constant",
"query": "50.8",
"hide": 2,
"description": "MG4 51 kWh battery: 50.8 kWh usable."
}
]
},
"annotations": {
"list": []
},
"panels": [
{
"id": 1,
"type": "stat",
"title": "State of charge",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 0,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: -30d)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and r._field == \"soc\")\n |> last()"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"color": {
"mode": "fixed",
"fixedColor": "#E0424C"
},
"decimals": 0
},
"overrides": []
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value"
}
},
{
"id": 2,
"type": "stat",
"title": "Range",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 4,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: -30d)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and r._field == \"est_battery_range\")\n |> last()"
}
],
"fieldConfig": {
"defaults": {
"unit": "suffix: km",
"color": {
"mode": "fixed",
"fixedColor": "#E0424C"
},
"decimals": 0
},
"overrides": []
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value"
}
},
{
"id": 3,
"type": "stat",
"title": "Odometer",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 8,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: -30d)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and r._field == \"odometer\")\n |> last()"
}
],
"fieldConfig": {
"defaults": {
"unit": "suffix: km",
"color": {
"mode": "fixed",
"fixedColor": "#E0424C"
},
"decimals": 0
},
"overrides": []
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value"
}
},
{
"id": 4,
"type": "stat",
"title": "Climate setpoint",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 12,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: -30d)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and r._field == \"hvac_setpoint\")\n |> last()"
}
],
"fieldConfig": {
"defaults": {
"unit": "celsius",
"color": {
"mode": "fixed",
"fixedColor": "#E0424C"
},
"decimals": 0
},
"overrides": []
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value"
}
},
{
"id": 5,
"type": "stat",
"title": "Last update",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 16,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: -30d)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and r._field == \"soc\")\n |> last()\n |> map(fn: (r) => ({_value: int(v: r._time) / 1000000}))"
}
],
"fieldConfig": {
"defaults": {
"unit": "dateTimeFromNow",
"color": {
"mode": "fixed",
"fixedColor": "#E0424C"
}
},
"overrides": []
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value"
},
"description": "When the car last reported."
},
{
"id": 6,
"type": "stat",
"title": "Energy in pack",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 20,
"y": 0,
"w": 4,
"h": 4
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: -30d)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and r._field == \"soc\")\n |> last()\n |> map(fn: (r) => ({_value: r._value / 100.0 * float(v: \"${usableKwh}\")}))"
}
],
"fieldConfig": {
"defaults": {
"unit": "kwatth",
"color": {
"mode": "fixed",
"fixedColor": "#E0424C"
},
"decimals": 1
},
"overrides": []
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value"
},
"description": "Computed: state of charge × usable capacity (dashboard constant usableKwh, 50.8 kWh for the 51 kWh battery). The car publishes no pack energy itself."
},
{
"id": 7,
"type": "timeseries",
"title": "State of charge and range",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 0,
"y": 4,
"w": 12,
"h": 8
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and (r._field == \"soc\" or r._field == \"est_battery_range\"))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> keep(columns: [\"_time\", \"_field\", \"_value\"])"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"custom": {
"lineWidth": 2,
"fillOpacity": 8,
"spanNulls": 600000,
"showPoints": "never"
}
},
"overrides": [
{
"matcher": {
"id": "byRegexp",
"options": ".*est_battery_range.*"
},
"properties": [
{
"id": "unit",
"value": "suffix: km"
},
{
"id": "custom.axisPlacement",
"value": "right"
}
]
}
]
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "multi"
}
}
},
{
"id": 8,
"type": "timeseries",
"title": "Power and speed",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 12,
"y": 4,
"w": 12,
"h": 8
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and (r._field == \"power\" or r._field == \"speed\"))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> keep(columns: [\"_time\", \"_field\", \"_value\"])"
}
],
"fieldConfig": {
"defaults": {
"unit": "kwatt",
"custom": {
"lineWidth": 2,
"fillOpacity": 8,
"spanNulls": 600000,
"showPoints": "never"
}
},
"overrides": [
{
"matcher": {
"id": "byRegexp",
"options": ".*speed.*"
},
"properties": [
{
"id": "unit",
"value": "velocitykmh"
},
{
"id": "custom.axisPlacement",
"value": "right"
}
]
}
]
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "multi"
}
},
"description": "Power is positive leaving the battery, negative while charging or regenerating."
},
{
"id": 9,
"type": "geomap",
"title": "Where the car was",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 0,
"y": 12,
"w": 12,
"h": 12
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and (r._field == \"lat\" or r._field == \"lon\"))\n |> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")\n |> keep(columns: [\"_time\", \"lat\", \"lon\"])\n |> sort(columns: [\"_time\"])"
}
],
"fieldConfig": {
"defaults": {},
"overrides": []
},
"options": {
"view": {
"id": "fit",
"lat": 0,
"lon": 0,
"zoom": 15,
"padding": 10,
"allLayers": true
},
"controls": {
"showZoom": true,
"mouseWheelZoom": true
},
"basemap": {
"type": "default",
"name": "Basemap"
},
"layers": [
{
"type": "route",
"name": "Drive",
"config": {
"style": {
"color": {
"fixed": "#E0424C"
},
"size": {
"fixed": 3
},
"opacity": 0.9
}
},
"location": {
"mode": "coords",
"latitude": "lat",
"longitude": "lon"
}
}
]
}
},
{
"id": 10,
"type": "timeseries",
"title": "Battery voltage and current",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 12,
"y": 12,
"w": 12,
"h": 6
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and (r._field == \"voltage\" or r._field == \"current\"))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> keep(columns: [\"_time\", \"_field\", \"_value\"])"
}
],
"fieldConfig": {
"defaults": {
"unit": "volt",
"custom": {
"lineWidth": 2,
"fillOpacity": 8,
"spanNulls": 600000,
"showPoints": "never"
}
},
"overrides": [
{
"matcher": {
"id": "byRegexp",
"options": ".*current.*"
},
"properties": [
{
"id": "unit",
"value": "amp"
},
{
"id": "custom.axisPlacement",
"value": "right"
}
]
}
]
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "multi"
}
},
"description": "Traction battery. Current is negative while charging or regenerating."
},
{
"id": 11,
"type": "timeseries",
"title": "Tire pressures",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"gridPos": {
"x": 12,
"y": 18,
"w": 12,
"h": 6
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "influxdb",
"uid": "mg4-influxdb"
},
"query": "from(bucket: \"mg4\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"telemetry\" and r.installationId == \"${installationId}\" and (r._field == \"tire_pressure_fl\" or r._field == \"tire_pressure_fr\" or r._field == \"tire_pressure_rl\" or r._field == \"tire_pressure_rr\"))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> keep(columns: [\"_time\", \"_field\", \"_value\"])"
}
],
"fieldConfig": {
"defaults": {
"unit": "pressurekpa",
"custom": {
"lineWidth": 2,
"fillOpacity": 8,
"spanNulls": 600000,
"showPoints": "never"
}
},
"overrides": []
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "multi"
}
}
}
]
}