From 4ca2e399016e31ab655e692aa5a02f34ee26bc86 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 15 Mar 2026 18:31:19 -0700 Subject: [PATCH] Externalize TeslaMate dashboards to forge mirror (#296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Replaces 18 TeslaMate dashboard ConfigMaps (713 KB / 22,080 lines) with a Grafana init container - Init container fetches dashboard JSON directly from `mirrors/teslamate` on forge, pinned to `v3.0.0` - Grafana's file provider picks them up from `/tmp/dashboards/TeslaMate/` via `foldersFromFilesStructure` - Non-TeslaMate dashboards remain as ConfigMaps (unchanged) ## How it works - New `init-teslamate-dashboards` init container uses busybox `wget` to fetch each JSON file from `https://forge.eblu.me/mirrors/teslamate/raw/tag/v3.0.0/grafana/dashboards/` - Files land in `/tmp/dashboards/TeslaMate/`, same emptyDir volume the sidecar uses - The sidecar continues to handle ConfigMap-based dashboards; the init container handles TeslaMate - Version pin is in the init container args (TESLAMATE_VERSION) ## Deployment and Testing - [ ] Sync `grafana` app from branch — verify init container runs and fetches dashboards - [ ] Sync `grafana-config` app from branch — verify TeslaMate ConfigMaps are pruned - [ ] Check Grafana UI: TeslaMate folder should still contain all 18 dashboards - [ ] Verify non-TeslaMate dashboards are unaffected - [ ] After merge: sync both apps from main Reviewed-on: https://forge.eblu.me/eblume/blumeops/pulls/296 --- .../configmap-teslamate-battery-health.yaml | 1761 ---------- .../configmap-teslamate-charge-level.yaml | 419 --- .../configmap-teslamate-charges.yaml | 1537 --------- .../configmap-teslamate-charging-stats.yaml | 2428 -------------- .../configmap-teslamate-drive-stats.yaml | 1603 ---------- .../configmap-teslamate-drives.yaml | 1636 ---------- .../configmap-teslamate-efficiency.yaml | 1187 ------- .../configmap-teslamate-locations.yaml | 1200 ------- .../configmap-teslamate-mileage.yaml | 293 -- .../configmap-teslamate-overview.yaml | 1990 ------------ .../configmap-teslamate-projected-range.yaml | 772 ----- .../configmap-teslamate-states.yaml | 528 --- .../configmap-teslamate-statistics.yaml | 1262 -------- .../configmap-teslamate-timeline.yaml | 770 ----- .../dashboards/configmap-teslamate-trip.yaml | 2819 ----------------- .../configmap-teslamate-updates.yaml | 619 ---- .../configmap-teslamate-vampire-drain.yaml | 666 ---- .../configmap-teslamate-visited.yaml | 571 ---- .../grafana-config/kustomization.yaml | 22 +- argocd/manifests/grafana/deployment.yaml | 45 + argocd/manifests/grafana/kustomization.yaml | 2 + .../externalize-teslamate-dashboards.infra.md | 1 + 22 files changed, 51 insertions(+), 22080 deletions(-) delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-battery-health.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-charge-level.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-charges.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-charging-stats.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-drive-stats.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-drives.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-efficiency.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-locations.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-mileage.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-overview.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-projected-range.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-states.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-statistics.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-timeline.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-trip.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-updates.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-vampire-drain.yaml delete mode 100644 argocd/manifests/grafana-config/dashboards/configmap-teslamate-visited.yaml create mode 100644 docs/changelog.d/externalize-teslamate-dashboards.infra.md diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-battery-health.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-battery-health.yaml deleted file mode 100644 index 0ca9f0f..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-battery-health.yaml +++ /dev/null @@ -1,1761 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-battery-health - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-battery-health.json: | - { - "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": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "**Usable (now)** is the estimated current battery capacity. It is average of the estimated capacity reported by the last 10 charging sessions to have a better estimation.\n\nIf you see just '1.0 kWh' here, it means that you need at least a long charge session.\n\n**Usable (new)** is the estimated Battery Capacity since you begun to use TeslaMate. That's why, the more data you have logged from your brand new car the better. For those who have not used TeslaMate since they got their new car, or for those who have bought it second hand, it's possible to set the max range to 100% and the battery capacity of the car battery when it was new in order to get a better and accurate estimation.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 1, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - }, - { - "color": "dark-red", - "value": 1 - }, - { - "color": "super-light-blue", - "value": 2 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 0, - "y": 0 - }, - "id": 13, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT \n CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json ->> 'MaxCapacity')::float END as \"Usable (new)\", \n ('$aux'::json ->> 'CurrentCapacity')::float as \"Usable (now)\",\n ('$aux'::json ->> 'CurrentCapacity')::float - CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json ->> 'MaxCapacity')::float END as \"Difference\"", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Battery Capacity", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 1, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/.*_km/" - }, - "properties": [ - { - "id": "unit", - "value": "lengthkm" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_mi/" - }, - "properties": [ - { - "id": "unit", - "value": "lengthmi" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/maxrange_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Max range (new)" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/currentrange_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Max range (now)" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/range_lost.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Range lost" - } - ] - } - ] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 6, - "y": 0 - }, - "id": 14, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT \n CASE WHEN $custom_max_range > 0 THEN $custom_max_range ELSE ('$aux'::json ->> 'MaxRange')::float END as \"maxrange_$length_unit\",\n ('$aux'::json ->> 'CurrentRange')::float as \"currentrange_$length_unit\",\n CASE WHEN $custom_max_range > 0 THEN $custom_max_range ELSE ('$aux'::json ->> 'MaxRange')::float END - ('$aux'::json ->> 'CurrentRange')::float as \"range_lost_$length_unit\"", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ranges [$preferred_range]", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "\"Logged\" is the distance traveled that is saved on TeslaMate database.\n\n\"Mileage\" is the distance the car has traveled since using TeslaMate.\n\nSo, if there is a difference between both values, it is the distance that for some reason a drive hasn't been fully recorded, for example due to a bug or an unexpected restart and that TeslaMate has not been able to record, either due to lack of connection, areas without signal, or that it has been out of service.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 12, - "y": 0 - }, - "id": 37, - "links": [ - { - "targetBlank": true, - "title": "Drive Stats", - "url": "/d/_7WkNSyWk/drive-stats" - } - ], - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "/.*/", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select ROUND(convert_km(sum(distance)::numeric, '$length_unit'),0)|| ' $length_unit' as \"Logged\"\r\nfrom drives \r\nwhere car_id = $car_id;\r\n", - "refId": "Logged", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT ROUND(convert_km((max(end_km) - min(start_km))::numeric, '$length_unit'),0)|| ' $length_unit' as \"Mileage\"\nFROM drives WHERE car_id = $car_id;", - "refId": "Mileage", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT ROUND(convert_km(max(end_km)::numeric, '$length_unit'),0) || ' $length_unit' as \"Odometer\"\nFROM drives WHERE car_id = $car_id;", - "refId": "Odometer", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT (\r\n (SELECT ROUND(convert_km((max(end_km) - min(start_km))::numeric, '$length_unit'),0) FROM drives WHERE car_id = $car_id) - \r\n (SELECT ROUND(convert_km(sum(distance)::numeric, '$length_unit'),0) from drives where car_id = $car_id) || ' $length_unit'\r\n)\r\nAS \"Data lost (not logged)\"", - "refId": "Data Lost", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Drive Stats", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "decimals": 2, - "mappings": [], - "unit": "kwatth" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "AC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "semi-dark-green", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "DC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "light-orange", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 13, - "w": 6, - "x": 18, - "y": 0 - }, - "id": 34, - "maxDataPoints": 3, - "options": { - "displayLabels": [ - "name", - "percent", - "value" - ], - "legend": { - "displayMode": "list", - "placement": "right", - "showLegend": false, - "values": [ - "value" - ] - }, - "pieType": "pie", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n\t\tcp.id,\n\t\tcp.charge_energy_added,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC'\n\t\t\t\t ELSE 'AC'\n\t\tEND AS current,\n\t\tcp.charge_energy_used\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n\t AND cp.charge_energy_added > 0.01\n GROUP BY 1,2\n)\nSELECT\n\tnow() AS time,\n\tSUM(GREATEST(charge_energy_added, charge_energy_used)) AS value,\n\tcurrent AS metric\nFROM data\nGROUP BY 3\nORDER BY metric DESC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "AC/DC - Energy Used", - "type": "piechart" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "This dashboard is meant to have a look of the Battery health based on the data logged in TeslaMate. So, the more data you have logged from your brand new car the better.\n\n**Degradation** is just an estimated value to have a reference, measured on **usable battery level** of every charging session with enough kWh added (in order to avoid dirty data from the sample), calculated according to the rated efficiency of the car.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 1, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "#EAB839", - "value": 10 - }, - { - "color": "red", - "value": 20 - }, - { - "color": "dark-red", - "value": 30 - } - ] - }, - "unit": "%" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 0, - "y": 6 - }, - "id": 17, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [], - "fields": "/^greatest$/", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT GREATEST(0, 100.0 - (('$aux'::json ->> 'CurrentCapacity')::float * 100.0 / CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json ->> 'MaxCapacity')::float END))\n\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Estimated Degradation", - "type": "gauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 1, - "mappings": [], - "max": 100, - "min": 1, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "light-red", - "value": 0 - }, - { - "color": "#EAB839", - "value": 80 - }, - { - "color": "light-green", - "value": 90 - } - ] - }, - "unit": "%" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 6, - "y": 6 - }, - "id": 12, - "options": { - "displayMode": "gradient", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 10, - "minVizWidth": 0, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showUnfilled": true, - "sizing": "auto", - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT \n LEAST(100, (100 - GREATEST(0, 100.0 - (('$aux'::json ->> 'CurrentCapacity')::float * 100.0 / CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json ->> 'MaxCapacity')::float END)))) as \"Battery Health (%)\"\n \n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Battery Health", - "type": "bargauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "\"# of Charging cycles\" is estimated by dividing the whole energy added to the battery by the battery capacity when new.\n\n\"Charging Efficiency\" is estimated on the difference between energy used from the charger and energy added to the battery.", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "light-yellow", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Total Energy added" - }, - "properties": [ - { - "id": "unit", - "value": "kwatth" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Total Energy used" - }, - "properties": [ - { - "id": "unit", - "value": "kwatth" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Charging Efficiency" - }, - "properties": [ - { - "id": "unit", - "value": "percentunit" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 12, - "y": 6 - }, - "id": 36, - "links": [ - { - "targetBlank": true, - "title": "Charging Stats", - "url": "/d/-pkIkhmRz/charging-stats" - } - ], - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n\tCOUNT(*) AS \"# of Charges\"\r\nFROM\r\n\tcharging_processes\r\nWHERE\r\n\tcar_id = $car_id AND charge_energy_added > 0.01\r\n\t", - "refId": "# of Charges", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tfloor(sum(charge_energy_added) / CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json ->> 'MaxCapacity')::float END) AS \"# of Charging cycles\"\nFROM charging_processes WHERE car_id = $car_id AND charge_energy_added > 0.01", - "refId": "# of Charging cycles", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tsum(charge_energy_added) as \"Total Energy added\"\nFROM\n\tcharging_processes\nWHERE\n\tcar_id = $car_id AND charge_energy_added > 0.01", - "refId": "Total Energy added", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n\tSUM(greatest(charge_energy_added, charge_energy_used)) AS \"Total Energy used\"\r\nFROM\r\n\tcharging_processes\r\nWHERE\r\n\tcar_id = $car_id AND charge_energy_added > 0.01\r\n", - "refId": "Total Energy used", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n\tSUM(charge_energy_added) / SUM(greatest(charge_energy_added, charge_energy_used)) AS \"Charging Efficiency\"\r\nFROM\r\n\tcharging_processes\r\nWHERE\r\n\tcar_id = $car_id AND charge_energy_added > 0.01\r\n", - "refId": "Charging Efficiency", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charging Stats", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 1, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "transparent", - "value": 0 - } - ] - }, - "unit": "%" - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 4, - "x": 6, - "y": 9 - }, - "id": 25, - "options": { - "displayMode": "lcd", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 10, - "minVizWidth": 0, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showUnfilled": true, - "sizing": "auto", - "text": {}, - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT * FROM ((SELECT usable_battery_level, date\r\nFROM positions\r\nWHERE car_id = $car_id AND usable_battery_level IS NOT NULL\r\nORDER BY date DESC\r\nLIMIT 1)\r\nUNION\r\n(SELECT usable_battery_level, date\r\nFROM charges c\r\nJOIN charging_processes p ON p.id = c.charging_process_id\r\nWHERE p.car_id = $car_id AND usable_battery_level IS NOT NULL\r\nORDER BY date DESC\r\nLIMIT 1)) AS last_usable_battery_level LIMIT 1", - "refId": "SOC", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n 0 as lowest,\r\n 20 as lower,\r\n CASE WHEN lfp_battery THEN 100 ELSE 81 END as upper\r\nfrom cars inner join car_settings on cars.settings_id = car_settings.id\r\nwhere cars.id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Current SOC", - "transformations": [ - { - "id": "configFromData", - "options": { - "applyTo": { - "id": "byFrameRefID", - "options": "SOC" - }, - "configRefId": "A", - "mappings": [ - { - "fieldName": "lower", - "handlerArguments": { - "threshold": { - "color": "green" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "upper", - "handlerArguments": { - "threshold": { - "color": "orange" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "lowest", - "handlerKey": "threshold1" - } - ] - } - } - ], - "type": "bargauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "This is the Derived Rated Efficiency that TeslaMate calculates based on battery charges. \nThis information can be seen in more detail on the \"Efficiency\" dashboard.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/.*_km/" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_mi/" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 4, - "w": 2, - "x": 10, - "y": 9 - }, - "id": 32, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "/.*/", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT ('$aux'::json ->> 'RatedEfficiency')::float * 10 / convert_km(1, '$length_unit') AS efficiency_$length_unit", - "refId": "Logged", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Efficiency", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 1, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-red", - "value": 0 - }, - { - "color": "dark-green", - "value": 7.84 - }, - { - "color": "semi-dark-orange", - "value": 31.36 - }, - { - "color": "light-blue", - "value": 35.28 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 4, - "x": 6, - "y": 11 - }, - "id": 27, - "options": { - "displayMode": "gradient", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 10, - "minVizWidth": 0, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "/^kwh$/", - "values": false - }, - "showUnfilled": true, - "sizing": "auto", - "text": {}, - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT * FROM ((SELECT usable_battery_level * ('$aux'::json ->> 'CurrentCapacity')::float / 100 as kWh, date, ('$aux'::json ->> 'CurrentCapacity')::float as Total\nFROM positions\nWHERE car_id = $car_id AND usable_battery_level IS NOT NULL\nORDER BY date DESC\nLIMIT 1)\nUNION\n(SELECT battery_level * ('$aux'::json ->> 'CurrentCapacity')::float / 100 as kWh, date, ('$aux'::json ->> 'CurrentCapacity')::float as Total\nFROM charges c\nJOIN charging_processes p ON p.id = c.charging_process_id\nWHERE p.car_id = $car_id AND usable_battery_level IS NOT NULL\nORDER BY date DESC\nLIMIT 1)) AS last_usable_battery_level LIMIT 1", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Current Stored Energy", - "type": "bargauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-RdYlGr", - "seriesBy": "last" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "fillOpacity": 50, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineWidth": 2, - "pointShape": "circle", - "pointSize": { - "fixed": 5 - }, - "pointStrokeWidth": 1, - "scaleDistribution": { - "type": "linear" - }, - "show": "points" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byFrameRefID", - "options": "Median" - }, - "properties": [ - { - "id": "custom.show", - "value": "lines" - }, - { - "id": "color", - "value": { - "fixedColor": "dark-red", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Odometer" - }, - "properties": [ - { - "id": "displayName", - "value": "Mileage" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "kWh" - }, - "properties": [ - { - "id": "displayName", - "value": "Battery Capacity" - }, - { - "id": "unit", - "value": "kwatth" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 13 - }, - "id": 28, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "mapping": "manual", - "series": [ - { - "color": { - "matcher": { - "id": "byName", - "options": "kWh" - } - }, - "frame": { - "matcher": { - "id": "byIndex", - "options": 0 - } - }, - "x": { - "matcher": { - "id": "byName", - "options": "Odometer" - } - }, - "y": { - "matcher": { - "id": "byName", - "options": "kWh" - } - } - }, - { - "frame": { - "matcher": { - "id": "byIndex", - "options": 1 - } - }, - "x": { - "matcher": { - "id": "byName", - "options": "Odometer" - } - }, - "y": { - "matcher": { - "id": "byName", - "options": "kWh" - } - } - } - ], - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT convert_km(AVG(p.odometer)::numeric,'$length_unit') AS \"Odometer\", \r\n\tAVG(c.rated_battery_range_km * ('$aux'::json ->> 'RatedEfficiency')::float / c.usable_battery_level) AS \"kWh\",\r\n\t--MAX(cp.id) AS id,\r\n\tto_char(timezone('$__timezone', timezone('UTC', cp.end_date)), 'YYYY-MM-dd') AS \"Date\"\r\n\tFROM charging_processes cp\r\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\tFROM charges WHERE usable_battery_level > 0 GROUP BY charging_process_id) AS last_charges\tON cp.id = last_charges.charging_process_id\r\n\t\tINNER JOIN charges c\r\n\t\tON c.charging_process_id = cp.id AND c.date = last_charges.date\r\n\t\tINNER JOIN positions p ON p.id = cp.position_id\r\n\tWHERE cp.car_id = $car_id\r\n\t\tAND cp.end_date IS NOT NULL\r\n\t\tAND cp.charge_energy_added >= ('$aux'::json ->> 'RatedEfficiency')::float\r\n\tGROUP BY 3", - "refId": "Projected Range", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT \n ROUND(MIN(convert_km(p.odometer::numeric,'$length_unit')),0) AS \"Odometer\",\n\tROUND(PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY c.rated_battery_range_km * ('$aux'::json ->> 'RatedEfficiency')::float / c.usable_battery_level)::numeric,1) AS \"kWh\",\n\tto_char(timezone('$__timezone', timezone('UTC', cp.end_date)), 'YYYYMM') || CASE WHEN to_char(timezone('$__timezone', timezone('UTC', cp.end_date)), 'DD')::int <= 15 THEN '1' ELSE '2' END AS Title\n\tFROM charging_processes cp\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\tFROM charges WHERE usable_battery_level > 0 GROUP BY charging_process_id) AS last_charges\tON cp.id = last_charges.charging_process_id\n\t\tINNER JOIN charges c\n\t\tON c.charging_process_id = cp.id AND c.date = last_charges.date\n\t\tINNER JOIN positions p ON p.id = cp.position_id\n\tWHERE cp.car_id = $car_id\n\t\tAND cp.end_date IS NOT NULL\n\t\tAND cp.charge_energy_added >= ('$aux'::json ->> 'RatedEfficiency')::float\n\tGROUP BY 3", - "refId": "Median", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Battery Capacity by Mileage", - "type": "xychart" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC", - "includeAll": false, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT unit_of_length FROM settings LIMIT 1", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "SELECT unit_of_length FROM settings LIMIT 1", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT preferred_range FROM settings LIMIT 1", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "SELECT preferred_range FROM settings LIMIT 1", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT base_url FROM settings LIMIT 1", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "SELECT base_url FROM settings LIMIT 1", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "WITH Aux as (\n SELECT \n car_id,\n COALESCE(derived_efficiency, car_efficiency) AS efficiency\n FROM (\n SELECT\n ROUND((charge_energy_added / NULLIF(end_rated_range_km - start_rated_range_km, 0))::numeric, 3) * 100 AS derived_efficiency,\n COUNT(*) as count,\n cars.id as car_id,\n cars.efficiency * 100 AS car_efficiency\n FROM cars\n LEFT JOIN charging_processes ON\n cars.id = charging_processes.car_id \n AND duration_min > 10\n AND end_battery_level <= 95\n AND start_rated_range_km IS NOT NULL\n AND end_rated_range_km IS NOT NULL\n AND charge_energy_added > 0\n WHERE cars.id = $car_id\n GROUP BY 1, 3, 4\n ORDER BY 2 DESC\n LIMIT 1\n ) AS Efficiency\n),\n\nCurrentCapacity AS (\n SELECT\n AVG(Capacity) AS Capacity\n FROM (\n SELECT \n c.rated_battery_range_km * aux.efficiency / c.usable_battery_level AS Capacity\n FROM charging_processes cp\n INNER JOIN charges c ON c.charging_process_id = cp.id \n INNER JOIN aux ON cp.car_id = aux.car_id\n WHERE\n cp.car_id = $car_id\n AND cp.end_date IS NOT NULL\n AND cp.charge_energy_added >= aux.efficiency\n AND c.usable_battery_level > 0\n ORDER BY cp.end_date DESC, c.date desc\n LIMIT 100\n ) AS lastCharges\n),\n\nMaxCapacity AS (\n SELECT \n MAX(c.rated_battery_range_km * aux.efficiency / c.usable_battery_level) AS Capacity\n FROM charging_processes cp\n INNER JOIN (\n SELECT\n charging_process_id,\n MAX(date) as date FROM charges WHERE usable_battery_level > 0 GROUP BY charging_process_id\n ) AS gcharges ON\n cp.id = gcharges.charging_process_id\n INNER JOIN charges c ON\n c.charging_process_id = cp.id\n AND c.date = gcharges.date\n INNER JOIN aux ON cp.car_id = aux.car_id\n WHERE\n cp.car_id = $car_id\n AND cp.end_date IS NOT NULL\n AND cp.charge_energy_added >= aux.efficiency\n),\n\nCurrentRange AS (\n SELECT\n (range * 100.0 / usable_battery_level) AS range\n FROM (\n (\n SELECT\n date,\n ${preferred_range}_battery_range_km AS range,\n usable_battery_level AS usable_battery_level\n FROM positions\n WHERE\n car_id = $car_id\n AND ideal_battery_range_km IS NOT NULL\n AND usable_battery_level > 0 \n ORDER BY date DESC\n LIMIT 1\n )\n UNION ALL\n (\n SELECT date,\n ${preferred_range}_battery_range_km AS range,\n usable_battery_level as usable_battery_level\n FROM charges c\n INNER JOIN charging_processes p ON p.id = c.charging_process_id\n WHERE\n p.car_id = $car_id\n AND usable_battery_level > 0\n ORDER BY date DESC\n LIMIT 1\n )\n ) AS data\n ORDER BY date DESC\n LIMIT 1\n),\n\nMaxRange AS (\n SELECT\n floor(extract(epoch from date)/86400)*86400 AS time,\n CASE\n WHEN sum(usable_battery_level) = 0 THEN sum(${preferred_range}_battery_range_km) * 100\n ELSE sum(${preferred_range}_battery_range_km) / sum(usable_battery_level) * 100\n END AS range\n FROM (\n SELECT\n battery_level,\n usable_battery_level,\n date,\n ${preferred_range}_battery_range_km\n FROM charges c \n INNER JOIN charging_processes p ON p.id = c.charging_process_id \n WHERE\n p.car_id = $car_id\n AND usable_battery_level IS NOT NULL\n ) AS data\n GROUP BY 1\n ORDER BY 2 DESC\n LIMIT 1\n),\n\nBase AS (\n SELECT NULL\n)\n\nSELECT\n json_build_object(\n 'MaxRange', convert_km(MaxRange.range,'$length_unit'),\n 'CurrentRange', convert_km(CurrentRange.range,'$length_unit'),\n 'MaxCapacity', MaxCapacity.Capacity,\n 'CurrentCapacity', CASE WHEN CurrentCapacity.Capacity IS NULL THEN 1 ELSE CurrentCapacity.Capacity END,\n 'RatedEfficiency', aux.efficiency\n )\nFROM Base\n LEFT JOIN MaxRange ON true\n LEFT JOIN CurrentRange ON true\n LEFT JOIN Aux ON true\n LEFT JOIN MaxCapacity ON true\n LEFT JOIN CurrentCapacity ON true", - "hide": 2, - "includeAll": false, - "name": "aux", - "options": [], - "query": "WITH Aux as (\n SELECT \n car_id,\n COALESCE(derived_efficiency, car_efficiency) AS efficiency\n FROM (\n SELECT\n ROUND((charge_energy_added / NULLIF(end_rated_range_km - start_rated_range_km, 0))::numeric, 3) * 100 AS derived_efficiency,\n COUNT(*) as count,\n cars.id as car_id,\n cars.efficiency * 100 AS car_efficiency\n FROM cars\n LEFT JOIN charging_processes ON\n cars.id = charging_processes.car_id \n AND duration_min > 10\n AND end_battery_level <= 95\n AND start_rated_range_km IS NOT NULL\n AND end_rated_range_km IS NOT NULL\n AND charge_energy_added > 0\n WHERE cars.id = $car_id\n GROUP BY 1, 3, 4\n ORDER BY 2 DESC\n LIMIT 1\n ) AS Efficiency\n),\n\nCurrentCapacity AS (\n SELECT\n AVG(Capacity) AS Capacity\n FROM (\n SELECT \n c.rated_battery_range_km * aux.efficiency / c.usable_battery_level AS Capacity\n FROM charging_processes cp\n INNER JOIN charges c ON c.charging_process_id = cp.id \n INNER JOIN aux ON cp.car_id = aux.car_id\n WHERE\n cp.car_id = $car_id\n AND cp.end_date IS NOT NULL\n AND cp.charge_energy_added >= aux.efficiency\n AND c.usable_battery_level > 0\n ORDER BY cp.end_date DESC, c.date desc\n LIMIT 100\n ) AS lastCharges\n),\n\nMaxCapacity AS (\n SELECT \n MAX(c.rated_battery_range_km * aux.efficiency / c.usable_battery_level) AS Capacity\n FROM charging_processes cp\n INNER JOIN (\n SELECT\n charging_process_id,\n MAX(date) as date FROM charges WHERE usable_battery_level > 0 GROUP BY charging_process_id\n ) AS gcharges ON\n cp.id = gcharges.charging_process_id\n INNER JOIN charges c ON\n c.charging_process_id = cp.id\n AND c.date = gcharges.date\n INNER JOIN aux ON cp.car_id = aux.car_id\n WHERE\n cp.car_id = $car_id\n AND cp.end_date IS NOT NULL\n AND cp.charge_energy_added >= aux.efficiency\n),\n\nCurrentRange AS (\n SELECT\n (range * 100.0 / usable_battery_level) AS range\n FROM (\n (\n SELECT\n date,\n ${preferred_range}_battery_range_km AS range,\n usable_battery_level AS usable_battery_level\n FROM positions\n WHERE\n car_id = $car_id\n AND ideal_battery_range_km IS NOT NULL\n AND usable_battery_level > 0 \n ORDER BY date DESC\n LIMIT 1\n )\n UNION ALL\n (\n SELECT date,\n ${preferred_range}_battery_range_km AS range,\n usable_battery_level as usable_battery_level\n FROM charges c\n INNER JOIN charging_processes p ON p.id = c.charging_process_id\n WHERE\n p.car_id = $car_id\n AND usable_battery_level > 0\n ORDER BY date DESC\n LIMIT 1\n )\n ) AS data\n ORDER BY date DESC\n LIMIT 1\n),\n\nMaxRange AS (\n SELECT\n floor(extract(epoch from date)/86400)*86400 AS time,\n CASE\n WHEN sum(usable_battery_level) = 0 THEN sum(${preferred_range}_battery_range_km) * 100\n ELSE sum(${preferred_range}_battery_range_km) / sum(usable_battery_level) * 100\n END AS range\n FROM (\n SELECT\n battery_level,\n usable_battery_level,\n date,\n ${preferred_range}_battery_range_km\n FROM charges c \n INNER JOIN charging_processes p ON p.id = c.charging_process_id \n WHERE\n p.car_id = $car_id\n AND usable_battery_level IS NOT NULL\n ) AS data\n GROUP BY 1\n ORDER BY 2 DESC\n LIMIT 1\n),\n\nBase AS (\n SELECT NULL\n)\n\nSELECT\n json_build_object(\n 'MaxRange', convert_km(MaxRange.range,'$length_unit'),\n 'CurrentRange', convert_km(CurrentRange.range,'$length_unit'),\n 'MaxCapacity', MaxCapacity.Capacity,\n 'CurrentCapacity', CASE WHEN CurrentCapacity.Capacity IS NULL THEN 1 ELSE CurrentCapacity.Capacity END,\n 'RatedEfficiency', aux.efficiency\n )\nFROM Base\n LEFT JOIN MaxRange ON true\n LEFT JOIN CurrentRange ON true\n LEFT JOIN Aux ON true\n LEFT JOIN MaxCapacity ON true\n LEFT JOIN CurrentCapacity ON true", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "0", - "value": "0" - }, - "description": "Set the capacity of your car battery when it was new, in case you started using TeslaMate after a while of having it. If not, leave it at 0, it will be calculated with the data that is logged in TeslaMate", - "label": "Custom Battery Capacity (kWh) when new", - "name": "custom_kwh_new", - "options": [ - { - "selected": true, - "text": "0", - "value": "0" - } - ], - "query": "0", - "type": "textbox" - }, - { - "current": { - "text": "0", - "value": "0" - }, - "description": "Set the max range to 100% of your car when it was new, in case you started using TeslaMate after a while of having it. If not, leave it at 0, the degradation will be calculated with the data that is logged in TeslaMate", - "label": "Custom Max Range when new", - "name": "custom_max_range", - "options": [ - { - "selected": true, - "text": "0", - "value": "0" - } - ], - "query": "0", - "type": "textbox" - } - ] - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": { - "hidden": true - }, - "timezone": "browser", - "title": "Tesla Battery Health", - "uid": "jchmRiqUfXgTM", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charge-level.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charge-level.yaml deleted file mode 100644 index 7ecc25b..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charge-level.yaml +++ /dev/null @@ -1,419 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-charge-level - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-charge-level.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "Charge Level", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "stepAfter", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "line" - } - }, - "decimals": 0, - "links": [], - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "transparent", - "value": 0 - } - ] - }, - "unit": "percent" - }, - "overrides": [] - }, - "gridPos": { - "h": 21, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "options": { - "legend": { - "calcs": [ - "mean", - "max", - "min" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\tdate_bin('2 minutes'::interval, timezone('UTC', date), to_timestamp(${__from:date:seconds})) as time,\n\tavg(battery_level) AS \"Battery Level\",\n\tavg(usable_battery_level) AS \"Usable Battery Level\"\nfrom positions\n\tWHERE $__timeFilter(date) AND car_id = $car_id and ideal_battery_range_km is not null\n\tgroup by time\n\tORDER BY time ASC\n;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n 20 as lower,\r\n CASE WHEN lfp_battery THEN 100 ELSE 80 END as upper\r\nfrom cars inner join car_settings on cars.settings_id = car_settings.id\r\nwhere cars.id = $car_id", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "-- To be able to calculate percentiles for unevenly sampled values we are bucketing & gapfilling values before running calculations\r\nwith positions_filtered as (\r\n select\r\n date,\r\n battery_level\r\n from\r\n positions p\r\n where\r\n p.car_id = $car_id\r\n -- p.ideal_battery_range_km condition is added to reduce overall amount of data and avoid data biases while driving (unevenly sampled data)\r\n and p.ideal_battery_range_km is not null\r\n and 1 = $include_average_percentiles\r\n),\r\ngen_date_series as (\r\n select\r\n -- series is used to bucket data and avoid gaps in series used to determine percentiles\r\n generate_series(to_timestamp(${__from:date:seconds} - (86400 * $days_moving_average_percentiles / 2)), to_timestamp(${__to:date:seconds}), concat($bucket_width, ' seconds')::INTERVAL) as series_id\r\n),\r\ndate_series as (\r\n select\r\n timezone('UTC', series_id) as series_id,\r\n -- before joining, get beginning of next series to be able to left join `positions_filtered`\r\n timezone('UTC', lead(series_id) over (order by series_id asc)) as next_series_id\r\n from\r\n gen_date_series\r\n),\r\npositions_bucketed as (\r\n select\r\n series_id,\r\n -- simple average can result in loss of accuracy, see https://www.timescale.com/blog/what-time-weighted-averages-are-and-why-you-should-care/ for details\r\n avg(battery_level) as battery_level,\r\n min(positions_filtered.date) as series_min_date\r\n from\r\n date_series\r\n left join positions_filtered on\r\n positions_filtered.date >= date_series.series_id\r\n and positions_filtered.date < date_series.next_series_id\r\n group by\r\n series_id\r\n),\r\n-- PostgreSQL cannot IGNORE NULLS via Window Functions LAST_VALUE - therefore use natural behavior of COUNT & MAX, see https://www.reddit.com/r/SQL/comments/wb949v/comment/ii5mmmi/ for details\r\npositions_bucketed_gapfilling_locf_intermediate as (\r\n select\r\n series_id,\r\n battery_level,\r\n series_min_date,\r\n count(battery_level) over (order by series_id) as i\r\n from\r\n positions_bucketed\r\n\r\n),\r\npositions_bucketed_gapfilled_locf as (\r\n select\r\n series_id,\r\n series_min_date,\r\n max(battery_level) over (partition by i) as battery_level_locf\r\n from\r\n positions_bucketed_gapfilling_locf_intermediate\r\n),\r\n-- PostgreSQL cannot use PERCENTILE_DISC as Window Function - therefore use ARRAY_AGG and UNNEST, see https://stackoverflow.com/a/72718604 for details\r\npositions_bucketed_gapfilled_locf_percentile_intermediate as (\r\n select\r\n series_id,\r\n series_min_date,\r\n min(series_min_date) over () as min_date,\r\n array_agg(battery_level_locf) over w as arr,\r\n avg(battery_level_locf) over w as battery_level_avg\r\n from\r\n positions_bucketed_gapfilled_locf\r\n window w as (rows between (86400 / $bucket_width) * ($days_moving_average_percentiles / 2) preceding and (86400 / $bucket_width) * ($days_moving_average_percentiles / 2) following)\r\n)\r\n\r\nselect\r\n series_id::timestamptz,\r\n (select percentile_cont(0.075) within group (order by s) from unnest(arr) trick(s)) as \"$days_moving_average_percentiles Day Moving 7.5% Percentile (${bucket_width:text} buckets)\",\r\n battery_level_avg as \"$days_moving_average_percentiles Day Moving Average (${bucket_width:text} buckets)\",\r\n (select percentile_cont(0.5) within group (order by s) from unnest(arr) trick(s)) as \"$days_moving_average_percentiles Day Moving Median (${bucket_width:text} buckets)\",\r\n (select percentile_cont(0.925) within group (order by s) from unnest(arr) trick(s)) as \"$days_moving_average_percentiles Day Moving 92.5% Percentile (${bucket_width:text} buckets)\"\r\nfrom\r\n positions_bucketed_gapfilled_locf_percentile_intermediate where $__timeFilter(series_id) and series_min_date >= min_date", - "refId": "C", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charge Level", - "transformations": [ - { - "id": "configFromData", - "options": { - "applyTo": { - "id": "byFrameRefID", - "options": "A" - }, - "configRefId": "B", - "mappings": [ - { - "fieldName": "lower", - "handlerArguments": { - "threshold": { - "color": "green" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "upper", - "handlerArguments": { - "threshold": { - "color": "green" - } - }, - "handlerKey": "threshold1" - } - ] - } - } - ], - "type": "timeseries" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "2h", - "value": "7200" - }, - "description": "Data used to calculate Moving Average / Percentiles is unevenly sampled in TeslaMate. To avoid biases towards more frequently sampled values, the data is bucketed. For buckets without sampled values, the last observed value is carried forward. Bucketing is not time-weighted but is a simple average. Increasing the bucket width results in a loss of accuracy.", - "includeAll": false, - "label": "Bucket Width", - "name": "bucket_width", - "options": [ - { - "selected": false, - "text": "1h", - "value": "3600" - }, - { - "selected": true, - "text": "2h", - "value": "7200" - }, - { - "selected": false, - "text": "4h", - "value": "14400" - } - ], - "query": "1h : 3600, 2h : 7200, 4h : 14400", - "type": "custom" - }, - { - "current": { - "text": "yes", - "value": "1" - }, - "includeAll": false, - "label": "Include Moving Average / Percentiles", - "name": "include_average_percentiles", - "options": [ - { - "selected": false, - "text": "no", - "value": "0" - }, - { - "selected": true, - "text": "yes", - "value": "1" - } - ], - "query": "no : 0, yes : 1", - "type": "custom" - }, - { - "current": { - "text": "1/6 of interval", - "value": "6" - }, - "description": "", - "includeAll": false, - "label": "Moving Average / Percentiles Width", - "name": "intervals_moving_average_percentiles", - "options": [ - { - "selected": true, - "text": "1/6 of interval", - "value": "6" - }, - { - "selected": false, - "text": "1/12 of interval", - "value": "12" - } - ], - "query": "1/6 of interval : 6, 1/12 of interval : 12", - "type": "custom" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select ((${__to:date:seconds} - ${__from:date:seconds}) / 86400 / $intervals_moving_average_percentiles)", - "hide": 2, - "includeAll": false, - "name": "days_moving_average_percentiles", - "options": [], - "query": "select ((${__to:date:seconds} - ${__from:date:seconds}) / 86400 / $intervals_moving_average_percentiles)", - "refresh": 2, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-6M", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Charge Level", - "uid": "WopVO_mgz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charges.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charges.yaml deleted file mode 100644 index 6b33cee..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charges.yaml +++ /dev/null @@ -1,1537 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-charges - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-charges.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 16, - "panels": [], - "title": "Summary of this period", - "type": "row" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "charge_energy_added" - }, - "properties": [ - { - "id": "displayName", - "value": "Total Energy added:" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 0, - "y": 1 - }, - "id": 10, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 6, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "charge_energy_added" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "charge_energy_used" - }, - "properties": [ - { - "id": "displayName", - "value": "Total Energy used:" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 6, - "y": 1 - }, - "id": 20, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 6, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "charge_energy_used" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 2, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "cost" - }, - "properties": [ - { - "id": "displayName", - "value": "Total Charging Cost:" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 12, - "y": 1 - }, - "id": 14, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 6, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "cost" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - }, - "unit": "m" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "duration_min" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Duration:" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 18, - "y": 1 - }, - "id": 15, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 6, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "duration_min" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "Browse your charges by Geofence, Location, Type, Cost and Duration in order to have an accurate Total of kWh added and their respective costs", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false, - "minWidth": 150 - }, - "displayName": "", - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "start_date" - }, - "properties": [ - { - "id": "displayName", - "value": "Date" - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "View charge details", - "url": "/d/BHhxFeZRz/charge-details?from=${__data.fields.start_date_ts.numeric}&to=${__data.fields.end_date_ts.numeric}&var-car_id=${__data.fields.car_id.numeric}&var-charging_process_id=${__data.fields.id.numeric}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 210 - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_added" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy added" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 115 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "start_battery_level" - }, - "properties": [ - { - "id": "displayName", - "value": "% Start" - }, - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 70 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_battery_level" - }, - "properties": [ - { - "id": "displayName", - "value": "% End" - }, - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 65 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration_min" - }, - "properties": [ - { - "id": "displayName", - "value": "Duration" - }, - { - "id": "unit", - "value": "m" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "outside_temp_avg_c" - }, - "properties": [ - { - "id": "displayName", - "value": "Temp" - }, - { - "id": "unit", - "value": "celsius" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "#C0D8FF", - "value": 0 - }, - { - "color": "#C8F2C2", - "value": 10 - }, - { - "color": "#FFA6B0", - "value": 20 - } - ] - } - }, - { - "id": "custom.minWidth", - "value": 70 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "cost" - }, - "properties": [ - { - "id": "displayName", - "value": "Cost" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "Set Cost", - "url": "${base_url:raw}/charge-cost/${__data.fields.id.numeric}" - } - ] - }, - { - "id": "noValue", - "value": "-" - }, - { - "id": "custom.minWidth", - "value": 70 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_ts/" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "address" - }, - "properties": [ - { - "id": "displayName", - "value": "Location" - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.path}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 180 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_added_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Range gained" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "unit", - "value": "lengthkm" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_added_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Range gained" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "unit", - "value": "lengthmi" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_added_per_hour" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Power" - }, - { - "id": "unit", - "value": "kwatt" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "#96D98D", - "value": 0 - }, - { - "color": "#56A64B", - "value": 20 - }, - { - "color": "#37872D", - "value": 55 - } - ] - } - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_added_per_hour_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Charge rate" - }, - { - "id": "unit", - "value": "velocitykmh" - }, - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "decimals", - "value": 0 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "outside_temp_avg_f" - }, - "properties": [ - { - "id": "displayName", - "value": "Temp" - }, - { - "id": "unit", - "value": "fahrenheit" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 70 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - }, - { - "color": "super-light-green", - "value": 50 - }, - { - "color": "super-light-red", - "value": 68 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_added_per_hour_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Charge rate" - }, - { - "id": "unit", - "value": "velocitymph" - }, - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "decimals", - "value": 0 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "path" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_used" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy used" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 105 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charging_efficiency" - }, - "properties": [ - { - "id": "displayName", - "value": "Efficiency" - }, - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.cellOptions", - "value": { - "mode": "basic", - "type": "gauge" - } - }, - { - "id": "color", - "value": { - "mode": "continuous-RdYlGr" - } - }, - { - "id": "max", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 120 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "car_id" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_date" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "cost_per_kwh" - }, - "properties": [ - { - "id": "displayName", - "value": "Cost / kWh" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "noValue", - "value": "-" - }, - { - "id": "custom.minWidth", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_type" - }, - "properties": [ - { - "id": "displayName", - "value": "Type" - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.minWidth", - "value": 40 - }, - { - "id": "mappings", - "value": [ - { - "options": { - "AC": { - "color": "green", - "index": 0 - }, - "DC": { - "color": "light-orange", - "index": 1 - } - }, - "type": "value" - } - ] - }, - { - "id": "custom.align", - "value": "center" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "odometer_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - }, - { - "id": "displayName", - "value": "Odometer" - }, - { - "id": "custom.minWidth", - "value": 95 - }, - { - "id": "decimals", - "value": 0 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "odometer_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - }, - { - "id": "displayName", - "value": "Odometer" - }, - { - "id": "custom.minWidth", - "value": 95 - }, - { - "id": "decimals", - "value": 0 - } - ] - } - ] - }, - "gridPos": { - "h": 19, - "w": 24, - "x": 0, - "y": 3 - }, - "id": 6, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n (round(extract(epoch FROM start_date) - 10) * 1000) AS start_date_ts,\n (round(extract(epoch FROM end_date) + 10) * 1000) AS end_date_ts,\n start_date,\n end_date,\n CONCAT_WS(', ', COALESCE(addresses.name, nullif(CONCAT_WS(' ', addresses.road, addresses.house_number), '')), addresses.city) AS address,\n g.name as geofence_name,\n g.id as geofence_id,\n p.latitude,\n p.longitude,\n cp.charge_energy_added,\n cp.charge_energy_used,\n duration_min,\n start_battery_level,\n end_battery_level,\n end_${preferred_range}_range_km - start_${preferred_range}_range_km as range_added,\n outside_temp_avg,\n cp.id,\n p.odometer - lag(p.odometer) OVER (ORDER BY start_date) AS distance,\n cars.efficiency,\n cp.car_id,\n cost,\n max(c.charger_voltage) as max_charger_voltage,\n CASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC' ELSE 'AC' END AS charge_type,\n p.odometer as odometer\n FROM\n charging_processes cp\n\tLEFT JOIN charges c ON cp.id = c.charging_process_id\n LEFT JOIN positions p ON p.id = cp.position_id\n LEFT JOIN cars ON cars.id = cp.car_id\n LEFT JOIN addresses ON addresses.id = cp.address_id\n LEFT JOIN geofences g ON g.id = geofence_id\n WHERE \n cp.car_id = $car_id AND\n $__timeFilter(start_date) AND\n (cp.charge_energy_added IS NULL OR cp.charge_energy_added > 0) AND\n ('${geofence:pipe}' = '-1' OR geofence_id in ($geofence))\n GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, p.odometer\n ORDER BY\n start_date\n)\nSELECT\n start_date_ts,\n end_date_ts,\n CASE WHEN geofence_id IS NULL THEN CONCAT('new?lat=', latitude, '&lng=', longitude)\n WHEN geofence_id IS NOT NULL THEN CONCAT(geofence_id, '/edit')\n END as path,\n car_id,\n id,\n -- Columns\n start_date,\n end_date,\n COALESCE(geofence_name, address) as address, \n charge_type,\n duration_min,\n cost,\n cost / NULLIF(greatest(charge_energy_added, charge_energy_used), 0) as cost_per_kwh,\n charge_energy_added,\n greatest(charge_energy_used, charge_energy_added) as charge_energy_used,\n charge_energy_added / greatest(charge_energy_used, charge_energy_added) as charging_efficiency,\n convert_celsius(outside_temp_avg, '$temp_unit') AS outside_temp_avg_$temp_unit,\n charge_energy_added * 60 / NULLIF (duration_min, 0) AS charge_energy_added_per_hour,\n convert_km(range_added * 60 / NULLIF (duration_min, 0), '$length_unit') AS range_added_per_hour_$length_unit,\n convert_km(range_added, '$length_unit') AS range_added_$length_unit,\n start_battery_level,\n end_battery_level,\n convert_km(odometer::numeric, '$length_unit') AS odometer_$length_unit\n FROM\n data\nWHERE\n (distance >= 0 OR distance IS NULL)\n AND duration_min >= '$min_duration_min'\n AND \n CASE\n WHEN '$cost' !~ '^[0-9]+$' THEN TRUE \n ELSE cost >= COALESCE(NULLIF('$cost', '')::NUMERIC, 0) \n END\n AND charge_type = ANY(CASE WHEN array_to_string(ARRAY[$charge_type], ',') = 'DC' THEN ARRAY['DC'] WHEN array_to_string(ARRAY[$charge_type], ',') = 'AC' THEN ARRAY['AC'] ELSE ARRAY['DC', 'AC'] END)\n AND address ILIKE '%$location%'\nORDER BY\n start_date DESC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charger type: $charge_type", - "type": "table" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 22 - }, - "id": 18, - "panels": [], - "title": "General information (All charges)", - "type": "row" - }, - { - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 24, - "x": 0, - "y": 23 - }, - "id": 19, - "options": { - "code": { - "language": "plaintext", - "showLineNumbers": false, - "showMiniMap": false - }, - "content": "From here you can check if you have \nincomplete data of **Charges** (charges without ending date)\nIf so, you may follow the official \nguide by Manually fixing data", - "mode": "markdown" - }, - "pluginVersion": "12.1.1", - "title": "", - "type": "text" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "fixed" - }, - "custom": { - "align": "center", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 24, - "x": 0, - "y": 25 - }, - "id": 17, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "enablePagination": true, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT id as \"Charging Process ID\", start_date, end_date, charge_energy_added, charge_energy_used, start_battery_level, end_battery_level, duration_min\nFROM charging_processes \nWHERE car_id = $car_id AND end_date is null\nORDER BY start_date DESC\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Incomplete Charges 🪫", - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "includeAll": false, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "allValue": "-1", - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT name AS __text, id AS __value FROM geofences ORDER BY name COLLATE \"C\" ASC;", - "includeAll": true, - "label": "Geofence", - "multi": true, - "name": "geofence", - "options": [], - "query": "SELECT name AS __text, id AS __value FROM geofences ORDER BY name COLLATE \"C\" ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "", - "value": "" - }, - "description": "Type a text contained in Location", - "label": "Location", - "name": "location", - "options": [ - { - "selected": true, - "text": "", - "value": "" - } - ], - "query": "", - "type": "textbox" - }, - { - "current": {}, - "includeAll": true, - "label": "Type", - "multi": true, - "name": "charge_type", - "options": [ - { - "selected": false, - "text": "AC", - "value": "AC" - }, - { - "selected": false, - "text": "DC", - "value": "DC" - } - ], - "query": "AC, DC", - "type": "custom" - }, - { - "current": { - "text": "", - "value": "" - }, - "label": "Cost >=", - "name": "cost", - "options": [ - { - "selected": true, - "text": "", - "value": "" - } - ], - "query": "", - "type": "textbox" - }, - { - "current": { - "text": "0", - "value": "0" - }, - "label": "Duration (minutes) >=", - "name": "min_duration_min", - "options": [ - { - "selected": true, - "text": "0", - "value": "0" - } - ], - "query": "0", - "type": "textbox" - } - ] - }, - "time": { - "from": "now-3M", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Charges", - "uid": "TSmNYvRRk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charging-stats.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charging-stats.yaml deleted file mode 100644 index 3bc6ec1..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-charging-stats.yaml +++ /dev/null @@ -1,2428 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-charging-stats - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-charging-stats.json: | - { - "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": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 12, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 0, - "y": 1 - }, - "id": 8, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tcount(*)\nFROM\n\tcharging_processes\nWHERE\n\t$__timeFilter(end_date)\n\tAND duration_min >= $min_duration\n\tAND car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "# of Charges", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 3, - "y": 1 - }, - "id": 10, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tsum(charge_energy_added)\nFROM\n\tcharging_processes\nWHERE\n\t$__timeFilter(end_date)\n\tAND duration_min >= $min_duration\n\tAND car_id = $car_id;\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Total Energy added", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 6, - "y": 1 - }, - "id": 14, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tCOALESCE(sum(cp.cost),0)\nFROM\n\tcharging_processes cp\nLEFT JOIN \n\taddresses addr ON addr.id = address_id\nLEFT JOIN\n geofences geo ON geo.id = geofence_id\nJOIN\n charges char ON char.charging_process_id = cp.id AND char.date = end_date\t\nWHERE\n $__timeFilter(end_date)\n AND (addr.name ILIKE '%supercharger%' OR geo.name ILIKE '%supercharger%' OR char.fast_charger_brand = 'Tesla')\n\tAND NULLIF(char.charger_phases, 0) IS NULL\n\tAND char.fast_charger_type != 'ACSingleWireCAN'\n\tAND cp.cost IS NOT NULL\n\tAND duration_min >= $min_duration\n\tAND cp.car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "SuC Charging Cost", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 9, - "y": 1 - }, - "id": 27, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tsum(cost)\nFROM\n\tcharging_processes\nWHERE\n\t$__timeFilter(end_date)\n\tAND duration_min >= $min_duration\n\tAND car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Total Charging Cost", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 2, - "displayName": "", - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#d8d9da", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 12, - "y": 1 - }, - "id": 26, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "-- Query shared between Charging Stats, Statistics & Trip Dashboards (with minor changes) - ensure to modify in all places when necessary\n\nwith drives_start_event as (\n\n select\n 'drive_start' as event, start_date as date, start_${preferred_range}_range_km as range, start_km as odometer, car_id\n from drives\n where car_id = $car_id and $__timeFilter(start_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\ndrives_end_event as (\n\n select\n 'drive_end' as event, end_date as date, end_${preferred_range}_range_km as range, end_km as odometer, car_id\n from drives\n where car_id = $car_id and $__timeFilter(start_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\ncharging_processes_start_event as (\n\n select\n 'charging_process_start' as event, start_date as date, start_${preferred_range}_range_km as range, p.odometer, cp.car_id\n from charging_processes cp\n inner join positions p on cp.position_id = p.id\n where cp.car_id = $car_id and $__timeFilter(end_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\ncharging_processes_end_event as (\n\n select\n 'charging_process_end' as event, end_date as date, end_${preferred_range}_range_km as range, p.odometer, cp.car_id\n from charging_processes cp\n inner join positions p on cp.position_id = p.id\n where cp.car_id = $car_id and $__timeFilter(end_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\npositions as (\n\n select\n case\n when drive_id is not null and lead(drive_id) over w is not null then 'drive_start'\n else 'something'\n end as event,\n date, ${preferred_range}_battery_range_km as range, p.odometer, p.car_id\n from positions p\n where ideal_battery_range_km is not null and car_id = $car_id and 48 > extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n and (drive_id in (select id from drives where $__timeFilter(start_date)) or drive_id is null and $__timeFilter(date))\n window w as (order by date)\n\n),\n\ncombined as (\n\n select * from drives_start_event\n union all\n select * from drives_end_event\n union all\n select * from charging_processes_start_event\n union all\n select * from charging_processes_end_event\n union all\n select * from positions\n\n),\n\nfinal as (\n\n select\n car_id,\n lead(odometer) over w - odometer as distance,\n case when event != 'drive_start' then greatest(range - lead(range) over w, 0) else range - lead(range) over w end as range_loss\n from combined\n window w as (order by date asc)\n\n),\n\nderived as (\n\n select\n convert_km(sum(distance)::numeric, '$length_unit') as distance,\n sum(range_loss) * c.efficiency as consumption\n from final\n inner join cars c on car_id = c.id\n group by c.efficiency\n\n),\n\ncharges as (\n\n SELECT\n sum(cost) / sum(charge_energy_added) as cost_per_kwh\n FROM charging_processes\n where car_id = $car_id and $__timeFilter(end_date)\n\n)\n\nselect\n consumption / distance * 100 * cost_per_kwh as cost_mileage\nfrom derived cross join charges", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Cost per 100 $length_unit", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#d8d9da", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 15, - "y": 1 - }, - "id": 31, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT \n sum(cost) / sum(greatest(charge_energy_added, charge_energy_used))\nFROM charging_processes\n WHERE $__timeFilter(end_date) AND duration_min >= $min_duration AND car_id = $car_id\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Cost per kWh", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#d8d9da", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 18, - "y": 1 - }, - "id": 32, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n\t\tcp.id,\n cp.cost,\n cp.charge_energy_added,\n cp.charge_energy_used,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC'\n\t\t\t\t ELSE 'AC'\n\t\tEND AS current\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n AND duration_min >= $min_duration\n\t AND $__timeFilter(end_date)\n GROUP BY 1\n)\n\nSELECT \n sum(cost) / sum(greatest(charge_energy_added, charge_energy_used))\nFROM data\n WHERE current = 'DC'", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Cost per kWh DC", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#d8d9da", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 21, - "y": 1 - }, - "id": 33, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n\t\tcp.id,\n cp.cost,\n cp.charge_energy_added,\n cp.charge_energy_used,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC'\n\t\t\t\t ELSE 'AC'\n\t\tEND AS current\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n AND duration_min >= $min_duration\n\t AND $__timeFilter(end_date)\n GROUP BY 1\n)\n\nSELECT \n sum(cost) / sum(greatest(charge_energy_added, charge_energy_used))\nFROM data\n WHERE current = 'AC'", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Cost per kWh AC", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 12, - "x": 0, - "y": 4 - }, - "id": 15, - "options": { - "calculate": true, - "calculation": { - "yBuckets": { - "mode": "size", - "value": "10.00001" - } - }, - "cellGap": 2, - "cellValues": {}, - "color": { - "exponent": 0.5, - "fill": "#b4ff00", - "min": 0, - "mode": "opacity", - "reverse": false, - "scale": "exponential", - "scheme": "Oranges", - "steps": 128 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": false - }, - "rowsFrame": { - "layout": "auto" - }, - "showValue": "never", - "tooltip": { - "maxHeight": 600, - "mode": "single", - "showColorScale": false, - "yHistogram": false - }, - "yAxis": { - "axisPlacement": "left", - "max": "100", - "reverse": false, - "unit": "short" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\t$__time(end_date),\n\tstart_battery_level,\n\tend_battery_level\nFROM\n\tcharging_processes\nWHERE\n\t$__timeFilter(end_date)\n\tAND duration_min >= $min_duration \n\tAND car_id = $car_id\nORDER BY\n\tend_date;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "timeFrom": "6M", - "title": "Charge Heatmap", - "type": "heatmap" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 35, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "line" - } - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "transparent", - "value": 0 - } - ] - }, - "unit": "percent" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Start SOC" - }, - "properties": [ - { - "id": "custom.lineWidth", - "value": 0 - }, - { - "id": "custom.fillBelowTo", - "value": "End SOC" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "End SOC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#73BF69", - "mode": "fixed" - } - }, - { - "id": "custom.fillBelowTo", - "value": "Start SOC" - }, - { - "id": "custom.lineWidth", - "value": 0 - } - ] - } - ] - }, - "gridPos": { - "h": 6, - "w": 12, - "x": 12, - "y": 4 - }, - "id": 16, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "desc" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH charges AS (\n\tSELECT\n\t\tend_date,\n\t\tstart_battery_level,\n\t\tend_battery_level,\n\t\tp.odometer,\n\t\tCOALESCE(\n\t\t\tLAG(p.odometer) OVER (\n\t\t\t\tORDER BY cp.end_date\n\t\t\t),\n\t\t\tp.odometer\n\t\t) as odometer_prev\n\tFROM\n\t\tcharging_processes cp\n\tJOIN positions p\n\tON p.id = cp.position_id\n\tWHERE\n\t\t$__timeFilter(cp.end_date)\n\t\tAND cp.duration_min >= $min_duration\n\t\tAND cp.car_id = $car_id\n)\nSELECT\n\tMIN(end_date) as time,\n\tMIN(start_battery_level) as \"Start SOC\",\n\tMAX(end_battery_level) as \"End SOC\"\nFROM charges\nGROUP BY\n\tCASE WHEN odometer - odometer_prev < 2 THEN odometer_prev ELSE odometer END\nORDER BY\n\ttime;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n 20 as lower,\r\n CASE WHEN lfp_battery THEN 100 ELSE 80 END as upper\r\nfrom cars inner join car_settings on cars.settings_id = car_settings.id\r\nwhere cars.id = $car_id", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "timeFrom": "6M", - "title": "Charge Delta", - "transformations": [ - { - "id": "configFromData", - "options": { - "applyTo": { - "id": "byFrameRefID", - "options": "A" - }, - "configRefId": "B", - "mappings": [ - { - "fieldName": "lower", - "handlerArguments": { - "threshold": { - "color": "green" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "upper", - "handlerArguments": { - "threshold": { - "color": "green" - } - }, - "handlerKey": "threshold1" - } - ] - } - } - ], - "type": "timeseries" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "decimals": 2, - "mappings": [], - "unit": "kwatth" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "AC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#73BF69", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "DC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "light-orange", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 13, - "w": 5, - "x": 0, - "y": 10 - }, - "id": 18, - "maxDataPoints": 3, - "options": { - "displayLabels": [ - "name" - ], - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true, - "values": [ - "value", - "percent" - ] - }, - "pieType": "pie", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n\t\tcp.id,\n\t\tcp.charge_energy_added,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC'\n\t\t\t\t ELSE 'AC'\n\t\tEND AS current,\n\t\tcp.charge_energy_used\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n\t AND duration_min >= $min_duration\n\t AND $__timeFilter(end_date)\n GROUP BY 1,2\n)\nSELECT\n\tnow() AS time,\n\tSUM(GREATEST(charge_energy_added, charge_energy_used)) AS value,\n\tcurrent AS metric\nFROM data\nGROUP BY 3\nORDER BY metric DESC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "AC/DC - Energy Used", - "type": "piechart" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-reds" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "pct" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "chg_total" - }, - "properties": [ - { - "id": "unit", - "value": "kwatth" - } - ] - } - ] - }, - "gridPos": { - "h": 13, - "w": 14, - "x": 5, - "y": 10 - }, - "id": 24, - "maxDataPoints": 1, - "options": { - "basemap": { - "config": {}, - "name": "Layer 0", - "tooltip": true, - "type": "osm-standard" - }, - "controls": { - "mouseWheelZoom": true, - "showAttribution": true, - "showDebug": false, - "showMeasure": false, - "showScale": false, - "showZoom": true - }, - "layers": [ - { - "config": { - "showLegend": false, - "style": { - "color": { - "field": "pct", - "fixed": "red" - }, - "opacity": 0.4, - "rotation": { - "fixed": 0, - "max": 360, - "min": -360, - "mode": "mod" - }, - "size": { - "field": "chg_total", - "fixed": 5, - "max": 30, - "min": 5 - }, - "symbol": { - "fixed": "img/icons/marker/circle.svg", - "mode": "fixed" - }, - "symbolAlign": { - "horizontal": "center", - "vertical": "center" - }, - "text": { - "field": "chg_total", - "fixed": "", - "mode": "field" - }, - "textConfig": { - "fontSize": 12, - "offsetX": 15, - "offsetY": 0, - "textAlign": "left", - "textBaseline": "middle" - } - } - }, - "location": { - "mode": "auto" - }, - "name": "Charge location", - "tooltip": true, - "type": "markers" - } - ], - "tooltip": { - "mode": "details" - }, - "view": { - "allLayers": true, - "id": "fit", - "lat": 0, - "lon": 0, - "zoom": 15 - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH charge_data AS (\r\nSELECT COALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city)) AS loc_nm\r\n, AVG(position.latitude) AS latitude\r\n, AVG(position.longitude) AS longitude\r\n, sum(charge.charge_energy_added) AS chg_total\r\n, count(*) as charges\r\nFROM charging_processes charge\r\nLEFT JOIN addresses address ON charge.address_id = address.id\r\nLEFT JOIN positions position ON charge.position_id = position.id\r\nLEFT JOIN geofences geofence ON charge.geofence_id = geofence.id\r\nWHERE $__timeFilter(charge.end_date)\r\nAND charge.duration_min >= $min_duration\r\nAND charge.car_id = $car_id\r\nGROUP BY COALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city))\r\n) \r\nSELECT loc_nm\r\n\t,latitude\r\n\t,longitude\r\n\t,chg_total\r\n\t,chg_total * 1.0 / (SELECT sum(chg_total) FROM charge_data) * 100 AS pct\r\n\t,charges\r\nFROM charge_data", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charging heat map by kWh", - "type": "geomap" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "decimals": 1, - "mappings": [], - "unit": "dtdurations" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "AC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#73BF69", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "DC" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "light-orange", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 13, - "w": 5, - "x": 19, - "y": 10 - }, - "id": 20, - "maxDataPoints": 3, - "options": { - "displayLabels": [ - "name" - ], - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true, - "values": [ - "value", - "percent" - ] - }, - "pieType": "pie", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n\t\tcp.id,\n\t\tcp.duration_min,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC'\n\t\t\t\t ELSE 'AC'\n\t\tEND AS current\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n\t AND cp.duration_min >= $min_duration\n\t AND $__timeFilter(end_date)\n GROUP BY 1,2\n)\nSELECT\n\tnow() AS time,\n\tsum(duration_min) * 60 AS value,\n\tcurrent AS metric\nFROM data\nGROUP BY 3\nORDER BY metric DESC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "AC/DC - Duration", - "type": "piechart" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-RdYlGr", - "seriesBy": "last" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "fillOpacity": 50, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "pointShape": "circle", - "pointSize": { - "fixed": 3 - }, - "pointStrokeWidth": 1, - "scaleDistribution": { - "type": "linear" - }, - "show": "points" - }, - "fieldMinMax": false, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byFrameRefID", - "options": "A" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "Show charge details", - "url": "/d/BHhxFeZRz/charge-details?from=${__data.fields.start_date.numeric}&to=${__data.fields.end_date.numeric}&var-car_id=${car_id}&var-charging_process_id=${__data.fields.charging_process_id.numeric}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byFrameRefID", - "options": "B" - }, - "properties": [ - { - "id": "custom.pointSize.fixed", - "value": 15 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Power" - }, - "properties": [ - { - "id": "unit", - "value": "kwatt" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "SoC" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - } - ] - } - ] - }, - "gridPos": { - "h": 16, - "w": 24, - "x": 0, - "y": 23 - }, - "id": 29, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "mapping": "manual", - "series": [ - { - "color": { - "matcher": { - "id": "byName", - "options": "Power" - } - }, - "frame": { - "matcher": { - "id": "byIndex", - "options": 0 - } - }, - "x": { - "matcher": { - "id": "byName", - "options": "SoC" - } - }, - "y": { - "matcher": { - "id": "byName", - "options": "Power" - } - } - }, - { - "color": { - "matcher": { - "id": "byName", - "options": "Power" - } - }, - "frame": { - "matcher": { - "id": "byIndex", - "options": 1 - } - }, - "x": { - "matcher": { - "id": "byName", - "options": "SoC" - } - }, - "y": { - "matcher": { - "id": "byName", - "options": "Power" - } - } - } - ], - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n c.battery_level as \"SoC\",\r\n round(avg(c.charger_power), 0) as \"Power\",\r\n c.charging_process_id as \"charging_process_id\",\r\n p.start_date as \"start_date\",\r\n p.end_date as \"end_date\",\r\n COALESCE(g.name, a.name) || ' ' || to_char(timezone('$__timezone', timezone('UTC', c.date)), 'YYYY-MM-dd') as \"Charge\"\r\nFROM\r\n charges c\r\nJOIN charging_processes p ON p.id = c.charging_process_id \r\nJOIN addresses a ON a.id = p.address_id\r\nLEFT JOIN geofences g ON g.id = p.geofence_id\r\nWHERE\r\n $__timeFilter(date)\r\n AND p.car_id = $car_id\r\n AND charger_power > 0\r\n AND c.fast_charger_present\r\nGROUP BY c.battery_level, c.charging_process_id, a.name, g.name, p,start_date, p.end_date, to_char(timezone('$__timezone', timezone('UTC', c.date)), 'YYYY-MM-dd')", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n c.battery_level as \"SoC\",\n PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY charger_power) as \"Power\"\nFROM\n charges c\njoin\n charging_processes p ON p.id = c.charging_process_id \nWHERE\n $__timeFilter(date)\n AND p.car_id = $car_id\n AND charger_power > 0\n AND c.fast_charger_present\nGROUP BY battery_level", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "DC Charging Curve", - "type": "xychart" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "Only End Battery Level of last Charging Process considered for consecutive Charging Processes", - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false, - "minWidth": 50 - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "soc" - }, - "properties": [ - { - "id": "custom.width", - "value": 50 - }, - { - "id": "displayName", - "value": "SOC" - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "unit", - "value": "percent" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "n" - }, - "properties": [ - { - "id": "displayName", - "value": "# of Charges" - }, - { - "id": "custom.cellOptions", - "value": { - "mode": "gradient", - "type": "gauge", - "valueDisplayMode": "text" - } - }, - { - "id": "max" - }, - { - "id": "min", - "value": 0 - }, - { - "id": "custom.align", - "value": "left" - } - ] - } - ] - }, - "gridPos": { - "h": 18, - "w": 3, - "x": 0, - "y": 39 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "with data as (\n\n select id, end_battery_level, end_date, 'Charging Process' as activity\n from charging_processes cp\n where car_id = $car_id and $__timeFilter(cp.end_date) and duration_min >= $min_duration\n \n union all\n \n select d.id, p.battery_level as end_battery_level, end_date, 'Drive' as activity\n from drives d\n inner join positions p on d.end_position_id = p.id\n where d.car_id = $car_id and $__timeFilter(d.end_date)\n\n),\n\nflag_consecutive_charges as (\n\n select *, lead(activity) over (order by end_date) as next_activity from data\n\n)\n\nSELECT\n ROUND(end_battery_level / 5, 0) * 5 AS SOC,\n count(*) AS n\nFROM\n flag_consecutive_charges\nwhere\n activity = 'Charging Process' and (next_activity != 'Charging Process' or next_activity is null)\nGROUP BY\n ROUND(end_battery_level / 5, 0) * 5\nORDER BY\n SOC DESC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n CASE WHEN lfp_battery THEN 100 ELSE 81 END as high,\r\n CASE WHEN lfp_battery THEN 100 ELSE 91 END as highest\r\nfrom cars inner join car_settings on cars.settings_id = car_settings.id\r\nwhere cars.id = $car_id", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charge Stats", - "transformations": [ - { - "id": "configFromData", - "options": { - "applyTo": { - "id": "byName", - "options": "soc" - }, - "configRefId": "B", - "mappings": [ - { - "fieldName": "high", - "handlerArguments": { - "threshold": { - "color": "yellow" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "highest", - "handlerKey": "threshold1" - } - ] - } - } - ], - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "Only Start Battery Level of first Charging Process considered for consecutive Charging Processes", - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false, - "minWidth": 50 - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "soc" - }, - "properties": [ - { - "id": "displayName", - "value": "SOC" - }, - { - "id": "unit", - "value": "percent" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "red", - "value": 0 - }, - { - "color": "#EAB839", - "value": 10 - }, - { - "color": "green", - "value": 20 - } - ] - } - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.width", - "value": 50 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "n" - }, - "properties": [ - { - "id": "displayName", - "value": "# of Discharges" - }, - { - "id": "custom.cellOptions", - "value": { - "mode": "gradient", - "type": "gauge" - } - }, - { - "id": "min", - "value": 0 - }, - { - "id": "custom.align", - "value": "left" - } - ] - } - ] - }, - "gridPos": { - "h": 18, - "w": 3, - "x": 3, - "y": 39 - }, - "id": 13, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "with data as (\n\n select id, start_battery_level, end_date, 'Charging Process' as activity\n from charging_processes cp\n where car_id = $car_id and $__timeFilter(cp.end_date) and duration_min >= $min_duration\n \n union all\n \n select d.id, p.battery_level as start_battery_level, end_date, 'Drive' as activity\n from drives d\n inner join positions p on d.start_position_id = p.id\n where d.car_id = $car_id and $__timeFilter(d.end_date)\n\n),\n\nflag_consecutive_charges as (\n\n select *, lag(activity) over (order by end_date) as previous_activity from data\n\n)\n\nSELECT\n ROUND(start_battery_level / 5, 0) * 5 AS SOC,\n count(*) AS n\nFROM\n flag_consecutive_charges\nwhere\n activity = 'Charging Process' and (previous_activity != 'Charging Process' or previous_activity is null)\nGROUP BY\n ROUND(start_battery_level / 5, 0) * 5\nORDER BY\n SOC DESC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Discharge Stats", - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "location" - }, - "properties": [ - { - "id": "displayName", - "value": "Location" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_added" - }, - "properties": [ - { - "id": "displayName", - "value": "Charged" - }, - { - "id": "custom.width", - "value": 120 - }, - { - "id": "custom.align", - "value": "left" - }, - { - "id": "unit", - "value": "kwatth" - }, - { - "id": "decimals", - "value": 2 - } - ] - } - ] - }, - "gridPos": { - "h": 18, - "w": 9, - "x": 6, - "y": 39 - }, - "id": 4, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tCOALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city)) AS location,\n sum(charge_energy_added) as charge_energy_added\nFROM\n\tcharging_processes c\nLEFT JOIN addresses address ON c.address_id = address.id\nLEFT JOIN geofences geofence ON geofence_id = geofence.id\nWHERE\n\t$__timeFilter(end_date)\n\tAND duration_min >= $min_duration\n\tAND car_id = $car_id\nGROUP BY\n\t1\nORDER BY\n\tSUM(charge_energy_added) DESC\nLIMIT 17;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Top Charging Stations (Charged)", - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "location" - }, - "properties": [ - { - "id": "displayName", - "value": "Location" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "cost" - }, - "properties": [ - { - "id": "displayName", - "value": "Cost" - }, - { - "id": "custom.width", - "value": 120 - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align", - "value": "left" - } - ] - } - ] - }, - "gridPos": { - "h": 18, - "w": 9, - "x": 15, - "y": 39 - }, - "id": 6, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tCOALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, CONCAT_WS(' ', address.road, address.house_number)), address.city)) AS location,\n\tsum(cost) as cost\nFROM\n\tcharging_processes c\n\tLEFT JOIN addresses address ON c.address_id = address.id\n\tLEFT JOIN geofences geofence ON geofence_id = geofence.id\nWHERE\n $__timeFilter(end_date) AND\n\tduration_min >= $min_duration AND\n\tcar_id = $car_id AND\n\tCOST IS NOT NULL\nGROUP BY\n\t1\nORDER BY\n\t2 DESC NULLS LAST\nLIMIT 17;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Top Charging Stations (Cost)", - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "label": "Duration >=", - "name": "min_duration", - "options": [ - { - "selected": true, - "text": "0", - "value": "0" - } - ], - "query": "0", - "type": "textbox" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-10y", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Charging Stats", - "uid": "-pkIkhmRz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-drive-stats.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-drive-stats.yaml deleted file mode 100644 index de7665d..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-drive-stats.yaml +++ /dev/null @@ -1,1603 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-drive-stats - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-drive-stats.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-blue", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 8, - "x": 0, - "y": 0 - }, - "id": 20, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "sum" - ] - }, - "graphMode": "area", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH since as (\n\tSELECT timezone('UTC', min(start_date)) as date FROM drives\n\tWHERE car_id = $car_id\n\tGROUP BY car_id\n),\n\nactual AS (\n\tSELECT\n\t\tdate_trunc('day', timezone('UTC', start_date), '$__timezone') AS date,\n\t\tcount(*) AS number_of_drives\n\tFROM drives\n\tWHERE car_id = $car_id and $__timeFilter(start_date) and end_date is not null\n\tGROUP BY 1\n),\n\nbase_line AS (\n\tSELECT date from generate_series(date_trunc('day', (select date from since), '$__timezone'), date_trunc('day', timestamp with time zone $__timeTo(), '$__timezone'), '1 day'::interval, '$__timezone') date\n)\n\nSELECT\n base_line.date as time,\n\tCOALESCE(actual.number_of_drives, 0) as number_of_drives\nFROM base_line\nLEFT JOIN actual ON actual.date = base_line.date\nWHERE date_trunc('day', timestamp with time zone $__timeFrom(), '$__timezone') <= base_line.date\norder by base_line.date\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "# of Drives", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 4, - "w": 8, - "x": 8, - "y": 0 - }, - "id": 16, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "sum" - ] - }, - "graphMode": "area", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH since as (\n\tSELECT timezone('UTC', min(start_date)) as date FROM drives\n\tWHERE car_id = $car_id\n\tGROUP BY car_id\n),\n\nactual AS (\n\tSELECT\n\t\tdate_trunc('day', timezone('UTC', start_date), '$__timezone') AS date,\n\t\tsum(distance) AS distance\n\tFROM drives\n\tWHERE car_id = $car_id and $__timeFilter(start_date) and end_date is not null\n\tGROUP BY 1\n),\n\nbase_line AS (\n\tSELECT date from generate_series(date_trunc('day', (select date from since), '$__timezone'), date_trunc('day', timestamp with time zone $__timeTo(), '$__timezone'), '1 day'::interval, '$__timezone') date)\n\nSELECT\n base_line.date as time,\n\tconvert_km(COALESCE(actual.distance, 0)::numeric, '$length_unit') as \"distance_$length_unit\"\nFROM base_line\nLEFT JOIN actual ON actual.date = base_line.date\nWHERE date_trunc('day', timestamp with time zone $__timeFrom(), '$__timezone') <= base_line.date\norder by base_line.date\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Total Distance logged", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-yellow", - "value": 0 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 8, - "x": 16, - "y": 0 - }, - "id": 22, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "sum" - ] - }, - "graphMode": "area", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH since as (\n\tSELECT timezone('UTC', min(start_date)) as date FROM drives\n\tWHERE car_id = $car_id\n\tGROUP BY car_id\n),\n\nactual AS (\n\tSELECT\n\t\tdate_trunc('day', timezone('UTC', start_date), '$__timezone') AS date,\n\t\tsum((start_${preferred_range}_range_km - end_${preferred_range}_range_km) * cars.efficiency) AS energy\n\tFROM drives\n INNER JOIN cars on drives.car_id = cars.id\n\tWHERE car_id = $car_id and $__timeFilter(start_date) and end_date is not null\n\tGROUP BY 1\n),\n\nbase_line AS (\n\tSELECT date from generate_series(date_trunc('day', (select date from since), '$__timezone'), date_trunc('day', timestamp with time zone $__timeTo(), '$__timezone'), '1 day'::interval, '$__timezone') date)\n\nSELECT\n base_line.date as time,\n\tcoalesce(energy, 0) as energy\nFROM base_line\nLEFT JOIN actual ON actual.date = base_line.date\nWHERE date_trunc('day', timestamp with time zone $__timeFrom(), '$__timezone') <= base_line.date\norder by base_line.date\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Total Energy consumed (net)", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "lengthkm" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 0, - "y": 4 - }, - "id": 26, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT convert_km((percentile_cont(0.5) WITHIN GROUP (ORDER BY distance))::numeric, '$length_unit') as \"distance_$length_unit\"\nFROM drives\nWHERE car_id = $car_id AND $__timeFilter(start_date) AND end_date IS NOT NULL;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Median distance of a drive", - "type": "stat" - }, - { - "datasource": { - "default": false, - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "lengthkm" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 8, - "y": 4 - }, - "id": 8, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 16, - "refId": "A" - } - ], - "title": "Ø Distance driven per day", - "type": "stat" - }, - { - "datasource": { - "default": false, - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 16, - "y": 4 - }, - "id": 14, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 22, - "refId": "A" - } - ], - "title": "Ø Energy consumed (net) per day", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "speed_kmh" - }, - "properties": [ - { - "id": "unit", - "value": "velocitykmh" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_mih" - }, - "properties": [ - { - "id": "unit", - "value": "velocitymph" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 0, - "y": 7 - }, - "id": 33, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT convert_km(max(speed_max), '$length_unit') AS speed_${length_unit}h\nFROM drives\nWHERE car_id = $car_id and $__timeFilter(start_date) and end_date is not null;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Max Speed", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "speed_kmh" - }, - "properties": [ - { - "id": "unit", - "value": "velocitykmh" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_mih" - }, - "properties": [ - { - "id": "unit", - "value": "velocitymph" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 8, - "y": 7 - }, - "id": 35, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT convert_km(max(speed_max), '$length_unit') AS speed_${length_unit}h\nFROM drives\nWHERE car_id = $car_id and $__timeFilter(start_date) and end_date is not null;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "timeFrom": "30d", - "title": "Max Speed", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "speed_kmh" - }, - "properties": [ - { - "id": "unit", - "value": "velocitykmh" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_mih" - }, - "properties": [ - { - "id": "unit", - "value": "velocitymph" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 16, - "y": 7 - }, - "id": 34, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT convert_km(max(speed_max), '$length_unit') AS speed_${length_unit}h\nFROM drives\nWHERE car_id = $car_id and $__timeFilter(start_date) and end_date is not null;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "timeFrom": "7d", - "title": "Max Speed", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": false, - "axisLabel": "", - "axisPlacement": "auto", - "axisWidth": -10, - "fillOpacity": 90, - "gradientMode": "hue", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineWidth": 1, - "scaleDistribution": { - "type": "linear" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "fieldMinMax": true, - "mappings": [], - "noValue": "0", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Elapsed" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 1 - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 10 - }, - "id": 36, - "options": { - "barRadius": 0.05, - "barWidth": 0.97, - "colorByField": "Elapsed", - "fullHighlight": false, - "groupWidth": 0.7, - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "orientation": "auto", - "showValue": "auto", - "stacking": "none", - "text": {}, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - }, - "xField": "Speed", - "xTickLabelRotation": 0, - "xTickLabelSpacing": 0 - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH drivedata AS (\r\n SELECT\r\n ROUND(convert_km(p.speed::numeric, '$length_unit') / 10, 0) * 10 AS speed_section_${length_unit},\r\n EXTRACT(EPOCH FROM (LEAD(p.\"date\") OVER (PARTITION BY p.drive_id ORDER BY p.\"date\") - p.\"date\")) AS seconds_elapsed\r\n FROM positions p\r\n WHERE p.car_id = $car_id AND $__timeFilter(p.date) AND p.ideal_battery_range_km IS NOT NULL\r\n)\r\n\r\nSELECT \r\n speed_section_${length_unit} AS \"Speed\",\r\n SUM(seconds_elapsed) * 100 / SUM(SUM(seconds_elapsed)) OVER () AS \"Elapsed\", \r\n TO_CHAR((SUM(seconds_elapsed) || ' second')::interval, 'HH24:MI:SS') AS \"Time\"\r\nFROM drivedata\r\nWHERE speed_section_${length_unit} > 0\r\nGROUP BY speed_section_${length_unit}\r\nORDER BY speed_section_${length_unit};\r\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Speed Histogram ($speed_unit)", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "Elapsed", - "Time", - "Speed", - "SpeedUnit" - ] - } - } - } - ], - "type": "barchart" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "mileage_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "mileage_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 12, - "x": 0, - "y": 17 - }, - "id": 32, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH since as (\r\n\tSELECT timezone('UTC', min(start_date)) as date FROM drives\r\n\tWHERE car_id = $car_id\r\n\tGROUP BY car_id\r\n)\r\n\r\nselect\r\n convert_km(((max(end_km) - min(start_km)) / greatest(extract(days from (timestamp with time zone $__timeTo() - greatest(timestamp with time zone $__timeFrom(), (select date from since)))), 1) * (365/12))::numeric, '$length_unit') as \"mileage_$length_unit\"\r\nfrom drives\r\nwhere car_id = $car_id and $__timeFilter(start_date) and end_date is not null\r\ngroup by car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Extrapolated monthly mileage", - "type": "stat" - }, - { - "datasource": { - "default": false, - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "yearly_mileage_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "yearly_mileage_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 12, - "x": 12, - "y": 17 - }, - "id": 30, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 32, - "refId": "A" - } - ], - "title": "Extrapolated annual mileage", - "transformations": [ - { - "id": "calculateField", - "options": { - "alias": "yearly_mileage_km", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "mileage_km" - } - }, - "operator": "*", - "right": { - "fixed": "12" - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": false - } - }, - { - "id": "calculateField", - "options": { - "alias": "yearly_mileage_mi", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "mileage_mi" - } - }, - "operator": "*", - "right": { - "fixed": "12" - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": false - } - }, - { - "id": "filterFieldsByName", - "options": { - "include": { - "pattern": "yearly.*" - } - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "displayName": "$__cell_0", - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-blue", - "value": 0 - }, - { - "color": "light-red", - "value": 50 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 11, - "w": 24, - "x": 0, - "y": 20 - }, - "id": 24, - "options": { - "displayMode": "gradient", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 16, - "minVizWidth": 8, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showUnfilled": true, - "sizing": "auto", - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT * FROM (\nSELECT\n\tCOALESCE(g.name, COALESCE(a.name, nullif(CONCAT_WS(' ', a.road, a.house_number), ''))) as name,\n\tcount(*) AS visited\nFROM drives t\nINNER JOIN addresses a ON end_address_id = a.id\nLEFT JOIN geofences g ON end_geofence_id = g.id\nWHERE t.car_id = $car_id AND $__timeFilter(t.start_date) and $__timeFilter(t.end_date) \nGROUP BY 1\nORDER BY visited DESC) AS destinations\nWHERE name NOT ILIKE ALL ${exclude_formatted_string:raw}\nLIMIT 10;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Top 10 Destinations (in this period)", - "type": "bargauge" - } - ], - "preload": false, - "refresh": false, - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "includeAll": false, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT CASE WHEN '$length_unit' = 'km' THEN 'km/h' WHEN '$length_unit' = 'mi' THEN 'mph' END", - "hide": 2, - "includeAll": false, - "name": "speed_unit", - "options": [], - "query": "SELECT CASE WHEN '$length_unit' = 'km' THEN 'km/h' WHEN '$length_unit' = 'mi' THEN 'mph' END", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "", - "value": "" - }, - "description": "Comma separated list of locations to exclude. Ex: home, work", - "label": "Exclude locations", - "name": "exclude", - "options": [ - { - "selected": true, - "text": "", - "value": "" - } - ], - "query": "", - "type": "textbox" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "WITH splits AS (\n SELECT unnest(string_to_array('$exclude', ', ')) AS part\n),\nsplit_strings AS (\n\tSELECT part AS part\n\tFROM (VALUES (NULL)) AS v(dummy)\n\tLEFT JOIN splits ON TRUE\n),\nexclude_string AS (\n\tSELECT array_to_string(array_agg(case when part is null then '''''' else '''%' || part || '%''' end), ', ') AS formatted_string\n\tFROM split_strings\n)\nSELECT '(ARRAY[' || formatted_string || '])' FROM exclude_string", - "hide": 2, - "includeAll": false, - "name": "exclude_formatted_string", - "options": [], - "query": "WITH splits AS (\n SELECT unnest(string_to_array('$exclude', ', ')) AS part\n),\nsplit_strings AS (\n\tSELECT part AS part\n\tFROM (VALUES (NULL)) AS v(dummy)\n\tLEFT JOIN splits ON TRUE\n),\nexclude_string AS (\n\tSELECT array_to_string(array_agg(case when part is null then '''''' else '''%' || part || '%''' end), ', ') AS formatted_string\n\tFROM split_strings\n)\nSELECT '(ARRAY[' || formatted_string || '])' FROM exclude_string", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-1y", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Drive Stats", - "uid": "_7WkNSyWk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-drives.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-drives.yaml deleted file mode 100644 index 1a86d57..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-drives.yaml +++ /dev/null @@ -1,1636 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-drives - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-drives.json: | - { - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 3, - "panels": [], - "title": "Summary of this period", - "type": "row" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "consumption_kWh" - }, - "properties": [ - { - "id": "displayName", - "value": "Total Energy consumed (net):" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 0, - "y": 1 - }, - "id": 4, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 2, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "consumption_kWh" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - }, - "unit": "m" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "duration_min" - }, - "properties": [ - { - "id": "displayName", - "value": "Total Duration:" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 6, - "y": 1 - }, - "id": 5, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 2, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "duration_min" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - }, - { - "id": "displayName", - "value": "Total Distance logged:" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - }, - { - "id": "displayName", - "value": "Total Distance logged:" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 12, - "y": 1 - }, - "id": 6, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 2, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "names": [ - "distance_mi", - "distance_km" - ] - } - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "default": false, - "type": "datasource", - "uid": "-- Dashboard --" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "text", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "consumption_kwh_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "displayName", - "value": "Ø Consumption (net):" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_kwh_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "displayName", - "value": "Ø Consumption (net):" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 18, - "y": 1 - }, - "id": 7, - "maxDataPoints": 100, - "options": { - "colorMode": "background", - "graphMode": "none", - "justifyMode": "center", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 2, - "refId": "A" - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "pattern": "distance_km|distance_mi|consumption_kWh" - } - } - }, - { - "id": "renameByRegex", - "options": { - "regex": "distance_(mi|km)", - "renamePattern": "distance" - } - }, - { - "id": "reduce", - "options": { - "includeTimeField": false, - "mode": "reduceFields", - "reducers": [ - "sum" - ] - } - }, - { - "id": "calculateField", - "options": { - "binary": { - "left": "consumption_kWh", - "operator": "/", - "right": "distance" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": true - } - }, - { - "id": "calculateField", - "options": { - "alias": "consumption_kwh_$length_unit", - "binary": { - "left": "1000", - "operator": "*", - "right": "consumption_kWh / distance" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": true - } - } - ], - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false, - "minWidth": 150 - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "start_date" - }, - "properties": [ - { - "id": "displayName", - "value": "Date" - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "View drive details", - "url": "/d/zm7wN6Zgz/drive-details?from=${__data.fields.start_date_ts.numeric}&to=${__data.fields.end_date_ts.numeric}&var-car_id=${__data.fields.car_id.numeric}&var-drive_id=${__data.fields.drive_id.numeric}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_kwh_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "custom.minWidth", - "value": 165 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_kwh_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "custom.minWidth", - "value": 165 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_kWh" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy consumed (net)" - }, - { - "id": "unit", - "value": "kwatth" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-green", - "value": 0 - }, - { - "color": "green", - "value": 20 - }, - { - "color": "dark-green", - "value": 30 - } - ] - } - }, - { - "id": "custom.minWidth", - "value": 180 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "start_address" - }, - "properties": [ - { - "id": "displayName", - "value": "Start" - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.start_path}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_address" - }, - "properties": [ - { - "id": "displayName", - "value": "Destination" - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.end_path}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "outside_temp_c" - }, - "properties": [ - { - "id": "displayName", - "value": "Temp" - }, - { - "id": "unit", - "value": "celsius" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 70 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - }, - { - "color": "super-light-green", - "value": 10 - }, - { - "color": "super-light-red", - "value": 20 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration_min" - }, - "properties": [ - { - "id": "displayName", - "value": "Duration" - }, - { - "id": "unit", - "value": "m" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "efficiency" - }, - "properties": [ - { - "id": "displayName", - "value": "Efficiency" - }, - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "custom.cellOptions", - "value": { - "mode": "lcd", - "type": "gauge" - } - }, - { - "id": "max", - "value": 1.25 - }, - { - "id": "min", - "value": 0 - }, - { - "id": "color", - "value": { - "mode": "thresholds" - } - }, - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-orange", - "value": 0 - }, - { - "color": "light-orange", - "value": 0.65 - }, - { - "color": "green", - "value": 0.99 - } - ] - } - }, - { - "id": "decimals" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_ts/" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_avg_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Speed" - }, - { - "id": "unit", - "value": "velocitykmh" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "outside_temp_f" - }, - "properties": [ - { - "id": "displayName", - "value": "Temp" - }, - { - "id": "unit", - "value": "fahrenheit" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 70 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - }, - { - "color": "super-light-green", - "value": 50 - }, - { - "color": "super-light-red", - "value": 68 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_avg_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Speed" - }, - { - "id": "unit", - "value": "velocitymph" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_max_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "max Speed" - }, - { - "id": "unit", - "value": "velocitymph" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 95 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_max_km" - }, - "properties": [ - { - "id": "displayName", - "value": "max Speed" - }, - { - "id": "unit", - "value": "velocitykmh" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 95 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/(start|end)_path/" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration_str" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "car_id" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "% Start" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "% End" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 65 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "has_reduced_range" - }, - "properties": [ - { - "id": "displayName", - "value": "❄" - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.align", - "value": "center" - }, - { - "id": "mappings", - "value": [ - { - "options": { - "false": { - "color": "transparent", - "index": 1, - "text": "." - }, - "true": { - "color": "dark-blue", - "index": 0, - "text": "❄" - } - }, - "type": "value" - } - ] - }, - { - "id": "custom.minWidth", - "value": 50 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "drive_id" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "power_max" - }, - "properties": [ - { - "id": "displayName", - "value": "max Power" - }, - { - "id": "unit", - "value": "kwatt" - }, - { - "id": "custom.minWidth", - "value": 90 - } - ] - } - ] - }, - "gridPos": { - "h": 19, - "w": 24, - "x": 0, - "y": 3 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n round(extract(epoch FROM start_date)) * 1000 AS start_date_ts,\n round(extract(epoch FROM end_date)) * 1000 AS end_date_ts,\n car.id as car_id,\n CASE\n WHEN start_geofence.id IS NULL THEN CONCAT('new?lat=', start_position.latitude, '&lng=', start_position.longitude)\n WHEN start_geofence.id IS NOT NULL THEN CONCAT(start_geofence.id, '/edit')\n END as start_path,\n CASE\n WHEN end_geofence.id IS NULL THEN CONCAT('new?lat=', end_position.latitude, '&lng=', end_position.longitude)\n WHEN end_geofence.id IS NOT NULL THEN CONCAT(end_geofence.id, '/edit')\n END as end_path,\n TO_CHAR((duration_min * INTERVAL '1 minute'), 'HH24:MI') as duration_str,\n drives.id as drive_id,\n -- Columns\n start_date,\n COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS start_address,\n COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS end_address,\n duration_min,\n distance,\n start_position.battery_level as start_battery_level,\n end_position.battery_level as end_battery_level,\n start_${preferred_range}_range_km - end_${preferred_range}_range_km as range_diff,\n car.efficiency as car_efficiency,\n outside_temp_avg,\n distance / coalesce(NULLIF(duration_min, 0) * 60, extract(epoch from end_date - start_date)) * 3600 AS avg_speed,\n speed_max,\n power_max,\n ascent,\n descent\n FROM drives\n LEFT JOIN addresses start_address ON start_address_id = start_address.id\n LEFT JOIN addresses end_address ON end_address_id = end_address.id\n LEFT JOIN positions start_position ON start_position_id = start_position.id\n LEFT JOIN positions end_position ON end_position_id = end_position.id\n LEFT JOIN geofences start_geofence ON start_geofence_id = start_geofence.id\n LEFT JOIN geofences end_geofence ON end_geofence_id = end_geofence.id\n LEFT JOIN cars car ON car.id = drives.car_id\n WHERE $__timeFilter(start_date) AND drives.car_id = $car_id \n AND convert_km(distance::numeric, '$length_unit') >= $min_dist \n AND convert_km(distance::numeric, '$length_unit') / coalesce(NULLIF(duration_min, 0) * 60, extract(epoch from end_date - start_date)) * 3600 >= $min_speed \n AND ('${geofence:pipe}' = '-1' OR start_geofence.id in ($geofence) OR end_geofence.id in ($geofence)) \n),\n\nreduced_range_info as (\n\n select\n drive_id,\n case\n when sum(case when battery_level - usable_battery_level > 0 then 1 else 0 end)::numeric / count(*) > 0.25 then true\n else false\n end as reduced_range\n from positions p where $__timeFilter(date) AND car_id = $car_id and p.ideal_battery_range_km is not null group by p.drive_id \n\n)\n\nSELECT\n start_date_ts,\n end_date_ts,\n car_id,\n start_path,\n end_path,\n duration_str,\n data.drive_id,\n -- Columns\n start_date,\n start_address,\n end_address,\n duration_min,\n convert_km(distance::numeric, '$length_unit') AS distance_$length_unit,\n start_battery_level as \"% Start\",\n end_battery_level as \"% End\",\n convert_celsius(outside_temp_avg, '$temp_unit') AS outside_temp_$temp_unit,\n convert_km(avg_speed::numeric, '$length_unit') AS speed_avg_$length_unit,\n convert_km(speed_max::numeric, '$length_unit') AS speed_max_$length_unit,\n power_max,\n reduced_range as has_reduced_range,\n CASE\n WHEN range_diff > 0 and 'by distance' = '$efficiency' THEN distance / range_diff\n WHEN 'slope-adjusted' = '$efficiency' THEN\n distance * car_efficiency -- Energy at 100% efficiency\n / nullif((\n (range_diff) * car_efficiency -- Actual Energy\n + 2100 * 0.85 * 9.81 * descent / 3600 / 1000 -- Potential energy recovered from descent\n - 2100 * 9.81 * ascent / 3600 / 1000 -- Potential energy for ascent\n ), 0)\n ELSE NULL\n END as efficiency,\n range_diff * car_efficiency as \"consumption_kWh\",\n range_diff * car_efficiency / convert_km(distance::numeric, '$length_unit') * 1000 as consumption_kWh_$length_unit\nFROM data\n left join reduced_range_info on data.drive_id = reduced_range_info.drive_id\nWHERE\n start_address ILIKE '%$location%' OR end_address ILIKE '%$location%'\nORDER BY data.drive_id DESC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Drive", - "type": "table" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 22 - }, - "id": 10, - "panels": [], - "title": "General information (All drives)", - "type": "row" - }, - { - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 24, - "x": 0, - "y": 23 - }, - "id": 8, - "options": { - "code": { - "language": "plaintext", - "showLineNumbers": false, - "showMiniMap": false - }, - "content": "From here you can check if you have \nincomplete data of **Drives** (drives without ending date)\nIf so, you may follow the official \nguide by Manually fixing data", - "mode": "markdown" - }, - "pluginVersion": "12.1.1", - "title": "", - "type": "text" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "fixed" - }, - "custom": { - "align": "center", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 25 - }, - "id": 9, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "enablePagination": true, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT id AS \"Drive ID\", start_date, end_date, distance, duration_min \nFROM drives \nWHERE car_id = $car_id AND end_date is null\nORDER BY start_date DESC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Incomplete Drives 🛣️", - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "includeAll": false, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "allValue": "-1", - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT name AS __text, id AS __value FROM geofences ORDER BY name COLLATE \"C\" ASC;", - "description": "Start or Destination Geofence", - "includeAll": true, - "label": "Geofence", - "multi": true, - "name": "geofence", - "options": [], - "query": "SELECT name AS __text, id AS __value FROM geofences ORDER BY name COLLATE \"C\" ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "", - "value": "" - }, - "description": "Type a text contained in Start or Destination Location ", - "label": "Location", - "name": "location", - "options": [ - { - "selected": true, - "text": "", - "value": "" - } - ], - "query": "", - "type": "textbox" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "temperature unit", - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "length unit", - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "0", - "value": "0" - }, - "label": "Distance >=", - "name": "min_dist", - "options": [ - { - "selected": true, - "text": "0", - "value": "0" - } - ], - "query": "0", - "type": "textbox" - }, - { - "current": { - "text": "0", - "value": "0" - }, - "label": "Speed >=", - "name": "min_speed", - "options": [ - { - "selected": true, - "text": "0", - "value": "0" - } - ], - "query": "0", - "type": "textbox" - }, - { - "allowCustomValue": false, - "current": { - "text": "slope-adjusted", - "value": "slope-adjusted" - }, - "description": "Select how Efficiency ratings should be calculated.\n\n\"by distance\" is doing a simple comparison based on distance driven and range lost while driving.\n\n\"slope-adjusted\" takes ascent / descent of the drive into account and adjusts the energy consumed accordingly. regen breaking efficiency is set to 85% and the vehicle is assumed to have a weight of 2100 kg.", - "label": "Efficiency", - "name": "efficiency", - "options": [ - { - "selected": true, - "text": "slope-adjusted", - "value": "slope-adjusted" - }, - { - "selected": false, - "text": "by distance", - "value": "by distance" - } - ], - "query": "slope-adjusted,by distance", - "type": "custom" - } - ] - }, - "time": { - "from": "now-3M", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Drives", - "uid": "Y8upc6ZRk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-efficiency.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-efficiency.yaml deleted file mode 100644 index 594dea9..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-efficiency.yaml +++ /dev/null @@ -1,1187 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-efficiency - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-efficiency.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 10, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "(Range lost while driving * Efficiency) / Distance driven", - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "consumption_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 0, - "y": 1 - }, - "id": 4, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select \n sum((start_${preferred_range}_range_km - end_${preferred_range}_range_km) * cars.efficiency) / convert_km(sum(distance)::numeric, '$length_unit') * 1000 AS \"consumption_$length_unit\"\nfrom drives \ninner join cars on cars.id = car_id\nwhere \n distance is not null and\n start_${preferred_range}_range_km - end_${preferred_range}_range_km >= 0.1 and\n car_id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Consumption (net)", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "(Range lost between charges * Efficiency) / Distance driven between charges", - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "consumption_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 8, - "y": 1 - }, - "id": 8, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH d1 AS (\n\tSELECT\n\t\tc.car_id,\n\t\tlag(end_${preferred_range}_range_km) OVER (ORDER BY start_date) - start_${preferred_range}_range_km AS range_loss,\n\t\tp.odometer - lag(p.odometer) OVER (ORDER BY start_date) AS distance\n\tFROM\n\t\tcharging_processes c\n\tLEFT JOIN positions p ON p.id = c.position_id \n\tWHERE\n\t end_date IS NOT NULL AND\n\t c.car_id = $car_id\n\tORDER BY\n\t\tstart_date\n),\nd2 AS (\nSELECT\n\tcar_id,\n\tsum(range_loss) AS range_loss,\n\tsum(distance) AS distance\nFROM\n\td1\nWHERE\n\tdistance >= 0 AND range_loss >= 0\nGROUP BY\n\tcar_id\n)\nSELECT\nrange_loss * c.efficiency / convert_km(distance::numeric, '$length_unit') * 1000 AS \"consumption_$length_unit\"\nFROM\n\td2\n\tLEFT JOIN cars c ON c.id = car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Consumption (gross)", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "Distance of all logged drives", - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 16, - "y": 1 - }, - "id": 6, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select convert_km(sum(distance)::numeric, '$length_unit') as \"distance_$length_unit\" \nfrom drives \nwhere car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Logged Distance", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "outside_temp_c" - }, - "properties": [ - { - "id": "displayName", - "value": "Temperature" - }, - { - "id": "unit", - "value": "celsius" - }, - { - "id": "custom.width", - "value": 125 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "outside_temp_f" - }, - "properties": [ - { - "id": "displayName", - "value": "Temperature" - }, - { - "id": "unit", - "value": "fahrenheit" - }, - { - "id": "custom.width", - "value": 125 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "efficiency" - }, - "properties": [ - { - "id": "displayName", - "value": "Driving Efficiency" - }, - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "mode": "lcd", - "type": "gauge" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-orange", - "value": 0 - }, - { - "color": "light-orange", - "value": 0.65 - }, - { - "color": "light-green", - "value": 0.99 - } - ] - } - }, - { - "id": "max", - "value": 1.15 - }, - { - "id": "min", - "value": 0 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "custom.width", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "custom.width", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "total_distance_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "km" - }, - { - "id": "custom.width", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "total_distance_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "mi" - }, - { - "id": "custom.width", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_speed_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Speed" - }, - { - "id": "unit", - "value": "velocitykmh" - }, - { - "id": "custom.width", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_speed_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Speed" - }, - { - "id": "unit", - "value": "velocitymph" - }, - { - "id": "custom.width", - "value": 200 - } - ] - } - ] - }, - "gridPos": { - "h": 12, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Temperature" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH t AS (\n\tSELECT\n\t CASE WHEN '$temp_unit' = 'C' THEN ROUND(cast(outside_temp_avg AS numeric) / 5, 0) * 5 \n\t\t\t WHEN '$temp_unit' = 'F' THEN ROUND(cast(convert_celsius(outside_temp_avg, '$temp_unit') AS numeric) / 10, 0) * 10\n\t\tEND AS outside_temp,\n\t\tsum(start_ideal_range_km - end_ideal_range_km) AS total_ideal_range,\n\t\tsum(start_rated_range_km - end_rated_range_km) AS total_rated_range,\n\t\tsum(distance) AS total_distance,\n\t\tsum(duration_min) as duration,\n\t\tcar_id\n\tFROM\n\t\tdrives\n\tWHERE\n\t\tdistance IS NOT NULL\n\t\tAND car_id = $car_id\n\t\tAND convert_km(distance::numeric, '$length_unit') >= $min_distance \n\t\tAND start_${preferred_range}_range_km - end_${preferred_range}_range_km > 0.1\n\tGROUP BY\n\t\t1,\n\t\tcar_id\n)\n\nSELECT\n\toutside_temp as outside_temp_$temp_unit,\n total_distance / total_${preferred_range}_range AS efficiency,\n\ttotal_${preferred_range}_range / convert_km(total_distance::numeric, '$length_unit') * c.efficiency * 1000 AS consumption_$length_unit,\n convert_km(total_distance::numeric, '$length_unit') as total_distance_$length_unit,\n\t(convert_km(total_distance::numeric, '$length_unit') / duration) * 60 as avg_speed_$length_unit\nFROM\n\tt\nJOIN cars c ON t.car_id = c.id\nWHERE outside_temp IS NOT NULL\norder by 1 desc\n", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Temperature – Driving Efficiency", - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "efficiency_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "efficiency_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 5, - "w": 4, - "x": 0, - "y": 16 - }, - "id": 14, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tefficiency / convert_km(1, '$length_unit') * 1000 as \"efficiency_$length_unit\"\nFROM\n\tcars\nWHERE\n\tid = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Current $preferred_range efficiency", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "efficiency_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Efficiency" - }, - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "efficiency_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Efficiency" - }, - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 5, - "w": 10, - "x": 4, - "y": 16 - }, - "id": 12, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n round((charge_energy_added / NULLIF(end_ideal_range_km - start_ideal_range_km, 0))::numeric / convert_km(1, '$length_unit'), 3) * 1000 as \"efficiency_$length_unit\",\n count(*) as count\nFROM\n charging_processes\nWHERE \n car_id = $car_id\n AND duration_min > 10\n AND end_battery_level <= 95\n AND start_ideal_range_km IS NOT NULL\n AND end_ideal_range_km IS NOT NULL\n AND charge_energy_added > 0\nGROUP BY\n 1\nORDER BY\n 2 DESC\nLIMIT 3", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Derived ideal efficiencies", - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "efficiency_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "displayName", - "value": "Efficiency" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "efficiency_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Efficiency" - }, - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 5, - "w": 10, - "x": 14, - "y": 16 - }, - "id": 15, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n round((charge_energy_added / NULLIF(end_rated_range_km - start_rated_range_km, 0))::numeric / convert_km(1, '$length_unit'), 3) * 1000 as \"efficiency_$length_unit\",\n\tcount(*) as count\nFROM\n charging_processes\nWHERE \n car_id = $car_id\n AND duration_min > 10\n AND end_battery_level <= 95\n AND start_rated_range_km IS NOT NULL\n AND end_rated_range_km IS NOT NULL\n AND charge_energy_added > 0\nGROUP BY\n 1\nORDER BY\n 2 DESC\nLIMIT 3", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Derived rated efficiencies", - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "1", - "value": "1" - }, - "includeAll": false, - "label": "min. distance per drive", - "name": "min_distance", - "options": [ - { - "selected": true, - "text": "1", - "value": "1" - }, - { - "selected": false, - "text": "5", - "value": "5" - }, - { - "selected": false, - "text": "10", - "value": "10" - }, - { - "selected": false, - "text": "25", - "value": "25" - }, - { - "selected": false, - "text": "50", - "value": "50" - } - ], - "query": "1, 5, 10, 25, 50", - "type": "custom" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": { - "hidden": true - }, - "timezone": "", - "title": "Tesla Efficiency", - "uid": "fu4SiQgWz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-locations.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-locations.yaml deleted file mode 100644 index a638512..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-locations.yaml +++ /dev/null @@ -1,1200 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-locations - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-locations.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 0, - "y": 0 - }, - "id": 12, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select count(*), count(distinct city) as city_count, count(distinct state) as state_count, count(distinct country) as country_count from addresses where id in (\r\n select start_address_id from drives where car_id in ($car_id) and $__timeFilter(start_date)\r\n union\r\n select end_address_id from drives where car_id in ($car_id) and $__timeFilter(end_date)\r\n union\r\n select address_id from charging_processes where car_id in ($car_id) and ($__timeFilter(start_date) or $__timeFilter(end_date))\r\n);", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "# of Addresses", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "city_count": true, - "country_count": true, - "state_count": true - }, - "includeByName": {}, - "indexByName": {}, - "renameByName": {} - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 6, - "y": 0 - }, - "id": 20, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 12, - "refId": "A" - } - ], - "title": "# of Cities", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "count": true, - "country_count": true, - "state_count": true - }, - "includeByName": {}, - "indexByName": {}, - "renameByName": {} - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 12, - "y": 0 - }, - "id": 18, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 12, - "refId": "A" - } - ], - "title": "# of States", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "city_count": true, - "count": true, - "country_count": true - }, - "includeByName": {}, - "indexByName": {}, - "renameByName": {} - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 18, - "y": 0 - }, - "id": 16, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 12, - "refId": "A" - } - ], - "title": "# of Countries", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "city_count": true, - "count": true, - "state_count": true - }, - "includeByName": {}, - "indexByName": {}, - "renameByName": {} - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "displayName": "$__cell_0", - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-green", - "value": 0 - }, - { - "color": "super-light-green", - "value": 50 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 3 - }, - "id": 10, - "options": { - "displayMode": "gradient", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 16, - "minVizWidth": 8, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showUnfilled": true, - "sizing": "auto", - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tcity,\n\tcount(*) as \"# of Addresses\"\nFROM\n\taddresses\nWHERE\n\tcity IS NOT NULL and\n id in (\n\t\tselect start_address_id from drives where car_id in ($car_id) and $__timeFilter(start_date) \n\t\tunion\n\t\tselect end_address_id from drives where car_id in ($car_id) and $__timeFilter(end_date) \n\t\tunion\n\t\tselect address_id from charging_processes where car_id in ($car_id) and ($__timeFilter(start_date) or $__timeFilter(end_date))\n\t)\nGROUP BY\n\t1\nORDER BY\n\t2 DESC\nLIMIT 10;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Cities", - "type": "bargauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "displayName": "$__cell_0", - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-orange", - "value": 0 - }, - { - "color": "super-light-orange", - "value": 50 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 3 - }, - "id": 14, - "options": { - "displayMode": "gradient", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 16, - "minVizWidth": 8, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showUnfilled": true, - "sizing": "auto", - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tstate,\n\tcount(*) as \"# of Addresses\"\nFROM\n\taddresses\nWHERE\n\tstate IS NOT NULL and\n id in (\n\t\tselect start_address_id from drives where car_id in ($car_id) and $__timeFilter(start_date)\n\t\tunion\n\t\tselect end_address_id from drives where car_id in ($car_id) and $__timeFilter(end_date)\n\t\tunion\n\t\tselect address_id from charging_processes where car_id in ($car_id) and ($__timeFilter(start_date) or $__timeFilter(end_date))\n\t)\nGROUP BY\n\t1\nORDER BY\n\t2 DESC\nLIMIT 10;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "States", - "type": "bargauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-blue", - "value": 0 - }, - { - "color": "light-red", - "value": 50 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Date" - }, - "properties": [ - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "custom.width", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "City" - }, - "properties": [ - { - "id": "custom.width" - } - ] - } - ] - }, - "gridPos": { - "h": 11, - "w": 24, - "x": 0, - "y": 11 - }, - "id": 22, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Date" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "with locations as (\n\n select address_id, geofence_id, start_date as end_date from charging_processes where car_id in ($car_id) and ($__timeFilter(start_date) or $__timeFilter(end_date))\n union\n select end_address_id as address_id, end_geofence_id as geofence_id, end_date from drives where car_id in ($car_id) and $__timeFilter(end_date)\n\n)\n\nSELECT\n max(l.end_date) as \"Date\",\n COALESCE(g.name, array_to_string(((string_to_array(a.display_name, ', ', ''))[0:2]), ', ')) AS \"Address\",\n\tCOALESCE(city, neighbourhood) as \"City\"\nFROM locations l\nINNER JOIN addresses a ON l.address_id = a.id\nLEFT JOIN geofences g ON l.geofence_id = g.id\nWHERE\n (a.display_name ilike '%$address_filter%' or g.name ilike '%$address_filter%')\nGROUP BY 2,3\nLIMIT 100", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Last visited", - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "decimals": 2, - "displayName": "", - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "updated_at" - }, - "properties": [ - { - "id": "displayName", - "value": "Updated at" - }, - { - "id": "unit", - "value": "time: YYYY-MM-DD HH:mm:ss" - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "displayName", - "value": "Name" - }, - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "", - "url": "${base_url:raw}/geo-fences/${__data.fields.path}" - } - ] - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "neighbourhood" - }, - "properties": [ - { - "id": "displayName", - "value": "Neighbourhood" - }, - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "city" - }, - "properties": [ - { - "id": "displayName", - "value": "City" - }, - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "state" - }, - "properties": [ - { - "id": "displayName", - "value": "State" - }, - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "country" - }, - "properties": [ - { - "id": "displayName", - "value": "Country" - }, - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "path" - }, - "properties": [ - { - "id": "custom.align" - }, - { - "id": "custom.hidden", - "value": true - } - ] - } - ] - }, - "gridPos": { - "h": 11, - "w": 18, - "x": 0, - "y": 22 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n CONCAT('new?lat=', latitude, '&lng=', longitude) as path,\n\tCOALESCE(name, CONCAT(road, ' ', house_number)) AS name,\n\tneighbourhood,\n\tcity,\n\tstate,\n\tcountry\nFROM addresses\nWHERE display_name ilike '%$address_filter%' and id in (\n select start_address_id from drives where car_id in ($car_id) and $__timeFilter(start_date)\n union\n select end_address_id from drives where car_id in ($car_id) and $__timeFilter(end_date)\n union\n select address_id from charging_processes where car_id in ($car_id) and ($__timeFilter(start_date) or $__timeFilter(end_date))\n)\nORDER BY inserted_at DESC\nLIMIT 100;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Addresses", - "transformations": [ - { - "id": "merge", - "options": { - "reducers": [] - } - } - ], - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "decimals": 2, - "displayName": "", - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Time" - }, - "properties": [ - { - "id": "displayName", - "value": "Time" - }, - { - "id": "unit", - "value": "time: YYYY-MM-DD HH:mm:ss" - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "displayName", - "value": "Name" - }, - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "", - "url": "${base_url:raw}/geo-fences/${__data.fields.id.numeric:raw}/edit" - } - ] - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.align" - }, - { - "id": "custom.hidden", - "value": true - } - ] - } - ] - }, - "gridPos": { - "h": 11, - "w": 6, - "x": 18, - "y": 22 - }, - "id": 6, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT id, name \nFROM geofences where id in (\n select start_geofence_id from drives where car_id in ($car_id) and $__timeFilter(start_date)\n union\n select end_geofence_id from drives where car_id in ($car_id) and $__timeFilter(end_date)\n union\n select geofence_id from charging_processes where car_id in ($car_id) and ($__timeFilter(start_date) or $__timeFilter(end_date))\n)\nORDER BY inserted_at DESC\nLIMIT 100;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Geo-fences", - "transformations": [ - { - "id": "merge", - "options": { - "reducers": [] - } - } - ], - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 1, - "includeAll": true, - "label": "Car", - "multi": true, - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "", - "value": "" - }, - "label": "Address", - "name": "address_filter", - "options": [ - { - "selected": true, - "text": "", - "value": "" - } - ], - "query": "", - "type": "textbox" - } - ] - }, - "time": { - "from": "now-1y", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Locations", - "uid": "ZzhF-aRWz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-mileage.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-mileage.yaml deleted file mode 100644 index 25e4965..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-mileage.yaml +++ /dev/null @@ -1,293 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-mileage - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-mileage.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "stepAfter", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "decimals": 0, - "links": [], - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": ".*_km$" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*_mi$" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "mileage_.*" - }, - "properties": [ - { - "id": "displayName", - "value": "Mileage" - } - ] - } - ] - }, - "gridPos": { - "h": 21, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "options": { - "legend": { - "calcs": [ - "min", - "max" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH o AS (SELECT\n start_date AS time,\n car_id,\n start_km AS \"odometer\"\nFROM drives\nUNION ALL\nSELECT\n end_date,\n car_id,\n end_km AS \"odometer\"\nFROM drives)\n\nSELECT\n time, \n convert_km(odometer::numeric, '$length_unit') as mileage_$length_unit\nFROM o\nWHERE\n\tcar_id = $car_id AND\n\t$__timeFilter(time)\norder by 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Mileage", - "type": "timeseries" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-6M", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Mileage", - "uid": "NjtMTFggz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-overview.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-overview.yaml deleted file mode 100644 index ca860be..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-overview.yaml +++ /dev/null @@ -1,1990 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-overview - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-overview.json: | - { - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "description": "A high level overview of your car", - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 1, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 18, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "displayName": "", - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "transparent", - "value": 0 - } - ] - }, - "unit": "percent" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 0, - "y": 1 - }, - "id": 4, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "(SELECT battery_level, date\nFROM positions\nWHERE car_id = $car_id and ideal_battery_range_km is not null\nORDER BY date DESC\nLIMIT 1)\nUNION\nSELECT battery_level, date\nFROM charges c\nJOIN charging_processes p ON p.id = c.charging_process_id\nWHERE $__timeFilter(date) AND p.car_id = $car_id\nORDER BY date DESC\nLIMIT 1", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n 0 as lowest,\r\n 10 as low,\r\n 20 as mid,\r\n CASE WHEN lfp_battery THEN 101 ELSE 81 END as high,\r\n CASE WHEN lfp_battery THEN 101 ELSE 91 END as highest\r\nfrom cars inner join car_settings on cars.settings_id = car_settings.id\r\nwhere cars.id = $car_id", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Battery Level", - "transformations": [ - { - "id": "configFromData", - "options": { - "applyTo": { - "id": "byFrameRefID", - "options": "A" - }, - "configRefId": "B", - "mappings": [ - { - "fieldName": "lowest", - "handlerKey": "threshold1" - }, - { - "fieldName": "low", - "handlerArguments": { - "threshold": { - "color": "yellow" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "mid", - "handlerArguments": { - "threshold": { - "color": "green" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "high", - "handlerArguments": { - "threshold": { - "color": "yellow" - } - }, - "handlerKey": "threshold1" - }, - { - "fieldName": "highest", - "handlerArguments": { - "threshold": { - "color": "red" - } - }, - "handlerKey": "threshold1" - } - ] - } - } - ], - "type": "gauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [], - "max": 260, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-green", - "value": 0 - } - ] - }, - "unit": "volt" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 3, - "y": 1 - }, - "id": 10, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "firstNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH charging_process AS (\n SELECT id, end_date\n FROM charging_processes\n WHERE car_id = $car_id\n ORDER BY start_date DESC\n LIMIT 1\n)\nSELECT\n $__time(date),\n CASE WHEN charging_process.end_date IS NULL THEN charger_voltage\n ELSE 0\n END AS \"Charging Voltage [V]\"\nFROM charges, charging_process\nWHERE charging_process.id = charging_process_id\nORDER BY date DESC\nLIMIT 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charging Voltage", - "type": "gauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "fieldMinMax": false, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-green", - "value": 0 - } - ] - }, - "unit": "kwatt" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 6, - "y": 1 - }, - "id": 11, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "firstNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH charging_process AS (\n SELECT id, end_date\n FROM charging_processes\n WHERE car_id = $car_id\n ORDER BY start_date DESC\n LIMIT 1\n)\nSELECT\n $__time(date),\n CASE WHEN charging_process.end_date IS NULL THEN charger_power\n ELSE 0\n END AS \"Power [kW]\"\nFROM charges, charging_process\nWHERE charging_process.id = charging_process_id\nORDER BY date DESC\nLIMIT 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n CASE WHEN lfp_battery THEN 170 ELSE 250 END as max_charging_kw\r\nfrom cars inner join car_settings on cars.settings_id = car_settings.id\r\nwhere cars.id = $car_id", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charging Power", - "transformations": [ - { - "id": "configFromData", - "options": { - "configRefId": "B", - "mappings": [ - { - "fieldName": "max_charging_kw", - "handlerKey": "max" - } - ] - } - } - ], - "type": "gauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percent" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 15, - "x": 9, - "y": 1 - }, - "id": 13, - "links": [ - { - "targetBlank": true, - "title": "Charge Level", - "url": "/d/WopVO_mgz/charge-level?${__url_time_range}" - } - ], - "options": { - "legend": { - "calcs": [ - "max", - "min" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT $__time(date), battery_level AS \"SOC\"\nFROM (\n\tSELECT battery_level, date\n\tFROM positions\n\tWHERE car_id = $car_id AND ideal_battery_range_km IS NOT NULL AND $__timeFilter(date)\n\tUNION ALL\n\tSELECT battery_level, date\n\tFROM charges c \n JOIN charging_processes p ON p.id = c.charging_process_id\n\tWHERE $__timeFilter(date) AND p.car_id = $car_id) AS data\nORDER BY date ASC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charge Level", - "type": "timeseries" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": ".*_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 0, - "y": 5 - }, - "id": 14, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "first" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n sum((start_${preferred_range}_range_km - end_${preferred_range}_range_km) * car.efficiency * 1000) / \n convert_km(sum(distance)::numeric, '$length_unit') as \"consumption_$length_unit\"\nFROM drives\nJOIN cars car ON car.id = car_id\nWHERE $__timeFilter(start_date) AND car_id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Consumption (net)", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": ".*_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 3, - "y": 5 - }, - "id": 22, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH d AS (\n\tSELECT\n\t\tc.car_id,\n\t\tlag(end_${preferred_range}_range_km) OVER (ORDER BY start_date) - start_${preferred_range}_range_km AS range_loss,\n\t\tp.odometer - lag(p.odometer) OVER (ORDER BY start_date) AS distance\n\tFROM charging_processes c\n\tLEFT JOIN positions p ON p.id = c.position_id \n\tWHERE\n\t end_date IS NOT NULL AND\n\t c.car_id = $car_id AND\n\t $__timeFilter(start_date)\n\tORDER BY start_date\n),\n\nrange_loss_between_charges AS (\n SELECT sum(range_loss) AS range_loss\n FROM d\n WHERE distance >= 0 AND range_loss >= 0\n GROUP BY car_id\n),\n\ncharge_dates AS (\n\tSELECT\n\t\tmin(start_date) as first_charge,\n\t\tmax(end_date) as last_charge\n\tFROM\n\t\tcharging_processes\n\tWHERE\n\t\tend_date IS NOT NULL\n\t\tAND car_id = $car_id\n\t\tAND $__timeFilter(start_date)\n),\n\nrange_loss_before_first_charge AS (\n\tSELECT\n\t\tmax(${preferred_range}_battery_range_km) - min(${preferred_range}_battery_range_km) AS range_loss\n\tFROM positions, charge_dates\n\tWHERE\n\t\tcar_id = $car_id\n\t\tAND $__timeFilter(date)\n\t\tAND ((select first_charge from charge_dates) is null OR date < (select first_charge from charge_dates))\n),\n\nrange_loss_after_last_charge AS (\n\tSELECT\n\t\tmax(${preferred_range}_battery_range_km) - min(${preferred_range}_battery_range_km) AS range_loss\n\tFROM positions, charge_dates\n\tWHERE\n\t\tcar_id = $car_id\n\t\tAND $__timeFilter(date)\n\t\tAND date > (select last_charge from charge_dates)\t\n),\n\ntotal_range_loss AS (\n SELECT sum(range_loss) as range_loss\n FROM (\n SELECT range_loss FROM range_loss_between_charges\n UNION ALL\n SELECT range_loss FROM range_loss_before_first_charge\n UNION ALL\n SELECT range_loss FROM range_loss_after_last_charge\n ) r\n),\n\ndistance AS (\n SELECT max(odometer) - min(odometer) as distance\n FROM positions\n WHERE car_id = $car_id AND $__timeFilter(date)\n)\n\nSELECT \n NULLIF(range_loss, 0) * (c.efficiency * 1000) / convert_km(NULLIF(distance::numeric, 0), '$length_unit') as \"consumption_$length_unit\"\nFROM total_range_loss, distance\nLEFT JOIN cars c ON c.id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Ø Consumption (gross)", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 6, - "y": 5 - }, - "id": 24, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n convert_km(sum(distance)::numeric, '$length_unit') AS distance_$length_unit\r\nFROM drives\r\nWHERE $__timeFilter(start_date) AND car_id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Total Distance logged", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "range_km" - }, - "properties": [ - { - "id": "unit", - "value": "lengthkm" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_mi" - }, - "properties": [ - { - "id": "unit", - "value": "lengthmi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 0, - "y": 8 - }, - "id": 25, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "first" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT $__time(date), range as \"range_$length_unit\"\nFROM (\n\t(SELECT date, convert_km(${preferred_range}_battery_range_km, '$length_unit') AS range\n\tFROM positions\n\tWHERE car_id = $car_id AND ideal_battery_range_km IS NOT NULL\n ORDER BY date DESC\n\tLIMIT 1)\n\tUNION ALL\n\t(SELECT date, convert_km(${preferred_range}_battery_range_km, '$length_unit') AS range\n\tFROM charges c\n\tJOIN charging_processes p ON p.id = c.charging_process_id\n\tWHERE p.car_id = $car_id\n\tORDER BY date DESC\n\tLIMIT 1)\n) AS data\nORDER BY date DESC\nLIMIT 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Range", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "version" - }, - "properties": [ - { - "id": "unit", - "value": "string" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 3, - "y": 8 - }, - "id": 2, - "links": [ - { - "targetBlank": true, - "title": "Updates", - "url": "/d/IiC07mgWz/updates" - } - ], - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "first" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "/^version$/", - "values": true - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select split_part(version, ' ', 1) as version \nfrom updates \nwhere car_id = $car_id \norder by start_date desc \nlimit 1", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Firmware", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "odometer_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "odometer_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - } - ] - }, - "gridPos": { - "h": 3, - "w": 3, - "x": 6, - "y": 8 - }, - "id": 6, - "links": [ - { - "targetBlank": true, - "title": "Mileage", - "url": "/d/NjtMTFggz/mileage" - } - ], - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "first" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "select $__time(date), convert_km(odometer::numeric, '$length_unit') as \"odometer_$length_unit\"\nfrom positions \nwhere car_id = $car_id and ideal_battery_range_km is not null\norder by date desc \nlimit 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Odometer", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "stepAfter", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Charging Voltage [V]" - }, - "properties": [ - { - "id": "min", - "value": 0 - }, - { - "id": "max", - "value": 250 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charger_power" - }, - "properties": [ - { - "id": "displayName", - "value": "Power" - }, - { - "id": "unit", - "value": "kwatt" - }, - { - "id": "custom.axisPlacement", - "value": "hidden" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "battery_heater" - }, - "properties": [ - { - "id": "displayName", - "value": "Battery heater" - }, - { - "id": "custom.axisPlacement", - "value": "hidden" - }, - { - "id": "unit", - "value": "bool_on_off" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charger_actual_current" - }, - "properties": [ - { - "id": "displayName", - "value": "Current" - }, - { - "id": "unit", - "value": "amp" - }, - { - "id": "custom.axisPlacement", - "value": "hidden" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_added" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy added" - }, - { - "id": "unit", - "value": "kwatth" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 15, - "x": 9, - "y": 8 - }, - "id": 15, - "links": [ - { - "targetBlank": true, - "title": "Charging Stats", - "url": "/d/-pkIkhmRz/charging-stats?${__url_time_range}" - } - ], - "options": { - "legend": { - "calcs": [ - "max", - "min" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n $__time(date),\n charger_power,\n (case when battery_heater_on then 1 when battery_heater then 1 else 0 end) as battery_heater,\n charger_actual_current,\n c.charge_energy_added\nFROM\n charges c\njoin\n charging_processes p ON p.id = c.charging_process_id \nWHERE\n $__timeFilter(date) and\n p.car_id = $car_id\nORDER BY\n date ASC", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n $__time(date),\n charger_voltage as \"Charging Voltage [V]\"\nFROM\n charges c\njoin\n charging_processes p ON p.id = c.charging_process_id \nWHERE\n $__timeFilter(date) and\n p.car_id = $car_id\nORDER BY\n date ASC", - "refId": "C", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charging Details", - "type": "timeseries" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-green", - "value": 0 - } - ] - }, - "unit": "degree" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 0, - "y": 11 - }, - "id": 16, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "firstNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\r\n\t$__time(date),\r\n\tconvert_celsius(driver_temp_setting, '$temp_unit') as \"Driver Temperature [°$temp_unit]\",\r\n\tconvert_celsius(inside_temp, '$temp_unit') AS \"Inside Temperature [°$temp_unit]\"\r\nFROM positions\r\nWHERE driver_temp_setting IS NOT NULL AND inside_temp IS NOT NULL AND car_id = $car_id AND date >= (TIMEZONE('UTC', NOW()) - INTERVAL '60m')\r\nORDER BY date DESC\r\nLIMIT 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Driver Temp", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "byVariable": false, - "include": { - "pattern": "time|Driver.*" - } - } - } - ], - "type": "gauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-green", - "value": 0 - } - ] - }, - "unit": "degree" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 3, - "y": 11 - }, - "id": 8, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "firstNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH last_position AS (\n\tSELECT date, convert_celsius(outside_temp, '$temp_unit') AS \"Outside Temperature [°$temp_unit]\"\n\tFROM positions\n\tWHERE car_id = $car_id AND outside_temp IS NOT NULL AND date >= (TIMEZONE('UTC', NOW()) - INTERVAL '60m')\n\tORDER BY date DESC\n\tLIMIT 1\n),\nlast_charge AS (\n\tSELECT date, convert_celsius(outside_temp, '$temp_unit') AS \"Outside Temperature [°$temp_unit]\"\n\tFROM charges\n\tJOIN charging_processes ON charges.charging_process_id = charging_processes.id\n\tWHERE car_id = $car_id AND outside_temp IS NOT NULL AND date >= (TIMEZONE('UTC', NOW()) - INTERVAL '60m')\n\tORDER BY date DESC\n\tLIMIT 1\n)\nSELECT * FROM last_position\nUNION ALL\nSELECT * FROM last_charge\nORDER BY date DESC\nLIMIT 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Outside Temp", - "type": "gauge" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "decimals": 0, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "semi-dark-green", - "value": 0 - } - ] - }, - "unit": "degree" - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 6, - "y": 11 - }, - "id": 9, - "options": { - "minVizHeight": 75, - "minVizWidth": 75, - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "firstNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 16, - "refId": "A" - } - ], - "title": "Inside Temp", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "pattern": "time|Inside.*" - } - } - } - ], - "type": "gauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisPlacement": "auto", - "fillOpacity": 100, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineWidth": 0, - "spanNulls": false - }, - "mappings": [ - { - "options": { - "0": { - "color": "#6ED0E0", - "index": 0, - "text": "online" - }, - "1": { - "color": "#8F3BB8", - "index": 1, - "text": "driving" - }, - "2": { - "color": "#F2CC0C", - "index": 2, - "text": "charging" - }, - "3": { - "color": "#FFB357", - "index": 3, - "text": "offline" - }, - "4": { - "color": "#56A64B", - "index": 4, - "text": "asleep" - }, - "5": { - "color": "#6ED0E0", - "index": 5, - "text": "online" - }, - "6": { - "color": "#E02F44", - "index": 6, - "text": "updating" - }, - "null": { - "index": 7, - "text": "N/A" - } - }, - "type": "value" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 5, - "w": 24, - "x": 0, - "y": 15 - }, - "id": 20, - "links": [ - { - "targetBlank": true, - "title": "States", - "url": "/d/xo4BNRkZz/states?${__url_time_range}" - } - ], - "options": { - "alignValue": "center", - "legend": { - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "mergeValues": true, - "rowHeight": 0.9, - "showValue": "auto", - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH states AS (\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [2, 0]) AS state\n FROM charging_processes\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [1, 0]) AS state\n FROM drives\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n start_date AS date,\n CASE\n WHEN state = 'offline' THEN 3\n WHEN state = 'asleep' THEN 4\n WHEN state = 'online' THEN 5\n END AS state\n FROM states\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [6, 0]) AS state\n FROM updates\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n)\nSELECT date AS \"time\", state\nFROM states\nWHERE \n date IS NOT NULL AND\n ($__timeFrom() :: timestamp - interval '30 day') < date AND \n date < ($__timeTo() :: timestamp + interval '30 day') \nORDER BY date ASC, state ASC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "States", - "type": "state-timeline" - } - ], - "preload": false, - "refresh": "30s", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-24h", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Overview", - "uid": "kOuP_Fggz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-projected-range.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-projected-range.yaml deleted file mode 100644 index 33e5a24..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-projected-range.yaml +++ /dev/null @@ -1,772 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-projected-range - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-projected-range.json: | - { - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "enable": false, - "hide": false, - "iconColor": "rgba(255, 96, 96, 1)", - "limit": 100, - "name": "Charged", - "rawQuery": "SELECT\n$__time(start_date),\nend_date as timeend,\nconcat('Charged: ',round(cast(charge_energy_added as numeric),2),' kWh') AS text\nFROM charging_processes\nWHERE\n$__timeFilter(start_date) AND duration_min > 5\nORDER BY start_date DESC", - "showIn": 0, - "tags": [], - "type": "tags" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 1, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "Projected Range", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 30, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "stepAfter", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "decimals": 0, - "links": [], - "mappings": [], - "min": 200, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/Mileage.*/" - }, - "properties": [ - { - "id": "custom.fillOpacity", - "value": 0 - }, - { - "id": "custom.axisLabel", - "value": "Mileage" - }, - { - "id": "min" - } - ] - } - ] - }, - "gridPos": { - "h": 21, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "options": { - "legend": { - "calcs": [ - "mean", - "max", - "min" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\t$__timeGroup(date, $interval) AS time,\n\tconvert_km((sum(${preferred_range}_battery_range_km) / nullif(sum(coalesce(usable_battery_level,battery_level)),0) * 100)::numeric, '$length_unit') AS \"Projected ${preferred_range} range [$length_unit]\"\nFROM\n\t(\n select battery_level, usable_battery_level, date,\n rated_battery_range_km, ideal_battery_range_km, outside_temp\n from positions\n where\n car_id = $car_id and $__timeFilter(date) and ideal_battery_range_km is not null\n union all\n select battery_level, coalesce(usable_battery_level,battery_level) as usable_battery_level, date,\n rated_battery_range_km, ideal_battery_range_km, outside_temp\n from charges c\n join\n charging_processes p ON p.id = c.charging_process_id \n where\n $__timeFilter(date) and p.car_id = $car_id\n ) as data\n\nGROUP BY\n\t1\nhaving convert_km((sum(${preferred_range}_battery_range_km) / nullif(sum(coalesce(usable_battery_level,battery_level)),0) * 100)::numeric, '$length_unit') is not null\nORDER BY\n\t1,2 DESC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\t$__timeGroup(date, $interval) AS time,\n\tconvert_km(avg(odometer)::numeric, '$length_unit') AS \"Mileage [$length_unit]\"\nFROM\n\tpositions\nWHERE\n\t$__timeFilter(date) and\n\tcar_id = $car_id and ideal_battery_range_km is not null\nGROUP BY\n\t1\nORDER BY\n\t1,2 DESC;", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Projected Range - Mileage", - "type": "timeseries" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "Projected Range", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 30, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "stepAfter", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "decimals": 0, - "links": [], - "mappings": [], - "min": 200, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/Battery.*/" - }, - "properties": [ - { - "id": "custom.fillOpacity", - "value": 0 - }, - { - "id": "max", - "value": 100 - }, - { - "id": "custom.axisLabel", - "value": "Battery Level" - } - ] - } - ] - }, - "gridPos": { - "h": 21, - "w": 24, - "x": 0, - "y": 22 - }, - "id": 6, - "options": { - "legend": { - "calcs": [ - "mean", - "max", - "min" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\t$__timeGroup(date, $interval) AS time,\n\tconvert_km((sum(${preferred_range}_battery_range_km) / sum(battery_level) * 100 ) - (sum(${preferred_range}_battery_range_km) / sum(battery_level) * 100 * (avg(battery_level)-avg(coalesce(usable_battery_level,battery_level)))/100 ), '$length_unit') AS \"Projected Range (using usable_battery_level) [$length_unit]\",\n\tconvert_km(max(${preferred_range}_battery_range_km) / max(battery_level) * 100, '$length_unit') AS \"Projected Range (using battery_level)[$length_unit]\"\nFROM\n\t(\n select battery_level, usable_battery_level, date,\n rated_battery_range_km, ideal_battery_range_km, outside_temp\n from positions\n where\n car_id = $car_id and $__timeFilter(date) and ideal_battery_range_km is not null\n union all\n select battery_level, coalesce(usable_battery_level,battery_level) as usable_battery_level, date,\n rated_battery_range_km, ideal_battery_range_km, outside_temp\n from charges c\n join\n charging_processes p ON p.id = c.charging_process_id \n where\n $__timeFilter(date) and p.car_id = $car_id\n ) as data\n\nGROUP BY\n\t1\nORDER BY\n\t1,2 DESC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "select \n\t$__timeGroup(date, $interval) AS time,\n avg(battery_level) AS \"Battery Level [%]\", avg(coalesce(usable_battery_level, battery_level)) as \"Usable Battery Level [%]\"\nfrom\n (SELECT\n battery_level, usable_battery_level\n , date\n FROM\n positions\n WHERE\n car_id = $car_id AND\n $__timeFilter(date) and ideal_battery_range_km is not null\n UNION ALL\n select\n battery_level, null as usable_battery_level\n , date\n from charges c\njoin\n charging_processes p ON p.id = c.charging_process_id \nWHERE\n $__timeFilter(date) and\n p.car_id = $car_id) as data\n\nGROUP BY\n 1\nORDER BY\n 1 ASC", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Projected Range - Battery Level", - "type": "timeseries" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "Projected Range", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 30, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "stepAfter", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "decimals": 0, - "links": [], - "mappings": [], - "min": 200, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/Temp.*/" - }, - "properties": [ - { - "id": "custom.fillOpacity", - "value": 0 - }, - { - "id": "custom.axisLabel", - "value": "Temp" - }, - { - "id": "min" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*using usable_battery_level.*/" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#56A64B", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*using battery_level.*/" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#C8F2C2", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 21, - "w": 24, - "x": 0, - "y": 43 - }, - "id": 5, - "options": { - "legend": { - "calcs": [ - "mean", - "max", - "min" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "\nSELECT\n\t$__timeGroup(date, $interval) AS time,\n\tconvert_km((sum(${preferred_range}_battery_range_km) / sum(battery_level) * 100 ) - (sum(${preferred_range}_battery_range_km) / sum(battery_level) * 100 * (avg(battery_level)-avg(coalesce(usable_battery_level,battery_level)))/100 ), '$length_unit') AS \"Projected Range (using usable_battery_level) [$length_unit]\",\n\tconvert_km(max(${preferred_range}_battery_range_km) / max(battery_level) * 100, '$length_unit') AS \"Projected Range (using battery_level)[$length_unit]\"\nFROM\n\t(\n select battery_level, usable_battery_level, date,\n rated_battery_range_km, ideal_battery_range_km, outside_temp\n from positions\n where\n car_id = $car_id and $__timeFilter(date) and ideal_battery_range_km is not null\n union all\n select battery_level, coalesce(usable_battery_level,battery_level) as usable_battery_level, date,\n rated_battery_range_km, ideal_battery_range_km, outside_temp\n from charges c\n join\n charging_processes p ON p.id = c.charging_process_id \n where\n $__timeFilter(date) and p.car_id = $car_id\n ) as data\n\nGROUP BY\n\t1\nORDER BY\n\t1,2 DESC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\t$__timeGroup(date, $interval) AS time,\n\tavg(convert_celsius(outside_temp, '$temp_unit')) as \"Outdoor Temperature [°$temp_unit]\"\n\nFROM\n\tpositions\nWHERE\n\t$__timeFilter(date) and\n\tcar_id = $car_id and ideal_battery_range_km is not null\nGROUP BY\n\t1\nORDER BY\n\t1,2 DESC", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Projected Range - Outdoor Temp", - "type": "timeseries" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "auto": false, - "auto_count": 30, - "auto_min": "10s", - "current": { - "text": "6h", - "value": "6h" - }, - "hide": 1, - "label": "Time Resolution", - "name": "interval", - "options": [ - { - "selected": false, - "text": "5m", - "value": "5m" - }, - { - "selected": false, - "text": "15m", - "value": "15m" - }, - { - "selected": false, - "text": "30m", - "value": "30m" - }, - { - "selected": false, - "text": "1h", - "value": "1h" - }, - { - "selected": false, - "text": "3h", - "value": "3h" - }, - { - "selected": true, - "text": "6h", - "value": "6h" - } - ], - "query": "5m,15m,30m,1h,3h,6h", - "refresh": 2, - "type": "interval" - } - ] - }, - "time": { - "from": "now-6M", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Projected Range", - "uid": "riqUfXgRz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-states.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-states.yaml deleted file mode 100644 index 37b4806..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-states.yaml +++ /dev/null @@ -1,528 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-states - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-states.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 16, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "Only distinguishes between online, offline and asleep.", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "dateTimeAsLocal" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 2, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "mean" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "/^time$/", - "values": true - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select $__time(start_date), state from states where car_id = $car_id order by start_date desc limit 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Last state change", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "Only distinguishes between online, offline and asleep.", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 12, - "y": 1 - }, - "id": 6, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "first" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "/^state$/", - "values": true - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select $__time(start_date), state from states where car_id = $car_id order by start_date desc limit 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Current State", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "based on any data ever recorded.", - "fieldConfig": { - "defaults": { - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "max": 1, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 18, - "y": 1 - }, - "id": 8, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "select 1 - sum(duration_min) / (EXTRACT(EPOCH FROM (max(end_date) - min(start_date))) / 60), 1 as time from drives where car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "parked (%)", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisPlacement": "auto", - "fillOpacity": 100, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineWidth": 0, - "spanNulls": false - }, - "mappings": [ - { - "options": { - "0": { - "color": "#6ED0E0", - "index": 0, - "text": "online" - }, - "1": { - "color": "#8F3BB8", - "index": 1, - "text": "driving" - }, - "2": { - "color": "#F2CC0C", - "index": 2, - "text": "charging" - }, - "3": { - "color": "#FFB357", - "index": 3, - "text": "offline" - }, - "4": { - "color": "#56A64B", - "index": 4, - "text": "asleep" - }, - "5": { - "color": "#6ED0E0", - "index": 5, - "text": "online" - }, - "6": { - "color": "#E02F44", - "index": 6, - "text": "updating" - }, - "null": { - "index": 7, - "text": "N/A" - } - }, - "type": "value" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 14, - "options": { - "alignValue": "center", - "legend": { - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "mergeValues": true, - "rowHeight": 0.9, - "showValue": "auto", - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH states AS (\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [2, 0]) AS state\n FROM charging_processes\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [1, 0]) AS state\n FROM drives\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n start_date AS date,\n CASE\n WHEN state = 'offline' THEN 3\n WHEN state = 'asleep' THEN 4\n WHEN state = 'online' THEN 5\n END AS state\n FROM states\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [6, 0]) AS state\n FROM updates\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n)\nSELECT date AS \"time\", state\nFROM states\nWHERE \n date IS NOT NULL AND\n ($__timeFrom() :: timestamp - interval '30 day') < date AND \n date < ($__timeTo() :: timestamp + interval '30 day') \nORDER BY date ASC, state ASC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "States", - "type": "state-timeline" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-2d", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla States", - "uid": "xo4BNRkZz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-statistics.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-statistics.yaml deleted file mode 100644 index 9cec1a6..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-statistics.yaml +++ /dev/null @@ -1,1262 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-statistics - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-statistics.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "noValue": "--", - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "red", - "value": 0 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Time driven" - }, - "properties": [ - { - "id": "unit", - "value": "dtdurations" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 170 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Period" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Trip", - "url": "/d/FkUpJpQZk/trip?from=${__data.fields.date_from}&to=${__data.fields.date_to}&var-car_id=$car_id" - } - ] - }, - { - "id": "custom.minWidth", - "value": 195 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Driving Efficiency" - }, - "properties": [ - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-orange", - "value": 0 - }, - { - "color": "light-orange", - "value": 0.65 - }, - { - "color": "light-green", - "value": 0.99 - } - ] - } - }, - { - "id": "max", - "value": 1.15 - }, - { - "id": "min", - "value": 0 - }, - { - "id": "custom.cellOptions", - "value": { - "mode": "lcd", - "type": "gauge" - } - }, - { - "id": "decimals" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Energy used" - }, - "properties": [ - { - "id": "decimals", - "value": 1 - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Charging stats", - "url": "/d/-pkIkhmRz/charging-stats?from=${__data.fields.date_from}&to=${__data.fields.date_to}&var-car_id=$car_id" - } - ] - }, - { - "id": "unit", - "value": "kwatth" - }, - { - "id": "custom.minWidth", - "value": 120 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Ø Energy used / Charge" - }, - "properties": [ - { - "id": "unit", - "value": "kwatth" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 190 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Costs" - }, - "properties": [ - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "# of Charges" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Charges", - "url": "/d/TSmNYvRRk/charges?from=${__data.fields.date_from}&to=${__data.fields.date_to}&var-car_id=$car_id" - } - ] - }, - { - "id": "custom.minWidth", - "value": 110 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "# of Drives" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Drives", - "url": "/d/Y8upc6ZRk/drives?from=${__data.fields.date_from}&to=${__data.fields.date_to}&var-car_id=$car_id" - } - ] - }, - { - "id": "custom.minWidth", - "value": 95 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/sum_distance_km/" - }, - "properties": [ - { - "id": "unit", - "value": "km" - }, - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "custom.minWidth", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/avg_outside_temp_c/" - }, - "properties": [ - { - "id": "unit", - "value": "celsius" - }, - { - "id": "displayName", - "value": "Ø Temp" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - }, - { - "color": "super-light-green", - "value": 10 - }, - { - "color": "super-light-red", - "value": 20 - } - ] - } - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.minWidth", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/sum_distance_mi/" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "mi" - }, - { - "id": "custom.minWidth", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/consumption_net_mi/" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "custom.width", - "value": 170 - }, - { - "id": "displayName", - "value": "Ø Consumption (net)" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/consumption_gross_mi/" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (gross)" - }, - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "custom.width", - "value": 190 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/consumption_net_km/" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "custom.width", - "value": 170 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/consumption_gross_km/" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (gross)" - }, - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "custom.width", - "value": 190 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/avg_outside_temp_f/" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Temp" - }, - { - "id": "unit", - "value": "fahrenheit" - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - }, - { - "color": "super-light-green", - "value": 50 - }, - { - "color": "super-light-red", - "value": 68 - } - ] - } - }, - { - "id": "custom.minWidth", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "date_from" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "date_to" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Ø Cost / kWh" - }, - "properties": [ - { - "id": "decimals", - "value": 2 - }, - { - "id": "mappings", - "value": [ - { - "options": { - "NaN": { - "index": 0, - "text": "--" - } - }, - "type": "value" - } - ] - }, - { - "id": "custom.minWidth", - "value": 115 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Ø Cost / 100 km" - }, - "properties": [ - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 135 - }, - { - "id": "mappings", - "value": [ - { - "options": { - "NaN": { - "index": 0, - "text": "--" - } - }, - "type": "value" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Consumption OH" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 140 - }, - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "mappings", - "value": [ - { - "options": { - "NaN": { - "index": 0, - "text": "--" - } - }, - "type": "value" - } - ] - } - ] - } - ] - }, - "gridPos": { - "h": 18, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "maxPerRow": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "frameIndex": 1, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Starting at" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\nSELECT\n duration_min > 1 AND\n distance > 1 AND\n ( \n start_position.usable_battery_level IS NULL OR\n (end_position.battery_level - end_position.usable_battery_level) = 0 \n ) AS is_sufficiently_precise,\n start_${preferred_range}_range_km - end_${preferred_range}_range_km AS range_diff,\n date_trunc('$period', timezone('UTC', start_date), '$__timezone') as date,\n drives.*\nFROM drives\n LEFT JOIN positions start_position ON start_position_id = start_position.id\n LEFT JOIN positions end_position ON end_position_id = end_position.id)\nSELECT\n EXTRACT(EPOCH FROM date)*1000 AS date_from,\n EXTRACT(EPOCH FROM date + interval '1 $period')*1000 AS date_to,\n CASE '$period'\n WHEN 'month' THEN to_char(timezone('$__timezone', date), 'YYYY Month')\n WHEN 'year' THEN to_char(timezone('$__timezone', date), 'YYYY')\n WHEN 'week' THEN 'week ' || to_char(timezone('$__timezone', date), 'WW') || ' starting ' || to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n ELSE to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n END AS display,\n date,\n sum(duration_min)*60 AS sum_duration_h, \n convert_km(max(end_km)::numeric - min(start_km)::numeric, '$length_unit') AS sum_distance_$length_unit,\n convert_celsius(avg(outside_temp_avg), '$temp_unit') AS avg_outside_temp_$temp_unit,\n count(*) AS cnt,\n case when sum(range_diff) > 0 then sum(distance)/sum(range_diff) else null end AS efficiency\nFROM data WHERE\n car_id = $car_id AND\n $__timeFilter(start_date)\nGROUP BY date", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n charging_processes.*,\n \tdate_trunc('$period', timezone('UTC', start_date), '$__timezone') as date\n FROM charging_processes)\nSELECT\n EXTRACT(EPOCH FROM date)*1000 AS date_from,\n EXTRACT(EPOCH FROM date + interval '1 $period')*1000 AS date_to,\n CASE '$period'\n WHEN 'month' THEN to_char(timezone('$__timezone', date), 'YYYY Month')\n WHEN 'year' THEN to_char(timezone('$__timezone', date), 'YYYY')\n WHEN 'week' THEN 'week ' || to_char(timezone('$__timezone', date), 'WW') || ' starting ' || to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n ELSE to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n END AS display,\n date,\n sum(greatest(charge_energy_added,charge_energy_used)) AS sum_energy_used_kwh,\n sum(charge_energy_added) as sum_energy_added_kwh,\n sum(greatest(charge_energy_added,charge_energy_used)) / count(*) AS avg_energy_charged_kwh,\n sum(cost) AS cost_charges,\n count(*) AS cnt_charges\nFROM data WHERE\n car_id = $car_id AND\n $__timeFilter(start_date) AND\n (charge_energy_added IS NULL OR charge_energy_added > 0.1)\nGROUP BY date", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n drives.*,\n date_trunc('$period', timezone('UTC', start_date), '$__timezone') as date\n FROM drives)\nSELECT\n EXTRACT(EPOCH FROM date)*1000 AS date_from,\n EXTRACT(EPOCH FROM date + interval '1 $period')*1000 AS date_to,\n CASE '$period'\n WHEN 'month' THEN to_char(timezone('$__timezone', date), 'YYYY Month')\n WHEN 'year' THEN to_char(timezone('$__timezone', date), 'YYYY')\n WHEN 'week' THEN 'week ' || to_char(timezone('$__timezone', date), 'WW') || ' starting ' || to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n ELSE to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n END AS display,\n date,\n sum((start_${preferred_range}_range_km - end_${preferred_range}_range_km) * car.efficiency * 1000) / \n convert_km(sum(distance)::numeric, '$length_unit') as consumption_net_$length_unit\nFROM data\nJOIN cars car ON car.id = car_id\nWHERE\n car_id = $car_id AND\n $__timeFilter(start_date)\nGROUP BY date", - "refId": "C", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "-- Query shared between Charging Stats, Statistics & Trip Dashboards (with minor changes) - ensure to modify in all places when necessary\n\nwith drives_start_event as (\n\n select\n 'drive_start' as event, start_date as date, start_${preferred_range}_range_km as range, start_km as odometer, car_id\n from drives\n where car_id = $car_id and $__timeFilter(start_date) and 0 = $high_precision\n\n),\n\ndrives_end_event as (\n\n select\n 'drive_end' as event, end_date as date, end_${preferred_range}_range_km as range, end_km as odometer, car_id\n from drives\n where car_id = $car_id and $__timeFilter(start_date) and 0 = $high_precision\n\n),\n\ncharging_processes_start_event as (\n\n select\n 'charging_process_start' as event, start_date as date, start_${preferred_range}_range_km as range, p.odometer, cp.car_id\n from charging_processes cp\n inner join positions p on cp.position_id = p.id\n where cp.car_id = $car_id and $__timeFilter(start_date) and 0 = $high_precision\n\n),\n\ncharging_processes_end_event as (\n\n select\n 'charging_process_end' as event, end_date as date, end_${preferred_range}_range_km as range, p.odometer, cp.car_id\n from charging_processes cp\n inner join positions p on cp.position_id = p.id\n where cp.car_id = $car_id and $__timeFilter(start_date) and 0 = $high_precision\n\n),\n\npositions as (\n\n select\n case\n when drive_id is not null and lead(drive_id) over w is not null then 'drive_start'\n else 'something'\n end as event,\n date, ${preferred_range}_battery_range_km as range, p.odometer, p.car_id\n from positions p\n where ideal_battery_range_km is not null and car_id = $car_id and 1 = $high_precision\n and (drive_id in (select id from drives where $__timeFilter(start_date)) or drive_id is null and $__timeFilter(date))\n window w as (order by date)\n\n),\n\ncombined as (\n\n select * from drives_start_event\n union all\n select * from drives_end_event\n union all\n select * from charging_processes_start_event\n union all\n select * from charging_processes_end_event\n union all\n select * from positions\n\n),\n\nfinal as (\n\n select\n car_id,\n date_trunc('$period', timezone('UTC', date), '$__timezone') as date,\n lead(odometer) over w - odometer as distance,\n case when event != 'drive_start' then greatest(range - lead(range) over w, 0) else range - lead(range) over w end as range_loss\n from combined\n window w as (order by date asc)\n\n)\n\nselect\n EXTRACT(EPOCH FROM date)*1000 AS date_from,\n EXTRACT(EPOCH FROM date + interval '1 $period')*1000 AS date_to,\n CASE '$period'\n WHEN 'month' THEN to_char(timezone('$__timezone', date), 'YYYY Month')\n WHEN 'year' THEN to_char(timezone('$__timezone', date), 'YYYY')\n WHEN 'week' THEN 'week ' || to_char(timezone('$__timezone', date), 'WW') || ' starting ' || to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n ELSE to_char(timezone('$__timezone', date), 'YYYY-MM-DD')\n END AS display,\n date,\n (sum(range_loss) * c.efficiency * 1000) / nullif(convert_km(sum(distance)::numeric, '$length_unit'), 0) as consumption_gross_$length_unit\nfrom final\n inner join cars c on car_id = c.id\ngroup by 1, 2, 3, 4, c.efficiency", - "refId": "D", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "per ${period}", - "transformations": [ - { - "id": "merge", - "options": {} - }, - { - "id": "seriesToColumns", - "options": { - "byField": "date" - } - }, - { - "id": "sortBy", - "options": { - "fields": {}, - "sort": [ - { - "desc": true, - "field": "date" - } - ] - } - }, - { - "id": "calculateField", - "options": { - "alias": "avg_cost_kwh", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "cost_charges" - } - }, - "operator": "/", - "right": { - "matcher": { - "id": "byName", - "options": "sum_energy_used_kwh" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "avg_cost_added_kwh", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "cost_charges" - } - }, - "operator": "/", - "right": { - "matcher": { - "id": "byName", - "options": "sum_energy_added_kwh" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "cost_per_1000km", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "consumption_gross_km" - } - }, - "operator": "*", - "right": { - "matcher": { - "id": "byName", - "options": "avg_cost_added_kwh" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "cost_per_1000mi", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "consumption_gross_mi" - } - }, - "operator": "*", - "right": { - "matcher": { - "id": "byName", - "options": "avg_cost_added_kwh" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "avg_cost_km", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "cost_per_1000km" - } - }, - "operator": "/", - "right": { - "fixed": "10" - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "avg_cost_mi", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "cost_per_1000mi" - } - }, - "operator": "/", - "right": { - "fixed": "10" - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "overhead_pct_km_temp", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "consumption_net_km" - } - }, - "operator": "/", - "right": { - "matcher": { - "id": "byName", - "options": "consumption_gross_km" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "overhead_pct_km", - "binary": { - "left": { - "fixed": "1" - }, - "operator": "-", - "right": { - "matcher": { - "id": "byName", - "options": "overhead_pct_km_temp" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "overhead_pct_mi_temp", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "consumption_net_mi" - } - }, - "operator": "/", - "right": { - "matcher": { - "id": "byName", - "options": "consumption_gross_mi" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "calculateField", - "options": { - "alias": "overhead_pct_mi", - "binary": { - "left": { - "fixed": "1" - }, - "operator": "-", - "right": { - "matcher": { - "id": "byName", - "options": "overhead_pct_mi_temp" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - } - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - "avg_cost_added_kwh": true, - "cost_per_1000km": true, - "cost_per_1000mi": true, - "date": true, - "overhead_pct_km_temp": true, - "overhead_pct_mi_temp": true, - "sum_energy_added_kwh": true - }, - "includeByName": {}, - "indexByName": { - "avg_cost_km": 12, - "avg_cost_kwh": 11, - "avg_cost_mi": 12, - "avg_energy_charged_kwh": 8, - "avg_outside_temp_c": 4, - "avg_outside_temp_f": 4, - "cnt": 5, - "cnt_charges": 10, - "consumption_gross_km": 14, - "consumption_gross_mi": 14, - "consumption_net_km": 13, - "consumption_net_mi": 13, - "cost_charges": 9, - "date": 1, - "date_from": 15, - "date_to": 16, - "display": 0, - "efficiency": 6, - "overhead_pct_km": 17, - "overhead_pct_mi": 17, - "sum_distance_km": 3, - "sum_distance_mi": 3, - "sum_duration_h": 2, - "sum_energy_used_kwh": 7 - }, - "renameByName": { - "avg_cost_km": "Ø Cost / 100 km", - "avg_cost_kwh": "Ø Cost / kWh", - "avg_cost_mi": "Ø Cost / 100 mi", - "avg_energy_charged_kwh": "Ø Energy used / Charge", - "avg_outside_temp_c": "", - "avg_outside_temp_f": "", - "cnt": "# of Drives", - "cnt_charges": "# of Charges", - "consumption_gross_km": "", - "consumption_gross_mi": "", - "consumption_net_km": "", - "consumption_net_mi": "", - "cost_charges": "Costs", - "date": "", - "date_from": "", - "date_to": "", - "display": "Period", - "efficiency": "Driving Efficiency", - "overhead_pct_km": "Consumption OH", - "overhead_pct_mi": "Consumption OH", - "sum_distance_km": "", - "sum_distance_mi": "", - "sum_duration_h": "Time driven", - "sum_energy_used_kwh": "Energy used" - } - } - } - ], - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "length unit", - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "temperature unit", - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "month", - "value": "month" - }, - "includeAll": false, - "label": "Period", - "name": "period", - "options": [ - { - "selected": false, - "text": "day", - "value": "day" - }, - { - "selected": false, - "text": "week", - "value": "week" - }, - { - "selected": true, - "text": "month", - "value": "month" - }, - { - "selected": false, - "text": "year", - "value": "year" - } - ], - "query": "day,week,month,year", - "type": "custom" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "no", - "value": "0" - }, - "description": "When enabled \"Ø Consumption (gross)\" will be calculated via Positions instead of Charging Processes and Drives.\n\nWhile being more accurate (especially for shorter periods) this will be slow on slow hardware!", - "includeAll": false, - "label": "High Precision", - "name": "high_precision", - "options": [ - { - "selected": true, - "text": "no", - "value": "0" - }, - { - "selected": false, - "text": "yes", - "value": "1" - } - ], - "query": "no : 0, yes : 1", - "type": "custom" - } - ] - }, - "time": { - "from": "now-10y", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Statistics", - "uid": "1EZnXszMk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-timeline.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-timeline.yaml deleted file mode 100644 index ed5eb08..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-timeline.yaml +++ /dev/null @@ -1,770 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-timeline - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-timeline.json: | - { - "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": 0, - "links": [ - { - "asDropdown": false, - "icon": "dashboard", - "includeVars": false, - "keepTime": false, - "tags": [], - "targetBlank": false, - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "includeVars": false, - "keepTime": false, - "tags": [ - "tesla" - ], - "targetBlank": false, - "title": "Dashboards", - "tooltip": "", - "type": "dashboards", - "url": "" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Start" - }, - "properties": [ - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "custom.width", - "value": 210 - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "", - "url": "/d/FkUpJpQZk/trip?from=${__data.fields.start_date_ts}&to=${__data.fields.end_date_ts}&var-car_id=$car_id" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "SoC" - }, - "properties": [ - { - "id": "custom.width", - "value": 65 - }, - { - "id": "unit", - "value": "percent" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "SoC Diff" - }, - "properties": [ - { - "id": "custom.width", - "value": 80 - }, - { - "id": "unit", - "value": "percent" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "start_path" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_path" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Action" - }, - "properties": [ - { - "id": "custom.width", - "value": 150 - }, - { - "id": "custom.filterable", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "kWh" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - }, - { - "id": "unit", - "value": "kwatth" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "displayName", - "value": "Energy Diff" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Duration" - }, - "properties": [ - { - "id": "unit", - "value": "m" - }, - { - "id": "custom.width", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Start Address" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.start_path:raw}" - } - ] - }, - { - "id": "custom.filterable", - "value": true - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "End Address" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.end_path:raw}" - } - ] - }, - { - "id": "custom.filterable", - "value": true - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "start_date_ts" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_date_ts" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "odometer_km" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_km/" - }, - "properties": [ - { - "id": "unit", - "value": "km" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_mi/" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_c/" - }, - "properties": [ - { - "id": "unit", - "value": "celsius" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_f/" - }, - "properties": [ - { - "id": "unit", - "value": "fahrenheit" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/odometer_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Odometer" - }, - { - "id": "custom.width", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/distance_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "custom.width", - "value": 100 - }, - { - "id": "decimals", - "value": 1 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/range_diff_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Range Diff" - }, - { - "id": "custom.width", - "value": 100 - }, - { - "id": "decimals", - "value": 1 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/outside_temp_avg_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Temp" - }, - { - "id": "custom.width", - "value": 75 - }, - { - "id": "decimals", - "value": 1 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/end_range_.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "Range" - }, - { - "id": "custom.width", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Action" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Slot details", - "url": "${__data.fields.slotlink:raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "slotlink" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - } - ] - }, - "gridPos": { - "h": 22, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Start" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "-- CTE is used in Parking Query\r\nwith drives_and_charging_processes as (\r\n\r\n select 'Drive' as activity, d.start_date, d.end_date, d.start_position_id, d.end_position_id, d.end_address_id, d.end_geofence_id, d.start_${preferred_range}_range_km, d.end_${preferred_range}_range_km, d.car_id, d.outside_temp_avg from drives d\r\n \r\n union all\r\n \r\n select 'Charging Process' as activity, cp.start_date, cp.end_date, cp.position_id as start_position_id, cp.position_id as end_position_id, cp.address_id as end_address_id, cp.geofence_id as end_geofence_id, cp.start_${preferred_range}_range_km, cp.end_${preferred_range}_range_km, cp.car_id, cp.outside_temp_avg from charging_processes cp\r\n\r\n)\r\n\r\nSELECT\r\n start_date AS \"Start\",\r\n end_date AS \"End\",\r\n ROUND(EXTRACT(EPOCH FROM start_date))*1000 AS start_date_ts,\r\n ROUND(EXTRACT(EPOCH FROM end_date))*1000 AS end_date_ts,\r\n '🚗 Driving' AS \"Action\",\r\n drives.duration_min AS \"Duration\",\r\n CASE WHEN start_geofence_id IS NULL THEN CONCAT('new?lat=', TP1.latitude, '&lng=', TP1.longitude)\r\n WHEN start_geofence_id IS NOT NULL THEN CONCAT(start_geofence_id, '/edit')\r\n END AS start_path,\r\n CASE WHEN end_geofence_id IS NULL THEN CONCAT('new?lat=', TP2.latitude, '&lng=', TP2.longitude)\r\n WHEN start_geofence_id IS NOT NULL THEN CONCAT(end_geofence_id, '/edit')\r\n END AS end_path,\r\n COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS \"Start Address\",\r\n COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS \"End Address\",\r\n convert_km(end_km::NUMERIC, '$length_unit') AS odometer_$length_unit,\r\n convert_km(distance::NUMERIC, '$length_unit') AS distance_$length_unit,\r\n convert_km(end_${preferred_range}_range_km::NUMERIC, '$length_unit') AS end_range_$length_unit,\r\n (end_${preferred_range}_range_km - start_${preferred_range}_range_km) * car.efficiency AS \"kWh\",\r\n convert_km((end_${preferred_range}_range_km - start_${preferred_range}_range_km)::NUMERIC, '$length_unit') AS range_diff_$length_unit,\r\n TP2.battery_level AS \"SoC\",\r\n TP2.battery_level-TP1.battery_level AS \"SoC Diff\",\r\n convert_celsius(outside_temp_avg, '$temp_unit') AS outside_temp_avg_$temp_unit,\r\n CONCAT('d/zm7wN6Zgz/drive-details?from=', ROUND(EXTRACT(EPOCH FROM start_date))*1000, '&to=', ROUND(EXTRACT(EPOCH FROM end_date))*1000, '&var-car_id=', drives.car_id, '&var-drive_id=', drives.id) AS slotlink\r\nFROM drives\r\n INNER JOIN cars AS car ON drives.car_id = car.id\r\n INNER JOIN positions AS TP1 on drives.start_position_id = TP1.id\r\n INNER JOIN positions AS TP2 on drives.end_position_id = TP2.id\r\n INNER JOIN addresses start_address ON start_address_id = start_address.id\r\n INNER JOIN addresses end_address ON end_address_id = end_address.id\r\n LEFT JOIN geofences start_geofence ON start_geofence_id = start_geofence.id\r\n LEFT JOIN geofences end_geofence ON end_geofence_id = end_geofence.id\r\nWHERE \r\n $__timeFilter(drives.start_date)\r\n AND drives.car_id = $car_id\r\n AND '🚗 Driving' in ($action_filter)\r\n AND\r\n (COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city))::TEXT ILIKE'%$text_filter%' or\r\n COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city))::TEXT ILIKE'%$text_filter%')\r\n\r\nUNION\r\nSELECT\r\n start_date AS \"Start\",\r\n end_date AS \"End\",\r\n ROUND(EXTRACT(EPOCH FROM start_date))*1000 AS start_date_ts,\r\n ROUND(EXTRACT(EPOCH FROM end_date))*1000 AS end_date_ts,\r\n '🔋 Charging' AS \"Action\",\r\n charging_processes.duration_min AS \"Duration\",\r\n CASE WHEN geofence_id IS NULL THEN CONCAT('new?lat=', address.latitude, '&lng=', address.longitude)\r\n WHEN geofence_id IS NOT NULL THEN CONCAT(geofence_id, '/edit')\r\n END AS start_path,\r\n NULL AS end_path,\r\n COALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city)) AS \"Start Address\",\r\n '' AS \"End Address\",\r\n convert_km(position.odometer::NUMERIC, '$length_unit') AS odometer_$length_unit,\r\n NULL AS distance_$length_unit,\r\n convert_km(end_${preferred_range}_range_km::NUMERIC, '$length_unit') AS end_range_$length_unit,\r\n charging_processes.charge_energy_added AS \"kWh\",\r\n convert_km((end_${preferred_range}_range_km - start_${preferred_range}_range_km)::NUMERIC, '$length_unit') AS range_diff_$length_unit, \r\n end_battery_level AS \"SoC\",\r\n end_battery_level - start_battery_level AS \"SoC Diff\",\r\n convert_celsius(outside_temp_avg, '$temp_unit') AS outside_temp_avg_$temp_unit,\r\n CONCAT('d/BHhxFeZRz/charge-details?from=', ROUND(EXTRACT(EPOCH FROM start_date)-10)*1000, '&to=', ROUND(EXTRACT(EPOCH FROM end_date)+10)*1000, '&var-car_id=', charging_processes.car_id, '&var-charging_process_id=', charging_processes.id) AS slotlink\r\nFROM charging_processes\r\n INNER JOIN positions AS position ON position_id = position.id\r\n INNER JOIN addresses AS address ON address_id = address.id\r\n LEFT JOIN geofences AS geofence ON geofence_id = geofence.id\r\nWHERE\r\n $__timeFilter(charging_processes.start_date)\r\n AND charging_processes.charge_energy_added > 0\r\n AND charging_processes.car_id = $car_id\r\n AND '🔋 Charging' in ($action_filter)\r\n AND COALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city))::TEXT ILIKE'%$text_filter%'\r\nUNION\r\nSELECT\r\n d.end_date AS \"Start\",\r\n LEAD(d.start_date) over w AS \"End\",\r\n ROUND(EXTRACT(EPOCH FROM d.end_date)) * 1000 AS start_date_ts,\r\n ROUND(EXTRACT(EPOCH FROM LEAD(d.start_date) over w))*1000 AS end_date_ts,\r\n '🅿️ Parking' AS \"Action\",\r\n EXTRACT(EPOCH FROM LEAD(d.start_date) over w - d.end_date)/60 AS \"Duration\",\r\n CASE WHEN d.end_geofence_id IS NULL THEN CONCAT('new?lat=', end_position.latitude, '&lng=', end_position.longitude)\r\n WHEN d.end_geofence_id IS NOT NULL THEN CONCAT(d.end_geofence_id, '/edit')\r\n END AS start_path,\r\n NULL AS end_path,\r\n COALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city)) AS \"Start Address\",\r\n '' AS \"End Address\",\r\n convert_km(end_position.odometer::NUMERIC, '$length_unit') AS odometer_$length_unit,\r\n NULL AS distance_$length_unit,\r\n convert_km(LEAD(d.start_${preferred_range}_range_km) over w::NUMERIC, '$length_unit') AS end_range_$length_unit,\r\n ((LEAD(d.start_${preferred_range}_range_km) over w + (LEAD(start_position.odometer) over w - end_position.odometer)) - d.end_${preferred_range}_range_km) * car.efficiency AS \"kWh\",\r\n convert_km(((LEAD(d.start_${preferred_range}_range_km) over w + (LEAD(start_position.odometer) over w - end_position.odometer)) - d.end_${preferred_range}_range_km)::NUMERIC, '$length_unit') AS range_diff_$length_unit,\r\n LEAD(start_position.battery_level) over w AS \"SoC\",\r\n LEAD(start_position.battery_level) over w - end_position.battery_level AS \"SoC Diff\",\r\n convert_celsius(outside_temp_avg, '$temp_unit') AS outside_temp_avg_$temp_unit,\r\n CONCAT('d/FkUpJpQZk/trip?from=', ROUND(EXTRACT(EPOCH FROM d.end_date))*1000, '&to=', ROUND(EXTRACT(EPOCH FROM LEAD(d.start_date) over w))*1000, '&var-car_id=', d.car_id) AS slotlink\r\nFROM drives_and_charging_processes AS d\r\n INNER JOIN cars AS car ON d.car_id = car.id\r\n INNER JOIN positions AS start_position on d.start_position_id = start_position.id\r\n INNER JOIN positions AS end_position on d.end_position_id = end_position.id\r\n INNER JOIN addresses AS address ON d.end_address_id = address.id\r\n LEFT JOIN geofences AS geofence ON d.end_geofence_id = geofence.id\r\nWHERE\r\n $__timeFilter(d.end_date)\r\n AND d.car_id=$car_id\r\n AND '🅿️ Parking' in ($action_filter)\r\n AND COALESCE(geofence.name, CONCAT_WS(', ', COALESCE(address.name, nullif(CONCAT_WS(' ', address.road, address.house_number), '')), address.city))::TEXT ILIKE'%$text_filter%'\r\nWINDOW w as (ORDER BY d.start_date ASC)\r\n\r\nUNION\r\nSELECT\r\n\tT1.end_date +(1 * interval '1 second') AS \"Start\", -- added 1 sec to get it after the corresponding Parking row\r\n\tT2.start_date AS \"End\",\r\n\tROUND(EXTRACT(EPOCH FROM T1.end_date)) * 1000 - 1 AS start_date_ts,\r\n\tROUND(EXTRACT(EPOCH FROM T2.start_date)) * 1000 - 1 AS end_date_ts,\r\n\t'❓ Missing' AS \"Action\",\r\n\t-- EXTRACT(EPOCH FROM T2.start_date - T1.end_date)/60 AS \"Duration\",\r\n\tNULL AS \"Duration\",\r\n\tCASE WHEN T1.end_geofence_id IS NULL THEN CONCAT('new?lat=', TP1.latitude, '&lng=', TP1.longitude)\r\n\t\tWHEN T1.end_geofence_id IS NOT NULL THEN CONCAT(T1.end_geofence_id, '/edit')\r\n\tEND AS start_path,\r\n\tCASE WHEN T2.start_geofence_id IS NULL THEN CONCAT('new?lat=', TP2.latitude, '&lng=', TP2.longitude)\r\n\t\tWHEN T2.start_geofence_id IS NOT NULL THEN CONCAT(T2.start_geofence_id, '/edit')\r\n\tEND AS end_path,\r\n\tCOALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS \"Start Address\",\r\n\tCOALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS \"End Address\",\r\n\tconvert_km(TP2.odometer::NUMERIC, '$length_unit') AS odometer_$length_unit,\r\n\tconvert_km((TP2.odometer - TP1.odometer)::NUMERIC, '$length_unit') AS distance_$length_unit,\r\n convert_km(T2.end_${preferred_range}_range_km::NUMERIC, '$length_unit') AS end_range_$length_unit,\r\n\t((TP2.${preferred_range}_battery_range_km + (TP2.odometer - TP1.odometer)) - TP1.${preferred_range}_battery_range_km) * car.efficiency AS \"kWh\",\r\n\tconvert_km(((TP2.${preferred_range}_battery_range_km + (TP2.odometer - TP1.odometer)) - TP1.${preferred_range}_battery_range_km)::NUMERIC, '$length_unit') AS range_diff_$length_unit,\r\n\tNULL AS \"SoC\",\r\n\tNULL AS \"SoC Diff\",\r\n\tNULL AS outside_temp_avg_$temp_unit,\r\n\tNULL AS slotlink\r\n\t-- TP2.battery_level AS \"SoC\",\r\n\t-- TP2.battery_level-TP1.battery_level AS \"SoC Diff\",\r\n\t-- (T1.outside_temp_avg+T2.outside_temp_avg)/2 AS outside_temp_avg_$temp_unit\r\nFROM drives AS T1\r\n INNER JOIN cars AS car ON T1.car_id = car.id\r\n\tINNER JOIN (SELECT d.*, LAG(id) OVER (ORDER BY id ASC) AS previous_id FROM drives d WHERE d.car_id = $car_id) AS T2 ON T1.id = T2.previous_id\r\n\tINNER JOIN positions AS TP1 ON T1.end_position_id = TP1.id\r\n\tINNER JOIN positions AS TP2 ON T2.start_position_id = TP2.id\r\n\tINNER JOIN addresses AS start_address ON T1.end_address_id = start_address.id\r\n\tINNER JOIN addresses AS end_address ON T2.start_address_id = end_address.id\r\n\tLEFT JOIN geofences AS start_geofence ON T1.end_geofence_id = start_geofence.id\r\n\tLEFT JOIN geofences AS end_geofence ON T2.start_geofence_id = end_geofence.id\r\nWHERE\r\n\t$__timeFilter(T1.end_date)\r\n\tAND TP2.odometer - TP1.odometer > 0.5\r\n AND T1.end_address_id <> T2.start_address_id AND ((COALESCE(T1.end_geofence_id, 0) <> COALESCE(T2.start_geofence_id, 0)) OR (T1.end_geofence_id IS NULL AND T2.start_geofence_id IS NULL))\r\n AND '❓ Missing' in ($action_filter)\r\n\tAND (\r\n\t (COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city))::TEXT ILIKE'%$text_filter%') or\r\n\t (COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)))::TEXT ILIKE'%$text_filter%')\r\nUNION\r\nSELECT\r\n start_date AS \"Start\",\r\n end_date AS \"End\",\r\n ROUND(EXTRACT(EPOCH FROM start_date))*1000 AS start_date_ts, \r\n ROUND(EXTRACT(EPOCH FROM end_date))*1000 AS end_date_ts, \r\n '💾 Updating' AS \"Action\",\r\n\tEXTRACT(EPOCH FROM end_date - start_date)/60 AS \"Duration\",\r\n NULL AS start_path,\r\n NULL AS end_path,\r\n version AS \"Start Address\",\r\n '' AS \"End Address\",\r\n NULL AS odometer_$length_unit,\r\n NULL AS distance_$length_unit,\r\n NULL AS end_range_$length_unit,\r\n NULL AS \"kWh\",\r\n NULL AS range_diff_$length_unit,\r\n NULL AS \"SoC\",\r\n NULL AS \"SoC Diff\",\r\n NULL AS outside_temp_avg_$temp_unit,\r\n CONCAT('https://www.notateslaapp.com/software-updates/version/', split_part(version, ' ', 1), '/release-notes') AS slotlink\r\nFROM updates\r\nWHERE \r\n $__timeFilter(start_date)\r\n AND car_id = $car_id \r\n AND '💾 Updating' in ($action_filter)\r\n AND version::TEXT ILIKE'%$text_filter%'\r\n\r\nORDER BY \"Start\" DESC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Timeline", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "End": true, - "start_date_ts": false - }, - "indexByName": { - "Action": 2, - "Duration": 7, - "End": 1, - "End Address": 4, - "SoC": 15, - "SoC Diff": 16, - "Start": 0, - "Start Address": 3, - "distance_km": 8, - "distance_mi": 9, - "end_date_ts": 22, - "end_path": 20, - "end_range_km": 10, - "end_range_mi": 11, - "kWh": 13, - "odometer_km": 5, - "odometer_mi": 6, - "outside_temp_avg_c": 17, - "outside_temp_avg_f": 18, - "range_diff_km": 12, - "range_diff_mi": 13, - "start_date_ts": 21, - "start_path": 19 - }, - "renameByName": { - "action": "", - "end_address": "End", - "km_diff": "Km", - "kwh": "", - "minutediff": "Time", - "odometer": "", - "outside_temp_avg": "Temperature", - "rangediff": "Range Difference", - "soc": "", - "soc_diff": "SoC Difference", - "start_address": "Start", - "start_date": "Date", - "start_date_ts": "" - } - } - } - ], - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "includeAll": true, - "label": "Action", - "multi": true, - "name": "action_filter", - "options": [ - { - "selected": false, - "text": "🚗 Driving", - "value": "🚗 Driving" - }, - { - "selected": false, - "text": "🔋 Charging", - "value": "🔋 Charging" - }, - { - "selected": false, - "text": "🅿️ Parking", - "value": "🅿️ Parking" - }, - { - "selected": false, - "text": "❓ Missing", - "value": "❓ Missing" - }, - { - "selected": false, - "text": "💾 Updating", - "value": "💾 Updating" - } - ], - "query": "🚗 Driving,🔋 Charging,🅿️ Parking,❓ Missing,💾 Updating", - "type": "custom" - }, - { - "current": { - "text": "", - "value": "" - }, - "label": "Address Filter", - "name": "text_filter", - "options": [ - { - "selected": true, - "text": "", - "value": "" - } - ], - "query": "", - "type": "textbox" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "length unit", - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "temperature unit", - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-7d", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Timeline", - "uid": "SUBgwtigz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-trip.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-trip.yaml deleted file mode 100644 index 771ac97..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-trip.yaml +++ /dev/null @@ -1,2819 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-trip - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-trip.json: | - { - "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": [ - { - "icon": "doc", - "tags": [], - "targetBlank": true, - "title": "Select last three drives", - "type": "link", - "url": "/d/FkUpJpQZk/trip?from=$from" - }, - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 15, - "w": 13, - "x": 0, - "y": 1 - }, - "id": 6, - "maxDataPoints": 500, - "options": { - "basemap": { - "config": {}, - "name": "Layer 0", - "type": "osm-standard" - }, - "controls": { - "mouseWheelZoom": true, - "showAttribution": true, - "showDebug": false, - "showMeasure": false, - "showScale": false, - "showZoom": true - }, - "layers": [ - { - "config": { - "arrow": 0, - "style": { - "color": { - "fixed": "dark-blue" - }, - "lineWidth": 2, - "opacity": 1, - "rotation": { - "fixed": 0, - "max": 360, - "min": -360, - "mode": "mod" - }, - "size": { - "fixed": 3, - "max": 15, - "min": 2 - }, - "symbol": { - "fixed": "img/icons/marker/circle.svg", - "mode": "fixed" - }, - "symbolAlign": { - "horizontal": "center", - "vertical": "center" - }, - "textConfig": { - "fontSize": 12, - "offsetX": 0, - "offsetY": 0, - "textAlign": "center", - "textBaseline": "middle" - } - } - }, - "name": "Layer 1", - "tooltip": true, - "type": "route" - } - ], - "tooltip": { - "mode": "details" - }, - "view": { - "allLayers": true, - "id": "fit", - "lat": 0, - "lon": 0, - "zoom": 15 - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "with unioned_positions as (\n\n -- fetch all positions based on start_date of drives so the map aligns with data shown in other panels\n select p.*\n from positions p\n inner join drives d on p.drive_id = d.id\n where p.car_id = $car_id and $__timeFilter(d.start_date)\n\n union all\n\n -- get all positions logged while not driving\n select *\n from positions p\n where p.car_id = $car_id and drive_id is null and $__timeFilter(date))\n\nSELECT $__timeGroup(date, '5s') AS time,\n avg(latitude) AS latitude,\n avg(longitude) AS longitude\nfrom unioned_positions\nGROUP BY 1\nORDER BY 1 ASC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "transparent": true, - "type": "geomap" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "unit", - "value": "km" - }, - { - "id": "displayName", - "value": "Mileage" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "unit", - "value": "mi" - }, - { - "id": "displayName", - "value": "Mileage" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 13, - "y": 1 - }, - "id": 10, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT convert_km((max(odometer) - min(odometer))::numeric, '$length_unit') as \"distance_$length_unit\"\nFROM positions\nWHERE car_id = $car_id AND ideal_battery_range_km IS NOT NULL\nand (drive_id in (select id from drives where $__timeFilter(start_date)) or drive_id is null and $__timeFilter(date))\nORDER BY 1", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "decimals": 1, - "mappings": [], - "unit": "dtdurations" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "charging (AC)" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#73BF69", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charging (DC)" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#FADE2A", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "driving" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "#5794F2", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 10, - "w": 5, - "x": 19, - "y": 1 - }, - "id": 38, - "maxDataPoints": 3, - "options": { - "displayLabels": [ - "name", - "percent" - ], - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true, - "values": [ - "value" - ] - }, - "pieType": "pie", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": true - }, - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\tnow() AS time,\n\tsum(extract(epoch FROM end_position.date - start_position.date)) as duration_sec,\n\t'driving' as metric\nFROM\n\tdrives\n\tJOIN positions start_position ON start_position_id = start_position.id\n\tJOIN positions end_position ON end_position_id = end_position.id\nWHERE\n\tdrives.car_id = $car_id\n\tAND $__timeFilter(start_date)\n\tAND end_date IS NOT NULL;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH charges_current AS (\n SELECT\n\t\tcp.id,\n \textract(epoch FROM LEAST(end_date, $__timeTo()) - GREATEST(start_date, $__timeFrom())) as duration_sec,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'charging (DC)'\n\t\t\t\t ELSE 'charging (AC)'\n\t\tEND AS current\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n\t AND cp.charge_energy_added > 0\n \tAND ($__timeFilter(start_date) OR $__timeFilter(end_date))\n GROUP BY 1,2\n),\n\ncharges_total AS (\n SELECT\n \tsum(duration_sec) AS duration_sec,\n \tcurrent AS metric\n FROM charges_current\n GROUP BY 2\n ORDER BY metric\n)\n\nSELECT\n\tnow() AS time,\n\tcoalesce(duration_sec, 0) as duration_sec,\n metric\nFROM\n\tcharges_total;", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Time spent", - "type": "piechart" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "speed_km" - }, - "properties": [ - { - "id": "unit", - "value": "velocitykmh" - }, - { - "id": "displayName", - "value": "Ø Speed excl. breaks" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_mi" - }, - "properties": [ - { - "id": "unit", - "value": "velocitymph" - }, - { - "id": "displayName", - "value": "Ø Speed excl. breaks" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 13, - "y": 3 - }, - "id": 26, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n convert_km(sum(end_position.odometer - start_position.odometer)::numeric, '$length_unit') / (sum(extract(epoch FROM end_position.date - start_position.date)) / 3600) as \"speed_$length_unit\"\nFROM\n\tdrives\n\tJOIN positions start_position ON start_position_id = start_position.id\n\tJOIN positions end_position ON end_position_id = end_position.id\nWHERE\n\tdrives.car_id = $car_id\n\tAND $__timeFilter(start_date)\n\tAND end_date IS NOT NULL;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "speed_km" - }, - "properties": [ - { - "id": "unit", - "value": "velocitykmh" - }, - { - "id": "displayName", - "value": "Ø Speed incl. DC charging" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "speed_mi" - }, - "properties": [ - { - "id": "unit", - "value": "velocitymph" - }, - { - "id": "displayName", - "value": "Ø Speed incl. DC charging" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 13, - "y": 5 - }, - "id": 28, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH dc_charges AS (\n SELECT\n\t\tcp.id,\n extract(epoch FROM cp.end_date - cp.start_date) as duration_sec,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'DC'\n\t\t\t\t ELSE 'AC'\n\t\tEND AS current\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n\t AND cp.charge_energy_added > 0\n AND ($__timeFilter(start_date) OR $__timeFilter(end_date))\n GROUP BY 1,2\n),\n\ndata AS (\n (\n SELECT\n sum(end_position.odometer - start_position.odometer) as distance, \n sum(extract(epoch FROM end_position.date - start_position.date)) as duration_sec\n FROM\n drives\n JOIN positions start_position ON start_position_id = start_position.id\n JOIN positions end_position ON end_position_id = end_position.id\n WHERE\n drives.car_id = $car_id\n AND $__timeFilter(start_date)\n ) UNION ALL (\n SELECT\n NULL as distance,\n sum(duration_sec)\n FROM\n dc_charges\n WHERE\n current = 'DC'\n )\n)\n\nSELECT convert_km(sum(distance)::numeric, '$length_unit') / (sum(duration_sec) / 3600) as \"speed_$length_unit\"\nfrom data", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "consumption_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "displayName", - "value": "Ø Consumption (net)" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "displayName", - "value": "Ø Consumption (net)" - } - ] - } - ] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 13, - "y": 7 - }, - "id": 30, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "text": {}, - "textMode": "auto", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n sum((start_${preferred_range}_range_km - end_${preferred_range}_range_km) * car.efficiency * 1000) / \n convert_km(sum(distance)::numeric, '$length_unit') as \"consumption_$length_unit\"\nFROM drives\nJOIN cars car ON car.id = car_id\nWHERE $__timeFilter(start_date) AND car_id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "consumption_km" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "displayName", - "value": "Ø Consumption (gross)" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_mi" - }, - "properties": [ - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "displayName", - "value": "Ø Consumption (gross)" - } - ] - } - ] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 16, - "y": 7 - }, - "id": 32, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "-- Query shared between Charging Stats, Statistics & Trip Dashboards (with minor changes) - ensure to modify in all places when necessary\n\nwith drives_start_event as (\n\n select\n 'drive_start' as event, start_date as date, start_${preferred_range}_range_km as range, start_km as odometer, car_id\n from drives\n where car_id = $car_id and $__timeFilter(start_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\ndrives_end_event as (\n\n select\n 'drive_end' as event, end_date as date, end_${preferred_range}_range_km as range, end_km as odometer, car_id\n from drives\n where car_id = $car_id and $__timeFilter(start_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\ncharging_processes_start_event as (\n\n select\n 'charging_process_start' as event, start_date as date, start_${preferred_range}_range_km as range, p.odometer, cp.car_id\n from charging_processes cp\n inner join positions p on cp.position_id = p.id\n where cp.car_id = $car_id and $__timeFilter(start_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\ncharging_processes_end_event as (\n\n select\n 'charging_process_end' as event, end_date as date, end_${preferred_range}_range_km as range, p.odometer, cp.car_id\n from charging_processes cp\n inner join positions p on cp.position_id = p.id\n where cp.car_id = $car_id and $__timeFilter(start_date) and 48 <= extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n\n),\n\npositions as (\n\n select\n case\n when drive_id is not null and lead(drive_id) over w is not null then 'drive_start'\n else 'something'\n end as event,\n date, ${preferred_range}_battery_range_km as range, p.odometer, p.car_id\n from positions p\n where ideal_battery_range_km is not null and car_id = $car_id and 48 > extract(hour FROM to_timestamp(${__to:date:seconds}) - to_timestamp(${__from:date:seconds}))\n and (drive_id in (select id from drives where $__timeFilter(start_date)) or drive_id is null and $__timeFilter(date))\n window w as (order by date)\n\n),\n\ncombined as (\n\n select * from drives_start_event\n union all\n select * from drives_end_event\n union all\n select * from charging_processes_start_event\n union all\n select * from charging_processes_end_event\n union all\n select * from positions\n\n),\n\nfinal as (\n\n select\n car_id,\n lead(odometer) over w - odometer as distance,\n case when event != 'drive_start' then greatest(range - lead(range) over w, 0) else range - lead(range) over w end as range_loss\n from combined\n window w as (order by date asc)\n\n)\n\nselect\n 'Total Energy consumed (gross)' as metric,\n sum(range_loss) * c.efficiency as value,\n (sum(range_loss) * c.efficiency * 1000) / nullif(convert_km(sum(distance)::numeric, '$length_unit'), 0) as consumption_$length_unit\nfrom final\n inner join cars c on car_id = c.id\ngroup by c.efficiency", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "metric": true, - "value": true - }, - "includeByName": {}, - "indexByName": {}, - "renameByName": {} - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "decimals": 2, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 6, - "x": 13, - "y": 11 - }, - "id": 22, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select sum(cost) as \"Total Charging Cost\" from charging_processes where $__timeFilter(end_date) AND car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "description": "", - "fieldConfig": { - "defaults": { - "decimals": 2, - "mappings": [ - { - "options": { - "match": "null", - "result": { - "text": "N/A" - } - }, - "type": "special" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 5, - "x": 19, - "y": 11 - }, - "id": 43, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "fieldOptions": { - "calcs": [ - "lastNotNull" - ] - }, - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH charges as (\r\n SELECT\r\n sum(cost) / sum(charge_energy_added) as cost_per_kwh\r\n FROM charging_processes\r\n where car_id = $car_id and $__timeFilter(start_date)\r\n),\r\n\r\nmileage as (\r\n SELECT convert_km((max(odometer) - min(odometer))::numeric, '$length_unit') as distance\r\n FROM positions\r\n WHERE car_id = $car_id and ideal_battery_range_km IS NOT NULL\r\n and (drive_id in (select id from drives where $__timeFilter(start_date)) or drive_id is null and $__timeFilter(date))\r\n)\r\n\r\nselect\r\n 'Total Energy consumed (gross)' as metric, -- Hack required for Join Transformation\r\n cost_per_kwh / distance * 100 as cost_mileage\r\nfrom mileage cross join charges", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "hide": false, - "panelId": 32, - "refId": "B" - } - ], - "title": "", - "transformations": [ - { - "id": "joinByField", - "options": { - "byField": "metric", - "mode": "inner" - } - }, - { - "id": "calculateField", - "options": { - "alias": "Ø Cost per 100 $length_unit", - "binary": { - "left": { - "matcher": { - "id": "byName", - "options": "cost_mileage" - } - }, - "operator": "*", - "right": { - "matcher": { - "id": "byName", - "options": "value" - } - } - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": true, - "window": { - "reducer": "mean", - "windowAlignment": "trailing", - "windowSize": 0.1, - "windowSizeMode": "percentage" - } - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "datasource", - "uid": "-- Mixed --" - }, - "fieldConfig": { - "defaults": { - "decimals": 2, - "displayName": "${__cell_0}", - "links": [], - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "light-yellow", - "value": 0 - }, - { - "color": "semi-dark-yellow", - "value": 10 - }, - { - "color": "semi-dark-orange", - "value": 100 - } - ] - }, - "unit": "kwatth" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 11, - "x": 13, - "y": 13 - }, - "id": 40, - "options": { - "displayMode": "gradient", - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": false - }, - "maxVizHeight": 300, - "minVizHeight": 10, - "minVizWidth": 0, - "namePlacement": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showUnfilled": false, - "sizing": "auto", - "valueMode": "color" - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "-- Dashboard --" - }, - "panelId": 32, - "refId": "A" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH charges_current AS (\n SELECT\n\t\tcp.id,\n\t\tcp.charge_energy_added as energy_added,\n\t\tCASE WHEN NULLIF(mode() within group (order by charger_phases),0) is null THEN 'Total Energy added (DC)'\n\t\t\t\t ELSE 'Total Energy added (AC)'\n\t\tEND AS metric\n\tFROM charging_processes cp\n RIGHT JOIN charges ON cp.id = charges.charging_process_id\n WHERE\n\t cp.car_id = $car_id\n\t AND cp.charge_energy_added > 0\n \tAND ($__timeFilter(start_date) OR $__timeFilter(end_date))\n GROUP BY 1,2\n)\n\nSELECT metric, sum(energy_added) AS energy_added\nFROM charges_current\nGROUP BY 1\nORDER BY 1 DESC;", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "transformations": [ - { - "id": "filterFieldsByName", - "options": { - "include": { - "pattern": "^(?:(?!consumption).)*$" - } - } - } - ], - "type": "bargauge" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisPlacement": "auto", - "fillOpacity": 100, - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineWidth": 0, - "spanNulls": false - }, - "mappings": [ - { - "options": { - "0": { - "color": "#6ED0E0", - "index": 0, - "text": "online" - }, - "1": { - "color": "#8F3BB8", - "index": 1, - "text": "driving" - }, - "2": { - "color": "#F2CC0C", - "index": 2, - "text": "charging" - }, - "3": { - "color": "#FFB357", - "index": 3, - "text": "offline" - }, - "4": { - "color": "#56A64B", - "index": 4, - "text": "asleep" - }, - "5": { - "color": "#6ED0E0", - "index": 5, - "text": "online" - }, - "6": { - "color": "#E02F44", - "index": 6, - "text": "updating" - }, - "null": { - "index": 7, - "text": "N/A" - } - }, - "type": "value" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 24, - "x": 0, - "y": 16 - }, - "id": 20, - "options": { - "alignValue": "center", - "legend": { - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "mergeValues": true, - "rowHeight": 1, - "showValue": "never", - "tooltip": { - "hideZeros": false, - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "WITH states AS (\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [2, 0]) AS state\n FROM charging_processes\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [1, 0]) AS state\n FROM drives\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n start_date AS date,\n CASE\n WHEN state = 'offline' THEN 3\n WHEN state = 'asleep' THEN 4\n WHEN state = 'online' THEN 5\n END AS state\n FROM states\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n UNION\n SELECT\n unnest(ARRAY [start_date + interval '1 second', end_date]) AS date,\n unnest(ARRAY [6, 0]) AS state\n FROM updates\n WHERE\n car_id = $car_id AND \n ($__timeFrom() :: timestamp - interval '30 day') < start_date AND \n (end_date < ($__timeTo() :: timestamp + interval '30 day') OR end_date IS NULL)\n)\nSELECT date AS \"time\", state\nFROM states\nWHERE \n date IS NOT NULL AND\n ($__timeFrom() :: timestamp - interval '30 day') < date AND \n date < ($__timeTo() :: timestamp + interval '30 day') \nORDER BY date ASC, state ASC;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "transparent": true, - "type": "state-timeline" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "decimals": 2, - "displayName": "", - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "start_date" - }, - "properties": [ - { - "id": "displayName", - "value": "Date" - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "View drive details", - "url": "/d/zm7wN6Zgz/drive-details?from=${__data.fields.start_date_ts.numeric}&to=${__data.fields.end_date_ts.numeric}&var-car_id=${__data.fields.car_id.numeric}&var-drive_id=${__data.fields.drive_id.numeric}" - } - ] - }, - { - "id": "custom.width", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_kwh_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/km" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 165 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption_kwh_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Consumption (net)" - }, - { - "id": "unit", - "value": "Wh/mi" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 165 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "start_address" - }, - "properties": [ - { - "id": "displayName", - "value": "Start" - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.start_path}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_address" - }, - "properties": [ - { - "id": "displayName", - "value": "Destination" - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.end_path}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration_min" - }, - "properties": [ - { - "id": "displayName", - "value": "Duration" - }, - { - "id": "unit", - "value": "m" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "links", - "value": [ - { - "title": "${__data.fields.duration_str}", - "url": "" - } - ] - }, - { - "id": "custom.width", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_ts/" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "distance_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Distance" - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "% Start" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - }, - { - "id": "custom.align", - "value": "auto" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "% End" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - }, - { - "id": "custom.align", - "value": "auto" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 65 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "(start_path|end_path|duration_str|car_id|drive_id)" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - } - ] - }, - "gridPos": { - "h": 11, - "w": 24, - "x": 0, - "y": 18 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Date" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n round(extract(epoch FROM start_date)) * 1000 AS start_date_ts,\n round(extract(epoch FROM end_date)) * 1000 AS end_date_ts,\n car.id as car_id,\n CASE WHEN start_geofence.id IS NULL THEN CONCAT('new?lat=', start_position.latitude, '&lng=', start_position.longitude)\n WHEN start_geofence.id IS NOT NULL THEN CONCAT(start_geofence.id, '/edit')\n END as start_path,\n CASE WHEN end_geofence.id IS NULL THEN CONCAT('new?lat=', end_position.latitude, '&lng=', end_position.longitude)\n WHEN end_geofence.id IS NOT NULL THEN CONCAT(end_geofence.id, '/edit')\n END as end_path,\n TO_CHAR((duration_min * INTERVAL '1 minute'), 'HH24:MI') as duration_str,\n drives.id as drive_id,\n -- Columns\n start_date,\n COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS start_address,\n COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS end_address,\n duration_min,\n distance,\n start_position.usable_battery_level as start_usable_battery_level,\n start_position.battery_level as start_battery_level,\n end_position.usable_battery_level as end_usable_battery_level,\n end_position.battery_level as end_battery_level,\n start_position.battery_level != start_position.usable_battery_level OR end_position.battery_level != end_position.usable_battery_level as reduced_range,\n duration_min > 1 AND distance > 1 AND ( \n start_position.usable_battery_level IS NULL OR end_position.usable_battery_level IS NULL\tOR\n (end_position.battery_level - end_position.usable_battery_level) = 0 \n ) as is_sufficiently_precise,\n start_${preferred_range}_range_km - end_${preferred_range}_range_km as range_diff,\n car.efficiency as car_efficiency,\n outside_temp_avg,\n distance / NULLIF(duration_min, 0) * 60 AS avg_speed\n FROM drives\n LEFT JOIN addresses start_address ON start_address_id = start_address.id\n LEFT JOIN addresses end_address ON end_address_id = end_address.id\n LEFT JOIN positions start_position ON start_position_id = start_position.id\n LEFT JOIN positions end_position ON end_position_id = end_position.id\n LEFT JOIN geofences start_geofence ON start_geofence_id = start_geofence.id\n LEFT JOIN geofences end_geofence ON end_geofence_id = end_geofence.id\n LEFT JOIN cars car ON car.id = drives.car_id\n WHERE $__timeFilter(start_date) AND drives.car_id = $car_id\n ORDER BY start_date DESC\n)\nSELECT\n start_date_ts,\n end_date_ts,\n car_id,\n start_path,\n end_path,\n duration_str,\n drive_id,\n -- Columns\n start_date,\n start_address,\n end_address,\n duration_min,\n convert_km(distance::numeric, '$length_unit') AS distance_$length_unit,\n start_battery_level as \"% Start\",\n end_battery_level as \"% End\",\n CASE WHEN is_sufficiently_precise THEN range_diff * car_efficiency / convert_km(distance::numeric, '$length_unit') * 1000\n END AS consumption_kWh_$length_unit\nFROM data;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Drives", - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "decimals": 2, - "displayName": "", - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "start_date" - }, - "properties": [ - { - "id": "displayName", - "value": "Date" - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "View charge details", - "url": "/d/BHhxFeZRz/charge-details?from=${__data.fields.start_date_ts.numeric}&to=${__data.fields.end_date_ts.numeric}&var-car_id=${__data.fields.car_id.numeric}&var-charging_process_id=${__data.fields.id.numeric:raw}" - } - ] - }, - { - "id": "custom.width", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_added" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy added" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.width", - "value": 115 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "start_battery_level" - }, - "properties": [ - { - "id": "displayName", - "value": "% Start" - }, - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 72 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_battery_level" - }, - "properties": [ - { - "id": "displayName", - "value": "% End" - }, - { - "id": "unit", - "value": "percent" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 62 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration_min" - }, - "properties": [ - { - "id": "displayName", - "value": "Duration" - }, - { - "id": "unit", - "value": "m" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.width", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "cost" - }, - "properties": [ - { - "id": "displayName", - "value": "Cost" - }, - { - "id": "unit", - "value": "none" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "Set Cost", - "url": "${base_url:raw}/charge-cost/${__data.fields.id.numeric:raw}" - } - ] - }, - { - "id": "custom.width", - "value": 70 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_ts/" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "address" - }, - "properties": [ - { - "id": "displayName", - "value": "Location" - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "Create or edit geo-fence", - "url": "${base_url:raw}/geo-fences/${__data.fields.path}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 200 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_added_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Range gained" - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.width", - "value": 120 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_added_per_hour" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Power" - }, - { - "id": "unit", - "value": "kwatt" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "#96D98D", - "value": 0 - }, - { - "color": "#56A64B", - "value": 20 - }, - { - "color": "#37872D", - "value": 55 - } - ] - } - }, - { - "id": "custom.width", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_added_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Range gained" - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 120 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "path" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "charge_energy_used" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy used" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.width", - "value": 105 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "car_id" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 29 - }, - "id": 36, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Date" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "WITH data AS (\n SELECT\n (round(extract(epoch FROM start_date) - 10) * 1000) AS start_date_ts,\n (round(extract(epoch FROM end_date) + 10) * 1000) AS end_date_ts,\n start_date,\n end_date,\n CONCAT_WS(', ', COALESCE(addresses.name, CONCAT_WS(' ', addresses.road, addresses.house_number)), addresses.city) AS address,\n g.name as geofence_name,\n g.id as geofence_id,\n p.latitude,\n p.longitude,\n charge_energy_added,\n charge_energy_used,\n duration_min,\n start_battery_level,\n end_battery_level,\n end_${preferred_range}_range_km - start_${preferred_range}_range_km as range_added,\n outside_temp_avg,\n c.id,\n p.odometer - lag(p.odometer) OVER (ORDER BY start_date) AS distance,\n cars.efficiency,\n c.car_id,\n cost\n FROM\n charging_processes c\n LEFT JOIN positions p ON p.id = c.position_id\n LEFT JOIN cars ON cars.id = c.car_id\n LEFT JOIN addresses ON addresses.id = c.address_id\n LEFT JOIN geofences g ON g.id = geofence_id\nWHERE \n (charge_energy_added IS NULL OR charge_energy_added > 0) AND\n c.car_id = $car_id AND\n $__timeFilter(start_date)\nORDER BY\n start_date\n)\nSELECT\n start_date_ts,\n end_date_ts,\n CASE WHEN geofence_id IS NULL THEN CONCAT('new?lat=', latitude, '&lng=', longitude)\n WHEN geofence_id IS NOT NULL THEN CONCAT(geofence_id, '/edit')\n END as path,\n car_id,\n id,\n -- Columns\n start_date,\n COALESCE(geofence_name, address) as address, \n duration_min,\n cost,\n charge_energy_added,\n charge_energy_used,\n charge_energy_added * 60 / NULLIF (duration_min, 0) AS charge_energy_added_per_hour,\n convert_km(range_added, '$length_unit') AS range_added_$length_unit,\n start_battery_level,\n end_battery_level\nFROM\n data\nWHERE\n (distance >= 0 OR distance IS NULL)\nORDER BY\n start_date DESC;\n ", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Charges", - "transformations": [ - { - "id": "merge", - "options": { - "reducers": [] - } - } - ], - "type": "table" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "decimals": 0, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percent" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "battery_level" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - }, - { - "id": "displayName", - "value": "SOC" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*_km$" - }, - "properties": [ - { - "id": "unit", - "value": "lengthkm" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*_mi$" - }, - "properties": [ - { - "id": "unit", - "value": "lengthmi" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "range_ideal_.*" - }, - "properties": [ - { - "id": "displayName", - "value": "Range (ideal)" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "range_rated_.*" - }, - "properties": [ - { - "id": "displayName", - "value": "Range (rated)" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 37 - }, - "id": 42, - "options": { - "legend": { - "calcs": [ - "min", - "max", - "lastNotNull" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "(\n SELECT $__timeGroup(date, '5s'), avg(battery_level) as battery_level, convert_km(avg(${preferred_range}_battery_range_km), '$length_unit') as range_${preferred_range}_${length_unit}\n FROM positions\n WHERE date BETWEEN ($__timeFrom()::timestamp - interval '1 day') AND ($__timeTo()::timestamp + interval '1 day') AND car_id = $car_id\n GROUP BY 1\n) UNION ALL (\n SELECT $__timeGroup(date, '5s'), avg(battery_level) as battery_level, convert_km(avg(${preferred_range}_battery_range_km), '$length_unit') as range_${preferred_range}_${length_unit}\n FROM charges c\n LEFT JOIN charging_processes p ON c.charging_process_id = p.id\n WHERE date BETWEEN ($__timeFrom()::timestamp - interval '1 day') AND ($__timeTo()::timestamp + interval '1 day') AND p.car_id = $car_id\n GROUP BY 1\n)\nORDER BY 1", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Battery Level & Range", - "type": "timeseries" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": ".*_m$" - }, - "properties": [ - { - "id": "unit", - "value": "lengthm" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*_ft$" - }, - "properties": [ - { - "id": "unit", - "value": "lengthft" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "elevation_.*" - }, - "properties": [ - { - "id": "displayName", - "value": "Elevation" - }, - { - "id": "color", - "value": { - "fixedColor": "semi-dark-blue", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 37 - }, - "id": 8, - "options": { - "legend": { - "calcs": [ - "min", - "max", - "lastNotNull" - ], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "hideZeros": false, - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "time_series", - "rawQuery": true, - "rawSql": "SELECT\n\t$__timeGroup(date, '5s'),\n\tROUND(convert_m(avg(elevation), '$alternative_length_unit')) AS elevation_${alternative_length_unit}\nFROM\n\tpositions\nWHERE\n car_id = $car_id AND\n date BETWEEN ($__timeFrom()::timestamp - interval '1 day') AND ($__timeTo()::timestamp + interval '1 day')\nGROUP BY\n 1\nORDER BY\n 1 ASC", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Elevation", - "type": "timeseries" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_temperature from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "temperature unit", - "name": "temp_unit", - "options": [], - "query": "select unit_of_temperature from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "label": "length unit", - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select case when unit_of_length = 'km' then 'm' when unit_of_length = 'mi' then 'ft' end from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "alternative_length_unit", - "options": [], - "query": "select case when unit_of_length = 'km' then 'm' when unit_of_length = 'mi' then 'ft' end from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "with last_drives as (select start_date from drives order by start_date desc limit 3)\nselect extract(epoch from min(start_date)) * 1000 from last_drives;", - "hide": 2, - "includeAll": false, - "name": "from", - "options": [], - "query": "with last_drives as (select start_date from drives order by start_date desc limit 3)\nselect extract(epoch from min(start_date)) * 1000 from last_drives;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-24h", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Trip", - "uid": "FkUpJpQZk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-updates.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-updates.yaml deleted file mode 100644 index f1de925..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-updates.yaml +++ /dev/null @@ -1,619 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-updates - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-updates.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 0, - "y": 1 - }, - "id": 8, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "count" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT count(*)\nFROM updates\nWHERE $__timeFilter(start_date) AND car_id = $car_id", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Updates", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "decimals": 1, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "#c7d0d9", - "value": 0 - } - ] - }, - "unit": "dtdurations" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 16, - "x": 8, - "y": 1 - }, - "id": 6, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": true - }, - "showPercentChange": false, - "textMode": "value", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY since_last_update) FROM (\n\tSELECT extract(EPOCH FROM start_date - lag(start_date) OVER (ORDER BY start_date)) AS since_last_update\n\tFROM updates\n\tWHERE $__timeFilter(start_date) AND car_id = $car_id\n) d;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Median time between updates", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "filterable": false, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "time" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 210 - }, - { - "id": "displayName", - "value": "Date" - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "update_duration" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "displayName", - "value": "Duration" - }, - { - "id": "unit", - "value": "dtdurations" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "since_last_update" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 180 - }, - { - "id": "displayName", - "value": "Since Previous Update" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "version" - }, - "properties": [ - { - "id": "displayName", - "value": "Installed Version" - }, - { - "id": "custom.align", - "value": "right" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "links", - "value": [ - { - "targetBlank": true, - "title": "${__data.fields[version]} release notes", - "url": "https://www.notateslaapp.com/software-updates/version/${__data.fields[version]}/release-notes" - } - ] - }, - { - "id": "unit", - "value": "string" - }, - { - "id": "custom.minWidth", - "value": 150 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "chg_ct" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 120 - }, - { - "id": "displayName", - "value": "# of Charges" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_ideal_range_km" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 130 - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "displayName", - "value": "Ø Ideal range" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_rated_range_km" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 130 - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "displayName", - "value": "Ø Rated range" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_ideal_range_mi" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 130 - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "displayName", - "value": "Ø Ideal range" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_rated_range_mi" - }, - "properties": [ - { - "id": "custom.minWidth", - "value": 130 - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "displayName", - "value": "Ø Rated range" - } - ] - } - ] - }, - "gridPos": { - "h": 28, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "Date" - } - ] - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "with u as (\r\n select *, coalesce(lag(start_date) over(order by start_date desc), now()) as next_start_date \r\n from updates\r\n where car_id = $car_id and $__timeFilter(start_date)\r\n),\r\nrng as (\r\n SELECT\r\n\t date_trunc('hour', timezone('UTC', date), '$__timezone') AS date,\r\n\t (sum(${preferred_range}_battery_range_km)/ nullif(sum(usable_battery_level),0) * 100 ) AS \"battery_rng\",\r\n\t sum(case when action = 'Charge' then 1 else 0 end) as chg_ct\r\n FROM (\r\n select usable_battery_level, start_date as date, start_rated_range_km as rated_battery_range_km, start_ideal_range_km as ideal_battery_range_km, 'Drive' as action\r\n from drives d\r\n inner join positions p on d.start_position_id = p.id \r\n where d.car_id = $car_id and $__timeFilter(start_date) and usable_battery_level > 0\r\n union all\r\n select end_battery_level as usable_battery_level, end_date, end_rated_range_km as rated_battery_range_km, end_ideal_range_km as ideal_battery_range_km, 'Charge' as action\r\n from charging_processes p\r\n where $__timeFilter(end_date) and p.car_id = $car_id\r\n ) as data\r\n GROUP BY 1\r\n)\r\n\r\nselect\t\r\n u.start_date as time,\r\n\textract(EPOCH FROM u.end_date - u.start_date) AS update_duration,\r\n\tage(date(u.start_date), date(lag(u.start_date) OVER (ORDER BY u.start_date))) AS since_last_update,\r\n\tsplit_part(u.version, ' ', 1) as version,\r\n\tsum(r.chg_ct) as chg_ct,\r\n\tconvert_km(avg(r.battery_rng), '$length_unit')::numeric(6,2) AS avg_${preferred_range}_range_${length_unit}\r\nfrom u u\r\nleft join rng r\r\n\tON r.date between u.start_date and u.next_start_date\r\ngroup by u.car_id,\r\n\tu.start_date,\r\n\tu.end_date,\r\n\tnext_start_date,\r\n\tsplit_part(u.version, ' ', 1)", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Updates", - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-10y", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "", - "title": "Tesla Updates", - "uid": "IiC07mgWz", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-vampire-drain.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-vampire-drain.yaml deleted file mode 100644 index 9eed637..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-vampire-drain.yaml +++ /dev/null @@ -1,666 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-vampire-drain - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-vampire-drain.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "start_date" - }, - "properties": [ - { - "id": "displayName", - "value": "Start" - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "", - "url": "/d/zm7wN6Zgz/drive-details?from=${__data.fields.start_date_ts.numeric}&to=${__data.fields.end_date_ts.numeric}" - } - ] - }, - { - "id": "custom.minWidth", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "end_date" - }, - "properties": [ - { - "id": "displayName", - "value": "End" - }, - { - "id": "unit", - "value": "dateTimeAsLocal" - }, - { - "id": "custom.minWidth", - "value": 210 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_diff_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Range loss" - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 95 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "displayName", - "value": "Period" - }, - { - "id": "unit", - "value": "s" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "rgb(133, 142, 133)", - "value": 0 - }, - { - "color": "#56A64B", - "value": 43200 - } - ] - } - }, - { - "id": "custom.minWidth", - "value": 100 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_lost_per_hour_km" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Range loss / h" - }, - { - "id": "unit", - "value": "lengthkm" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 135 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*_ts/" - }, - "properties": [ - { - "id": "custom.hidden", - "value": true - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "standby" - }, - "properties": [ - { - "id": "displayName", - "value": "Standby" - }, - { - "id": "unit", - "value": "percentunit" - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "#FF7383", - "value": 0 - }, - { - "color": "#FFB357", - "value": 0.3 - }, - { - "color": "#56A64B", - "value": 0.85 - } - ] - } - }, - { - "id": "decimals", - "value": 0 - }, - { - "id": "custom.minWidth", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "consumption" - }, - "properties": [ - { - "id": "displayName", - "value": "Energy drained" - }, - { - "id": "unit", - "value": "kwatth" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 125 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "avg_power" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Power" - }, - { - "id": "unit", - "value": "watt" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.minWidth", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_lost_per_hour_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Ø Range loss / h" - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 135 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "range_diff_mi" - }, - "properties": [ - { - "id": "displayName", - "value": "Range loss" - }, - { - "id": "unit", - "value": "lengthmi" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.minWidth", - "value": 95 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "soc_diff" - }, - "properties": [ - { - "id": "displayName", - "value": "SoC Diff" - }, - { - "id": "unit", - "value": "percent" - }, - { - "id": "custom.minWidth", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "has_reduced_range" - }, - "properties": [ - { - "id": "displayName", - "value": " " - }, - { - "id": "custom.align", - "value": "center" - }, - { - "id": "mappings", - "value": [ - { - "options": { - "0": { - "color": "transparent", - "index": 1, - "text": " " - }, - "1": { - "color": "dark-blue", - "index": 0, - "text": "❄" - } - }, - "type": "value" - } - ] - }, - { - "id": "links", - "value": [ - { - "title": "In cold weather, the estimated range loss cannot be estimated correctly and is therefore hidden.", - "url": "" - } - ] - }, - { - "id": "custom.width", - "value": 50 - } - ] - } - ] - }, - "gridPos": { - "h": 23, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "with merge as (\n SELECT \n c.start_date AS start_date,\n c.end_date AS end_date,\n c.start_ideal_range_km AS start_ideal_range_km,\n c.end_ideal_range_km AS end_ideal_range_km,\n c.start_rated_range_km AS start_rated_range_km,\n c.end_rated_range_km AS end_rated_range_km,\n start_battery_level,\n end_battery_level,\n p.usable_battery_level AS start_usable_battery_level,\n NULL AS end_usable_battery_level,\n p.odometer AS start_km,\n p.odometer AS end_km\n FROM charging_processes c\n JOIN positions p ON c.position_id = p.id\n WHERE c.car_id = $car_id AND $__timeFilter(start_date)\n UNION\n SELECT \n d.start_date AS start_date,\n d.end_date AS end_date,\n d.start_ideal_range_km AS start_ideal_range_km,\n d.end_ideal_range_km AS end_ideal_range_km,\n d.start_rated_range_km AS start_rated_range_km,\n d.end_rated_range_km AS end_rated_range_km,\n start_position.battery_level AS start_battery_level,\n end_position.battery_level AS end_battery_level,\n start_position.usable_battery_level AS start_usable_battery_level,\n end_position.usable_battery_level AS end_usable_battery_level,\n d.start_km AS start_km,\n d.end_km AS end_km\n FROM drives d\n JOIN positions start_position ON d.start_position_id = start_position.id\n JOIN positions end_position ON d.end_position_id = end_position.id\n WHERE d.car_id = $car_id AND $__timeFilter(start_date)\n), \nv as (\n SELECT\n lag(t.end_date) OVER w AS start_date,\n t.start_date AS end_date,\n lag(t.end_${preferred_range}_range_km) OVER w AS start_range,\n t.start_${preferred_range}_range_km AS end_range,\n lag(t.end_km) OVER w AS start_km,\n t.start_km AS end_km,\n EXTRACT(EPOCH FROM age(t.start_date, lag(t.end_date) OVER w)) AS duration,\n lag(t.end_battery_level) OVER w AS start_battery_level,\n lag(t.end_usable_battery_level) OVER w AS start_usable_battery_level,\n\t\tstart_battery_level AS end_battery_level,\n\t\tstart_usable_battery_level AS end_usable_battery_level,\n\t\tstart_battery_level > COALESCE(start_usable_battery_level, start_battery_level) AS has_reduced_range\n FROM merge t\n WINDOW w AS (ORDER BY t.start_date ASC)\n ORDER BY start_date DESC\n)\n\nSELECT\n round(extract(epoch FROM v.start_date)) * 1000 AS start_date_ts,\n round(extract(epoch FROM v.end_date)) * 1000 AS end_date_ts,\n -- Columns\n v.start_date,\n v.end_date,\n v.duration,\n (coalesce(s_asleep.sleep, 0) + coalesce(s_offline.sleep, 0)) / v.duration as standby,\n\t-greatest(v.start_battery_level - v.end_battery_level, 0) as soc_diff,\n\tCASE WHEN has_reduced_range THEN 1 ELSE 0 END as has_reduced_range,\n\tconvert_km(CASE WHEN has_reduced_range THEN NULL ELSE (v.start_range - v.end_range)::numeric END, '$length_unit') AS range_diff_$length_unit,\n CASE WHEN has_reduced_range THEN NULL ELSE (v.start_range - v.end_range) * c.efficiency END AS consumption,\n CASE WHEN has_reduced_range THEN NULL ELSE ((v.start_range - v.end_range) * c.efficiency) / (v.duration / 3600) * 1000 END as avg_power,\n convert_km(CASE WHEN has_reduced_range THEN NULL ELSE ((v.start_range - v.end_range) / (v.duration / 3600))::numeric END, '$length_unit') AS range_lost_per_hour_${length_unit}\nFROM v,\n LATERAL (\n SELECT EXTRACT(EPOCH FROM sum(age(s.end_date, s.start_date))) as sleep\n FROM states s\n WHERE\n state = 'asleep' AND\n v.start_date <= s.start_date AND s.end_date <= v.end_date AND\n s.car_id = $car_id\n ) s_asleep,\n LATERAL (\n SELECT EXTRACT(EPOCH FROM sum(age(s.end_date, s.start_date))) as sleep\n FROM states s\n WHERE\n state = 'offline' AND\n v.start_date <= s.start_date AND s.end_date <= v.end_date AND\n s.car_id = $car_id\n ) s_offline\nJOIN cars c ON c.id = $car_id\nWHERE\n v.duration > ($duration * 60 * 60)\n AND v.start_range - v.end_range >= 0\n AND v.end_km - v.start_km < 1;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Vampire Drain", - "transformations": [ - { - "id": "merge", - "options": { - "reducers": [] - } - } - ], - "type": "table" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "6", - "value": "6" - }, - "includeAll": false, - "label": "min. Idle Time (h)", - "name": "duration", - "options": [ - { - "selected": false, - "text": "0", - "value": "0" - }, - { - "selected": false, - "text": "1", - "value": "1" - }, - { - "selected": false, - "text": "3", - "value": "3" - }, - { - "selected": true, - "text": "6", - "value": "6" - }, - { - "selected": false, - "text": "12", - "value": "12" - }, - { - "selected": false, - "text": "18", - "value": "18" - }, - { - "selected": false, - "text": "24", - "value": "24" - } - ], - "query": "0,1,3,6,12,18,24", - "type": "custom" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select unit_of_length from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "select unit_of_length from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select preferred_range from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "preferred_range", - "options": [], - "query": "select preferred_range from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-90d", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Vampire Drain", - "uid": "zhHx2Fggk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-visited.yaml b/argocd/manifests/grafana-config/dashboards/configmap-teslamate-visited.yaml deleted file mode 100644 index b78d5ac..0000000 --- a/argocd/manifests/grafana-config/dashboards/configmap-teslamate-visited.yaml +++ /dev/null @@ -1,571 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: grafana-dashboard-teslamate-visited - namespace: monitoring - labels: - grafana_dashboard: "1" - annotations: - grafana_folder: "TeslaMate" -data: - teslamate-visited.json: | - { - "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": 0, - "links": [ - { - "icon": "dashboard", - "tags": [], - "title": "TeslaMate", - "tooltip": "", - "type": "link", - "url": "${base_url:raw}" - }, - { - "asDropdown": true, - "icon": "external link", - "tags": [ - "tesla" - ], - "title": "Dashboards", - "type": "dashboards" - } - ], - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 4, - "panels": [], - "repeat": "car_id", - "title": "$car_id", - "type": "row" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-red", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 21, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 2, - "maxDataPoints": 10000000, - "options": { - "basemap": { - "config": {}, - "name": "Layer 0", - "type": "osm-standard" - }, - "controls": { - "mouseWheelZoom": true, - "showAttribution": true, - "showDebug": false, - "showMeasure": false, - "showScale": false, - "showZoom": true - }, - "layers": [ - { - "config": { - "arrow": 0, - "style": { - "color": { - "fixed": "dark-blue" - }, - "lineWidth": 2, - "opacity": 1, - "rotation": { - "fixed": 0, - "max": 360, - "min": -360, - "mode": "mod" - }, - "size": { - "fixed": 3, - "max": 15, - "min": 2 - }, - "symbol": { - "fixed": "img/icons/marker/circle.svg", - "mode": "fixed" - }, - "symbolAlign": { - "horizontal": "center", - "vertical": "center" - }, - "textConfig": { - "fontSize": 12, - "offsetX": 0, - "offsetY": 0, - "textAlign": "center", - "textBaseline": "middle" - } - } - }, - "location": { - "latitude": "lat", - "longitude": "long", - "mode": "auto" - }, - "name": "Layer 1", - "tooltip": true, - "type": "route" - } - ], - "tooltip": { - "mode": "none" - }, - "view": { - "allLayers": true, - "id": "fit", - "lat": 0, - "lon": 0, - "zoom": 15 - } - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n date_trunc('minute', timezone('UTC', date), '$__timezone') as time,\n avg(latitude) as latitude,\n avg(longitude) as longitude\nFROM\n positions\nWHERE\n car_id = $car_id AND $__timeFilter(date) and ideal_battery_range_km is not null\nGROUP BY 1\nORDER BY 1", - "refId": "Positions", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "geomap" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "super-light-blue", - "value": 0 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 5, - "x": 0, - "y": 22 - }, - "id": 5, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "/.*/", - "values": true - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT ROUND(convert_km((max(end_km) - min(start_km))::numeric, '$length_unit'),0)|| ' $length_unit' as \"Mileage\"\nFROM drives WHERE car_id = $car_id AND $__timeFilter(start_date)", - "refId": "distance traveled", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "Total Energy added" - }, - "properties": [ - { - "id": "unit", - "value": "kwatth" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Total Energy used" - }, - "properties": [ - { - "id": "unit", - "value": "kwatth" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Charging Efficiency" - }, - "properties": [ - { - "id": "unit", - "value": "percent" - } - ] - } - ] - }, - "gridPos": { - "h": 2, - "w": 14, - "x": 5, - "y": 22 - }, - "id": 6, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "center", - "orientation": "vertical", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "mean" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "SELECT\n\tsum(charge_energy_added) as \"Total Energy added\",\n\tSUM(greatest(charge_energy_added, charge_energy_used)) AS \"Total Energy used\",\n\tSUM(charge_energy_added) * 100 / SUM(greatest(charge_energy_added, charge_energy_used)) AS \"Charging Efficiency\"\nFROM\n\tcharging_processes\nWHERE\n\tcar_id = $car_id AND $__timeFilter(start_date) AND charge_energy_added > 0.01", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - }, - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "description": "", - "fieldConfig": { - "defaults": { - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 2, - "w": 5, - "x": 19, - "y": 22 - }, - "id": 7, - "maxDataPoints": 100, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showPercentChange": false, - "textMode": "value_and_name", - "wideLayout": true - }, - "pluginVersion": "12.1.1", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "editorMode": "code", - "format": "table", - "rawQuery": true, - "rawSql": "select sum(cost) as \"Total Charging Cost\" from charging_processes where $__timeFilter(start_date) AND car_id = $car_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "", - "type": "stat" - } - ], - "preload": false, - "refresh": "", - "schemaVersion": 41, - "tags": [ - "tesla" - ], - "templating": { - "list": [ - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "hide": 2, - "includeAll": true, - "label": "Car", - "name": "car_id", - "options": [], - "query": "SELECT\n id as __value,\n CASE WHEN COUNT(id) OVER (PARTITION BY name) > 1 AND name IS NOT NULL THEN CONCAT(name, ' - ', RIGHT(vin, 6)) ELSE COALESCE(name, CONCAT('VIN ', vin)) end as __text \nFROM cars\nORDER BY display_priority ASC, name ASC, vin ASC;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "select base_url from settings limit 1;", - "hide": 2, - "includeAll": false, - "name": "base_url", - "options": [], - "query": "select base_url from settings limit 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": {}, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "TeslaMate" - }, - "definition": "SELECT unit_of_length FROM settings LIMIT 1", - "hide": 2, - "includeAll": false, - "name": "length_unit", - "options": [], - "query": "SELECT unit_of_length FROM settings LIMIT 1", - "refresh": 1, - "regex": "", - "type": "query" - } - ] - }, - "time": { - "from": "now-90d", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Tesla Visited", - "uid": "RG_DxSmgk", - "version": 1 - } diff --git a/argocd/manifests/grafana-config/kustomization.yaml b/argocd/manifests/grafana-config/kustomization.yaml index 45a8380..bb7ef87 100644 --- a/argocd/manifests/grafana-config/kustomization.yaml +++ b/argocd/manifests/grafana-config/kustomization.yaml @@ -26,22 +26,6 @@ resources: - dashboards/configmap-sifaka-disks.yaml - dashboards/configmap-forgejo.yaml - dashboards/configmap-tempo.yaml - # TeslaMate dashboards - - dashboards/configmap-teslamate-overview.yaml - - dashboards/configmap-teslamate-charges.yaml - - dashboards/configmap-teslamate-drives.yaml - - dashboards/configmap-teslamate-efficiency.yaml - - dashboards/configmap-teslamate-states.yaml - - dashboards/configmap-teslamate-vampire-drain.yaml - - dashboards/configmap-teslamate-battery-health.yaml - - dashboards/configmap-teslamate-statistics.yaml - - dashboards/configmap-teslamate-charge-level.yaml - - dashboards/configmap-teslamate-updates.yaml - - dashboards/configmap-teslamate-trip.yaml - - dashboards/configmap-teslamate-locations.yaml - - dashboards/configmap-teslamate-mileage.yaml - - dashboards/configmap-teslamate-drive-stats.yaml - - dashboards/configmap-teslamate-charging-stats.yaml - - dashboards/configmap-teslamate-projected-range.yaml - - dashboards/configmap-teslamate-timeline.yaml - - dashboards/configmap-teslamate-visited.yaml + # TeslaMate dashboards are fetched by the init-teslamate-dashboards init + # container in the Grafana deployment, sourced from mirrors/teslamate on forge. + # See argocd/manifests/grafana/deployment.yaml for the version pin. diff --git a/argocd/manifests/grafana/deployment.yaml b/argocd/manifests/grafana/deployment.yaml index e352e92..bdf4a6f 100644 --- a/argocd/manifests/grafana/deployment.yaml +++ b/argocd/manifests/grafana/deployment.yaml @@ -45,6 +45,51 @@ spec: volumeMounts: - name: storage mountPath: /var/lib/grafana + # Fetch TeslaMate dashboards from forge mirror at a pinned tag. + # To upgrade: update TESLAMATE_VERSION below. + - name: init-teslamate-dashboards + image: docker.io/library/alpine:kustomized + imagePullPolicy: IfNotPresent + command: ["sh", "-c"] + args: + - | + set -e + TESLAMATE_VERSION="v3.0.0" + BASE_URL="https://forge.ops.eblu.me/mirrors/teslamate/raw/tag/${TESLAMATE_VERSION}/grafana/dashboards" + DEST="/tmp/dashboards/TeslaMate" + mkdir -p "$DEST" + for f in \ + battery-health.json \ + charge-level.json \ + charges.json \ + charging-stats.json \ + drive-stats.json \ + drives.json \ + efficiency.json \ + locations.json \ + mileage.json \ + overview.json \ + projected-range.json \ + states.json \ + statistics.json \ + timeline.json \ + trip.json \ + updates.json \ + vampire-drain.json \ + visited.json \ + ; do + wget -q -O "$DEST/$f" "$BASE_URL/$f" + done + echo "Fetched $(ls "$DEST" | wc -l) TeslaMate dashboards" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: RuntimeDefault + volumeMounts: + - name: sc-dashboard-volume + mountPath: /tmp/dashboards containers: # Dashboard sidecar - watches ConfigMaps with grafana_dashboard=1 - name: grafana-sc-dashboard diff --git a/argocd/manifests/grafana/kustomization.yaml b/argocd/manifests/grafana/kustomization.yaml index 38e1269..e307db1 100644 --- a/argocd/manifests/grafana/kustomization.yaml +++ b/argocd/manifests/grafana/kustomization.yaml @@ -11,6 +11,8 @@ resources: - rbac.yaml images: + - name: docker.io/library/alpine + newTag: "3.21" - name: docker.io/library/busybox newTag: 1.31.1 - name: registry.ops.eblu.me/blumeops/grafana-sidecar diff --git a/docs/changelog.d/externalize-teslamate-dashboards.infra.md b/docs/changelog.d/externalize-teslamate-dashboards.infra.md new file mode 100644 index 0000000..684ce74 --- /dev/null +++ b/docs/changelog.d/externalize-teslamate-dashboards.infra.md @@ -0,0 +1 @@ +Externalize TeslaMate Grafana dashboards to forge mirror, removing 713 KB of ConfigMaps from the repo.