Le bilan se lit en colonnes : les titres, puis les valeurs

Le format « une ligne par grandeur » etait illisible, et la hauteur du panneau
n'en montrait que trois sur sept. Le tableau rend desormais une ligne
d'en-tetes et une ligne de valeurs, ce qui est la forme attendue pour un
resume.

C'est toujours un panneau `table` et pas un `stat` : ce dernier, sur exactement
cette requete, affichait sept « — » alors que l'API montrait qu'il recevait
sept champs de type number avec leurs valeurs. Une note le rappelle dans le
generateur pour ne pas y revenir.

Les unites reviennent en overrides puisque les libelles n'ont plus a les
porter, avec deux colorations utiles : le reseau importe passe a l'ambre au-dela
de 3 kWh et a l'orange au-dela de 8, l'autonomie a un fond vert au-dessus de
85 %.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
This commit is contained in:
Tallagrand Thierry
2026-09-08 00:24:00 +02:00
parent 2569718ddd
commit c42b29c76f
2 changed files with 177 additions and 48 deletions

View File

@@ -1274,36 +1274,30 @@ report AS (
# Une seule ligne, six colonnes : c'est le resume que l'on lit en premier.
# L'autonomie se calcule sur la maison SANS la voiture, sinon une grosse charge
# solaire du vehicule gonfle artificiellement le taux.
# Le bilan sort en LIGNES (une par grandeur), pas en colonnes.
# Le bilan sort en COLONNES : le tableau rend une ligne d'en-tetes et une ligne
# de valeurs, ce qui est la forme la plus lisible pour un resume.
#
# ⚠️ Quatre tentatives ont echoue avec un panneau `stat` alimente par une seule
# ligne a sept colonnes : il affichait sept « — » alors que l'API `/api/ds/query`
# montrait que le serveur lui renvoyait bien sept champs de type number avec
# leurs valeurs. Ce n'etait donc ni la requete, ni le cache, ni le provisioning
# (md5 du fichier servi et version en base verifies) : le panneau recevait les
# donnees et ne les rendait pas. Un tableau, lui, affiche toujours ce qu'il
# recoit — et le format « une ligne par grandeur » se lit tres bien pour un
# bilan. L'unite est portee par le libelle, ce qui permet de melanger kWh et %.
BILAN_TOTAUX = BILAN_BASE + """,
totaux AS (
SELECT sum(pv) AS pv, sum(maison) AS maison, sum(reseau) AS reseau,
sum(voiture) AS voiture,
sum(greatest(batterie, 0)) AS bat_plus,
sum(greatest(-batterie, 0)) AS bat_moins
FROM report
)
SELECT x.rang, x.grandeur AS "Grandeur", x.valeur AS "Valeur"
FROM totaux, LATERAL (VALUES
(1, 'Solaire produit (kWh)', round((pv / 60.0 / 1000.0)::numeric, 1)),
(2, 'Maison consommee (kWh)', round((maison / 60.0 / 1000.0)::numeric, 1)),
(3, 'Reseau importe (kWh)', round((reseau / 60.0 / 1000.0)::numeric, 1)),
(4, 'Voiture (kWh)', round((voiture / 60.0 / 1000.0)::numeric, 1)),
(5, 'Batterie chargee (kWh)', round((bat_plus / 60.0 / 1000.0)::numeric, 1)),
(6, 'Batterie rendue (kWh)', round((bat_moins/ 60.0 / 1000.0)::numeric, 1)),
(7, 'Autonomie (%)', round((100.0 * greatest(maison - reseau, 0)
/ nullif(maison, 0))::numeric, 0))
) AS x(rang, grandeur, valeur)
ORDER BY x.rang"""
# ⚠️ C'est un panneau `table`, PAS un `stat`. Quatre tentatives avec un `stat`
# sur exactement cette requete ont affiche sept « — » alors que l'API
# `/api/ds/query` montrait que le serveur lui renvoyait bien sept champs de type
# number avec leurs valeurs. Ce n'etait ni la requete, ni le cache, ni le
# provisioning (md5 du fichier servi et version en base verifies) : le panneau
# recevait les donnees et ne les rendait pas. Ne pas repasser en `stat`.
#
# ⚠️ Le `GROUP BY (1 = 1)` reste necessaire — un agregat global sans GROUP BY
# rendait un resultat vide cote Grafana. PostgreSQL refuse `GROUP BY true`
# (non-integer constant) mais accepte cette forme, qui n'impose aucune colonne
# dans le SELECT.
BILAN_TOTAUX = BILAN_BASE + """SELECT
round((sum(pv) / 60.0 / 1000.0)::numeric, 1) AS "Solaire produit",
round((sum(maison) / 60.0 / 1000.0)::numeric, 1) AS "Maison consommee",
round((sum(reseau) / 60.0 / 1000.0)::numeric, 1) AS "Reseau importe",
round((sum(voiture) / 60.0 / 1000.0)::numeric, 1) AS "Voiture",
round((sum(greatest(batterie, 0)) / 60.0 / 1000.0)::numeric, 1) AS "Batterie chargee",
round((sum(greatest(-batterie, 0)) / 60.0 / 1000.0)::numeric, 1) AS "Batterie rendue",
round((100.0 * greatest(sum(maison) - sum(reseau), 0)
/ nullif(sum(maison), 0))::numeric, 0) AS "Autonomie"
FROM report GROUP BY (1 = 1)"""
BILAN_FLUX = BILAN_BASE + """SELECT t AS time,
pv AS "Production solaire",
@@ -1320,16 +1314,29 @@ journee = dashboard(
"Les energies sont integrees depuis les puissances mesurees.",
[
table("Le bilan depuis minuit", [sql("A", BILAN_TOTAUX, fmt="table")],
PG, 0, 0, 24, 5,
desc="Sept grandeurs, une par ligne. L'autonomie est la part de la "
"consommation de la maison qui n'est PAS venue du reseau. "
PG, 0, 0, 24, 4,
desc="Une ligne d'en-tetes, une ligne de valeurs. L'autonomie est la part "
"de la consommation de la maison qui n'est PAS venue du reseau. "
"« Batterie rendue » est ce qu'elle a restitue, donc du solaire "
"differe et non une consommation supplementaire.",
overrides=[sur("rang", [{"id": "custom.hidden", "value": True}]),
sur("Grandeur", [{"id": "custom.width", "value": 230}]),
sur("Valeur", [{"id": "custom.cellOptions",
"value": {"type": "color-text"}},
{"id": "decimals", "value": 1}])]),
overrides=[sur(n, [{"id": "unit", "value": "kwatth"},
{"id": "decimals", "value": 1}]) for n in
("Solaire produit", "Maison consommee", "Voiture",
"Batterie chargee", "Batterie rendue")]
+ [sur("Reseau importe", [{"id": "unit", "value": "kwatth"},
{"id": "decimals", "value": 1},
{"id": "custom.cellOptions",
"value": {"type": "color-text"}},
{"id": "thresholds", "value": seuils(
("green", None), ("#EAB839", 3),
("orange", 8))}]),
sur("Autonomie", [{"id": "unit", "value": "percent"},
{"id": "decimals", "value": 0},
{"id": "custom.cellOptions",
"value": {"type": "color-background"}},
{"id": "thresholds", "value": seuils(
("red", None), ("#EAB839", 60),
("green", 85))}])]),
# ⚠️ PAS de FILTRE_VUE ici : cette transformation ne garde que les colonnes
# nommees par la variable $vue de « Le systeme ». Sur un tableau qui n'a pas