Notation like Home Assistant, each screen in its own language, and the language in every build

From the end-to-end test on the bench boards and an independent review:
- Units spaced as Home Assistant does (54% / 54 % in German and French, 18°, 21.5 °C), in the firmware and the app.
- Grouping from five digits where the language does (1234 but 12.345 in Spanish, Polish, Portuguese): the layout
  message carries group_min and percent_space; an unknown number style no longer refuses a layout.
- Automatic follows Home Assistant's own language for the clock and numbers, also without a translation (Swedish:
  24 hours, 1 234,5; pt-BR: 1.234,5): regions.json from the CLDR for all 63 languages Home Assistant offers.
- 12-hour clock: the top bar says 3:48 PM, the clock card 3:48 (not 03:48), Last runs follow the clock.
- The climate setpoint font has the decimal comma; the value fonts have ², ³ and µ (m³ was a box).
- Weather days: at most three letters without the dot (mié, sáb, czw); the screen took three bytes.
- Texts fall back per key through the base language (pt-BR -> pt -> en) in the firmware and the app.
- Each screen gets the app's words in the language its firmware speaks; firmware from before the languages gets
  English and its own letters, not boxes.
- set_language re-reads what it writes (indentation, comments, quoted keys, CRLF, !include) and every build writes
  the language first; the 24-hour pin no longer hits a fresh install and waits for the old clock switches.
- Tests: region and notation, plural parity with the C++ rules, set_language edge cases, the pin, PUT /api/language.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-19 16:52:34 +02:00
parent ad8a8ccf56
commit 125346d94e
37 changed files with 1419 additions and 448 deletions
+2 -1
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": ".",
"group_min": "1"
"group_min": "1",
"percent": " %"
},
"time": {
"just_now": "Gerade eben",
+2 -1
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ".",
"group": ",",
"group_min": "1"
"group_min": "1",
"percent": "%"
},
"time": {
"just_now": "Just now",
+2 -1
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": ".",
"group_min": "2"
"group_min": "2",
"percent": "%"
},
"time": {
"just_now": "Justo ahora",
+9 -8
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": " ",
"group_min": "1"
"group_min": "1",
"percent": " %"
},
"time": {
"just_now": "À l'instant",
@@ -49,13 +50,13 @@
"sam."
],
"weekdays_min": [
"dim.",
"lun.",
"mar.",
"mer.",
"jeu.",
"ven.",
"sam."
"dim",
"lun",
"mar",
"mer",
"jeu",
"ven",
"sam"
],
"months": [
"janvier",
+2 -1
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": ".",
"group_min": "2"
"group_min": "2",
"percent": "%"
},
"time": {
"just_now": "Proprio ora",
+2 -1
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": ".",
"group_min": "1"
"group_min": "1",
"percent": "%"
},
"time": {
"just_now": "Zojuist",
+9 -8
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": " ",
"group_min": "2"
"group_min": "2",
"percent": "%"
},
"time": {
"just_now": "Przed chwilą",
@@ -49,13 +50,13 @@
"sob."
],
"weekdays_min": [
"niedz.",
"pon.",
"wt.",
"śr.",
"czw.",
"pt.",
"sob."
"nie",
"pon",
"wt",
"śr",
"czw",
"pt",
"sob"
],
"months": [
"stycznia",
+9 -8
View File
@@ -11,7 +11,8 @@
"number": {
"decimal": ",",
"group": " ",
"group_min": "2"
"group_min": "2",
"percent": "%"
},
"time": {
"just_now": "Agora mesmo",
@@ -49,13 +50,13 @@
"sábado"
],
"weekdays_min": [
"domingo",
"segunda",
"terça",
"quarta",
"quinta",
"sexta",
"sábado"
"dom",
"seg",
"ter",
"qua",
"qui",
"sex",
"sáb"
],
"months": [
"janeiro",