Le conseiller ne lisait pas mal : on lui parlait mal
Reprise de la campagne apres la specialisation en observateur. Le harnais affichait encore `strategy` et `night_target_soc`, deux champs que l observateur n emet plus : il mesurait des undefined. Reecrit pour noter ce qui compte chez un observateur — la gravite tombe-t-elle dans la fourchette attendue, et a-t-il NOMME la chose, par des mots-cles choisis hors du vocabulaire du prompt. Quatre defauts trouves, aucun n etant un defaut de raisonnement du modele : - « Contacteur FERME » : pour un relais, ferme veut dire qui laisse passer. Le modele l a lu comme coupe et a demande, reseau present, « pourquoi le contacteur reste FERME alors que le bilan juge le reseau necessaire ». - Le signe de l excedent : le prompt affichait « 14 W », il a ecrit « negatif (-14 W) » — et sur un autre cas « negatif » puis « positif » au passage suivant, sur le MEME prompt. - « day_vehicle_full_idle » ne veut rien dire pour lui : il signalait une ressource refusee sans voir que le vehicule est PLEIN. - Un excedent calcule sous censure ne veut rien dire : sur le BOOST du 11/09 il concluait « pas de soleil, donc le reseau est normal » alors que les 121 W de PV sont bas PARCE QUE la consigne de 8260 W les evince. Plus une grandeur derivee de plus, `consigne - maison`, parce qu il voyait la version flagrante du defaut (SOC 20, 0 A) et manquait la version discrete (SOC 45, +2 A). Elle a d abord fait TOMBER le cas du BOOST, en annoncant « il reste 7005 W pour recharger » comme une bonne nouvelle sur une batterie a 96 % : corrigee en lui faisant dire l inverse quand il n y a rien a recharger, la question ayant deja une reponse dans le bilan. Trois defauts etaient les miens : deux fixtures decrivaient un etat que l installation ne peut pas prendre — c est le conseiller qui l a signale — et un attendu exigeait « haute » la ou l echelle de gravite du prompt ancre elle-meme cet incident sur « moyenne ». Incidents 39/40 au final, contre 23/35 au depart. Les deux cas de vrai silence restent silencieux 5/5. ⚠️ Trouve en marge : cinq helpers du conseiller sont geles depuis la specialisation, et le cablage de la cible SOC matin les lit encore — ses quatre gardes passent toutes, la fraicheur datant le RUN et non la VALEUR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
This commit is contained in:
@@ -107,6 +107,14 @@ const ctx = {
|
||||
// Meme principe que le bilan : on lui donne la grandeur, pas les ingredients.
|
||||
const maisonHorsVoitureW = Math.max(0, ctx.houseW - (ctx.evcsCharging ? ctx.evcsCurrentA * 230 : 0));
|
||||
const excedentSolaireW = Math.round(ctx.pvW - maisonHorsVoitureW);
|
||||
const margeRechargeW = ctx.gridOn && Number.isFinite(ctx.gridSetpointW)
|
||||
? Math.round(ctx.gridSetpointW - maisonHorsVoitureW)
|
||||
: null;
|
||||
// Le bilan dit lui-meme si la batterie doit monter. A defaut de bilan
|
||||
// exploitable on ne tranche pas, et la marge reste un simple constat.
|
||||
const batterieDoitMonter = Number.isFinite(ctx.balanceRequiredSoc) && Number.isFinite(ctx.soc)
|
||||
? ctx.soc < ctx.balanceRequiredSoc
|
||||
: null;
|
||||
const margeDechargeA = Number.isFinite(ctx.bmsMaxDischargeA) && Number.isFinite(ctx.batteryCurrentA)
|
||||
? Math.round(ctx.bmsMaxDischargeA - Math.abs(Math.min(0, ctx.batteryCurrentA)))
|
||||
: null;
|
||||
@@ -213,14 +221,46 @@ const systemPrompt = [
|
||||
' evince la production — 5,6 kW de solaire remplaces par du reseau.',
|
||||
'- haute : un actionneur bascule de facon repetee, OU le materiel est sollicite',
|
||||
' pres de ses limites, OU un automate defait ce qu un autre vient de',
|
||||
' faire. Exemple reel : le contacteur reseau qui bascule six fois en',
|
||||
' dix minutes le 12/09 — chaque bascule coute 50 a 150 Wh et use le',
|
||||
' relais, et aucun automate ne le voyait.',
|
||||
' faire. Deux exemples reels : le contacteur reseau qui bascule six',
|
||||
' fois en dix minutes le 12/09 — chaque bascule coute 50 a 150 Wh et',
|
||||
' use le relais, et aucun automate ne le voyait ; et le 05/09 a 20:40,',
|
||||
' le parc a -97,4 A pour une limite declaree de 100 A, soit 3 A de',
|
||||
' marge, pendant que le reseau restait disponible et inutilise.',
|
||||
'UNE OSCILLATION EST TOUJOURS DE GRAVITE HAUTE, meme si chaque bascule prise',
|
||||
'isolement parait anodine : c est la repetition qui fait le degat, et c est',
|
||||
'precisement ce qu aucune regle locale ne peut voir.',
|
||||
].join('\n');
|
||||
|
||||
// Les etats du controleur sont des identifiants internes. Le conseiller n'a
|
||||
// aucune raison de savoir que `day_vehicle_full_idle` veut dire « le vehicule
|
||||
// est plein, il n'absorbera plus rien » — et sans le savoir il signale comme
|
||||
// une anomalie un systeme qui a raison.
|
||||
const ETATS = {
|
||||
vehicle_not_connected: 'aucun vehicule branche',
|
||||
idle_wait_conditions: 'a l arret, conditions de demarrage non reunies',
|
||||
idle_wait_source: 'a l arret, en attente d une source',
|
||||
day_vehicle_full_idle: 'vehicule PLEIN, il n absorbera plus rien (memoire du jour)',
|
||||
night_recovery_done_idle: 'charge de nuit terminee ET batterie a la cible',
|
||||
night_session_done_idle: 'charge de nuit terminee, batterie encore sous la cible',
|
||||
departure_done_idle: 'charge avant depart terminee',
|
||||
vehicle_full_or_paused: 'le vehicule ne demande plus de courant',
|
||||
start_min_current: 'demarrage au courant minimal',
|
||||
start_grid_hc_min_current: 'demarrage sur le reseau en heures creuses',
|
||||
start_manual_local_min_current: 'demarrage manuel au courant minimal',
|
||||
charging_hold_grid: 'en charge sur le reseau, consigne tenue',
|
||||
charging_hold_manual_local: 'en charge, consigne manuelle',
|
||||
charging_hold_cloud_tolerance: 'en charge, tolerance nuage en cours',
|
||||
charging_step_up_battery: 'en charge, courant en hausse sur le solaire',
|
||||
charging_step_up_grid_hc: 'en charge, courant en hausse sur le reseau',
|
||||
charging_step_down_battery: 'en charge, courant en baisse',
|
||||
charging_step_down_system_cap: 'en charge, courant ramene au plafond du systeme',
|
||||
battery_current_hard_stop: 'ARRET : la batterie se dechargeait trop fort',
|
||||
stop_conditions_lost: 'ARRET : conditions de maintien perdues',
|
||||
stop_source_lost: 'ARRET : la source a disparu',
|
||||
hold_min_run: 'maintenu le temps de la duree minimale de marche',
|
||||
};
|
||||
const etatLisible = (e) => ETATS[e] ? `${ETATS[e]} (${e})` : e;
|
||||
|
||||
function nombre(v, unite, defaut) {
|
||||
return Number.isFinite(v) ? `${v}${unite}` : (defaut || 'inconnu');
|
||||
}
|
||||
@@ -247,13 +287,13 @@ const userPrompt = [
|
||||
`- PV : ${Math.round(ctx.pvW)} W instantane, ${Math.round(ctx.pvAvg10mW)} W sur 10 min`,
|
||||
`- Chargeurs solaires : ${ctx.mppt.aFond}/${ctx.mppt.total} a pleine puissance, ${ctx.mppt.brides} qui se BRIDENT`,
|
||||
`- Maison : ${Math.round(ctx.houseW)} W, dont voiture ${ctx.evcsCharging ? Math.round(ctx.evcsCurrentA * 230) : 0} W`,
|
||||
`- EXCEDENT SOLAIRE (production moins maison hors voiture) : ${excedentSolaireW} W`,
|
||||
`- EXCEDENT SOLAIRE (production moins maison hors voiture) : ${excedentSolaireW > 0 ? `+${excedentSolaireW} W, il RESTE du solaire` : excedentSolaireW < 0 ? `${excedentSolaireW} W` : '0 W, exactement a l equilibre'}${ctx.mppt.brides > 0 ? ` — ATTENTION, ce chiffre est CENSURE : ${ctx.mppt.brides} chargeurs se retiennent, la ressource reelle est PLUS HAUTE${excedentSolaireW < 0 ? ' et ce chiffre negatif ne prouve PAS qu il manque du soleil' : ''}` : excedentSolaireW < 0 ? ', DEFICIT reel : la batterie porte deja la maison' : ''}`,
|
||||
`- MARGE DE DECHARGE du parc : ${margeDechargeA === null ? 'inconnue' : `${margeDechargeA} A restants`}${partDuPlafond === null ? '' : ` — la batterie est a ${partDuPlafond} % de son plafond`}`,
|
||||
`- Contacteur EDF : ${ctx.gridOn ? 'FERME' : 'ouvert'} (AC-IN ${ctx.acinAvailable ? 'present' : 'absent'})`,
|
||||
`- Consigne de puissance reseau : ${nombre(ctx.gridSetpointW, ' W')}`,
|
||||
`- Reseau EDF : ${ctx.gridOn ? 'PRESENT, il peut alimenter la maison' : 'ABSENT, la maison vit sur batterie et solaire'} (contacteur ${ctx.gridOn ? 'ferme' : 'ouvert'}, AC-IN ${ctx.acinAvailable ? 'present' : 'absent'})`,
|
||||
`- Consigne de puissance reseau : ${nombre(ctx.gridSetpointW, ' W')}${margeRechargeW === null ? '' : batterieDoitMonter === false && margeRechargeW > 0 ? ` — la batterie n a PAS besoin de monter (SOC ${ctx.soc} %, bilan ${ctx.balanceRequiredSoc} %), donc ces ${margeRechargeW} W de demande reseau n ont aucune destination : ils ne peuvent que remplacer du solaire` : margeRechargeW > 0 ? ` — il reste ${margeRechargeW} W pour RECHARGER la batterie, qui en a besoin` : ' — une fois la maison servie il ne reste RIEN pour recharger la batterie'}`,
|
||||
`- Limites declarees par le parc : charge ${nombre(ctx.bmsMaxChargeA, ' A')}, decharge ${nombre(ctx.bmsMaxDischargeA, ' A')}`,
|
||||
`- Vehicule : ${ctx.vehicleConnected ? `BRANCHE (${ctx.vehicleSelected})` : 'AUCUN branche'}${ctx.evcsCharging ? `, en charge a ${ctx.evcsCurrentA} A` : ''}`,
|
||||
`- Controleur : ${ctx.surplusState} | source ${ctx.sourceMode} | strategie reelle ${ctx.userStrategy}`,
|
||||
`- Controleur : ${etatLisible(ctx.surplusState)} | source ${ctx.sourceMode} | strategie reelle ${ctx.userStrategy}`,
|
||||
`- Cible SOC matin actuellement appliquee : ${ctx.nightTargetActual} %`,
|
||||
`- Prevision : ${ctx.todayRemainingKwh} kWh restant aujourd hui, ${ctx.tomorrowKwh} kWh demain`,
|
||||
'',
|
||||
|
||||
Reference in New Issue
Block a user