etm-powersync-app/lib/l10n/app_localizations_fr.dart
Patrick Schurig 43fd79ad62 feat(écran): « Commandé, pas encore mesuré » remplace « Réservé au véhicule »
Le moteur a livré la définition d'`evReservedW`, et il ne pouvait pas l'écrire
avant d'en avoir sorti la part réseau d'`EV_GRID_START` : un champ à deux natures
ne se documente pas. Le libellé tranché est le sien, parce qu'il dit la chose —
la latence entre l'ordre et sa lecture au compteur.

« Réservé au véhicule » affirmait deux faussetés : que c'est réservé, et que ça
regarde le véhicule plutôt que la latence de sa mesure.

La clé ARB garde le nom du champ de la box (`budgetEvReserved`), pas celui de
l'ancienne affirmation. Et la consigne qui compte reste écrite à côté : ce n'est
pas un registre, on ne réconcilie rien dessus — la nature du champ l'interdit,
pas son état de livraison.

`draw.committedW` : annoncé livré en +etm31, NON vérifié à la sonde. La box porte
`powersync-energy-plugin-nymea 1.15.2+etm30` au 2026-08-30 et ne publie aucune
clé `draw`. L'exception `EV_GRID_START` reste donc dans `surplusShareW` : c'est
la sonde qui autorise le retrait, pas l'annonce.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw
2026-08-30 09:16:04 +02:00

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 => 'Commandé, pas encore mesuré';
@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';
}
}