sensor.evcs_prevision_nuit : la nuit a venir, uniquement depuis le bilan et des etats lus
Incident 27-28/09 : l'agent presentait le surplus solaire de demain comme de l'energie batterie et lisait une projection de jour du controleur la nuit. Ce capteur ne relaie que le bilan (meme arbitre que la decision de nuit) ; bilan > 30 min -> indisponible. Tests 65/65. 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:
@@ -2,7 +2,7 @@
|
||||
// Les cas PV reprennent les gammes du banc OpenClaw (HANDOFF §77) : G3, G4, G5, G7.
|
||||
// node tests/diagnostics-agent/run.mjs
|
||||
import fs from 'node:fs';
|
||||
import { diagnosticPv, etatCellules, productionJour, chargeSolaire, bilanNuit, etatReseau, importJour, COMPTEURS_IMPORT, COMPTEUR_EDF, MPPT_MODES, ORIGINE_PAR_SOURCE, consoJour, COMPTEURS_CONSO, projectionSoir } from '../../tools/diagnostics-agent.mjs';
|
||||
import { diagnosticPv, etatCellules, productionJour, chargeSolaire, bilanNuit, etatReseau, importJour, COMPTEURS_IMPORT, COMPTEUR_EDF, MPPT_MODES, ORIGINE_PAR_SOURCE, consoJour, COMPTEURS_CONSO, projectionSoir, previsionNuit } from '../../tools/diagnostics-agent.mjs';
|
||||
|
||||
const LIM = 'voltage_current_limited', ACT = 'mppt_active';
|
||||
function st({ pv, conso, reseau, soc = 80, courant = 0, edf = 'off', modes }) {
|
||||
@@ -287,6 +287,36 @@ for (const [nom, r, test] of imp) {
|
||||
globalThis.__nConso = (globalThis.__nConso || 0) + pj.length;
|
||||
}
|
||||
|
||||
// --- Prevision de la nuit : releve reel du 28/09 01:25 ----------------------
|
||||
{
|
||||
const base = () => new Map(Object.entries({
|
||||
'input_text.evcs_balance_status': 'ok', 'input_text.evcs_balance_last_run': '28/09 01:25',
|
||||
'input_number.evcs_balance_energy_to_cover_kwh': '5.47', 'input_number.evcs_balance_grid_energy_needed_kwh': '5.77',
|
||||
'input_boolean.evcs_balance_grid_needed': 'on', 'input_text.evcs_balance_crossing_hour': '09 h',
|
||||
'input_number.evcs_balance_required_soc': '40.2', 'sensor.victron_battery_soc': '21',
|
||||
'sensor.evcs_reseau': 'raccorde', 'input_boolean.victron_evcs_night_grid_session_committed': 'on',
|
||||
'binary_sensor.victron_evcs_vehicle_connected': 'off',
|
||||
// pieges : valeurs internes qui ne doivent JAMAIS apparaitre
|
||||
'input_number.victron_evcs_projected_end_soc_after_charge': '73.7', 'input_number.evcs_balance_vehicle_surplus_kwh': '26.95',
|
||||
}).map(([k, v]) => [k, { state: v }]));
|
||||
const t = new Date('2026-09-27T23:30:00Z'); // 01:30 a Paris
|
||||
const pn = [
|
||||
['nuit 28/09 : 5,77 kWh EDF, 5,47 a couvrir, retour 09 h, aucune voiture', previsionNuit(base(), t),
|
||||
(r) => r.etat === 5.77 && r.attributs.voiture === 'aucune' && /5.77 kWh a prendre sur EDF/.test(r.attributs.explication)],
|
||||
['jamais 73,7 ni 26,95 dans la prevision (incident 27/09)', previsionNuit(base(), t),
|
||||
(r) => !/73\.7|26\.95/.test(JSON.stringify(r))],
|
||||
['bilan perime (> 30 min) -> indisponible', previsionNuit(base(), new Date('2026-09-28T00:30:00Z')),
|
||||
(r) => r.etat === 'indisponible'],
|
||||
['reseau non necessaire -> 0 et « la batterie suffit »', (() => { const m = base(); m.set('input_boolean.evcs_balance_grid_needed', { state: 'off' }); return previsionNuit(m, t); })(),
|
||||
(r) => r.etat === 0 && /batterie suffit/.test(r.attributs.explication)],
|
||||
];
|
||||
for (const [nom, r, test] of pn) {
|
||||
const ok = test(r); if (!ok) { ko++; console.log(JSON.stringify(r)); }
|
||||
console.log(`${ok ? 'OK ' : 'KO '} ${nom}`);
|
||||
}
|
||||
globalThis.__nConso = (globalThis.__nConso || 0) + pn.length;
|
||||
}
|
||||
|
||||
const n = (globalThis.__nConso || 0) + cas.length + cel.length + prod.length + charge.length + 1 + bn.length + res.length + imp.length;
|
||||
console.log(`\n${n - ko}/${n}`);
|
||||
process.exit(ko ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user