-
Import
+
{#IMPORT}
@@ -341,7 +337,7 @@
var ts = 0;
var esp8266pins = [
- [255, "off / default"],
+ [255, "{#PIN_OFF}"],
[0, "D3 (GPIO0)"],
[1, "TX (GPIO1)"],
[2, "D4 (GPIO2)"],
@@ -358,12 +354,12 @@
[13, "D7 (GPIO13)"],
[14, "D5 (GPIO14)"],
[15, "D8 (GPIO15)"],
- [16, "D0 (GPIO16 - no IRQ!)"]
+ [16, "D0 (GPIO16 - {#PIN_NO_IRQ})"]
];
/*IF_ESP32*/
var esp32pins = [
- [255, "off / default"],
+ [255, "{#PIN_OFF}"],
[0, "GPIO0"],
[1, "TX (GPIO1)"],
[2, "GPIO2 (LED)"],
@@ -386,14 +382,14 @@
[27, "GPIO27"],
[32, "GPIO32"],
[33, "GPIO33"],
- [34, "GPIO34 (in only)"],
- [35, "GPIO35 (in only)"],
- [36, "VP (GPIO36, in only)"],
- [39, "VN (GPIO39, in only)"]
+ [34, "GPIO34 ({#PIN_INPUT_ONLY})"],
+ [35, "GPIO35 ({#PIN_INPUT_ONLY})"],
+ [36, "VP (GPIO36, {#PIN_INPUT_ONLY})"],
+ [39, "VN (GPIO39, {#PIN_INPUT_ONLY})"]
];
var esp32s3pins = [
[255, "off / default"],
- [0, "GPIO0 (DONT USE - BOOT)"],
+ [0, "GPIO0 ({#PIN_DONT_USE} - BOOT)"],
[1, "GPIO1"],
[2, "GPIO2"],
[3, "GPIO3"],
@@ -412,16 +408,16 @@
[16, "GPIO16"],
[17, "GPIO17"],
[18, "GPIO18"],
- [19, "GPIO19 (DONT USE - USB-)"],
- [20, "GPIO20 (DONT USE - USB+)"],
+ [19, "GPIO19 ({#PIN_DONT_USE} - USB-)"],
+ [20, "GPIO20 ({#PIN_DONT_USE} - USB+)"],
[21, "GPIO21"],
- [26, "GPIO26 (PSRAM - not available)"],
- [27, "GPIO27 (FLASH - not available)"],
- [28, "GPIO28 (FLASH - not available)"],
- [29, "GPIO29 (FLASH - not available)"],
- [30, "GPIO30 (FLASH - not available)"],
- [31, "GPIO31 (FLASH - not available)"],
- [32, "GPIO32 (FLASH - not available)"],
+ [26, "GPIO26 (PSRAM - {#PIN_NOT_AVAIL})"],
+ [27, "GPIO27 (FLASH - {#PIN_NOT_AVAIL})"],
+ [28, "GPIO28 (FLASH - {#PIN_NOT_AVAIL})"],
+ [29, "GPIO29 (FLASH - {#PIN_NOT_AVAIL})"],
+ [30, "GPIO30 (FLASH - {#PIN_NOT_AVAIL})"],
+ [31, "GPIO31 (FLASH - {#PIN_NOT_AVAIL})"],
+ [32, "GPIO32 (FLASH - {#PIN_NOT_AVAIL})"],
[33, "GPIO33 (not exposed on WROOM modules)"],
[34, "GPIO34 (not exposed on WROOM modules)"],
[35, "GPIO35"],
@@ -434,8 +430,8 @@
[42, "GPIO42"],
[43, "GPIO43"],
[44, "GPIO44"],
- [45, "GPIO45 (DONT USE - STRAPPING PIN)"],
- [46, "GPIO46 (DONT USE - STRAPPING PIN)"],
+ [45, "GPIO45 ({#PIN_DONT_USE} - STRAPPING PIN)"],
+ [46, "GPIO46 ({#PIN_DONT_USE} - STRAPPING PIN)"],
[47, "GPIO47"],
[48, "GPIO48"],
];
@@ -459,17 +455,17 @@
[15, "GPIO15 (PSRAM/FLASH)"],
[16, "GPIO16 (PSRAM/FLASH)"],
[17, "GPIO17 (PSRAM/FLASH)"],
- [18, "GPIO18 (DONT USE - USB-)"],
- [19, "GPIO19 (DONT USE - USB+)"],
+ [18, "GPIO18 ({#PIN_DONT_USE} - USB-)"],
+ [19, "GPIO19 ({#PIN_DONT_USE} - USB+)"],
[20, "GPIO20 (RX)"],
[21, "GPIO21 (TX)"],
];
/*ENDIF_ESP32*/
var nrfPa = [
- [0, "MIN (recommended)"],
+ [0, "MIN ({#PIN_RECOMMENDED})"],
[1, "LOW"],
[2, "HIGH"],
- [3, "MAX (experimental)"]
+ [3, "MAX ({#PIN_EXPERIMENTAL})"]
];
var esp32cmtPa = [];
var esp32cmtFreq = [];
@@ -487,8 +483,8 @@
}
/*ENDIF_ESP32*/
var led_high_active = [
- [0, "low active"],
- [1, "high active"],
+ [0, "{#PIN_LOW_ACTIVE}"],
+ [1, "{#PIN_HIGH_ACTIVE}"],
];
window.onload = function() {
@@ -513,31 +509,31 @@
var e = document.getElementById("networks");
selDelAllOpt(e);
if(obj["success"])
- e.appendChild(opt("-1", "scanning ..."))
+ e.appendChild(opt("-1", "{#NETWORK_SCANNING}"))
else
- e.appendChild(opt("-1", "Error: " + obj["error"]));
+ e.appendChild(opt("-1", "{#ERROR} " + obj["error"]));
}
function apiCbNtp(obj) {
var e = document.getElementById("apiResultNtp");
if(obj["success"])
- e.innerHTML = "command executed, set new time ...";
+ e.innerHTML = "{#NTP_COMMAND_EXE}";
else
- e.innerHTML = "Error: " + obj["error"];
+ e.innerHTML = "{#ERROR} " + obj["error"];
}
function apiCbNtp2(obj) {
var e = document.getElementById("apiResultNtp");
var date = new Date(obj["ts_now"] * 1000);
- e.innerHTML = "synced at: " + toIsoDateStr(date) + ", difference: " + (ts - obj["ts_now"]) + "ms";
+ e.innerHTML = "{#NTP_SYNCED_AT}: " + toIsoDateStr(date) + ", {#NTP_DIFF}: " + (ts - obj["ts_now"]) + "ms";
}
function apiCbMqtt(obj) {
var e = document.getElementById("apiResultMqtt");
if(obj["success"])
- e.innerHTML = "command executed";
+ e.innerHTML = "{#MQTT_EXE}";
else
- e.innerHTML = "Error: " + obj["error"];
+ e.innerHTML = "{#ERROR} " + obj["error"];
}
function setTime() {
@@ -572,7 +568,7 @@
function hide() {
document.getElementById("form").submit();
var e = document.getElementById("content");
- e.replaceChildren(span("upload started"));
+ e.replaceChildren(span("{#IMPORT_UPLOAD_STARTED}"));
}
function delIv() {
@@ -626,7 +622,7 @@
if(!obj["pwd_set"])
e.value = "";
var d = document.getElementById("prot_mask");
- var a = ["Index", "Live", "Webserial", "Settings", "Update", "System"];
+ var a = ["Index", "{#NAV_LIVE}", "{#NAV_WEBSERIAL}", "{#NAV_SETTINGS}", "Update", "System"];
var el = [];
for(var i = 0; i < 6; i++) {
var chk = ((obj["prot_mask"] & (1 << i)) == (1 << i));
@@ -657,13 +653,13 @@
ml("th", {style: "width: 10%; text-align: center;"}, ""),
ml("th", {}, "Name"),
ml("th", {}, "Serial"),
- ml("th", {style: "width: 10%; text-align: center;"}, "Edit"),
- ml("th", {style: "width: 10%; text-align: center;"}, "Delete")
+ ml("th", {style: "width: 10%; text-align: center;"}, "{#INV_EDIT}"),
+ ml("th", {style: "width: 10%; text-align: center;"}, "{#INV_DELETE}")
]));
for(let i = 0; i < obj.inverter.length; i++) {
lines.push(ml("tr", {}, [
- ml("td", {}, badge(obj.inverter[i].enabled, (obj.inverter[i].enabled) ? "enabled" : "disabled")),
+ ml("td", {}, badge(obj.inverter[i].enabled, (obj.inverter[i].enabled) ? "{#ENABLED}" : "{#DISABLED}")),
ml("td", {}, obj.inverter[i].name),
ml("td", {}, String(obj.inverter[i].serial)),
ml("td", {style: "text-align: center;", onclick: function() {ivModal(obj.inverter[i]);}}, svg(iconGear, 25, 25, "icon icon-fg pointer")),
@@ -686,7 +682,7 @@
e.innerHTML = ""; // remove all childs
e.append(ml("table", {class: "table"}, ml("tbody", {}, lines)));
if(obj.max_num_inverters > obj.inverter.length)
- e.append(ml("div", {class: "row my-3"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", value: "add Inverter", class: "btn", onclick: function() { ivModal(add); }}, null))));
+ e.append(ml("div", {class: "row my-3"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", value: "{#BTN_INV_ADD}", class: "btn", onclick: function() { ivModal(add); }}, null))));
ivGlob(obj);
}
@@ -694,10 +690,10 @@
function ivModal(obj) {
var lines = [];
lines.push(ml("tr", {}, [
- ml("th", {style: "width: 10%;"}, "Input"),
- ml("th", {}, "Max Module Power [Wp]"),
+ ml("th", {style: "width: 10%;"}, "{#INV_INPUT}"),
+ ml("th", {}, "{#INV_MAX_MODULE_POWER} [Wp]"),
ml("th", {}, "Name (optional)"),
- ml("th", {}, "Yield Correction [kWh] (optional)")
+ ml("th", {}, "{#INV_YIELD_CORR} [kWh] (optional)")
]));
for(let i = 0; i < 6; i++) {
@@ -718,14 +714,14 @@
var ser = ml("input", {name: "ser", class: "text", type: "number", max: 138999999999, value: obj.serial}, null);
var html = ml("div", {}, [
- tabs(["General", "Inputs", "Radio", "Advanced"]),
- ml("div", {id: "divGeneral", class: "tab-content"}, [
+ tabs(["{#TAB_GENERAL}", "{#TAB_INPUTS}", "{#TAB_RADIO}", "{#TAB_ADVANCED}"]),
+ ml("div", {id: "div{#TAB_GENERAL}", class: "tab-content"}, [
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-2"}, "Enable"),
+ ml("div", {class: "col-2"}, "{#INV_ENABLE}"),
ml("div", {class: "col-10"}, cbEn)
]),
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-2 mt-2"}, "Serial"),
+ ml("div", {class: "col-2 mt-2"}, "{#INV_SERIAL}"),
ml("div", {class: "col-10"}, ser)
]),
ml("div", {class: "row mb-3"}, [
@@ -733,45 +729,45 @@
ml("div", {class: "col-10"}, ml("input", {name: "name", class: "text", type: "text", value: obj.name}, null))
])
]),
- ml("div", {id: "divInputs", class: "tab-content hide"}, [
+ ml("div", {id: "div{#TAB_INPUTS}", class: "tab-content hide"}, [
ml("div", {class: "row mb-3"},
ml("table", {class: "table"},
ml("tbody", {}, lines)
)
)
]),
- ml("div", {id: "divRadio", class: "tab-content hide"}, [
+ ml("div", {id: "div{#TAB_RADIO}", class: "tab-content hide"}, [
ml("input", {type: "hidden", name: "isnrf"}, null),
ml("div", {id: "setcmt"}, [
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-3 mt-2"}, "Frequency"),
+ ml("div", {class: "col-3 mt-2"}, "{#INV_FREQUENCY}"),
ml("div", {class: "col-9"}, sel("freq", esp32cmtFreq, obj.freq))
]),
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-3 mt-2"}, "Power Level"),
+ ml("div", {class: "col-3 mt-2"}, "{#INV_POWER_LEVEL}"),
ml("div", {class: "col-9"}, sel("cmtpa", esp32cmtPa, obj.pa))
]),
]),
ml("div", {id: "setnrf"},
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-3 mt-2"}, "Power Level"),
+ ml("div", {class: "col-3 mt-2"}, "{#INV_POWER_LEVEL}"),
ml("div", {class: "col-9"}, sel("nrfpa", nrfPa, obj.pa))
]),
),
]),
- ml("div", {id: "divAdvanced", class: "tab-content hide"}, [
+ ml("div", {id: "div{#TAB_ADVANCED}", class: "tab-content hide"}, [
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-10"}, "Pause communication during night (lat. and lon. need to be set)"),
+ ml("div", {class: "col-10"}, "{#INV_PAUSE_DURING_NIGHT}"),
ml("div", {class: "col-2"}, cbDisNightCom)
]),
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-10"}, "Include inverter to sum of total (should be checked by default, MqTT only)"),
+ ml("div", {class: "col-10"}, "{#INV_INCLUDE_MQTT_SUM}"),
ml("div", {class: "col-2"}, cbAddTotal)
])
]),
ml("div", {class: "row mt-5"}, [
ml("div", {class: "col-8", id: "res"}, ""),
- ml("div", {class: "col-4 a-r"}, ml("input", {type: "button", value: "save", class: "btn", onclick: function() { ivSave(); }}, null))
+ ml("div", {class: "col-4 a-r"}, ml("input", {type: "button", value: "{#BTN_SAVE}", class: "btn", onclick: function() { ivSave(); }}, null))
])
]);
@@ -808,7 +804,7 @@
})
});
- modal("Edit inverter " + obj.name, html);
+ modal("{#INV_EDIT_MODAL}: " + obj.name, html);
ser.dispatchEvent(new Event('change'));
function ivSave() {
@@ -839,7 +835,7 @@
function cb(obj2) {
var e = document.getElementById("res");
if(!obj2.success)
- e.innerHTML = "error: " + obj2.error;
+ e.innerHTML = "{#ERROR}" + obj2.error;
else {
modalClose();
getAjax("/api/inverter/list", parseIv);
@@ -849,10 +845,10 @@
function ivDel(obj) {
var html = ml("div", {class: "row"}, [
- ml("div", {class: "col-9"}, "do you realy want to delete inverter " + obj.name + "?"),
- ml("div", {class: "col-3 a-r"}, ml("div", {class: "col-4 a-r"}, ml("input", {type: "button", value: "yes", class: "btn", onclick: function() { del(); }}, null)))
+ ml("div", {class: "col-9"}, "{#INV_DELETE_SURE} (" + obj.name + ")"),
+ ml("div", {class: "col-3 a-r"}, ml("div", {class: "col-4 a-r"}, ml("input", {type: "button", value: "{#BTN_YES}", class: "btn", onclick: function() { del(); }}, null)))
]);
- modal("Delete inverter " + obj.name, html);
+ modal("{#INV_DELETE_MODAL}: " + obj.name, html);
function del() {
var o = new Object();
@@ -896,7 +892,7 @@
for(p of [["sunOffsSr", "offsSr"], ["sunOffsSs", "offsSs"]]) {
const sel = document.getElementsByName(p[0])[0];
for(var i = -60; i <= 60; i++) {
- sel.appendChild(opt(i, i + " minutes", (i == (obj[p[1]] / 60))));
+ sel.appendChild(opt(i, i + " {#NTP_MINUTES}", (i == (obj[p[1]] / 60))));
}
}
}
@@ -909,7 +905,7 @@
if ("ESP32-S3" == system.chip_model) pinList = esp32s3pins;
else if("ESP32-C3" == system["chip_model"]) pinList = esp32c3pins;
/*ENDIF_ESP32*/
- pins = [['led0', 'pinLed0', 'At least one inverter is producing'], ['led1', 'pinLed1', 'MqTT connected'], ['led2', 'pinLed2', 'Night time']];
+ pins = [['led0', 'pinLed0', '{#LED_AT_LEAST_ONE_PRODUCING}'], ['led1', 'pinLed1', '{#LED_MQTT_CONNECTED}'], ['led2', 'pinLed2', '{#LED_NIGHT_TIME}']];
for(p of pins) {
e.append(
ml("div", {class: "row mb-3"}, [
@@ -922,13 +918,13 @@
}
e.append(
ml("div", { class: "row mb-3" }, [
- ml("div", { class: "col-12 col-sm-3 my-2" }, "LED polarity"),
+ ml("div", { class: "col-12 col-sm-3 my-2" }, "{#LED_POLARITY}"),
ml("div", { class: "col-12 col-sm-9" },
sel('pinLedHighActive', led_high_active, obj.led_high_active)
)
]),
ml("div", { class: "row mb-3" }, [
- ml("div", { class: "col-12 col-sm-3 my-2" }, "LED luminance (0-255)"),
+ ml("div", { class: "col-12 col-sm-3 my-2" }, "{#LED_LUMINANCE} (0-255)"),
ml("div", { class: "col-12 col-sm-9" }, ml("input", {class: "text", type: "number", name: "pinLedLum", value: obj.led_lum, min: 0, max: 255}, null))
])
)
@@ -948,7 +944,7 @@
e.replaceChildren (
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-8 col-sm-3 my-2"}, "NRF24 Enable"),
+ ml("div", {class: "col-8 col-sm-3 my-2"}, "{#NRF24_ENABLE}"),
ml("div", {class: "col-4 col-sm-9"}, en)
])
);
@@ -982,7 +978,7 @@
e.replaceChildren (
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-8 col-sm-3 my-2"}, "CMT2300A Enable"),
+ ml("div", {class: "col-8 col-sm-3 my-2"}, "{#CMT_ENABLE}"),
ml("div", {class: "col-4 col-sm-9"}, en)
])
);
@@ -1033,7 +1029,7 @@
);
}
// keep display types grouped
- var opts = [[0, "None"],
+ var opts = [[0, "{#DISP_NONE}"],
[2, "SH1106 128x64 (1.3\")"],
[5, "SSD1306 64x48 (0.66\" Wemos OLED Shield)"],
[4, "SSD1306 128x32 (0.91\")"],
@@ -1046,7 +1042,7 @@
var dtype_sel = sel("disp_typ", opts, obj["disp_typ"]);
document.getElementById("dispType").append(
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-12 col-sm-3 my-2"}, "Type"),
+ ml("div", {class: "col-12 col-sm-3 my-2"}, "{#DISP_TYPE}"),
ml("div", {class: "col-12 col-sm-9"}, dtype_sel)
])
);
@@ -1057,22 +1053,22 @@
/*ENDIF_ESP32*/
document.getElementById("dispRot").append(
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-12 col-sm-3 my-2"}, "Rotation"),
+ ml("div", {class: "col-12 col-sm-3 my-2"}, "{#DISP_ROTATION}"),
ml("div", {class: "col-12 col-sm-9"}, sel("disp_rot", opts, obj["disp_rot"]))
])
);
- var opts1 = [[0, "off"], [1, "pixel shift"], [2, "motion sensor"]];
+ var opts1 = [[0, "{#DISP_SCREENSAVER_OFF}"], [1, "{#DISP_PIXEL_SHIFT}"], [2, "{#DISP_MOTION_SENS}"]];
var screensaver_sel = sel("disp_screensaver", opts1, obj["disp_screensaver"]);
screensaver_sel.id = 'disp_screensaver';
document.getElementById("screenSaver").append(
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-12 col-sm-3 my-2"}, "Screensaver (OLED only)"),
+ ml("div", {class: "col-12 col-sm-3 my-2"}, "{#DISP_SCREENSAVER}"),
ml("div", {class: "col-12 col-sm-9"}, screensaver_sel)
])
);
- var esp8266pirpins = [[255, "off / default"],
+ var esp8266pirpins = [[255, "{#PIN_OFF}"],
[17, "A0"]];
document.getElementById("pirPin").append(
ml("div", {class: "row mb-3"}, [
@@ -1155,12 +1151,12 @@
var s = document.getElementById("networks");
selDelAllOpt(s);
if(root["networks"].length > 0) {
- s.appendChild(opt("-1", "please select network"));
+ s.appendChild(opt("-1", "{#NETWORK_PLEASE_SELECT}"));
for(i = 0; i < root["networks"].length; i++) {
s.appendChild(opt(root["networks"][i]["ssid"], root["networks"][i]["ssid"] + " (" + root["networks"][i]["rssi"] + " dBm)"));
}
} else
- s.appendChild(opt("-1", "no network found"));
+ s.appendChild(opt("-1", "{#NO_NETWORK_FOUND}"));
}
function selNet() {
diff --git a/src/web/html/system.html b/src/web/html/system.html
index f400db41..16c6343e 100644
--- a/src/web/html/system.html
+++ b/src/web/html/system.html
@@ -46,7 +46,7 @@
function irqBadge(state) {
switch(state) {
- case 0: return badge(false, "unknown", "warning"); break;
+ case 0: return badge(false, "{#UNKNOWN}", "warning"); break;
case 1: return badge(true, "true"); break;
default: return badge(false, "false"); break;
}
@@ -57,16 +57,16 @@
if(obj.radioNrf.en) {
lines = [
- tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "not ") + "connected")),
- tr("Interrupt Pin working", irqBadge(obj.radioNrf.irqOk)),
- tr("NRF24 Data Rate", dr[obj.radioNrf.dataRate] + "bps"),
+ tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "{#NOT} ") + "{#CONNECTED}")),
+ tr("{#IRQ_WORKING}", irqBadge(obj.radioNrf.irqOk)),
+ tr("{#NRF24_DATA_RATE}", dr[obj.radioNrf.dataRate] + "bps"),
tr("DTU Radio ID", obj.radioNrf.sn)
];
} else
- lines = [tr("NRF24L01", badge(false, "not enabled"))];
+ lines = [tr("NRF24L01", badge(false, "{#NOT_ENABLED}"))];
document.getElementById("info").append(
- headline("Radio NRF"),
+ headline("{#NRF24_RADIO}"),
ml("table", {class: "table"},
ml("tbody", {}, lines)
)
@@ -75,15 +75,15 @@
/*IF_ESP32*/
if(obj.radioCmt.en) {
cmt = [
- tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "not ") + "connected")),
- tr("Interrupt Pin working", irqBadge(obj.radioCmt.irqOk)),
+ tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "{#NOT} ") + "{#CONNECTED}")),
+ tr("{#IRQ_WORKING}", irqBadge(obj.radioCmt.irqOk)),
tr("DTU Radio ID", obj.radioCmt.sn)
];
} else
- cmt = [tr("CMT2300A", badge(false, "not enabled"))];
+ cmt = [tr("CMT2300A", badge(false, "{#NOT_ENABLED}"))];
document.getElementById("info").append(
- headline("Radio CMT"),
+ headline("{#CMT_RADIO}"),
ml("table", {class: "table"},
ml("tbody", {}, cmt)
)
@@ -94,13 +94,13 @@
function parseMqtt(obj) {
if(obj.enabled) {
lines = [
- tr("connected", badge(obj.connected, ((obj.connected) ? "true" : "false"))),
+ tr("{#CONNECTED}", badge(obj.connected, ((obj.connected) ? "{#TRUE}" : "{#FALSE}"))),
tr("#TX", obj.tx_cnt),
tr("#RX", obj.rx_cnt)
];
} else
- lines = tr("enabled", badge(false, "false"));
+ lines = tr("{#ENABLED}", badge(false, "{#FALSE}"));
document.getElementById("info").append(
headline("MqTT"),
@@ -113,14 +113,14 @@
function parseIndex(obj) {
if(obj.ts_sunrise > 0) {
document.getElementById("info").append(
- headline("Sun"),
+ headline("{#SUN}"),
ml("table", {class: "table"},
ml("tbody", {}, [
- tr("Sunrise", new Date(obj.ts_sunrise * 1000).toLocaleString('de-DE')),
- tr("Sunset", new Date(obj.ts_sunset * 1000).toLocaleString('de-DE')),
- tr("Communication start", new Date((obj.ts_sunrise + obj.ts_offsSr) * 1000).toLocaleString('de-DE')),
- tr("Communication stop", new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE')),
- tr("Night behaviour", badge(obj.disNightComm, ((obj.disNightComm) ? "not" : "") + " communicating", "warning"))
+ tr("{#SUNRISE}", new Date(obj.ts_sunrise * 1000).toLocaleString('de-DE')),
+ tr("{#SUNSET}", new Date(obj.ts_sunset * 1000).toLocaleString('de-DE')),
+ tr("{#COMMUNICATION_START}", new Date((obj.ts_sunrise + obj.ts_offsSr) * 1000).toLocaleString('de-DE')),
+ tr("{#COMMUNICATION_STTOP}", new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE')),
+ tr("{#NIGHT_BEHAVE}", badge(obj.disNightComm, ((obj.disNightComm) ? "{#NOT}" : "") + " {#COMMUNICATING}", "warning"))
])
)
);
diff --git a/src/web/html/update.html b/src/web/html/update.html
index 4e56b1ad..f0e39fe7 100644
--- a/src/web/html/update.html
+++ b/src/web/html/update.html
@@ -9,14 +9,14 @@
- Select firmware file (*.bin)
+ {#SELECT_FILE} (*.bin)
@@ -31,7 +31,7 @@
function hide() {
document.getElementById("form").submit();
var e = document.getElementById("content");
- e.replaceChildren(span("update started"));
+ e.replaceChildren(span("{#UPDATE_STARTED}"));
}
getAjax("/api/generic", parseGeneric);
diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html
index 27f5da35..8099539c 100644
--- a/src/web/html/visualization.html
+++ b/src/web/html/visualization.html
@@ -10,7 +10,7 @@
-
Every seconds the values are updated
+
{#EVERY} {#UPDATE_SECS}
{#HTML_FOOTER}
@@ -70,20 +70,20 @@
ml("div", {class: "col"}, [
ml("div", {class: "p-2 total-h"},
ml("div", {class: "row"},
- ml("div", {class: "col mx-2 mx-md-1"}, "TOTAL")
+ ml("div", {class: "col mx-2 mx-md-1"}, "{#TOTAL}")
),
),
ml("div", {class: "p-2 total-bg"}, [
ml("div", {class: "row"}, [
- numBig(total[0], "W", "AC Power"),
- numBig(total[1], "Wh", "Yield Day"),
- numBig(total[2], "kWh", "Yield Total")
+ numBig(total[0], "W", "{#AC_POWER}"),
+ numBig(total[1], "Wh", "{#YIELD_DAY}"),
+ numBig(total[2], "kWh", "{#YIELD_TOTAL}")
]),
ml("div", {class: "hr"}),
ml("div", {class: "row"}, [
- numMid(total[3], "W", "Max Power"),
- numMid(total[4], "W", "DC Power"),
- numMid(total[5], "var", "Reactive Power")
+ numMid(total[3], "W", "{#MAX_POWER}"),
+ numMid(total[4], "W", "{#DC_POWER}"),
+ numMid(total[5], "var", "{#REACTIVE_POWER}")
])
])
])
@@ -119,31 +119,31 @@
getAjax("/api/inverter/version/" + obj.id, parseIvVersion);
}}, obj.name)),
ml("div", {class: "col a-c", onclick: function() {limitModal(obj)}}, [
- ml("span", {class: "d-none d-sm-block pointer"}, "Active Power Control: " + pwrLimit),
- ml("span", {class: "d-block d-sm-none pointer"}, "APC: " + pwrLimit)
+ ml("span", {class: "d-none d-sm-block pointer"}, "{#ACTIVE_POWER_CONTROL}: " + pwrLimit),
+ ml("span", {class: "d-block d-sm-none pointer"}, "{#APC}: " + pwrLimit)
]),
ml("div", {class: "col a-c"}, ml("span", { class: "pointer", onclick: function() {
getAjax("/api/inverter/alarm/" + obj.id, parseIvAlarm);
- }}, ("Alarms: " + obj.alarm_cnt))),
+ }}, ("{#ALARMS}: " + obj.alarm_cnt))),
ml("div", {class: "col a-r mx-2 mx-md-1"}, String(obj.ch[0][5].toFixed(1)) + t.innerText)
])
),
ml("div", {class: "p-2 " + clbg}, [
ml("div", {class: "row"},[
- numBig(obj.ch[0][2], "W", "AC Power"),
- numBig(obj.ch[0][7], "Wh", "Yield Day"),
- numBig(obj.ch[0][6], "kWh", "Yield Total")
+ numBig(obj.ch[0][2], "W", "{#AC_POWER}"),
+ numBig(obj.ch[0][7], "Wh", "{#YIELD_DAY}"),
+ numBig(obj.ch[0][6], "kWh", "{#YIELD_TOTAL}")
]),
ml("div", {class: "hr"}),
ml("div", {class: "row mt-2"},[
- numMid(obj.ch[0][11], "W", "Max AC Power", {class: "fs-6 tooltip", data: maxAcPwr}),
- numMid(obj.ch[0][8], "W", "DC Power"),
- numMid(obj.ch[0][0], "V", "AC Voltage"),
- numMid(obj.ch[0][1], "A", "AC Current"),
- numMid(obj.ch[0][3], "Hz", "Frequency"),
- numMid(obj.ch[0][9], "%", "Efficiency"),
- numMid(obj.ch[0][10], "var", "Reactive Power"),
- numMid(obj.ch[0][4], "", "Power Factor")
+ numMid(obj.ch[0][11], "W", "{#MAX_AC_POWER}", {class: "fs-6 tooltip", data: maxAcPwr}),
+ numMid(obj.ch[0][8], "W", "{#DC_POWER}"),
+ numMid(obj.ch[0][0], "V", "{#DC_VOLTAGE}"),
+ numMid(obj.ch[0][1], "A", "{#AC_CURRENT}"),
+ numMid(obj.ch[0][3], "Hz", "{#FREQUENCY}"),
+ numMid(obj.ch[0][9], "%", "{#EFFICIENCY}"),
+ numMid(obj.ch[0][10], "var", "{#REACTIVE_POWER}"),
+ numMid(obj.ch[0][4], "", "{#POWER_FACTOR}")
])
])
])
@@ -172,26 +172,26 @@
ml("div", {class: "p-2 a-c " + clh}, name),
ml("div", {class: "p-2 " + clbg}, [
ml("div", {class: "row"}, [
- numCh(vals[2], units[2], "DC Power"),
- numCh(vals[6], units[2], "Max Power"),
- numCh(vals[5], units[5], "Irradiation"),
- numCh(vals[3], units[3], "Yield Day"),
- numCh(vals[4], units[4], "Yield Total"),
- numCh(vals[0], units[0], "DC Voltage"),
- numCh(vals[1], units[1], "DC Current")
+ numCh(vals[2], units[2], "{#DC_POWER}"),
+ numCh(vals[6], units[2], "{#MAX_POWER}"),
+ numCh(vals[5], units[5], "{#IRRADIATION}"),
+ numCh(vals[3], units[3], "{#YIELD_DAY}"),
+ numCh(vals[4], units[4], "{#YIELD_TOTAL}"),
+ numCh(vals[0], units[0], "{#DC_VOLTAGE}"),
+ numCh(vals[1], units[1], "{#DC_CURRENT}")
])
])
]);
}
function tsInfo(obj) {
- var ageInfo = "Last received data requested at: ";
+ var ageInfo = "{#LAST_RECEIVED}: ";
if(obj.ts_last_success > 0) {
var date = new Date(obj.ts_last_success * 1000);
ageInfo += toIsoDateStr(date);
}
else
- ageInfo += "nothing received";
+ ageInfo += "{#NOTHING_RECEIVED}";
if(obj.rssi > -127) {
if(obj.generation < 2)
@@ -252,10 +252,10 @@
var offs = new Date().getTimezoneOffset() * -60;
html.push(
ml("div", {class: "row"}, [
- ml("div", {class: "col"}, ml("strong", {}, "Event")),
+ ml("div", {class: "col"}, ml("strong", {}, "{#EVENT}")),
ml("div", {class: "col"}, ml("strong", {}, "ID")),
ml("div", {class: "col"}, ml("strong", {}, "Start")),
- ml("div", {class: "col"}, ml("strong", {}, "End"))
+ ml("div", {class: "col"}, ml("strong", {}, "{#END}"))
])
);
@@ -271,7 +271,7 @@
);
}
}
- modal("Alarms of inverter " + obj.iv_name, ml("div", {}, html));
+ modal("{#ALARMS_MODAL}: " + obj.iv_name, ml("div", {}, html));
}
function parseIvVersion(obj) {
@@ -283,7 +283,7 @@
case 3: model = "HMT-"; break;
default: model = "???-"; break;
}
- model += String(obj.max_pwr) + " (Serial: " + obj.serial + ")";
+ model += String(obj.max_pwr) + " ({#SERIAL}: " + obj.serial + ")";
var html = ml("table", {class: "table"}, [
@@ -291,15 +291,15 @@
tr("Model", model),
tr("Firmware Version / Build", String(obj.fw_ver) + " (build: " + String(obj.fw_date) + " " + String(obj.fw_time) + ")"),
tr("Hardware Version / Build", (obj.hw_ver/100).toFixed(2) + " (build: " + String(obj.prod_cw) + "/" + String(obj.prod_year) + ")"),
- tr("Hardware Number", obj.part_num.toString(16)),
+ tr("{#HW_NUMBER}", obj.part_num.toString(16)),
tr("Bootloader Version", (obj.boot_ver/100).toFixed(2)),
- tr("Grid Profile", ml("input", {type: "button", value: "show", class: "btn", onclick: function() {
+ tr("Grid Profile", ml("input", {type: "button", value: "{#BTN_SHOW}", class: "btn", onclick: function() {
modalClose();
getAjax("/api/inverter/grid/" + obj.id, showGridProfile);
}}, null))
])
])
- modal("Info for inverter " + obj.name, ml("div", {}, html))
+ modal("{#INV_INFO}: " + obj.name, ml("div", {}, html))
}
function getGridValue(g) {
@@ -332,9 +332,9 @@
))
content.push(ml("div", {class: "row my-2"}, [
ml("div", {class: "col-4"}, ml("b", {}, "Name")),
- ml("div", {class: "col-3"}, ml("b", {}, "Value")),
- ml("div", {class: "col-3"}, ml("b", {}, "Range")),
- ml("div", {class: "col-2"}, ml("b", {}, "Default"))
+ ml("div", {class: "col-3"}, ml("b", {}, "{#VALUE}")),
+ ml("div", {class: "col-3"}, ml("b", {}, "{#RANGE}")),
+ ml("div", {class: "col-2"}, ml("b", {}, "{#DEFAULT}"))
]))
for(e of g.info.group) {
if(Array.isArray(e[id])) {
@@ -362,10 +362,10 @@
var v = getGridValue(glob);
if(null === g) {
if(0 == obj.grid.length) {
- content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("p", {}, "Profile was not read until now, maybe turned off?"))))
+ content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("p", {}, "{#PROFILE_NOT_READ}?"))))
} else {
- content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("h5", {}, "Unknown Profile"))))
- content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("p", {}, "Please open a new issue at https://github.com/lumapu/ahoy and copy the raw data into it."))))
+ content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("h5", {}, "{#UNKNOWN_PROFILE}"))))
+ content.push(ml("div", {class: "row"}, ml("div", {class: "col"}, ml("p", {}, "{#OPEN_ISSUE}."))))
content.push(ml("div", {class: "row"}, ml("div", {class: "col my-2"}, ml("pre", {}, obj.grid))))
}
} else {
@@ -378,7 +378,7 @@
}
}
- modal("Grid Profile for inverter " + obj.name, ml("div", {}, ml("div", {class: "col mb-2"}, [...content])))
+ modal("{#PROFILE_MODAL}: " + obj.name, ml("div", {}, ml("div", {class: "col mb-2"}, [...content])))
})
}
@@ -386,56 +386,56 @@
function parseIvRadioStats(obj) {
var html = ml("table", {class: "table"}, [
ml("tbody", {}, [
- tr2(["TX count", obj.tx_cnt, ""]),
- tr2(["RX success", obj.rx_success, String(Math.round(obj.rx_success / obj.tx_cnt * 10000) / 100) + " %"]),
- tr2(["RX fail", obj.rx_fail, String(Math.round(obj.rx_fail / obj.tx_cnt * 10000) / 100) + " %"]),
- tr2(["RX no answer", obj.rx_fail_answer, String(Math.round(obj.rx_fail_answer / obj.tx_cnt * 10000) / 100) + " %"]),
- tr2(["RX fragments", obj.frame_cnt, ""]),
- tr2(["TX retransmits", obj.retransmits, ""]),
- tr2(["Inverter loss rate", "lost " + obj.ivLoss + " of " + obj.ivSent, String(Math.round(obj.ivLoss / obj.ivSent * 10000) / 100) + " %"]),
- tr2(["DTU loss rate", "lost " + obj.dtuLoss + " of " + obj.dtuSent, String(Math.round(obj.dtuLoss / obj.dtuSent * 10000) / 100) + " %"])
+ tr2(["{#TX_COUNT}", obj.tx_cnt, ""]),
+ tr2(["{#RX_SUCCESS}", obj.rx_success, String(Math.round(obj.rx_success / obj.tx_cnt * 10000) / 100) + " %"]),
+ tr2(["{#RX_FAIL}", obj.rx_fail, String(Math.round(obj.rx_fail / obj.tx_cnt * 10000) / 100) + " %"]),
+ tr2(["{#RX_NO_ANSWER}", obj.rx_fail_answer, String(Math.round(obj.rx_fail_answer / obj.tx_cnt * 10000) / 100) + " %"]),
+ tr2(["{#RX_FRAGMENTS}", obj.frame_cnt, ""]),
+ tr2(["{#TX_RETRANSMITS}", obj.retransmits, ""]),
+ tr2(["{#INV_LOSS_RATE}", "{#LOST_1} " + obj.ivLoss + " {#LOST_2} " + obj.ivSent + " {#LOST_3}", String(Math.round(obj.ivLoss / obj.ivSent * 10000) / 100) + " %"]),
+ tr2(["{#DTU_LOSS_RATE}", "{#LOST_1} " + obj.dtuLoss + " {#LOST_2} " + obj.dtuSent + " {#LOST_3}", String(Math.round(obj.dtuLoss / obj.dtuSent * 10000) / 100) + " %"])
])
])
- modal("Radio statistics for inverter " + obj.name, ml("div", {}, html))
+ modal("{#RADIO_STAT_MODAL}: " + obj.name, ml("div", {}, html))
}
function limitModal(obj) {
var opt = [["pct", "%"], ["watt", "W"]];
var html = ml("div", {}, [
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-12 col-sm-5 my-2"}, "Limit Value"),
+ ml("div", {class: "col-12 col-sm-5 my-2"}, "{#LIMIT_VALUE}"),
ml("div", {class: "col-8 col-sm-5"}, ml("input", {name: "limit", type: "number", step: "0.1", min: 1}, "")),
ml("div", {class: "col-4 col-sm-2"}, sel("type", opt, "pct"))
]),
ml("div", {class: "row mb-3"}, [
- ml("div", {class: "col-8 col-sm-5"}, "Keep limit over inverter restart"),
+ ml("div", {class: "col-8 col-sm-5"}, "{#KEEP_LIMIT}"),
ml("div", {class: "col-4 col-sm-7"}, ml("input", {type: "checkbox", name: "keep"}))
]),
ml("div", {class: "row my-3"},
- ml("div", {class: "col a-r"}, ml("input", {type: "button", value: "Apply", class: "btn", onclick: function() {
+ ml("div", {class: "col a-r"}, ml("input", {type: "button", value: "{#BTN_APPLY}", class: "btn", onclick: function() {
applyLimit(obj.id);
}}, null))
),
ml("div", {class: "row my-4"}, [
- ml("div", {class: "col-12 col-sm-5 my-2"}, "Control"),
+ ml("div", {class: "col-12 col-sm-5 my-2"}, "{#CONTROL}"),
ml("div", {class: "col col-sm-7 a-r"}, [
- ml("input", {type: "button", value: "restart", class: "btn", onclick: function() {
+ ml("input", {type: "button", value: "{#RESTART}", class: "btn", onclick: function() {
applyCtrl(obj.id, "restart");
}}, null),
- ml("input", {type: "button", value: "turn off", class: "btn mx-1", onclick: function() {
+ ml("input", {type: "button", value: "{#TURN_OFF}", class: "btn mx-1", onclick: function() {
applyCtrl(obj.id, "power", 0);
}}, null),
- ml("input", {type: "button", value: "turn on", class: "btn", onclick: function() {
+ ml("input", {type: "button", value: "{#TURN_ON}", class: "btn", onclick: function() {
applyCtrl(obj.id, "power", 1);
}}, null)
])
]),
ml("div", {class: "row mt-1"}, [
- ml("div", {class: "col-12 col-sm-5 my-2"}, "Result"),
+ ml("div", {class: "col-12 col-sm-5 my-2"}, "{#RESULT}"),
ml("div", {class: "col-sm-7 my-2"}, ml("span", {name: "pwrres"}, "-"))
])
]);
- modal("Active Power Control for inverter " + obj.name, html);
+ modal("{#POWER_LIMIT_MODAL}: " + obj.name, html);
}
function applyLimit(id) {
@@ -470,19 +470,19 @@
function ctrlCb(obj) {
var e = document.getElementsByName("pwrres")[0];
if(obj.success) {
- e.innerHTML = "received command, waiting for inverter acknowledge ...";
+ e.innerHTML = "{#CMD_RECEIVED_WAIT_ACK}";
tPwrAck = window.setInterval("getAjax('/api/inverter/pwrack/" + obj.id + "', updatePwrAck)", 1000);
}
else
- e.innerHTML = "Error: " + obj["error"];
+ e.innerHTML = "{#ERROR}: " + obj["error"];
}
function ctrlCb2(obj) {
var e = document.getElementsByName("pwrres")[0];
if(obj.success)
- e.innerHTML = "command received";
+ e.innerHTML = "{#COMMAND_RECEIVED}";
else
- e.innerHTML = "Error: " + obj["error"];
+ e.innerHTML = "{#ERROR}: " + obj["error"];
}
function updatePwrAck(obj) {
@@ -492,7 +492,7 @@
clearInterval(tPwrAck);
if(null == e)
return;
- e.innerHTML = "inverter acknowledged active power control command";
+ e.innerHTML = "{#INV_ACK}";
}
function parse(obj) {
diff --git a/src/web/html/wizard.html b/src/web/html/wizard.html
index 1ebfb65f..674823b2 100644
--- a/src/web/html/wizard.html
+++ b/src/web/html/wizard.html
@@ -24,23 +24,23 @@
function wifi() {
return ml("div", {}, [
- ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "Welcome to AhoyDTU"))),
- ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "Network Setup"))),
- sect("Choose your WiFi Network", ml("select", {id: "net", onchange: () => {if(found) clearInterval(v)}}, ml("option", {value: "-1"}, "---"))),
- sect("... or name it manually", ml("input", {id: "man", type: "text"})),
- sect("WiFi Password", ml("input", {id: "pwd", type: "password"})),
- ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn", value: "next", onclick: () => {saveWifi()}}, null))),
- ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "stop wizard")))
+ ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "{#WELCOME}"))),
+ ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "{#NETWORK_SETUP}"))),
+ sect("{#CHOOSE_WIFI}", ml("select", {id: "net", onchange: () => {if(found) clearInterval(v)}}, ml("option", {value: "-1"}, "---"))),
+ sect("{#WIFI_MANUAL}", ml("input", {id: "man", type: "text"})),
+ sect("{#WIFI_PASSWORD}", ml("input", {id: "pwd", type: "password"})),
+ ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn", value: "{#BTN_NEXT}", onclick: () => {saveWifi()}}, null))),
+ ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}")))
])
}
function checkWifi() {
c.replaceChildren(
- ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "Welcome to AhoyDTU"))),
- ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "Test Connection"))),
- sect("AhoyDTU is trying to connect to your WiFi", ml("span", {id: "state"}, "connecting ...")),
- ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn hide", id: "btn", value: "Finish", onclick: () => {redirect()}}, null))),
- ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "stop wizard")))
+ ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "{#WELCOME}"))),
+ ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "{#TEST_CONNECTION}"))),
+ sect("{#TRY_TO_CONNECT}", ml("span", {id: "state"}, "{#CONNECTING}")),
+ ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn hide", id: "btn", value: "{#BTN_FINISH}", onclick: () => {redirect()}}, null))),
+ ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "{#STOP_WIZARD}")))
)
v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 2500);
}
@@ -53,7 +53,7 @@
if("0.0.0.0" != obj["ip"]) {
clearInterval(v)
setHide("btn", false)
- document.getElementById("state").innerHTML = "success, got following IP in your network: " + obj.ip
+ document.getElementById("state").innerHTML = "{#NETWORK_SUCCESS}" + obj.ip
}
}
@@ -68,7 +68,7 @@
var e = document.getElementById("net");
if(obj.networks.length > 0) {
var a = []
- a.push(ml("option", {value: -1}, obj.networks.length + " Network(s) found"))
+ a.push(ml("option", {value: -1}, obj.networks.length + " {#NUM_NETWORKS_FOUND}"))
for(n of obj.networks) {
a.push(ml("option", {value: n.ssid}, n.ssid + " (" + n.rssi + "dBm)"))
found = true;
diff --git a/src/web/lang.json b/src/web/lang.json
new file mode 100644
index 00000000..d6c76ffc
--- /dev/null
+++ b/src/web/lang.json
@@ -0,0 +1,1334 @@
+{
+ "files": [
+ {
+ "name": "general",
+ "list": [
+ {
+ "token": "NAV_LIVE",
+ "en": "Live",
+ "de": "Daten"
+ },
+ {
+ "token": "NAV_WEBSERIAL",
+ "en": "Webserial",
+ "de": "Web Konsole"
+ },
+ {
+ "token": "NAV_SETTINGS",
+ "en": "Settings",
+ "de": "Einstellungen"
+ },
+ {
+ "token": "NAV_DOCUMENTATION",
+ "en": "Documentation",
+ "de": "Dokumentation"
+ },
+ {
+ "token": "NAV_ABOUT",
+ "en": "About",
+ "de": "Über"
+ }
+ ]
+ },
+ {
+ "name": "wizard.html",
+ "list": [
+ {
+ "token": "WELCOME",
+ "en": "Welcome to AhoyDTU",
+ "de": "Willkommen zu AhoyDTU"
+ },
+ {
+ "token": "NETWORK_SETUP",
+ "en": "Network Setup",
+ "de": "Netzwerkeinstellung"
+ },
+ {
+ "token": "CHOOSE_WIFI",
+ "en": "Choose your WiFi Network",
+ "de": "Wähle dein WiFi Netzwerk aus"
+ },
+ {
+ "token": "WIFI_MANUAL",
+ "en": "... or name it manually",
+ "de": "... oder nenne es hier"
+ },
+ {
+ "token": "WIFI_PASSWORD",
+ "en": "WiFi Password",
+ "de": "WiFi Passwort"
+ },
+ {
+ "token": "STOP_WIZARD",
+ "en": "stop wizard",
+ "de": "Einrichtung beenden"
+ },
+ {
+ "token": "BTN_NEXT",
+ "en": "next >>",
+ "de": "prüfen >>"
+ },
+ {
+ "token": "TEST_CONNECTION",
+ "en": "Test Connection",
+ "de": "Verbindung wird überprüft"
+ },
+ {
+ "token": "TRY_TO_CONNECT",
+ "en": "AhoyDTU is trying to connect to your WiFi",
+ "de": "AhoyDTU versucht eine Verindung mit deinem Netzwerk herzustellen"
+ },
+ {
+ "token": "CONNECTING",
+ "en": "connecting ...",
+ "de": "verbinde ..."
+ },
+ {
+ "token": "NETWORK_SUCCESS",
+ "en": "success, got following IP in your network: ",
+ "de": "Verindung erfolgreich. AhoyDTU hat die folgende IP bekommen: "
+ },
+ {
+ "token": "BTN_FINISH",
+ "en": "Finish >>",
+ "de": "Fertig >>"
+ },
+ {
+ "token": "NUM_NETWORKS_FOUND",
+ "en": "Network(s) found",
+ "de": "Netzwerk(e) gefunden"
+ }
+ ]
+ },
+ {
+ "name": "setup.html",
+ "list": [
+ {
+ "token": "SETTINGS",
+ "en": "Settings",
+ "de": "Einstellungen"
+ },
+ {
+ "token": "SYSTEM_CONFIG",
+ "en": "System Config",
+ "de": "Systemkonfiguration"
+ },
+ {
+ "token": "DEVICE_NAME",
+ "en": "Device Host Name",
+ "de": "Name der DTU"
+ },
+ {
+ "token": "REBOOT_AT_MIDNIGHT",
+ "en": "Reboot Ahoy at midnight",
+ "de": "um Mitternacht neu starten"
+ },
+ {
+ "token": "DARK_MODE",
+ "en": "Dark Mode",
+ "de": "dunkler Modus"
+ },
+ {
+ "token": "DARK_MODE_NOTE",
+ "en": "(empty browser cache or use CTRL + F5 after reboot to apply this setting)",
+ "de": "(der Browser-Cache muss geleert oder STRG + F5 gedrückt werden, um diese Einstellung zu aktivieren)"
+ },
+ {
+ "token": "PINOUT_CONFIGURATION",
+ "en": "Pinout Configuration",
+ "de": "Anschlusseinstellungen"
+ },
+ {
+ "token": "RADIO",
+ "en": "Radio",
+ "de": "Funkmodul"
+ },
+ {
+ "token": "SERIAL_CONSOLE",
+ "en": "Serial console",
+ "de": "Serielle Konsole"
+ },
+ {
+ "token": "LOG_PRINT_INVERTER_DATA",
+ "en": "print inverter data",
+ "de": "Livedaten ausgeben"
+ },
+ {
+ "token": "LOG_SERIAL_DEBUG",
+ "en": "Serial Debug",
+ "de": "Entwicklerinformationen ausgeben"
+ },
+ {
+ "token": "LOG_PRIVACY_MODE",
+ "en": "Privacy Mode",
+ "de": "Privatsphärenmodus"
+ },
+ {
+ "token": "LOG_PRINT_TRACES",
+ "en": "Print whole traces in Log",
+ "de": "alle Informationen in Log schreiben"
+ },
+ {
+ "token": "NETWORK",
+ "en": "Network",
+ "de": "Netzwerk"
+ },
+ {
+ "token": "AP_PWD",
+ "en": "AP Password (min. length: 8)",
+ "de": "AP Passwort (min. Länge: 8 Zeichen)"
+ },
+ {
+ "token": "SEARCH_NETWORKS",
+ "en": "Search Networks",
+ "de": "Netzwerke suchen"
+ },
+ {
+ "token": "BTN_SCAN",
+ "en": "scan",
+ "de": "Suche starten"
+ },
+ {
+ "token": "AVAIL_NETWORKS",
+ "en": "Avail Networks",
+ "de": "Verfügbare Netzwerke"
+ },
+ {
+ "token": "NETWORK_NOT_SCANNED",
+ "en": "not scanned",
+ "de": "nicht gesucht"
+ },
+ {
+ "token": "SSID_HIDDEN",
+ "en": "SSID is hidden",
+ "de": "SSID ist versteckt"
+ },
+ {
+ "token": "PASSWORD",
+ "en": "Password",
+ "de": "Passwort"
+ },
+ {
+ "token": "STATIC_IP",
+ "en": "Static IP (optional)",
+ "de": "Statische IP (optional)"
+ },
+ {
+ "token": "NETWORK_HINT_BLANK",
+ "en": "Leave fields blank for DHCP
The following fields are parsed in this format: 192.168.4.1",
+ "de": "Felder leer lassen um in den DHCP Modus zu wechseln.
Das Format der IP Adressen ist: 192.168.4.1"
+ },
+ {
+ "token": "IP_ADDRESS",
+ "en": "IP Address",
+ "de": "IP Adresse"
+ },
+ {
+ "token": "SUBMASK",
+ "en": "Submask",
+ "de": "Subnetzmaske"
+ },
+ {
+ "token": "PROTECTION",
+ "en": "Protection",
+ "de": "Zugriffsschutz"
+ },
+ {
+ "token": "ADMIN_PASSWORD",
+ "en": "Admin Password",
+ "de": "Administratorpasswort"
+ },
+ {
+ "token": "PROTECTION_NOTE",
+ "en": "Select pages which should be protected by password",
+ "de": "Auswählen, welche Bereiche passwortgeschützt werden sollen"
+ },
+ {
+ "token": "INVERTER",
+ "en": "Inverter",
+ "de": "Wechselrichter"
+ },
+ {
+ "token": "INTERVAL",
+ "en": "Interval [s]",
+ "de": "Intervall [s]"
+ },
+ {
+ "token": "INV_GAP",
+ "en": "Communication Gap [ms]",
+ "de": "Kommunikationslücke"
+ },
+ {
+ "token": "INV_RESET_MIDNIGHT",
+ "en": "Reset values and YieldDay at midnight",
+ "de": "Werte und Gesamtertrag um Mitternacht zurücksetzen"
+ },
+ {
+ "token": "INV_PAUSE_SUNSET",
+ "en": "Reset values at sunset",
+ "de": "Werte bei Sonnenuntergang zurücksetzen"
+ },
+ {
+ "token": "INV_RESET_NOT_AVAIL",
+ "en": "Reset values when inverter status is 'not available'",
+ "de": "Werte zurücksetzen, sobald der Wechselrichter nicht erreichbar ist"
+ },
+ {
+ "token": "INV_RESET_MAX_MIDNIGHT",
+ "en": "Reset 'max' values at midnight",
+ "de": "Maximalwerte bei Sonnenuntergang zurücksetzen"
+ },
+ {
+ "token": "INV_START_WITHOUT_TIME",
+ "en": "Start without time sync (useful in AP-Only-Mode)",
+ "de": "Kommunikation starten ohne gültige Zeit (sinnvoll im AP Modus)"
+ },
+ {
+ "token": "INV_READ_GRID_PROFILE",
+ "en": "Read Grid Profile",
+ "de": "Grid-Profil auslesen"
+ },
+ {
+ "token": "INV_YIELD_EFF",
+ "en": "Yield Efficiency (default 1.0)",
+ "de": "Ertragseffizienz (Standard 1.0)"
+ },
+ {
+ "token": "NTP_INTERVAL",
+ "en": "NTP Interval (in minutes, min. 5 minutes)",
+ "de": "NTP Intervall (in Minuten, min. 5 Minuten)"
+ },
+ {
+ "token": "NTP_SET_SYS_TIME",
+ "en": "set system time",
+ "de": "Systemzeit setzten"
+ },
+ {
+ "token": "BTN_FROM_BROWSER",
+ "en": "from browser",
+ "de": "vom Browser übernehmen"
+ },
+ {
+ "token": "BTN_SYNC_NTP",
+ "en": "sync NTP",
+ "de": "NTP syncchronisieren"
+ },
+ {
+ "token": "NTP_SYS_TIME",
+ "en": "System Time",
+ "de": "Systemzeit"
+ },
+ {
+ "token": "SUNRISE_SUNSET",
+ "en": "Sunrise & Sunset",
+ "de": "Sonnenaufgang & -untergang"
+ },
+ {
+ "token": "LATITUDE",
+ "en": "Latitude (decimal)",
+ "de": "Breitengrad (dezimal)"
+ },
+ {
+ "token": "LONGITUDE",
+ "en": "Longitude (decimal)",
+ "de": "Längengrad (dezimal)"
+ },
+ {
+ "token": "OFFSET_SUNRISE",
+ "en": "Offset (sunrise)",
+ "de": "Zeitversatz (Sonnenaufgang)"
+ },
+ {
+ "token": "OFFSET_SUNSET",
+ "en": "Offset (sunset)",
+ "de": "Zeitversatz (Sonnenuntergang)"
+ },
+ {
+ "token": "MQTT_USER",
+ "en": "Username (optional)",
+ "de": "Benutzername (optional)"
+ },
+ {
+ "token": "MQTT_PASSWORD",
+ "en": "Password (optional)",
+ "de": "Passwort (optional)"
+ },
+ {
+ "token": "MQTT_NOTE",
+ "en": "Send Inverter data in a fixed interval, even if there is no change. A value of '0' disables the fixed interval. The data is published once it was successfully received from inverter. (default: 0)",
+ "de": "Wechselrichterdaten in fixem Intervall schicken, auch wenn es keine Änderung gab. Ein Wert von '0' deaktiviert das fixe Intervall, die Wechselrichterdaten werden übertragen, sobald neue zur Verfügung stehen. (Standard: 0)"
+ },
+ {
+ "token": "DISPLAY_CONFIG",
+ "en": "Display Config",
+ "de": "Display Konfiguration"
+ },
+ {
+ "token": "DISP_OFF_INV",
+ "en": "Turn off while inverters are offline",
+ "de": "schalte das Display aus, während die Wechselrichter aus sind"
+ },
+ {
+ "token": "DISP_LUMINANCE",
+ "en": "Luminance",
+ "de": "Helligkeit"
+ },
+ {
+ "token": "DISP_PINOUT",
+ "en": "Pinout",
+ "de": "Anschlusseinstellungen"
+ },
+ {
+ "token": "BTN_REBOOT_SUCCESSFUL_SAVE",
+ "en": "Reboot device after successful save",
+ "de": "Nach erfolgreichem Speichern AhoyDTU neu starten"
+ },
+ {
+ "token": "BTN_ERASE",
+ "en": "ERASE SETTINGS (not WiFi)",
+ "de": "Einstellungen zurücksetzen (nicht WiFi)"
+ },
+ {
+ "token": "IM_EXPORT",
+ "en": "Import / Export JSON Settings",
+ "de": "Import / Export JSON Einstellungen"
+ },
+ {
+ "token": "IMPORT",
+ "en": "Import",
+ "de": "Import"
+ },
+ {
+ "token": "EXPORT",
+ "en": "Export",
+ "de": "Export"
+ },
+ {
+ "token": "BTN_EXPORT",
+ "en": "Export settings (JSON file)",
+ "de": "Einstellungen exportieren (JSON Datei)"
+ },
+ {
+ "token": "EXPORT_NOTE",
+ "en": "(only values, passwords will be skipped!)",
+ "de": "(nur Werte, Passwörter werden nicht mit exportiert!)"
+ },
+ {
+ "token": "PIN_OFF",
+ "en": "off / default",
+ "de": "aus / Standard"
+ },
+ {
+ "token": "PIN_NO_IRQ",
+ "en": "no IRQ!",
+ "de": "kein Interrupt!"
+ },
+ {
+ "token": "PIN_INPUT_ONLY",
+ "en": "in only",
+ "de": "nur Eingang"
+ },
+ {
+ "token": "PIN_DONT_USE",
+ "en": "DONT USE",
+ "de": "nicht benutzen"
+ },
+ {
+ "token": "PIN_NOT_AVAIL",
+ "en": "not available",
+ "de": "nicht verfügbar"
+ },
+ {
+ "token": "PIN_RECOMMENDED",
+ "en": "recommended",
+ "de": "empfohlen"
+ },
+ {
+ "token": "PIN_EXPERIMENTAL",
+ "en": "experimental",
+ "de": "experimentell"
+ },
+ {
+ "token": "PIN_LOW_ACTIVE",
+ "en": "low active",
+ "de": "low aktiv"
+ },
+ {
+ "token": "PIN_HIGH_ACTIVE",
+ "en": "high active",
+ "de": "high aktiv"
+ },
+ {
+ "token": "NETWORK_SCANNING",
+ "en": "scanning ...",
+ "de": "suche ..."
+ },
+ {
+ "token": "ERROR",
+ "en": "Error:",
+ "de": "Fehler:"
+ },
+ {
+ "token": "NTP_COMMAND_EXE",
+ "en": "command executed, set new time ...",
+ "de": "Befehl ausgeführt, setze neue Zeit ..."
+ },
+ {
+ "token": "NTP_SYNCED_AT",
+ "en": "synced at",
+ "de": "syncchronisiert um"
+ },
+ {
+ "token": "NTP_DIFF",
+ "en": "difference",
+ "de": "Unterschied"
+ },
+ {
+ "token": "MQTT_EXE",
+ "en": "command executed",
+ "de": "Befehl ausgeführt"
+ },
+ {
+ "token": "IMPORT_UPLOAD_STARTED",
+ "en": "upload started",
+ "de": "hochladen gestartet"
+ },
+ {
+ "token": "INV_EDIT",
+ "en": "Edit",
+ "de": "Bearbeiten"
+ },
+ {
+ "token": "INV_DELETE",
+ "en": "Delete",
+ "de": "Löschen"
+ },
+ {
+ "token": "ENABLED",
+ "en": "enabled",
+ "de": "aktiviert"
+ },
+ {
+ "token": "DISABLED",
+ "en": "disabled",
+ "de": "deaktiviert"
+ },
+ {
+ "token": "BTN_INV_ADD",
+ "en": "add Inverter",
+ "de": "Wechselrichter hinzufuegen"
+ },
+ {
+ "token": "INV_INPUT",
+ "en": "Input",
+ "de": "Eingang"
+ },
+ {
+ "token": "INV_MAX_MODULE_POWER",
+ "en": "Max Module Power",
+ "de": "Maximale Panelleistung"
+ },
+ {
+ "token": "INV_YIELD_CORR",
+ "en": "Yield Correction",
+ "de": "Ertragskorrektur"
+ },
+ {
+ "token": "TAB_GENERAL",
+ "en": "General",
+ "de": "Allgemein"
+ },
+ {
+ "token": "TAB_INPUTS",
+ "en": "Inputs",
+ "de": "Eingaenge"
+ },
+ {
+ "token": "TAB_RADIO",
+ "en": "Radio",
+ "de": "Funkmodul"
+ },
+ {
+ "token": "TAB_ADVANCED",
+ "en": "Advanced",
+ "de": "Erweitert"
+ },
+ {
+ "token": "INV_ENABLE",
+ "en": "Enabled",
+ "de": "aktiviert"
+ },
+ {
+ "token": "INV_SERIAL",
+ "en": "Serial",
+ "de": "Seriennummer"
+ },
+ {
+ "token": "INV_FREQUENCY",
+ "en": "Frequency",
+ "de": "Frequenz"
+ },
+ {
+ "token": "INV_POWER_LEVEL",
+ "en": "Power Level",
+ "de": "Sendeleistung"
+ },
+ {
+ "token": "INV_PAUSE_DURING_NIGHT",
+ "en": "Pause communication during night (lat. and lon. need to be set)",
+ "de": "Kommunikation während der Nacht pausieren (Breiten- und Längengrad müssen gesetzt sein"
+ },
+ {
+ "token": "INV_INCLUDE_MQTT_SUM",
+ "en": "Include inverter to sum of total (should be checked by default, MqTT only)",
+ "de": "Wechselrichter in Liste der aufzuaddierenden Wechselrichter aufnehmen (nur MqTT)"
+ },
+ {
+ "token": "BTN_SAVE",
+ "en": "save",
+ "de": "speichern"
+ },
+ {
+ "token": "INV_EDIT_MODAL",
+ "en": "Edit inverter",
+ "de": "Wechselrichter editieren"
+ },
+ {
+ "token": "INV_DELETE_SURE",
+ "en": "do you realy want to delete inverter?",
+ "de": "Willst du den Wechselrichter wirklich löschen?"
+ },
+ {
+ "token": "BTN_YES",
+ "en": "yes",
+ "de": "ja"
+ },
+ {
+ "token": "INV_DELETE_MODAL",
+ "en": "Delete inverter",
+ "de": "Wechselrichter löschen "
+ },
+ {
+ "token": "NTP_MINUTES",
+ "en": "minutes",
+ "de": "Minuten"
+ },
+ {
+ "token": "LED_AT_LEAST_ONE_PRODUCING",
+ "en": "At least one inverter is producing",
+ "de": "mindestens ein Wechselrichter produziert"
+ },
+ {
+ "token": "LED_MQTT_CONNECTED",
+ "en": "MqTT connected",
+ "de": "MqTT verbunden"
+ },
+ {
+ "token": "LED_NIGHT_TIME",
+ "en": "Night time",
+ "de": "Nachtschaltung"
+ },
+ {
+ "token": "LED_POLARITY",
+ "en": "LED polarity",
+ "de": "LED Polarität"
+ },
+ {
+ "token": "LED_LUMINANCE",
+ "en": "LED luminance",
+ "de": "LED Helligkeit"
+ },
+ {
+ "token": "NRF24_ENABLE",
+ "en": "NRF24 radio enable",
+ "de": "NRF24 Funkmodul aktivieren"
+ },
+ {
+ "token": "CMT_ENABLE",
+ "en": "CMT2300A radio enable",
+ "de": "CMT2300A Funkmodul aktivieren"
+ },
+ {
+ "token": "DISP_NONE",
+ "en": "None",
+ "de": "keins"
+ },
+ {
+ "token": "DISP_TYPE",
+ "en": "Type",
+ "de": "Typ"
+ },
+ {
+ "token": "DISP_ROTATION",
+ "en": "Rotation",
+ "de": "Drehung"
+ },
+ {
+ "token": "DISP_SCREENSAVER_OFF",
+ "en": "off",
+ "de": "aus"
+ },
+ {
+ "token": "DISP_PIXEL_SHIFT",
+ "en": "pixel shift",
+ "de": "Bildversatz"
+ },
+ {
+ "token": "DISP_MOTION_SENS",
+ "en": "motion sensor",
+ "de": "Bewegungssensor"
+ },
+ {
+ "token": "DISP_SCREENSAVER",
+ "en": "Screensaver (OLED only)",
+ "de": "Bildschrimschoner (nur OLED)"
+ },
+ {
+ "token": "NETWORK_PLEASE_SELECT",
+ "en": "please select network",
+ "de": "bitte Netzwerk auswählen"
+ },
+ {
+ "token": "NO_NETWORK_FOUND",
+ "en": "no network found",
+ "de": "kein Netzwerk gefunden"
+ }
+ ]
+ },
+ {
+ "name": "system.html",
+ "list": [
+ {
+ "token": "UNKNOWN",
+ "en": "unknown",
+ "de": "unbekannt"
+ },
+ {
+ "token": "CONNECTED",
+ "en": "connected",
+ "de": "verbunden"
+ },
+ {
+ "token": "NOT",
+ "en": "not",
+ "de": "nicht"
+ },
+ {
+ "token": "IRQ_WORKING",
+ "en": "Interrupt Pin working",
+ "de": "Interrupt Pin funktoniert"
+ },
+ {
+ "token": "NRF24_DATA_RATE",
+ "en": "NRF24 Data Rate",
+ "de": "NRF24 Geschwindigkeit"
+ },
+ {
+ "token": "NOT_ENABLED",
+ "en": "not enabled",
+ "de": "nicht aktiviert"
+ },
+ {
+ "token": "NRF24_RADIO",
+ "en": "Radio NRF24",
+ "de": "NRF24 Funkmodul"
+ },
+ {
+ "token": "CMT_RADIO",
+ "en": "Radio CMT",
+ "de": "CMT2300A Funkmodul"
+ },
+ {
+ "token": "TRUE",
+ "en": "true",
+ "de": "ja"
+ },
+ {
+ "token": "FALSE",
+ "en": "false",
+ "de": "nein"
+ },
+ {
+ "token": "ENABLED",
+ "en": "enabled",
+ "de": "aktiviert"
+ },
+ {
+ "token": "SUN",
+ "en": "Sun",
+ "de": "Sonne"
+ },
+ {
+ "token": "SUNRISE",
+ "en": "sunrise",
+ "de": "Sonnenaufgang"
+ },
+ {
+ "token": "SUNSET",
+ "en": "sunset",
+ "de": "Sonnenuntergang"
+ },
+ {
+ "token": "COMMUNICATION_START",
+ "en": "Communication start",
+ "de": "Start der Kommunikation"
+ },
+ {
+ "token": "COMMUNICATION_STOP",
+ "en": "Communication stop",
+ "de": "Ende der Kommunikation"
+ },
+ {
+ "token": "NIGHT_BEHAVE",
+ "en": "Night behaviour",
+ "de": "Verhalten bei Nacht"
+ },
+ {
+ "token": "COMMUNICATING",
+ "en": "communicating",
+ "de": "aktiv"
+ }
+ ]
+ },
+ {
+ "name": "index.html",
+ "list": [
+ {
+ "token": "SUPPORT",
+ "en": "Support this project",
+ "de": "Dieses Projekt unterstützen"
+ },
+ {
+ "token": "CHANGELOG",
+ "en": "Changelog",
+ "de": "Änderungshistorie"
+ },
+ {
+ "token": "DISCUSS",
+ "en": "Discuss with us on",
+ "de": "Diskutiere mit uns bei"
+ },
+ {
+ "token": "REPORT",
+ "en": "Report",
+ "de": "Melde "
+ },
+ {
+ "token": "ISSUES",
+ "en": "Issues",
+ "de": "Fehler "
+ },
+ {
+ "token": "CONTRIBUTE",
+ "en": "Contribute to",
+ "de": "Unterstütze bei"
+ },
+ {
+ "token": "DOCUMENTATION",
+ "en": "documentation",
+ "de": "der Dokumentation"
+ },
+ {
+ "token": "DEV_FIRMWARE",
+ "en": "development firmware",
+ "de": "Entwicklerversionen der Firmware"
+ },
+ {
+ "token": "DEV_CHANGELOG",
+ "en": "Development Changelog",
+ "de": "Änderungshistorie der Entwicklerversionen"
+ },
+ {
+ "token": "DON_MAKE",
+ "en": "make a",
+ "de": "Unterstüze mit"
+ },
+ {
+ "token": "DON_MAKE",
+ "en": "make a",
+ "de": "Unterstüze z.B. mit"
+ },
+ {
+ "token": "DONATION",
+ "en": "donation",
+ "de": "Paypal"
+ },
+ {
+ "token": "COMMAND_EXE",
+ "en": "command executed",
+ "de": "Befehl ausgeführt"
+ },
+ {
+ "token": "ERROR",
+ "en": "Error",
+ "de": "Fehler"
+ },
+ {
+ "token": "NTP_UNREACH",
+ "en": "NTP timeserver unreachable",
+ "de": "NTP Zeitserver nicht erreichbar"
+ },
+ {
+ "token": "POLLING_STOP",
+ "en": "Polling inverter(s), will pause at sunset",
+ "de": "Abfrage der Wechselrichter wird zum Sonnenuntergang stoppen"
+ },
+ {
+ "token": "NIGHT_TIME",
+ "en": "Night time, inverter polling disabled",
+ "de": "Nacht, Wechselrichterabfrage deaktivert"
+ },
+ {
+ "token": "PAUSED_AT",
+ "en": "paused at",
+ "de": "pausiert um"
+ },
+ {
+ "token": "START_AT",
+ "en": "will start polling at",
+ "de": "wird starten um"
+ },
+ {
+ "token": "DISABLED",
+ "en": "disabled",
+ "de": "deaktiviert"
+ },
+ {
+ "token": "NOT_YET_AVAIL",
+ "en": "not yet available",
+ "de": "gerade nicht verfügbar"
+ },
+ {
+ "token": "AVAIL",
+ "en": "available and is",
+ "de": "verfügbar und ist"
+ },
+ {
+ "token": "AVAIL_NO_DATA",
+ "en": "available but no data was received until now",
+ "de": "verfügbar, aber bis jetzt keine Daten empfangen"
+ },
+ {
+ "token": "NOT_PRODUCING",
+ "en": "not producing",
+ "de": "produziert nicht"
+ },
+ {
+ "token": "PRODUCING",
+ "en": "producing",
+ "de": "produziert"
+ },
+ {
+ "token": "INVERTER",
+ "en": "Inverter",
+ "de": "Wechselrichter"
+ },
+ {
+ "token": "IS",
+ "en": "is",
+ "de": "ist"
+ },
+ {
+ "token": "LAST_SUCCESS",
+ "en": "last successful transmission",
+ "de": "letzte erfolgreiche Übertragung"
+ },
+ {
+ "token": "UPDATE_AVAIL",
+ "en": "Update available, current released version",
+ "de": "Update verfügbar, aktuell veröffentlichte Version"
+ },
+ {
+ "token": "USING_DEV_VERSION",
+ "en": "You are using development version",
+ "de": "Du verwendest eine Entwicklerversion"
+ },
+ {
+ "token": "DEV_ISSUE_RELEASE_VERSION",
+ "en": "In case of issues you may want to try the current stable release",
+ "de": "Wenn du Fehler feststellst solltest du die aktuelle Releaseversion verwenden"
+ },
+ {
+ "token": "RELEASE_INSTALLED",
+ "en": "You are using the current stable release",
+ "de": "Du verwendest das aktuelle Release"
+ }
+ ]
+ },
+ {
+ "name": "update.html",
+ "list": [
+ {
+ "token": "SELECT_FILE",
+ "en": "Select firmware file",
+ "de": "Firmware Datei auswählen"
+ },
+ {
+ "token": "BTN_UPDATE",
+ "en": "Update",
+ "de": "aktualisieren"
+ },
+ {
+ "token": "BTN_UPDATE",
+ "en": "Update",
+ "de": "aktualisieren"
+ },
+ {
+ "token": "DOWNLOADS",
+ "en": "Download latest Release and Development versions (without login)",
+ "de": "Lade die letzte Releaseversion oder Entwicklerversion herunter (ohne Login)"
+ },
+ {
+ "token": "UPDATE_STARTED",
+ "en": "update started",
+ "de": "Aktualisierung gestartet"
+ }
+ ]
+ },
+ {
+ "name": "visualization.html",
+ "list": [
+ {
+ "token": "EVERY",
+ "en": "Every",
+ "de": "Alle"
+ },
+ {
+ "token": "UPDATE_SECS",
+ "en": "seconds the values are updated",
+ "de": "Sekunden werden die Daten aktualisiert"
+ },
+ {
+ "token": "TOTAL",
+ "en": "TOTAL",
+ "de": "GESAMT"
+ },
+ {
+ "token": "AC_POWER",
+ "en": "AC Power",
+ "de": "AC Leistung"
+ },
+ {
+ "token": "YIELD_DAY",
+ "en": "Yield Day",
+ "de": "Tagesertrag"
+ },
+ {
+ "token": "YIELD_TOTAL",
+ "en": "Yield Total",
+ "de": "Gesamtertrag"
+ },
+ {
+ "token": "MAX_POWER",
+ "en": "Max Power",
+ "de": "Maximale Leistung"
+ },
+ {
+ "token": "DC_POWER",
+ "en": "DC Power",
+ "de": "DC Leistung"
+ },
+ {
+ "token": "REACTIVE_POWER",
+ "en": "Reactive Power",
+ "de": "Blindleistung"
+ },
+ {
+ "token": "ACTIVE_POWER_CONTROL",
+ "en": "Active Power Control",
+ "de": "Leistungsbegrenzung"
+ },
+ {
+ "token": "APC",
+ "en": "APC",
+ "de": "Begr."
+ },
+ {
+ "token": "ALARMS",
+ "en": "Alarms",
+ "de": "Meldungen"
+ },
+ {
+ "token": "MAX_AC_POWER",
+ "en": "Max AC Power",
+ "de": "Max AC Leistung"
+ },
+ {
+ "token": "DC_POWER",
+ "en": "DC Power",
+ "de": "DC Leistung"
+ },
+ {
+ "token": "DC_VOLTAGE",
+ "en": "DC Voltage",
+ "de": "DC Spannung"
+ },
+ {
+ "token": "AC_CURRENT",
+ "en": "AC Current",
+ "de": "AC Strom"
+ },
+ {
+ "token": "FREQUENCY",
+ "en": "Frequency",
+ "de": "Frequenz"
+ },
+ {
+ "token": "EFFICIENCY",
+ "en": "Efficiency",
+ "de": "Effizienz"
+ },
+ {
+ "token": "POWER_FACTOR",
+ "en": "Power Factor",
+ "de": "Leistungsfaktor"
+ },
+ {
+ "token": "IRRADIATION",
+ "en": "Irradiation",
+ "de": "Einstrahlung"
+ },
+ {
+ "token": "DC_CURRENT",
+ "en": "DC Current",
+ "de": "DC Strom"
+ },
+ {
+ "token": "LAST_RECEIVED",
+ "en": "Last received data requested at",
+ "de": "Zuletzt empfangene Daten wurden angefragt um"
+ },
+ {
+ "token": "NOTHING_RECEIVED",
+ "en": "nothing received",
+ "de": "nichts empfangen"
+ },
+ {
+ "token": "ALARMS_MODAL",
+ "en": "Alarms of inverter",
+ "de": "Meldungen von Wechselrichter"
+ },
+ {
+ "token": "SERIAL",
+ "en": "Serial",
+ "de": "Seriennummer"
+ },
+ {
+ "token": "BTN_SHOW",
+ "en": "show",
+ "de": "anzeigen"
+ },
+ {
+ "token": "EVENT",
+ "en": "Event",
+ "de": "Ereignis"
+ },
+ {
+ "token": "END",
+ "en": "End",
+ "de": "Ende"
+ },
+ {
+ "token": "HW_NUMBER",
+ "en": "Hardware Number",
+ "de": "Hardware Nummer"
+ },
+ {
+ "token": "INV_INFO",
+ "en": "Info for inverter",
+ "de": "Info für Wechselrichter"
+ },
+ {
+ "token": "VALUE",
+ "en": "Value",
+ "de": "Wert"
+ },
+ {
+ "token": "RANGE",
+ "en": "Range",
+ "de": "Bereich"
+ },
+ {
+ "token": "DEFAULT",
+ "en": "Default",
+ "de": "Standard"
+ },
+ {
+ "token": "PROFILE_NOT_READ",
+ "en": "Profile was not read until now, maybe turned off",
+ "de": "Grid-Profil wurde bis jetzt noch nicht gelesen oder das Auslesen ist nicht aktiv"
+ },
+ {
+ "token": "UNKNOWN_PROFILE",
+ "en": "Unknown Profile",
+ "de": "Unbekanntes Profil"
+ },
+ {
+ "token": "OPEN_ISSUE",
+ "en": "Please open a new issue at https://github.com/lumapu/ahoy and copy the raw data into it",
+ "de": "Bitte erstelle einen neuen Issue auf https://github.com/lumapu/ahoy und kopiere die Rohdaten hinein"
+ },
+ {
+ "token": "PROFILE_MODAL",
+ "en": "Grid Profile for inverter",
+ "de": "Grid-Profil für Wechselrichter"
+ },
+ {
+ "token": "TX_COUNT",
+ "en": "TX count",
+ "de": "Sendezähler"
+ },
+ {
+ "token": "RX_SUCCESS",
+ "en": "RX success",
+ "de": "erfolgreicher Empfang"
+ },
+ {
+ "token": "RX_FAIL",
+ "en": "RX fail",
+ "de": "fehlgeschlagener Empfang"
+ },
+ {
+ "token": "RX_NO_ANSWER",
+ "en": "RX no answer",
+ "de": "keine Antwort"
+ },
+ {
+ "token": "RX_FRAGMENTS",
+ "en": "RX fragments",
+ "de": "empfangene Fragmente"
+ },
+ {
+ "token": "TX_RETRANSMITS",
+ "en": "TX retransmits",
+ "de": "erneute Sendeversuche"
+ },
+ {
+ "token": "INV_LOSS_RATE",
+ "en": "Inverter loss rate",
+ "de": "Wechselrichter Empfangsqualität"
+ },
+ {
+ "token": "DTU_LOSS_RATE",
+ "en": "DTU loss rate",
+ "de": "DTU Empfangsqualität"
+ },
+ {
+ "token": "RADIO_STAT_MODAL",
+ "en": "Radio statistics for inverter",
+ "de": "Funkstatistik für Wechselrichter"
+ },
+ {
+ "token": "LOST_1",
+ "en": "lost",
+ "de": ""
+ },
+ {
+ "token": "LOST_2",
+ "en": "of",
+ "de": "von"
+ },
+ {
+ "token": "LOST_3",
+ "en": "",
+ "de": "verloren"
+ },
+ {
+ "token": "LIMIT_VALUE",
+ "en": "Limit Value",
+ "de": "Wert der Leistungsbegrenzung"
+ },
+ {
+ "token": "KEEP_LIMIT",
+ "en": "Keep limit over inverter restart",
+ "de": "Leistungsbegrenzung dauerhaft speichern (im Wechselrichter)"
+ },
+ {
+ "token": "BTN_APPLY",
+ "en": "Apply",
+ "de": "anwenden"
+ },
+ {
+ "token": "CONTROL",
+ "en": "Control",
+ "de": "Ansteuern"
+ },
+ {
+ "token": "RESTART",
+ "en": "restart",
+ "de": "neustarten"
+ },
+ {
+ "token": "TURN_OFF",
+ "en": "turn off",
+ "de": "ausschalten"
+ },
+ {
+ "token": "TURN_ON",
+ "en": "turn on",
+ "de": "anschalten"
+ },
+ {
+ "token": "RESULT",
+ "en": "Result",
+ "de": "Status"
+ },
+ {
+ "token": "POWER_LIMIT_MODAL",
+ "en": "Active Power Control for inverter",
+ "de": "Leistungsbegrenzung für Wechselrichter"
+ },
+ {
+ "token": "CMD_RECEIVED_WAIT_ACK",
+ "en": "received command, waiting for inverter acknowledge ...",
+ "de": "Befehl erhalten, warte auf Bestäigung von Wechselrichter ..."
+ },
+ {
+ "token": "COMMAND_RECEIVED",
+ "en": "command received",
+ "de": "Befehl erhalten"
+ },
+ {
+ "token": "ERROR",
+ "en": "Error",
+ "de": "Fehler"
+ },
+ {
+ "token": "INV_ACK",
+ "en": "inverter acknowledged active power control command",
+ "de": "Wechselrichter hat die Leistungsbegrenzung akzeptiert"
+ }
+ ]
+ },
+ {
+ "name": "save.html",
+ "list": [
+ {
+ "token": "SAVE_SETTINGS",
+ "en": "Saving settings...",
+ "de": "Einstellungen werden gespeichert ..."
+ },
+ {
+ "token": "SUCCESS_SAVED_RELOAD",
+ "en": "Settings successfully saved. Automatic page reload in 3 seconds.",
+ "de": "Einstellungen erfolgreich gespeichert. Automatische Weiterleitung in 3 Sekunden"
+ },
+ {
+ "token": "SUCCESS_SAVED_REBOOT",
+ "en": "Settings successfully saved. Rebooting. Automatic redirect in",
+ "de": "Einstellungen erfolgreich gespeichert. Automatische Weiterleitung nach Reboot in"
+ },
+ {
+ "token": "SECONDS",
+ "en": "seconds",
+ "de": "Sekunden"
+ },
+ {
+ "token": "FAILED_SAVE",
+ "en": "Failed saving settings",
+ "de": "Fehler beim Speichern"
+ }
+ ]
+ }
+ ]
+}