mirror of
https://github.com/revspace/operame
synced 2024-12-04 13:47:29 +00:00
Add basic i18n support and English translations
This commit is contained in:
parent
f76e092998
commit
69ddf8054a
@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
Dit is de broncode van de firmware voor de [Operame CO2-meter](https://operame.nl/).
|
Dit is de broncode van de firmware voor de [Operame CO2-meter](https://operame.nl/).
|
||||||
|
|
||||||
|
## Language
|
||||||
|
|
||||||
|
The default language is Dutch; users can pick a different language using the
|
||||||
|
WiFi configuration portal. To change the default setting to English, change
|
||||||
|
`#define LANGUAGE "nl"` to `#define LANGUAGE "en"`.
|
||||||
|
|
||||||
## Gebruik
|
## Gebruik
|
||||||
|
|
||||||
### Installatie
|
### Installatie
|
||||||
|
89
operame.ino
89
operame.ino
@ -8,8 +8,10 @@
|
|||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
#include <logo.h>
|
#include <logo.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <operame_strings.h>
|
||||||
|
|
||||||
#define LANGUAGE "nl"
|
#define LANGUAGE "nl"
|
||||||
|
OperameLanguage::Texts T;
|
||||||
|
|
||||||
enum Driver { AQC, MHZ };
|
enum Driver { AQC, MHZ };
|
||||||
Driver driver;
|
Driver driver;
|
||||||
@ -178,7 +180,7 @@ void connect_mqtt() {
|
|||||||
failures = 0;
|
failures = 0;
|
||||||
} else {
|
} else {
|
||||||
failures++;
|
failures++;
|
||||||
if (failures >= max_failures) panic("MQTT onbereikbaar");
|
if (failures >= max_failures) panic(T.error_mqtt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +260,7 @@ int get_co2() {
|
|||||||
if (driver == MHZ) return mhz_get_co2();
|
if (driver == MHZ) return mhz_get_co2();
|
||||||
|
|
||||||
// Should be unreachable
|
// Should be unreachable
|
||||||
panic("driverfout");
|
panic(T.error_driver);
|
||||||
return -1; // suppress warning
|
return -1; // suppress warning
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +282,7 @@ void setup() {
|
|||||||
sprite.createSprite(display.width(), display.height());
|
sprite.createSprite(display.width(), display.height());
|
||||||
|
|
||||||
while (digitalRead(pin_pcb_ok)) {
|
while (digitalRead(pin_pcb_ok)) {
|
||||||
display_big("module verkeerd om!", TFT_RED);
|
display_big(T.error_module, TFT_RED);
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,32 +303,39 @@ void setup() {
|
|||||||
|
|
||||||
WiFiSettings.hostname = "operame-";
|
WiFiSettings.hostname = "operame-";
|
||||||
WiFiSettings.language = LANGUAGE;
|
WiFiSettings.language = LANGUAGE;
|
||||||
wifi_enabled = WiFiSettings.checkbox("operame_wifi", false, "WiFi-verbinding gebruiken");
|
WiFiSettings.begin();
|
||||||
ota_enabled = WiFiSettings.checkbox("operame_ota", false, "Draadloos herprogrammeren inschakelen. (Gebruikt portaalwachtwoord!)") && wifi_enabled;
|
|
||||||
|
OperameLanguage::select(T, WiFiSettings.language);
|
||||||
|
for (auto& str : T.portal_instructions[0]) {
|
||||||
|
str.replace("{ssid}", WiFiSettings.hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi_enabled = WiFiSettings.checkbox("operame_wifi", false, T.config_wifi);
|
||||||
|
ota_enabled = WiFiSettings.checkbox("operame_ota", false, T.config_ota) && wifi_enabled;
|
||||||
|
|
||||||
WiFiSettings.heading("CO2-niveaus");
|
WiFiSettings.heading("CO2-niveaus");
|
||||||
co2_warning = WiFiSettings.integer("operame_co2_warning", 400, 5000, 700, "Geel vanaf [ppm]");
|
co2_warning = WiFiSettings.integer("operame_co2_warning", 400, 5000, 700, T.config_co2_warning);
|
||||||
co2_critical = WiFiSettings.integer("operame_co2_critical",400, 5000, 800, "Rood vanaf [ppm]");
|
co2_critical = WiFiSettings.integer("operame_co2_critical",400, 5000, 800, T.config_co2_critical);
|
||||||
co2_blink = WiFiSettings.integer("operame_co2_blink", 800, 5000, 800, "Knipperen vanaf [ppm]");
|
co2_blink = WiFiSettings.integer("operame_co2_blink", 800, 5000, 800, T.config_co2_blink);
|
||||||
|
|
||||||
WiFiSettings.heading("MQTT");
|
WiFiSettings.heading("MQTT");
|
||||||
mqtt_enabled = WiFiSettings.checkbox("operame_mqtt", false, "Metingen via het MQTT-protocol versturen") && wifi_enabled;
|
mqtt_enabled = WiFiSettings.checkbox("operame_mqtt", false, T.config_mqtt) && wifi_enabled;
|
||||||
String server = WiFiSettings.string("mqtt_server", 64, "", "Broker");
|
String server = WiFiSettings.string("mqtt_server", 64, "", T.config_mqtt_server);
|
||||||
int port = WiFiSettings.integer("mqtt_port", 0, 65535, 1883, "Broker TCP-poort");
|
int port = WiFiSettings.integer("mqtt_port", 0, 65535, 1883, T.config_mqtt_port);
|
||||||
max_failures = WiFiSettings.integer("operame_max_failures", 0, 1000, 10, "Aantal verbindingsfouten voor automatische herstart");
|
max_failures = WiFiSettings.integer("operame_max_failures", 0, 1000, 10, T.config_max_failures);
|
||||||
mqtt_topic = WiFiSettings.string("operame_mqtt_topic", WiFiSettings.hostname, "Topic");
|
mqtt_topic = WiFiSettings.string("operame_mqtt_topic", WiFiSettings.hostname, T.config_mqtt_topic);
|
||||||
mqtt_interval = 1000UL * WiFiSettings.integer("operame_mqtt_interval", 10, 3600, 60, "Publicatie-interval [s]");
|
mqtt_interval = 1000UL * WiFiSettings.integer("operame_mqtt_interval", 10, 3600, 60, T.config_mqtt_interval);
|
||||||
mqtt_template = WiFiSettings.string("operame_mqtt_template", "{} PPM", "Berichtsjabloon");
|
mqtt_template = WiFiSettings.string("operame_mqtt_template", "{} PPM", T.config_mqtt_template);
|
||||||
WiFiSettings.info("De {} in het sjabloon wordt vervangen door de gemeten waarde.");
|
WiFiSettings.info(T.config_template_info);
|
||||||
|
|
||||||
|
|
||||||
WiFiSettings.onConnect = [] {
|
WiFiSettings.onConnect = [] {
|
||||||
display_big("Verbinden met WiFi...", TFT_BLUE);
|
display_big(T.connecting, TFT_BLUE);
|
||||||
check_portalbutton();
|
check_portalbutton();
|
||||||
return 50;
|
return 50;
|
||||||
};
|
};
|
||||||
WiFiSettings.onFailure = [] {
|
WiFiSettings.onFailure = [] {
|
||||||
display_big("WiFi mislukt!", TFT_RED);
|
display_big(T.error_wifi, TFT_RED);
|
||||||
delay(2000);
|
delay(2000);
|
||||||
};
|
};
|
||||||
static int portal_phase = 0;
|
static int portal_phase = 0;
|
||||||
@ -345,44 +354,10 @@ void setup() {
|
|||||||
if (WiFi.softAPgetStationNum() == 0) portal_phase = 0;
|
if (WiFi.softAPgetStationNum() == 0) portal_phase = 0;
|
||||||
else if (! portal_phase) portal_phase = 1;
|
else if (! portal_phase) portal_phase = 1;
|
||||||
|
|
||||||
switch (portal_phase) {
|
display_lines(T.portal_instructions[portal_phase], TFT_WHITE, TFT_BLUE);
|
||||||
case 0: {
|
|
||||||
display_lines({
|
|
||||||
"Voor configuratie,",
|
|
||||||
"verbind met WiFi",
|
|
||||||
"\"" + WiFiSettings.hostname + "\"",
|
|
||||||
"met een smartphone."
|
|
||||||
}, TFT_WHITE, TFT_BLUE);
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
case 1: {
|
|
||||||
display_lines({
|
|
||||||
"Volg instructies op",
|
|
||||||
"uw smartphone.",
|
|
||||||
"(inlog-notificatie)"
|
|
||||||
}, TFT_WHITE, TFT_BLUE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
display_lines({
|
|
||||||
"Wijzig instellingen",
|
|
||||||
"en klik op \"Save\".",
|
|
||||||
"(rechtsonder)"
|
|
||||||
}, TFT_WHITE, TFT_BLUE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
display_lines({
|
|
||||||
"Wijzig instellingen",
|
|
||||||
"en klik op \"Save\".",
|
|
||||||
"Of \"Restart device\"",
|
|
||||||
"als u klaar bent."
|
|
||||||
}, TFT_WHITE, TFT_BLUE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (portal_phase == 0 && millis() - portal_start > 10*60*1000) {
|
if (portal_phase == 0 && millis() - portal_start > 10*60*1000) {
|
||||||
panic("Tijd verstreken");
|
panic(T.error_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ota_enabled) ArduinoOTA.handle();
|
if (ota_enabled) ArduinoOTA.handle();
|
||||||
@ -409,9 +384,9 @@ void loop() {
|
|||||||
|
|
||||||
every(50) {
|
every(50) {
|
||||||
if (co2 < 0) {
|
if (co2 < 0) {
|
||||||
display_big("sensorfout", TFT_RED);
|
display_big(T.error_sensor, TFT_RED);
|
||||||
} else if (co2 == 0) {
|
} else if (co2 == 0) {
|
||||||
display_big("wacht...");
|
display_big(T.wait);
|
||||||
} else {
|
} else {
|
||||||
// some MH-Z19's go to 10000 but the display has space for 4 digits
|
// some MH-Z19's go to 10000 but the display has space for 4 digits
|
||||||
display_ppm(co2 > 9999 ? 9999 : co2);
|
display_ppm(co2 > 9999 ? 9999 : co2);
|
||||||
|
151
operame_strings.h
Normal file
151
operame_strings.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace OperameLanguage {
|
||||||
|
|
||||||
|
struct Texts {
|
||||||
|
const char
|
||||||
|
*error_mqtt,
|
||||||
|
*error_driver,
|
||||||
|
*error_module,
|
||||||
|
*error_timeout,
|
||||||
|
*error_sensor,
|
||||||
|
*error_wifi,
|
||||||
|
*config_wifi,
|
||||||
|
*config_ota,
|
||||||
|
*config_co2_warning,
|
||||||
|
*config_co2_critical,
|
||||||
|
*config_co2_blink,
|
||||||
|
*config_mqtt,
|
||||||
|
*config_mqtt_server,
|
||||||
|
*config_mqtt_port,
|
||||||
|
*config_max_failures,
|
||||||
|
*config_mqtt_topic,
|
||||||
|
*config_mqtt_interval,
|
||||||
|
*config_mqtt_template,
|
||||||
|
*config_template_info,
|
||||||
|
*connecting,
|
||||||
|
*wait
|
||||||
|
;
|
||||||
|
std::vector<std::list<String>> portal_instructions;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<const String, const String> languages {
|
||||||
|
// Ordered alphabetically
|
||||||
|
{ "en", "English" },
|
||||||
|
{ "nl", "Nederlands" },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool available(const String& language) {
|
||||||
|
return languages.count(language) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool select(Texts& T, String language) {
|
||||||
|
if (! available(language)) {
|
||||||
|
if (available("en")) language = "en";
|
||||||
|
else language = languages.begin()->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language == "en") {
|
||||||
|
T.error_mqtt = "MQTT unreachable";
|
||||||
|
T.error_driver = "driver error";
|
||||||
|
T.error_module = "module turned around!";
|
||||||
|
T.error_timeout = "Time's up";
|
||||||
|
T.error_sensor = "sensor error";
|
||||||
|
T.error_wifi = "WiFi failed!";
|
||||||
|
T.wait = "wait...";
|
||||||
|
T.config_wifi = "Use WiFi connection";
|
||||||
|
T.config_ota = "Enable wireless reprogramming. (Uses portal password!)";
|
||||||
|
T.config_co2_warning = "Yellow from [ppm]";
|
||||||
|
T.config_co2_critical = "Red from [ppm]";
|
||||||
|
T.config_co2_blink = "Blink from [ppm]";
|
||||||
|
T.config_mqtt = "Publish measurements via the MQTT protocol";
|
||||||
|
T.config_mqtt_server = "Broker"; // probably should not be translated
|
||||||
|
T.config_mqtt_port = "Broker TCP port";
|
||||||
|
T.config_max_failures = "Number of failed connections before automatic restart";
|
||||||
|
T.config_mqtt_topic = "Topic"; // probably should not be translated
|
||||||
|
T.config_mqtt_interval = "Publication interval [s]";
|
||||||
|
T.config_mqtt_template = "Message template";
|
||||||
|
T.config_template_info = "The {} in the template is replaced by the measurement value.";
|
||||||
|
T.connecting = "Connecting to WiFi...";
|
||||||
|
T.portal_instructions = {
|
||||||
|
{
|
||||||
|
"For configuration,",
|
||||||
|
"connect to WiFi",
|
||||||
|
"\"{ssid}\"",
|
||||||
|
"with a smartphone."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Follow instructions",
|
||||||
|
"on your smartphone.",
|
||||||
|
"(log in notification)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Change settings",
|
||||||
|
"and click \"Save\".",
|
||||||
|
"(bottom right)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Change settings",
|
||||||
|
"and click \"Save\".",
|
||||||
|
"Or \"Restart device\"",
|
||||||
|
"when you're done."
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(language == "nl") {
|
||||||
|
T.error_mqtt = "MQTT onbereikbaar";
|
||||||
|
T.error_driver = "driverfout";
|
||||||
|
T.error_module = "module verkeerd om!";
|
||||||
|
T.error_timeout = "Tijd verstreken";
|
||||||
|
T.error_sensor = "sensorfout";
|
||||||
|
T.error_wifi = "WiFi mislukt!";
|
||||||
|
T.wait = "wacht...";
|
||||||
|
T.config_wifi = "WiFi-verbinding gebruiken";
|
||||||
|
T.config_ota = "Draadloos herprogrammeren inschakelen. (Gebruikt portaalwachtwoord!)";
|
||||||
|
T.config_co2_warning = "Geel vanaf [ppm]";
|
||||||
|
T.config_co2_critical = "Rood vanaf [ppm]";
|
||||||
|
T.config_co2_blink = "Knipperen vanaf [ppm]";
|
||||||
|
T.config_mqtt = "Metingen via het MQTT-protocol versturen";
|
||||||
|
T.config_mqtt_server = "Broker"; // zo heet dat in MQTT
|
||||||
|
T.config_mqtt_port = "Broker TCP-poort";
|
||||||
|
T.config_max_failures = "Aantal verbindingsfouten voor automatische herstart";
|
||||||
|
T.config_mqtt_topic = "Topic"; // zo heet dat in MQTT
|
||||||
|
T.config_mqtt_interval = "Publicatie-interval [s]";
|
||||||
|
T.config_mqtt_template = "Berichtsjabloon";
|
||||||
|
T.config_template_info = "De {} in het sjabloon wordt vervangen door de gemeten waarde.";
|
||||||
|
T.connecting = "Verbinden met WiFi...";
|
||||||
|
T.portal_instructions = {
|
||||||
|
{
|
||||||
|
"Voor configuratie,",
|
||||||
|
"verbind met WiFi",
|
||||||
|
"\"{ssid}\"",
|
||||||
|
"met een smartphone."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Volg instructies op",
|
||||||
|
"uw smartphone.",
|
||||||
|
"(inlog-notificatie)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Wijzig instellingen",
|
||||||
|
"en klik op \"Opslaan\".",
|
||||||
|
"(rechtsonder)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Wijzig instellingen",
|
||||||
|
"en klik op \"Opslaan\".",
|
||||||
|
"Of \"Herstarten\"",
|
||||||
|
"als u klaar bent."
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
@ -21,13 +21,18 @@ framework = arduino
|
|||||||
targets = upload
|
targets = upload
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
lib_deps =
|
lib_deps =
|
||||||
ESP-WiFiSettings@^3.7
|
ESP-WiFiSettings@^3.7.2
|
||||||
MH-Z19
|
MH-Z19
|
||||||
TFT_eSPI
|
TFT_eSPI
|
||||||
MQTT
|
MQTT
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
|
# ESP-WiFiSettings languages:
|
||||||
|
-DLANGUAGE_EN
|
||||||
|
-DLANGUAGE_NL
|
||||||
|
# ESP32 debugging:
|
||||||
# -DCORE_DEBUG_LEVEL=5
|
# -DCORE_DEBUG_LEVEL=5
|
||||||
|
# TFT_eSPI configuration:
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
-DST7789_DRIVER=1
|
-DST7789_DRIVER=1
|
||||||
-DCGRAM_OFFSET=1
|
-DCGRAM_OFFSET=1
|
||||||
|
Loading…
Reference in New Issue
Block a user