diff --git a/CHANGELOG.md b/CHANGELOG.md index ea79921..f13dd3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to econet-exporter are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +* Optional Grafana dashboard shipped as a ConfigMap in the Helm chart. Enable + with `hull.config.settings.grafanaDashboard.enabled=true`; the ConfigMap is + labeled `grafana_dashboard: "1"` for the Grafana sidecar to auto-import. The + dashboard uses the default Prometheus datasource (no hard-coded UID) and has a + multi-select `Device` filter driven by `econet_friendly_name`. Covers connect/ + heating/mode/setpoint/hot-water/alerts, setpoint range, hot-water availability, + energy + cost + water usage, a heating-state timeline, WiFi signal, and a + device-info table. Sidecar label/value and Grafana folder are configurable. + ## [v0.3.0] - 2026-07-05 ### Changed diff --git a/README.md b/README.md index 8f3bc03..3fe917d 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,22 @@ Polled usage: `econet_energy_usage_kwh`, `econet_water_usage_gallons`, > Note: `econet_wifi_signal_db` is only delivered over Rheem's MQTT push stream, > which this exporter does not use — it stays at `0`. +### 📈 Grafana dashboard + +The Helm chart ships a ready-made Grafana dashboard +(`helm/dashboards/econet-exporter.json`). It is **off by default**; enable it by +setting `hull.config.settings.grafanaDashboard.enabled=true`, which renders a +ConfigMap labeled `grafana_dashboard: "1"` for the [Grafana sidecar](https://github.com/grafana/helm-charts/tree/main/charts/grafana#sidecar-for-dashboards) +to auto-import. The dashboard uses the **default Prometheus datasource** (no +hard-coded UID) and has a multi-select **Device** filter backed by +`econet_friendly_name`. Tunables under `grafanaDashboard`: `label` / `labelValue` +(match your sidecar's watch config) and `folder` (target Grafana folder). + +```sh +helm upgrade --install econet ./helm \ + --set hull.config.settings.grafanaDashboard.enabled=true +``` + ## 📂 Project Structure - `proto/econet/v1alpha1/` - Protobuf definitions (source). - `api/econet/v1alpha1/` - Generated proto, grpc, grpc-gateway code. diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 784b020..a38ffad 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.6 +version: 0.2.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/dashboards/econet-exporter.json b/helm/dashboards/econet-exporter.json new file mode 100644 index 0000000..3ff02a0 --- /dev/null +++ b/helm/dashboards/econet-exporter.json @@ -0,0 +1,721 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { "type": "grafana", "uid": "-- Grafana --" }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "links": [], + "liveNow": false, + "refresh": "30s", + "schemaVersion": 39, + "tags": ["econet", "rheem", "water-heater"], + "templating": { + "list": [ + { + "current": {}, + "hide": 0, + "includeAll": false, + "label": "Data source", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "current": {}, + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "definition": "label_values(econet_device_info, econet_friendly_name)", + "hide": 0, + "includeAll": true, + "label": "Device", + "multi": true, + "name": "device", + "options": [], + "query": { + "query": "label_values(econet_device_info, econet_friendly_name)", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "sort": 1, + "type": "query" + } + ] + }, + "time": { "from": "now-24h", "to": "now" }, + "timepicker": {}, + "timezone": "", + "title": "EcoNet Water Heater", + "uid": "econet-exporter", + "version": 1, + "weekStart": "", + "panels": [ + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, + "id": 1, + "title": "Overview", + "type": "row", + "panels": [] + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [ + { "options": { "0": { "color": "red", "index": 1, "text": "Offline" } }, "type": "value" }, + { "options": { "1": { "color": "green", "index": 0, "text": "Online" } }, "type": "value" } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "red", "value": null }, + { "color": "green", "value": 1 } + ] + } + }, + "overrides": [] + }, + "gridPos": { "h": 4, "w": 4, "x": 0, "y": 1 }, + "id": 2, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, + "textMode": "auto" + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_connected{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Connected", + "type": "stat" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [ + { "options": { "0": { "color": "blue", "index": 1, "text": "Idle" } }, "type": "value" }, + { "options": { "1": { "color": "orange", "index": 0, "text": "Heating" } }, "type": "value" } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "blue", "value": null }, + { "color": "orange", "value": 1 } + ] + } + }, + "overrides": [] + }, + "gridPos": { "h": 4, "w": 4, "x": 4, "y": 1 }, + "id": 3, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, + "textMode": "auto" + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_running{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_running_state}}", + "refId": "A" + } + ], + "title": "Heating State", + "type": "stat" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "fixed", "fixedColor": "purple" }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [{ "color": "purple", "value": null }] } + }, + "overrides": [] + }, + "gridPos": { "h": 4, "w": 4, "x": 8, "y": 1 }, + "id": 4, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, + "textMode": "name" + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_mode{econet_friendly_name=~\"$device\"} == 1", + "legendFormat": "{{econet_mode}}", + "refId": "A" + } + ], + "title": "Mode", + "type": "stat" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [], + "unit": "fahrenheit", + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "blue", "value": null }, + { "color": "green", "value": 110 }, + { "color": "orange", "value": 130 } + ] + } + }, + "overrides": [] + }, + "gridPos": { "h": 4, "w": 4, "x": 12, "y": 1 }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, + "textMode": "auto" + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_setpoint_fahrenheit{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Setpoint", + "type": "stat" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [], + "max": 100, + "min": 0, + "unit": "percent", + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "red", "value": null }, + { "color": "orange", "value": 25 }, + { "color": "green", "value": 60 } + ] + } + }, + "overrides": [] + }, + "gridPos": { "h": 4, "w": 4, "x": 16, "y": 1 }, + "id": 6, + "options": { + "orientation": "auto", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_hot_water_availability_percent{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Hot Water Available", + "type": "gauge" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "mappings": [], + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "green", "value": null }, + { "color": "red", "value": 1 } + ] + } + }, + "overrides": [] + }, + "gridPos": { "h": 4, "w": 4, "x": 20, "y": 1 }, + "id": 7, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, + "textMode": "auto" + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_alert_count{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Active Alerts", + "type": "stat" + }, + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, + "id": 10, + "title": "Temperature & Hot Water", + "type": "row", + "panels": [] + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "lineInterpolation": "stepAfter", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { "type": "linear" }, + "showPoints": "never", + "spanNulls": true, + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } + }, + "mappings": [], + "unit": "fahrenheit" + }, + "overrides": [ + { + "matcher": { "id": "byRegexp", "options": ".*min.*" }, + "properties": [{ "id": "custom.lineStyle", "value": { "dash": [10, 10], "fill": "dash" } }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "blue" } }] + }, + { + "matcher": { "id": "byRegexp", "options": ".*max.*" }, + "properties": [{ "id": "custom.lineStyle", "value": { "dash": [10, 10], "fill": "dash" } }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "red" } }] + } + ] + }, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 6 }, + "id": 11, + "options": { + "legend": { "calcs": ["lastNotNull", "min", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_setpoint_fahrenheit{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}} setpoint", + "refId": "A" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_setpoint_min_fahrenheit{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}} min", + "refId": "B" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_setpoint_max_fahrenheit{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}} max", + "refId": "C" + } + ], + "title": "Setpoint (with allowed range)", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 20, + "gradientMode": "opacity", + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { "type": "linear" }, + "showPoints": "never", + "spanNulls": true, + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } + }, + "mappings": [], + "max": 100, + "min": 0, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 6 }, + "id": 12, + "options": { + "legend": { "calcs": ["lastNotNull", "min"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_hot_water_availability_percent{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Hot Water Availability", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 }, + "id": 20, + "title": "Energy & Water", + "type": "row", + "panels": [] + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 60, + "gradientMode": "none", + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { "type": "linear" }, + "showPoints": "never", + "spanNulls": true, + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } + }, + "mappings": [], + "unit": "kwatth" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 8, "x": 0, "y": 15 }, + "id": 21, + "options": { + "legend": { "calcs": ["lastNotNull", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_energy_usage_kwh * on(econet_serial) group_left(econet_friendly_name) econet_device_info{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Energy Usage Today (kWh)", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 60, + "gradientMode": "none", + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { "type": "linear" }, + "showPoints": "never", + "spanNulls": true, + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } + }, + "mappings": [], + "unit": "currencyUSD" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 8, "x": 8, "y": 15 }, + "id": 22, + "options": { + "legend": { "calcs": ["lastNotNull", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_energy_cost_dollars * on(econet_serial) group_left(econet_friendly_name) econet_device_info{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Energy Cost Today ($)", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 60, + "gradientMode": "none", + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { "type": "linear" }, + "showPoints": "never", + "spanNulls": true, + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } + }, + "mappings": [], + "unit": "volgal" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 8, "x": 16, "y": 15 }, + "id": 23, + "options": { + "legend": { "calcs": ["lastNotNull", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_water_usage_gallons * on(econet_serial) group_left(econet_friendly_name) econet_device_info{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "Water Usage Today (gal)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 23 }, + "id": 30, + "title": "Device Health", + "type": "row", + "panels": [] + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "custom": { "fillOpacity": 80, "lineWidth": 0 }, + "mappings": [ + { "options": { "0": { "color": "blue", "index": 1, "text": "Idle" } }, "type": "value" }, + { "options": { "1": { "color": "orange", "index": 0, "text": "Heating" } }, "type": "value" } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "blue", "value": null }, + { "color": "orange", "value": 1 } + ] + } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 24 }, + "id": 31, + "options": { + "alignValue": "left", + "legend": { "displayMode": "list", "placement": "bottom", "showLegend": true }, + "mergeValues": true, + "rowHeight": 0.9, + "showValue": "auto", + "tooltip": { "mode": "single", "sort": "none" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_running{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}} ({{econet_running_state}})", + "refId": "A" + } + ], + "title": "Heating Timeline", + "type": "state-timeline" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { "type": "linear" }, + "showPoints": "never", + "spanNulls": true, + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } + }, + "mappings": [], + "unit": "dB" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 6, "x": 12, "y": 24 }, + "id": 32, + "options": { + "legend": { "calcs": ["lastNotNull"], "displayMode": "list", "placement": "bottom", "showLegend": true }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_wifi_signal_db{econet_friendly_name=~\"$device\"}", + "legendFormat": "{{econet_friendly_name}}", + "refId": "A" + } + ], + "title": "WiFi Signal", + "type": "timeseries" + }, + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "custom": { "align": "auto", "cellOptions": { "type": "auto" }, "inspect": false }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] } + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 6, "x": 18, "y": 24 }, + "id": 33, + "options": { + "cellHeight": "sm", + "footer": { "countRows": false, "fields": "", "reducer": ["sum"], "show": false }, + "showHeader": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { "type": "prometheus", "uid": "${datasource}" }, + "expr": "econet_device_info{econet_friendly_name=~\"$device\"}", + "format": "table", + "instant": true, + "refId": "A" + } + ], + "title": "Device Info", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { "Time": true, "Value": true, "__name__": true, "job": true, "instance": true }, + "indexByName": {}, + "renameByName": { + "econet_friendly_name": "Name", + "econet_serial": "Serial", + "econet_device_id": "Device ID", + "econet_type": "Type", + "econet_generic_type": "Generic Type", + "econet_mode": "Mode" + } + } + } + ], + "type": "table" + } + ] +} diff --git a/helm/templates/grafana-dashboard.yaml b/helm/templates/grafana-dashboard.yaml new file mode 100644 index 0000000..82d0628 --- /dev/null +++ b/helm/templates/grafana-dashboard.yaml @@ -0,0 +1,20 @@ +{{- $gd := .Values.hull.config.settings.grafanaDashboard | default dict }} +{{- if $gd.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-grafana-dashboard + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Chart.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- /* Label the Grafana sidecar watches for to auto-import dashboards */}} + {{ $gd.label | default "grafana_dashboard" }}: {{ $gd.labelValue | default "1" | quote }} + {{- with $gd.folder }} + annotations: + grafana_folder: {{ . | quote }} + {{- end }} +data: + econet-exporter.json: |- +{{ .Files.Get "dashboards/econet-exporter.json" | indent 4 }} +{{- end }} diff --git a/helm/values.yaml b/helm/values.yaml index e4dccea..f6b83b5 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -58,6 +58,18 @@ hull: otelResourceAttributes: app=econet-exporter otlpEndpoint: http://otel.otel.svc.cluster.local:4317 # Replace me + # Ship a ready-made Grafana dashboard as a ConfigMap for the Grafana + # sidecar to auto-import (kiwigrid/k8s-sidecar). Flip enabled to true; + # the dashboard uses the default Prometheus datasource and filters by + # device name. No datasource UID hard-coding required. + grafanaDashboard: + enabled: false + # Label/value the Grafana sidecar is configured to watch for. + label: grafana_dashboard + labelValue: "1" + # Optional Grafana folder to file the dashboard under (blank = General). + folder: "" + serviceType: ClusterIP serviceLbIP: "" # Used if serviceTyps=LoadBalancer