Patrick Schurig 2a4659ff8f fix(etm): ECS-414 — échelle d'échec généralisée à SgReady et EtmVariableLoad
Même modèle qu'ECS-410, rien de nouveau conçu : m_pending, verdict à zéro,
échelle bornée à trois barreaux, `this` en contexte de connexion.

PLANCHER PROPRE À CHAQUE ADAPTATEUR. Pour EtmVariableLoadAdapter, consigne 0 W.
Pour SgReadyAdapter, le barreau 3 est l'ÉTAT 2 — pas « tous contacts ouverts ».
Ouvrir les deux contacts d'une PAC est une COMMANDE, et selon l'encodage câblé
c'est potentiellement le BLOCAGE, donc l'inverse d'une mise en sécurité.

ATOMICITÉ DU REPLI — le point qui n'existait pas sur le routeur relais. Un état
SG-Ready est porté par deux bits ; si une écriture échoue, on est dans un motif
valide mais NON VOULU, et le retour depuis ce motif peut exiger de traverser le
blocage. applyStateRelays() prend désormais un ENSEMBLE de relais réellement
fermés au lieu d'un index d'état, de sorte que transientHarm ordonne le repli
exactement comme il ordonne l'aller. Sans cela, la récupération serait plus
dangereuse que la panne qu'elle corrige.

Le repli écrit les contacts directement, sans repasser par applyAction : le verrou
minStateHoldS n'est donc jamais consulté — équivalent d'un force = true, comme le
repli L2. À 900 s sur une PAC, attendre un quart d'heure pour sortir d'un état non
voulu ne serait pas défendable.

DEUX INCOHÉRENCES TROUVÉES PAR LE TEST, et corrigées :

  1. readActualOn() traitait un contact injoignable comme OUVERT, alors qu'ECS-411
     le suppose FERMÉ. Conséquence : un repli ne demandant aucune écriture
     « réussissait » à vide alors qu'on ne savait rien du matériel.

  2. Corollaire inverse : une fois supposé fermé, un contact injoignable n'était
     plus jamais écrit quand la cible le voulait fermé — l'échec était masqué et
     la transition paraissait réussie sans qu'aucune écriture n'ait été tentée.
     Un contact non vérifiable est désormais TOUJOURS commandé.

Test testSgReadyPartialFailure. Ce qu'il verrouille n'est pas le défaut mais le
PLANCHER : le repli ramène K1 à l'ouverture, soit l'état 2 sur cet encodage. Un
plancher « contacts ouverts par principe » aurait pu, sur un autre câblage, valoir
l'état 1 — le blocage. Vérifie aussi que minStateHoldS = 900 s ne retarde pas le
repli, que la charge figée a plancher == plafond, et que la levée relit l'état.

Une correction de mon propre scénario au passage : j'avais écrit un cas
« récupération au barreau 2 » qui n'est pas constructible avec un contact
définitivement injoignable — rien ne peut alors être confirmé, et le défaut est
l'issue honnête.

Build amd64 0 erreur. Simulation : 18/18.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 12:07:39 +02:00
..
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00
2026-01-11 11:09:23 +01:00