diff --git a/grafana/dashboards/battery-health.json b/grafana/dashboards/battery-health.json
new file mode 100644
index 00000000..8ba0fc64
--- /dev/null
+++ b/grafana/dashboards/battery-health.json
@@ -0,0 +1,1558 @@
+{
+ "__elements": [],
+ "__requires": [
+ {
+ "type": "panel",
+ "id": "bargauge",
+ "name": "Bar gauge",
+ "version": ""
+ },
+ {
+ "type": "panel",
+ "id": "gauge",
+ "name": "Gauge",
+ "version": ""
+ },
+ {
+ "type": "grafana",
+ "id": "grafana",
+ "name": "Grafana",
+ "version": "8.5.15"
+ },
+ {
+ "type": "panel",
+ "id": "natel-plotly-panel",
+ "name": "Plotly",
+ "version": "0.0.7"
+ },
+ {
+ "type": "panel",
+ "id": "piechart",
+ "name": "Pie chart",
+ "version": ""
+ },
+ {
+ "type": "datasource",
+ "id": "postgres",
+ "name": "PostgreSQL",
+ "version": "1.0.0"
+ },
+ {
+ "type": "panel",
+ "id": "stat",
+ "name": "Stat",
+ "version": ""
+ }
+ ],
+ "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": 1,
+ "id": null,
+ "iteration": 1681039491922,
+ "links": [
+ {
+ "icon": "dashboard",
+ "tags": [],
+ "title": "TeslaMate",
+ "tooltip": "",
+ "type": "link",
+ "url": "[[base_url:raw]]"
+ },
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "tags": [
+ "tesla"
+ ],
+ "title": "Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "liveNow": false,
+ "panels": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "**Usable (now)** is the estimated current battery capacity. \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. ",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "super-light-blue",
+ "value": null
+ }
+ ]
+ },
+ "unit": "kwatth"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 0,
+ "y": 0
+ },
+ "id": 13,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "value_and_name"
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT \n CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json -> 'MaxCapacity')::text::float END as \"Usable (new)\", \n ('$aux'::json -> 'CurrentCapacity')::text::float as \"Usable (now)\",\n ('$aux'::json -> 'CurrentCapacity')::text::float - CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json -> 'MaxCapacity')::text::float END as \"Difference\"\n \n \n \n \n \n \n ",
+ "refId": "A",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Battery Capacity",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "super-light-blue",
+ "value": null
+ }
+ ]
+ }
+ },
+ "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",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "value_and_name"
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT \n CASE WHEN $custom_max_range > 0 THEN $custom_max_range ELSE ('$aux'::json -> 'MaxRange')::text::float END as \"maxrange_$length_unit\",\n ('$aux'::json -> 'CurrentRange')::text::float as \"currentrange_$length_unit\",\n CASE WHEN $custom_max_range > 0 THEN $custom_max_range ELSE ('$aux'::json -> 'MaxRange')::text::float END - ('$aux'::json -> 'CurrentRange')::text::float as \"range_lost_$length_unit\"",
+ "refId": "A",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Ranges",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "super-light-blue",
+ "value": null
+ }
+ ]
+ }
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 12,
+ "y": 0
+ },
+ "id": 32,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "/.*/",
+ "values": false
+ },
+ "textMode": "value_and_name"
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "hide": false,
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT ROUND(convert_km((max(odometer) - min(odometer))::numeric, '$length_unit'),0)|| ' $length_unit' as \"Logged\"\nfrom positions where car_id = $car_id;",
+ "refId": "DistanceLogged",
+ "select": [
+ [
+ {
+ "params": [
+ "efficiency"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "cars",
+ "timeColumn": "inserted_at",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "hide": false,
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "select ROUND(convert_km(ROUND(odometer::numeric,0), '$length_unit'),0) || ' $length_unit' as \"Odometer\"\nfrom positions \nwhere car_id = $car_id\norder by date desc \nlimit 1;",
+ "refId": "Odometer",
+ "select": [
+ [
+ {
+ "params": [
+ "efficiency"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "cars",
+ "timeColumn": "inserted_at",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Mileage",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "light-yellow",
+ "value": null
+ }
+ ]
+ }
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "Total energy added"
+ },
+ "properties": [
+ {
+ "id": "unit",
+ "value": "kwatth"
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 18,
+ "y": 0
+ },
+ "id": 36,
+ "links": [],
+ "maxDataPoints": 100,
+ "options": {
+ "colorMode": "value",
+ "fieldOptions": {
+ "calcs": [
+ "mean"
+ ]
+ },
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "mean"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "value_and_name"
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT\n\tsum(charge_energy_added) as \"Total energy added\"\nFROM\n\tcharging_processes\nWHERE\n\tcar_id = $car_id;",
+ "refId": "A",
+ "select": [
+ [
+ {
+ "params": [
+ "efficiency"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "cars",
+ "timeColumn": "inserted_at",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "hide": false,
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT\n\tround(ceil(sum(charge_energy_added) / ('$aux'::json -> 'MaxCapacity')::text::numeric),0) AS \"Estimated charging cycles\"\nFROM charging_processes WHERE car_id = $car_id;",
+ "refId": "B",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Battery Stats",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "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 form 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": null
+ },
+ {
+ "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": {
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [],
+ "fields": "/^greatest$/",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": true
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT GREATEST(0, 100.0 - (('$aux'::json -> 'CurrentCapacity')::text::float * 100.0 / CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json -> 'MaxCapacity')::text::float END))\n\n",
+ "refId": "A",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Estimated Degradation",
+ "type": "gauge"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "mappings": [],
+ "max": 100,
+ "min": 1,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "light-red",
+ "value": null
+ },
+ {
+ "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",
+ "minVizHeight": 10,
+ "minVizWidth": 0,
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showUnfilled": true
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT \n LEAST(100, (100 - GREATEST(0, 100.0 - (('$aux'::json -> 'CurrentCapacity')::text::float * 100.0 / CASE WHEN $custom_kwh_new > 0 THEN $custom_kwh_new ELSE ('$aux'::json -> 'MaxCapacity')::text::float END)))) as \"Battery Health (%)\"\n \n",
+ "refId": "A",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Battery Health",
+ "type": "bargauge"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "Estimated charging cycles are based on the whole energy added to the battery. So the more data you logged the better. \n",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "super-light-blue",
+ "value": null
+ }
+ ]
+ }
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 12,
+ "y": 6
+ },
+ "id": 29,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "/.*/",
+ "values": false
+ },
+ "textMode": "value_and_name"
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT \n round(('$aux'::json -> 'LastChargekWhAdded')::text::numeric,1) || ' kWh' as \"Last Energy added\",\n round(('$aux'::json -> 'LastMileageAdded')::text::numeric,1) || ' $length_unit' as \"Last Range added\"",
+ "refId": "LastChanging",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Charges",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "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": 7,
+ "w": 6,
+ "x": 18,
+ "y": 6
+ },
+ "id": 34,
+ "links": [],
+ "maxDataPoints": 3,
+ "options": {
+ "displayLabels": [
+ "name",
+ "percent",
+ "value"
+ ],
+ "legend": {
+ "displayMode": "hidden",
+ "placement": "bottom"
+ },
+ "pieType": "pie",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "tooltip": {
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "8.5.6",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "time_series",
+ "group": [],
+ "metricColumn": "none",
+ "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\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(charge_energy_added) AS value,\n\tcurrent AS metric\nFROM data\nGROUP BY 3\nORDER BY metric DESC;",
+ "refId": "A",
+ "select": [
+ [
+ {
+ "params": [
+ "latitude"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "addresses",
+ "timeColumn": "inserted_at",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Summary AC/DC Energy Added",
+ "type": "piechart"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "mappings": [],
+ "max": 100,
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "dark-red",
+ "value": null
+ },
+ {
+ "color": "semi-dark-green",
+ "value": 20
+ },
+ {
+ "color": "semi-dark-orange",
+ "value": 80
+ },
+ {
+ "color": "light-blue",
+ "value": 100
+ }
+ ]
+ },
+ "unit": "%"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 2,
+ "w": 6,
+ "x": 6,
+ "y": 9
+ },
+ "id": 25,
+ "options": {
+ "displayMode": "lcd",
+ "minVizHeight": 10,
+ "minVizWidth": 0,
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showUnfilled": true,
+ "text": {}
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "%",
+ "metricColumn": "none",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "rawQuery": true,
+ "rawSql": "(SELECT usable_battery_level, date\r\nFROM positions\r\nWHERE car_id = $car_id\r\nORDER BY date DESC\r\nLIMIT 1)\r\nUNION\r\nSELECT 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\r\nORDER BY date DESC\r\nLIMIT 1",
+ "refId": "SOC",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Current SOC",
+ "type": "bargauge"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "mappings": [],
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "dark-red",
+ "value": null
+ },
+ {
+ "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": 6,
+ "x": 6,
+ "y": 11
+ },
+ "id": 27,
+ "options": {
+ "displayMode": "gradient",
+ "minVizHeight": 10,
+ "minVizWidth": 0,
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "/^kwh$/",
+ "values": false
+ },
+ "showUnfilled": true,
+ "text": {}
+ },
+ "pluginVersion": "8.5.15",
+ "targets": [
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "%",
+ "metricColumn": "none",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "rawQuery": true,
+ "rawSql": "(SELECT usable_battery_level * ('$aux'::json -> 'CurrentCapacity')::text::float / 100 as kWh, date, ('$aux'::json -> 'CurrentCapacity')::text::float as Total\nFROM positions\nWHERE car_id = $car_id\nORDER BY date DESC\nLIMIT 1)\nUNION\nSELECT battery_level * ('$aux'::json -> 'CurrentCapacity')::text::float / 100 as kWh, date, ('$aux'::json -> 'CurrentCapacity')::text::float as Total\nFROM charges c\nJOIN charging_processes p ON p.id = c.charging_process_id\nWHERE p.car_id = $car_id\nORDER BY date DESC\nLIMIT 1",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Current Capacity",
+ "type": "bargauge"
+ },
+ {
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 13
+ },
+ "id": 28,
+ "links": [],
+ "pconfig": {
+ "fixScale": "",
+ "layout": {
+ "dragmode": "zoom",
+ "font": {
+ "family": "\"Open Sans\", Helvetica, Arial, sans-serif"
+ },
+ "hovermode": "closest",
+ "legend": {
+ "orientation": "h"
+ },
+ "showlegend": false,
+ "xaxis": {
+ "rangemode": "normal",
+ "showgrid": true,
+ "title": "Odometer",
+ "type": "linear",
+ "zeroline": false
+ },
+ "yaxis": {
+ "rangemode": "normal",
+ "showgrid": true,
+ "title": "kWh",
+ "type": "linear",
+ "zeroline": false
+ },
+ "zaxis": {
+ "rangemode": "normal",
+ "showgrid": true,
+ "type": "linear",
+ "zeroline": false
+ }
+ },
+ "loadFromCDN": false,
+ "settings": {
+ "displayModeBar": false,
+ "type": "scatter"
+ },
+ "showAnnotations": true,
+ "traces": [
+ {
+ "mapping": {
+ "color": "id",
+ "text": "title",
+ "x": "odometer",
+ "y": "kWh"
+ },
+ "name": "Mileage, kWh",
+ "settings": {
+ "color_option": "ramp",
+ "line": {
+ "color": "#C0D8FF",
+ "dash": "dashdot",
+ "shape": "linear",
+ "width": 1
+ },
+ "marker": {
+ "color": "#33B5E5",
+ "colorscale": "Reds",
+ "line": {
+ "color": "#DDD",
+ "width": 0
+ },
+ "showscale": false,
+ "size": 10,
+ "sizemin": 3,
+ "sizemode": "diameter",
+ "sizeref": 0.2,
+ "symbol": "circle"
+ }
+ },
+ "show": {
+ "line": true,
+ "lines": false,
+ "markers": true
+ }
+ },
+ {
+ "mapping": {
+ "color": "id",
+ "x": "M-Odometer",
+ "y": "M-kWh"
+ },
+ "name": "Median",
+ "settings": {
+ "color_option": "ramp",
+ "line": {
+ "color": "#C0D8FF",
+ "dash": "solid",
+ "shape": "linear",
+ "width": 2
+ },
+ "marker": {
+ "color": "#33B5E5",
+ "colorscale": "Reds",
+ "line": {
+ "color": "#DDD",
+ "width": 0
+ },
+ "showscale": false,
+ "size": 3,
+ "sizemin": 3,
+ "sizemode": "diameter",
+ "sizeref": 0.2,
+ "symbol": "circle"
+ }
+ },
+ "show": {
+ "line": true,
+ "lines": true,
+ "markers": false
+ }
+ }
+ ]
+ },
+ "pluginVersion": "8.5.6",
+ "targets": [
+ {
+ "alias": "",
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "hide": false,
+ "metricColumn": "none",
+ "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')::text::float / AVG(c.usable_battery_level) AS \"kWh\",\r\n\tMAX(cp.id) AS id,\r\n\tto_char(cp.end_date, 'YYYY-MM-dd') AS Title\r\n\tFROM charging_processes cp\r\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\tFROM charges 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.end_rated_range_km > cp.start_rated_range_km\r\n\tGROUP BY 4",
+ "refId": "Projected Range",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "timeColumn": "time",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ },
+ {
+ "alias": "",
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "format": "table",
+ "group": [],
+ "hide": false,
+ "metricColumn": "none",
+ "rawQuery": true,
+ "rawSql": "SELECT \n ROUND(MIN(convert_km(p.odometer::numeric,'$length_unit')),0) AS \"M-Odometer\",\n\tROUND(PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY c.rated_battery_range_km * ('$aux'::json -> 'RatedEfficiency')::text::float / c.usable_battery_level)::numeric,1) AS \"M-kWh\",\n\tto_char(cp.end_date, 'YYYYMM') || CASE WHEN to_char(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 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.end_rated_range_km > cp.start_rated_range_km\n\tGROUP BY 3",
+ "refId": "Median",
+ "select": [
+ [
+ {
+ "params": [
+ "start_km"
+ ],
+ "type": "column"
+ }
+ ]
+ ],
+ "table": "drives",
+ "timeColumn": "start_date",
+ "timeColumnType": "timestamp",
+ "where": [
+ {
+ "name": "$__timeFilter",
+ "params": [],
+ "type": "macro"
+ }
+ ]
+ }
+ ],
+ "title": "Battery Capacity by Mileage",
+ "type": "natel-plotly-panel",
+ "version": 1
+ }
+ ],
+ "refresh": "",
+ "schemaVersion": 36,
+ "style": "dark",
+ "tags": [
+ "tesla"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {},
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "definition": "SELECT name AS __text, id AS __value FROM cars ORDER BY display_priority ASC, name ASC;",
+ "hide": 0,
+ "includeAll": false,
+ "label": "Car",
+ "multi": false,
+ "name": "car_id",
+ "options": [],
+ "query": "SELECT name AS __text, id AS __value FROM cars ORDER BY display_priority ASC, name ASC;",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "tagValuesQuery": "",
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "current": {},
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "definition": "select unit_of_length from settings limit 1;",
+ "hide": 2,
+ "includeAll": false,
+ "label": "",
+ "multi": false,
+ "name": "length_unit",
+ "options": [],
+ "query": "select unit_of_length from settings limit 1;",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "tagValuesQuery": "",
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "current": {},
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "definition": "select base_url from settings limit 1;",
+ "hide": 2,
+ "includeAll": false,
+ "label": "",
+ "multi": false,
+ "name": "base_url",
+ "options": [],
+ "query": "select base_url from settings limit 1;",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "tagValuesQuery": "",
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "current": {},
+ "datasource": {
+ "type": "postgres",
+ "uid": "TeslaMate"
+ },
+ "definition": "-- CONCATENATED JOIN QUERIES TO IMPROVE PERFORMANCE\nWITH\naux\tAS\n(\n\tSELECT cp.charge_energy_added,\n\t\tcp.car_id, cp.charge_energy_added / (cp.end_rated_range_km - cp.start_rated_range_km) * 100.0 AS rated_efficiency,\n\t\t(cp.end_rated_range_km - cp.start_rated_range_km) AS added_range_km\n\tFROM charging_processes cp\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\n\t\tFROM charges\n\t\tGROUP BY charging_process_id) AS last_charges\n\t\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\tWHERE cp.car_id = $car_id\n\t\tAND cp.end_date IS NOT NULL\n\t\tAND cp.end_rated_range_km > cp.start_rated_range_km\n\tORDER BY cp.end_date DESC \n\tLIMIT 1\n), \nCurrentCapacity\t AS\n(\n\tSELECT AVG(Capacity) AS CurrentCapacity FROM\n (SELECT (100.0 * cp.charge_energy_added) / (GREATEST(1,MAX(usable_battery_level) - MIN(usable_battery_level))) AS Capacity\t\n FROM charging_processes cp\n\t INNER JOIN charges c\tON cp.id = c.charging_process_id\n INNER JOIN aux ON cp.car_id = aux.car_id\n\t WHERE cp.car_id = $car_id AND cp.charge_energy_added >= aux.rated_efficiency AND cp.end_date >= date_trunc('month', current_date - interval '1 month') \n GROUP BY cp.charge_energy_added, cp.end_date\n ) AS lastEstimatedCapacity\n), \nMaxCapacity AS\n(\n\tSELECT MAX(c.rated_battery_range_km * cars.efficiency * 100.0 / c.usable_battery_level) AS MaxCapacity\n\tFROM charging_processes cp\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\n\t\tFROM charges\n\t\tGROUP BY charging_process_id) AS last_charges\n\t\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 cars ON cp.car_id = cars.id\n\tWHERE cp.car_id = $car_id\n\t\tAND cp.end_date IS NOT NULL\n\t\tAND cp.end_rated_range_km > cp.start_rated_range_km\n\t\tAND c.charge_energy_added >= cars. Efficiency\n), \nCurrentRange AS\n(\n SELECT\n\t\tfloor(extract(epoch from date)/86400)*86400 AS timecurrent,\n\t\tsum(rated_battery_range_km) / sum(usable_battery_level) * 100 AS rated_range_km\n\tFROM (\n\t\tSELECT battery_level, usable_battery_level, date, rated_battery_range_km from charges c \n\t\tJOIN charging_processes p ON p.id = c.charging_process_id \n\t\tWHERE p.car_id = $car_id AND usable_battery_level IS NOT NULL) AS data\n\tGROUP BY 1\n\tORDER BY 1 DESC\n\tLIMIT 1\n), \nMaxRange AS\n(\n SELECT\n\t\tfloor(extract(epoch from date)/86400)*86400 AS time,\n\t\tsum(rated_battery_range_km) / sum(usable_battery_level) * 100 AS max_rated_range_km\n\tFROM (\n\t\tSELECT battery_level, usable_battery_level, date, rated_battery_range_km from charges c \n\t\tJOIN charging_processes p ON p.id = c.charging_process_id \n\t\tWHERE p.car_id = $car_id AND usable_battery_level IS NOT NULL) AS data\n\tGROUP BY 1\n\tORDER BY 2 DESC\n\tLIMIT 1\n) \nSELECT CONCAT('{\"LastChargekWhAdded\": ', aux.charge_energy_added, \n ', \"LastMileageAdded\" : ', convert_km(aux.added_range_km,'$length_unit'),\n ', \"MaxRange\": ', convert_km(MaxRange.max_rated_range_km,'$length_unit'),\n ', \"CurrentRange\": ',convert_km(CurrentRange.rated_range_km,'$length_unit'),\n ', \"MaxCapacity\": ', MaxCapacity.MaxCapacity,\n ', \"CurrentCapacity\": ',CurrentCapacity.CurrentCapacity,\n ', \"RatedEfficiency\": ',aux.rated_efficiency, '}') \nFROM MaxRange, CurrentRange, Aux, MaxCapacity, CurrentCapacity;\n-- The following query is the result of many tests and hours of work. This panel is for your own personal use. \n-- If you think you can improve it and contribute, please create a pull request and do not take it to your repository, \n-- much less upload it to another repository as if the original idea were yours, nor do you share it on social media\n-- without mentioning the author. Respect the ingenuity and work of others. Cheers!\n-- 16/04/2023\n-- By @jheredianet - Twitter: @juanheredia",
+ "hide": 2,
+ "includeAll": false,
+ "multi": false,
+ "name": "aux",
+ "options": [],
+ "query": "-- CONCATENATED JOIN QUERIES TO IMPROVE PERFORMANCE\nWITH\naux\tAS\n(\n\tSELECT cp.charge_energy_added,\n\t\tcp.car_id, cp.charge_energy_added / (cp.end_rated_range_km - cp.start_rated_range_km) * 100.0 AS rated_efficiency,\n\t\t(cp.end_rated_range_km - cp.start_rated_range_km) AS added_range_km\n\tFROM charging_processes cp\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\n\t\tFROM charges\n\t\tGROUP BY charging_process_id) AS last_charges\n\t\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\tWHERE cp.car_id = $car_id\n\t\tAND cp.end_date IS NOT NULL\n\t\tAND cp.end_rated_range_km > cp.start_rated_range_km\n\tORDER BY cp.end_date DESC \n\tLIMIT 1\n), \nCurrentCapacity\t AS\n(\n\tSELECT AVG(Capacity) AS CurrentCapacity FROM\n (SELECT (100.0 * cp.charge_energy_added) / (GREATEST(1,MAX(usable_battery_level) - MIN(usable_battery_level))) AS Capacity\t\n FROM charging_processes cp\n\t INNER JOIN charges c\tON cp.id = c.charging_process_id\n INNER JOIN aux ON cp.car_id = aux.car_id\n\t WHERE cp.car_id = $car_id AND cp.charge_energy_added >= aux.rated_efficiency AND cp.end_date >= date_trunc('month', current_date - interval '1 month') \n GROUP BY cp.charge_energy_added, cp.end_date\n ) AS lastEstimatedCapacity\n), \nMaxCapacity AS\n(\n\tSELECT MAX(c.rated_battery_range_km * cars.efficiency * 100.0 / c.usable_battery_level) AS MaxCapacity\n\tFROM charging_processes cp\n\t\tJOIN (SELECT charging_process_id, MAX(date) as date\n\t\tFROM charges\n\t\tGROUP BY charging_process_id) AS last_charges\n\t\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 cars ON cp.car_id = cars.id\n\tWHERE cp.car_id = $car_id\n\t\tAND cp.end_date IS NOT NULL\n\t\tAND cp.end_rated_range_km > cp.start_rated_range_km\n\t\tAND c.charge_energy_added >= cars. Efficiency\n), \nCurrentRange AS\n(\n SELECT\n\t\tfloor(extract(epoch from date)/86400)*86400 AS timecurrent,\n\t\tsum(rated_battery_range_km) / sum(usable_battery_level) * 100 AS rated_range_km\n\tFROM (\n\t\tSELECT battery_level, usable_battery_level, date, rated_battery_range_km from charges c \n\t\tJOIN charging_processes p ON p.id = c.charging_process_id \n\t\tWHERE p.car_id = $car_id AND usable_battery_level IS NOT NULL) AS data\n\tGROUP BY 1\n\tORDER BY 1 DESC\n\tLIMIT 1\n), \nMaxRange AS\n(\n SELECT\n\t\tfloor(extract(epoch from date)/86400)*86400 AS time,\n\t\tsum(rated_battery_range_km) / sum(usable_battery_level) * 100 AS max_rated_range_km\n\tFROM (\n\t\tSELECT battery_level, usable_battery_level, date, rated_battery_range_km from charges c \n\t\tJOIN charging_processes p ON p.id = c.charging_process_id \n\t\tWHERE p.car_id = $car_id AND usable_battery_level IS NOT NULL) AS data\n\tGROUP BY 1\n\tORDER BY 2 DESC\n\tLIMIT 1\n) \nSELECT CONCAT('{\"LastChargekWhAdded\": ', aux.charge_energy_added, \n ', \"LastMileageAdded\" : ', convert_km(aux.added_range_km,'$length_unit'),\n ', \"MaxRange\": ', convert_km(MaxRange.max_rated_range_km,'$length_unit'),\n ', \"CurrentRange\": ',convert_km(CurrentRange.rated_range_km,'$length_unit'),\n ', \"MaxCapacity\": ', MaxCapacity.MaxCapacity,\n ', \"CurrentCapacity\": ',CurrentCapacity.CurrentCapacity,\n ', \"RatedEfficiency\": ',aux.rated_efficiency, '}') \nFROM MaxRange, CurrentRange, Aux, MaxCapacity, CurrentCapacity;\n-- The following query is the result of many tests and hours of work. This panel is for your own personal use. \n-- If you think you can improve it and contribute, please create a pull request and do not take it to your repository, \n-- much less upload it to another repository as if the original idea were yours, nor do you share it on social media\n-- without mentioning the author. Respect the ingenuity and work of others. Cheers!\n-- 16/04/2023\n-- By @jheredianet - Twitter: @juanheredia",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "type": "query"
+ },
+ {
+ "current": {
+ "selected": false,
+ "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",
+ "hide": 0,
+ "label": "Custom Battery Capacity (kWh) when new",
+ "name": "custom_kwh_new",
+ "options": [
+ {
+ "selected": true,
+ "text": "0",
+ "value": "0"
+ }
+ ],
+ "query": "0",
+ "skipUrlSync": false,
+ "type": "textbox"
+ },
+ {
+ "current": {
+ "selected": false,
+ "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",
+ "hide": 0,
+ "label": "Custom Max Range when new",
+ "name": "custom_max_range",
+ "options": [
+ {
+ "selected": true,
+ "text": "0",
+ "value": "0"
+ }
+ ],
+ "query": "0",
+ "skipUrlSync": false,
+ "type": "textbox"
+ }
+ ]
+ },
+
+ "timepicker": {
+ "hidden": true,
+ "refresh_intervals": []
+ },
+ "timezone": "browser",
+ "title": "Battery Health",
+ "uid": "jchmRiqUfXgTM",
+ "version": 7,
+ "weekStart": ""
+}
\ No newline at end of file
diff --git a/website/docs/projects.md b/website/docs/projects.md
index 466bd91f..4982209b 100644
--- a/website/docs/projects.md
+++ b/website/docs/projects.md
@@ -2,20 +2,6 @@
title: Projects using TeslaMate
---
-Here is a list of projects using TeslaMate.
-
-- [Gaussmeter](#gaussmeter)
-- [Home Assistant Addon](#home-assistant-addon)
-- [MMM-Teslamate](#mmm-teslamate)
-- [TeslaMateAgile](#teslamateagile)
-- [TeslaMateApi](#teslamateapi)
-- [TeslaMate_Telegram_Bot](#teslamate_telegram_bot)
-- [TeslaMate-ABRP](#teslamate_abrp)
-- [Custom Grafana Dashboards](#customgrafanadashboards)
-- [Home Assistant Integration](#tesla-home-assistant-integration)
-
----
-
## [Gaussmeter](https://github.com/gaussmeter/gaussmeter)
An LED illuminated acrylic Tesla Model 3. Its color and scale of light depend on the cars current state.
@@ -58,7 +44,7 @@ This is a telegram bot written in Python to notify by Telegram message when a ne
LINK: [github.com/JakobLichterfeld/TeslaMate_Telegram_Bot](https://github.com/JakobLichterfeld/TeslaMate_Telegram_Bot)
-## [TeslaMate-ABRP](https://fetzu.github.io/teslamate-abrp/)
+## [TeslaMate ABRP](https://fetzu.github.io/teslamate-abrp/)
A python script (also available as a lightweight docker image) that pushes car status data to [ABetterRoutePlanner](https://abetterrouteplanner.com) based on contents of TeslaMate MQTT's topic.
@@ -70,6 +56,12 @@ Collection of custom dashboards for Grafana.
LINK: [github.com/CarlosCuezva/dashboards-Grafana-Teslamate](https://github.com/CarlosCuezva/dashboards-Grafana-Teslamate)
+## [TeslaMate Custom Dashboards](https://github.com/jheredianet/Teslamate-CustomGrafanaDashboards)
+
+Teslamate Custom Dashboards: Battery Health, Charging Costs Stats, Charging CurveStats, Tracking Drives and more. Also, there are two dashboards (Current Charge & Drive View) that could be browsed on the car while driving or charging.
+
+LINK: [github.com/jheredianet/Teslamate-CustomGrafanaDashboards](https://github.com/jheredianet/Teslamate-CustomGrafanaDashboards)
+
## [Tesla Home Assistant Integration](https://github.com/alandtse/tesla)
The Tesla Home Assistant integration can use the data from the TeslaMate MQTT integration to update car data in near-real time.
diff --git a/website/docs/screenshots.mdx b/website/docs/screenshots.mdx
index a7da97c8..577e1c50 100644
--- a/website/docs/screenshots.mdx
+++ b/website/docs/screenshots.mdx
@@ -57,3 +57,11 @@ import useBaseUrl from '@docusaurus/useBaseUrl';
## Updates
+
+## Lifetime driving map
+
+
+
+## Visited addresses
+
+
\ No newline at end of file
diff --git a/website/static/screenshots/lifetime_driving_map.png b/website/static/screenshots/lifetime_driving_map.png
new file mode 100644
index 00000000..1b370736
Binary files /dev/null and b/website/static/screenshots/lifetime_driving_map.png differ
diff --git a/website/static/screenshots/locations.png b/website/static/screenshots/locations.png
new file mode 100644
index 00000000..bf4a9a2b
Binary files /dev/null and b/website/static/screenshots/locations.png differ