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:
@@ -30,7 +30,7 @@ import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import pg from 'pg';
|
||||
import { texteRapport, envoyer, donneesNuit, texteDepuis } from './rapport-nuit.mjs';
|
||||
import { diagnosticPv, etatCellules, productionJour, chargeSolaire, bilanNuit, etatReseau, importJour, minuitLocal, COMPTEURS_IMPORT, COMPTEUR_EDF, consoJour, COMPTEURS_CONSO, projectionSoir, previsionNuit, vrmVersCourbes } from './diagnostics-agent.mjs';
|
||||
import { diagnosticPv, etatCellules, productionJour, chargeSolaire, bilanNuit, etatReseau, importJour, minuitLocal, COMPTEURS_IMPORT, COMPTEUR_EDF, consoJour, COMPTEURS_CONSO, projectionSoir, previsionNuit, vrmVersCourbes, nuitMaisonPrevue } from './diagnostics-agent.mjs';
|
||||
|
||||
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const ONCE = process.argv.includes('--once');
|
||||
@@ -1994,6 +1994,43 @@ async function publierPrevisionVrm(sql) {
|
||||
return n;
|
||||
}
|
||||
|
||||
// La nuit de la maison prevue par la soiree (28/09/2026). Les nuits closes
|
||||
// viennent de la MEME requete que le tableau Grafana « La nuit »
|
||||
// (tools/nuits-maison.sql) : un seul calcul, deux lecteurs. Le bilan lit le
|
||||
// FACTEUR (nuit prevue / nuit moyenne) pour recaler son profil de 21:30 a 09:00.
|
||||
const NUITS_SQL = fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), 'nuits-maison.sql'), 'utf8');
|
||||
const SOIREE_SQL = `
|
||||
WITH pts AS (
|
||||
SELECT cle, ts, valeur,
|
||||
least(coalesce(lead(ts) OVER (PARTITION BY cle ORDER BY ts), now()), ts + interval '1 hour') AS fin
|
||||
FROM mesure WHERE cle IN ('sensor.victron_consumption_power_l1', 'sensor.victron_evcs_ac_power')
|
||||
AND ts > to_timestamp($1 / 1000.0) - interval '2 hours' AND ts < to_timestamp($2 / 1000.0)
|
||||
)
|
||||
SELECT sum(valeur * extract(epoch FROM least(fin, to_timestamp($2 / 1000.0)) - greatest(ts, to_timestamp($1 / 1000.0)))
|
||||
* CASE WHEN cle = 'sensor.victron_evcs_ac_power' THEN -1 ELSE 1 END) / 3.6e6 AS kwh,
|
||||
count(*) FILTER (WHERE cle = 'sensor.victron_consumption_power_l1') AS points
|
||||
FROM pts WHERE fin > to_timestamp($1 / 1000.0)`;
|
||||
let nuitMaisonPubliee = false;
|
||||
async function publierNuitMaison(client) {
|
||||
if (DRY || !client) return 0;
|
||||
const maintenant = new Date();
|
||||
const cadre = nuitMaisonPrevue([], NaN, maintenant);
|
||||
let res = cadre;
|
||||
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 soir = (await client.query(SOIREE_SQL, [debut - 3.5 * 3600000, debut])).rows[0];
|
||||
// Une soiree sans mesure (service arrete) ne vaut pas zero kWh.
|
||||
const soiree = soir && Number(soir.points) > 0 ? Number(soir.kwh) : NaN;
|
||||
res = nuitMaisonPrevue(nuits, soiree, maintenant);
|
||||
}
|
||||
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',
|
||||
unit_of_measurement: typeof res.etat === 'number' ? 'kWh' : undefined, ...res.attributs,
|
||||
calcule_a: maintenant.toISOString(),
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
let bilanNuitPublie = false; // publie des le premier cycle, puis toutes les 5 min
|
||||
async function publierBilanNuit(client) {
|
||||
if (DRY || !client) return 0;
|
||||
@@ -2095,6 +2132,9 @@ async function cycle(client) {
|
||||
vrm: (DRY || (vrmPublie && new Date().getMinutes() % 15 !== 7)) ? 0 : await publierPrevisionVrm(sql).then((n) => { vrmPublie = true; return n; }).catch((e) => {
|
||||
console.error(`prevision VRM : ${e.message}`); return 0;
|
||||
}),
|
||||
nuitMaison: (DRY || (nuitMaisonPubliee && new Date().getMinutes() % 5 !== 2)) ? 0 : await publierNuitMaison(client).then((n) => { nuitMaisonPubliee = true; return n; }).catch((e) => {
|
||||
console.error(`nuit de la maison : ${e.message}`); return 0;
|
||||
}),
|
||||
bilanNuit: (DRY || (bilanNuitPublie && new Date().getMinutes() % 5 !== 1)) ? 0 : await publierBilanNuit(client).then((n) => { bilanNuitPublie = true; return n; }).catch((e) => {
|
||||
console.error(`bilan de nuit : ${e.message}`); return 0;
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user