HA Bilan energetique : nuage soiree/nuit (ApexCharts), points publies dans sensor.evcs_nuit_maison_prevue_kwh
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:
@@ -247,6 +247,81 @@ views:
|
|||||||
pleine à cette heure : au-delà de 25 %, la production maximale
|
pleine à cette heure : au-delà de 25 %, la production maximale
|
||||||
observée est minorée et le bilan le signale.*
|
observée est minorée et le bilan le signale.*
|
||||||
|
|
||||||
|
# Nuage soiree / nuit (28/09/2026) : meme donnees que Grafana « La nuit »,
|
||||||
|
# publiees par le service d'historisation dans sensor.evcs_nuit_maison_prevue_kwh
|
||||||
|
# (attribut `nuage` = [soiree, nuit, voiture 0/1]). Graphique « ligne » a trait
|
||||||
|
# nul + marqueurs = nuage de points ; axe X numerique (kWh), pas le temps.
|
||||||
|
- type: custom:apexcharts-card
|
||||||
|
header:
|
||||||
|
show: true
|
||||||
|
title: Soirée contre nuit — la soirée annonce la nuit
|
||||||
|
show_states: false
|
||||||
|
graph_span: 1d
|
||||||
|
apex_config:
|
||||||
|
chart:
|
||||||
|
height: 300
|
||||||
|
zoom: {enabled: false}
|
||||||
|
xaxis:
|
||||||
|
type: numeric
|
||||||
|
min: 2
|
||||||
|
max: 10.5
|
||||||
|
tickAmount: 8
|
||||||
|
decimalsInFloat: 1
|
||||||
|
title: {text: 'Soirée 18:00-21:30 (kWh, voiture exclue)'}
|
||||||
|
yaxis:
|
||||||
|
- min: 7
|
||||||
|
max: 16
|
||||||
|
decimalsInFloat: 0
|
||||||
|
title: {text: 'Nuit 21:30-09:00 (kWh)'}
|
||||||
|
markers:
|
||||||
|
size: [6, 6, 0, 11]
|
||||||
|
tooltip:
|
||||||
|
x:
|
||||||
|
formatter: 'EVAL:function(v) { return "soirée " + v.toFixed(2) + " kWh"; }'
|
||||||
|
legend:
|
||||||
|
show: true
|
||||||
|
series:
|
||||||
|
- entity: sensor.evcs_nuit_maison_prevue_kwh
|
||||||
|
name: Nuit sans voiture
|
||||||
|
type: line
|
||||||
|
stroke_width: 0
|
||||||
|
color: '#4caf50'
|
||||||
|
data_generator: |
|
||||||
|
return (entity.attributes.nuage || []).filter(p => !p[2])
|
||||||
|
.map(p => [p[0], p[1]]).sort((a, b) => a[0] - b[0]);
|
||||||
|
- entity: sensor.evcs_nuit_maison_prevue_kwh
|
||||||
|
name: Nuit avec voiture
|
||||||
|
type: line
|
||||||
|
stroke_width: 0
|
||||||
|
color: '#2196f3'
|
||||||
|
data_generator: |
|
||||||
|
return (entity.attributes.nuage || []).filter(p => p[2])
|
||||||
|
.map(p => [p[0], p[1]]).sort((a, b) => a[0] - b[0]);
|
||||||
|
- entity: sensor.evcs_nuit_maison_prevue_kwh
|
||||||
|
name: Régression
|
||||||
|
type: line
|
||||||
|
stroke_width: 2
|
||||||
|
color: '#ff9800'
|
||||||
|
data_generator: |
|
||||||
|
const a = entity.attributes.a, b = entity.attributes.b, n = entity.attributes.nuage || [];
|
||||||
|
if (a === null || b === null || !n.length) return [];
|
||||||
|
const xs = n.map(p => p[0]), lo = Math.min(...xs), hi = Math.max(...xs);
|
||||||
|
return [[lo, a + b * lo], [hi, a + b * hi]];
|
||||||
|
- entity: sensor.evcs_nuit_maison_prevue_kwh
|
||||||
|
name: Ce soir (prévu)
|
||||||
|
type: line
|
||||||
|
stroke_width: 0
|
||||||
|
color: '#f44336'
|
||||||
|
data_generator: |
|
||||||
|
const s = entity.attributes.soiree_kwh, v = parseFloat(entity.state);
|
||||||
|
return (s !== null && s !== undefined && !isNaN(v)) ? [[s, v]] : [];
|
||||||
|
|
||||||
|
- type: markdown
|
||||||
|
content: |
|
||||||
|
{% set s = 'sensor.evcs_nuit_maison_prevue_kwh' %}
|
||||||
|
{% if is_number(states(s)) %}**Cette nuit** : soirée {{ state_attr(s, 'soiree_kwh') }} kWh → nuit prévue **{{ states(s) }} kWh** (moyenne {{ state_attr(s, 'nuit_moyenne_kwh') }}), soit **×{{ state_attr(s, 'facteur') }}** sur le profil du bilan.{% else %}Hors de la fenêtre 21:30 → 09:00 : pas de prévision de nuit en cours.{% endif %}
|
||||||
|
Modèle sur {{ state_attr(s, 'nuits') }} nuits : nuit = {{ state_attr(s, 'a') }} + {{ state_attr(s, 'b') }} × soirée (r² {{ state_attr(s, 'r2') }}).
|
||||||
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
content: |
|
content: |
|
||||||
### ⚠️ Taille du parc — en équivalents US2000C
|
### ⚠️ Taille du parc — en équivalents US2000C
|
||||||
|
|||||||
@@ -2015,19 +2015,23 @@ async function publierNuitMaison(client) {
|
|||||||
if (DRY || !client) return 0;
|
if (DRY || !client) return 0;
|
||||||
const maintenant = new Date();
|
const maintenant = new Date();
|
||||||
const cadre = nuitMaisonPrevue([], NaN, maintenant);
|
const cadre = nuitMaisonPrevue([], NaN, maintenant);
|
||||||
let res = cadre;
|
// Les nuits closes sont lues A CHAQUE fois, meme le jour : elles alimentent
|
||||||
|
// aussi le nuage du tableau HA (attribut `nuage`, [soiree, nuit, voiture 0/1]).
|
||||||
|
const nuits = (await client.query(NUITS_SQL +
|
||||||
|
'\nSELECT soiree_kwh AS soiree, maison_nuit_kwh AS nuit, voiture_kwh AS voiture FROM nuits ORDER BY j')).rows;
|
||||||
|
let soiree = NaN;
|
||||||
if (cadre.etat !== 'hors_fenetre') {
|
if (cadre.etat !== 'hors_fenetre') {
|
||||||
const nuits = (await client.query(NUITS_SQL + '\nSELECT soiree_kwh AS soiree, maison_nuit_kwh AS nuit FROM nuits')).rows;
|
|
||||||
const debut = cadre.attributs.debut_ms;
|
const debut = cadre.attributs.debut_ms;
|
||||||
const soir = (await client.query(SOIREE_SQL, [debut - 3.5 * 3600000, debut])).rows[0];
|
const soir = (await client.query(SOIREE_SQL, [debut - 3.5 * 3600000, debut])).rows[0];
|
||||||
// Une soiree sans mesure (service arrete) ne vaut pas zero kWh.
|
// Une soiree sans mesure (service arrete) ne vaut pas zero kWh.
|
||||||
const soiree = soir && Number(soir.points) > 0 ? Number(soir.kwh) : NaN;
|
soiree = soir && Number(soir.points) > 0 ? Number(soir.kwh) : NaN;
|
||||||
res = nuitMaisonPrevue(nuits, soiree, maintenant);
|
|
||||||
}
|
}
|
||||||
|
const res = nuitMaisonPrevue(nuits, soiree, maintenant);
|
||||||
|
const nuage = nuits.map((n) => [Number(n.soiree), Number(n.nuit), Number(n.voiture) >= 0.5 ? 1 : 0]);
|
||||||
await publierCapteur('sensor.evcs_nuit_maison_prevue_kwh', res.etat, {
|
await publierCapteur('sensor.evcs_nuit_maison_prevue_kwh', res.etat, {
|
||||||
friendly_name: 'EVCS — nuit de la maison prevue par la soiree', icon: 'mdi:chart-scatter-plot',
|
friendly_name: 'EVCS — nuit de la maison prevue par la soiree', icon: 'mdi:chart-scatter-plot',
|
||||||
unit_of_measurement: typeof res.etat === 'number' ? 'kWh' : undefined, ...res.attributs,
|
unit_of_measurement: typeof res.etat === 'number' ? 'kWh' : undefined, ...res.attributs,
|
||||||
calcule_a: maintenant.toISOString(),
|
nuage, calcule_a: maintenant.toISOString(),
|
||||||
});
|
});
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user