L'arrivée de la V2C sur .75 a révélé deux défauts que le banc ne pouvait pas montrer avant, plus deux pièges de contrat à documenter. 1. ⚠️ isNotGrouped ÉTAIT CALCULÉ ET AFFICHÉ NULLE PART. GroupedOrder détecte depuis le premier jour qu'un ordre n'est pas groupé par domaine, le provider l'expose, et aucune vue ne le lisait — le cas ne s'était jamais produit, chaque domaine du banc ayant ses charges d'un seul tenant. Il se produit maintenant : la V2C, créée d'office au rang 1 que le chauffe-eau occupait déjà, donne l'ordre à plat « ecs · ev · heating · ev · ev ». Le domaine ev est coupé en deux par le chauffage. Ce n'était pas un détail d'affichage. L'écran groupe pour afficher, donc ce qu'on voit n'est plus l'ordre réel de la box — et le premier enregistrement réaplatit EN GROUPANT, ce qui change l'arbitrage sans que personne ne l'ait demandé. Chiffré par test sur la configuration réelle : la PAC passerait du rang 2 au rang 5. C'est exactement ce que le commentaire de GroupedOrder interdit depuis le début ; le garde-fou existait, il n'était pas branché. 2. « L'APPAREIL N'EXISTE PLUS » N'EST PAS UN DÉFAUT À LEVER. La Terra AC a été supprimée de nymea ; son entrée LoadConfig survit, occupe le rang 4, et s'affiche en THING_MISSING avec un bouton « Lever le défaut ». ClearLoadFault y répondrait EnergyErrorNoError sans rien changer, et le défaut reviendrait au cycle suivant — un bouton qui ne peut pas tenir sa promesse fait douter de la box au lieu de désigner la cause. Le bouton disparaît sur ce code, remplacé par ce qu'il faut faire : réinstaller l'appareil, ou retirer la charge. Et le libellé cesse de se lire « votre configuration est cassée » : le cas normal est un appareil remplacé, le plugin crée d'office une entrée par borne détectée mais ne la retire pas quand le Thing s'en va. 3. Deux pièges du Thing V2C, documentés là où quelqu'un serait tenté de les câbler : chargeEnergy est EXACT pendant la charge — sa croissance recoupe currentPower à mieux d'un pour cent — et REMIS À ZÉRO à l'arrêt de la charge, pas au débranchement. Mesuré : 0,3456 kWh → 0 dès que charging passe à faux, 119 secondes avant que le câble ne bouge. Sur du pilotage par surplus il repartirait de zéro à chaque nuage, et après coup une nuit entière vaudrait 0 — soit « rien livré » affiché là où la vérité est « pas mesurable ». Le plugin publiera un sessionEnergy construit ; rien n'est bâti en attendant, et surtout aucune accumulation côté app. powerL1/L2/L3 sont des ampères mal nommés, renommage currentL* en cours côté plugin. Ni affichage, ni conversion : une conversion écrite ici survivrait au correctif et le contredirait. Fixture ajoutée : la configuration réelle à cinq entrées, avec ses deux enseignements de terrain — deux rangs à 1, et une entrée orpheline qui consomme un rang. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vrTVifar2GN5rtUh89Wkq
620 lines
20 KiB
Dart
620 lines
20 KiB
Dart
// ignore: unused_import
|
|
import 'package:intl/intl.dart' as intl;
|
|
import 'app_localizations.dart';
|
|
|
|
// ignore_for_file: type=lint
|
|
|
|
/// The translations for French (`fr`).
|
|
class L10nFr extends L10n {
|
|
L10nFr([String locale = 'fr']) : super(locale);
|
|
|
|
@override
|
|
String get installerLoadsTitle => 'Rôles & appareils';
|
|
|
|
@override
|
|
String get installerLoadsSubtitle =>
|
|
'Ordre de service des charges pilotables';
|
|
|
|
@override
|
|
String get loadsEmpty =>
|
|
'Aucune charge pilotable déclarée sur cette installation.';
|
|
|
|
@override
|
|
String loadsLoadError(String error) {
|
|
return 'Lecture de la configuration impossible : $error';
|
|
}
|
|
|
|
@override
|
|
String get sectionUnclassified => 'Non classé';
|
|
|
|
@override
|
|
String get domainEv => 'Véhicule électrique';
|
|
|
|
@override
|
|
String get domainEcs => 'Eau chaude sanitaire';
|
|
|
|
@override
|
|
String get domainHvac => 'Climatisation';
|
|
|
|
@override
|
|
String get domainHeating => 'Chauffage';
|
|
|
|
@override
|
|
String domainUnknown(String code) {
|
|
return 'Domaine « $code »';
|
|
}
|
|
|
|
@override
|
|
String get adapterRelayRouter => 'Routeur de relais';
|
|
|
|
@override
|
|
String get adapterEtmVariableLoad => 'Charge modulable';
|
|
|
|
@override
|
|
String get adapterSgReady => 'SG-Ready';
|
|
|
|
@override
|
|
String get adapterEvCharger => 'Borne de recharge';
|
|
|
|
@override
|
|
String adapterUnknown(String code) {
|
|
return 'Mécanisme « $code »';
|
|
}
|
|
|
|
@override
|
|
String get loadEnabled => 'Active';
|
|
|
|
@override
|
|
String get loadDisabled => 'Exclue de l\'arbitrage';
|
|
|
|
@override
|
|
String loadPriority(int rank) {
|
|
return 'Rang $rank';
|
|
}
|
|
|
|
@override
|
|
String loadMinOn(int seconds) {
|
|
return 'Maintien ON minimal : $seconds s';
|
|
}
|
|
|
|
@override
|
|
String loadMinOff(int seconds) {
|
|
return 'Maintien OFF minimal : $seconds s';
|
|
}
|
|
|
|
@override
|
|
String loadRelayCount(int count) {
|
|
String _temp0 = intl.Intl.pluralLogic(
|
|
count,
|
|
locale: localeName,
|
|
other: '$count relais',
|
|
one: '1 relais',
|
|
);
|
|
return '$_temp0';
|
|
}
|
|
|
|
@override
|
|
String get loadMeterSlot => 'Compteur dédié : non rattachable';
|
|
|
|
@override
|
|
String get orderNotGroupedTitle => 'Ordre non groupé';
|
|
|
|
@override
|
|
String get orderNotGroupedBody =>
|
|
'L\'ordre en place sur la box n\'est pas groupé par domaine : les charges d\'un même domaine ne se suivent pas. L\'ordre réel est affiché ci-dessous, tel que la box l\'applique.';
|
|
|
|
@override
|
|
String get orderNotGroupedAction => 'Normaliser l\'ordre';
|
|
|
|
@override
|
|
String get orderNotGroupedWarning =>
|
|
'Normaliser modifiera l\'ordre d\'arbitrage réel de l\'installation. Aucune écriture ne part tant que vous n\'avez pas confirmé.';
|
|
|
|
@override
|
|
String get orderNormalizeConfirm => 'Normaliser et enregistrer';
|
|
|
|
@override
|
|
String get cancel => 'Annuler';
|
|
|
|
@override
|
|
String get saveOrder => 'Enregistrer l\'ordre';
|
|
|
|
@override
|
|
String get savePending => 'Envoi en cours…';
|
|
|
|
@override
|
|
String get saveWaitingBox => 'En attente de confirmation de la box…';
|
|
|
|
@override
|
|
String get saveConfirmed => 'Configuration confirmée par la box.';
|
|
|
|
@override
|
|
String saveRejected(String reason) {
|
|
return 'La box a refusé : $reason';
|
|
}
|
|
|
|
@override
|
|
String get saveDiverged =>
|
|
'La box a enregistré un état différent de celui demandé. L\'affichage montre ce que la box applique réellement.';
|
|
|
|
@override
|
|
String validationDuplicateId(String id) {
|
|
return 'L\'identifiant de charge « $id » apparaît deux fois.';
|
|
}
|
|
|
|
@override
|
|
String validationThingClaimedTwice(
|
|
String thingId,
|
|
String first,
|
|
String second,
|
|
) {
|
|
return 'L\'appareil $thingId est commandé par deux charges actives, « $first » et « $second » : deux commandes contradictoires et une puissance comptée deux fois.';
|
|
}
|
|
|
|
@override
|
|
String get telemetryUnavailableTitle => 'Télémétrie indisponible';
|
|
|
|
@override
|
|
String get telemetryUnavailableBody =>
|
|
'Cette box n\'expose pas GetLoadTelemetry. Puissance allouée, verrous, disponibilité et motifs de décision ne sont pas lisibles depuis l\'app.';
|
|
|
|
@override
|
|
String telemetryStale(int seconds) {
|
|
return 'Données anciennes — dernier point il y a $seconds s';
|
|
}
|
|
|
|
@override
|
|
String get telemetryDegradedMode =>
|
|
'Mode dégradé L2 — compteur muet, planification suspendue';
|
|
|
|
@override
|
|
String get faultTitle => 'En défaut';
|
|
|
|
@override
|
|
String get faultClearAction => 'Lever le défaut';
|
|
|
|
@override
|
|
String get faultCleared => 'Défaut levé — confirmé par la télémétrie relue.';
|
|
|
|
@override
|
|
String get faultClearNoop => 'Aucun défaut à lever sur cette charge.';
|
|
|
|
@override
|
|
String faultUnknown(String code) {
|
|
return 'Défaut « $code »';
|
|
}
|
|
|
|
@override
|
|
String decisionUnknown(String code, String params) {
|
|
return 'Décision « $code »$params';
|
|
}
|
|
|
|
@override
|
|
String get telemetryTitle => 'Arbitrage en direct';
|
|
|
|
@override
|
|
String get telemetryNeverRan =>
|
|
'Aucun cycle d\'arbitrage depuis le démarrage du service.';
|
|
|
|
@override
|
|
String telemetryLastCycle(int seconds) {
|
|
return 'Dernier cycle il y a $seconds s';
|
|
}
|
|
|
|
@override
|
|
String get telemetryBudgetTitle => 'Budget de surplus du cycle';
|
|
|
|
@override
|
|
String get telemetryBudgetAbsent =>
|
|
'Aucun budget publié pour ce cycle : la planification est suspendue.';
|
|
|
|
@override
|
|
String get budgetSurplus => 'Surplus entrant';
|
|
|
|
@override
|
|
String get budgetEvReserved => 'Réservé au véhicule';
|
|
|
|
@override
|
|
String get budgetRecredited => 'Recrédité';
|
|
|
|
@override
|
|
String get budgetAllocated => 'Alloué';
|
|
|
|
@override
|
|
String get budgetRemaining => 'Reliquat';
|
|
|
|
@override
|
|
String watts(int watts) {
|
|
final intl.NumberFormat wattsNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String wattsString = wattsNumberFormat.format(watts);
|
|
|
|
return '$wattsString W';
|
|
}
|
|
|
|
@override
|
|
String telemetryAllocated(int watts) {
|
|
final intl.NumberFormat wattsNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String wattsString = wattsNumberFormat.format(watts);
|
|
|
|
return 'Alloué $wattsString W';
|
|
}
|
|
|
|
@override
|
|
String telemetryEvCharging(double current, int phases) {
|
|
final intl.NumberFormat currentNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String currentString = currentNumberFormat.format(current);
|
|
|
|
return 'Borne : en charge, $currentString A sur $phases phase(s)';
|
|
}
|
|
|
|
@override
|
|
String get telemetryEvIdle => 'Borne : ne charge pas';
|
|
|
|
@override
|
|
String get telemetryEvUnplugged => 'Borne : aucun véhicule branché';
|
|
|
|
@override
|
|
String get telemetryEvStateUnknown => 'Borne : état non publié ce cycle';
|
|
|
|
@override
|
|
String get telemetryFundedByGrid =>
|
|
'Financée au réseau (échéance ou tarif dynamique) — hors budget de surplus';
|
|
|
|
@override
|
|
String get telemetryNotArbitrated =>
|
|
'Non arbitrée — absente du dernier cycle publié';
|
|
|
|
@override
|
|
String lockMinOn(int seconds) {
|
|
return 'Maintien ON — $seconds s restantes';
|
|
}
|
|
|
|
@override
|
|
String lockMinOff(int seconds) {
|
|
return 'Maintien OFF — $seconds s restantes';
|
|
}
|
|
|
|
@override
|
|
String lockMinStateHold(int seconds) {
|
|
return 'Maintien d\'état — $seconds s restantes';
|
|
}
|
|
|
|
@override
|
|
String lockUnknown(String kind, int seconds) {
|
|
return 'Verrou « $kind » — $seconds s restantes';
|
|
}
|
|
|
|
@override
|
|
String get lockAsOfCycle => 'au dernier cycle';
|
|
|
|
@override
|
|
String mechanismRelayStage(int stage, int max) {
|
|
final intl.NumberFormat stageNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String stageString = stageNumberFormat.format(stage);
|
|
final intl.NumberFormat maxNumberFormat = intl.NumberFormat.decimalPattern(
|
|
localeName,
|
|
);
|
|
final String maxString = maxNumberFormat.format(max);
|
|
|
|
return 'Palier $stageString W sur $maxString W';
|
|
}
|
|
|
|
@override
|
|
String mechanismVariableSetpoint(int setpoint, int percent) {
|
|
final intl.NumberFormat setpointNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String setpointString = setpointNumberFormat.format(setpoint);
|
|
|
|
return 'Consigne $setpointString W ($percent %)';
|
|
}
|
|
|
|
@override
|
|
String mechanismSgReadyState(int state, int estimated) {
|
|
final intl.NumberFormat estimatedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String estimatedString = estimatedNumberFormat.format(estimated);
|
|
|
|
return 'État SG-Ready $state — estimation $estimatedString W';
|
|
}
|
|
|
|
@override
|
|
String mechanismEvCharger(double current, int phases) {
|
|
final intl.NumberFormat currentNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String currentString = currentNumberFormat.format(current);
|
|
|
|
return '$currentString A sur $phases phase(s)';
|
|
}
|
|
|
|
@override
|
|
String mechanismUnknown(String kind) {
|
|
return 'Mécanisme « $kind »';
|
|
}
|
|
|
|
@override
|
|
String get decisionEvSurplus =>
|
|
'Véhicule rechargé sur le surplus photovoltaïque.';
|
|
|
|
@override
|
|
String get decisionEvSpotMarket =>
|
|
'Véhicule rechargé sur un créneau tarifaire favorable.';
|
|
|
|
@override
|
|
String get decisionEvDeadline =>
|
|
'Véhicule prioritaire : l\'échéance approche.';
|
|
|
|
@override
|
|
String get decisionEvEcoMin =>
|
|
'Pas de surplus : le courant minimum est maintenu.';
|
|
|
|
@override
|
|
String get decisionEvIdle => 'Pas de surplus : la recharge est suspendue.';
|
|
|
|
@override
|
|
String decisionLoadUnavailable(int frozen) {
|
|
final intl.NumberFormat frozenNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String frozenString = frozenNumberFormat.format(frozen);
|
|
|
|
return 'Charge en défaut : aucune commande n\'est émise, et $frozenString W restent comptés au budget.';
|
|
}
|
|
|
|
@override
|
|
String decisionLockMinOn(int applied, int budget) {
|
|
final intl.NumberFormat appliedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String appliedString = appliedNumberFormat.format(applied);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Le maintien ON a relevé la consigne à $appliedString W ; le budget en payait $budgetString W.';
|
|
}
|
|
|
|
@override
|
|
String decisionLockMinOff(int requested, int budget) {
|
|
final intl.NumberFormat requestedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String requestedString = requestedNumberFormat.format(requested);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Le maintien OFF interdit l\'enclenchement ; le budget payait pourtant $requestedString W sur $budgetString W disponibles.';
|
|
}
|
|
|
|
@override
|
|
String decisionLockMinOffCapped(int applied, int requested, int budget) {
|
|
final intl.NumberFormat appliedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String appliedString = appliedNumberFormat.format(applied);
|
|
final intl.NumberFormat requestedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String requestedString = requestedNumberFormat.format(requested);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Le maintien OFF plafonne la consigne à $appliedString W ; $requestedString W étaient demandés sur $budgetString W de budget.';
|
|
}
|
|
|
|
@override
|
|
String decisionSurplusSetpoint(int setpoint, int budget) {
|
|
final intl.NumberFormat setpointNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String setpointString = setpointNumberFormat.format(setpoint);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Consigne de $setpointString W servie par le surplus ($budgetString W de budget).';
|
|
}
|
|
|
|
@override
|
|
String decisionSurplusSetpointStepped(int setpoint, int budget) {
|
|
final intl.NumberFormat setpointNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String setpointString = setpointNumberFormat.format(setpoint);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Consigne de $setpointString W servie par le surplus, arrondie sur un palier déclaré ($budgetString W de budget).';
|
|
}
|
|
|
|
@override
|
|
String decisionSurplusInsufficient(int budget) {
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Aucun surplus à distribuer ($budgetString W) — rien n\'est commandé.';
|
|
}
|
|
|
|
@override
|
|
String decisionLockMinStateHold(int state) {
|
|
return 'État $state maintenu par protection anti court-cycle.';
|
|
}
|
|
|
|
@override
|
|
String decisionSgForced(int estimated, int budget) {
|
|
final intl.NumberFormat estimatedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String estimatedString = estimatedNumberFormat.format(estimated);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Pompe à chaleur en état 4 (forcé) — estimation $estimatedString W sur $budgetString W de budget.';
|
|
}
|
|
|
|
@override
|
|
String decisionSgRecommended(int estimated, int budget) {
|
|
final intl.NumberFormat estimatedNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String estimatedString = estimatedNumberFormat.format(estimated);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Pompe à chaleur en état 3 (recommandation) — estimation $estimatedString W sur $budgetString W de budget.';
|
|
}
|
|
|
|
@override
|
|
String decisionSgNormal(int budget) {
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
|
|
return 'Aucun surplus ($budgetString W) — pompe à chaleur en état 2 (normal, sans consigne).';
|
|
}
|
|
|
|
@override
|
|
String decisionBelowMinPower(int budget, int min) {
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
final intl.NumberFormat minNumberFormat = intl.NumberFormat.decimalPattern(
|
|
localeName,
|
|
);
|
|
final String minString = minNumberFormat.format(min);
|
|
|
|
return 'Budget de $budgetString W sous le premier palier ($minString W) — rien n\'est commandé, le budget passe à la charge suivante.';
|
|
}
|
|
|
|
@override
|
|
String decisionBelowMinPowerState(int budget, int state, int min) {
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
final intl.NumberFormat minNumberFormat = intl.NumberFormat.decimalPattern(
|
|
localeName,
|
|
);
|
|
final String minString = minNumberFormat.format(min);
|
|
|
|
return 'Budget de $budgetString W sous l\'état $state ($minString W estimés) — maintien en état 2, le budget passe à la charge suivante.';
|
|
}
|
|
|
|
@override
|
|
String decisionEvGridStart(int grid, int budget, int floor) {
|
|
final intl.NumberFormat gridNumberFormat = intl.NumberFormat.decimalPattern(
|
|
localeName,
|
|
);
|
|
final String gridString = gridNumberFormat.format(grid);
|
|
final intl.NumberFormat budgetNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String budgetString = budgetNumberFormat.format(budget);
|
|
final intl.NumberFormat floorNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String floorString = floorNumberFormat.format(floor);
|
|
|
|
return 'Démarrage soutiré : $gridString W achetés au réseau pour compléter les $budgetString W de surplus et atteindre le plancher de $floorString W.';
|
|
}
|
|
|
|
@override
|
|
String decisionPhaseLimit(int limit, int required) {
|
|
final intl.NumberFormat limitNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String limitString = limitNumberFormat.format(limit);
|
|
final intl.NumberFormat requiredNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String requiredString = requiredNumberFormat.format(required);
|
|
|
|
return 'Limite de phase atteinte : $limitString W disponibles pour $requiredString W exigés — ce n\'est pas le surplus qui manque.';
|
|
}
|
|
|
|
@override
|
|
String decisionBatteryReserveWithheld(int withheld, int soc, int seuil) {
|
|
final intl.NumberFormat withheldNumberFormat =
|
|
intl.NumberFormat.decimalPattern(localeName);
|
|
final String withheldString = withheldNumberFormat.format(withheld);
|
|
|
|
return '$withheldString W de surplus retenus par la réserve batterie ($soc % sous le seuil de $seuil %) — il y a du surplus, mais une règle interdit de le distribuer.';
|
|
}
|
|
|
|
@override
|
|
String decisionBatteryReserve(int soc, int seuil) {
|
|
return 'Budget annulé par la réserve batterie ($soc % sous le seuil de $seuil %) — il y a du surplus, mais une règle interdit de le distribuer.';
|
|
}
|
|
|
|
@override
|
|
String get decisionBatteryReserveShort =>
|
|
'Budget annulé par la réserve batterie — il y a du surplus, mais une règle interdit de le distribuer.';
|
|
|
|
@override
|
|
String get decisionDegradedL2 =>
|
|
'Consigne de repli : le compteur est muet et le watchdog a suspendu la planification.';
|
|
|
|
@override
|
|
String get decisionSafeStateRelay =>
|
|
'État sûr avant retrait : tous les relais sont ouverts.';
|
|
|
|
@override
|
|
String get decisionSafeStateSetpoint =>
|
|
'État sûr avant retrait : consigne ramenée à 0 W.';
|
|
|
|
@override
|
|
String get decisionSafeStateSgReady =>
|
|
'État sûr avant retrait : état 2 (normal), jamais le blocage.';
|
|
|
|
@override
|
|
String get faultWriteFailed =>
|
|
'Échec d\'écriture : l\'échelle de commande est épuisée, plus aucune commande n\'est émise tant que le défaut n\'est pas levé.';
|
|
|
|
@override
|
|
String get faultThingMissing =>
|
|
'L\'appareil commandé n\'existe plus dans nymea — retiré, ou jamais réinstallé après un remplacement. La charge, elle, est toujours déclarée : c\'est pour ça qu\'elle apparaît ici.';
|
|
|
|
@override
|
|
String get faultThingMissingAction =>
|
|
'Rien à lever ici : le défaut ne partira pas tant qu\'aucun appareil ne répond. Réinstallez-le dans nymea, ou retirez cette charge de la configuration.';
|
|
|
|
@override
|
|
String get faultUnusableEncoding =>
|
|
'Encodage SG-Ready inexploitable : l\'état 2 ne peut pas être exprimé, cette pompe à chaleur n\'est pas pilotable.';
|
|
|
|
@override
|
|
String get faultClearPending =>
|
|
'Levée demandée — en attente de la télémétrie…';
|
|
|
|
@override
|
|
String get faultClearStillFaulty =>
|
|
'La charge est toujours en défaut après la levée.';
|
|
|
|
@override
|
|
String faultClearRejected(String reason) {
|
|
return 'La box a refusé la levée : $reason';
|
|
}
|
|
|
|
@override
|
|
String get faultClearHint =>
|
|
'La levée est une action délibérée : le défaut ne se lève jamais tout seul.';
|
|
|
|
@override
|
|
String get domainBattery => 'Batterie';
|
|
|
|
@override
|
|
String domainAssignTitle(String label) {
|
|
return 'Classer « $label »';
|
|
}
|
|
|
|
@override
|
|
String get domainAssignAction => 'Changer de domaine';
|
|
|
|
@override
|
|
String get domainAssignNone => 'Retirer du classement';
|
|
|
|
@override
|
|
String get domainAssignHint =>
|
|
'Le domaine est une intention déclarée par l\'installateur. L\'arbitre ne la lit pas : elle ne sert qu\'à grouper l\'ordre de service.';
|
|
|
|
@override
|
|
String localeRequested(String requested, String effective) {
|
|
return 'Locale demandée : $requested · retenue par la box : $effective';
|
|
}
|
|
}
|