Bilan : la nuit prevue suit la soiree reelle (regression sur 24 nuits), nuage Grafana corrige
Le service publie le facteur nuit prevue / nuit moyenne (sensor.evcs_nuit_maison_prevue_kwh), le bilan l'applique a son profil de 21:30 a 09:00. Diagnostics 81/81, bilan 68/68. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011uJ47NxgfpGnuuMr3f2n7Z
This commit is contained in:
@@ -217,13 +217,17 @@ PREVISION_A_VENIR = """
|
||||
# changement), plafond 1 h pour qu'un trou n'extrapole rien — meme methode que
|
||||
# le rapport de nuit (§76). « Maison » = consommation AC moins la voiture.
|
||||
# Chiffres verifies contre un calcul independant (script) le 28/09 : identiques.
|
||||
NUITS_CTE = pathlib.Path(__file__).with_name('grafana-nuits.sql').read_text()
|
||||
NUITS_CTE = pathlib.Path(__file__).with_name('nuits-maison.sql').read_text()
|
||||
PROFIL_SQL = pathlib.Path(__file__).with_name('grafana-profil-horaire.sql').read_text()
|
||||
|
||||
def nuits_sql(select):
|
||||
return NUITS_CTE.rstrip() + "\n" + select
|
||||
|
||||
CE_SOIR = """,
|
||||
# UNE seule trame, colonnes X puis Y (mapping automatique : premiere colonne
|
||||
# numerique = X). La premiere version (4 requetes, mapping manuel par trame)
|
||||
# affichait « Err » dans Grafana 11.3. La droite est calculee pour CHAQUE nuit :
|
||||
# elle passe par toutes les abscisses, donc aucun trou ne la coupe.
|
||||
NUAGE = """,
|
||||
f AS (
|
||||
SELECT ((CASE WHEN (now() AT TIME ZONE 'Europe/Paris')::time >= time '18:00'
|
||||
THEN (now() AT TIME ZONE 'Europe/Paris')::date
|
||||
@@ -236,17 +240,19 @@ soir AS (
|
||||
WHEN p.cle = 'sensor.victron_consumption_power_l1' THEN 1 ELSE 0 END) / 3.6e6 AS kwh
|
||||
FROM pts p, f
|
||||
WHERE p.fin > f.s0 AND p.ts < least(f.s0 + interval '3 hours 30 minutes', now())
|
||||
)
|
||||
SELECT round(s.kwh::numeric, 2) AS "Soiree",
|
||||
round((regr_intercept(maison_nuit_kwh, soiree_kwh) + regr_slope(maison_nuit_kwh, soiree_kwh) * s.kwh)::numeric, 2) AS "Ce soir (prevu)"
|
||||
FROM nuits, soir s GROUP BY s.kwh"""
|
||||
|
||||
DROITE = """
|
||||
SELECT v.x AS "Soiree", round((r.a + r.b * v.x)::numeric, 2) AS "Regression"
|
||||
FROM (SELECT regr_intercept(maison_nuit_kwh, soiree_kwh) AS a, regr_slope(maison_nuit_kwh, soiree_kwh) AS b,
|
||||
min(soiree_kwh) AS lo, max(soiree_kwh) AS hi FROM nuits) r,
|
||||
LATERAL (VALUES (r.lo), (r.hi)) v(x)
|
||||
ORDER BY 1"""
|
||||
),
|
||||
r AS (SELECT regr_intercept(maison_nuit_kwh, soiree_kwh) AS a, regr_slope(maison_nuit_kwh, soiree_kwh) AS b FROM nuits)
|
||||
SELECT soiree_kwh::float8 AS "Soiree",
|
||||
CASE WHEN voiture_kwh < 0.5 THEN maison_nuit_kwh END::float8 AS "Nuit sans voiture",
|
||||
CASE WHEN voiture_kwh >= 0.5 THEN maison_nuit_kwh END::float8 AS "Nuit avec voiture",
|
||||
round((r.a + r.b * soiree_kwh)::numeric, 2)::float8 AS "Regression",
|
||||
NULL::float8 AS "Ce soir (prevu)"
|
||||
FROM nuits, r
|
||||
UNION ALL
|
||||
SELECT round(s.kwh::numeric, 2)::float8, NULL, NULL, round((r.a + r.b * s.kwh)::numeric, 2)::float8,
|
||||
round((r.a + r.b * s.kwh)::numeric, 2)::float8
|
||||
FROM soir s, r
|
||||
ORDER BY 1"""
|
||||
|
||||
NUIT_XY = {"type": "xychart", "title": "Soiree contre nuit : le nuage des nuits",
|
||||
"description": ("Un point = une nuit. En abscisse ce que la maison a consomme de 18:00 a "
|
||||
@@ -255,13 +261,7 @@ NUIT_XY = {"type": "xychart", "title": "Soiree contre nuit : le nuage des nuits"
|
||||
"est CE SOIR, place sur la droite : une prevision, pas une mesure. "
|
||||
"1 point de SOC = 0,30 kWh sur le parc actuel."),
|
||||
"datasource": PG, "gridPos": {"x": 0, "y": 32, "w": 14, "h": 11},
|
||||
"targets": [
|
||||
sql("A", nuits_sql('SELECT soiree_kwh AS "Soiree", maison_nuit_kwh AS "Nuit sans voiture" '
|
||||
'FROM nuits WHERE voiture_kwh < 0.5 ORDER BY 1'), fmt="table"),
|
||||
sql("B", nuits_sql('SELECT soiree_kwh AS "Soiree", maison_nuit_kwh AS "Nuit avec voiture" '
|
||||
'FROM nuits WHERE voiture_kwh >= 0.5 ORDER BY 1'), fmt="table"),
|
||||
sql("C", nuits_sql(DROITE), fmt="table"),
|
||||
sql("D", NUITS_CTE.rstrip() + CE_SOIR, fmt="table")],
|
||||
"targets": [sql("A", NUITS_CTE.rstrip() + NUAGE, fmt="table")],
|
||||
"fieldConfig": {"defaults": {"unit": "kwatth", "color": {"mode": "palette-classic"},
|
||||
"custom": {"show": "points", "pointSize": {"fixed": 9}, "pointShape": "circle",
|
||||
"lineWidth": 2, "fillOpacity": 60}},
|
||||
@@ -276,12 +276,7 @@ NUIT_XY = {"type": "xychart", "title": "Soiree contre nuit : le nuage des nuits"
|
||||
{"matcher": {"id": "byName", "options": "Ce soir (prevu)"},
|
||||
"properties": [{"id": "color", "value": {"mode": "fixed", "fixedColor": "red"}},
|
||||
{"id": "custom.pointSize", "value": {"fixed": 18}}]}]},
|
||||
"options": {"mapping": "manual",
|
||||
"series": [{"frame": {"matcher": {"id": "byIndex", "options": i}},
|
||||
"x": {"matcher": {"id": "byName", "options": "Soiree"}},
|
||||
"y": {"matcher": {"id": "byName", "options": n}}}
|
||||
for i, n in enumerate(["Nuit sans voiture", "Nuit avec voiture",
|
||||
"Regression", "Ce soir (prevu)"])],
|
||||
"options": {"mapping": "auto", "series": [{}],
|
||||
"legend": {"showLegend": True, "displayMode": "list", "placement": "bottom"},
|
||||
"tooltip": {"mode": "single", "sort": "none"}}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user