Rewrite display language handling to work with locale strings instead of magic numbers.
This is required to implement further i18n functions using the language packs
This commit is contained in:
parent
6113e0737b
commit
d259042542
@ -5,7 +5,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#define CONFIG_FILENAME "/config.json"
|
#define CONFIG_FILENAME "/config.json"
|
||||||
#define CONFIG_VERSION 0x00011c00 // 0.1.28 // make sure to clean all after change
|
#define CONFIG_VERSION 0x00011d00 // 0.1.29 // make sure to clean all after change
|
||||||
|
|
||||||
#define WIFI_MAX_SSID_STRLEN 32
|
#define WIFI_MAX_SSID_STRLEN 32
|
||||||
#define WIFI_MAX_PASSWORD_STRLEN 64
|
#define WIFI_MAX_PASSWORD_STRLEN 64
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#define CHAN_MAX_NAME_STRLEN 31
|
#define CHAN_MAX_NAME_STRLEN 31
|
||||||
|
|
||||||
#define DEV_MAX_MAPPING_NAME_STRLEN 63
|
#define DEV_MAX_MAPPING_NAME_STRLEN 63
|
||||||
|
#define LOCALE_STRLEN 2
|
||||||
|
|
||||||
struct CHANNEL_CONFIG_T {
|
struct CHANNEL_CONFIG_T {
|
||||||
uint16_t MaxChannelPower;
|
uint16_t MaxChannelPower;
|
||||||
@ -144,7 +145,7 @@ struct CONFIG_T {
|
|||||||
bool ScreenSaver;
|
bool ScreenSaver;
|
||||||
uint8_t Rotation;
|
uint8_t Rotation;
|
||||||
uint8_t Contrast;
|
uint8_t Contrast;
|
||||||
uint8_t Language;
|
char Locale[LOCALE_STRLEN + 1];
|
||||||
struct {
|
struct {
|
||||||
uint32_t Duration;
|
uint32_t Duration;
|
||||||
uint8_t Mode;
|
uint8_t Mode;
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public:
|
|||||||
void setContrast(const uint8_t contrast);
|
void setContrast(const uint8_t contrast);
|
||||||
void setStatus(const bool turnOn);
|
void setStatus(const bool turnOn);
|
||||||
void setOrientation(const uint8_t rotation = DISPLAY_ROTATION);
|
void setOrientation(const uint8_t rotation = DISPLAY_ROTATION);
|
||||||
void setLanguage(const uint8_t language);
|
void setLocale(const String& locale);
|
||||||
void setDiagramMode(DiagramMode_t mode);
|
void setDiagramMode(DiagramMode_t mode);
|
||||||
void setStartupDisplay();
|
void setStartupDisplay();
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ private:
|
|||||||
|
|
||||||
DisplayType_t _display_type = DisplayType_t::None;
|
DisplayType_t _display_type = DisplayType_t::None;
|
||||||
DiagramMode_t _diagram_mode = DiagramMode_t::Off;
|
DiagramMode_t _diagram_mode = DiagramMode_t::Off;
|
||||||
uint8_t _display_language = DISPLAY_LANGUAGE;
|
String _display_language = DISPLAY_LOCALE;
|
||||||
uint8_t _mExtra;
|
uint8_t _mExtra;
|
||||||
const uint16_t _period = 1000;
|
const uint16_t _period = 1000;
|
||||||
const uint16_t _interval = 60000; // interval at which to power save (milliseconds)
|
const uint16_t _interval = 60000; // interval at which to power save (milliseconds)
|
||||||
@ -73,6 +73,15 @@ private:
|
|||||||
char _fmtText[32];
|
char _fmtText[32];
|
||||||
bool _isLarge = false;
|
bool _isLarge = false;
|
||||||
uint8_t _lineOffsets[5];
|
uint8_t _lineOffsets[5];
|
||||||
|
|
||||||
|
String _i18n_offline;
|
||||||
|
String _i18n_yield_today_kwh;
|
||||||
|
String _i18n_yield_today_wh;
|
||||||
|
String _i18n_date_format;
|
||||||
|
String _i18n_current_power_kw;
|
||||||
|
String _i18n_current_power_w;
|
||||||
|
String _i18n_yield_total_mwh;
|
||||||
|
String _i18n_yield_total_kwh;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DisplayGraphicClass Display;
|
extern DisplayGraphicClass Display;
|
||||||
|
|||||||
@ -99,7 +99,7 @@
|
|||||||
#define DISPLAY_SCREENSAVER true
|
#define DISPLAY_SCREENSAVER true
|
||||||
#define DISPLAY_ROTATION 2U
|
#define DISPLAY_ROTATION 2U
|
||||||
#define DISPLAY_CONTRAST 60U
|
#define DISPLAY_CONTRAST 60U
|
||||||
#define DISPLAY_LANGUAGE 0U
|
#define DISPLAY_LOCALE "en"
|
||||||
#define DISPLAY_DIAGRAM_DURATION (10UL * 60UL * 60UL)
|
#define DISPLAY_DIAGRAM_DURATION (10UL * 60UL * 60UL)
|
||||||
#define DISPLAY_DIAGRAM_MODE 1U
|
#define DISPLAY_DIAGRAM_MODE 1U
|
||||||
|
|
||||||
|
|||||||
@ -107,7 +107,7 @@ bool ConfigurationClass::write()
|
|||||||
display["screensaver"] = config.Display.ScreenSaver;
|
display["screensaver"] = config.Display.ScreenSaver;
|
||||||
display["rotation"] = config.Display.Rotation;
|
display["rotation"] = config.Display.Rotation;
|
||||||
display["contrast"] = config.Display.Contrast;
|
display["contrast"] = config.Display.Contrast;
|
||||||
display["language"] = config.Display.Language;
|
display["locale"] = config.Display.Locale;
|
||||||
display["diagram_duration"] = config.Display.Diagram.Duration;
|
display["diagram_duration"] = config.Display.Diagram.Duration;
|
||||||
display["diagram_mode"] = config.Display.Diagram.Mode;
|
display["diagram_mode"] = config.Display.Diagram.Mode;
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ bool ConfigurationClass::read()
|
|||||||
config.Display.ScreenSaver = display["screensaver"] | DISPLAY_SCREENSAVER;
|
config.Display.ScreenSaver = display["screensaver"] | DISPLAY_SCREENSAVER;
|
||||||
config.Display.Rotation = display["rotation"] | DISPLAY_ROTATION;
|
config.Display.Rotation = display["rotation"] | DISPLAY_ROTATION;
|
||||||
config.Display.Contrast = display["contrast"] | DISPLAY_CONTRAST;
|
config.Display.Contrast = display["contrast"] | DISPLAY_CONTRAST;
|
||||||
config.Display.Language = display["language"] | DISPLAY_LANGUAGE;
|
strlcpy(config.Display.Locale, display["locale"] | DISPLAY_LOCALE, sizeof(config.Display.Locale));
|
||||||
config.Display.Diagram.Duration = display["diagram_duration"] | DISPLAY_DIAGRAM_DURATION;
|
config.Display.Diagram.Duration = display["diagram_duration"] | DISPLAY_DIAGRAM_DURATION;
|
||||||
config.Display.Diagram.Mode = display["diagram_mode"] | DISPLAY_DIAGRAM_MODE;
|
config.Display.Diagram.Mode = display["diagram_mode"] | DISPLAY_DIAGRAM_MODE;
|
||||||
|
|
||||||
@ -383,6 +383,22 @@ void ConfigurationClass::migrate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.Cfg.Version < 0x00011d00) {
|
||||||
|
JsonObject device = doc["device"];
|
||||||
|
JsonObject display = device["display"];
|
||||||
|
switch (display["language"] | 0U) {
|
||||||
|
case 0U:
|
||||||
|
strlcpy(config.Display.Locale, "en", sizeof(config.Display.Locale));
|
||||||
|
break;
|
||||||
|
case 1U:
|
||||||
|
strlcpy(config.Display.Locale, "de", sizeof(config.Display.Locale));
|
||||||
|
break;
|
||||||
|
case 2U:
|
||||||
|
strlcpy(config.Display.Locale, "fr", sizeof(config.Display.Locale));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
config.Cfg.Version = CONFIG_VERSION;
|
config.Cfg.Version = CONFIG_VERSION;
|
||||||
|
|||||||
@ -16,18 +16,11 @@ std::map<DisplayType_t, std::function<U8G2*(uint8_t, uint8_t, uint8_t, uint8_t)>
|
|||||||
{ DisplayType_t::ST7567_GM12864I_59N, [](uint8_t reset, uint8_t clock, uint8_t data, uint8_t cs) { return new U8G2_ST7567_ENH_DG128064I_F_HW_I2C(U8G2_R0, reset, clock, data); } },
|
{ DisplayType_t::ST7567_GM12864I_59N, [](uint8_t reset, uint8_t clock, uint8_t data, uint8_t cs) { return new U8G2_ST7567_ENH_DG128064I_F_HW_I2C(U8G2_R0, reset, clock, data); } },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Language defintion, respect order in languages[] and translation lists
|
// Language defintion, respect order in translation lists
|
||||||
#define I18N_LOCALE_EN 0
|
#define I18N_LOCALE_EN 0
|
||||||
#define I18N_LOCALE_DE 1
|
#define I18N_LOCALE_DE 1
|
||||||
#define I18N_LOCALE_FR 2
|
#define I18N_LOCALE_FR 2
|
||||||
|
|
||||||
// Languages supported. Note: the order is important and must match locale_translations.h
|
|
||||||
const uint8_t languages[] = {
|
|
||||||
I18N_LOCALE_EN,
|
|
||||||
I18N_LOCALE_DE,
|
|
||||||
I18N_LOCALE_FR
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char* const i18n_offline[] = { "Offline", "Offline", "Offline" };
|
static const char* const i18n_offline[] = { "Offline", "Offline", "Offline" };
|
||||||
|
|
||||||
static const char* const i18n_current_power_w[] = { "%.0f W", "%.0f W", "%.0f W" };
|
static const char* const i18n_current_power_w[] = { "%.0f W", "%.0f W", "%.0f W" };
|
||||||
@ -166,9 +159,24 @@ void DisplayGraphicClass::setOrientation(const uint8_t rotation)
|
|||||||
calcLineHeights();
|
calcLineHeights();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGraphicClass::setLanguage(const uint8_t language)
|
void DisplayGraphicClass::setLocale(const String& locale)
|
||||||
{
|
{
|
||||||
_display_language = language < sizeof(languages) / sizeof(languages[0]) ? language : DISPLAY_LANGUAGE;
|
_display_language = locale;
|
||||||
|
uint8_t idx = I18N_LOCALE_EN;
|
||||||
|
if (locale == "de") {
|
||||||
|
idx = I18N_LOCALE_DE;
|
||||||
|
} else if (locale == "fr") {
|
||||||
|
idx = I18N_LOCALE_FR;
|
||||||
|
}
|
||||||
|
|
||||||
|
_i18n_offline = i18n_offline[idx];
|
||||||
|
_i18n_yield_today_kwh = i18n_yield_today_kwh[idx];
|
||||||
|
_i18n_yield_today_wh = i18n_yield_today_wh[idx];
|
||||||
|
_i18n_date_format = i18n_date_format[idx];
|
||||||
|
_i18n_current_power_kw = i18n_current_power_kw[idx];
|
||||||
|
_i18n_current_power_w = i18n_current_power_w[idx];
|
||||||
|
_i18n_yield_total_mwh = i18n_yield_total_mwh[idx];
|
||||||
|
_i18n_yield_total_kwh = i18n_yield_total_kwh[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayGraphicClass::setDiagramMode(DiagramMode_t mode)
|
void DisplayGraphicClass::setDiagramMode(DiagramMode_t mode)
|
||||||
@ -225,9 +233,9 @@ void DisplayGraphicClass::loop()
|
|||||||
if (showText) {
|
if (showText) {
|
||||||
const float watts = Datastore.getTotalAcPowerEnabled();
|
const float watts = Datastore.getTotalAcPowerEnabled();
|
||||||
if (watts > 999) {
|
if (watts > 999) {
|
||||||
snprintf(_fmtText, sizeof(_fmtText), i18n_current_power_kw[_display_language], watts / 1000);
|
snprintf(_fmtText, sizeof(_fmtText), _i18n_current_power_kw.c_str(), watts / 1000);
|
||||||
} else {
|
} else {
|
||||||
snprintf(_fmtText, sizeof(_fmtText), i18n_current_power_w[_display_language], watts);
|
snprintf(_fmtText, sizeof(_fmtText), _i18n_current_power_w.c_str(), watts);
|
||||||
}
|
}
|
||||||
printText(_fmtText, 0);
|
printText(_fmtText, 0);
|
||||||
}
|
}
|
||||||
@ -237,7 +245,7 @@ void DisplayGraphicClass::loop()
|
|||||||
|
|
||||||
//=====> Offline ===========
|
//=====> Offline ===========
|
||||||
else {
|
else {
|
||||||
printText(i18n_offline[_display_language], 0);
|
printText(_i18n_offline.c_str(), 0);
|
||||||
// check if it's time to enter power saving mode
|
// check if it's time to enter power saving mode
|
||||||
if (millis() - _previousMillis >= (_interval * 2)) {
|
if (millis() - _previousMillis >= (_interval * 2)) {
|
||||||
displayPowerSave = enablePowerSafe;
|
displayPowerSave = enablePowerSafe;
|
||||||
@ -249,16 +257,16 @@ void DisplayGraphicClass::loop()
|
|||||||
// Daily production
|
// Daily production
|
||||||
float wattsToday = Datastore.getTotalAcYieldDayEnabled();
|
float wattsToday = Datastore.getTotalAcYieldDayEnabled();
|
||||||
if (wattsToday >= 10000) {
|
if (wattsToday >= 10000) {
|
||||||
snprintf(_fmtText, sizeof(_fmtText), i18n_yield_today_kwh[_display_language], wattsToday / 1000);
|
snprintf(_fmtText, sizeof(_fmtText), _i18n_yield_today_kwh.c_str(), wattsToday / 1000);
|
||||||
} else {
|
} else {
|
||||||
snprintf(_fmtText, sizeof(_fmtText), i18n_yield_today_wh[_display_language], wattsToday);
|
snprintf(_fmtText, sizeof(_fmtText), _i18n_yield_today_wh.c_str(), wattsToday);
|
||||||
}
|
}
|
||||||
printText(_fmtText, 1);
|
printText(_fmtText, 1);
|
||||||
|
|
||||||
// Total production
|
// Total production
|
||||||
const float wattsTotal = Datastore.getTotalAcYieldTotalEnabled();
|
const float wattsTotal = Datastore.getTotalAcYieldTotalEnabled();
|
||||||
auto const format = (wattsTotal >= 1000) ? i18n_yield_total_mwh : i18n_yield_total_kwh;
|
auto const format = (wattsTotal >= 1000) ? _i18n_yield_total_mwh : _i18n_yield_total_kwh;
|
||||||
snprintf(_fmtText, sizeof(_fmtText), format[_display_language], wattsTotal);
|
snprintf(_fmtText, sizeof(_fmtText), format.c_str(), wattsTotal);
|
||||||
printText(_fmtText, 2);
|
printText(_fmtText, 2);
|
||||||
|
|
||||||
//=====> IP or Date-Time ========
|
//=====> IP or Date-Time ========
|
||||||
@ -268,7 +276,7 @@ void DisplayGraphicClass::loop()
|
|||||||
} else {
|
} else {
|
||||||
// Get current time
|
// Get current time
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
strftime(_fmtText, sizeof(_fmtText), i18n_date_format[_display_language], localtime(&now));
|
strftime(_fmtText, sizeof(_fmtText), _i18n_date_format.c_str(), localtime(&now));
|
||||||
printText(_fmtText, 3);
|
printText(_fmtText, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
|||||||
display["power_safe"] = config.Display.PowerSafe;
|
display["power_safe"] = config.Display.PowerSafe;
|
||||||
display["screensaver"] = config.Display.ScreenSaver;
|
display["screensaver"] = config.Display.ScreenSaver;
|
||||||
display["contrast"] = config.Display.Contrast;
|
display["contrast"] = config.Display.Contrast;
|
||||||
display["language"] = config.Display.Language;
|
display["locale"] = config.Display.Locale;
|
||||||
display["diagramduration"] = config.Display.Diagram.Duration;
|
display["diagramduration"] = config.Display.Diagram.Duration;
|
||||||
display["diagrammode"] = config.Display.Diagram.Mode;
|
display["diagrammode"] = config.Display.Diagram.Mode;
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
|||||||
config.Display.PowerSafe = root["display"]["power_safe"].as<bool>();
|
config.Display.PowerSafe = root["display"]["power_safe"].as<bool>();
|
||||||
config.Display.ScreenSaver = root["display"]["screensaver"].as<bool>();
|
config.Display.ScreenSaver = root["display"]["screensaver"].as<bool>();
|
||||||
config.Display.Contrast = root["display"]["contrast"].as<uint8_t>();
|
config.Display.Contrast = root["display"]["contrast"].as<uint8_t>();
|
||||||
config.Display.Language = root["display"]["language"].as<uint8_t>();
|
strlcpy(config.Display.Locale, root["display"]["locale"].as<String>().c_str(), sizeof(config.Display.Locale));
|
||||||
config.Display.Diagram.Duration = root["display"]["diagramduration"].as<uint32_t>();
|
config.Display.Diagram.Duration = root["display"]["diagramduration"].as<uint32_t>();
|
||||||
config.Display.Diagram.Mode = root["display"]["diagrammode"].as<DiagramMode_t>();
|
config.Display.Diagram.Mode = root["display"]["diagrammode"].as<DiagramMode_t>();
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
|
|||||||
Display.enablePowerSafe = config.Display.PowerSafe;
|
Display.enablePowerSafe = config.Display.PowerSafe;
|
||||||
Display.enableScreensaver = config.Display.ScreenSaver;
|
Display.enableScreensaver = config.Display.ScreenSaver;
|
||||||
Display.setContrast(config.Display.Contrast);
|
Display.setContrast(config.Display.Contrast);
|
||||||
Display.setLanguage(config.Display.Language);
|
Display.setLocale(config.Display.Locale);
|
||||||
Display.Diagram().updatePeriod();
|
Display.Diagram().updatePeriod();
|
||||||
|
|
||||||
WebApi.writeConfig(retMsg);
|
WebApi.writeConfig(retMsg);
|
||||||
|
|||||||
@ -143,7 +143,7 @@ void setup()
|
|||||||
Display.enablePowerSafe = config.Display.PowerSafe;
|
Display.enablePowerSafe = config.Display.PowerSafe;
|
||||||
Display.enableScreensaver = config.Display.ScreenSaver;
|
Display.enableScreensaver = config.Display.ScreenSaver;
|
||||||
Display.setContrast(config.Display.Contrast);
|
Display.setContrast(config.Display.Contrast);
|
||||||
Display.setLanguage(config.Display.Language);
|
Display.setLocale(config.Display.Locale);
|
||||||
Display.setStartupDisplay();
|
Display.setStartupDisplay();
|
||||||
MessageOutput.println("done");
|
MessageOutput.println("done");
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export interface Display {
|
|||||||
power_safe: boolean;
|
power_safe: boolean;
|
||||||
screensaver: boolean;
|
screensaver: boolean;
|
||||||
contrast: number;
|
contrast: number;
|
||||||
language: number;
|
locale: string;
|
||||||
diagramduration: number;
|
diagramduration: number;
|
||||||
diagrammode: number;
|
diagrammode: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -160,13 +160,13 @@
|
|||||||
{{ $t('deviceadmin.DisplayLanguage') }}
|
{{ $t('deviceadmin.DisplayLanguage') }}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-select" v-model="deviceConfigList.display.language">
|
<select class="form-select" v-model="deviceConfigList.display.locale">
|
||||||
<option
|
<option
|
||||||
v-for="language in displayLanguageList"
|
v-for="locale in displayLocaleList"
|
||||||
:key="language.key"
|
:key="locale.key"
|
||||||
:value="language.key"
|
:value="locale.key"
|
||||||
>
|
>
|
||||||
{{ $t(`deviceadmin.` + language.value) }}
|
{{ $t(`deviceadmin.` + locale.value) }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -289,10 +289,10 @@ export default defineComponent({
|
|||||||
{ key: 2, value: 'rot180' },
|
{ key: 2, value: 'rot180' },
|
||||||
{ key: 3, value: 'rot270' },
|
{ key: 3, value: 'rot270' },
|
||||||
],
|
],
|
||||||
displayLanguageList: [
|
displayLocaleList: [
|
||||||
{ key: 0, value: 'en' },
|
{ key: 'en', value: 'en' },
|
||||||
{ key: 1, value: 'de' },
|
{ key: 'de', value: 'de' },
|
||||||
{ key: 2, value: 'fr' },
|
{ key: 'fr', value: 'fr' },
|
||||||
],
|
],
|
||||||
diagramModeList: [
|
diagramModeList: [
|
||||||
{ key: 0, value: 'off' },
|
{ key: 0, value: 'off' },
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user