Kilometrage des vehicules : releves km, km par kWh, capacite estimee (tables, vues, Grafana, formulaire HA)
This commit is contained in:
@@ -1350,6 +1350,101 @@ ORDER BY date_trunc(pas.unite, debut)"""
|
||||
COULEURS_VEHICULES = {"VW": "blue", "JEEP": "green", "ZERO": "purple",
|
||||
"Invite": "yellow", "Non etiquete": "orange"}
|
||||
|
||||
# Kilometrage et capacite (04/10/2026) : vues km_intervalle et capacite_estimee
|
||||
# du service d'historisation (tools/kilometrage.mjs). Aucune constante ici : les
|
||||
# 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"""
|
||||
|
||||
KM_XY = {"type": "xychart", "pluginVersion": "11.3.0",
|
||||
"title": "Kilometres contre kWh : le nuage des trajets",
|
||||
"description": ("Un point = l'intervalle entre deux releves du compteur d'un vehicule. "
|
||||
"kWh consommes = kWh livres par la borne entre les deux releves + "
|
||||
"(niveau au 1er - niveau au 2nd) x capacite. Les droites sont les "
|
||||
"references donnees par le proprietaire (JEEP 50 km, VW 42 km, ZERO 200 km "
|
||||
"pour une charge pleine). Sous la droite : on a roule moins loin par kWh "
|
||||
"(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")],
|
||||
"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]}}])
|
||||
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"]],
|
||||
"legend": {"showLegend": True, "displayMode": "list", "placement": "bottom"},
|
||||
"tooltip": {"mode": "single", "sort": "none"}}}
|
||||
|
||||
KM_INTERVALLES = table("Les intervalles entre releves", [sql("A",
|
||||
"SELECT vehicule AS \"Vehicule\",\n"
|
||||
" to_char(debut AT TIME ZONE 'Europe/Paris', 'Dy DD/MM HH24:MI') AS \"Du\",\n"
|
||||
" to_char(fin AT TIME ZONE 'Europe/Paris', 'Dy DD/MM HH24:MI') AS \"Au\",\n"
|
||||
" km_parcourus AS \"km\",\n"
|
||||
" round(kwh_charges::numeric, 2) AS \"kWh borne\",\n"
|
||||
" niveau_debut || ' -> ' || niveau_fin || ' %' AS \"Niveau\",\n"
|
||||
" round(kwh_consommes::numeric, 2) AS \"kWh consommes\",\n"
|
||||
" round(km_par_kwh::numeric, 1) AS \"km/kWh\",\n"
|
||||
" round(km_par_kwh_ref::numeric, 1) AS \"Reference\",\n"
|
||||
" statut AS \"Statut\"\n"
|
||||
"FROM km_intervalle ORDER BY fin DESC", fmt="table")],
|
||||
PG, 14, 24, 10, 11,
|
||||
"Tous les intervalles, y compris ceux ecartes du nuage, avec la raison. "
|
||||
"« niveau manquant » : redonner le releve avec le niveau (« JEEP 112694 km 54 % »).",
|
||||
overrides=[sur("kWh borne", [{"id": "unit", "value": "kwatth"}]),
|
||||
sur("kWh consommes", [{"id": "unit", "value": "kwatth"}])])
|
||||
|
||||
KM_CAPACITE = ts("Capacite estimee des batteries (usure)", [sql("A",
|
||||
"SELECT debranche AS time,\n"
|
||||
" CASE WHEN vehicule = 'JEEP' THEN capacite_kwh END AS \"JEEP\",\n"
|
||||
" CASE WHEN vehicule = 'VW' THEN capacite_kwh END AS \"VW\",\n"
|
||||
" CASE WHEN vehicule = 'ZERO' THEN capacite_kwh END AS \"ZERO\"\n"
|
||||
"FROM capacite_estimee WHERE capacite_kwh IS NOT NULL AND $__timeFilter(debranche)\n"
|
||||
"ORDER BY 1")],
|
||||
PG, 0, 35, 14, 9, "kwatth",
|
||||
"Un point = un branchement ou le niveau a ete donne et la charge menee au plein "
|
||||
"(ou suivie d'un releve « debranche a NN % ») : capacite = kWh livres par la borne "
|
||||
"depuis le branchement / part manquante. Ce sont des kWh AU COMPTEUR (pertes du "
|
||||
"chargeur comprises). Une pente descendante sur des mois = usure de la batterie. "
|
||||
"Le niveau saisi est un entier : sur une petite charge, 1 point d'erreur pese lourd.",
|
||||
extra={"overrides": [sur(v, [{"id": "color", "value": {"mode": "fixed", "fixedColor": COULEURS_VEHICULES[v]}}])
|
||||
for v in ["JEEP", "VW", "ZERO"]]})
|
||||
KM_CAPACITE["fieldConfig"]["defaults"]["custom"].update(
|
||||
{"drawStyle": "points", "pointSize": 10, "showPoints": "always", "spanNulls": False})
|
||||
|
||||
KM_RELEVES = table("Les releves du compteur", [sql("A",
|
||||
"SELECT to_char(ts AT TIME ZONE 'Europe/Paris', 'Dy DD/MM HH24:MI') AS \"Quand\",\n"
|
||||
" vehicule AS \"Vehicule\", km AS \"Compteur\",\n"
|
||||
" coalesce(niveau_pct || ' %', '?') AS \"Niveau\", source AS \"Source\"\n"
|
||||
"FROM releve_km ORDER BY ts DESC", fmt="table")],
|
||||
PG, 14, 35, 10, 9,
|
||||
"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"}])])
|
||||
|
||||
vehicules = dashboard("evcs-vehicules", "Les vehicules", (
|
||||
"Ce que chaque voiture encaisse, session par session et sur la periode "
|
||||
"choisie. L'etiquette vient d'un selecteur manuel : elle peut etre fausse, "
|
||||
@@ -1430,6 +1525,7 @@ vehicules = dashboard("evcs-vehicules", "Les vehicules", (
|
||||
{"id": "custom.width", "value": 110}]),
|
||||
sur("dont reseau", [{"id": "unit", "value": "kwatth"}]),
|
||||
sur("P max", [{"id": "unit", "value": "watt"}])]),
|
||||
KM_XY, KM_INTERVALLES, KM_CAPACITE, KM_RELEVES,
|
||||
])
|
||||
|
||||
# =====================================================================
|
||||
@@ -1791,7 +1887,7 @@ journee = dashboard(
|
||||
# found ». Ici on veut les quatre colonnes, tout le temps.
|
||||
barchart("Energie heure par heure",
|
||||
[sql("A", energie_sql(prevision=True), fmt="table")],
|
||||
PG, 0, 4, 24, 9, "kwatth",
|
||||
PG, 0, 5, 24, 9, "kwatth",
|
||||
"La forme de la journee : quand le solaire a couvert la maison, quand il "
|
||||
"a fallu acheter — et, a la suite des barres mesurees, ce que la derniere "
|
||||
"prevision annonce pour les heures qui restent. L'heure EN COURS n'a pas "
|
||||
|
||||
Reference in New Issue
Block a user