Budget voiture de la nuit : annonce dans la prevision, cartes Bilan energetique (Production) et EVCS Master

This commit is contained in:
Tallagrand Thierry
2026-09-30 15:01:31 +02:00
parent e0d855f33f
commit ae380da696
5 changed files with 110 additions and 10 deletions

View File

@@ -1265,10 +1265,17 @@ autoriser une charge complete avec EDF.** Decisions (30/09) : profil **prudent +
bande de SOC (-30 A en 40-60 %, -15 A en 25-40 %, valeurs fixes) : a SOC moyen la voiture bande de SOC (-30 A en 40-60 %, -15 A en 25-40 %, valeurs fixes) : a SOC moyen la voiture
ne tire qu'environ 1 kW, et un budget peut ne pas etre entierement delivre en 6 h. ne tire qu'environ 1 kW, et un budget peut ne pas etre entierement delivre en 6 h.
- P9 (reseau avant depart) est OFF chez le proprietaire : non touche. - P9 (reseau avant depart) est OFF chez le proprietaire : non touche.
- **A faire** : annoncer le budget et le mode dans `sensor.evcs_prevision_nuit` (lu par - **Fait le 30/09 apres-midi** (accord du proprietaire) : `sensor.evcs_prevision_nuit`
l'agent) ; commande vocale « charge complete cette nuit » (SPARK, ecriture du seul annonce le budget et le reglage (« La voiture peut prendre environ 6,3 kWh sur la batterie
`input_select.victron_evcs_night_charge_mode`) ; carte sur EVCS Master ; verifier la sans EDF, puis elle s'arrete et attend le soleil (reglage « sans EDF ») » ; en session, le
premiere nuit reelle (budget fige, arret, raison). budget FIGE et « Deja x kWh donnes ») ; attributs `mode_charge_nuit`, `budget_voiture_kwh`,
`budget_voiture_fige`, `budget_deja_donne_kwh`. Diagnostics 95/95, mutation qui mord.
Cartes : **Bilan energetique, onglet Production (4e)** « Voiture cette nuit — sans EDF ou
charge complete » (reglage, budget prevu, budget fige + deja donne) ; **EVCS Master**,
Parametres utilisateur (reglage + budget). Sauvegardes `*.bak-20260930-budget`.
Commande vocale demandee a SPARK (ecriture du seul `input_select.victron_evcs_night_charge_mode`).
- **A verifier** : la premiere nuit reelle avec voiture branchee (budget fige a 01:24,
arret au compteur, raison publiee).
--- ---
*Document mis a jour le : 30/09/2026 (~13:30) — budget voiture de la nuit sans EDF (bilan + controleur) ; fiche de l'agent allegee (25 831 car.), concierge sans silence, calendrier JEEP mar/sam ; nuit du 28-29 verifiee, achat EDF annonce = maison en HC + manque batterie ; regle HC active, vehicule branche a midi (JEEP/VW/ZERO), prevision de nuit a trois verdicts, nuits superposees et bilan recale sur la soiree* *Document mis a jour le : 30/09/2026 (~13:30) — budget voiture de la nuit sans EDF (bilan + controleur) ; fiche de l'agent allegee (25 831 car.), concierge sans silence, calendrier JEEP mar/sam ; nuit du 28-29 verifiee, achat EDF annonce = maison en HC + manque batterie ; regle HC active, vehicule branche a midi (JEEP/VW/ZERO), prevision de nuit a trois verdicts, nuits superposees et bilan recale sur la soiree*

View File

