diff --git a/deploy/historisation/grafana/dashboards/vehicules.json b/deploy/historisation/grafana/dashboards/vehicules.json index ef0d7be..a879d83 100644 --- a/deploy/historisation/grafana/dashboards/vehicules.json +++ b/deploy/historisation/grafana/dashboards/vehicules.json @@ -605,7 +605,62 @@ "format": "table", "rawQuery": true, "editorMode": "code", - "rawSql": "WITH i AS (SELECT * FROM km_intervalle WHERE statut = 'valide'),\ncap AS (SELECT DISTINCT ON (vehicule) capacite_kwh AS c FROM releve_km\n WHERE capacite_kwh > 0 ORDER BY vehicule, ts DESC),\nx AS (SELECT round(kwh_consommes::numeric, 2)::float8 AS x, vehicule, km_parcourus::float8 AS km FROM i\n UNION ALL SELECT 0, NULL, NULL\n UNION ALL SELECT c::float8, NULL, NULL FROM cap)\nSELECT x AS \"kWh consommes\",\n CASE WHEN vehicule = 'JEEP' THEN km END AS \"JEEP\",\n CASE WHEN vehicule = 'VW' THEN km END AS \"VW\",\n CASE WHEN vehicule = 'ZERO' THEN km END AS \"ZERO\",\n round((x * (SELECT autonomie_ref_km / capacite_kwh FROM releve_km\n WHERE vehicule = 'JEEP' AND capacite_kwh > 0 AND autonomie_ref_km > 0 ORDER BY ts DESC LIMIT 1))::numeric, 1)::float8 AS \"Reference JEEP\",\n round((x * (SELECT autonomie_ref_km / capacite_kwh FROM releve_km\n WHERE vehicule = 'VW' AND capacite_kwh > 0 AND autonomie_ref_km > 0 ORDER BY ts DESC LIMIT 1))::numeric, 1)::float8 AS \"Reference VW\",\n round((x * (SELECT autonomie_ref_km / capacite_kwh FROM releve_km\n WHERE vehicule = 'ZERO' AND capacite_kwh > 0 AND autonomie_ref_km > 0 ORDER BY ts DESC LIMIT 1))::numeric, 1)::float8 AS \"Reference ZERO\"\nFROM x ORDER BY 1" + "rawSql": "SELECT x AS \"kWh ref JEEP\", round((x * autonomie_ref_km / capacite_kwh)::numeric, 1)::float8 AS \"Reference JEEP\"\nFROM (SELECT autonomie_ref_km, capacite_kwh FROM releve_km\n WHERE vehicule = 'JEEP' AND capacite_kwh > 0 AND autonomie_ref_km > 0\n ORDER BY ts DESC LIMIT 1) r,\n LATERAL (VALUES (0::float8), (r.capacite_kwh::float8)) v(x) ORDER BY 1" + }, + { + "refId": "B", + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "evcs-pg" + }, + "format": "table", + "rawQuery": true, + "editorMode": "code", + "rawSql": "SELECT x AS \"kWh ref VW\", round((x * autonomie_ref_km / capacite_kwh)::numeric, 1)::float8 AS \"Reference VW\"\nFROM (SELECT autonomie_ref_km, capacite_kwh FROM releve_km\n WHERE vehicule = 'VW' AND capacite_kwh > 0 AND autonomie_ref_km > 0\n ORDER BY ts DESC LIMIT 1) r,\n LATERAL (VALUES (0::float8), (r.capacite_kwh::float8)) v(x) ORDER BY 1" + }, + { + "refId": "C", + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "evcs-pg" + }, + "format": "table", + "rawQuery": true, + "editorMode": "code", + "rawSql": "SELECT x AS \"kWh ref ZERO\", round((x * autonomie_ref_km / capacite_kwh)::numeric, 1)::float8 AS \"Reference ZERO\"\nFROM (SELECT autonomie_ref_km, capacite_kwh FROM releve_km\n WHERE vehicule = 'ZERO' AND capacite_kwh > 0 AND autonomie_ref_km > 0\n ORDER BY ts DESC LIMIT 1) r,\n LATERAL (VALUES (0::float8), (r.capacite_kwh::float8)) v(x) ORDER BY 1" + }, + { + "refId": "D", + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "evcs-pg" + }, + "format": "table", + "rawQuery": true, + "editorMode": "code", + "rawSql": "SELECT round(kwh_consommes::numeric, 2)::float8 AS \"kWh JEEP\",\n km_parcourus::float8 AS \"JEEP\"\nFROM km_intervalle WHERE statut = 'valide' AND vehicule = 'JEEP' ORDER BY 1" + }, + { + "refId": "E", + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "evcs-pg" + }, + "format": "table", + "rawQuery": true, + "editorMode": "code", + "rawSql": "SELECT round(kwh_consommes::numeric, 2)::float8 AS \"kWh VW\",\n km_parcourus::float8 AS \"VW\"\nFROM km_intervalle WHERE statut = 'valide' AND vehicule = 'VW' ORDER BY 1" + }, + { + "refId": "F", + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "evcs-pg" + }, + "format": "table", + "rawQuery": true, + "editorMode": "code", + "rawSql": "SELECT round(kwh_consommes::numeric, 2)::float8 AS \"kWh ZERO\",\n km_parcourus::float8 AS \"ZERO\"\nFROM km_intervalle WHERE statut = 'valide' AND vehicule = 'ZERO' ORDER BY 1" } ], "fieldConfig": { @@ -620,11 +675,23 @@ "fixed": 10 }, "pointShape": "circle", - "lineWidth": 1, + "lineWidth": 2, "fillOpacity": 60 } }, "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "^kWh .*" + }, + "properties": [ + { + "id": "unit", + "value": "kwatth" + } + ] + }, { "matcher": { "id": "byName", @@ -766,13 +833,13 @@ "frame": { "matcher": { "id": "byIndex", - "options": 0 + "options": 3 } }, "x": { "matcher": { "id": "byName", - "options": "kWh consommes" + "options": "kWh JEEP" } }, "y": { @@ -786,13 +853,13 @@ "frame": { "matcher": { "id": "byIndex", - "options": 0 + "options": 4 } }, "x": { "matcher": { "id": "byName", - "options": "kWh consommes" + "options": "kWh VW" } }, "y": { @@ -806,13 +873,13 @@ "frame": { "matcher": { "id": "byIndex", - "options": 0 + "options": 5 } }, "x": { "matcher": { "id": "byName", - "options": "kWh consommes" + "options": "kWh ZERO" } }, "y": { @@ -832,7 +899,7 @@ "x": { "matcher": { "id": "byName", - "options": "kWh consommes" + "options": "kWh ref JEEP" } }, "y": { @@ -846,13 +913,13 @@ "frame": { "matcher": { "id": "byIndex", - "options": 0 + "options": 1 } }, "x": { "matcher": { "id": "byName", - "options": "kWh consommes" + "options": "kWh ref VW" } }, "y": { @@ -866,13 +933,13 @@ "frame": { "matcher": { "id": "byIndex", - "options": 0 + "options": 2 } }, "x": { "matcher": { "id": "byName", - "options": "kWh consommes" + "options": "kWh ref ZERO" } }, "y": { @@ -1117,7 +1184,11 @@ "properties": [ { "id": "unit", - "value": "lengthkm" + "value": "suffix: km" + }, + { + "id": "decimals", + "value": 0 } ] } diff --git a/tools/gen-grafana-dashboards.py b/tools/gen-grafana-dashboards.py index e88cb4b..e933104 100644 --- a/tools/gen-grafana-dashboards.py +++ b/tools/gen-grafana-dashboards.py @@ -1355,20 +1355,22 @@ COULEURS_VEHICULES = {"VW": "blue", "JEEP": "green", "ZERO": "purple", # references (autonomie / capacite) viennent du releve, donc des helpers HA. KM_REF = """(SELECT autonomie_ref_km / capacite_kwh FROM releve_km WHERE vehicule = '{v}' AND capacite_kwh > 0 AND autonomie_ref_km > 0 ORDER BY ts DESC LIMIT 1)""" -KM_NUAGE = """WITH i AS (SELECT * FROM km_intervalle WHERE statut = 'valide'), -cap AS (SELECT DISTINCT ON (vehicule) capacite_kwh AS c FROM releve_km - WHERE capacite_kwh > 0 ORDER BY vehicule, ts DESC), -x AS (SELECT round(kwh_consommes::numeric, 2)::float8 AS x, vehicule, km_parcourus::float8 AS km FROM i - UNION ALL SELECT 0, NULL, NULL - UNION ALL SELECT c::float8, NULL, NULL FROM cap) -SELECT x AS "kWh consommes", - CASE WHEN vehicule = 'JEEP' THEN km END AS "JEEP", - CASE WHEN vehicule = 'VW' THEN km END AS "VW", - CASE WHEN vehicule = 'ZERO' THEN km END AS "ZERO", - round((x * """ + KM_REF.format(v="JEEP") + """)::numeric, 1)::float8 AS "Reference JEEP", - round((x * """ + KM_REF.format(v="VW") + """)::numeric, 1)::float8 AS "Reference VW", - round((x * """ + KM_REF.format(v="ZERO") + """)::numeric, 1)::float8 AS "Reference ZERO" -FROM x ORDER BY 1""" +# UNE TRAME PAR SERIE (04/10) : la version a une seule trame mettait des +# colonnes entierement vides, que le nuage tracait a ZERO (points violets sur +# l'axe, capture du proprietaire). Ici aucune colonne n'a de valeur nulle. +def km_points(v): + return ("SELECT round(kwh_consommes::numeric, 2)::float8 AS \"kWh " + v + "\",\n" + " km_parcourus::float8 AS \"" + v + "\"\n" + "FROM km_intervalle WHERE statut = 'valide' AND vehicule = '" + v + "' ORDER BY 1") + +def km_reference(v): + return ("SELECT x AS \"kWh ref " + v + "\", round((x * autonomie_ref_km / capacite_kwh)::numeric, 1)::float8 AS \"Reference " + v + "\"\n" + "FROM (SELECT autonomie_ref_km, capacite_kwh FROM releve_km\n" + " WHERE vehicule = '" + v + "' AND capacite_kwh > 0 AND autonomie_ref_km > 0\n" + " ORDER BY ts DESC LIMIT 1) r,\n" + " LATERAL (VALUES (0::float8), (r.capacite_kwh::float8)) v(x) ORDER BY 1") + +KM_VEHICULES = ["JEEP", "VW", "ZERO"] KM_XY = {"type": "xychart", "pluginVersion": "11.3.0", "title": "Kilometres contre kWh : le nuage des trajets", @@ -1380,21 +1382,30 @@ KM_XY = {"type": "xychart", "pluginVersion": "11.3.0", "(conduite, froid, chauffage — ou batterie qui s'use). Les intervalles " "d'une hybride finis batterie vide sont ecartes (km essence possibles)."), "datasource": PG, "gridPos": {"x": 0, "y": 24, "w": 14, "h": 11}, - "targets": [sql("A", KM_NUAGE, fmt="table")], + # References EN PREMIER (trames 0-2, toujours remplies), points ensuite : une + # trame de points vide ne peut pas decaler l'index d'une reference. + "targets": [sql(chr(65 + i), km_reference(v), fmt="table") for i, v in enumerate(KM_VEHICULES)] + + [sql(chr(68 + i), km_points(v), fmt="table") for i, v in enumerate(KM_VEHICULES)], "fieldConfig": {"defaults": {"unit": "lengthkm", "color": {"mode": "palette-classic"}, "custom": {"show": "points", "pointSize": {"fixed": 10}, "pointShape": "circle", - "lineWidth": 1, "fillOpacity": 60}}, - "overrides": [sur(v, [{"id": "color", "value": {"mode": "fixed", "fixedColor": COULEURS_VEHICULES[v]}}]) + "lineWidth": 2, "fillOpacity": 60}}, + "overrides": [{"matcher": {"id": "byRegexp", "options": "^kWh .*"}, + "properties": [{"id": "unit", "value": "kwatth"}]}] + + [sur(v, [{"id": "color", "value": {"mode": "fixed", "fixedColor": COULEURS_VEHICULES[v]}}]) for v in ["JEEP", "VW", "ZERO"]] + [sur("Reference " + v, [{"id": "color", "value": {"mode": "fixed", "fixedColor": COULEURS_VEHICULES[v]}}, {"id": "custom.show", "value": "lines"}, {"id": "custom.lineStyle", "value": {"fill": "dash", "dash": [10, 10]}}]) for v in ["JEEP", "VW", "ZERO"]]}, "options": {"mapping": "manual", - "series": [{"frame": {"matcher": {"id": "byIndex", "options": 0}}, - "x": {"matcher": {"id": "byName", "options": "kWh consommes"}}, - "y": {"matcher": {"id": "byName", "options": n}}} - for n in ["JEEP", "VW", "ZERO", "Reference JEEP", "Reference VW", "Reference ZERO"]], + "series": [{"frame": {"matcher": {"id": "byIndex", "options": 3 + i}}, + "x": {"matcher": {"id": "byName", "options": "kWh " + v}}, + "y": {"matcher": {"id": "byName", "options": v}}} + for i, v in enumerate(KM_VEHICULES)] + + [{"frame": {"matcher": {"id": "byIndex", "options": i}}, + "x": {"matcher": {"id": "byName", "options": "kWh ref " + v}}, + "y": {"matcher": {"id": "byName", "options": "Reference " + v}}} + for i, v in enumerate(KM_VEHICULES)], "legend": {"showLegend": True, "displayMode": "list", "placement": "bottom"}, "tooltip": {"mode": "single", "sort": "none"}}} @@ -1443,7 +1454,7 @@ KM_RELEVES = table("Les releves du compteur", [sql("A", "Releves recus par WhatsApp (concierge) ou par le tableau EVCS Master. Un " "releve fait au branchement est date du branchement : le compteur n'avance pas " "pendant la charge.", - overrides=[sur("Compteur", [{"id": "unit", "value": "lengthkm"}])]) + overrides=[sur("Compteur", [{"id": "unit", "value": "suffix: km"}, {"id": "decimals", "value": 0}])]) vehicules = dashboard("evcs-vehicules", "Les vehicules", ( "Ce que chaque voiture encaisse, session par session et sur la periode "