Available networks
- - - - - --
diff --git a/.gitignore b/.gitignore
index d4b07d4..6d729a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
.pio
.vscode
build/*.bin
-data/**/*.gz
+data/*
secrets.ini
+node_modules
+package-lock.json
!.gitkeep
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..d635dbe
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,142 @@
+const { src, dest, series, parallel } = require('gulp');
+const concat = require('gulp-concat');
+const gzip = require('gulp-gzip');
+const postcss = require('gulp-postcss');
+const cssnano = require('cssnano');
+const terser = require('gulp-terser');
+const jsonminify = require('gulp-jsonminify');
+const htmlmin = require('gulp-html-minifier-terser');
+
+// Paths for tasks
+let paths = {
+ styles: {
+ dest: 'data/static/',
+ bundles: {
+ 'app.css': [
+ 'src_data/styles/pico.min.css',
+ 'src_data/styles/iconly.css',
+ 'src_data/styles/app.css'
+ ]
+ }
+ },
+ scripts: {
+ dest: 'data/static/',
+ bundles: {
+ 'app.js': [
+ 'src_data/scripts/i18n.min.js',
+ 'src_data/scripts/lang.js',
+ 'src_data/scripts/utils.js'
+ ]
+ }
+ },
+ json: [
+ {
+ src: 'src_data/locales/*.json',
+ dest: 'data/static/locales/'
+ }
+ ],
+ static: [
+ {
+ src: 'src_data/fonts/*.*',
+ dest: 'data/static/fonts/'
+ },
+ {
+ src: 'src_data/images/*.*',
+ dest: 'data/static/images/'
+ }
+ ],
+ pages: {
+ src: 'src_data/pages/*.html',
+ dest: 'data/pages/'
+ }
+};
+
+
+
+// Tasks
+const styles = (cb) => {
+ for (let name in paths.styles.bundles) {
+ const items = paths.styles.bundles[name];
+
+ src(items)
+ .pipe(postcss([
+ cssnano({ preset: 'advanced' })
+ ]))
+ .pipe(concat(name))
+ .pipe(gzip({
+ append: true
+ }))
+ .pipe(dest(paths.styles.dest));
+ }
+
+ cb();
+}
+
+const scripts = (cb) => {
+ for (let name in paths.scripts.bundles) {
+ const items = paths.scripts.bundles[name];
+
+ src(items)
+ .pipe(terser().on('error', console.error))
+ .pipe(concat(name))
+ .pipe(gzip({
+ append: true
+ }))
+ .pipe(dest(paths.scripts.dest));
+ }
+
+ cb();
+}
+
+const jsonFiles = (cb) => {
+ for (let i in paths.json) {
+ const item = paths.json[i];
+
+ src(item.src)
+ .pipe(jsonminify())
+ .pipe(gzip({
+ append: true
+ }))
+ .pipe(dest(item.dest));
+ }
+
+ cb();
+}
+
+const staticFiles = (cb) => {
+ for (let i in paths.static) {
+ const item = paths.static[i];
+
+ src(item.src, { encoding: false })
+ .pipe(gzip({
+ append: true
+ }))
+ .pipe(dest(item.dest));
+ }
+
+ cb();
+}
+
+const pages = () => {
+ return src(paths.pages.src)
+ .pipe(htmlmin({
+ html5: true,
+ caseSensitive: true,
+ collapseWhitespace: true,
+ collapseInlineTagWhitespace: true,
+ conservativeCollapse: true,
+ removeComments: true,
+ minifyJS: true
+ }))
+ .pipe(gzip({
+ append: true
+ }))
+ .pipe(dest(paths.pages.dest));
+}
+
+exports.build_styles = styles;
+exports.build_scripts = scripts;
+exports.build_json = jsonFiles;
+exports.build_static = staticFiles;
+exports.build_pages = pages;
+exports.build_all = parallel(styles, scripts, jsonFiles, staticFiles, pages);
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..62380e7
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "otgateway",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "devDependencies": {
+ "cssnano": "^7.0.2",
+ "cssnano-preset-advanced": "^7.0.2",
+ "gulp": "^5.0.0",
+ "gulp-concat": "^2.6.1",
+ "gulp-gzip": "^1.4.2",
+ "gulp-html-minifier-terser": "^7.1.0",
+ "gulp-jsonminify": "^1.1.0",
+ "gulp-postcss": "^10.0.0",
+ "gulp-terser": "^2.1.0"
+ }
+}
diff --git a/src/PortalTask.h b/src/PortalTask.h
index 05b3115..1c30b26 100644
--- a/src/PortalTask.h
+++ b/src/PortalTask.h
@@ -77,7 +77,7 @@ protected:
#endif
// index page
- /*auto indexPage = (new DynamicPage("/", &LittleFS, "/index.html"))
+ /*auto indexPage = (new DynamicPage("/", &LittleFS, "/pages/index.html"))
->setTemplateCallback([](const char* var) -> String {
String result;
@@ -88,10 +88,10 @@ protected:
return result;
});
this->webServer->addHandler(indexPage);*/
- this->webServer->addHandler(new StaticPage("/", &LittleFS, "/index.html", PORTAL_CACHE));
+ this->webServer->addHandler(new StaticPage("/", &LittleFS, "/pages/index.html", PORTAL_CACHE));
// dashboard page
- auto dashboardPage = (new StaticPage("/dashboard.html", &LittleFS, "/dashboard.html", PORTAL_CACHE))
+ auto dashboardPage = (new StaticPage("/dashboard.html", &LittleFS, "/pages/dashboard.html", PORTAL_CACHE))
->setBeforeSendCallback([this]() {
if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) {
this->webServer->requestAuthentication(DIGEST_AUTH);
@@ -117,7 +117,7 @@ protected:
});
// network settings page
- auto networkPage = (new StaticPage("/network.html", &LittleFS, "/network.html", PORTAL_CACHE))
+ auto networkPage = (new StaticPage("/network.html", &LittleFS, "/pages/network.html", PORTAL_CACHE))
->setBeforeSendCallback([this]() {
if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) {
this->webServer->requestAuthentication(DIGEST_AUTH);
@@ -129,7 +129,7 @@ protected:
this->webServer->addHandler(networkPage);
// settings page
- auto settingsPage = (new StaticPage("/settings.html", &LittleFS, "/settings.html", PORTAL_CACHE))
+ auto settingsPage = (new StaticPage("/settings.html", &LittleFS, "/pages/settings.html", PORTAL_CACHE))
->setBeforeSendCallback([this]() {
if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) {
this->webServer->requestAuthentication(DIGEST_AUTH);
@@ -141,7 +141,7 @@ protected:
this->webServer->addHandler(settingsPage);
// upgrade page
- auto upgradePage = (new StaticPage("/upgrade.html", &LittleFS, "/upgrade.html", PORTAL_CACHE))
+ auto upgradePage = (new StaticPage("/upgrade.html", &LittleFS, "/pages/upgrade.html", PORTAL_CACHE))
->setBeforeSendCallback([this]() {
if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) {
this->webServer->requestAuthentication(DIGEST_AUTH);
@@ -250,6 +250,7 @@ protected:
fsNetworkSettings.update();
network->setHostname(networkSettings.hostname)
->setStaCredentials(networkSettings.sta.ssid, networkSettings.sta.password, networkSettings.sta.channel)
+ ->setApCredentials(networkSettings.ap.ssid, networkSettings.ap.password, networkSettings.ap.channel)
->setUseDhcp(networkSettings.useDhcp)
->setStaticConfig(
networkSettings.staticConfig.ip,
@@ -326,6 +327,7 @@ protected:
fsNetworkSettings.update();
network->setHostname(networkSettings.hostname)
->setStaCredentials(networkSettings.sta.ssid, networkSettings.sta.password, networkSettings.sta.channel)
+ ->setApCredentials(networkSettings.ap.ssid, networkSettings.ap.password, networkSettings.ap.channel)
->setUseDhcp(networkSettings.useDhcp)
->setStaticConfig(
networkSettings.staticConfig.ip,
@@ -573,7 +575,7 @@ protected:
}
});
- this->webServer->serveStatic("/favicon.ico", LittleFS, "/static/favicon.ico", PORTAL_CACHE);
+ this->webServer->serveStatic("/favicon.ico", LittleFS, "/static/images/favicon.ico", PORTAL_CACHE);
this->webServer->serveStatic("/static", LittleFS, "/static", PORTAL_CACHE);
}
diff --git a/src_data/static/fonts/iconly.eot b/src_data/fonts/iconly.eot
similarity index 100%
rename from src_data/static/fonts/iconly.eot
rename to src_data/fonts/iconly.eot
diff --git a/src_data/fonts/iconly.svg b/src_data/fonts/iconly.svg
new file mode 100644
index 0000000..8eed6c2
--- /dev/null
+++ b/src_data/fonts/iconly.svg
@@ -0,0 +1,78 @@
+
+
+
diff --git a/src_data/static/fonts/iconly.ttf b/src_data/fonts/iconly.ttf
similarity index 100%
rename from src_data/static/fonts/iconly.ttf
rename to src_data/fonts/iconly.ttf
diff --git a/src_data/static/fonts/iconly.woff b/src_data/fonts/iconly.woff
similarity index 100%
rename from src_data/static/fonts/iconly.woff
rename to src_data/fonts/iconly.woff
diff --git a/src_data/static/fonts/iconly.woff2 b/src_data/fonts/iconly.woff2
similarity index 100%
rename from src_data/static/fonts/iconly.woff2
rename to src_data/fonts/iconly.woff2
diff --git a/src_data/static/favicon.ico b/src_data/images/favicon.ico
similarity index 100%
rename from src_data/static/favicon.ico
rename to src_data/images/favicon.ico
diff --git a/src_data/locales/en.json b/src_data/locales/en.json
new file mode 100644
index 0000000..f86c061
--- /dev/null
+++ b/src_data/locales/en.json
@@ -0,0 +1,331 @@
+{
+ "values": {
+ "logo": "OpenTherm Gateway",
+ "nav": {
+ "license": "License",
+ "source": "Source code",
+ "help": "Help",
+ "issues": "Issues & questions",
+ "releases": "Releases"
+ },
+
+ "button": {
+ "upgrade": "Upgrade",
+ "restart": "Restart",
+ "save": "Save",
+ "saved": "Saved",
+ "refresh": "Refresh",
+ "restore": "Restore",
+ "restored": "Restored",
+ "backup": "Backup",
+ "wait": "Please wait...",
+ "uploading": "Uploading...",
+ "success": "Success",
+ "error": "Error"
+ },
+
+ "index": {
+ "title": "OpenTherm Gateway",
+
+ "section": {
+ "network": "Network",
+ "system": "System"
+ },
+
+ "system": {
+ "build": {
+ "title": "Build",
+ "version": "Version",
+ "date": "Date",
+ "sdk": "Core/SDK"
+ },
+ "uptime": "Uptime",
+ "memory": {
+ "title": "Free memory",
+ "maxFreeBlock": "max free block",
+ "min": "min"
+ },
+ "board": "Board",
+ "chip": {
+ "model": "Chip",
+ "cores": "Cores",
+ "freq": "frequency"
+ },
+ "flash": {
+ "size": "Flash size",
+ "realSize": "real size"
+ },
+ "lastResetReason": "Last reset reason"
+ }
+ },
+
+ "dashboard": {
+ "name": "Dashboard",
+ "title": "Dashboard - OpenTherm Gateway",
+
+ "section": {
+ "control": "Control",
+ "states": "States and sensors",
+ "otDiag": "OpenTherm diagnostic"
+ },
+
+ "thermostat": {
+ "heating": "Heating",
+ "dhw": "DHW",
+ "temp.current": "Current",
+ "enable": "Enable",
+ "turbo": "Turbo mode"
+ },
+
+ "state": {
+ "ot": "OpenTherm connected",
+ "mqtt": "MQTT connected",
+ "emergency": "Emergency",
+ "heating": "Heating",
+ "dhw": "DHW",
+ "flame": "Flame",
+ "fault": "Fault",
+ "diag": "Diagnostic",
+ "extpump": "External pump",
+ "modulation": "Modulation",
+ "pressure": "Pressure",
+ "dhwFlowRate": "DHW flow rate",
+ "faultCode": "Fault code",
+ "indoorTemp": "Indoor temp",
+ "outdoorTemp": "Outdoor temp",
+ "heatingTemp": "Heating temp",
+ "heatingSetpointTemp": "Heating setpoint temp",
+ "heatingReturnTemp": "Heating return temp",
+ "dhwTemp": "DHW temp",
+ "exhaustTemp": "Exhaust temp"
+ }
+ },
+
+ "network": {
+ "title": "Network - OpenTherm Gateway",
+ "name": "Network settings",
+
+ "section": {
+ "static": "Static settings",
+ "availableNetworks": "Available networks",
+ "staSettings": "WiFi settings",
+ "apSettings": "AP settings"
+ },
+
+ "scan": {
+ "pos": "#",
+ "info": "Info"
+ },
+
+ "wifi": {
+ "ssid": "SSID",
+ "password": "Password",
+ "channel": "Channel",
+ "signal": "Signal",
+ "connected": "Connected"
+ },
+
+ "params": {
+ "hostname": "Hostname",
+ "dhcp": "Use DHCP",
+ "mac": "MAC",
+ "ip": "IP",
+ "subnet": "Subnet",
+ "gateway": "Gateway",
+ "dns": "DNS"
+ },
+
+ "sta": {
+ "channel.note": "set 0 for auto select"
+ }
+ },
+
+ "settings": {
+ "title": "Settings - OpenTherm Gateway",
+ "name": "Settings",
+
+ "section": {
+ "portal": "Portal settings",
+ "system": "System settings",
+ "diag": "Diagnostic",
+ "heating": "Heating settings",
+ "dhw": "DHW settings",
+ "emergency": "Emergency mode settings",
+ "emergency.events": "Events",
+ "emergency.regulators": "Using regulators",
+ "equitherm": "Equitherm settings",
+ "pid": "PID settings",
+ "ot": "OpenTherm settings",
+ "ot.options": "Options",
+ "mqtt": "MQTT settings",
+ "outdorSensor": "Outdoor sensor settings",
+ "indoorSensor": "Indoor sensor settings",
+ "extPump": "External pump settings"
+ },
+
+ "enable": "Enable",
+ "note": {
+ "restart": "After changing these settings, the device must be restarted for the changes to take effect.",
+ "blankNotUse": "blank - not use"
+ },
+
+ "temp": {
+ "min": "Minimum temperature",
+ "max": "Maximum temperature"
+ },
+
+ "portal": {
+ "login": "Login",
+ "password": "Password",
+ "auth": "Require authentication"
+ },
+
+ "system": {
+ "unit": "Unit system",
+ "metric": "Metric (celsius, liters, bar)",
+ "imperial": "Imperial (fahrenheit, gallons, psi)",
+ "statusLedGpio": "Status LED GPIO",
+ "debug": "Debug mode",
+ "serial": {
+ "enable": "Enable Serial port",
+ "baud": {
+ "title": "Serial port baud rate",
+ "note": "Available: 9600, 19200, 38400, 57600, 74880, 115200"
+ }
+ },
+ "telnet": {
+ "enable": "Enable Telnet",
+ "port": {
+ "title": "Telnet port",
+ "note": "Default: 23"
+ }
+ }
+ },
+
+ "heating": {
+ "hyst": "Hysteresis",
+ "maxMod": "Max modulation level"
+ },
+
+ "emergency": {
+ "desc": "! Emergency mode can be useful only when using Equitherm and/or PID (when normal work) and when reporting indoor/outdoor temperature via MQTT or API. In this mode, sensor values that are reported via MQTT/API are not used.",
+
+ "target": {
+ "title": "Target temperature",
+ "note": "Indoor temperature if Equitherm or PID is enabled
Heat carrier temperature if Equitherm and PID is disabled"
+ },
+ "treshold": "Treshold time (sec)",
+
+ "events": {
+ "network": "On network fault",
+ "mqtt": "On MQTT fault"
+ },
+
+ "regulators": {
+ "equitherm": "Equitherm (requires at least an external/boiler outdoor sensor)",
+ "pid": "PID (requires at least an external/BLE indoor sensor)"
+ }
+ },
+
+ "equitherm": {
+ "n": "N factor",
+ "k": "K factor",
+ "t": {
+ "title": "T factor",
+ "note": "Not used if PID is enabled"
+ }
+ },
+
+ "pid": {
+ "p": "P factor",
+ "i": "I factor",
+ "d": "D factor",
+ "dt": "DT in seconds"
+ },
+
+ "ot": {
+ "inGpio": "In GPIO",
+ "outGpio": "Out GPIO",
+ "ledGpio": "RX LED GPIO",
+ "memberIdCode": "Master MemberID code",
+
+ "options": {
+ "dhwPresent": "DHW present",
+ "summerWinterMode": "Summer/winter mode",
+ "heatingCh2Enabled": "Heating CH2 always enabled",
+ "heatingCh1ToCh2": "Duplicate heating CH1 to CH2",
+ "dhwToCh2": "Duplicate DHW to CH2",
+ "dhwBlocking": "DHW blocking",
+ "modulationSyncWithHeating": "Sync modulation with heating",
+ "getMinMaxTemp": "Get min/max temp from boiler"
+ },
+
+ "faultState": {
+ "gpio": "Fault state GPIO",
+ "note": "Can be useful to switch on another boiler via relay. Blank - not use.",
+ "invert": "Invert fault state"
+ },
+
+ "nativeHeating": {
+ "title": "Native heating control (boiler)",
+ "note": "Works ONLY if the boiler requires the desired room temperature and regulates the temperature of the coolant itself. Not compatible with PID and Equitherm regulators and hysteresis in firmware."
+ }
+ },
+
+ "mqtt": {
+ "homeAssistantDiscovery": "Home Assistant Discovery",
+ "server": "Server",
+ "port": "Port",
+ "user": "User",
+ "password": "Password",
+ "prefix": "Prefix",
+ "interval": "Publish interval (sec)"
+ },
+
+ "tempSensor": {
+ "source": {
+ "type": "Source type",
+ "boiler": "From boiler via OpenTherm",
+ "manual": "Manual via MQTT/API",
+ "ext": "External (DS18B20)",
+ "ble": "BLE device (ONLY for some ESP32 which support BLE)"
+ },
+ "gpio": "GPIO",
+ "offset": "Temp offset (calibration)",
+ "bleAddress": {
+ "title": "BLE address",
+ "note": "ONLY for some ESP32 which support BLE"
+ }
+ },
+
+ "extPump": {
+ "use": "Use external pump",
+ "gpio": "Relay GPIO",
+ "postCirculationTime": "Post circulation time (min)",
+ "antiStuckInterval": "Anti stuck interval (days)",
+ "antiStuckTime": "Anti stuck time (min)"
+ }
+ },
+
+ "upgrade": {
+ "title": "Upgrade - OpenTherm Gateway",
+ "name": "Upgrade",
+
+ "section": {
+ "backupAndRestore": "Backup & restore",
+ "backupAndRestore.desc": "In this section you can save and restore a backup of ALL settings.",
+ "upgrade": "Upgrade",
+ "upgrade.desc": "In this section you can upgrade the firmware and filesystem of your device.
Latest releases can be downloaded from the Releases page of the project repository."
+ },
+
+ "note": {
+ "disclaimer1": "After a successful upgrade the filesystem, ALL settings will be reset to default values! Save backup before upgrading.",
+ "disclaimer2": "After a successful upgrade, the device will automatically reboot after 10 seconds."
+ },
+
+ "settingsFile": "Settings file",
+ "fw": "Firmware",
+ "fs": "Filesystem"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src_data/locales/ru.json b/src_data/locales/ru.json
new file mode 100644
index 0000000..4349836
--- /dev/null
+++ b/src_data/locales/ru.json
@@ -0,0 +1,331 @@
+{
+ "values": {
+ "logo": "OpenTherm Gateway",
+ "nav": {
+ "license": "Лицензия",
+ "source": "Исходный код",
+ "help": "Помощь",
+ "issues": "Проблемы и вопросы",
+ "releases": "Релизы"
+ },
+
+ "button": {
+ "upgrade": "Обновить",
+ "restart": "Перезагрузка",
+ "save": "Сохранить",
+ "saved": "Сохранено",
+ "refresh": "Обновить",
+ "restore": "Восстановить настройки",
+ "restored": "Восстановлено",
+ "backup": "Сохранить настройки",
+ "wait": "Пожалуйста, подождите...",
+ "uploading": "Загрузка...",
+ "success": "Успешно",
+ "error": "Ошибка"
+ },
+
+ "index": {
+ "title": "OpenTherm Gateway",
+
+ "section": {
+ "network": "Сеть",
+ "system": "Система"
+ },
+
+ "system": {
+ "build": {
+ "title": "Билд",
+ "version": "Версия",
+ "date": "Дата",
+ "sdk": "Ядро/SDK"
+ },
+ "uptime": "Аптайм",
+ "memory": {
+ "title": "ОЗУ",
+ "maxFreeBlock": "макс. блок",
+ "min": "мин."
+ },
+ "board": "Плата",
+ "chip": {
+ "model": "Чип",
+ "cores": "Кол-во ядер",
+ "freq": "частота"
+ },
+ "flash": {
+ "size": "Размер ПЗУ",
+ "realSize": "реальный размер"
+ },
+ "lastResetReason": "Причина перезагрузки"
+ }
+ },
+
+ "dashboard": {
+ "name": "Дашборд",
+ "title": "Дашборд - OpenTherm Gateway",
+
+ "section": {
+ "control": "Управление",
+ "states": "Состояние и сенсоры",
+ "otDiag": "Диагностика OpenTherm"
+ },
+
+ "thermostat": {
+ "heating": "Отопление",
+ "dhw": "ГВС",
+ "temp.current": "Текущая",
+ "enable": "Вкл",
+ "turbo": "Турбо"
+ },
+
+ "state": {
+ "ot": "OpenTherm подключение",
+ "mqtt": "MQTT подключение",
+ "emergency": "Аварийный режим",
+ "heating": "Отопление",
+ "dhw": "ГВС",
+ "flame": "Пламя",
+ "fault": "Ошибка",
+ "diag": "Диагностика",
+ "extpump": "Внешний насос",
+ "modulation": "Уровень модуляции",
+ "pressure": "Давление",
+ "dhwFlowRate": "Расход ГВС",
+ "faultCode": "Код ошибки",
+ "indoorTemp": "Внутренняя темп.",
+ "outdoorTemp": "Наружная темп.",
+ "heatingTemp": "Темп. отопления",
+ "heatingSetpointTemp": "Уставка темп. отопления",
+ "heatingReturnTemp": "Темп. обратки отопления",
+ "dhwTemp": "Темп. ГВС",
+ "exhaustTemp": "Темп. выхлопных газов"
+ }
+ },
+
+ "network": {
+ "title": "Сеть - OpenTherm Gateway",
+ "name": "Настройки сети",
+
+ "section": {
+ "static": "Статические параметры",
+ "availableNetworks": "Доступные сети",
+ "staSettings": "Настройки подключения",
+ "apSettings": "Настройки точки доступа"
+ },
+
+ "scan": {
+ "pos": "#",
+ "info": "Инфо"
+ },
+
+ "wifi": {
+ "ssid": "Имя сети",
+ "password": "Пароль",
+ "channel": "Канал",
+ "signal": "Сигнал",
+ "connected": "Подключено"
+ },
+
+ "params": {
+ "hostname": "Имя хоста",
+ "dhcp": "Использовать DHCP",
+ "mac": "MAC адрес",
+ "ip": "IP адрес",
+ "subnet": "Адрес подсети",
+ "gateway": "Адрес шлюза",
+ "dns": "DNS адрес"
+ },
+
+ "sta": {
+ "channel.note": "установите 0 для автоматического выбора"
+ }
+ },
+
+ "settings": {
+ "title": "Настройки - OpenTherm Gateway",
+ "name": "Настройки",
+
+ "section": {
+ "portal": "Настройки портала",
+ "system": "Системные настройки",
+ "diag": "Диагностика",
+ "heating": "Настройки отопления",
+ "dhw": "Настройки ГВС",
+ "emergency": "Настройки аварийного режима",
+ "emergency.events": "События",
+ "emergency.regulators": "Используемые регуляторы",
+ "equitherm": "Настройки ПЗА",
+ "pid": "Настройки ПИД",
+ "ot": "Настройки OpenTherm",
+ "ot.options": "Опции",
+ "mqtt": "Настройки MQTT",
+ "outdorSensor": "Настройки наружного датчика температуры",
+ "indoorSensor": "Настройки внутреннего датчика температуры",
+ "extPump": "Настройки дополнительного насоса"
+ },
+
+ "enable": "Вкл",
+ "note": {
+ "restart": "После изменения этих настроек устройство необходимо перезагрузить, чтобы изменения вступили в силу.",
+ "blankNotUse": "пусто - не использовать"
+ },
+
+ "temp": {
+ "min": "Мин. температура",
+ "max": "Макс. температура"
+ },
+
+ "portal": {
+ "login": "Логин",
+ "password": "Пароль",
+ "auth": "Требовать аутентификацию"
+ },
+
+ "system": {
+ "unit": "Система единиц",
+ "metric": "Метрическая (цильсии, литры, бары)",
+ "imperial": "Imperial (фаренгейты, галлоны, psi)",
+ "statusLedGpio": "Статус LED GPIO",
+ "debug": "Отладка",
+ "serial": {
+ "enable": "Вкл. Serial порт",
+ "baud": {
+ "title": "Скорость Serial порта",
+ "note": "Доступно: 9600, 19200, 38400, 57600, 74880, 115200"
+ }
+ },
+ "telnet": {
+ "enable": "Вкл. Telnet",
+ "port": {
+ "title": "Telnet порт",
+ "note": "По умолчанию: 23"
+ }
+ }
+ },
+
+ "heating": {
+ "hyst": "Гистерезис",
+ "maxMod": "Макс. уровень модуляции"
+ },
+
+ "emergency": {
+ "desc": "! Аварийный режим может быть полезен только при использовании ПЗА и/или ПИД и при передачи наружной/внутренней температуры через MQTT или API. В этом режиме значения датчиков, передаваемые через MQTT/API, не используются.",
+
+ "target": {
+ "title": "Целевая температура",
+ "note": "Целевая внутренняя температура если ПЗА и/или ПИД включены
Целевая температура теплоносителя если ПЗА и ПИД выключены"
+ },
+ "treshold": "Пороговое время включения (сек)",
+
+ "events": {
+ "network": "При отключении сети",
+ "mqtt": "При отключении MQTT"
+ },
+
+ "regulators": {
+ "equitherm": "ПЗА (требуется внешний или подключенный к котлу датчик наружной температуры)",
+ "pid": "ПИД (требуется внешний/BLE датчик внутренней температуры)"
+ }
+ },
+
+ "equitherm": {
+ "n": "Коэффициент N",
+ "k": "Коэффициент K",
+ "t": {
+ "title": "Коэффициент T",
+ "note": "Не используется, если ПИД включен"
+ }
+ },
+
+ "pid": {
+ "p": "Коэффициент P",
+ "i": "Коэффициент I",
+ "d": "Коэффициент D",
+ "dt": "DT в секундах"
+ },
+
+ "ot": {
+ "inGpio": "Вход GPIO",
+ "outGpio": "Выход GPIO",
+ "ledGpio": "RX LED GPIO",
+ "memberIdCode": "Master MemberID код",
+
+ "options": {
+ "dhwPresent": "Контур ГВС",
+ "summerWinterMode": "Летний/зимний режим",
+ "heatingCh2Enabled": "Канал 2 отопления всегда вкл.",
+ "heatingCh1ToCh2": "Дублировать параметры отопления канала 1 в канал 2",
+ "dhwToCh2": "Дублировать параметры ГВС в канал 2",
+ "dhwBlocking": "DHW blocking",
+ "modulationSyncWithHeating": "Синхронизировать модуляцию с отоплением",
+ "getMinMaxTemp": "Получать мин. и макс. температуру от котла"
+ },
+
+ "faultState": {
+ "gpio": "Fault state GPIO",
+ "note": "Can be useful to switch on another boiler via relay. Blank - not use.",
+ "invert": "Invert fault state"
+ },
+
+ "nativeHeating": {
+ "title": "Передать управление отоплением котлу",
+ "note": "Работает ТОЛЬКО если котел требует и принимает целевую температуру в помещении и сам регулирует температуру теплоносителя на основе встроенного режима кривых. Несовместимо с ПИД и ПЗА, а также с гистерезисом встроенного ПО."
+ }
+ },
+
+ "mqtt": {
+ "homeAssistantDiscovery": "Home Assistant Discovery",
+ "server": "Адрес сервера",
+ "port": "Порт",
+ "user": "Имя пользователя",
+ "password": "Пароль",
+ "prefix": "Префикс",
+ "interval": "Интервал публикации (в секундах)"
+ },
+
+ "tempSensor": {
+ "source": {
+ "type": "Источник данных",
+ "boiler": "От котла через OpenTherm",
+ "manual": "Вручную через MQTT/API",
+ "ext": "Внешний датчик (DS18B20)",
+ "ble": "BLE устройство (ТОЛЬКО для некоторых плат ESP32 с поддержкой BLE)"
+ },
+ "gpio": "GPIO",
+ "offset": "Смещение температуры (калибровка)",
+ "bleAddress": {
+ "title": "BLE адрес",
+ "note": "ТОЛЬКО для некоторых плат ESP32 с поддержкой BLE"
+ }
+ },
+
+ "extPump": {
+ "use": "Использовать доп. насос",
+ "gpio": "GPIO реле",
+ "postCirculationTime": "Время постциркуляции (в минутах)",
+ "antiStuckInterval": "Интервал защиты от блокировки (в днях)",
+ "antiStuckTime": "Время работы насоса (в минутах)"
+ }
+ },
+
+ "upgrade": {
+ "title": "Обновление - OpenTherm Gateway",
+ "name": "Обновление",
+
+ "section": {
+ "backupAndRestore": "Резервное копирование и восстановление",
+ "backupAndRestore.desc": "В этом разделе вы можете сохранить и восстановить резервную копию ВСЕХ настроек.",
+ "upgrade": "Обновление",
+ "upgrade.desc": "В этом разделе вы можете обновить прошивку и файловую систему вашего устройства.
Последнюю версию можно загрузить со страницы Релизы в репозитории проекта."
+ },
+
+ "note": {
+ "disclaimer1": "После успешного обновления файловой системы ВСЕ настройки будут сброшены на стандартные! Создайте резервную копию ПЕРЕД обновлением.",
+ "disclaimer2": "После успешного обновления устройство автоматически перезагрузится через 10 секунд."
+ },
+
+ "settingsFile": "Файл настроек",
+ "fw": "Прошивка",
+ "fs": "Файловая система"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src_data/network.html b/src_data/network.html
deleted file mode 100644
index 06e3a89..0000000
--- a/src_data/network.html
+++ /dev/null
@@ -1,211 +0,0 @@
-
-
-
-
| OpenTherm connected: | +dashboard.state.ot | |
|---|---|---|
| MQTT connected: | +dashboard.state.mqtt | |
| Emergency: | +dashboard.state.emergency | |
| Heating: | +dashboard.state.heating | |
| DHW: | +dashboard.state.dhw | |
| Flame: | +dashboard.state.flame | |
| Fault: | +dashboard.state.fault | |
| Diagnostic: | +dashboard.state.diag | |
| External pump: | +dashboard.state.extpump | |
| Modulation: | +dashboard.state.modulation | % |
| Pressure: | +dashboard.state.pressure | |
| DHW flow rate: | +dashboard.state.dhwFlowRate | /min |
| Fault code: | +dashboard.state.faultCode | |
| Indoor temp: | +dashboard.state.indoorTemp | |
| Outdoor temp: | +dashboard.state.outdoorTemp | |
| Heating temp: | +dashboard.state.heatingTemp | |
| Heating setpoint temp: | +dashboard.state.heatingSetpointTemp | |
| Heating return temp: | +dashboard.state.heatingReturnTemp | |
| DHW temp: | +dashboard.state.dhwTemp | |
| Exhaust temp: | +dashboard.state.exhaustTemp |