@@ -472,6 +472,43 @@ views:
path: production path: production
icon: mdi:solar-power icon: mdi:solar-power
cards: cards:
# Budget voiture de la nuit (30/09/2026) : ce que la batterie peut donner
# a la voiture sans EDF ; reglage de la nuit (sans_edf par defaut, remis
# chaque jour a 12:00 ; complete = budget batterie puis EDF en HC).
- type: entities
title: Voiture cette nuit — sans EDF ou charge complète
entities:
- entity: input_select.victron_evcs_night_charge_mode
name: Charge de la voiture cette nuit
- entity: input_number.evcs_balance_night_vehicle_budget_kwh
name: Budget batterie sans EDF (prévu par le bilan)
- entity: input_text.victron_evcs_night_budget
name: Budget figé à 01:24 (budget|index borne)
- type: markdown
content: |
{% set m = states('input_select.victron_evcs_night_charge_mode') %}
{% set b = states('input_number.evcs_balance_night_vehicle_budget_kwh') | float(0) %}
{% set f = states('input_text.victron_evcs_night_budget') %}
{% if '|' in f %}
{% set fb = f.split('|')[0] | float(0) %}
{% set ref = f.split('|')[1] | float(0) %}
{% set c = states('sensor.evcs_hq2239dnt7p_total_energy') | float(ref) %}
**Session en cours** : budget figé **{{ fb | round(1) }} kWh**, déjà
**{{ (c - ref) | round(1) }} kWh** donnés à la voiture.
{% else %}
Cette nuit, la voiture pourra prendre environ **{{ b | round(1) }} kWh**
sur la batterie sans EDF (profil prudent, plancher 22 %, la batterie
tient jusqu'à la nuit suivante).
{% endif %}
{% if m == 'complete' %}
🔌 **Charge complète** : le budget batterie d'abord, puis EDF en heures
creuses pour le reste. Retour automatique à « sans EDF » demain à 12:00.
{% else %}
🔋 **Sans EDF** (par défaut) : la voiture s'arrête au budget et attend le
soleil. Si EDF se ferme de toute façon pour protéger la batterie, elle en
profite en heures creuses.
{% endif %}
# Source de la prevision du bilan (28/09/2026) : VRM en essai, comparaison # Source de la prevision du bilan (28/09/2026) : VRM en essai, comparaison
# prevue le 05/10. Revenir a forecast_solar = retour arriere immediat. # prevue le 05/10. Revenir a forecast_solar = retour arriere immediat.
- type: entities - type: entities

View File

@@ -225,6 +225,10 @@ views:
name: 🔋 Niveau du véhicule branché (à saisir au branchement) name: 🔋 Niveau du véhicule branché (à saisir au branchement)
- entity: input_datetime.victron_evcs_departure_ponctuel - entity: input_datetime.victron_evcs_departure_ponctuel
name: 🕒 Repart aujourd'hui à (départ ponctuel, VW / ZERO) name: 🕒 Repart aujourd'hui à (départ ponctuel, VW / ZERO)
- entity: input_select.victron_evcs_night_charge_mode
name: 🌙 Charge cette nuit (sans EDF = budget batterie seul)
- entity: input_number.evcs_balance_night_vehicle_budget_kwh
name: 🔋 Budget batterie de la nuit sans EDF
- entity: input_datetime.victron_evcs_jeep_midday_departure - entity: input_datetime.victron_evcs_jeep_midday_departure
name: JEEP repart après midi à name: JEEP repart après midi à
- entity: input_text.victron_evcs_jeep_midday_departure_days - entity: input_text.victron_evcs_jeep_midday_departure_days

View File

@@ -438,6 +438,33 @@ for (const [nom, r, test] of imp) {
(r) => r.etat === 'indisponible' && /etat « erreur »/.test(r.attributs.explication)], (r) => r.etat === 'indisponible' && /etat « erreur »/.test(r.attributs.explication)],
['bilan perime -> indisponible, dit depuis combien de temps', previsionNuit(base(), new Date('2026-09-28T00:30:00Z')), ['bilan perime -> indisponible, dit depuis combien de temps', previsionNuit(base(), new Date('2026-09-28T00:30:00Z')),
(r) => r.etat === 'indisponible' && /recalcule depuis 65 min/.test(r.attributs.explication)], (r) => r.etat === 'indisponible' && /recalcule depuis 65 min/.test(r.attributs.explication)],
// Budget voiture de la nuit (30/09) : ce que la batterie peut donner sans EDF.
...(() => {
const nuit = (extra) => { const m = base(); for (const [k, v] of Object.entries({
'input_boolean.victron_evcs_night_grid_session_committed': 'off', 'input_boolean.evcs_balance_grid_needed': 'off',
'input_number.evcs_balance_night_vehicle_budget_kwh': '6.46', ...extra,
})) m.set(k, { state: v }); return previsionNuit(m, t); };
return [
['voiture branchee, sans EDF (defaut) : « environ 6,5 kWh sur la batterie … s arrete »',
nuit({ 'binary_sensor.victron_evcs_vehicle_connected': 'on' }),
(r) => r.attributs.mode_charge_nuit === 'sans_edf' && r.attributs.budget_voiture_kwh === 6.46
&& /Voiture branchee\. La voiture peut prendre environ 6,5 kWh sur la batterie sans EDF, puis elle s arrete/.test(r.attributs.texte_rapport)],
['charge complete demandee : « puis EDF en heures creuses pour le reste »',
nuit({ 'binary_sensor.victron_evcs_vehicle_connected': 'on', 'input_select.victron_evcs_night_charge_mode': 'complete' }),
(r) => r.attributs.mode_charge_nuit === 'complete' && /puis EDF en heures creuses pour le reste/.test(r.attributs.texte_rapport)],
['session : budget FIGE et deja donne (3,7 fige a l index 4000, compteur 4001,2)',
nuit({ 'binary_sensor.victron_evcs_vehicle_connected': 'on', 'input_text.victron_evcs_night_budget': '3.7|4000',
'sensor.evcs_hq2239dnt7p_total_energy': '4001.2' }),
(r) => r.attributs.budget_voiture_fige && r.attributs.budget_voiture_kwh === 3.7 && r.attributs.budget_deja_donne_kwh === 1.2
&& /environ 3,7 kWh/.test(r.attributs.texte_rapport) && /Deja 1,2 kWh donnes/.test(r.attributs.texte_rapport)],
['budget nul, sans EDF : « rien … elle attendra le soleil »',
nuit({ 'binary_sensor.victron_evcs_vehicle_connected': 'on', 'input_number.evcs_balance_night_vehicle_budget_kwh': '0' }),
(r) => /La batterie ne peut rien donner a la voiture cette nuit sans EDF : elle attendra le soleil/.test(r.attributs.texte_rapport)],
['aucune voiture : le budget est annonce pour le cas ou on en branche une',
nuit({ 'binary_sensor.victron_evcs_vehicle_connected': 'off' }),
(r) => /Aucun vehicule branche\. S il y en a un cette nuit : la voiture peut prendre environ 6,5 kWh/.test(r.attributs.texte_rapport)],
];
})(),
['plus jamais d attribut reseau_necessaire_kwh (lu comme un achat le 28/09)', previsionNuit(base(), t), ['plus jamais d attribut reseau_necessaire_kwh (lu comme un achat le 28/09)', previsionNuit(base(), t),
(r) => !('reseau_necessaire_kwh' in r.attributs) && 'import_prevu_kwh' in r.attributs], (r) => !('reseau_necessaire_kwh' in r.attributs) && 'import_prevu_kwh' in r.attributs],
['jamais d attribut qui ressemble a un SOC du matin (incident 21:16)', previsionNuit(base(), t), ['jamais d attribut qui ressemble a un SOC du matin (incident 21:16)', previsionNuit(base(), t),

View File

@@ -652,13 +652,37 @@ export function previsionNuit(st, maintenant = new Date()) {
? ' Sous reserve : l historique de production de ces heures de fin de journee est incomplet (batterie souvent pleine a cette heure) ; la decision reelle est reprise ' + (hcDebut ? `a ${hcDebut}` : 'a l ouverture des heures creuses') + '.' ? ' Sous reserve : l historique de production de ces heures de fin de journee est incomplet (batterie souvent pleine a cette heure) ; la decision reelle est reprise ' + (hcDebut ? `a ${hcDebut}` : 'a l ouverture des heures creuses') + '.'
: ''; : '';
attributs.reserve_bilan = degrade ? 'forme de production minoree sur les heures de deficit' : null; attributs.reserve_bilan = degrade ? 'forme de production minoree sur les heures de deficit' : null;
const voiture = attributs.voiture === 'aucune'
? 'Aucun vehicule branche.'
: attributs.voiture === 'branchee'
? 'Un vehicule est branche : sa charge s ajoute et sera decidee par le controleur.'
: 'Etat du vehicule inconnu.';
const hc = hcDebut ? `a ${hcDebut}` : 'a l ouverture des heures creuses'; const hc = hcDebut ? `a ${hcDebut}` : 'a l ouverture des heures creuses';
const kwh = (x) => String(x).replace('.', ','); const kwh = (x) => String(x).replace('.', ',');
// BUDGET VOITURE DE LA NUIT (30/09) : ce que la batterie peut donner sans EDF,
// et le reglage de la nuit (sans_edf par defaut, complete sur demande). Pendant
// la session, le budget FIGE par le controleur et ce qui a deja ete donne.
const modeNuit = txt('input_select.victron_evcs_night_charge_mode') === 'complete' ? 'complete' : 'sans_edf';
const fige = (txt('input_text.victron_evcs_night_budget') || '').match(/^\s*([\d.]+)\|([\d.]+)\s*$/);
const compteur = nombre(st, 'sensor.evcs_hq2239dnt7p_total_energy');
const budgetPublie = nombre(st, 'input_number.evcs_balance_night_vehicle_budget_kwh');
const budgetKwh = fige ? Number(fige[1]) : budgetPublie;
const dejaDonne = fige && compteur !== null ? Math.max(0, Math.round((compteur - Number(fige[2])) * 10) / 10) : null;
const b = budgetKwh !== null ? kwh(Math.round(budgetKwh * 10) / 10) : null;
const suite = modeNuit === 'complete'
? 'puis EDF en heures creuses pour le reste (charge complete demandee)'
: 'puis elle s arrete et attend le soleil (reglage « sans EDF »)';
const phraseBudget = b === null ? ''
: budgetKwh < 0.1
? (modeNuit === 'complete'
? 'La batterie ne peut rien donner a la voiture cette nuit : EDF la chargera en heures creuses (charge complete demandee).'
: 'La batterie ne peut rien donner a la voiture cette nuit sans EDF : elle attendra le soleil (reglage « sans EDF »).')
: `La voiture peut prendre environ ${b} kWh sur la batterie sans EDF, ${suite}.` +
(dejaDonne !== null ? ` Deja ${kwh(dejaDonne)} kWh donnes.` : '');
attributs.mode_charge_nuit = modeNuit;
attributs.budget_voiture_kwh = budgetKwh;
attributs.budget_voiture_fige = !!fige;
attributs.budget_deja_donne_kwh = dejaDonne;
const voiture = attributs.voiture === 'aucune'
? 'Aucun vehicule branche.' + (phraseBudget ? ` S il y en a un cette nuit : ${phraseBudget.charAt(0).toLowerCase()}${phraseBudget.slice(1)}` : '')
: attributs.voiture === 'branchee'
? (phraseBudget ? `Voiture branchee. ${phraseBudget}` : 'Un vehicule est branche : sa charge s ajoute et sera decidee par le controleur.')
: 'Etat du vehicule inconnu.';
const jusqua = hcFin ? `jusqu a ${hcFin}` : 'jusqu a la fin des heures creuses'; const jusqua = hcFin ? `jusqu a ${hcFin}` : 'jusqu a la fin des heures creuses';
const plage = hcDebut && hcFin ? `de ${hcDebut} a ${hcFin}` : 'en heures creuses'; const plage = hcDebut && hcFin ? `de ${hcDebut} a ${hcFin}` : 'en heures creuses';
const detail = maisonHcKwh === null ? '' const detail = maisonHcKwh === null ? ''
@@ -693,7 +717,8 @@ export function previsionNuit(st, maintenant = new Date()) {
const achatSi = maisonHcKwh !== null const achatSi = maisonHcKwh !== null
? ` Si EDF s engage ${hc}, la maison y achetera environ ${kwh(Math.round(maisonHcKwh * 10) / 10)} kWh ${jusqua}.` : ''; ? ` Si EDF s engage ${hc}, la maison y achetera environ ${kwh(Math.round(maisonHcKwh * 10) / 10)} kWh ${jusqua}.` : '';
const texteJour = `Il est trop tot pour la prevision de la nuit : elle se calcule le soir, sur la consommation reelle ` + const texteJour = `Il est trop tot pour la prevision de la nuit : elle se calcule le soir, sur la consommation reelle ` +
`de la soiree, et la decision d EDF se prend ${hc}.${repere}${achatSi} Batterie a ${soc !== null ? Math.round(soc) : '?'} % maintenant.`; `de la soiree, et la decision d EDF se prend ${hc}.${repere}${achatSi} Batterie a ${soc !== null ? Math.round(soc) : '?'} % maintenant.` +
(phraseBudget ? ` ${phraseBudget}` : '');
return { etat: 'jour', attributs: { ...attributs, verdict: 'jour', statut: 'jour', return { etat: 'jour', attributs: { ...attributs, verdict: 'jour', statut: 'jour',
prochaine_traversee: m ? `${m[1]} h -> ${m[2]} h` : null, prochaine_traversee: m ? `${m[1]} h -> ${m[2]} h` : null,
prochaine_traversee_soc_requis_pct: m ? ndSoc : null, prochaine_traversee_kwh: m ? ndKwh : null, prochaine_traversee_soc_requis_pct: m ? ndSoc : null, prochaine_traversee_kwh: m ? ndKwh : null,