Le vocabulaire des deux générateurs sortait en français en dur. Il est
externalisé dans un dict REF par générateur, EN ANGLAIS, un seul jeu servi
identique dans les trois langues.
La raison est une MESURE, pas un goût : nymea ne sert aucune traduction sur
notre parc. Vérifié le 2026-10-12 sur le banc `hems` —
Integrations.GetThingClasses rend la MÊME charge utile au sha256 près
(243 340 octets) pour fr_FR, de_DE et en_US, et nymea-plugins-translations
n'est pas installé. Les noms de modèles, de registres et d'unités sont donc
déjà en anglais ; traduire les seuls en-têtes de colonnes autour aurait
fabriqué des pages bilingues sans rien gagner. Côté API c'est plus direct
encore : méthodes, champs, types et `description` viennent d'introspect.json.
Ce qui se TRADUIT, en revanche, c'est la prose et la navigation. D'où deux
ajouts côté fiches appareils :
- SCAFFOLD : l'échafaudage de prose par langue (titre de catégorie, intertitre
« Référence », mention de guide à venir). Sans lui, chaque nouvel appareil
créerait sa fiche dans la seule langue par défaut, et fallback_to_default la
servirait EN FRANÇAIS sous /de/ et /en/ — par le simple fait d'être créée.
- CATEGORY_LABELS_I18N pour les titres de pages d'index de catégorie.
`--lang` existait depuis la CI mais n'était PAS lu (« Conservé pour
compatibilité CI »). Il désigne maintenant la langue par défaut — celle dont
les fichiers n'ont pas de suffixe — et `--locales` dit lesquelles générer.
ensure_device_pages() et ensure_category_indexes() bouclent dessus, et ne
réécrivent JAMAIS une page existante : la prose traduite à la main survit aux
régénérations. Vérifié : second passage, « Doc à jour », 0 page régénérée.
Les messages de diagnostic (ERREUR, AVERTISSEMENT, BLOQUANT) restent en
français : ils s'adressent au mainteneur, pas au site.
Note de méthode : la validation par ast.parse() ne voit pas une erreur de table
des symboles (`global` après usage). compile() la voit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- render_header_badges() fonction partagée pour canal + origine + stabilité
- Marqueur __badges_<plugin>__ dans les 9 fiches (5 manuelles + 4 auto)
- Marqueur __index_<cat>__ dans les 3 index manuels (compteurs, bornes, smart)
- Front matter hide: [toc] sur tous les index de catégorie
- .badge.experimental ajouté dans extra.css (waveshare)
- process() gère __badges_ keys via render_header_badges()
- build_category_index_page() inclut hide:toc front matter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le générateur crée désormais entièrement les fiches inexistantes (titre,
badges, section générée BEGIN/END) et les index.md de catégorie manquants.
Les fiches rédigées manuellement (eastron, abb-b2x, abb-terra, keba,
waveshare) sont préservées — seul le contenu entre marqueurs est réinjecté.
- gen_device_reference.py : ensure_device_pages() + ensure_category_indexes()
créent les .md manquants dans le format exact de process() → idempotent
- render_matrix() : inclut tous les canaux (nightly sans JSON = ligne stub)
- generate_summary() : intègre check mode + inclut toutes les entrées nav
- process()/repl() : gère __index_<cat>__ et nightly sans JSON → stub
- load_plugins/load_meta : logging explicite pour JSON vides ou non parsables
- Supprimer stubs manuels hvac/{daikinairco,sgready,simpleheatpump,index}.md
et onduleurs/{fronius,index}.md → remplacés par fichiers générés
- 9 appareils dans la matrice et dans le SUMMARY.md, mkdocs build --strict OK
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>