Lot B côté app, partie NON bloquée par le lot plugin (voir §Limites).
§1 Locale (indépendant) — JSONRPC.Hello portait {} : l'app était en en_US de
fait alors que nymea gère la locale PAR CONNEXION (o:locale). Envoi de la
locale à chaque Hello, donc aussi après reconnexion subie (m_clientLocales
repart au défaut de la box à chaque socket). Locale demandée ET retenue
journalisées : un .qm introuvable rend exactement comme une absence de
traduction, sans cette trace un catalogue mal packagé passe inaperçu.
§2 i18n — flutter_localizations + intl + ARB (français seul). Aucune chaîne
en dur dans le nouvel écran. Les codes reçus de la box (domaine, mécanisme)
sont des clés ARB avec repli explicite sur code brut si l'app ne les connaît
pas : une box en avance sur l'app est un cas normal en parc déployé.
§3 Modèle — LoadConfigEntry est une VUE en lecture au-dessus de la map brute ;
l'écriture repart de la map d'origine (patched()). Pas de couche de filtrage
préventive : l'aller-retour neutre passe contre .75, donc l'écho verbatim est
sûr par construction (§7-1).
§4 Priorité à deux niveaux — groupByDomain / flattenToPayload. Le rang de
domaine se déduit de l'ordre d'apparition à plat ; la box ne sait rien des
groupes. Config non contiguë : signalée, ordre réel affiché, normalisation
seulement sur confirmation explicite. Miroir client de validateSet().
§5 Écritures asynchrones — LoadConfigProvider ne conclut jamais sur
l'acquittement du RPC : pending → LoadConfigChanged → confirmed|diverged.
NymeaEnergy.GetLoadConfig / SetLoadConfig deviennent RÉELS (ils étaient des
stubs journalisés). Conséquence traitée : EnergySetupProvider.persist()
n'émet plus setLoadConfig(buildLoadDescriptors()) — SetLoadConfig remplace
TOUT l'ensemble, et _commit() l'appelait à chaque changement d'UI : une
reconstruction depuis le modèle typé aurait écrasé la config réelle de la
box sans geste explicite.
Écran /energy/loads, gaté installateur (drawer + garde de routeur).
Limites — le lot plugin n'est PAS déployé sur .75 : GetLoadTelemetry,
LoadTelemetryChanged et o:domain sont absents (19 méthodes / 13 notifications
inchangées). Toute la moitié télémétrie du brief est donc hors d'atteinte, et
o:domain n'étant pas au schéma, la box rejetterait la clé (jsonvalidator.cpp:143).
Fixtures multi-domaines synthétiques : .75 n'a qu'une charge.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
197 lines
4.9 KiB
Dart
197 lines
4.9 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 localeRequested(String requested, String effective) {
|
|
return 'Locale demandée : $requested · retenue par la box : $effective';
|
|
}
|
|
}
|