Etiquettes : la derniere reponse humaine fait foi (correction de permutation), rejeu du 04/10
This commit is contained in:
@@ -599,6 +599,9 @@ async function migrer(client) {
|
||||
pose_a timestamptz NOT NULL DEFAULT now(),
|
||||
sessions_vues integer NOT NULL DEFAULT 0
|
||||
)`);
|
||||
// Correction humaine (05/10) : l'etiquette ne vaut que pour les sessions non
|
||||
// terminees a cet instant (NULL = tout le branchement).
|
||||
await client.query('ALTER TABLE etiquette_branchement ADD COLUMN IF NOT EXISTS applique_depuis timestamptz');
|
||||
await client.query(
|
||||
'CREATE INDEX IF NOT EXISTS session_charge_debut_idx ON session_charge (debut DESC)');
|
||||
|
||||
@@ -1323,10 +1326,34 @@ async function appliquerEtiquetteConcierge(sql, client, st) {
|
||||
WHERE x.value = ANY($1::text[]))`,
|
||||
[[...cibles]]);
|
||||
const contradiction = deja.map((r) => r.label).filter((l) => l && l !== label);
|
||||
// CORRECTION HUMAINE (05/10/2026, decision du proprietaire) : sa DERNIERE
|
||||
// reponse fait foi. Cas reel du 04/10 : JEEP notee a 16:59, puis « Non
|
||||
// maintenant c'est la zero » a 17:16 — permutation rapide que la borne n'a
|
||||
// pas vue. L'ancien refus laissait JEEP en base pendant que le concierge
|
||||
// repondait « Noté : ZERO ». Desormais : les sessions TERMINEES avant la
|
||||
// correction gardent leur etiquette (c'etait le bon vehicule a ce moment-la),
|
||||
// la session en cours et les suivantes prennent la nouvelle. Une
|
||||
// contradiction NON humaine (regle de puissance) reste refusee.
|
||||
let correctionDepuis = null;
|
||||
if (contradiction.length) {
|
||||
return refuser(
|
||||
`le branchement porte deja l etiquette ${contradiction.join('/')}, incompatible avec ${label}`,
|
||||
{ sessions: [...cibles], deja: contradiction });
|
||||
if (!CANAUX_HUMAINS.has(source)) {
|
||||
return refuser(
|
||||
`le branchement porte deja l etiquette ${contradiction.join('/')}, incompatible avec ${label}`,
|
||||
{ sessions: [...cibles], deja: contradiction });
|
||||
}
|
||||
correctionDepuis = Number.isFinite(Date.parse(confirmedAt)) ? new Date(confirmedAt) : new Date();
|
||||
const { rows: encore } = await lire(
|
||||
`SELECT debut FROM session_charge WHERE debut = ANY($1::timestamptz[])
|
||||
AND (fin IS NULL OR fin > $2 OR NOT terminee)`, [[...cibles], correctionDepuis]);
|
||||
const gardees = cibles.size - encore.length;
|
||||
cibles.clear();
|
||||
for (const r of encore) cibles.add(enIso(r.debut));
|
||||
await journaliser(sql, 'vehicule',
|
||||
`Etiquette corrigee par le proprietaire : ${contradiction.join('/')} -> ${label} a partir de `
|
||||
+ `${correctionDepuis.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Paris' })}`
|
||||
+ (gardees ? ` (${gardees} session${gardees > 1 ? 's' : ''} terminee${gardees > 1 ? 's' : ''} avant : inchangee${gardees > 1 ? 's' : ''})` : ''),
|
||||
{ origine: 'correction', source_airtria: source, label, avant: contradiction,
|
||||
confirmed_at: confirmedAt, depuis: correctionDepuis.toISOString(), gardees });
|
||||
}
|
||||
|
||||
const sur = CANAUX_HUMAINS.has(source);
|
||||
@@ -1361,12 +1388,13 @@ async function appliquerEtiquetteConcierge(sql, client, st) {
|
||||
const branchement = bornes[0]?.t || null;
|
||||
if (branchement) {
|
||||
await sql(
|
||||
`INSERT INTO etiquette_branchement (branchement, label, source_airtria, confirmed_at)
|
||||
VALUES ($1,$2,$3,$4)
|
||||
`INSERT INTO etiquette_branchement (branchement, label, source_airtria, confirmed_at, applique_depuis)
|
||||
VALUES ($1,$2,$3,$4,$5)
|
||||
ON CONFLICT (branchement) DO UPDATE
|
||||
SET label = EXCLUDED.label, source_airtria = EXCLUDED.source_airtria,
|
||||
confirmed_at = EXCLUDED.confirmed_at, pose_a = now()`,
|
||||
[branchement, label, source, confirmedAt || null]);
|
||||
confirmed_at = EXCLUDED.confirmed_at, pose_a = now(),
|
||||
applique_depuis = EXCLUDED.applique_depuis`,
|
||||
[branchement, label, source, confirmedAt || null, correctionDepuis]);
|
||||
}
|
||||
|
||||
// Le controleur lit le selecteur : la reponse doit y arriver, pas seulement
|
||||
@@ -1439,7 +1467,7 @@ async function etiqueterJeepUconnect(sql, client, st, branche, niveau) {
|
||||
async function appliquerEtiquettesEnAttente(sql, client) {
|
||||
if (DRY) return 0;
|
||||
const { rows } = await client.query(
|
||||
`SELECT branchement, label, source_airtria FROM etiquette_branchement
|
||||
`SELECT branchement, label, source_airtria, applique_depuis FROM etiquette_branchement
|
||||
WHERE branchement > now() - interval '48 hours' ORDER BY branchement`);
|
||||
let n = 0;
|
||||
for (const e of rows) {
|
||||
@@ -1452,8 +1480,9 @@ async function appliquerEtiquettesEnAttente(sql, client) {
|
||||
WHERE genre = 'vehicule'
|
||||
AND detail->>'entite' = 'binary_sensor.victron_evcs_vehicle_connected'
|
||||
AND detail->>'apres' = 'off' AND ts > $1::timestamptz), 'infinity'::timestamptz)
|
||||
AND ($4::timestamptz IS NULL OR s.fin IS NULL OR s.fin > $4::timestamptz OR NOT s.terminee)
|
||||
AND (s.vehicule IS DISTINCT FROM $2 OR s.vehicule_sur IS DISTINCT FROM $3)`,
|
||||
[e.branchement, e.label, sur]);
|
||||
[e.branchement, e.label, sur, e.applique_depuis]);
|
||||
if (rowCount) {
|
||||
await journaliser(sql, 'vehicule',
|
||||
`Etiquette ${e.label} posee sur ${rowCount} session(s) ouverte(s) depuis le branchement`,
|
||||
|
||||
Reference in New Issue
Block a user