Build each screen in one language: the screen texts from the translations, European letters in the fonts, and Language & region in the app
The firmware takes its texts from screen_manager/translations/<code>.json at build time (components/smart_display: one table in main.cpp, keys in screen_text_keys.h), and the fonts carry every letter European languages write with. The app keeps Settings -> Language & region (language, clock, numbers) for every screen, writes LANGUAGE into the screens' YAML and sends the clock and the number format in the layout message; the per-screen 24-hour clock goes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+89
-51
@@ -18,6 +18,9 @@ substitutions:
|
||||
DASHBOARD_INBOX_INTERNAL: "false"
|
||||
CALIBRATION_ON_BOOT: "false" # a bench build: start on the touch test page
|
||||
ROOM_NAME: "" # top left until ESP Screens sends the screen name
|
||||
# The language of every text on the screen (app 0.2.90): a file in screen_manager/translations, English for any
|
||||
# text it lacks. ESP Screens writes it into the screen's own YAML, from Home Assistant's language or its Settings.
|
||||
LANGUAGE: "en"
|
||||
|
||||
## DIM settings
|
||||
AUTO_DIM: "true" # true = enable auto dimming
|
||||
@@ -213,7 +216,7 @@ esphome:
|
||||
settings_screen::apply = []() { id(apply_screen_settings).execute(); };
|
||||
settings_screen::report = [](const char *key, int32_t value) { runtime_tiles::setting_event(key, value); };
|
||||
settings_screen::name_text = []() { return std::string("${DEVICE_FRIENDLY_NAME}"); };
|
||||
settings_screen::address_text = []() { return id(wifi_ip).state.empty() ? std::string("No network") : id(wifi_ip).state; };
|
||||
settings_screen::address_text = []() { return id(wifi_ip).state.empty() ? std::string(screen_text::tr(screen_text::txt::status_no_network)) : id(wifi_ip).state; };
|
||||
settings_screen::firmware_text = []() { return std::string("${SCREEN_FIRMWARE_VERSION}"); };
|
||||
settings_screen::link_text = []() { return std::string(esphome::api_is_connected() ? "Connected" : "Not connected"); };
|
||||
settings_screen::restart_device = []() { ESP_LOGI("settings", "restart from the screen"); App.safe_reboot(); };
|
||||
@@ -663,21 +666,35 @@ font:
|
||||
id: headline
|
||||
size: ${FONT_HEADLINE_SIZE}
|
||||
bpp: 4
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
|
||||
'0','1','2','3','4','5','6','7','8','9',
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'ä','ö','ü','Ä','Ö','Ü','ß','/','·']
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°','0','1','2','3','4','5',
|
||||
'6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||
'U','V','W','X','Y','Z',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
|
||||
'r','s','t','u','v','w','x','y','z','/','·',
|
||||
'À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø',
|
||||
'Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð',
|
||||
'ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','þ','ÿ','Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń',
|
||||
'Ś','ś','Ź','ź','Ż','ż','Č','č','Ď','ď','Ě','ě','Ň','ň','Ř','ř','Š','š','Ť','ť','Ů','ů','Ž','ž',
|
||||
'Ĺ','ĺ','Ľ','ľ','Ŕ','ŕ','Ő','ő','Ű','ű','Ă','ă','Ș','ș','Ț','ț','Đ','đ','Ā','ā','Ē','ē','Ģ','ģ',
|
||||
'Ī','ī','Ķ','ķ','Ļ','ļ','Ņ','ņ','Ū','ū','Ė','ė','Į','į','Ų','ų','Ğ','ğ','İ','ı','Ş','ş','Ċ','ċ',
|
||||
'Ġ','ġ','Ħ','ħ','Ŵ','ŵ','Ŷ','ŷ','Ŀ','ŀ','Œ','œ','Ÿ','„','“','”','‘','’','«','»','‹','›','¿','¡',
|
||||
'€','£']
|
||||
|
||||
- file: "${FONT_DIR}/Roboto-500.ttf"
|
||||
id: watch_value
|
||||
size: ${FONT_WATCH_VALUE_SIZE}
|
||||
bpp: 4
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
|
||||
'0','1','2','3','4','5','6','7','8','9',
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'ä','ö','ü','Ä','Ö','Ü','ß','/','·']
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°','0','1','2','3','4','5',
|
||||
'6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||
'U','V','W','X','Y','Z',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
|
||||
'r','s','t','u','v','w','x','y','z','/','·',
|
||||
'À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø',
|
||||
'Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð',
|
||||
'ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','þ','ÿ','Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń',
|
||||
'Ś','ś','Ź','ź','Ż','ż','Č','č','Ď','ď','Ě','ě','Ň','ň','Ř','ř','Š','š','Ť','ť','Ů','ů','Ž','ž',
|
||||
'Ĺ','ĺ','Ľ','ľ','Ŕ','ŕ','Ő','ő','Ű','ű','Ă','ă','Ș','ș','Ț','ț','Đ','đ','Ā','ā','Ē','ē','Ģ','ģ',
|
||||
'Ī','ī','Ķ','ķ','Ļ','ļ','Ņ','ņ','Ū','ū','Ė','ė','Į','į','Ų','ų','Ğ','ğ','İ','ı','Ş','ş','Ċ','ċ',
|
||||
'Ġ','ġ','Ħ','ħ','Ŵ','ŵ','Ŷ','ŷ','Ŀ','ŀ','Œ','œ','Ÿ','„','“','”','‘','’','«','»','‹','›','¿','¡',
|
||||
'€','£']
|
||||
|
||||
# Clock card digits only; the date line reuses the tile title font.
|
||||
- file: "${FONT_DIR}/Roboto-500.ttf"
|
||||
@@ -697,31 +714,52 @@ font:
|
||||
id: label
|
||||
size: ${FONT_LABEL_SIZE}
|
||||
bpp: 4
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
|
||||
'0','1','2','3','4','5','6','7','8','9',
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'ä','ö','ü','Ä','Ö','Ü','ß','/','·']
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°','0','1','2','3','4','5',
|
||||
'6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||
'U','V','W','X','Y','Z',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
|
||||
'r','s','t','u','v','w','x','y','z','/','·',
|
||||
'À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø',
|
||||
'Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð',
|
||||
'ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','þ','ÿ','Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń',
|
||||
'Ś','ś','Ź','ź','Ż','ż','Č','č','Ď','ď','Ě','ě','Ň','ň','Ř','ř','Š','š','Ť','ť','Ů','ů','Ž','ž',
|
||||
'Ĺ','ĺ','Ľ','ľ','Ŕ','ŕ','Ő','ő','Ű','ű','Ă','ă','Ș','ș','Ț','ț','Đ','đ','Ā','ā','Ē','ē','Ģ','ģ',
|
||||
'Ī','ī','Ķ','ķ','Ļ','ļ','Ņ','ņ','Ū','ū','Ė','ė','Į','į','Ų','ų','Ğ','ğ','İ','ı','Ş','ş','Ċ','ċ',
|
||||
'Ġ','ġ','Ħ','ħ','Ŵ','ŵ','Ŷ','ŷ','Ŀ','ŀ','Œ','œ','Ÿ','„','“','”','‘','’','«','»','‹','›','¿','¡',
|
||||
'€','£']
|
||||
|
||||
- file: "${FONT_DIR}/Roboto-400.ttf"
|
||||
id: sublabel
|
||||
size: ${FONT_SUBLABEL_SIZE}
|
||||
bpp: 4
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
|
||||
'0','1','2','3','4','5','6','7','8','9',
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'ä','ö','ü','Ä','Ö','Ü','ß','/','…','·']
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°','0','1','2','3','4','5',
|
||||
'6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||
'U','V','W','X','Y','Z',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
|
||||
'r','s','t','u','v','w','x','y','z','/','…','·',
|
||||
'À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø',
|
||||
'Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð',
|
||||
'ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','þ','ÿ','Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń',
|
||||
'Ś','ś','Ź','ź','Ż','ż','Č','č','Ď','ď','Ě','ě','Ň','ň','Ř','ř','Š','š','Ť','ť','Ů','ů','Ž','ž',
|
||||
'Ĺ','ĺ','Ľ','ľ','Ŕ','ŕ','Ő','ő','Ű','ű','Ă','ă','Ș','ș','Ț','ț','Đ','đ','Ā','ā','Ē','ē','Ģ','ģ',
|
||||
'Ī','ī','Ķ','ķ','Ļ','ļ','Ņ','ņ','Ū','ū','Ė','ė','Į','į','Ų','ų','Ğ','ğ','İ','ı','Ş','ş','Ċ','ċ',
|
||||
'Ġ','ġ','Ħ','ħ','Ŵ','ŵ','Ŷ','ŷ','Ŀ','ŀ','Œ','œ','Ÿ','„','“','”','‘','’','«','»','‹','›','¿','¡',
|
||||
'€','£']
|
||||
|
||||
- file: "${FONT_DIR}/Roboto-400.ttf"
|
||||
id: sublabel_big
|
||||
size: ${FONT_SUBLABEL_BIG_SIZE}
|
||||
bpp: 4
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
|
||||
'0','1','2','3','4','5','6','7','8','9',
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'ä','ö','ü','Ä','Ö','Ü','ß','/','…','·',"'",'#','*','=',';','²','³','µ','é','è','ë','ê','ï','î','ó','ô','à','á','â','ç','ñ','ú','û','–']
|
||||
glyphs: ['<','>','—','&','@','!',',','.','?','"','%','(',')','+','-','_',':','°','0','1','2','3','4','5',
|
||||
'6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||
'U','V','W','X','Y','Z',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
|
||||
'r','s','t','u','v','w','x','y','z','/','…','·',"'",'#','*','=',';','²','³','µ','–',
|
||||
'À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø',
|
||||
'Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð',
|
||||
'ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','þ','ÿ','Ą','ą','Ć','ć','Ę','ę','Ł','ł','Ń','ń',
|
||||
'Ś','ś','Ź','ź','Ż','ż','Č','č','Ď','ď','Ě','ě','Ň','ň','Ř','ř','Š','š','Ť','ť','Ů','ů','Ž','ž',
|
||||
'Ĺ','ĺ','Ľ','ľ','Ŕ','ŕ','Ő','ő','Ű','ű','Ă','ă','Ș','ș','Ț','ț','Đ','đ','Ā','ā','Ē','ē','Ģ','ģ',
|
||||
'Ī','ī','Ķ','ķ','Ļ','ļ','Ņ','ņ','Ū','ū','Ė','ė','Į','į','Ų','ų','Ğ','ğ','İ','ı','Ş','ş','Ċ','ċ',
|
||||
'Ġ','ġ','Ħ','ħ','Ŵ','ŵ','Ŷ','ŷ','Ŀ','ŀ','Œ','œ','Ÿ','„','“','”','‘','’','«','»','‹','›','¿','¡',
|
||||
'€','£']
|
||||
|
||||
# Material Design Icons (MDI) — included at fonts/materialdesignicons-webfont.ttf (Apache 2.0)
|
||||
# Source: https://github.com/Templarian/MaterialDesign-Webfont
|
||||
@@ -1157,6 +1195,12 @@ text_sensor:
|
||||
entity_category: diagnostic
|
||||
lambda: 'return {"${SCREEN_FIRMWARE_VERSION}"};'
|
||||
update_interval: 60s
|
||||
# The language this firmware was built in (0.2.90+): ESP Screens offers an update when it differs from the chosen one.
|
||||
- platform: template
|
||||
name: "Screen language"
|
||||
entity_category: diagnostic
|
||||
lambda: 'return {screen_text::LANGUAGE};'
|
||||
update_interval: 60s
|
||||
# ESP Screen Manager matches the screen to its YAML profile and OTA address.
|
||||
- platform: template
|
||||
name: "Device name"
|
||||
@@ -1216,17 +1260,6 @@ switch:
|
||||
- lambda: 'settings_screen::set("dark_mode", 1);'
|
||||
turn_off_action:
|
||||
- lambda: 'settings_screen::set("dark_mode", 0);'
|
||||
- platform: template
|
||||
id: setting_clock_24h
|
||||
name: "24-hour clock"
|
||||
icon: "mdi:clock-outline"
|
||||
entity_category: config
|
||||
restore_mode: DISABLED
|
||||
lambda: return screen_settings::current.clock_24h;
|
||||
turn_on_action:
|
||||
- lambda: 'settings_screen::set("clock_24h", 1);'
|
||||
turn_off_action:
|
||||
- lambda: 'settings_screen::set("clock_24h", 0);'
|
||||
- platform: template
|
||||
id: setting_auto_home
|
||||
name: "Back to page 1"
|
||||
@@ -1461,7 +1494,7 @@ lvgl:
|
||||
width: ${ALERT_TEXT_W}
|
||||
height: ${ALERT_TITLE_H}
|
||||
long_mode: DOT
|
||||
text: "Notification"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::alert_notification));'
|
||||
text_font: headline
|
||||
clickable: false
|
||||
- label:
|
||||
@@ -1505,7 +1538,7 @@ lvgl:
|
||||
- label:
|
||||
id: alert_ok_label
|
||||
align: CENTER
|
||||
text: "OK"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::alert_ok));'
|
||||
text_font: headline
|
||||
clickable: false
|
||||
|
||||
@@ -2717,7 +2750,7 @@ lvgl:
|
||||
id: climate_set_label
|
||||
align: CENTER
|
||||
y: ${CLIMATE_CAPTION_Y}
|
||||
text: "Target"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::climate_target));'
|
||||
text_font: sublabel
|
||||
styles: paint_subtle
|
||||
clickable: false
|
||||
@@ -2912,7 +2945,7 @@ lvgl:
|
||||
- label:
|
||||
align: TOP_MID
|
||||
y: ${PICKER_TITLE_Y}
|
||||
text: "Mode"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::climate_mode));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
|
||||
@@ -2954,7 +2987,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Off"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_off));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
- obj:
|
||||
@@ -2973,7 +3006,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Heat"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_heat));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
- obj:
|
||||
@@ -2992,7 +3025,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Cool"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_cool));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
- obj:
|
||||
@@ -3011,7 +3044,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Heat/Cool"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_heat_cool));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
- obj:
|
||||
@@ -3030,7 +3063,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Auto"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_auto));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
- obj:
|
||||
@@ -3049,7 +3082,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Dry"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_dry));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
- obj:
|
||||
@@ -3068,7 +3101,7 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Fan only"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::ha_climate_fan_only));'
|
||||
text_font: sublabel_big
|
||||
clickable: false
|
||||
|
||||
@@ -3076,7 +3109,7 @@ lvgl:
|
||||
id: cfan_title
|
||||
width: 100%
|
||||
height: ${PICKER_TITLE_H}
|
||||
text: "Fan"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::climate_fan));'
|
||||
text_font: sublabel
|
||||
styles: paint_subtle
|
||||
text_align: CENTER
|
||||
@@ -3165,7 +3198,7 @@ lvgl:
|
||||
id: cswing_title
|
||||
width: 100%
|
||||
height: ${PICKER_TITLE_H}
|
||||
text: "Swing"
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::climate_swing));'
|
||||
text_font: sublabel
|
||||
styles: paint_subtle
|
||||
text_align: CENTER
|
||||
@@ -3310,7 +3343,7 @@ lvgl:
|
||||
- label:
|
||||
align: TOP_MID
|
||||
y: ${TOUCH_TEST_TITLE_Y}
|
||||
text: ${TOUCH_TEST_TITLE}
|
||||
text: !lambda 'return std::string(screen_text::tr(screen_text::txt::${TOUCH_TEST_TITLE}));'
|
||||
text_font: ${TOUCH_TEST_TITLE_FONT}
|
||||
- obj:
|
||||
x: ${TOUCH_TEST_INSET}
|
||||
@@ -4192,6 +4225,11 @@ script:
|
||||
}
|
||||
|
||||
|
||||
# The screen's texts in the LANGUAGE substitution's language: the build puts that one language in the firmware
|
||||
# (components/smart_display).
|
||||
smart_display:
|
||||
language: ${LANGUAGE}
|
||||
|
||||
# HA blueprint transport; never publishes the JSON command as an HA state.
|
||||
text:
|
||||
- platform: smart_display
|
||||
|
||||
Reference in New Issue
Block a user