From 639f9cba4e4e77d4fb009c3fae46fce05d8e2d4a Mon Sep 17 00:00:00 2001 From: Johannes Heck Date: Fri, 24 Jun 2022 15:16:42 +0200 Subject: [PATCH] Added average cost per kWh to charging stats (#2693) * add avg cost per kWh stat * fix datasource & pluginVersion * title * add cost_per_kwh to charges table as well * fix decimals and noValue * improve queries, remove param --- grafana/dashboards/charges.json | 32 +++++++++- grafana/dashboards/charging-stats.json | 82 +++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 10 deletions(-) diff --git a/grafana/dashboards/charges.json b/grafana/dashboards/charges.json index 37ee6850ac..548ed191b6 100644 --- a/grafana/dashboards/charges.json +++ b/grafana/dashboards/charges.json @@ -706,6 +706,34 @@ "value": true } ] + }, + { + "matcher": { + "id": "byName", + "options": "cost_per_kwh" + }, + "properties": [ + { + "id": "unit", + "value": "none" + }, + { + "id": "displayName", + "value": "Cost per kWh" + }, + { + "id": "custom.width", + "value": 100 + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "noValue", + "value": "-" + } + ] } ] }, @@ -741,7 +769,7 @@ "group": [], "metricColumn": "none", "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 start_[[preferred_range]]_range_km,\n end_[[preferred_range]]_range_km,\n outside_temp_avg,\n cp.id,\n lag(end_[[preferred_range]]_range_km) OVER (ORDER BY start_date) - start_[[preferred_range]]_range_km AS range_loss,\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 FROM\n charging_processes cp\n\t LEFT 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\nWHERE \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))\nGROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,21,p.odometer\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 end_date,\n COALESCE(geofence_name, address) as address, \n duration_min,\n cost,\n charge_energy_added,\n charge_energy_used,\n CASE WHEN charge_energy_used IS NULL THEN NULL ELSE LEAST(charge_energy_added / NULLIF(charge_energy_used, 0), 1.0) END 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((end_[[preferred_range]]_range_km - start_[[preferred_range]]_range_km) * 60 / NULLIF (duration_min, 0), '$length_unit') AS range_added_per_hour_$length_unit,\n start_battery_level,\n end_battery_level,\n convert_km(distance::numeric, '$length_unit') AS distance_$length_unit\n FROM\n data\nWHERE\n (distance >= 0 OR distance IS NULL)\n AND max_charger_voltage >= '$voltage'\n AND duration_min >= '$min_duration_min'\nORDER BY\n start_date DESC;", + "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 start_[[preferred_range]]_range_km,\n end_[[preferred_range]]_range_km,\n outside_temp_avg,\n cp.id,\n lag(end_[[preferred_range]]_range_km) OVER (ORDER BY start_date) - start_[[preferred_range]]_range_km AS range_loss,\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 FROM\n charging_processes cp\n\t LEFT 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\nWHERE \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))\nGROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,21,p.odometer\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 end_date,\n COALESCE(geofence_name, address) as address, \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 charge_energy_used,\n CASE WHEN charge_energy_used IS NULL THEN NULL ELSE LEAST(charge_energy_added / NULLIF(charge_energy_used, 0), 1.0) END 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((end_[[preferred_range]]_range_km - start_[[preferred_range]]_range_km) * 60 / NULLIF (duration_min, 0), '$length_unit') AS range_added_per_hour_$length_unit,\n start_battery_level,\n end_battery_level,\n convert_km(distance::numeric, '$length_unit') AS distance_$length_unit\n FROM\n data\nWHERE\n (distance >= 0 OR distance IS NULL)\n AND max_charger_voltage >= '$voltage'\n AND duration_min >= '$min_duration_min'\nORDER BY\n start_date DESC;", "refId": "A", "select": [ [ @@ -1056,7 +1084,7 @@ "type": "stat" } ], - "schemaVersion": 34, + "schemaVersion": 36, "style": "dark", "tags": [ "tesla" diff --git a/grafana/dashboards/charging-stats.json b/grafana/dashboards/charging-stats.json index ea0429e2e1..86b5ac8c59 100644 --- a/grafana/dashboards/charging-stats.json +++ b/grafana/dashboards/charging-stats.json @@ -79,7 +79,7 @@ }, "gridPos": { "h": 3, - "w": 6, + "w": 5, "x": 0, "y": 1 }, @@ -159,8 +159,8 @@ }, "gridPos": { "h": 3, - "w": 6, - "x": 6, + "w": 5, + "x": 5, "y": 1 }, "id": 10, @@ -241,7 +241,7 @@ "gridPos": { "h": 3, "w": 4, - "x": 12, + "x": 10, "y": 1 }, "id": 14, @@ -323,7 +323,7 @@ "gridPos": { "h": 3, "w": 4, - "x": 16, + "x": 14, "y": 1 }, "id": 27, @@ -403,8 +403,8 @@ }, "gridPos": { "h": 3, - "w": 4, - "x": 20, + "w": 3, + "x": 18, "y": 1 }, "id": 26, @@ -456,6 +456,72 @@ "title": "Cost per 100 $length_unit", "type": "stat" }, + { + "datasource": "TeslaMate", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#d8d9da", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 1 + }, + "id": 31, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.4.5", + "targets": [ + { + "format": "table", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT (\n SELECT sum(cost)\n FROM charging_processes\n WHERE $__timeFilter(end_date) AND car_id = $car_id\n) / (\n SELECT sum(greatest(charge_energy_added, charge_energy_used))\n FROM charging_processes\n WHERE $__timeFilter(end_date) AND car_id = $car_id\n)", + "refId": "A", + "table": "drives", + "timeColumn": "start_date", + "timeColumnType": "timestamp", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Average Cost per kWh", + "type": "stat" + }, { "cards": {}, "color": { @@ -1701,7 +1767,7 @@ } ], "refresh": false, - "schemaVersion": 35, + "schemaVersion": 36, "style": "dark", "tags": [ "tesla"