Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7f3c66e05 | ||
|
|
17bd31b2a2 | ||
|
|
8662b9dc8f | ||
|
|
6efa3a52fe | ||
|
|
7e31de6c71 | ||
|
|
b53dae6a43 | ||
|
|
de2318bc6a | ||
|
|
081209420a | ||
|
|
75bc4d5c4a | ||
|
|
527e9cc1d6 | ||
|
|
60b7caf4bc | ||
|
|
e8d0ad0a4e | ||
|
|
afe269aeff | ||
|
|
4702909043 | ||
|
|
4c32ccc450 | ||
|
|
2e3b38e14f | ||
|
|
b6c80f355f | ||
|
|
65b2a3c2bd | ||
|
|
0cb361d243 | ||
|
|
c7f54ca4fb | ||
|
|
1d46176b5e | ||
|
|
5e2f6c9cea | ||
|
|
f439f8c5ba | ||
|
|
bae7770371 | ||
|
|
4e5a3e9da5 | ||
|
|
412e1594e9 | ||
|
|
9701e8c97b | ||
|
|
2fe546812c | ||
|
|
7efcbaa57e |
68
README.md
@@ -1,40 +1,44 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||

|
|
||||||
<br>
|
|
||||||
[](https://github.com/Laxilef/OTGateway/releases)
|
[](https://github.com/Laxilef/OTGateway/releases)
|
||||||
[](https://github.com/Laxilef/OTGateway/releases/latest)
|
[](https://github.com/Laxilef/OTGateway/releases/latest)
|
||||||
[](LICENSE.txt)
|
[](LICENSE.txt)
|
||||||
[](https://t.me/otgateway)
|
[](https://t.me/otgateway)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Hot water temperature control
|
- DHW temperature control
|
||||||
- Heating temperature control
|
- Heating temperature control
|
||||||
- Smart heating temperature control modes:
|
- Smart heating temperature control modes:
|
||||||
- PID
|
- PID
|
||||||
- Equithermic curves - adjusts the temperature based on indoor and outdoor temperatures
|
- Equithermic curves - adjusts the temperature based on indoor and outdoor temperatures
|
||||||
- Hysteresis setting (for accurate maintenance of room temperature)
|
- Hysteresis setting _(for accurate maintenance of room temperature)_
|
||||||
- Ability to connect an external sensors to monitor outdoor and indoor temperature ([compatible sensors](https://github.com/Laxilef/OTGateway/wiki/Compatibility#temperature-sensors))
|
- Ability to connect [additional (external) sensors](https://github.com/Laxilef/OTGateway/wiki/Compatibility#temperature-sensors): Dallas (1-wire), NTC 10k, Bluetooth (BLE). Makes it possible to monitor indoor and outdoor temperatures, temperatures on pipes/heat exchangers/etc.
|
||||||
- Emergency mode. If the Wi-Fi connection is lost or the gateway cannot connect to the MQTT server, the mode will turn on. This mode will automatically maintain the set temperature and prevent your home from freezing. In this mode it is also possible to use equithermal curves (weather-compensated control).
|
- Emergency mode. In any dangerous situation _(loss of connection with Wifi, MQTT, sensors, etc)_ it will not let you and your home freeze.
|
||||||
- Automatic error reset (not with all boilers)
|
- Ability of remote fault reset _(not with all boilers)_
|
||||||
- Diagnostics:
|
- Diagnostics:
|
||||||
- The process of heating: works/does not work
|
- Displaying gateway status
|
||||||
- The process of heating water for hot water: working/not working
|
- Displaying the connection status to the boiler via OpenTherm
|
||||||
- Display of boiler errors
|
- Displaying the fault status and fault code
|
||||||
- Burner status (flame): on/off
|
- Displaying the diagnostic status & diagnostic code
|
||||||
- Burner modulation level in percent
|
- Display of the process of heating: works/does not work
|
||||||
- Pressure in the heating system
|
- Display of burner (flame) status: on/off
|
||||||
- Gateway status (depending on errors and connection status)
|
- Display of burner modulation level in percent
|
||||||
- Boiler connection status via OpenTherm interface
|
- Display of pressure in the heating system
|
||||||
- The current temperature of the heat carrier (usually the return heat carrier)
|
- Display of current temperature of the heat carrier
|
||||||
- Set heat carrier temperature (depending on the selected mode)
|
- Display of return temperature of the heat carrier
|
||||||
- Current hot water temperature
|
- Display of setpoint heat carrier temperature (useful when using PID or Equitherm)
|
||||||
|
- Display of the process of DHW: working/not working
|
||||||
|
- Display of current DHW temperature
|
||||||
|
- _And other information..._
|
||||||
- [Home Assistant](https://www.home-assistant.io/) integration via MQTT. The ability to create any automation for the boiler!
|
- [Home Assistant](https://www.home-assistant.io/) integration via MQTT. The ability to create any automation for the boiler!
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
All available information and instructions can be found in the wiki:
|
All available information and instructions can be found in the wiki:
|
||||||
|
|
||||||
@@ -52,6 +56,7 @@ All available information and instructions can be found in the wiki:
|
|||||||
* [Ratios](https://github.com/Laxilef/OTGateway/wiki#ratios)
|
* [Ratios](https://github.com/Laxilef/OTGateway/wiki#ratios)
|
||||||
* [Fit coefficients](https://github.com/Laxilef/OTGateway/wiki#fit-coefficients)
|
* [Fit coefficients](https://github.com/Laxilef/OTGateway/wiki#fit-coefficients)
|
||||||
* [PID mode](https://github.com/Laxilef/OTGateway/wiki#pid-mode)
|
* [PID mode](https://github.com/Laxilef/OTGateway/wiki#pid-mode)
|
||||||
|
* [Logs and debug](https://github.com/Laxilef/OTGateway/wiki#logs-and-debug)
|
||||||
* [Compatibility](https://github.com/Laxilef/OTGateway/wiki/Compatibility)
|
* [Compatibility](https://github.com/Laxilef/OTGateway/wiki/Compatibility)
|
||||||
* [Boilers](https://github.com/Laxilef/OTGateway/wiki/Compatibility#boilers)
|
* [Boilers](https://github.com/Laxilef/OTGateway/wiki/Compatibility#boilers)
|
||||||
* [Boards](https://github.com/Laxilef/OTGateway/wiki/Compatibility#boards)
|
* [Boards](https://github.com/Laxilef/OTGateway/wiki/Compatibility#boards)
|
||||||
@@ -64,24 +69,5 @@ All available information and instructions can be found in the wiki:
|
|||||||
* [Connection](https://github.com/Laxilef/OTGateway/wiki/OT-adapters#connection)
|
* [Connection](https://github.com/Laxilef/OTGateway/wiki/OT-adapters#connection)
|
||||||
* [Leds on board](https://github.com/Laxilef/OTGateway/wiki/OT-adapters#leds-on-board)
|
* [Leds on board](https://github.com/Laxilef/OTGateway/wiki/OT-adapters#leds-on-board)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
- [ESP8266Scheduler](https://github.com/nrwiersma/ESP8266Scheduler) (for ESP8266)
|
|
||||||
- [ESP32Scheduler](https://github.com/laxilef/ESP32Scheduler) (for ESP32)
|
|
||||||
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
|
|
||||||
- [OpenTherm Library](https://github.com/ihormelnyk/opentherm_library)
|
|
||||||
- [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient)
|
|
||||||
- [ESPTelnet](https://github.com/LennartHennigs/ESPTelnet)
|
|
||||||
- [FileData](https://github.com/GyverLibs/FileData)
|
|
||||||
- [GyverPID](https://github.com/GyverLibs/GyverPID)
|
|
||||||
- [GyverBlinker](https://github.com/GyverLibs/GyverBlinker)
|
|
||||||
- [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library)
|
|
||||||
- [TinyLogger](https://github.com/laxilef/TinyLogger)
|
|
||||||
|
|
||||||
## Debug
|
|
||||||
To display DEBUG messages you must enable debug in settings (switch is disabled by default).
|
|
||||||
You can connect via Telnet to read messages. IP: ESP8266 ip, port: 23
|
|
||||||
|
|
||||||
___
|
___
|
||||||
This project is tested with BrowserStack.
|
This project is tested with BrowserStack.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 261 KiB After Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 326 KiB After Width: | Height: | Size: 386 KiB |
|
Before Width: | Height: | Size: 684 KiB After Width: | Height: | Size: 849 KiB |
BIN
assets/BOM.xlsx
BIN
assets/CPL.csv
22697
assets/Schematic.pdf
BIN
assets/ha.png
|
Before Width: | Height: | Size: 190 KiB |
BIN
assets/poster-1.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/poster-2.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/poster-3.png
Normal file
|
After Width: | Height: | Size: 973 KiB |
@@ -12,16 +12,17 @@ public:
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void send(int code, T contentType, const JsonVariantConst content, bool pretty = false) {
|
void send(int code, T contentType, const JsonVariantConst content, bool pretty = false) {
|
||||||
|
auto contentLength = pretty ? measureJsonPretty(content) : measureJson(content);
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP8266
|
#ifdef ARDUINO_ARCH_ESP8266
|
||||||
if (!this->webServer->chunkedResponseModeStart(code, contentType)) {
|
if (!this->webServer->chunkedResponseModeStart(code, contentType)) {
|
||||||
this->webServer->send(505, F("text/html"), F("HTTP1.1 required"));
|
this->webServer->send(505, F("text/html"), F("HTTP1.1 required"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->webServer->setContentLength(measureJson(content));
|
this->webServer->setContentLength(contentLength);
|
||||||
#else
|
#else
|
||||||
this->webServer->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
this->webServer->setContentLength(contentLength);
|
||||||
this->webServer->sendHeader(F("Content-Length"), String(measureJson(content)));
|
|
||||||
this->webServer->send(code, contentType, emptyString);
|
this->webServer->send(code, contentType, emptyString);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,17 @@
|
|||||||
|
|
||||||
class CustomOpenTherm : public OpenTherm {
|
class CustomOpenTherm : public OpenTherm {
|
||||||
public:
|
public:
|
||||||
typedef std::function<void()> YieldCallback;
|
typedef std::function<void(unsigned int)> DelayCallback;
|
||||||
typedef std::function<void(unsigned long, byte)> BeforeSendRequestCallback;
|
typedef std::function<void(unsigned long, byte)> BeforeSendRequestCallback;
|
||||||
typedef std::function<void(unsigned long, unsigned long, OpenThermResponseStatus, byte)> AfterSendRequestCallback;
|
typedef std::function<void(unsigned long, unsigned long, OpenThermResponseStatus, byte)> AfterSendRequestCallback;
|
||||||
|
|
||||||
CustomOpenTherm(int inPin = 4, int outPin = 5, bool isSlave = false) : OpenTherm(inPin, outPin, isSlave) {}
|
CustomOpenTherm(int inPin = 4, int outPin = 5, bool isSlave = false) : OpenTherm(inPin, outPin, isSlave) {
|
||||||
|
this->_outPin = outPin;
|
||||||
|
}
|
||||||
~CustomOpenTherm() {}
|
~CustomOpenTherm() {}
|
||||||
|
|
||||||
CustomOpenTherm* setYieldCallback(YieldCallback callback = nullptr) {
|
CustomOpenTherm* setDelayCallback(DelayCallback callback = nullptr) {
|
||||||
this->yieldCallback = callback;
|
this->delayCallback = callback;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -28,14 +30,28 @@ public:
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
if (this->status == OpenThermStatus::NOT_INITIALIZED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->end();
|
||||||
|
this->status = OpenThermStatus::NOT_INITIALIZED;
|
||||||
|
|
||||||
|
digitalWrite(this->_outPin, LOW);
|
||||||
|
if (this->delayCallback) {
|
||||||
|
this->delayCallback(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->begin();
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long sendRequest(unsigned long request, byte attempts = 5, byte _attempt = 0) {
|
unsigned long sendRequest(unsigned long request, byte attempts = 5, byte _attempt = 0) {
|
||||||
_attempt++;
|
_attempt++;
|
||||||
|
|
||||||
while (!this->isReady()) {
|
while (!this->isReady()) {
|
||||||
if (this->yieldCallback) {
|
if (this->delayCallback) {
|
||||||
this->yieldCallback();
|
this->delayCallback(150);
|
||||||
} else {
|
|
||||||
::yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->process();
|
this->process();
|
||||||
@@ -51,17 +67,13 @@ public:
|
|||||||
_response = 0;
|
_response = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
do {
|
||||||
this->process();
|
if (this->delayCallback) {
|
||||||
|
this->delayCallback(150);
|
||||||
if (this->status == OpenThermStatus::READY || this->status == OpenThermStatus::DELAY) {
|
|
||||||
break;
|
|
||||||
} else if (this->yieldCallback) {
|
|
||||||
this->yieldCallback();
|
|
||||||
} else {
|
|
||||||
::yield();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
this->process();
|
||||||
|
} while (this->status != OpenThermStatus::READY && this->status != OpenThermStatus::DELAY);
|
||||||
|
|
||||||
_response = this->getLastResponse();
|
_response = this->getLastResponse();
|
||||||
_responseStatus = this->getLastResponseStatus();
|
_responseStatus = this->getLastResponseStatus();
|
||||||
@@ -151,7 +163,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
YieldCallback yieldCallback;
|
DelayCallback delayCallback;
|
||||||
BeforeSendRequestCallback beforeSendRequestCallback;
|
BeforeSendRequestCallback beforeSendRequestCallback;
|
||||||
AfterSendRequestCallback afterSendRequestCallback;
|
AfterSendRequestCallback afterSendRequestCallback;
|
||||||
|
int _outPin;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ extra_configs = secrets.default.ini
|
|||||||
core_dir = .pio
|
core_dir = .pio
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
version = 1.5.0
|
version = 1.5.1
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson@^7.1.0
|
bblanchon/ArduinoJson@^7.3.0
|
||||||
;ihormelnyk/OpenTherm Library@^1.1.5
|
;ihormelnyk/OpenTherm Library@^1.1.5
|
||||||
https://github.com/ihormelnyk/opentherm_library#master
|
https://github.com/ihormelnyk/opentherm_library#master
|
||||||
;arduino-libraries/ArduinoMqttClient@^0.1.8
|
;arduino-libraries/ArduinoMqttClient@^0.1.8
|
||||||
@@ -85,13 +85,13 @@ board_build.ldscript = eagle.flash.4m1m.ld
|
|||||||
;platform_packages =
|
;platform_packages =
|
||||||
; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.5
|
; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.5
|
||||||
; framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.1/esp32-arduino-libs-idf-release_v5.1-33fbade6.zip
|
; framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.1/esp32-arduino-libs-idf-release_v5.1-33fbade6.zip
|
||||||
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10/platform-espressif32.zip
|
||||||
platform_packages =
|
platform_packages =
|
||||||
board_build.partitions = esp32_partitions.csv
|
board_build.partitions = esp32_partitions.csv
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
laxilef/ESP32Scheduler@^1.0.1
|
laxilef/ESP32Scheduler@^1.0.1
|
||||||
nimble_lib = h2zero/NimBLE-Arduino@^1.4.2
|
nimble_lib = h2zero/NimBLE-Arduino@^2.1.0
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
post:tools/esp32.py
|
post:tools/esp32.py
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public:
|
|||||||
if (sSensor.type == Sensors::Type::BLUETOOTH) {
|
if (sSensor.type == Sensors::Type::BLUETOOTH) {
|
||||||
// available state topic
|
// available state topic
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)];
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)];
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_SENSOR_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_SENSOR_CONN, true);
|
||||||
|
|
||||||
String sName = sSensor.name;
|
String sName = sSensor.name;
|
||||||
switch (vType) {
|
switch (vType) {
|
||||||
@@ -254,7 +254,7 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
// available state topic
|
// available state topic
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)];
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)];
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_SENSOR_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_SENSOR_CONN, true);
|
||||||
|
|
||||||
doc[FPSTR(HA_NAME)] = sSensor.name;
|
doc[FPSTR(HA_NAME)] = sSensor.name;
|
||||||
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}");
|
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}");
|
||||||
@@ -970,7 +970,7 @@ public:
|
|||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_OT_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true);
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating"));
|
||||||
@@ -991,7 +991,7 @@ public:
|
|||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_OT_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true);
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("dhw"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("dhw"));
|
||||||
@@ -1012,7 +1012,7 @@ public:
|
|||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_OT_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true);
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("flame"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("flame"));
|
||||||
@@ -1033,7 +1033,7 @@ public:
|
|||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_OT_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true);
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("fault"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("fault"));
|
||||||
@@ -1054,7 +1054,7 @@ public:
|
|||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str();
|
||||||
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_OT_CONN;
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true);
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC));
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ protected:
|
|||||||
emergencyFlags |= 0b00000010;
|
emergencyFlags |= 0b00000010;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.opentherm.nativeHeatingControl) {
|
if (settings.opentherm.options.nativeHeatingControl) {
|
||||||
emergencyFlags |= 0b00000100;
|
emergencyFlags |= 0b00000100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -532,13 +532,13 @@ protected:
|
|||||||
|
|
||||||
bool publishNonStaticHaEntities(bool force = false) {
|
bool publishNonStaticHaEntities(bool force = false) {
|
||||||
static byte _heatingMinTemp, _heatingMaxTemp, _dhwMinTemp, _dhwMaxTemp = 0;
|
static byte _heatingMinTemp, _heatingMaxTemp, _dhwMinTemp, _dhwMaxTemp = 0;
|
||||||
static bool _indoorTempControl, _dhwPresent = false;
|
static bool _indoorTempControl, _dhwSupport = false;
|
||||||
|
|
||||||
bool published = false;
|
bool published = false;
|
||||||
if (force || _dhwPresent != settings.opentherm.dhwPresent) {
|
if (force || _dhwSupport != settings.opentherm.options.dhwSupport) {
|
||||||
_dhwPresent = settings.opentherm.dhwPresent;
|
_dhwSupport = settings.opentherm.options.dhwSupport;
|
||||||
|
|
||||||
if (_dhwPresent) {
|
if (_dhwSupport) {
|
||||||
this->haHelper->publishInputDhwMinTemp(settings.system.unitSystem);
|
this->haHelper->publishInputDhwMinTemp(settings.system.unitSystem);
|
||||||
this->haHelper->publishInputDhwMaxTemp(settings.system.unitSystem);
|
this->haHelper->publishInputDhwMaxTemp(settings.system.unitSystem);
|
||||||
this->haHelper->publishDhwState();
|
this->haHelper->publishDhwState();
|
||||||
@@ -569,7 +569,7 @@ protected:
|
|||||||
published = true;
|
published = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dhwPresent && (force || _dhwMinTemp != settings.dhw.minTemp || _dhwMaxTemp != settings.dhw.maxTemp)) {
|
if (_dhwSupport && (force || _dhwMinTemp != settings.dhw.minTemp || _dhwMaxTemp != settings.dhw.maxTemp)) {
|
||||||
_dhwMinTemp = settings.dhw.minTemp;
|
_dhwMinTemp = settings.dhw.minTemp;
|
||||||
_dhwMaxTemp = settings.dhw.maxTemp;
|
_dhwMaxTemp = settings.dhw.maxTemp;
|
||||||
|
|
||||||
|
|||||||
@@ -98,8 +98,8 @@ protected:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this->instance->setYieldCallback([this]() {
|
this->instance->setDelayCallback([this](unsigned int time) {
|
||||||
this->delay(25);
|
this->delay(time);
|
||||||
});
|
});
|
||||||
|
|
||||||
this->instance->begin();
|
this->instance->begin();
|
||||||
@@ -153,18 +153,18 @@ protected:
|
|||||||
&& !vars.master.heating.blocking;
|
&& !vars.master.heating.blocking;
|
||||||
|
|
||||||
// DHW settings
|
// DHW settings
|
||||||
vars.master.dhw.enabled = settings.opentherm.dhwPresent && settings.dhw.enabled;
|
vars.master.dhw.enabled = settings.opentherm.options.dhwSupport && settings.dhw.enabled;
|
||||||
vars.master.dhw.targetTemp = settings.dhw.target;
|
vars.master.dhw.targetTemp = settings.dhw.target;
|
||||||
|
|
||||||
// CH2 settings
|
// CH2 settings
|
||||||
vars.master.ch2.enabled = settings.opentherm.heatingCh2Enabled
|
vars.master.ch2.enabled = settings.opentherm.options.ch2AlwaysEnabled
|
||||||
|| (settings.opentherm.heatingCh1ToCh2 && vars.master.heating.enabled)
|
|| (settings.opentherm.options.heatingToCh2 && vars.master.heating.enabled)
|
||||||
|| (settings.opentherm.dhwToCh2 && settings.opentherm.dhwPresent && settings.dhw.enabled);
|
|| (settings.opentherm.options.dhwToCh2 && settings.opentherm.options.dhwSupport && settings.dhw.enabled);
|
||||||
|
|
||||||
if (settings.opentherm.heatingCh1ToCh2) {
|
if (settings.opentherm.options.heatingToCh2) {
|
||||||
vars.master.ch2.targetTemp = vars.master.heating.setpointTemp;
|
vars.master.ch2.targetTemp = vars.master.heating.setpointTemp;
|
||||||
|
|
||||||
} else if (settings.opentherm.dhwToCh2) {
|
} else if (settings.opentherm.options.dhwToCh2) {
|
||||||
vars.master.ch2.targetTemp = vars.master.dhw.targetTemp;
|
vars.master.ch2.targetTemp = vars.master.dhw.targetTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,18 +174,24 @@ protected:
|
|||||||
|
|
||||||
// Immergas fix
|
// Immergas fix
|
||||||
// https://arduino.ru/forum/programmirovanie/termostat-opentherm-na-esp8266?page=15#comment-649392
|
// https://arduino.ru/forum/programmirovanie/termostat-opentherm-na-esp8266?page=15#comment-649392
|
||||||
if (settings.opentherm.immergasFix) {
|
if (settings.opentherm.options.immergasFix) {
|
||||||
statusLb = 0xCA;
|
statusLb = 0xCA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Summer/winter mode
|
||||||
|
bool summerWinterMode = settings.opentherm.options.summerWinterMode;
|
||||||
|
if (settings.opentherm.options.heatingStateToSummerWinterMode) {
|
||||||
|
summerWinterMode = vars.master.heating.enabled == summerWinterMode;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long response = this->instance->setBoilerStatus(
|
unsigned long response = this->instance->setBoilerStatus(
|
||||||
vars.master.heating.enabled,
|
vars.master.heating.enabled,
|
||||||
vars.master.dhw.enabled,
|
vars.master.dhw.enabled,
|
||||||
false,
|
settings.opentherm.options.coolingSupport,
|
||||||
settings.opentherm.nativeHeatingControl,
|
settings.opentherm.options.nativeHeatingControl,
|
||||||
vars.master.ch2.enabled,
|
vars.master.ch2.enabled,
|
||||||
settings.opentherm.summerWinterMode,
|
summerWinterMode,
|
||||||
settings.opentherm.dhwBlocking,
|
settings.opentherm.options.dhwBlocking,
|
||||||
statusLb
|
statusLb
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -197,12 +203,12 @@ protected:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vars.slave.connected && millis() - this->lastSuccessResponse < 1150) {
|
if (!vars.slave.connected && millis() - this->lastSuccessResponse < 1325) {
|
||||||
Log.sinfoln(FPSTR(L_OT), F("Connected"));
|
Log.sinfoln(FPSTR(L_OT), F("Connected"));
|
||||||
|
|
||||||
vars.slave.connected = true;
|
vars.slave.connected = true;
|
||||||
|
|
||||||
} else if (vars.slave.connected && millis() - this->lastSuccessResponse > 1150) {
|
} else if (vars.slave.connected && millis() - this->lastSuccessResponse > 1325) {
|
||||||
Log.swarningln(FPSTR(L_OT), F("Disconnected"));
|
Log.swarningln(FPSTR(L_OT), F("Disconnected"));
|
||||||
|
|
||||||
// Mark sensors as disconnected
|
// Mark sensors as disconnected
|
||||||
@@ -242,6 +248,8 @@ protected:
|
|||||||
vars.slave.diag.active = false;
|
vars.slave.diag.active = false;
|
||||||
vars.slave.diag.code = 0;
|
vars.slave.diag.code = 0;
|
||||||
|
|
||||||
|
this->instance->reset();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,15 +273,16 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
vars.slave.heating.active = CustomOpenTherm::isCentralHeatingActive(response);
|
vars.slave.heating.active = CustomOpenTherm::isCentralHeatingActive(response);
|
||||||
vars.slave.dhw.active = settings.opentherm.dhwPresent ? CustomOpenTherm::isHotWaterActive(response) : false;
|
vars.slave.dhw.active = settings.opentherm.options.dhwSupport ? CustomOpenTherm::isHotWaterActive(response) : false;
|
||||||
vars.slave.flame = CustomOpenTherm::isFlameOn(response);
|
vars.slave.flame = CustomOpenTherm::isFlameOn(response);
|
||||||
|
vars.slave.cooling = CustomOpenTherm::isCoolingActive(response);
|
||||||
vars.slave.fault.active = CustomOpenTherm::isFault(response);
|
vars.slave.fault.active = CustomOpenTherm::isFault(response);
|
||||||
vars.slave.diag.active = CustomOpenTherm::isDiagnostic(response);
|
vars.slave.diag.active = CustomOpenTherm::isDiagnostic(response);
|
||||||
|
|
||||||
Log.snoticeln(
|
Log.snoticeln(
|
||||||
FPSTR(L_OT), F("Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; fault: %hhu; diag: %hhu"),
|
FPSTR(L_OT), F("Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; cooling: %hhu; fault: %hhu; diag: %hhu"),
|
||||||
vars.slave.heating.active, vars.slave.dhw.active,
|
vars.slave.heating.active, vars.slave.dhw.active,
|
||||||
vars.slave.flame, vars.slave.fault.active, vars.slave.diag.active
|
vars.slave.flame, vars.slave.cooling, vars.slave.fault.active, vars.slave.diag.active
|
||||||
);
|
);
|
||||||
|
|
||||||
// These parameters will be updated every minute
|
// These parameters will be updated every minute
|
||||||
@@ -309,7 +318,7 @@ protected:
|
|||||||
Log.swarningln(FPSTR(L_OT), F("Failed receive min modulation and max power"));
|
Log.swarningln(FPSTR(L_OT), F("Failed receive min modulation and max power"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vars.master.heating.enabled && settings.opentherm.modulationSyncWithHeating) {
|
if (!vars.master.heating.enabled && settings.opentherm.options.modulationSyncWithHeating) {
|
||||||
if (this->setMaxModulationLevel(0)) {
|
if (this->setMaxModulationLevel(0)) {
|
||||||
Log.snoticeln(FPSTR(L_OT), F("Set max modulation: 0% (response: %hhu%%)"), vars.slave.modulation.max);
|
Log.snoticeln(FPSTR(L_OT), F("Set max modulation: 0% (response: %hhu%%)"), vars.slave.modulation.max);
|
||||||
|
|
||||||
@@ -334,7 +343,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
// Get DHW min/max temp (if necessary)
|
// Get DHW min/max temp (if necessary)
|
||||||
if (settings.opentherm.dhwPresent && settings.opentherm.getMinMaxTemp) {
|
if (settings.opentherm.options.dhwSupport && settings.opentherm.options.getMinMaxTemp) {
|
||||||
if (this->updateMinMaxDhwTemp()) {
|
if (this->updateMinMaxDhwTemp()) {
|
||||||
uint8_t convertedMinTemp = convertTemp(
|
uint8_t convertedMinTemp = convertTemp(
|
||||||
vars.slave.dhw.minTemp,
|
vars.slave.dhw.minTemp,
|
||||||
@@ -380,7 +389,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
// Get heating min/max temp
|
// Get heating min/max temp
|
||||||
if (settings.opentherm.getMinMaxTemp) {
|
if (settings.opentherm.options.getMinMaxTemp) {
|
||||||
if (this->updateMinMaxHeatingTemp()) {
|
if (this->updateMinMaxHeatingTemp()) {
|
||||||
uint8_t convertedMinTemp = convertTemp(
|
uint8_t convertedMinTemp = convertTemp(
|
||||||
vars.slave.heating.minTemp,
|
vars.slave.heating.minTemp,
|
||||||
@@ -520,7 +529,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update DHW temp
|
// Update DHW temp
|
||||||
if (settings.opentherm.dhwPresent && Sensors::getAmountByType(Sensors::Type::OT_DHW_TEMP, true)) {
|
if (settings.opentherm.options.dhwSupport && Sensors::getAmountByType(Sensors::Type::OT_DHW_TEMP, true)) {
|
||||||
bool result = this->updateDhwTemp();
|
bool result = this->updateDhwTemp();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -546,7 +555,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update DHW temp 2
|
// Update DHW temp 2
|
||||||
if (settings.opentherm.dhwPresent && Sensors::getAmountByType(Sensors::Type::OT_DHW_TEMP2, true)) {
|
if (settings.opentherm.options.dhwSupport && Sensors::getAmountByType(Sensors::Type::OT_DHW_TEMP2, true)) {
|
||||||
if (this->updateDhwTemp2()) {
|
if (this->updateDhwTemp2()) {
|
||||||
float convertedDhwTemp2 = convertTemp(
|
float convertedDhwTemp2 = convertTemp(
|
||||||
vars.slave.dhw.currentTemp2,
|
vars.slave.dhw.currentTemp2,
|
||||||
@@ -570,7 +579,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update DHW flow rate
|
// Update DHW flow rate
|
||||||
if (settings.opentherm.dhwPresent && Sensors::getAmountByType(Sensors::Type::OT_DHW_FLOW_RATE, true)) {
|
if (settings.opentherm.options.dhwSupport && Sensors::getAmountByType(Sensors::Type::OT_DHW_FLOW_RATE, true)) {
|
||||||
if (this->updateDhwFlowRate()) {
|
if (this->updateDhwFlowRate()) {
|
||||||
float convertedDhwFlowRate = convertVolume(
|
float convertedDhwFlowRate = convertVolume(
|
||||||
vars.slave.dhw.flowRate,
|
vars.slave.dhw.flowRate,
|
||||||
@@ -643,7 +652,7 @@ protected:
|
|||||||
|
|
||||||
// Update CH2 temp
|
// Update CH2 temp
|
||||||
if (Sensors::getAmountByType(Sensors::Type::OT_CH2_TEMP, true)) {
|
if (Sensors::getAmountByType(Sensors::Type::OT_CH2_TEMP, true)) {
|
||||||
if (vars.master.ch2.enabled && !settings.opentherm.nativeHeatingControl) {
|
if (vars.master.ch2.enabled && !settings.opentherm.options.nativeHeatingControl) {
|
||||||
if (this->updateCh2Temp()) {
|
if (this->updateCh2Temp()) {
|
||||||
float convertedCh2Temp = convertTemp(
|
float convertedCh2Temp = convertTemp(
|
||||||
vars.slave.ch2.currentTemp,
|
vars.slave.ch2.currentTemp,
|
||||||
@@ -942,7 +951,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Native heating control
|
// Native heating control
|
||||||
if (settings.opentherm.nativeHeatingControl) {
|
if (settings.opentherm.options.nativeHeatingControl) {
|
||||||
// Converted current indoor temp
|
// Converted current indoor temp
|
||||||
float convertedTemp = convertTemp(vars.master.heating.indoorTemp, settings.system.unitSystem, settings.opentherm.unitSystem);
|
float convertedTemp = convertTemp(vars.master.heating.indoorTemp, settings.system.unitSystem, settings.opentherm.unitSystem);
|
||||||
|
|
||||||
@@ -958,7 +967,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set current CH2 indoor temp
|
// Set current CH2 indoor temp
|
||||||
if (settings.opentherm.heatingCh1ToCh2) {
|
if (settings.opentherm.options.heatingToCh2) {
|
||||||
if (this->setRoomTempCh2(convertedTemp)) {
|
if (this->setRoomTempCh2(convertedTemp)) {
|
||||||
Log.sinfoln(
|
Log.sinfoln(
|
||||||
FPSTR(L_OT_HEATING), F("Set current CH2 indoor temp: %.2f (converted: %.2f, response: %.2f)"),
|
FPSTR(L_OT_HEATING), F("Set current CH2 indoor temp: %.2f (converted: %.2f, response: %.2f)"),
|
||||||
@@ -990,7 +999,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set target CH2 temp
|
// Set target CH2 temp
|
||||||
if (settings.opentherm.heatingCh1ToCh2 && this->needSetCh2Temp(convertedTemp)) {
|
if (settings.opentherm.options.heatingToCh2 && this->needSetCh2Temp(convertedTemp)) {
|
||||||
if (this->setRoomSetpointCh2(convertedTemp)) {
|
if (this->setRoomSetpointCh2(convertedTemp)) {
|
||||||
this->ch2SetTempTime = millis();
|
this->ch2SetTempTime = millis();
|
||||||
|
|
||||||
@@ -1006,20 +1015,22 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normal heating control
|
// Normal heating control
|
||||||
if (!settings.opentherm.nativeHeatingControl && vars.master.heating.enabled) {
|
if (!settings.opentherm.options.nativeHeatingControl && vars.master.heating.enabled) {
|
||||||
// Converted target heating temp
|
// Converted target heating temp
|
||||||
float convertedTemp = convertTemp(vars.master.heating.setpointTemp, settings.system.unitSystem, settings.opentherm.unitSystem);
|
float convertedTemp = convertTemp(vars.master.heating.setpointTemp, settings.system.unitSystem, settings.opentherm.unitSystem);
|
||||||
|
|
||||||
if (this->needSetHeatingTemp(convertedTemp)) {
|
if (this->needSetHeatingTemp(convertedTemp)) {
|
||||||
// Set max heating temp
|
// Set max heating temp
|
||||||
if (this->setMaxHeatingTemp(convertedTemp)) {
|
if (settings.opentherm.options.maxTempSyncWithTargetTemp) {
|
||||||
Log.sinfoln(
|
if (this->setMaxHeatingTemp(convertedTemp)) {
|
||||||
FPSTR(L_OT_HEATING), F("Set max heating temp: %.2f (converted: %.2f)"),
|
Log.sinfoln(
|
||||||
vars.master.heating.setpointTemp, convertedTemp
|
FPSTR(L_OT_HEATING), F("Set max heating temp: %.2f (converted: %.2f)"),
|
||||||
);
|
vars.master.heating.setpointTemp, convertedTemp
|
||||||
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set max heating temp"));
|
Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set max heating temp"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set target heating temp
|
// Set target heating temp
|
||||||
@@ -1038,8 +1049,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set CH2 temp
|
// Set CH2 temp
|
||||||
if (!settings.opentherm.nativeHeatingControl && vars.master.ch2.enabled) {
|
if (!settings.opentherm.options.nativeHeatingControl && vars.master.ch2.enabled) {
|
||||||
if (settings.opentherm.heatingCh1ToCh2 || settings.opentherm.dhwToCh2) {
|
if (settings.opentherm.options.heatingToCh2 || settings.opentherm.options.dhwToCh2) {
|
||||||
// Converted target CH2 temp
|
// Converted target CH2 temp
|
||||||
float convertedTemp = convertTemp(
|
float convertedTemp = convertTemp(
|
||||||
vars.master.ch2.targetTemp,
|
vars.master.ch2.targetTemp,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ protected:
|
|||||||
this->indoorSensorsConnected = Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::INDOOR_TEMP);
|
this->indoorSensorsConnected = Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::INDOOR_TEMP);
|
||||||
//this->outdoorSensorsConnected = Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::OUTDOOR_TEMP);
|
//this->outdoorSensorsConnected = Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::OUTDOOR_TEMP);
|
||||||
|
|
||||||
if (settings.equitherm.enabled || settings.pid.enabled || settings.opentherm.nativeHeatingControl) {
|
if (settings.equitherm.enabled || settings.pid.enabled || settings.opentherm.options.nativeHeatingControl) {
|
||||||
vars.master.heating.indoorTempControl = true;
|
vars.master.heating.indoorTempControl = true;
|
||||||
vars.master.heating.minTemp = THERMOSTAT_INDOOR_MIN_TEMP;
|
vars.master.heating.minTemp = THERMOSTAT_INDOOR_MIN_TEMP;
|
||||||
vars.master.heating.maxTemp = THERMOSTAT_INDOOR_MAX_TEMP;
|
vars.master.heating.maxTemp = THERMOSTAT_INDOOR_MAX_TEMP;
|
||||||
@@ -93,7 +93,7 @@ protected:
|
|||||||
void hysteresis() {
|
void hysteresis() {
|
||||||
bool useHyst = false;
|
bool useHyst = false;
|
||||||
if (settings.heating.hysteresis > 0.01f && this->indoorSensorsConnected) {
|
if (settings.heating.hysteresis > 0.01f && this->indoorSensorsConnected) {
|
||||||
useHyst = settings.equitherm.enabled || settings.pid.enabled || settings.opentherm.nativeHeatingControl;
|
useHyst = settings.equitherm.enabled || settings.pid.enabled || settings.opentherm.options.nativeHeatingControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useHyst) {
|
if (useHyst) {
|
||||||
@@ -110,13 +110,13 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline float getHeatingMinSetpointTemp() {
|
inline float getHeatingMinSetpointTemp() {
|
||||||
return settings.opentherm.nativeHeatingControl
|
return settings.opentherm.options.nativeHeatingControl
|
||||||
? vars.master.heating.minTemp
|
? vars.master.heating.minTemp
|
||||||
: settings.heating.minTemp;
|
: settings.heating.minTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float getHeatingMaxSetpointTemp() {
|
inline float getHeatingMaxSetpointTemp() {
|
||||||
return settings.opentherm.nativeHeatingControl
|
return settings.opentherm.options.nativeHeatingControl
|
||||||
? vars.master.heating.maxTemp
|
? vars.master.heating.maxTemp
|
||||||
: settings.heating.maxTemp;
|
: settings.heating.maxTemp;
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ protected:
|
|||||||
if (vars.emergency.state) {
|
if (vars.emergency.state) {
|
||||||
return settings.emergency.target;
|
return settings.emergency.target;
|
||||||
|
|
||||||
} else if (settings.opentherm.nativeHeatingControl) {
|
} else if (settings.opentherm.options.nativeHeatingControl) {
|
||||||
return settings.heating.target;
|
return settings.heating.target;
|
||||||
|
|
||||||
} else if (!settings.equitherm.enabled && !settings.pid.enabled) {
|
} else if (!settings.equitherm.enabled && !settings.pid.enabled) {
|
||||||
|
|||||||
@@ -175,16 +175,19 @@ protected:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (millis() - this->dallasSearchTime[gpio] > this->dallasSearchInterval) {
|
if (millis() - this->dallasSearchTime[gpio] < this->dallasSearchInterval) {
|
||||||
this->dallasSearchTime[gpio] = millis();
|
continue;
|
||||||
instance.begin();
|
|
||||||
|
|
||||||
Log.straceln(
|
|
||||||
FPSTR(L_SENSORS_DALLAS),
|
|
||||||
F("GPIO %hhu, devices on bus: %hhu, DS18* devices: %hhu"),
|
|
||||||
gpio, instance.getDeviceCount(), instance.getDS18Count()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->dallasSearchTime[gpio] = millis();
|
||||||
|
this->owInstances[gpio].reset();
|
||||||
|
instance.begin();
|
||||||
|
|
||||||
|
Log.straceln(
|
||||||
|
FPSTR(L_SENSORS_DALLAS),
|
||||||
|
F("GPIO %hhu, devices on bus: %hhu, DS18* devices: %hhu"),
|
||||||
|
gpio, instance.getDeviceCount(), instance.getDS18Count()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,25 +277,14 @@ protected:
|
|||||||
unsigned long ts = millis();
|
unsigned long ts = millis();
|
||||||
|
|
||||||
if (this->dallasPolling[gpio]) {
|
if (this->dallasPolling[gpio]) {
|
||||||
auto minPollingTime = instance.millisToWaitForConversion(12);
|
auto minPollingTime = instance.millisToWaitForConversion(12) * 2;
|
||||||
unsigned long estimatePollingTime = ts - this->dallasLastPollingTime[gpio];
|
unsigned long estimatePollingTime = ts - this->dallasLastPollingTime[gpio];
|
||||||
|
|
||||||
// check conversion time
|
// check conversion time
|
||||||
|
// isConversionComplete does not work with chinese clones!
|
||||||
if (estimatePollingTime < minPollingTime) {
|
if (estimatePollingTime < minPollingTime) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check conversion
|
|
||||||
bool conversionComplete = instance.isConversionComplete();
|
|
||||||
if (!conversionComplete) {
|
|
||||||
if (estimatePollingTime > (minPollingTime * 2)) {
|
|
||||||
this->dallasPolling[gpio] = false;
|
|
||||||
|
|
||||||
Log.swarningln(FPSTR(L_SENSORS_DALLAS), F("GPIO %hhu, timeout receiving data"), gpio);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read sensors data for current instance
|
// read sensors data for current instance
|
||||||
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) {
|
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) {
|
||||||
@@ -345,28 +337,6 @@ protected:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check sensors on bus
|
|
||||||
if (!instance.getDeviceCount()) {
|
|
||||||
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) {
|
|
||||||
auto& sSensor = Sensors::settings[sensorId];
|
|
||||||
|
|
||||||
// only target & valid sensors
|
|
||||||
if (!sSensor.enabled || sSensor.type != Sensors::Type::DALLAS_TEMP || sSensor.purpose == Sensors::Purpose::NOT_CONFIGURED) {
|
|
||||||
continue;
|
|
||||||
|
|
||||||
} else if (sSensor.gpio != gpio || isEmptyAddress(sSensor.address)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& rSensor = Sensors::results[sensorId];
|
|
||||||
if (rSensor.signalQuality > 0) {
|
|
||||||
rSensor.signalQuality--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// start polling
|
// start polling
|
||||||
instance.setResolution(12);
|
instance.setResolution(12);
|
||||||
instance.requestTemperatures();
|
instance.requestTemperatures();
|
||||||
@@ -380,10 +350,10 @@ protected:
|
|||||||
|
|
||||||
void pollingBleSensors() {
|
void pollingBleSensors() {
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
if (!NimBLEDevice::getInitialized() && millis() > 5000) {
|
if (!NimBLEDevice::isInitialized() && millis() > 5000) {
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Initialized"));
|
Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Initialized"));
|
||||||
BLEDevice::init("");
|
BLEDevice::init("");
|
||||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
NimBLEDevice::setPower(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) {
|
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) {
|
||||||
@@ -445,7 +415,7 @@ protected:
|
|||||||
|
|
||||||
bool connectToBleDevice(const uint8_t sensorId) {
|
bool connectToBleDevice(const uint8_t sensorId) {
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
if (!NimBLEDevice::getInitialized()) {
|
if (!NimBLEDevice::isInitialized()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,7 +430,7 @@ protected:
|
|||||||
sSensor.address[0], sSensor.address[1], sSensor.address[2],
|
sSensor.address[0], sSensor.address[1], sSensor.address[2],
|
||||||
sSensor.address[3], sSensor.address[4], sSensor.address[5]
|
sSensor.address[3], sSensor.address[4], sSensor.address[5]
|
||||||
};
|
};
|
||||||
const NimBLEAddress address = NimBLEAddress(addr);
|
const auto address = NimBLEAddress(addr, 0);
|
||||||
|
|
||||||
NimBLEClient* pClient = nullptr;
|
NimBLEClient* pClient = nullptr;
|
||||||
pClient = NimBLEDevice::getClientByPeerAddress(address);
|
pClient = NimBLEDevice::getClientByPeerAddress(address);
|
||||||
@@ -470,12 +440,13 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pClient == nullptr) {
|
if (pClient == nullptr) {
|
||||||
if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) {
|
if (NimBLEDevice::getCreatedClientCount() >= NIMBLE_MAX_CONNECTIONS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pClient = NimBLEDevice::createClient();
|
pClient = NimBLEDevice::createClient();
|
||||||
pClient->setConnectTimeout(5);
|
pClient->setConnectTimeout(5000);
|
||||||
|
pClient->setSelfDelete(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pClient->isConnected()) {
|
if(pClient->isConnected()) {
|
||||||
@@ -492,7 +463,6 @@ protected:
|
|||||||
sensorId, sSensor.name, address.toString().c_str()
|
sensorId, sSensor.name, address.toString().c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
NimBLEDevice::deleteClient(pClient);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +506,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -609,7 +579,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -694,7 +664,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -793,7 +763,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,16 +57,21 @@ struct Settings {
|
|||||||
float minPower = 0.0f;
|
float minPower = 0.0f;
|
||||||
float maxPower = 0.0f;
|
float maxPower = 0.0f;
|
||||||
|
|
||||||
bool dhwPresent = true;
|
struct {
|
||||||
bool summerWinterMode = false;
|
bool dhwSupport = true;
|
||||||
bool heatingCh2Enabled = true;
|
bool coolingSupport = false;
|
||||||
bool heatingCh1ToCh2 = false;
|
bool summerWinterMode = false;
|
||||||
bool dhwToCh2 = false;
|
bool heatingStateToSummerWinterMode = false;
|
||||||
bool dhwBlocking = false;
|
bool ch2AlwaysEnabled = true;
|
||||||
bool modulationSyncWithHeating = false;
|
bool heatingToCh2 = false;
|
||||||
bool getMinMaxTemp = true;
|
bool dhwToCh2 = false;
|
||||||
bool nativeHeatingControl = false;
|
bool dhwBlocking = false;
|
||||||
bool immergasFix = false;
|
bool modulationSyncWithHeating = false;
|
||||||
|
bool maxTempSyncWithTargetTemp = true;
|
||||||
|
bool getMinMaxTemp = true;
|
||||||
|
bool nativeHeatingControl = false;
|
||||||
|
bool immergasFix = false;
|
||||||
|
} options;
|
||||||
} opentherm;
|
} opentherm;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -287,6 +292,7 @@ struct Variables {
|
|||||||
|
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
bool flame = false;
|
bool flame = false;
|
||||||
|
bool cooling = false;
|
||||||
float pressure = 0.0f;
|
float pressure = 0.0f;
|
||||||
float heatExchangerTemp = 0.0f;
|
float heatExchangerTemp = 0.0f;
|
||||||
|
|
||||||
|
|||||||
379
src/strings.h
@@ -3,192 +3,197 @@
|
|||||||
#define PROGMEM
|
#define PROGMEM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char L_SETTINGS[] PROGMEM = "SETTINGS";
|
const char L_SETTINGS[] PROGMEM = "SETTINGS";
|
||||||
const char L_SETTINGS_OT[] PROGMEM = "SETTINGS.OT";
|
const char L_SETTINGS_OT[] PROGMEM = "SETTINGS.OT";
|
||||||
const char L_SETTINGS_DHW[] PROGMEM = "SETTINGS.DHW";
|
const char L_SETTINGS_DHW[] PROGMEM = "SETTINGS.DHW";
|
||||||
const char L_SETTINGS_HEATING[] PROGMEM = "SETTINGS.HEATING";
|
const char L_SETTINGS_HEATING[] PROGMEM = "SETTINGS.HEATING";
|
||||||
const char L_NETWORK[] PROGMEM = "NETWORK";
|
const char L_NETWORK[] PROGMEM = "NETWORK";
|
||||||
const char L_NETWORK_SETTINGS[] PROGMEM = "NETWORK.SETTINGS";
|
const char L_NETWORK_SETTINGS[] PROGMEM = "NETWORK.SETTINGS";
|
||||||
const char L_PORTAL_WEBSERVER[] PROGMEM = "PORTAL.WEBSERVER";
|
const char L_PORTAL_WEBSERVER[] PROGMEM = "PORTAL.WEBSERVER";
|
||||||
const char L_PORTAL_DNSSERVER[] PROGMEM = "PORTAL.DNSSERVER";
|
const char L_PORTAL_DNSSERVER[] PROGMEM = "PORTAL.DNSSERVER";
|
||||||
const char L_PORTAL_CAPTIVE[] PROGMEM = "PORTAL.CAPTIVE";
|
const char L_PORTAL_CAPTIVE[] PROGMEM = "PORTAL.CAPTIVE";
|
||||||
const char L_PORTAL_OTA[] PROGMEM = "PORTAL.OTA";
|
const char L_PORTAL_OTA[] PROGMEM = "PORTAL.OTA";
|
||||||
const char L_MAIN[] PROGMEM = "MAIN";
|
const char L_MAIN[] PROGMEM = "MAIN";
|
||||||
const char L_MQTT[] PROGMEM = "MQTT";
|
const char L_MQTT[] PROGMEM = "MQTT";
|
||||||
const char L_MQTT_HA[] PROGMEM = "MQTT.HA";
|
const char L_MQTT_HA[] PROGMEM = "MQTT.HA";
|
||||||
const char L_MQTT_MSG[] PROGMEM = "MQTT.MSG";
|
const char L_MQTT_MSG[] PROGMEM = "MQTT.MSG";
|
||||||
const char L_OT[] PROGMEM = "OT";
|
const char L_OT[] PROGMEM = "OT";
|
||||||
const char L_OT_DHW[] PROGMEM = "OT.DHW";
|
const char L_OT_DHW[] PROGMEM = "OT.DHW";
|
||||||
const char L_OT_HEATING[] PROGMEM = "OT.HEATING";
|
const char L_OT_HEATING[] PROGMEM = "OT.HEATING";
|
||||||
const char L_OT_CH2[] PROGMEM = "OT.CH2";
|
const char L_OT_CH2[] PROGMEM = "OT.CH2";
|
||||||
const char L_SENSORS[] PROGMEM = "SENSORS";
|
const char L_SENSORS[] PROGMEM = "SENSORS";
|
||||||
const char L_SENSORS_SETTINGS[] PROGMEM = "SENSORS.SETTINGS";
|
const char L_SENSORS_SETTINGS[] PROGMEM = "SENSORS.SETTINGS";
|
||||||
const char L_SENSORS_DALLAS[] PROGMEM = "SENSORS.DALLAS";
|
const char L_SENSORS_DALLAS[] PROGMEM = "SENSORS.DALLAS";
|
||||||
const char L_SENSORS_NTC[] PROGMEM = "SENSORS.NTC";
|
const char L_SENSORS_NTC[] PROGMEM = "SENSORS.NTC";
|
||||||
const char L_SENSORS_BLE[] PROGMEM = "SENSORS.BLE";
|
const char L_SENSORS_BLE[] PROGMEM = "SENSORS.BLE";
|
||||||
const char L_REGULATOR[] PROGMEM = "REGULATOR";
|
const char L_REGULATOR[] PROGMEM = "REGULATOR";
|
||||||
const char L_REGULATOR_PID[] PROGMEM = "REGULATOR.PID";
|
const char L_REGULATOR_PID[] PROGMEM = "REGULATOR.PID";
|
||||||
const char L_REGULATOR_EQUITHERM[] PROGMEM = "REGULATOR.EQUITHERM";
|
const char L_REGULATOR_EQUITHERM[] PROGMEM = "REGULATOR.EQUITHERM";
|
||||||
const char L_CASCADE_INPUT[] PROGMEM = "CASCADE.INPUT";
|
const char L_CASCADE_INPUT[] PROGMEM = "CASCADE.INPUT";
|
||||||
const char L_CASCADE_OUTPUT[] PROGMEM = "CASCADE.OUTPUT";
|
const char L_CASCADE_OUTPUT[] PROGMEM = "CASCADE.OUTPUT";
|
||||||
const char L_EXTPUMP[] PROGMEM = "EXTPUMP";
|
const char L_EXTPUMP[] PROGMEM = "EXTPUMP";
|
||||||
|
|
||||||
|
|
||||||
const char S_ACTIONS[] PROGMEM = "actions";
|
const char S_ACTIONS[] PROGMEM = "actions";
|
||||||
const char S_ACTIVE[] PROGMEM = "active";
|
const char S_ACTIVE[] PROGMEM = "active";
|
||||||
const char S_ADDRESS[] PROGMEM = "address";
|
const char S_ADDRESS[] PROGMEM = "address";
|
||||||
const char S_ANTI_STUCK_INTERVAL[] PROGMEM = "antiStuckInterval";
|
const char S_ANTI_STUCK_INTERVAL[] PROGMEM = "antiStuckInterval";
|
||||||
const char S_ANTI_STUCK_TIME[] PROGMEM = "antiStuckTime";
|
const char S_ANTI_STUCK_TIME[] PROGMEM = "antiStuckTime";
|
||||||
const char S_AP[] PROGMEM = "ap";
|
const char S_AP[] PROGMEM = "ap";
|
||||||
const char S_APP_VERSION[] PROGMEM = "appVersion";
|
const char S_APP_VERSION[] PROGMEM = "appVersion";
|
||||||
const char S_AUTH[] PROGMEM = "auth";
|
const char S_AUTH[] PROGMEM = "auth";
|
||||||
const char S_BACKTRACE[] PROGMEM = "backtrace";
|
const char S_BACKTRACE[] PROGMEM = "backtrace";
|
||||||
const char S_BATTERY[] PROGMEM = "battery";
|
const char S_BATTERY[] PROGMEM = "battery";
|
||||||
const char S_BAUDRATE[] PROGMEM = "baudrate";
|
const char S_BAUDRATE[] PROGMEM = "baudrate";
|
||||||
const char S_BLOCKING[] PROGMEM = "blocking";
|
const char S_BLOCKING[] PROGMEM = "blocking";
|
||||||
const char S_BSSID[] PROGMEM = "bssid";
|
const char S_BSSID[] PROGMEM = "bssid";
|
||||||
const char S_BUILD[] PROGMEM = "build";
|
const char S_BUILD[] PROGMEM = "build";
|
||||||
const char S_CASCADE_CONTROL[] PROGMEM = "cascadeControl";
|
const char S_CASCADE_CONTROL[] PROGMEM = "cascadeControl";
|
||||||
const char S_CHANNEL[] PROGMEM = "channel";
|
const char S_CHANNEL[] PROGMEM = "channel";
|
||||||
const char S_CHIP[] PROGMEM = "chip";
|
const char S_CH2_ALWAYS_ENABLED[] PROGMEM = "ch2AlwaysEnabled";
|
||||||
const char S_CODE[] PROGMEM = "code";
|
const char S_CHIP[] PROGMEM = "chip";
|
||||||
const char S_CONNECTED[] PROGMEM = "connected";
|
const char S_CODE[] PROGMEM = "code";
|
||||||
const char S_CONTINUES[] PROGMEM = "continues";
|
const char S_CONNECTED[] PROGMEM = "connected";
|
||||||
const char S_CORE[] PROGMEM = "core";
|
const char S_CONTINUES[] PROGMEM = "continues";
|
||||||
const char S_CORES[] PROGMEM = "cores";
|
const char S_COOLING[] PROGMEM = "cooling";
|
||||||
const char S_CRASH[] PROGMEM = "crash";
|
const char S_COOLING_SUPPORT[] PROGMEM = "coolingSupport";
|
||||||
const char S_CURRENT_TEMP[] PROGMEM = "currentTemp";
|
const char S_CORE[] PROGMEM = "core";
|
||||||
const char S_DATA[] PROGMEM = "data";
|
const char S_CORES[] PROGMEM = "cores";
|
||||||
const char S_DATE[] PROGMEM = "date";
|
const char S_CRASH[] PROGMEM = "crash";
|
||||||
const char S_DHW[] PROGMEM = "dhw";
|
const char S_CURRENT_TEMP[] PROGMEM = "currentTemp";
|
||||||
const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking";
|
const char S_DATA[] PROGMEM = "data";
|
||||||
const char S_DHW_PRESENT[] PROGMEM = "dhwPresent";
|
const char S_DATE[] PROGMEM = "date";
|
||||||
const char S_DHW_TO_CH2[] PROGMEM = "dhwToCh2";
|
const char S_DHW[] PROGMEM = "dhw";
|
||||||
const char S_DIAG[] PROGMEM = "diag";
|
const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking";
|
||||||
const char S_DNS[] PROGMEM = "dns";
|
const char S_DHW_SUPPORT[] PROGMEM = "dhwSupport";
|
||||||
const char S_DT[] PROGMEM = "dt";
|
const char S_DHW_TO_CH2[] PROGMEM = "dhwToCh2";
|
||||||
const char S_D_FACTOR[] PROGMEM = "d_factor";
|
const char S_DIAG[] PROGMEM = "diag";
|
||||||
const char S_EMERGENCY[] PROGMEM = "emergency";
|
const char S_DNS[] PROGMEM = "dns";
|
||||||
const char S_ENABLED[] PROGMEM = "enabled";
|
const char S_DT[] PROGMEM = "dt";
|
||||||
const char S_ENV[] PROGMEM = "env";
|
const char S_D_FACTOR[] PROGMEM = "d_factor";
|
||||||
const char S_EPC[] PROGMEM = "epc";
|
const char S_EMERGENCY[] PROGMEM = "emergency";
|
||||||
const char S_EQUITHERM[] PROGMEM = "equitherm";
|
const char S_ENABLED[] PROGMEM = "enabled";
|
||||||
const char S_EXTERNAL_PUMP[] PROGMEM = "externalPump";
|
const char S_ENV[] PROGMEM = "env";
|
||||||
const char S_FACTOR[] PROGMEM = "factor";
|
const char S_EPC[] PROGMEM = "epc";
|
||||||
const char S_FAULT[] PROGMEM = "fault";
|
const char S_EQUITHERM[] PROGMEM = "equitherm";
|
||||||
const char S_FILTERING[] PROGMEM = "filtering";
|
const char S_EXTERNAL_PUMP[] PROGMEM = "externalPump";
|
||||||
const char S_FILTERING_FACTOR[] PROGMEM = "filteringFactor";
|
const char S_FACTOR[] PROGMEM = "factor";
|
||||||
const char S_FLAGS[] PROGMEM = "flags";
|
const char S_FAULT[] PROGMEM = "fault";
|
||||||
const char S_FLAME[] PROGMEM = "flame";
|
const char S_FILTERING[] PROGMEM = "filtering";
|
||||||
const char S_FLASH[] PROGMEM = "flash";
|
const char S_FILTERING_FACTOR[] PROGMEM = "filteringFactor";
|
||||||
const char S_FREE[] PROGMEM = "free";
|
const char S_FLAGS[] PROGMEM = "flags";
|
||||||
const char S_FREQ[] PROGMEM = "freq";
|
const char S_FLAME[] PROGMEM = "flame";
|
||||||
const char S_GATEWAY[] PROGMEM = "gateway";
|
const char S_FLASH[] PROGMEM = "flash";
|
||||||
const char S_GET_MIN_MAX_TEMP[] PROGMEM = "getMinMaxTemp";
|
const char S_FREE[] PROGMEM = "free";
|
||||||
const char S_GPIO[] PROGMEM = "gpio";
|
const char S_FREQ[] PROGMEM = "freq";
|
||||||
const char S_HEAP[] PROGMEM = "heap";
|
const char S_GATEWAY[] PROGMEM = "gateway";
|
||||||
const char S_HEATING[] PROGMEM = "heating";
|
const char S_GET_MIN_MAX_TEMP[] PROGMEM = "getMinMaxTemp";
|
||||||
const char S_HEATING_CH1_TO_CH2[] PROGMEM = "heatingCh1ToCh2";
|
const char S_GPIO[] PROGMEM = "gpio";
|
||||||
const char S_HEATING_CH2_ENABLED[] PROGMEM = "heatingCh2Enabled";
|
const char S_HEAP[] PROGMEM = "heap";
|
||||||
const char S_HIDDEN[] PROGMEM = "hidden";
|
const char S_HEATING[] PROGMEM = "heating";
|
||||||
const char S_HOME_ASSISTANT_DISCOVERY[] PROGMEM = "homeAssistantDiscovery";
|
const char S_HEATING_TO_CH2[] PROGMEM = "heatingToCh2";
|
||||||
const char S_HOSTNAME[] PROGMEM = "hostname";
|
const char S_HEATING_STATE_TO_SUMMER_WINTER_MODE[] PROGMEM = "heatingStateToSummerWinterMode";
|
||||||
const char S_HUMIDITY[] PROGMEM = "humidity";
|
const char S_HIDDEN[] PROGMEM = "hidden";
|
||||||
const char S_HYSTERESIS[] PROGMEM = "hysteresis";
|
const char S_HOME_ASSISTANT_DISCOVERY[] PROGMEM = "homeAssistantDiscovery";
|
||||||
const char S_ID[] PROGMEM = "id";
|
const char S_HOSTNAME[] PROGMEM = "hostname";
|
||||||
const char S_IMMERGAS_FIX[] PROGMEM = "immergasFix";
|
const char S_HUMIDITY[] PROGMEM = "humidity";
|
||||||
const char S_INDOOR_TEMP[] PROGMEM = "indoorTemp";
|
const char S_HYSTERESIS[] PROGMEM = "hysteresis";
|
||||||
const char S_INDOOR_TEMP_CONTROL[] PROGMEM = "indoorTempControl";
|
const char S_ID[] PROGMEM = "id";
|
||||||
const char S_IN_GPIO[] PROGMEM = "inGpio";
|
const char S_IMMERGAS_FIX[] PROGMEM = "immergasFix";
|
||||||
const char S_INPUT[] PROGMEM = "input";
|
const char S_INDOOR_TEMP[] PROGMEM = "indoorTemp";
|
||||||
const char S_INTERVAL[] PROGMEM = "interval";
|
const char S_INDOOR_TEMP_CONTROL[] PROGMEM = "indoorTempControl";
|
||||||
const char S_INVERT_STATE[] PROGMEM = "invertState";
|
const char S_IN_GPIO[] PROGMEM = "inGpio";
|
||||||
const char S_IP[] PROGMEM = "ip";
|
const char S_INPUT[] PROGMEM = "input";
|
||||||
const char S_I_FACTOR[] PROGMEM = "i_factor";
|
const char S_INTERVAL[] PROGMEM = "interval";
|
||||||
const char S_K_FACTOR[] PROGMEM = "k_factor";
|
const char S_INVERT_STATE[] PROGMEM = "invertState";
|
||||||
const char S_LOGIN[] PROGMEM = "login";
|
const char S_IP[] PROGMEM = "ip";
|
||||||
const char S_LOG_LEVEL[] PROGMEM = "logLevel";
|
const char S_I_FACTOR[] PROGMEM = "i_factor";
|
||||||
const char S_MAC[] PROGMEM = "mac";
|
const char S_K_FACTOR[] PROGMEM = "k_factor";
|
||||||
const char S_MASTER[] PROGMEM = "master";
|
const char S_LOGIN[] PROGMEM = "login";
|
||||||
const char S_MAX[] PROGMEM = "max";
|
const char S_LOG_LEVEL[] PROGMEM = "logLevel";
|
||||||
const char S_MAX_FREE_BLOCK[] PROGMEM = "maxFreeBlock";
|
const char S_MAC[] PROGMEM = "mac";
|
||||||
const char S_MAX_MODULATION[] PROGMEM = "maxModulation";
|
const char S_MASTER[] PROGMEM = "master";
|
||||||
const char S_MAX_POWER[] PROGMEM = "maxPower";
|
const char S_MAX[] PROGMEM = "max";
|
||||||
const char S_MAX_TEMP[] PROGMEM = "maxTemp";
|
const char S_MAX_FREE_BLOCK[] PROGMEM = "maxFreeBlock";
|
||||||
const char S_MEMBER_ID[] PROGMEM = "memberId";
|
const char S_MAX_MODULATION[] PROGMEM = "maxModulation";
|
||||||
const char S_MIN[] PROGMEM = "min";
|
const char S_MAX_POWER[] PROGMEM = "maxPower";
|
||||||
const char S_MIN_FREE[] PROGMEM = "minFree";
|
const char S_MAX_TEMP[] PROGMEM = "maxTemp";
|
||||||
const char S_MIN_MAX_FREE_BLOCK[] PROGMEM = "minMaxFreeBlock";
|
const char S_MAX_TEMP_SYNC_WITH_TARGET_TEMP[] PROGMEM = "maxTempSyncWithTargetTemp";
|
||||||
const char S_MIN_POWER[] PROGMEM = "minPower";
|
const char S_MEMBER_ID[] PROGMEM = "memberId";
|
||||||
const char S_MIN_TEMP[] PROGMEM = "minTemp";
|
const char S_MIN[] PROGMEM = "min";
|
||||||
const char S_MODEL[] PROGMEM = "model";
|
const char S_MIN_FREE[] PROGMEM = "minFree";
|
||||||
const char S_MODULATION[] PROGMEM = "modulation";
|
const char S_MIN_MAX_FREE_BLOCK[] PROGMEM = "minMaxFreeBlock";
|
||||||
const char S_MODULATION_SYNC_WITH_HEATING[] PROGMEM = "modulationSyncWithHeating";
|
const char S_MIN_POWER[] PROGMEM = "minPower";
|
||||||
const char S_MQTT[] PROGMEM = "mqtt";
|
const char S_MIN_TEMP[] PROGMEM = "minTemp";
|
||||||
const char S_NAME[] PROGMEM = "name";
|
const char S_MODEL[] PROGMEM = "model";
|
||||||
const char S_NATIVE_HEATING_CONTROL[] PROGMEM = "nativeHeatingControl";
|
const char S_MODULATION[] PROGMEM = "modulation";
|
||||||
const char S_NETWORK[] PROGMEM = "network";
|
const char S_MODULATION_SYNC_WITH_HEATING[] PROGMEM = "modulationSyncWithHeating";
|
||||||
const char S_N_FACTOR[] PROGMEM = "n_factor";
|
const char S_MQTT[] PROGMEM = "mqtt";
|
||||||
const char S_OFFSET[] PROGMEM = "offset";
|
const char S_NAME[] PROGMEM = "name";
|
||||||
const char S_ON_ENABLED_HEATING[] PROGMEM = "onEnabledHeating";
|
const char S_NATIVE_HEATING_CONTROL[] PROGMEM = "nativeHeatingControl";
|
||||||
const char S_ON_FAULT[] PROGMEM = "onFault";
|
const char S_NETWORK[] PROGMEM = "network";
|
||||||
const char S_ON_LOSS_CONNECTION[] PROGMEM = "onLossConnection";
|
const char S_N_FACTOR[] PROGMEM = "n_factor";
|
||||||
const char S_OPENTHERM[] PROGMEM = "opentherm";
|
const char S_OFFSET[] PROGMEM = "offset";
|
||||||
const char S_OUTDOOR_TEMP[] PROGMEM = "outdoorTemp";
|
const char S_ON_ENABLED_HEATING[] PROGMEM = "onEnabledHeating";
|
||||||
const char S_OUT_GPIO[] PROGMEM = "outGpio";
|
const char S_ON_FAULT[] PROGMEM = "onFault";
|
||||||
const char S_OUTPUT[] PROGMEM = "output";
|
const char S_ON_LOSS_CONNECTION[] PROGMEM = "onLossConnection";
|
||||||
const char S_PASSWORD[] PROGMEM = "password";
|
const char S_OPENTHERM[] PROGMEM = "opentherm";
|
||||||
const char S_PID[] PROGMEM = "pid";
|
const char S_OPTIONS[] PROGMEM = "options";
|
||||||
const char S_PORT[] PROGMEM = "port";
|
const char S_OUTDOOR_TEMP[] PROGMEM = "outdoorTemp";
|
||||||
const char S_PORTAL[] PROGMEM = "portal";
|
const char S_OUT_GPIO[] PROGMEM = "outGpio";
|
||||||
const char S_POST_CIRCULATION_TIME[] PROGMEM = "postCirculationTime";
|
const char S_OUTPUT[] PROGMEM = "output";
|
||||||
const char S_POWER[] PROGMEM = "power";
|
const char S_PASSWORD[] PROGMEM = "password";
|
||||||
const char S_PREFIX[] PROGMEM = "prefix";
|
const char S_PID[] PROGMEM = "pid";
|
||||||
const char S_PROTOCOL_VERSION[] PROGMEM = "protocolVersion";
|
const char S_PORT[] PROGMEM = "port";
|
||||||
const char S_PURPOSE[] PROGMEM = "purpose";
|
const char S_PORTAL[] PROGMEM = "portal";
|
||||||
const char S_P_FACTOR[] PROGMEM = "p_factor";
|
const char S_POST_CIRCULATION_TIME[] PROGMEM = "postCirculationTime";
|
||||||
const char S_REAL_SIZE[] PROGMEM = "realSize";
|
const char S_POWER[] PROGMEM = "power";
|
||||||
const char S_REASON[] PROGMEM = "reason";
|
const char S_PREFIX[] PROGMEM = "prefix";
|
||||||
const char S_RESET_DIAGNOSTIC[] PROGMEM = "resetDiagnostic";
|
const char S_PROTOCOL_VERSION[] PROGMEM = "protocolVersion";
|
||||||
const char S_RESET_FAULT[] PROGMEM = "resetFault";
|
const char S_PURPOSE[] PROGMEM = "purpose";
|
||||||
const char S_RESET_REASON[] PROGMEM = "resetReason";
|
const char S_P_FACTOR[] PROGMEM = "p_factor";
|
||||||
const char S_RESTART[] PROGMEM = "restart";
|
const char S_REAL_SIZE[] PROGMEM = "realSize";
|
||||||
const char S_RETURN_TEMP[] PROGMEM = "returnTemp";
|
const char S_REASON[] PROGMEM = "reason";
|
||||||
const char S_REV[] PROGMEM = "rev";
|
const char S_RESET_DIAGNOSTIC[] PROGMEM = "resetDiagnostic";
|
||||||
const char S_RSSI[] PROGMEM = "rssi";
|
const char S_RESET_FAULT[] PROGMEM = "resetFault";
|
||||||
const char S_RX_LED_GPIO[] PROGMEM = "rxLedGpio";
|
const char S_RESET_REASON[] PROGMEM = "resetReason";
|
||||||
const char S_SDK[] PROGMEM = "sdk";
|
const char S_RESTART[] PROGMEM = "restart";
|
||||||
const char S_SENSORS[] PROGMEM = "sensors";
|
const char S_RETURN_TEMP[] PROGMEM = "returnTemp";
|
||||||
const char S_SERIAL[] PROGMEM = "serial";
|
const char S_REV[] PROGMEM = "rev";
|
||||||
const char S_SERVER[] PROGMEM = "server";
|
const char S_RSSI[] PROGMEM = "rssi";
|
||||||
const char S_SETTINGS[] PROGMEM = "settings";
|
const char S_RX_LED_GPIO[] PROGMEM = "rxLedGpio";
|
||||||
const char S_SIGNAL_QUALITY[] PROGMEM = "signalQuality";
|
const char S_SDK[] PROGMEM = "sdk";
|
||||||
const char S_SIZE[] PROGMEM = "size";
|
const char S_SENSORS[] PROGMEM = "sensors";
|
||||||
const char S_SLAVE[] PROGMEM = "slave";
|
const char S_SERIAL[] PROGMEM = "serial";
|
||||||
const char S_SSID[] PROGMEM = "ssid";
|
const char S_SERVER[] PROGMEM = "server";
|
||||||
const char S_STA[] PROGMEM = "sta";
|
const char S_SETTINGS[] PROGMEM = "settings";
|
||||||
const char S_STATE[] PROGMEM = "state";
|
const char S_SIGNAL_QUALITY[] PROGMEM = "signalQuality";
|
||||||
const char S_STATIC_CONFIG[] PROGMEM = "staticConfig";
|
const char S_SIZE[] PROGMEM = "size";
|
||||||
const char S_STATUS_LED_GPIO[] PROGMEM = "statusLedGpio";
|
const char S_SLAVE[] PROGMEM = "slave";
|
||||||
const char S_SETPOINT_TEMP[] PROGMEM = "setpointTemp";
|
const char S_SSID[] PROGMEM = "ssid";
|
||||||
const char S_SUBNET[] PROGMEM = "subnet";
|
const char S_STA[] PROGMEM = "sta";
|
||||||
const char S_SUMMER_WINTER_MODE[] PROGMEM = "summerWinterMode";
|
const char S_STATE[] PROGMEM = "state";
|
||||||
const char S_SYSTEM[] PROGMEM = "system";
|
const char S_STATIC_CONFIG[] PROGMEM = "staticConfig";
|
||||||
const char S_TARGET[] PROGMEM = "target";
|
const char S_STATUS_LED_GPIO[] PROGMEM = "statusLedGpio";
|
||||||
const char S_TARGET_TEMP[] PROGMEM = "targetTemp";
|
const char S_SETPOINT_TEMP[] PROGMEM = "setpointTemp";
|
||||||
const char S_TELNET[] PROGMEM = "telnet";
|
const char S_SUBNET[] PROGMEM = "subnet";
|
||||||
const char S_TEMPERATURE[] PROGMEM = "temperature";
|
const char S_SUMMER_WINTER_MODE[] PROGMEM = "summerWinterMode";
|
||||||
const char S_THRESHOLD_TIME[] PROGMEM = "thresholdTime";
|
const char S_SYSTEM[] PROGMEM = "system";
|
||||||
const char S_TOTAL[] PROGMEM = "total";
|
const char S_TARGET[] PROGMEM = "target";
|
||||||
const char S_TRESHOLD_TIME[] PROGMEM = "tresholdTime";
|
const char S_TARGET_TEMP[] PROGMEM = "targetTemp";
|
||||||
const char S_TURBO[] PROGMEM = "turbo";
|
const char S_TELNET[] PROGMEM = "telnet";
|
||||||
const char S_TURBO_FACTOR[] PROGMEM = "turboFactor";
|
const char S_TEMPERATURE[] PROGMEM = "temperature";
|
||||||
const char S_TYPE[] PROGMEM = "type";
|
const char S_THRESHOLD_TIME[] PROGMEM = "thresholdTime";
|
||||||
const char S_T_FACTOR[] PROGMEM = "t_factor";
|
const char S_TOTAL[] PROGMEM = "total";
|
||||||
const char S_UNIT_SYSTEM[] PROGMEM = "unitSystem";
|
const char S_TRESHOLD_TIME[] PROGMEM = "tresholdTime";
|
||||||
const char S_UPTIME[] PROGMEM = "uptime";
|
const char S_TURBO[] PROGMEM = "turbo";
|
||||||
const char S_USE[] PROGMEM = "use";
|
const char S_TURBO_FACTOR[] PROGMEM = "turboFactor";
|
||||||
const char S_USE_DHCP[] PROGMEM = "useDhcp";
|
const char S_TYPE[] PROGMEM = "type";
|
||||||
const char S_USER[] PROGMEM = "user";
|
const char S_T_FACTOR[] PROGMEM = "t_factor";
|
||||||
const char S_VALUE[] PROGMEM = "value";
|
const char S_UNIT_SYSTEM[] PROGMEM = "unitSystem";
|
||||||
const char S_VERSION[] PROGMEM = "version";
|
const char S_UPTIME[] PROGMEM = "uptime";
|
||||||
|
const char S_USE[] PROGMEM = "use";
|
||||||
|
const char S_USE_DHCP[] PROGMEM = "useDhcp";
|
||||||
|
const char S_USER[] PROGMEM = "user";
|
||||||
|
const char S_VALUE[] PROGMEM = "value";
|
||||||
|
const char S_VERSION[] PROGMEM = "version";
|
||||||
|
|||||||
159
src/utils.h
@@ -377,16 +377,21 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
|||||||
opentherm[FPSTR(S_MAX_MODULATION)] = src.opentherm.maxModulation;
|
opentherm[FPSTR(S_MAX_MODULATION)] = src.opentherm.maxModulation;
|
||||||
opentherm[FPSTR(S_MIN_POWER)] = roundf(src.opentherm.minPower, 2);
|
opentherm[FPSTR(S_MIN_POWER)] = roundf(src.opentherm.minPower, 2);
|
||||||
opentherm[FPSTR(S_MAX_POWER)] = roundf(src.opentherm.maxPower, 2);
|
opentherm[FPSTR(S_MAX_POWER)] = roundf(src.opentherm.maxPower, 2);
|
||||||
opentherm[FPSTR(S_DHW_PRESENT)] = src.opentherm.dhwPresent;
|
|
||||||
opentherm[FPSTR(S_SUMMER_WINTER_MODE)] = src.opentherm.summerWinterMode;
|
auto otOptions = opentherm[FPSTR(S_OPTIONS)].to<JsonObject>();
|
||||||
opentherm[FPSTR(S_HEATING_CH2_ENABLED)] = src.opentherm.heatingCh2Enabled;
|
otOptions[FPSTR(S_DHW_SUPPORT)] = src.opentherm.options.dhwSupport;
|
||||||
opentherm[FPSTR(S_HEATING_CH1_TO_CH2)] = src.opentherm.heatingCh1ToCh2;
|
otOptions[FPSTR(S_COOLING_SUPPORT)] = src.opentherm.options.coolingSupport;
|
||||||
opentherm[FPSTR(S_DHW_TO_CH2)] = src.opentherm.dhwToCh2;
|
otOptions[FPSTR(S_SUMMER_WINTER_MODE)] = src.opentherm.options.summerWinterMode;
|
||||||
opentherm[FPSTR(S_DHW_BLOCKING)] = src.opentherm.dhwBlocking;
|
otOptions[FPSTR(S_HEATING_STATE_TO_SUMMER_WINTER_MODE)] = src.opentherm.options.heatingStateToSummerWinterMode;
|
||||||
opentherm[FPSTR(S_MODULATION_SYNC_WITH_HEATING)] = src.opentherm.modulationSyncWithHeating;
|
otOptions[FPSTR(S_CH2_ALWAYS_ENABLED)] = src.opentherm.options.ch2AlwaysEnabled;
|
||||||
opentherm[FPSTR(S_GET_MIN_MAX_TEMP)] = src.opentherm.getMinMaxTemp;
|
otOptions[FPSTR(S_HEATING_TO_CH2)] = src.opentherm.options.heatingToCh2;
|
||||||
opentherm[FPSTR(S_NATIVE_HEATING_CONTROL)] = src.opentherm.nativeHeatingControl;
|
otOptions[FPSTR(S_DHW_TO_CH2)] = src.opentherm.options.dhwToCh2;
|
||||||
opentherm[FPSTR(S_IMMERGAS_FIX)] = src.opentherm.immergasFix;
|
otOptions[FPSTR(S_DHW_BLOCKING)] = src.opentherm.options.dhwBlocking;
|
||||||
|
otOptions[FPSTR(S_MODULATION_SYNC_WITH_HEATING)] = src.opentherm.options.modulationSyncWithHeating;
|
||||||
|
otOptions[FPSTR(S_MAX_TEMP_SYNC_WITH_TARGET_TEMP)] = src.opentherm.options.maxTempSyncWithTargetTemp;
|
||||||
|
otOptions[FPSTR(S_GET_MIN_MAX_TEMP)] = src.opentherm.options.getMinMaxTemp;
|
||||||
|
otOptions[FPSTR(S_NATIVE_HEATING_CONTROL)] = src.opentherm.options.nativeHeatingControl;
|
||||||
|
otOptions[FPSTR(S_IMMERGAS_FIX)] = src.opentherm.options.immergasFix;
|
||||||
|
|
||||||
auto mqtt = dst[FPSTR(S_MQTT)].to<JsonObject>();
|
auto mqtt = dst[FPSTR(S_MQTT)].to<JsonObject>();
|
||||||
mqtt[FPSTR(S_ENABLED)] = src.mqtt.enabled;
|
mqtt[FPSTR(S_ENABLED)] = src.mqtt.enabled;
|
||||||
@@ -718,101 +723,128 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_PRESENT)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_SUPPORT)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_PRESENT)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_SUPPORT)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.dhwPresent) {
|
if (value != dst.opentherm.options.dhwSupport) {
|
||||||
dst.opentherm.dhwPresent = value;
|
dst.opentherm.options.dhwSupport = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_SUMMER_WINTER_MODE)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_COOLING_SUPPORT)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_SUMMER_WINTER_MODE)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_COOLING_SUPPORT)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.summerWinterMode) {
|
if (value != dst.opentherm.options.coolingSupport) {
|
||||||
dst.opentherm.summerWinterMode = value;
|
dst.opentherm.options.coolingSupport = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_HEATING_CH2_ENABLED)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SUMMER_WINTER_MODE)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_HEATING_CH2_ENABLED)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SUMMER_WINTER_MODE)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.heatingCh2Enabled) {
|
if (value != dst.opentherm.options.summerWinterMode) {
|
||||||
dst.opentherm.heatingCh2Enabled = value;
|
dst.opentherm.options.summerWinterMode = value;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dst.opentherm.heatingCh2Enabled) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_STATE_TO_SUMMER_WINTER_MODE)].is<bool>()) {
|
||||||
dst.opentherm.heatingCh1ToCh2 = false;
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_STATE_TO_SUMMER_WINTER_MODE)].as<bool>();
|
||||||
dst.opentherm.dhwToCh2 = false;
|
|
||||||
|
if (value != dst.opentherm.options.heatingStateToSummerWinterMode) {
|
||||||
|
dst.opentherm.options.heatingStateToSummerWinterMode = value;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_CH2_ALWAYS_ENABLED)].is<bool>()) {
|
||||||
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_CH2_ALWAYS_ENABLED)].as<bool>();
|
||||||
|
|
||||||
|
if (value != dst.opentherm.options.ch2AlwaysEnabled) {
|
||||||
|
dst.opentherm.options.ch2AlwaysEnabled = value;
|
||||||
|
|
||||||
|
if (dst.opentherm.options.ch2AlwaysEnabled) {
|
||||||
|
dst.opentherm.options.heatingToCh2 = false;
|
||||||
|
dst.opentherm.options.dhwToCh2 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_HEATING_CH1_TO_CH2)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_TO_CH2)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_HEATING_CH1_TO_CH2)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_TO_CH2)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.heatingCh1ToCh2) {
|
if (value != dst.opentherm.options.heatingToCh2) {
|
||||||
dst.opentherm.heatingCh1ToCh2 = value;
|
dst.opentherm.options.heatingToCh2 = value;
|
||||||
|
|
||||||
if (dst.opentherm.heatingCh1ToCh2) {
|
if (dst.opentherm.options.heatingToCh2) {
|
||||||
dst.opentherm.heatingCh2Enabled = false;
|
dst.opentherm.options.ch2AlwaysEnabled = false;
|
||||||
dst.opentherm.dhwToCh2 = false;
|
dst.opentherm.options.dhwToCh2 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_TO_CH2)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_TO_CH2)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_TO_CH2)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_TO_CH2)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.dhwToCh2) {
|
if (value != dst.opentherm.options.dhwToCh2) {
|
||||||
dst.opentherm.dhwToCh2 = value;
|
dst.opentherm.options.dhwToCh2 = value;
|
||||||
|
|
||||||
if (dst.opentherm.dhwToCh2) {
|
if (dst.opentherm.options.dhwToCh2) {
|
||||||
dst.opentherm.heatingCh2Enabled = false;
|
dst.opentherm.options.ch2AlwaysEnabled = false;
|
||||||
dst.opentherm.heatingCh1ToCh2 = false;
|
dst.opentherm.options.heatingToCh2 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_BLOCKING)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_BLOCKING)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_BLOCKING)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_BLOCKING)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.dhwBlocking) {
|
if (value != dst.opentherm.options.dhwBlocking) {
|
||||||
dst.opentherm.dhwBlocking = value;
|
dst.opentherm.options.dhwBlocking = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_MODULATION_SYNC_WITH_HEATING)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_MODULATION_SYNC_WITH_HEATING)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_MODULATION_SYNC_WITH_HEATING)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_MODULATION_SYNC_WITH_HEATING)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.modulationSyncWithHeating) {
|
if (value != dst.opentherm.options.modulationSyncWithHeating) {
|
||||||
dst.opentherm.modulationSyncWithHeating = value;
|
dst.opentherm.options.modulationSyncWithHeating = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_GET_MIN_MAX_TEMP)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_MAX_TEMP_SYNC_WITH_TARGET_TEMP)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_GET_MIN_MAX_TEMP)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_MAX_TEMP_SYNC_WITH_TARGET_TEMP)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.getMinMaxTemp) {
|
if (value != dst.opentherm.options.maxTempSyncWithTargetTemp) {
|
||||||
dst.opentherm.getMinMaxTemp = value;
|
dst.opentherm.options.maxTempSyncWithTargetTemp = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_NATIVE_HEATING_CONTROL)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_GET_MIN_MAX_TEMP)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_NATIVE_HEATING_CONTROL)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_GET_MIN_MAX_TEMP)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.nativeHeatingControl) {
|
if (value != dst.opentherm.options.getMinMaxTemp) {
|
||||||
dst.opentherm.nativeHeatingControl = value;
|
dst.opentherm.options.getMinMaxTemp = value;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_NATIVE_HEATING_CONTROL)].is<bool>()) {
|
||||||
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_NATIVE_HEATING_CONTROL)].as<bool>();
|
||||||
|
|
||||||
|
if (value != dst.opentherm.options.nativeHeatingControl) {
|
||||||
|
dst.opentherm.options.nativeHeatingControl = value;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
dst.equitherm.enabled = false;
|
dst.equitherm.enabled = false;
|
||||||
@@ -823,11 +855,11 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_IMMERGAS_FIX)].is<bool>()) {
|
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_IMMERGAS_FIX)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_IMMERGAS_FIX)].as<bool>();
|
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_IMMERGAS_FIX)].as<bool>();
|
||||||
|
|
||||||
if (value != dst.opentherm.immergasFix) {
|
if (value != dst.opentherm.options.immergasFix) {
|
||||||
dst.opentherm.immergasFix = value;
|
dst.opentherm.options.immergasFix = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -923,7 +955,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
if (src[FPSTR(S_EQUITHERM)][FPSTR(S_ENABLED)].is<bool>()) {
|
if (src[FPSTR(S_EQUITHERM)][FPSTR(S_ENABLED)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_EQUITHERM)][FPSTR(S_ENABLED)].as<bool>();
|
bool value = src[FPSTR(S_EQUITHERM)][FPSTR(S_ENABLED)].as<bool>();
|
||||||
|
|
||||||
if (!dst.opentherm.nativeHeatingControl) {
|
if (!dst.opentherm.options.nativeHeatingControl) {
|
||||||
if (value != dst.equitherm.enabled) {
|
if (value != dst.equitherm.enabled) {
|
||||||
dst.equitherm.enabled = value;
|
dst.equitherm.enabled = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -967,7 +999,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
if (src[FPSTR(S_PID)][FPSTR(S_ENABLED)].is<bool>()) {
|
if (src[FPSTR(S_PID)][FPSTR(S_ENABLED)].is<bool>()) {
|
||||||
bool value = src[FPSTR(S_PID)][FPSTR(S_ENABLED)].as<bool>();
|
bool value = src[FPSTR(S_PID)][FPSTR(S_ENABLED)].as<bool>();
|
||||||
|
|
||||||
if (!dst.opentherm.nativeHeatingControl) {
|
if (!dst.opentherm.options.nativeHeatingControl) {
|
||||||
if (value != dst.pid.enabled) {
|
if (value != dst.pid.enabled) {
|
||||||
dst.pid.enabled = value;
|
dst.pid.enabled = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -1326,7 +1358,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
// force check emergency target
|
// force check emergency target
|
||||||
{
|
{
|
||||||
float value = !src[FPSTR(S_EMERGENCY)][FPSTR(S_TARGET)].isNull() ? src[FPSTR(S_EMERGENCY)][FPSTR(S_TARGET)].as<float>() : dst.emergency.target;
|
float value = !src[FPSTR(S_EMERGENCY)][FPSTR(S_TARGET)].isNull() ? src[FPSTR(S_EMERGENCY)][FPSTR(S_TARGET)].as<float>() : dst.emergency.target;
|
||||||
bool noRegulators = !dst.opentherm.nativeHeatingControl;
|
bool noRegulators = !dst.opentherm.options.nativeHeatingControl;
|
||||||
bool valid = isValidTemp(
|
bool valid = isValidTemp(
|
||||||
value,
|
value,
|
||||||
dst.system.unitSystem,
|
dst.system.unitSystem,
|
||||||
@@ -1351,7 +1383,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
|
|
||||||
// force check heating target
|
// force check heating target
|
||||||
{
|
{
|
||||||
bool indoorTempControl = dst.equitherm.enabled || dst.pid.enabled || dst.opentherm.nativeHeatingControl;
|
bool indoorTempControl = dst.equitherm.enabled || dst.pid.enabled || dst.opentherm.options.nativeHeatingControl;
|
||||||
float minTemp = indoorTempControl ? THERMOSTAT_INDOOR_MIN_TEMP : dst.heating.minTemp;
|
float minTemp = indoorTempControl ? THERMOSTAT_INDOOR_MIN_TEMP : dst.heating.minTemp;
|
||||||
float maxTemp = indoorTempControl ? THERMOSTAT_INDOOR_MAX_TEMP : dst.heating.maxTemp;
|
float maxTemp = indoorTempControl ? THERMOSTAT_INDOOR_MAX_TEMP : dst.heating.maxTemp;
|
||||||
|
|
||||||
@@ -1720,6 +1752,7 @@ void varsToJson(const Variables& src, JsonVariant dst) {
|
|||||||
slave[FPSTR(S_PROTOCOL_VERSION)] = src.slave.appVersion;
|
slave[FPSTR(S_PROTOCOL_VERSION)] = src.slave.appVersion;
|
||||||
slave[FPSTR(S_CONNECTED)] = src.slave.connected;
|
slave[FPSTR(S_CONNECTED)] = src.slave.connected;
|
||||||
slave[FPSTR(S_FLAME)] = src.slave.flame;
|
slave[FPSTR(S_FLAME)] = src.slave.flame;
|
||||||
|
slave[FPSTR(S_COOLING)] = src.slave.cooling;
|
||||||
|
|
||||||
auto sModulation = slave[FPSTR(S_MODULATION)].to<JsonObject>();
|
auto sModulation = slave[FPSTR(S_MODULATION)].to<JsonObject>();
|
||||||
sModulation[FPSTR(S_MIN)] = src.slave.modulation.min;
|
sModulation[FPSTR(S_MIN)] = src.slave.modulation.min;
|
||||||
|
|||||||
@@ -87,6 +87,18 @@
|
|||||||
"turbo": "Turbo mode"
|
"turbo": "Turbo mode"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"notify": {
|
||||||
|
"fault": {
|
||||||
|
"title": "Boiler Fault state is active!",
|
||||||
|
"note": "It is recommended to inspect the boiler and study the documentation to interpret the fault code:"
|
||||||
|
},
|
||||||
|
"diag": {
|
||||||
|
"title": "Boiler Diagnostic state is active!",
|
||||||
|
"note": "Perhaps your boiler needs inspection? It is recommended study the documentation to interpret the diag code:"
|
||||||
|
},
|
||||||
|
"reset": "Try reset"
|
||||||
|
},
|
||||||
|
|
||||||
"states": {
|
"states": {
|
||||||
"mNetworkConnected": "Network connection",
|
"mNetworkConnected": "Network connection",
|
||||||
"mMqttConnected": "MQTT connection",
|
"mMqttConnected": "MQTT connection",
|
||||||
@@ -97,8 +109,9 @@
|
|||||||
|
|
||||||
"sConnected": "OpenTherm connection",
|
"sConnected": "OpenTherm connection",
|
||||||
"sFlame": "Flame",
|
"sFlame": "Flame",
|
||||||
|
"sCooling": "Cooling",
|
||||||
"sFaultActive": "Fault",
|
"sFaultActive": "Fault",
|
||||||
"sFaultCode": "Faul code",
|
"sFaultCode": "Fault code",
|
||||||
"sDiagActive": "Diagnostic",
|
"sDiagActive": "Diagnostic",
|
||||||
"sDiagCode": "Diagnostic code",
|
"sDiagCode": "Diagnostic code",
|
||||||
|
|
||||||
@@ -356,13 +369,16 @@
|
|||||||
|
|
||||||
"options": {
|
"options": {
|
||||||
"desc": "Options",
|
"desc": "Options",
|
||||||
"dhwPresent": "DHW present",
|
"dhwSupport": "DHW support",
|
||||||
|
"coolingSupport": "Cooling support",
|
||||||
"summerWinterMode": "Summer/winter mode",
|
"summerWinterMode": "Summer/winter mode",
|
||||||
"heatingCh2Enabled": "Heating CH2 always enabled",
|
"heatingStateToSummerWinterMode": "Heating state as summer/winter mode",
|
||||||
"heatingCh1ToCh2": "Duplicate heating CH1 to CH2",
|
"ch2AlwaysEnabled": "CH2 always enabled",
|
||||||
|
"heatingToCh2": "Duplicate heating to CH2",
|
||||||
"dhwToCh2": "Duplicate DHW to CH2",
|
"dhwToCh2": "Duplicate DHW to CH2",
|
||||||
"dhwBlocking": "DHW blocking",
|
"dhwBlocking": "DHW blocking",
|
||||||
"modulationSyncWithHeating": "Sync modulation with heating",
|
"modulationSyncWithHeating": "Sync modulation with heating",
|
||||||
|
"maxTempSyncWithTargetTemp": "Sync max heating temp with target temp",
|
||||||
"getMinMaxTemp": "Get min/max temp from boiler",
|
"getMinMaxTemp": "Get min/max temp from boiler",
|
||||||
"immergasFix": "Fix for Immergas boilers"
|
"immergasFix": "Fix for Immergas boilers"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -87,6 +87,18 @@
|
|||||||
"turbo": "Турбо"
|
"turbo": "Турбо"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"notify": {
|
||||||
|
"fault": {
|
||||||
|
"title": "Состояние неисправности котла активно!",
|
||||||
|
"note": "Рекомендуется осмотреть котел и изучить документацию котла для расшифровки кода неисправности:"
|
||||||
|
},
|
||||||
|
"diag": {
|
||||||
|
"title": "Состояние диагностики котла активно!",
|
||||||
|
"note": "Возможно, вашему котлу требуется проверка? Рекомендуется изучить документацию котла для расшифровки кода диагностики:"
|
||||||
|
},
|
||||||
|
"reset": "Сбросить"
|
||||||
|
},
|
||||||
|
|
||||||
"states": {
|
"states": {
|
||||||
"mNetworkConnected": "Подключение к сети",
|
"mNetworkConnected": "Подключение к сети",
|
||||||
"mMqttConnected": "Подключение к MQTT",
|
"mMqttConnected": "Подключение к MQTT",
|
||||||
@@ -97,6 +109,7 @@
|
|||||||
|
|
||||||
"sConnected": "Подключение к OpenTherm",
|
"sConnected": "Подключение к OpenTherm",
|
||||||
"sFlame": "Пламя",
|
"sFlame": "Пламя",
|
||||||
|
"sCooling": "Охлаждение",
|
||||||
"sFaultActive": "Ошибка",
|
"sFaultActive": "Ошибка",
|
||||||
"sFaultCode": "Код ошибки",
|
"sFaultCode": "Код ошибки",
|
||||||
"sDiagActive": "Диагностика",
|
"sDiagActive": "Диагностика",
|
||||||
@@ -180,7 +193,7 @@
|
|||||||
"purpose": "Назначение",
|
"purpose": "Назначение",
|
||||||
"purposes": {
|
"purposes": {
|
||||||
"outdoorTemp": "Внешняя температура",
|
"outdoorTemp": "Внешняя температура",
|
||||||
"indoorTemp": "Внутреняя температура",
|
"indoorTemp": "Внутренняя температура",
|
||||||
"heatTemp": "Отопление, температура",
|
"heatTemp": "Отопление, температура",
|
||||||
"heatRetTemp": "Отопление, температура обратки",
|
"heatRetTemp": "Отопление, температура обратки",
|
||||||
"dhwTemp": "ГВС, температура",
|
"dhwTemp": "ГВС, температура",
|
||||||
@@ -356,13 +369,16 @@
|
|||||||
|
|
||||||
"options": {
|
"options": {
|
||||||
"desc": "Опции",
|
"desc": "Опции",
|
||||||
"dhwPresent": "Контур ГВС",
|
"dhwSupport": "Поддержка ГВС",
|
||||||
|
"coolingSupport": "Поддержка охлаждения",
|
||||||
"summerWinterMode": "Летний/зимний режим",
|
"summerWinterMode": "Летний/зимний режим",
|
||||||
"heatingCh2Enabled": "Канал 2 отопления всегда вкл.",
|
"heatingStateToSummerWinterMode": "Летний/зимний режим в качестве состояния отопления",
|
||||||
"heatingCh1ToCh2": "Дублировать параметры отопления канала 1 в канал 2",
|
"ch2AlwaysEnabled": "Канал 2 всегда вкл.",
|
||||||
|
"heatingToCh2": "Дублировать параметры отопления в канал 2",
|
||||||
"dhwToCh2": "Дублировать параметры ГВС в канал 2",
|
"dhwToCh2": "Дублировать параметры ГВС в канал 2",
|
||||||
"dhwBlocking": "DHW blocking",
|
"dhwBlocking": "DHW blocking",
|
||||||
"modulationSyncWithHeating": "Синхронизировать модуляцию с отоплением",
|
"modulationSyncWithHeating": "Синхронизировать модуляцию с отоплением",
|
||||||
|
"maxTempSyncWithTargetTemp": "Синхронизировать макс. темп. отопления с целевой темп.",
|
||||||
"getMinMaxTemp": "Получать мин. и макс. температуру от котла",
|
"getMinMaxTemp": "Получать мин. и макс. температуру от котла",
|
||||||
"immergasFix": "Фикс для котлов Immergas"
|
"immergasFix": "Фикс для котлов Immergas"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -71,6 +71,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="notify notify-error notify-fault hidden">
|
||||||
|
<div class="notify-icon">
|
||||||
|
<i class="icons-error"></i>
|
||||||
|
</div>
|
||||||
|
<div class="notify-content">
|
||||||
|
<b data-i18n>dashboard.notify.fault.title</b><br />
|
||||||
|
<small>
|
||||||
|
<span data-i18n>dashboard.notify.fault.note</span> <b class="sFaultCode"></b>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="notify-actions">
|
||||||
|
<button class="reset" data-i18n>dashboard.notify.reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="notify notify-alarm notify-diag hidden">
|
||||||
|
<div class="notify-icon">
|
||||||
|
<i class="icons-alarm"></i>
|
||||||
|
</div>
|
||||||
|
<div class="notify-content">
|
||||||
|
<b data-i18n>dashboard.notify.diag.title</b><br />
|
||||||
|
<small>
|
||||||
|
<span data-i18n>dashboard.notify.diag.note</span> <b class="sDiagCode"></b>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="notify-actions">
|
||||||
|
<button class="reset" data-i18n>dashboard.notify.reset</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -113,6 +143,10 @@
|
|||||||
<th scope="row" data-i18n>dashboard.states.sFlame</th>
|
<th scope="row" data-i18n>dashboard.states.sFlame</th>
|
||||||
<td><i class="sFlame"></i></td>
|
<td><i class="sFlame"></i></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" data-i18n>dashboard.states.sCooling</th>
|
||||||
|
<td><i class="sCooling"></i></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
@@ -354,6 +388,60 @@
|
|||||||
newSettings.dhw.enabled = event.currentTarget.checked;
|
newSettings.dhw.enabled = event.currentTarget.checked;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.querySelector('.notify-fault .reset').addEventListener('click', async (event) => {
|
||||||
|
const resetBtn = document.querySelector(".notify-fault .reset");
|
||||||
|
if (!resetBtn.disabled) {
|
||||||
|
resetBtn.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = await fetch("/api/vars", {
|
||||||
|
method: "POST",
|
||||||
|
cache: "no-cache",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"actions": {
|
||||||
|
"resetFault": true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (resetBtn.disabled) {
|
||||||
|
resetBtn.disabled = false;
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelector('.notify-diag .reset').addEventListener('click', async (event) => {
|
||||||
|
const resetBtn = document.querySelector(".notify-diag .reset");
|
||||||
|
if (!resetBtn.disabled) {
|
||||||
|
resetBtn.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = await fetch("/api/vars", {
|
||||||
|
method: "POST",
|
||||||
|
cache: "no-cache",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"actions": {
|
||||||
|
"resetDiagnostic": true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (resetBtn.disabled) {
|
||||||
|
resetBtn.disabled = false;
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
|
|
||||||
setTimeout(async function onLoadPage() {
|
setTimeout(async function onLoadPage() {
|
||||||
let unitSystem = null;
|
let unitSystem = null;
|
||||||
|
|
||||||
@@ -372,8 +460,8 @@
|
|||||||
(prevSettings.heating.enabled != newSettings.heating.enabled)
|
(prevSettings.heating.enabled != newSettings.heating.enabled)
|
||||||
|| (prevSettings.heating.turbo != newSettings.heating.turbo)
|
|| (prevSettings.heating.turbo != newSettings.heating.turbo)
|
||||||
|| (prevSettings.heating.target != newSettings.heating.target)
|
|| (prevSettings.heating.target != newSettings.heating.target)
|
||||||
|| (prevSettings.opentherm.dhwPresent && prevSettings.dhw.enabled != newSettings.dhw.enabled)
|
|| (prevSettings.opentherm.options.dhwSupport && prevSettings.dhw.enabled != newSettings.dhw.enabled)
|
||||||
|| (prevSettings.opentherm.dhwPresent && prevSettings.dhw.target != newSettings.dhw.target)
|
|| (prevSettings.opentherm.options.dhwSupport && prevSettings.dhw.target != newSettings.dhw.target)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (modified) {
|
if (modified) {
|
||||||
@@ -397,7 +485,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
noRegulators = !result.opentherm.nativeHeatingControl && !result.equitherm.enabled && !result.pid.enabled;
|
noRegulators = !result.opentherm.options.nativeHeatingControl && !result.equitherm.enabled && !result.pid.enabled;
|
||||||
prevSettings = result;
|
prevSettings = result;
|
||||||
unitSystem = result.system.unitSystem;
|
unitSystem = result.system.unitSystem;
|
||||||
newSettings.heating.enabled = result.heating.enabled;
|
newSettings.heating.enabled = result.heating.enabled;
|
||||||
@@ -406,7 +494,7 @@
|
|||||||
newSettings.dhw.enabled = result.dhw.enabled;
|
newSettings.dhw.enabled = result.dhw.enabled;
|
||||||
newSettings.dhw.target = result.dhw.target;
|
newSettings.dhw.target = result.dhw.target;
|
||||||
|
|
||||||
if (result.opentherm.dhwPresent) {
|
if (result.opentherm.options.dhwSupport) {
|
||||||
show('#thermostat-dhw');
|
show('#thermostat-dhw');
|
||||||
} else {
|
} else {
|
||||||
hide('#thermostat-dhw');
|
hide('#thermostat-dhw');
|
||||||
@@ -462,6 +550,7 @@
|
|||||||
result.slave.connected ? "green" : "red"
|
result.slave.connected ? "green" : "red"
|
||||||
);
|
);
|
||||||
setState('.sFlame', result.slave.flame);
|
setState('.sFlame', result.slave.flame);
|
||||||
|
setState('.sCooling', result.slave.cooling);
|
||||||
|
|
||||||
setValue('.sModMin', result.slave.modulation.min);
|
setValue('.sModMin', result.slave.modulation.min);
|
||||||
setValue('.sModMax', result.slave.modulation.max);
|
setValue('.sModMax', result.slave.modulation.max);
|
||||||
@@ -489,6 +578,13 @@
|
|||||||
: "-"
|
: "-"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (result.slave.fault.active) {
|
||||||
|
show(".notify-fault");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
hide('.notify-fault');
|
||||||
|
}
|
||||||
|
|
||||||
setStatus(
|
setStatus(
|
||||||
'.sDiagActive',
|
'.sDiagActive',
|
||||||
result.slave.diag.active ? "success" : "error",
|
result.slave.diag.active ? "success" : "error",
|
||||||
@@ -501,6 +597,13 @@
|
|||||||
: "-"
|
: "-"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (result.slave.diag.active) {
|
||||||
|
show(".notify-diag");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
hide('.notify-diag');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MASTER
|
// MASTER
|
||||||
setState('.mHeatEnabled', result.master.heating.enabled);
|
setState('.mHeatEnabled', result.master.heating.enabled);
|
||||||
|
|||||||
@@ -38,37 +38,37 @@
|
|||||||
|
|
||||||
<div id="network-settings-busy" aria-busy="true"></div>
|
<div id="network-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/network/settings" id="network-settings" class="hidden">
|
<form action="/api/network/settings" id="network-settings" class="hidden">
|
||||||
<label for="network-hostname">
|
<label>
|
||||||
<span data-i18n>network.params.hostname</span>
|
<span data-i18n>network.params.hostname</span>
|
||||||
<input type="text" id="network-hostname" name="hostname" maxlength="24" pattern="[A-Za-z0-9]+[A-Za-z0-9\-]+[A-Za-z0-9]+" required>
|
<input type="text" name="hostname" maxlength="24" pattern="[A-Za-z0-9]+[A-Za-z0-9\-]+[A-Za-z0-9]+" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="network-use-dhcp">
|
<label>
|
||||||
<input type="checkbox" id="network-use-dhcp" name="useDhcp" value="true">
|
<input type="checkbox" name="useDhcp" value="true">
|
||||||
<span data-i18n>network.params.dhcp</span>
|
<span data-i18n>network.params.dhcp</span>
|
||||||
</label>
|
</label>
|
||||||
<br />
|
<br />
|
||||||
<hr />
|
<hr />
|
||||||
<h4 data-i18n>network.section.static</h4>
|
<h4 data-i18n>network.section.static</h4>
|
||||||
|
|
||||||
<label for="network-static-ip">
|
<label>
|
||||||
<span data-i18n>network.params.ip</span>
|
<span data-i18n>network.params.ip</span>
|
||||||
<input type="text" id="network-static-ip" name="staticConfig[ip]" value="true" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
<input type="text" name="staticConfig[ip]" value="true" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="network-static-gateway">
|
<label>
|
||||||
<span data-i18n>network.params.gateway</span>
|
<span data-i18n>network.params.gateway</span>
|
||||||
<input type="text" id="network-static-gateway" name="staticConfig[gateway]" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
<input type="text" name="staticConfig[gateway]" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="network-static-subnet">
|
<label>
|
||||||
<span data-i18n>network.params.subnet</span>
|
<span data-i18n>network.params.subnet</span>
|
||||||
<input type="text" id="network-static-subnet" name="staticConfig[subnet]" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
<input type="text" name="staticConfig[subnet]" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="network-static-dns">
|
<label>
|
||||||
<span data-i18n>network.params.dns</span>
|
<span data-i18n>network.params.dns</span>
|
||||||
<input type="text" id="network-static-dns" name="staticConfig[dns]" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
<input type="text" name="staticConfig[dns]" maxlength="16" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<button type="submit" data-i18n>button.save</button>
|
<button type="submit" data-i18n>button.save</button>
|
||||||
@@ -109,19 +109,19 @@
|
|||||||
|
|
||||||
<div id="sta-settings-busy" aria-busy="true"></div>
|
<div id="sta-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/network/settings" id="sta-settings" class="hidden">
|
<form action="/api/network/settings" id="sta-settings" class="hidden">
|
||||||
<label for="sta-ssid">
|
<label>
|
||||||
<span data-i18n>network.wifi.ssid</span>
|
<span data-i18n>network.wifi.ssid</span>
|
||||||
<input type="text" id="sta-ssid" name="sta[ssid]" maxlength="32" required>
|
<input type="text" name="sta[ssid]" maxlength="32" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="sta-password">
|
<label>
|
||||||
<span data-i18n>network.wifi.password</span>
|
<span data-i18n>network.wifi.password</span>
|
||||||
<input type="password" id="sta-password" name="sta[password]" maxlength="64" required>
|
<input type="password" name="sta[password]" maxlength="64" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="sta-channel">
|
<label>
|
||||||
<span data-i18n>network.wifi.channel</span>
|
<span data-i18n>network.wifi.channel</span>
|
||||||
<input type="number" inputmode="numeric" id="sta-channel" name="sta[channel]" min="0" max="12" step="1" required>
|
<input type="number" inputmode="numeric" name="sta[channel]" min="0" max="12" step="1" required>
|
||||||
<small data-i18n>network.sta.channel.note</small>
|
<small data-i18n>network.sta.channel.note</small>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -140,19 +140,19 @@
|
|||||||
|
|
||||||
<div id="ap-settings-busy" aria-busy="true"></div>
|
<div id="ap-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/network/settings" id="ap-settings" class="hidden">
|
<form action="/api/network/settings" id="ap-settings" class="hidden">
|
||||||
<label for="ap-ssid">
|
<label>
|
||||||
<span data-i18n>network.wifi.ssid</span>
|
<span data-i18n>network.wifi.ssid</span>
|
||||||
<input type="text" id="ap-ssid" name="ap[ssid]" maxlength="32" required>
|
<input type="text" name="ap[ssid]" maxlength="32" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="ap-password">
|
<label>
|
||||||
<span data-i18n>network.wifi.password</span>
|
<span data-i18n>network.wifi.password</span>
|
||||||
<input type="text" id="ap-password" name="ap[password]" maxlength="64" required>
|
<input type="text" name="ap[password]" maxlength="64" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="ap-channel">
|
<label>
|
||||||
<span data-i18n>network.wifi.channel</span>
|
<span data-i18n>network.wifi.channel</span>
|
||||||
<input type="number" inputmode="numeric" id="ap-channel" name="ap[channel]" min="1" max="12" step="1" required>
|
<input type="number" inputmode="numeric" name="ap[channel]" min="1" max="12" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<button type="submit" data-i18n>button.save</button>
|
<button type="submit" data-i18n>button.save</button>
|
||||||
@@ -179,22 +179,22 @@
|
|||||||
lang.build();
|
lang.build();
|
||||||
|
|
||||||
const fillData = (data) => {
|
const fillData = (data) => {
|
||||||
setInputValue('#network-hostname', data.hostname);
|
setInputValue("[name='hostname']", data.hostname);
|
||||||
setCheckboxValue('#network-use-dhcp', data.useDhcp);
|
setCheckboxValue("[name='useDhcp']", data.useDhcp);
|
||||||
setInputValue('#network-static-ip', data.staticConfig.ip);
|
setInputValue("[name='staticConfig[ip]']", data.staticConfig.ip);
|
||||||
setInputValue('#network-static-gateway', data.staticConfig.gateway);
|
setInputValue("[name='staticConfig[gateway]']", data.staticConfig.gateway);
|
||||||
setInputValue('#network-static-subnet', data.staticConfig.subnet);
|
setInputValue("[name='staticConfig[subnet]']", data.staticConfig.subnet);
|
||||||
setInputValue('#network-static-dns', data.staticConfig.dns);
|
setInputValue("[name='staticConfig[dns]']", data.staticConfig.dns);
|
||||||
setBusy('#network-settings-busy', '#network-settings', false);
|
setBusy('#network-settings-busy', '#network-settings', false);
|
||||||
|
|
||||||
setInputValue('#sta-ssid', data.sta.ssid);
|
setInputValue("[name='sta[ssid]']", data.sta.ssid);
|
||||||
setInputValue('#sta-password', data.sta.password);
|
setInputValue("[name='sta[password]']", data.sta.password);
|
||||||
setInputValue('#sta-channel', data.sta.channel);
|
setInputValue("[name='sta[channel]']", data.sta.channel);
|
||||||
setBusy('#sta-settings-busy', '#sta-settings', false);
|
setBusy('#sta-settings-busy', '#sta-settings', false);
|
||||||
|
|
||||||
setInputValue('#ap-ssid', data.ap.ssid);
|
setInputValue("[name='ap[ssid]']", data.ap.ssid);
|
||||||
setInputValue('#ap-password', data.ap.password);
|
setInputValue("[name='ap[password]']", data.ap.password);
|
||||||
setInputValue('#ap-channel', data.ap.channel);
|
setInputValue("[name='ap[channel]']", data.ap.channel);
|
||||||
setBusy('#ap-settings-busy', '#ap-settings', false);
|
setBusy('#ap-settings-busy', '#ap-settings', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -134,12 +134,12 @@
|
|||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n>sensors.correction.offset</span>
|
<span data-i18n>sensors.correction.offset</span>
|
||||||
<input type="number" inputmode="numeric" name="offset" min="-20" max="20" step="0.01" required>
|
<input type="number" inputmode="decimal" name="offset" min="-20" max="20" step="0.01" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n>sensors.correction.factor</span>
|
<span data-i18n>sensors.correction.factor</span>
|
||||||
<input type="number" inputmode="numeric" name="factor" min="0.01" max="10" step="0.01" required>
|
<input type="number" inputmode="decimal" name="factor" min="0.01" max="10" step="0.01" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
@@ -159,7 +159,7 @@
|
|||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n>sensors.filtering.factor.title</span>
|
<span data-i18n>sensors.filtering.factor.title</span>
|
||||||
<input type="number" inputmode="numeric" name="filteringFactor" min="0.01" max="1" step="0.01">
|
<input type="number" inputmode="decimal" name="filteringFactor" min="0.01" max="1" step="0.01">
|
||||||
<small data-i18n>sensors.filtering.factor.note</small>
|
<small data-i18n>sensors.filtering.factor.note</small>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,19 +41,19 @@
|
|||||||
<div id="portal-settings-busy" aria-busy="true"></div>
|
<div id="portal-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="portal-settings" class="hidden">
|
<form action="/api/settings" id="portal-settings" class="hidden">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="portal-login">
|
<label>
|
||||||
<span data-i18n>settings.portal.login</span>
|
<span data-i18n>settings.portal.login</span>
|
||||||
<input type="text" id="portal-login" name="portal[login]" maxlength="12" required>
|
<input type="text" name="portal[login]" maxlength="12" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="portal-password">
|
<label>
|
||||||
<span data-i18n>settings.portal.password</span>
|
<span data-i18n>settings.portal.password</span>
|
||||||
<input type="password" id="portal-password" name="portal[password]" maxlength="32" required>
|
<input type="password" name="portal[password]" maxlength="32" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="portal-auth">
|
<label>
|
||||||
<input type="checkbox" id="portal-auth" name="portal[auth]" value="true">
|
<input type="checkbox" name="portal[auth]" value="true">
|
||||||
<span data-i18n>settings.portal.auth</span>
|
<span data-i18n>settings.portal.auth</span>
|
||||||
</label>
|
</label>
|
||||||
<br />
|
<br />
|
||||||
@@ -74,20 +74,20 @@
|
|||||||
<legend data-i18n>settings.system.unit</legend>
|
<legend data-i18n>settings.system.unit</legend>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" class="system-unit-system" name="system[unitSystem]" value="0" />
|
<input type="radio" name="system[unitSystem]" value="0" />
|
||||||
<span data-i18n>settings.system.metric</span>
|
<span data-i18n>settings.system.metric</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" class="system-unit-system" name="system[unitSystem]" value="1" />
|
<input type="radio" name="system[unitSystem]" value="1" />
|
||||||
<span data-i18n>settings.system.imperial</span>
|
<span data-i18n>settings.system.imperial</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="system-status-led-gpio">
|
<label>
|
||||||
<span data-i18n>settings.system.statusLedGpio</span>
|
<span data-i18n>settings.system.statusLedGpio</span>
|
||||||
<input type="number" inputmode="numeric" id="system-status-led-gpio" name="system[statusLedGpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="system[statusLedGpio]" min="0" max="254" step="1">
|
||||||
<small data-i18n>settings.note.blankNotUse</small>
|
<small data-i18n>settings.note.blankNotUse</small>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -95,19 +95,19 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend data-i18n>settings.section.diag</legend>
|
<legend data-i18n>settings.section.diag</legend>
|
||||||
|
|
||||||
<label for="system-serial-enable">
|
<label>
|
||||||
<input type="checkbox" id="system-serial-enable" name="system[serial][enabled]" value="true">
|
<input type="checkbox" name="system[serial][enabled]" value="true">
|
||||||
<span data-i18n>settings.system.serial.enable</span>
|
<span data-i18n>settings.system.serial.enable</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="system-telnet-enable">
|
<label>
|
||||||
<input type="checkbox" id="system-telnet-enable" name="system[telnet][enabled]" value="true">
|
<input type="checkbox" name="system[telnet][enabled]" value="true">
|
||||||
<span data-i18n>settings.system.telnet.enable</span>
|
<span data-i18n>settings.system.telnet.enable</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="system-log-level">
|
<label>
|
||||||
<span data-i18n>settings.system.logLevel</span>
|
<span data-i18n>settings.system.logLevel</span>
|
||||||
<select id="system-log-level" name="system[logLevel]">
|
<select name="system[logLevel]">
|
||||||
<option value="0">SILENT</option>
|
<option value="0">SILENT</option>
|
||||||
<option value="1">FATAL</option>
|
<option value="1">FATAL</option>
|
||||||
<option value="2">ERROR</option>
|
<option value="2">ERROR</option>
|
||||||
@@ -120,9 +120,9 @@
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="system-serial-baudrate">
|
<label>
|
||||||
<span data-i18n>settings.system.serial.baud</span>
|
<span data-i18n>settings.system.serial.baud</span>
|
||||||
<select id="system-serial-baudrate" name="system[serial][baudrate]" required>
|
<select name="system[serial][baudrate]" required>
|
||||||
<option value="9600">9600</option>
|
<option value="9600">9600</option>
|
||||||
<option value="19200">19200</option>
|
<option value="19200">19200</option>
|
||||||
<option value="38400">38400</option>
|
<option value="38400">38400</option>
|
||||||
@@ -132,9 +132,9 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="system-telnet-port">
|
<label>
|
||||||
<span data-i18n>settings.system.telnet.port.title</span>
|
<span data-i18n>settings.system.telnet.port.title</span>
|
||||||
<input type="number" inputmode="numeric" id="system-telnet-port" name="system[telnet][port]" min="1" max="65535" step="1" required>
|
<input type="number" inputmode="numeric" name="system[telnet][port]" min="1" max="65535" step="1" required>
|
||||||
<small data-i18n>settings.system.telnet.port.note</small>
|
<small data-i18n>settings.system.telnet.port.note</small>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -156,26 +156,26 @@
|
|||||||
<div id="heating-settings-busy" aria-busy="true"></div>
|
<div id="heating-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="heating-settings" class="hidden">
|
<form action="/api/settings" id="heating-settings" class="hidden">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="heating-min-temp">
|
<label>
|
||||||
<span data-i18n>settings.temp.min</span>
|
<span data-i18n>settings.temp.min</span>
|
||||||
<input type="number" inputmode="numeric" id="heating-min-temp" name="heating[minTemp]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="heating[minTemp]" min="0" max="0" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="heating-max-temp">
|
<label>
|
||||||
<span data-i18n>settings.temp.max</span>
|
<span data-i18n>settings.temp.max</span>
|
||||||
<input type="number" inputmode="numeric" id="heating-max-temp" name="heating[maxTemp]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="heating[maxTemp]" min="0" max="0" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="heating-hysteresis">
|
<label>
|
||||||
<span data-i18n>settings.heating.hyst</span>
|
<span data-i18n>settings.heating.hyst</span>
|
||||||
<input type="number" inputmode="numeric" id="heating-hysteresis" name="heating[hysteresis]" min="0" max="5" step="0.05" required>
|
<input type="number" inputmode="decimal" name="heating[hysteresis]" min="0" max="5" step="0.05" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="heating-turbo-factor">
|
<label>
|
||||||
<span data-i18n>settings.heating.turboFactor</span>
|
<span data-i18n>settings.heating.turboFactor</span>
|
||||||
<input type="number" inputmode="numeric" id="heating-turbo-factor" name="heating[turboFactor]" min="1.5" max="10" step="0.1" required>
|
<input type="number" inputmode="decimal" name="heating[turboFactor]" min="1.5" max="10" step="0.1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -192,14 +192,14 @@
|
|||||||
<div id="dhw-settings-busy" aria-busy="true"></div>
|
<div id="dhw-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="dhw-settings" class="hidden">
|
<form action="/api/settings" id="dhw-settings" class="hidden">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="dhw-min-temp">
|
<label>
|
||||||
<span data-i18n>settings.temp.min</span>
|
<span data-i18n>settings.temp.min</span>
|
||||||
<input type="number" inputmode="numeric" id="dhw-min-temp" name="dhw[minTemp]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="dhw[minTemp]" min="0" max="0" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="dhw-max-temp">
|
<label>
|
||||||
<span data-i18n>settings.temp.max</span>
|
<span data-i18n>settings.temp.max</span>
|
||||||
<input type="number" inputmode="numeric" id="dhw-max-temp" name="dhw[maxTemp]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="dhw[maxTemp]" min="0" max="0" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -220,15 +220,15 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="emergency-target">
|
<label>
|
||||||
<span data-i18n>settings.emergency.target.title</span>
|
<span data-i18n>settings.emergency.target.title</span>
|
||||||
<input type="number" inputmode="numeric" id="emergency-target" name="emergency[target]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="emergency[target]" min="0" max="0" step="1" required>
|
||||||
<small data-i18n>settings.emergency.target.note</small>
|
<small data-i18n>settings.emergency.target.note</small>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="emergency-treshold-time">
|
<label>
|
||||||
<span data-i18n>settings.emergency.treshold</span>
|
<span data-i18n>settings.emergency.treshold</span>
|
||||||
<input type="number" inputmode="numeric" id="emergency-treshold-time" name="emergency[tresholdTime]" min="60" max="1800" step="1" required>
|
<input type="number" inputmode="numeric" name="emergency[tresholdTime]" min="60" max="1800" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -245,26 +245,26 @@
|
|||||||
<div id="equitherm-settings-busy" aria-busy="true"></div>
|
<div id="equitherm-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="equitherm-settings" class="hidden">
|
<form action="/api/settings" id="equitherm-settings" class="hidden">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="equitherm-enable">
|
<label>
|
||||||
<input type="checkbox" id="equitherm-enable" name="equitherm[enabled]" value="true">
|
<input type="checkbox" name="equitherm[enabled]" value="true">
|
||||||
<span data-i18n>settings.enable</span>
|
<span data-i18n>settings.enable</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="equitherm-n-factor">
|
<label>
|
||||||
<span data-i18n>settings.equitherm.n</span>
|
<span data-i18n>settings.equitherm.n</span>
|
||||||
<input type="number" inputmode="numeric" id="equitherm-n-factor" name="equitherm[n_factor]" min="0.001" max="10" step="0.001" required>
|
<input type="number" inputmode="decimal" name="equitherm[n_factor]" min="0.001" max="10" step="0.001" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="equitherm-k-factor">
|
<label>
|
||||||
<span data-i18n>settings.equitherm.k</span>
|
<span data-i18n>settings.equitherm.k</span>
|
||||||
<input type="number" inputmode="numeric" id="equitherm-k-factor" name="equitherm[k_factor]" min="0" max="10" step="0.01" required>
|
<input type="number" inputmode="decimal" name="equitherm[k_factor]" min="0" max="10" step="0.01" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="equitherm-t-factor">
|
<label>
|
||||||
<span data-i18n>settings.equitherm.t.title</span>
|
<span data-i18n>settings.equitherm.t.title</span>
|
||||||
<input type="number" inputmode="numeric" id="equitherm-t-factor" name="equitherm[t_factor]" min="0" max="10" step="0.01" required>
|
<input type="number" inputmode="decimal" name="equitherm[t_factor]" min="0" max="10" step="0.01" required>
|
||||||
<small data-i18n>settings.equitherm.t.note</small>
|
<small data-i18n>settings.equitherm.t.note</small>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -282,45 +282,45 @@
|
|||||||
<div id="pid-settings-busy" aria-busy="true"></div>
|
<div id="pid-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="pid-settings" class="hidden">
|
<form action="/api/settings" id="pid-settings" class="hidden">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="pid-enable">
|
<label>
|
||||||
<input type="checkbox" id="pid-enable" name="pid[enabled]" value="true">
|
<input type="checkbox" name="pid[enabled]" value="true">
|
||||||
<span data-i18n>settings.enable</span>
|
<span data-i18n>settings.enable</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="pid-p-factor">
|
<label>
|
||||||
<span data-i18n>settings.pid.p</span>
|
<span data-i18n>settings.pid.p</span>
|
||||||
<input type="number" inputmode="numeric" id="pid-p-factor" name="pid[p_factor]" min="0.1" max="1000" step="0.01" required>
|
<input type="number" inputmode="decimal" name="pid[p_factor]" min="0.1" max="1000" step="0.01" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="pid-i-factor">
|
<label>
|
||||||
<span data-i18n>settings.pid.i</span>
|
<span data-i18n>settings.pid.i</span>
|
||||||
<input type="number" inputmode="numeric" id="pid-i-factor" name="pid[i_factor]" min="0" max="100" step="0.0001" required>
|
<input type="number" inputmode="decimal" name="pid[i_factor]" min="0" max="100" step="0.0001" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="pid-d-factor">
|
<label>
|
||||||
<span data-i18n>settings.pid.d</span>
|
<span data-i18n>settings.pid.d</span>
|
||||||
<input type="number" inputmode="numeric" id="pid-d-factor" name="pid[d_factor]" min="0" max="100000" step="0.1" required>
|
<input type="number" inputmode="decimal" name="pid[d_factor]" min="0" max="100000" step="0.1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="pid-dt">
|
<label>
|
||||||
<span data-i18n>settings.pid.dt</span>
|
<span data-i18n>settings.pid.dt</span>
|
||||||
<input type="number" inputmode="numeric" id="pid-dt" name="pid[dt]" min="30" max="1800" step="1" required>
|
<input type="number" inputmode="numeric" name="pid[dt]" min="30" max="1800" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="pid-min-temp">
|
<label>
|
||||||
<span data-i18n>settings.temp.min</span>
|
<span data-i18n>settings.temp.min</span>
|
||||||
<input type="number" inputmode="numeric" id="pid-min-temp" name="pid[minTemp]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="pid[minTemp]" min="0" max="0" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="pid-max-temp">
|
<label>
|
||||||
<span data-i18n>settings.temp.max</span>
|
<span data-i18n>settings.temp.max</span>
|
||||||
<input type="number" inputmode="numeric" id="pid-max-temp" name="pid[maxTemp]" min="0" max="0" step="1" required>
|
<input type="number" inputmode="numeric" name="pid[maxTemp]" min="0" max="0" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -336,67 +336,67 @@
|
|||||||
<details>
|
<details>
|
||||||
<summary><b data-i18n>settings.section.ot</b></summary>
|
<summary><b data-i18n>settings.section.ot</b></summary>
|
||||||
<div>
|
<div>
|
||||||
<div id="opentherm-settings-busy" aria-busy="true"></div>
|
<div id="ot-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="opentherm-settings" class="hidden">
|
<form action="/api/settings" id="ot-settings" class="hidden">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend data-i18n>settings.system.unit</legend>
|
<legend data-i18n>settings.system.unit</legend>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" class="opentherm-unit-system" name="opentherm[unitSystem]" value="0" />
|
<input type="radio" name="opentherm[unitSystem]" value="0" />
|
||||||
<span data-i18n>settings.system.metric</span>
|
<span data-i18n>settings.system.metric</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" class="opentherm-unit-system" name="opentherm[unitSystem]" value="1" />
|
<input type="radio" name="opentherm[unitSystem]" value="1" />
|
||||||
<span data-i18n>settings.system.imperial</span>
|
<span data-i18n>settings.system.imperial</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="opentherm-in-gpio">
|
<label>
|
||||||
<span data-i18n>settings.ot.inGpio</span>
|
<span data-i18n>settings.ot.inGpio</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-in-gpio" name="opentherm[inGpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="opentherm[inGpio]" min="0" max="254" step="1">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-in-gpio">
|
<label>
|
||||||
<span data-i18n>settings.ot.outGpio</span>
|
<span data-i18n>settings.ot.outGpio</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-out-gpio" name="opentherm[outGpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="opentherm[outGpio]" min="0" max="254" step="1">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-rx-led-gpio">
|
<label>
|
||||||
<span data-i18n>settings.ot.ledGpio</span>
|
<span data-i18n>settings.ot.ledGpio</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-rx-led-gpio" name="opentherm[rxLedGpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="opentherm[rxLedGpio]" min="0" max="254" step="1">
|
||||||
<small data-i18n>settings.note.blankNotUse</small>
|
<small data-i18n>settings.note.blankNotUse</small>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="opentherm-member-id-code">
|
<label>
|
||||||
<span data-i18n>settings.ot.memberId</span>
|
<span data-i18n>settings.ot.memberId</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-member-id" name="opentherm[memberId]" min="0" max="255" step="1" required>
|
<input type="number" inputmode="numeric" name="opentherm[memberId]" min="0" max="255" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-flags">
|
<label>
|
||||||
<span data-i18n>settings.ot.flags</span>
|
<span data-i18n>settings.ot.flags</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-flags" name="opentherm[flags]" min="0" max="255" step="1" required>
|
<input type="number" inputmode="numeric" name="opentherm[flags]" min="0" max="255" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-max-modulation">
|
<label>
|
||||||
<span data-i18n>settings.ot.maxMod</span>
|
<span data-i18n>settings.ot.maxMod</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-max-modulation" name="opentherm[maxModulation]" min="1" max="100" step="1" required>
|
<input type="number" inputmode="numeric" name="opentherm[maxModulation]" min="1" max="100" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="opentherm-min-power">
|
<label>
|
||||||
<span data-i18n>settings.ot.minPower.title</span>
|
<span data-i18n>settings.ot.minPower.title</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-min-power" name="opentherm[minPower]" min="0" max="1000" step="0.1">
|
<input type="number" inputmode="decimal" name="opentherm[minPower]" min="0" max="1000" step="0.01">
|
||||||
<small data-i18n>settings.ot.minPower.note</small>
|
<small data-i18n>settings.ot.minPower.note</small>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-max-power">
|
<label>
|
||||||
<span data-i18n>settings.ot.maxPower.title</span>
|
<span data-i18n>settings.ot.maxPower.title</span>
|
||||||
<input type="number" inputmode="numeric" id="opentherm-max-power" name="opentherm[maxPower]" min="0" max="1000" step="0.1">
|
<input type="number" inputmode="decimal" name="opentherm[maxPower]" min="0" max="1000" step="0.01">
|
||||||
<small data-i18n>settings.ot.maxPower.note</small>
|
<small data-i18n>settings.ot.maxPower.note</small>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -404,54 +404,69 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend data-i18n>settings.ot.options.desc</legend>
|
<legend data-i18n>settings.ot.options.desc</legend>
|
||||||
|
|
||||||
<label for="opentherm-dhw-present">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-dhw-present" name="opentherm[dhwPresent]" value="true">
|
<input type="checkbox" name="opentherm[options][dhwSupport]" value="true">
|
||||||
<span data-i18n>settings.ot.options.dhwPresent</span>
|
<span data-i18n>settings.ot.options.dhwSupport</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-sw-mode">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-sw-mode" name="opentherm[summerWinterMode]" value="true">
|
<input type="checkbox" name="opentherm[options][coolingSupport]" value="true">
|
||||||
|
<span data-i18n>settings.ot.options.coolingSupport</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="opentherm[options][summerWinterMode]" value="true">
|
||||||
<span data-i18n>settings.ot.options.summerWinterMode</span>
|
<span data-i18n>settings.ot.options.summerWinterMode</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-heating-ch2-enabled">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-heating-ch2-enabled" name="opentherm[heatingCh2Enabled]" value="true">
|
<input type="checkbox" name="opentherm[options][heatingStateToSummerWinterMode]" value="true">
|
||||||
<span data-i18n>settings.ot.options.heatingCh2Enabled</span>
|
<span data-i18n>settings.ot.options.heatingStateToSummerWinterMode</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-heating-ch1-to-ch2">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-heating-ch1-to-ch2" name="opentherm[heatingCh1ToCh2]" value="true">
|
<input type="checkbox" name="opentherm[options][ch2AlwaysEnabled]" value="true">
|
||||||
<span data-i18n>settings.ot.options.heatingCh1ToCh2</span>
|
<span data-i18n>settings.ot.options.ch2AlwaysEnabled</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-dhw-to-ch2">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-dhw-to-ch2" name="opentherm[dhwToCh2]" value="true">
|
<input type="checkbox" name="opentherm[options][heatingToCh2]" value="true">
|
||||||
|
<span data-i18n>settings.ot.options.heatingToCh2</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="opentherm[options][dhwToCh2]" value="true">
|
||||||
<span data-i18n>settings.ot.options.dhwToCh2</span>
|
<span data-i18n>settings.ot.options.dhwToCh2</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-dhw-blocking">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-dhw-blocking" name="opentherm[dhwBlocking]" value="true">
|
<input type="checkbox" name="opentherm[options][dhwBlocking]" value="true">
|
||||||
<span data-i18n>settings.ot.options.dhwBlocking</span>
|
<span data-i18n>settings.ot.options.dhwBlocking</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-sync-modulation-with-heating">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-sync-modulation-with-heating" name="opentherm[modulationSyncWithHeating]" value="true">
|
<input type="checkbox" name="opentherm[options][modulationSyncWithHeating]" value="true">
|
||||||
<span data-i18n>settings.ot.options.modulationSyncWithHeating</span>
|
<span data-i18n>settings.ot.options.modulationSyncWithHeating</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-get-min-max-temp">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-get-min-max-temp" name="opentherm[getMinMaxTemp]" value="true">
|
<input type="checkbox" name="opentherm[options][maxTempSyncWithTargetTemp]" value="true">
|
||||||
|
<span data-i18n>settings.ot.options.maxTempSyncWithTargetTemp</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="opentherm[options][getMinMaxTemp]" value="true">
|
||||||
<span data-i18n>settings.ot.options.getMinMaxTemp</span>
|
<span data-i18n>settings.ot.options.getMinMaxTemp</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="opentherm-immergas-fix">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-immergas-fix" name="opentherm[immergasFix]" value="true">
|
<input type="checkbox" name="opentherm[options][immergasFix]" value="true">
|
||||||
<span data-i18n>settings.ot.options.immergasFix</span>
|
<span data-i18n>settings.ot.options.immergasFix</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<label for="opentherm-native-heating-control">
|
<label>
|
||||||
<input type="checkbox" id="opentherm-native-heating-control" name="opentherm[nativeHeatingControl]" value="true">
|
<input type="checkbox" name="opentherm[options][nativeHeatingControl]" value="true">
|
||||||
<span data-i18n>settings.ot.nativeHeating.title</span><br />
|
<span data-i18n>settings.ot.nativeHeating.title</span><br />
|
||||||
<small data-i18n>settings.ot.nativeHeating.note</small>
|
<small data-i18n>settings.ot.nativeHeating.note</small>
|
||||||
</label>
|
</label>
|
||||||
@@ -470,50 +485,50 @@
|
|||||||
<div id="mqtt-settings-busy" aria-busy="true"></div>
|
<div id="mqtt-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="mqtt-settings" class="hidden">
|
<form action="/api/settings" id="mqtt-settings" class="hidden">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="mqtt-enable">
|
<label>
|
||||||
<input type="checkbox" id="mqtt-enable" name="mqtt[enabled]" value="true">
|
<input type="checkbox" name="mqtt[enabled]" value="true">
|
||||||
<span data-i18n>settings.enable</span>
|
<span data-i18n>settings.enable</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="mqtt-ha-discovery">
|
<label>
|
||||||
<input type="checkbox" id="mqtt-ha-discovery" name="mqtt[homeAssistantDiscovery]" value="true">
|
<input type="checkbox" name="mqtt[homeAssistantDiscovery]" value="true">
|
||||||
<span data-i18n>settings.mqtt.homeAssistantDiscovery</span>
|
<span data-i18n>settings.mqtt.homeAssistantDiscovery</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="mqtt-server">
|
<label>
|
||||||
<span data-i18n>settings.mqtt.server</span>
|
<span data-i18n>settings.mqtt.server</span>
|
||||||
<input type="text" id="mqtt-server" name="mqtt[server]" maxlength="80" required>
|
<input type="text" name="mqtt[server]" maxlength="80" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="mqtt-port">
|
<label>
|
||||||
<span data-i18n>settings.mqtt.port</span>
|
<span data-i18n>settings.mqtt.port</span>
|
||||||
<input type="number" inputmode="numeric" id="mqtt-port" name="mqtt[port]" min="1" max="65535" step="1" required>
|
<input type="number" inputmode="numeric" name="mqtt[port]" min="1" max="65535" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="mqtt-user">
|
<label>
|
||||||
<span data-i18n>settings.mqtt.user</span>
|
<span data-i18n>settings.mqtt.user</span>
|
||||||
<input type="text" id="mqtt-user" name="mqtt[user]" maxlength="32" required>
|
<input type="text" name="mqtt[user]" maxlength="32" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="mqtt-password">
|
<label>
|
||||||
<span data-i18n>settings.mqtt.password</span>
|
<span data-i18n>settings.mqtt.password</span>
|
||||||
<input type="password" id="mqtt-password" name="mqtt[password]" maxlength="32">
|
<input type="password" name="mqtt[password]" maxlength="32">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="mqtt-prefix">
|
<label>
|
||||||
<span data-i18n>settings.mqtt.prefix</span>
|
<span data-i18n>settings.mqtt.prefix</span>
|
||||||
<input type="text" id="mqtt-prefix" name="mqtt[prefix]" maxlength="32" required>
|
<input type="text" name="mqtt[prefix]" maxlength="32" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="mqtt-interval">
|
<label>
|
||||||
<span data-i18n>settings.mqtt.interval</span>
|
<span data-i18n>settings.mqtt.interval</span>
|
||||||
<input type="number" inputmode="numeric" id="mqtt-interval" name="mqtt[interval]" min="3" max="60" step="1" required>
|
<input type="number" inputmode="numeric" name="mqtt[interval]" min="3" max="60" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -530,33 +545,33 @@
|
|||||||
<div id="extpump-settings-busy" aria-busy="true"></div>
|
<div id="extpump-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="extpump-settings" class="hidden">
|
<form action="/api/settings" id="extpump-settings" class="hidden">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="extpump-use">
|
<label>
|
||||||
<input type="checkbox" id="extpump-use" name="externalPump[use]" value="true">
|
<input type="checkbox" name="externalPump[use]" value="true">
|
||||||
<span data-i18n>settings.extPump.use</span>
|
<span data-i18n>settings.extPump.use</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="extpump-gpio">
|
<label>
|
||||||
<span data-i18n>settings.extPump.gpio</span>
|
<span data-i18n>settings.extPump.gpio</span>
|
||||||
<input type="number" inputmode="numeric" id="extpump-gpio" name="externalPump[gpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="externalPump[gpio]" min="0" max="254" step="1">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="extpump-pc-time">
|
<label>
|
||||||
<span data-i18n>settings.extPump.postCirculationTime</span>
|
<span data-i18n>settings.extPump.postCirculationTime</span>
|
||||||
<input type="number" inputmode="numeric" id="extpump-pc-time" name="externalPump[postCirculationTime]" min="1" max="120" step="1" required>
|
<input type="number" inputmode="numeric" name="externalPump[postCirculationTime]" min="1" max="120" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="extpump-as-interval">
|
<label>
|
||||||
<span data-i18n>settings.extPump.antiStuckInterval</span>
|
<span data-i18n>settings.extPump.antiStuckInterval</span>
|
||||||
<input type="number" inputmode="numeric" id="extpump-as-interval" name="externalPump[antiStuckInterval]" min="1" max="366" step="1" required>
|
<input type="number" inputmode="numeric" name="externalPump[antiStuckInterval]" min="1" max="366" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="extpump-as-time">
|
<label>
|
||||||
<span data-i18n>settings.extPump.antiStuckTime</span>
|
<span data-i18n>settings.extPump.antiStuckTime</span>
|
||||||
<input type="number" inputmode="numeric" id="extpump-as-time" name="externalPump[antiStuckTime]" min="1" max="20" step="1" required>
|
<input type="number" inputmode="numeric" name="externalPump[antiStuckTime]" min="1" max="20" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -573,74 +588,74 @@
|
|||||||
<div id="cc-settings-busy" aria-busy="true"></div>
|
<div id="cc-settings-busy" aria-busy="true"></div>
|
||||||
<form action="/api/settings" id="cc-settings" class="hidden">
|
<form action="/api/settings" id="cc-settings" class="hidden">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="cc-input-enable">
|
<label>
|
||||||
<input type="checkbox" id="cc-input-enable" name="cascadeControl[input][enabled]" value="true">
|
<input type="checkbox" name="cascadeControl[input][enabled]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.input.enable</span>
|
<span data-i18n>settings.cascadeControl.input.enable</span>
|
||||||
<br />
|
<br />
|
||||||
<small data-i18n>settings.cascadeControl.input.desc</small>
|
<small data-i18n>settings.cascadeControl.input.desc</small>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="cc-input-invert-state">
|
<label>
|
||||||
<input type="checkbox" id="cc-input-invert-state" name="cascadeControl[input][invertState]" value="true">
|
<input type="checkbox" name="cascadeControl[input][invertState]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.input.invertState</span>
|
<span data-i18n>settings.cascadeControl.input.invertState</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="cc-input-gpio">
|
<label>
|
||||||
<span data-i18n>settings.cascadeControl.input.gpio</span>
|
<span data-i18n>settings.cascadeControl.input.gpio</span>
|
||||||
<input type="number" inputmode="numeric" id="cc-input-gpio" name="cascadeControl[input][gpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="cascadeControl[input][gpio]" min="0" max="254" step="1">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="cc-input-tt">
|
<label>
|
||||||
<span data-i18n>settings.cascadeControl.input.thresholdTime</span>
|
<span data-i18n>settings.cascadeControl.input.thresholdTime</span>
|
||||||
<input type="number" inputmode="numeric" id="cc-input-tt" name="cascadeControl[input][thresholdTime]" min="5" max="600" step="1" required>
|
<input type="number" inputmode="numeric" name="cascadeControl[input][thresholdTime]" min="5" max="600" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="cc-output-enable">
|
<label>
|
||||||
<input type="checkbox" id="cc-output-enable" name="cascadeControl[output][enabled]" value="true">
|
<input type="checkbox" name="cascadeControl[output][enabled]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.output.enable</span>
|
<span data-i18n>settings.cascadeControl.output.enable</span>
|
||||||
<br />
|
<br />
|
||||||
<small data-i18n>settings.cascadeControl.output.desc</small>
|
<small data-i18n>settings.cascadeControl.output.desc</small>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="cc-output-invert-state">
|
<label>
|
||||||
<input type="checkbox" id="cc-output-invert-state" name="cascadeControl[output][invertState]" value="true">
|
<input type="checkbox" name="cascadeControl[output][invertState]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.output.invertState</span>
|
<span data-i18n>settings.cascadeControl.output.invertState</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label for="cc-output-gpio">
|
<label>
|
||||||
<span data-i18n>settings.cascadeControl.output.gpio</span>
|
<span data-i18n>settings.cascadeControl.output.gpio</span>
|
||||||
<input type="number" outputmode="numeric" id="cc-output-gpio" name="cascadeControl[output][gpio]" min="0" max="254" step="1">
|
<input type="number" outputmode="numeric" name="cascadeControl[output][gpio]" min="0" max="254" step="1">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="cc-output-tt">
|
<label>
|
||||||
<span data-i18n>settings.cascadeControl.output.thresholdTime</span>
|
<span data-i18n>settings.cascadeControl.output.thresholdTime</span>
|
||||||
<input type="number" outputmode="numeric" id="cc-output-tt" name="cascadeControl[output][thresholdTime]" min="5" max="600" step="1" required>
|
<input type="number" outputmode="numeric" name="cascadeControl[output][thresholdTime]" min="5" max="600" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend data-i18n>settings.cascadeControl.output.events.desc</legend>
|
<legend data-i18n>settings.cascadeControl.output.events.desc</legend>
|
||||||
|
|
||||||
<label for="cc-on-fault">
|
<label>
|
||||||
<input type="checkbox" id="cc-on-fault" name="cascadeControl[output][onFault]" value="true">
|
<input type="checkbox" name="cascadeControl[output][onFault]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.output.events.onFault</span>
|
<span data-i18n>settings.cascadeControl.output.events.onFault</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="cc-on-loss-conn">
|
<label>
|
||||||
<input type="checkbox" id="cc-on-loss-conn" name="cascadeControl[output][onLossConnection]" value="true">
|
<input type="checkbox" name="cascadeControl[output][onLossConnection]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.output.events.onLossConnection</span>
|
<span data-i18n>settings.cascadeControl.output.events.onLossConnection</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="cc-on-enabled-heating">
|
<label>
|
||||||
<input type="checkbox" id="cc-on-enabled-heating" name="cascadeControl[output][onEnabledHeating]" value="true">
|
<input type="checkbox" name="cascadeControl[output][onEnabledHeating]" value="true">
|
||||||
<span data-i18n>settings.cascadeControl.output.events.onEnabledHeating</span>
|
<span data-i18n>settings.cascadeControl.output.events.onEnabledHeating</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -671,111 +686,114 @@
|
|||||||
|
|
||||||
const fillData = (data) => {
|
const fillData = (data) => {
|
||||||
// System
|
// System
|
||||||
setSelectValue('#system-log-level', data.system.logLevel);
|
setSelectValue("[name='system[logLevel]']", data.system.logLevel);
|
||||||
setCheckboxValue('#system-serial-enable', data.system.serial.enabled);
|
setCheckboxValue("[name='system[serial][enabled]']", data.system.serial.enabled);
|
||||||
setSelectValue('#system-serial-baudrate', data.system.serial.baudrate);
|
setSelectValue("[name='system[serial][baudrate]']", data.system.serial.baudrate);
|
||||||
setCheckboxValue('#system-telnet-enable', data.system.telnet.enabled);
|
setCheckboxValue("[name='system[telnet][enabled]']", data.system.telnet.enabled);
|
||||||
setInputValue('#system-telnet-port', data.system.telnet.port);
|
setInputValue("[name='system[telnet][port]']", data.system.telnet.port);
|
||||||
setRadioValue('.system-unit-system', data.system.unitSystem);
|
setRadioValue("[name='system[unitSystem]']", data.system.unitSystem);
|
||||||
setInputValue('#system-status-led-gpio', data.system.statusLedGpio < 255 ? data.system.statusLedGpio : '');
|
setInputValue("[name='system[statusLedGpio]']", data.system.statusLedGpio < 255 ? data.system.statusLedGpio : '');
|
||||||
setBusy('#system-settings-busy', '#system-settings', false);
|
setBusy('#system-settings-busy', '#system-settings', false);
|
||||||
|
|
||||||
// Portal
|
// Portal
|
||||||
setCheckboxValue('#portal-auth', data.portal.auth);
|
setCheckboxValue("[name='portal[auth]']", data.portal.auth);
|
||||||
setInputValue('#portal-login', data.portal.login);
|
setInputValue("[name='portal[login]']", data.portal.login);
|
||||||
setInputValue('#portal-password', data.portal.password);
|
setInputValue("[name='portal[password]']", data.portal.password);
|
||||||
setBusy('#portal-settings-busy', '#portal-settings', false);
|
setBusy('#portal-settings-busy', '#portal-settings', false);
|
||||||
|
|
||||||
// Opentherm
|
// Opentherm
|
||||||
setRadioValue('.opentherm-unit-system', data.opentherm.unitSystem);
|
setRadioValue("[name='opentherm[unitSystem]']", data.opentherm.unitSystem);
|
||||||
setInputValue('#opentherm-in-gpio', data.opentherm.inGpio < 255 ? data.opentherm.inGpio : '');
|
setInputValue("[name='opentherm[inGpio]']", data.opentherm.inGpio < 255 ? data.opentherm.inGpio : '');
|
||||||
setInputValue('#opentherm-out-gpio', data.opentherm.outGpio < 255 ? data.opentherm.outGpio : '');
|
setInputValue("[name='opentherm[outGpio]']", data.opentherm.outGpio < 255 ? data.opentherm.outGpio : '');
|
||||||
setInputValue('#opentherm-rx-led-gpio', data.opentherm.rxLedGpio < 255 ? data.opentherm.rxLedGpio : '');
|
setInputValue("[name='opentherm[rxLedGpio]']", data.opentherm.rxLedGpio < 255 ? data.opentherm.rxLedGpio : '');
|
||||||
setInputValue('#opentherm-member-id', data.opentherm.memberId);
|
setInputValue("[name='opentherm[memberId]']", data.opentherm.memberId);
|
||||||
setInputValue('#opentherm-flags', data.opentherm.flags);
|
setInputValue("[name='opentherm[flags]']", data.opentherm.flags);
|
||||||
setInputValue('#opentherm-max-modulation', data.opentherm.maxModulation);
|
setInputValue("[name='opentherm[maxModulation]']", data.opentherm.maxModulation);
|
||||||
setInputValue('#opentherm-min-power', data.opentherm.minPower);
|
setInputValue("[name='opentherm[minPower]']", data.opentherm.minPower);
|
||||||
setInputValue('#opentherm-max-power', data.opentherm.maxPower);
|
setInputValue("[name='opentherm[maxPower]']", data.opentherm.maxPower);
|
||||||
setCheckboxValue('#opentherm-dhw-present', data.opentherm.dhwPresent);
|
setCheckboxValue("[name='opentherm[options][dhwSupport]']", data.opentherm.options.dhwSupport);
|
||||||
setCheckboxValue('#opentherm-sw-mode', data.opentherm.summerWinterMode);
|
setCheckboxValue("[name='opentherm[options][coolingSupport]']", data.opentherm.options.coolingSupport);
|
||||||
setCheckboxValue('#opentherm-heating-ch2-enabled', data.opentherm.heatingCh2Enabled);
|
setCheckboxValue("[name='opentherm[options][summerWinterMode]']", data.opentherm.options.summerWinterMode);
|
||||||
setCheckboxValue('#opentherm-heating-ch1-to-ch2', data.opentherm.heatingCh1ToCh2);
|
setCheckboxValue("[name='opentherm[options][heatingStateToSummerWinterMode]']", data.opentherm.options.heatingStateToSummerWinterMode);
|
||||||
setCheckboxValue('#opentherm-dhw-to-ch2', data.opentherm.dhwToCh2);
|
setCheckboxValue("[name='opentherm[options][ch2AlwaysEnabled]']", data.opentherm.options.ch2AlwaysEnabled);
|
||||||
setCheckboxValue('#opentherm-dhw-blocking', data.opentherm.dhwBlocking);
|
setCheckboxValue("[name='opentherm[options][heatingToCh2]']", data.opentherm.options.heatingToCh2);
|
||||||
setCheckboxValue('#opentherm-sync-modulation-with-heating', data.opentherm.modulationSyncWithHeating);
|
setCheckboxValue("[name='opentherm[options][dhwToCh2]']", data.opentherm.options.dhwToCh2);
|
||||||
setCheckboxValue('#opentherm-get-min-max-temp', data.opentherm.getMinMaxTemp);
|
setCheckboxValue("[name='opentherm[options][dhwBlocking]']", data.opentherm.options.dhwBlocking);
|
||||||
setCheckboxValue('#opentherm-native-heating-control', data.opentherm.nativeHeatingControl);
|
setCheckboxValue("[name='opentherm[options][modulationSyncWithHeating]']", data.opentherm.options.modulationSyncWithHeating);
|
||||||
setCheckboxValue('#opentherm-immergas-fix', data.opentherm.immergasFix);
|
setCheckboxValue("[name='opentherm[options][maxTempSyncWithTargetTemp]']", data.opentherm.options.maxTempSyncWithTargetTemp);
|
||||||
setBusy('#opentherm-settings-busy', '#opentherm-settings', false);
|
setCheckboxValue("[name='opentherm[options][getMinMaxTemp]']", data.opentherm.options.getMinMaxTemp);
|
||||||
|
setCheckboxValue("[name='opentherm[options][nativeHeatingControl]']", data.opentherm.options.nativeHeatingControl);
|
||||||
|
setCheckboxValue("[name='opentherm[options][immergasFix]']", data.opentherm.options.immergasFix);
|
||||||
|
setBusy('#ot-settings-busy', '#ot-settings', false);
|
||||||
|
|
||||||
// MQTT
|
// MQTT
|
||||||
setCheckboxValue('#mqtt-enable', data.mqtt.enabled);
|
setCheckboxValue("[name='mqtt[enabled]']", data.mqtt.enabled);
|
||||||
setCheckboxValue('#mqtt-ha-discovery', data.mqtt.homeAssistantDiscovery);
|
setCheckboxValue("[name='mqtt[homeAssistantDiscovery]']", data.mqtt.homeAssistantDiscovery);
|
||||||
setInputValue('#mqtt-server', data.mqtt.server);
|
setInputValue("[name='mqtt[server]']", data.mqtt.server);
|
||||||
setInputValue('#mqtt-port', data.mqtt.port);
|
setInputValue("[name='mqtt[port]']", data.mqtt.port);
|
||||||
setInputValue('#mqtt-user', data.mqtt.user);
|
setInputValue("[name='mqtt[user]']", data.mqtt.user);
|
||||||
setInputValue('#mqtt-password', data.mqtt.password);
|
setInputValue("[name='mqtt[password]']", data.mqtt.password);
|
||||||
setInputValue('#mqtt-prefix', data.mqtt.prefix);
|
setInputValue("[name='mqtt[prefix]']", data.mqtt.prefix);
|
||||||
setInputValue('#mqtt-interval', data.mqtt.interval);
|
setInputValue("[name='mqtt[interval]']", data.mqtt.interval);
|
||||||
setBusy('#mqtt-settings-busy', '#mqtt-settings', false);
|
setBusy('#mqtt-settings-busy', '#mqtt-settings', false);
|
||||||
|
|
||||||
// Extpump
|
// Extpump
|
||||||
setCheckboxValue('#extpump-use', data.externalPump.use);
|
setCheckboxValue("[name='externalPump[use]']", data.externalPump.use);
|
||||||
setInputValue('#extpump-gpio', data.externalPump.gpio < 255 ? data.externalPump.gpio : '');
|
setInputValue("[name='externalPump[gpio]']", data.externalPump.gpio < 255 ? data.externalPump.gpio : '');
|
||||||
setInputValue('#extpump-pc-time', data.externalPump.postCirculationTime);
|
setInputValue("[name='externalPump[postCirculationTime]']", data.externalPump.postCirculationTime);
|
||||||
setInputValue('#extpump-as-interval', data.externalPump.antiStuckInterval);
|
setInputValue("[name='externalPump[antiStuckInterval]']", data.externalPump.antiStuckInterval);
|
||||||
setInputValue('#extpump-as-time', data.externalPump.antiStuckTime);
|
setInputValue("[name='externalPump[antiStuckTime]']", data.externalPump.antiStuckTime);
|
||||||
setBusy('#extpump-settings-busy', '#extpump-settings', false);
|
setBusy('#extpump-settings-busy', '#extpump-settings', false);
|
||||||
|
|
||||||
// Cascade control
|
// Cascade control
|
||||||
setCheckboxValue('#cc-input-enable', data.cascadeControl.input.enabled);
|
setCheckboxValue("[name='cascadeControl[input][enabled]']", data.cascadeControl.input.enabled);
|
||||||
setInputValue('#cc-input-gpio', data.cascadeControl.input.gpio < 255 ? data.cascadeControl.input.gpio : '');
|
setInputValue("[name='cascadeControl[input][gpio]']", data.cascadeControl.input.gpio < 255 ? data.cascadeControl.input.gpio : '');
|
||||||
setCheckboxValue('#cc-input-invert-state', data.cascadeControl.input.invertState);
|
setCheckboxValue("[name='cascadeControl[input][invertState]']", data.cascadeControl.input.invertState);
|
||||||
setInputValue('#cc-input-tt', data.cascadeControl.input.thresholdTime);
|
setInputValue("[name='cascadeControl[input][thresholdTime]']", data.cascadeControl.input.thresholdTime);
|
||||||
|
|
||||||
setCheckboxValue('#cc-output-enable', data.cascadeControl.output.enabled);
|
setCheckboxValue("[name='cascadeControl[output][enabled]']", data.cascadeControl.output.enabled);
|
||||||
setInputValue('#cc-output-gpio', data.cascadeControl.output.gpio < 255 ? data.cascadeControl.output.gpio : '');
|
setInputValue("[name='cascadeControl[output][gpio]']", data.cascadeControl.output.gpio < 255 ? data.cascadeControl.output.gpio : '');
|
||||||
setCheckboxValue('#cc-output-invert-state', data.cascadeControl.output.invertState);
|
setCheckboxValue("[name='cascadeControl[output][invertState]']", data.cascadeControl.output.invertState);
|
||||||
setInputValue('#cc-output-tt', data.cascadeControl.output.thresholdTime);
|
setInputValue("[name='cascadeControl[output][thresholdTime]']", data.cascadeControl.output.thresholdTime);
|
||||||
setCheckboxValue('#cc-on-fault', data.cascadeControl.output.onFault);
|
setCheckboxValue("[name='cascadeControl[output][onFault]']", data.cascadeControl.output.onFault);
|
||||||
setCheckboxValue('#cc-on-loss-conn', data.cascadeControl.output.onLossConnection);
|
setCheckboxValue("[name='cascadeControl[output][onLossConnection]']", data.cascadeControl.output.onLossConnection);
|
||||||
setCheckboxValue('#cc-on-enabled-heating', data.cascadeControl.output.onEnabledHeating);
|
setCheckboxValue("[name='cascadeControl[output][onEnabledHeating]']", data.cascadeControl.output.onEnabledHeating);
|
||||||
setBusy('#cc-settings-busy', '#cc-settings', false);
|
setBusy('#cc-settings-busy', '#cc-settings', false);
|
||||||
|
|
||||||
// Heating
|
// Heating
|
||||||
setInputValue('#heating-min-temp', data.heating.minTemp, {
|
setInputValue("[name='heating[minTemp]']", data.heating.minTemp, {
|
||||||
"min": data.system.unitSystem == 0 ? 0 : 32,
|
"min": data.system.unitSystem == 0 ? 0 : 32,
|
||||||
"max": data.system.unitSystem == 0 ? 99 : 211
|
"max": data.system.unitSystem == 0 ? 99 : 211
|
||||||
});
|
});
|
||||||
setInputValue('#heating-max-temp', data.heating.maxTemp, {
|
setInputValue("[name='heating[maxTemp]']", data.heating.maxTemp, {
|
||||||
"min": data.system.unitSystem == 0 ? 1 : 33,
|
"min": data.system.unitSystem == 0 ? 1 : 33,
|
||||||
"max": data.system.unitSystem == 0 ? 100 : 212
|
"max": data.system.unitSystem == 0 ? 100 : 212
|
||||||
});
|
});
|
||||||
setInputValue('#heating-hysteresis', data.heating.hysteresis);
|
setInputValue("[name='heating[hysteresis]']", data.heating.hysteresis);
|
||||||
setInputValue('#heating-turbo-factor', data.heating.turboFactor);
|
setInputValue("[name='heating[turboFactor]']", data.heating.turboFactor);
|
||||||
setBusy('#heating-settings-busy', '#heating-settings', false);
|
setBusy('#heating-settings-busy', '#heating-settings', false);
|
||||||
|
|
||||||
// DHW
|
// DHW
|
||||||
setInputValue('#dhw-min-temp', data.dhw.minTemp, {
|
setInputValue("[name='dhw[minTemp]']", data.dhw.minTemp, {
|
||||||
"min": data.system.unitSystem == 0 ? 0 : 32,
|
"min": data.system.unitSystem == 0 ? 0 : 32,
|
||||||
"max": data.system.unitSystem == 0 ? 99 : 211
|
"max": data.system.unitSystem == 0 ? 99 : 211
|
||||||
});
|
});
|
||||||
setInputValue('#dhw-max-temp', data.dhw.maxTemp, {
|
setInputValue("[name='dhw[maxTemp]']", data.dhw.maxTemp, {
|
||||||
"min": data.system.unitSystem == 0 ? 1 : 33,
|
"min": data.system.unitSystem == 0 ? 1 : 33,
|
||||||
"max": data.system.unitSystem == 0 ? 100 : 212
|
"max": data.system.unitSystem == 0 ? 100 : 212
|
||||||
});
|
});
|
||||||
setBusy('#dhw-settings-busy', '#dhw-settings', false);
|
setBusy('#dhw-settings-busy', '#dhw-settings', false);
|
||||||
|
|
||||||
// Emergency mode
|
// Emergency mode
|
||||||
setInputValue('#emergency-treshold-time', data.emergency.tresholdTime);
|
setInputValue("[name='emergency[tresholdTime]']", data.emergency.tresholdTime);
|
||||||
if (data.opentherm.nativeHeatingControl) {
|
if (data.opentherm.options.nativeHeatingControl) {
|
||||||
setInputValue('#emergency-target', data.emergency.target, {
|
setInputValue("[name='emergency[target]']", data.emergency.target, {
|
||||||
"min": data.system.unitSystem == 0 ? 5 : 41,
|
"min": data.system.unitSystem == 0 ? 5 : 41,
|
||||||
"max": data.system.unitSystem == 0 ? 30 : 86
|
"max": data.system.unitSystem == 0 ? 30 : 86
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setInputValue('#emergency-target', data.emergency.target, {
|
setInputValue("[name='emergency[target]']", data.emergency.target, {
|
||||||
"min": data.heating.minTemp,
|
"min": data.heating.minTemp,
|
||||||
"max": data.heating.maxTemp,
|
"max": data.heating.maxTemp,
|
||||||
});
|
});
|
||||||
@@ -784,23 +802,23 @@
|
|||||||
setBusy('#emergency-settings-busy', '#emergency-settings', false);
|
setBusy('#emergency-settings-busy', '#emergency-settings', false);
|
||||||
|
|
||||||
// Equitherm
|
// Equitherm
|
||||||
setCheckboxValue('#equitherm-enable', data.equitherm.enabled);
|
setCheckboxValue("[name='equitherm[enabled]']", data.equitherm.enabled);
|
||||||
setInputValue('#equitherm-n-factor', data.equitherm.n_factor);
|
setInputValue("[name='equitherm[n_factor]']", data.equitherm.n_factor);
|
||||||
setInputValue('#equitherm-k-factor', data.equitherm.k_factor);
|
setInputValue("[name='equitherm[k_factor]']", data.equitherm.k_factor);
|
||||||
setInputValue('#equitherm-t-factor', data.equitherm.t_factor);
|
setInputValue("[name='equitherm[t_factor]']", data.equitherm.t_factor);
|
||||||
setBusy('#equitherm-settings-busy', '#equitherm-settings', false);
|
setBusy('#equitherm-settings-busy', '#equitherm-settings', false);
|
||||||
|
|
||||||
// PID
|
// PID
|
||||||
setCheckboxValue('#pid-enable', data.pid.enabled);
|
setCheckboxValue("[name='pid[enabled]']", data.pid.enabled);
|
||||||
setInputValue('#pid-p-factor', data.pid.p_factor);
|
setInputValue("[name='pid[p_factor]']", data.pid.p_factor);
|
||||||
setInputValue('#pid-i-factor', data.pid.i_factor);
|
setInputValue("[name='pid[i_factor]']", data.pid.i_factor);
|
||||||
setInputValue('#pid-d-factor', data.pid.d_factor);
|
setInputValue("[name='pid[d_factor]']", data.pid.d_factor);
|
||||||
setInputValue('#pid-dt', data.pid.dt);
|
setInputValue("[name='pid[dt]']", data.pid.dt);
|
||||||
setInputValue('#pid-min-temp', data.pid.minTemp, {
|
setInputValue("[name='pid[minTemp]']", data.pid.minTemp, {
|
||||||
"min": data.equitherm.enabled ? (data.system.unitSystem == 0 ? -100 : -146) : (data.system.unitSystem == 0 ? 0 : 32),
|
"min": data.equitherm.enabled ? (data.system.unitSystem == 0 ? -100 : -146) : (data.system.unitSystem == 0 ? 0 : 32),
|
||||||
"max": (data.system.unitSystem == 0 ? 99 : 211)
|
"max": (data.system.unitSystem == 0 ? 99 : 211)
|
||||||
});
|
});
|
||||||
setInputValue('#pid-max-temp', data.pid.maxTemp, {
|
setInputValue("[name='pid[maxTemp]']", data.pid.maxTemp, {
|
||||||
"min": (data.system.unitSystem == 0 ? 0 : 33),
|
"min": (data.system.unitSystem == 0 ? 0 : 33),
|
||||||
"max": (data.system.unitSystem == 0 ? 100 : 212)
|
"max": (data.system.unitSystem == 0 ? 100 : 212)
|
||||||
});
|
});
|
||||||
@@ -827,7 +845,7 @@
|
|||||||
setupForm('#emergency-settings', fillData);
|
setupForm('#emergency-settings', fillData);
|
||||||
setupForm('#equitherm-settings', fillData);
|
setupForm('#equitherm-settings', fillData);
|
||||||
setupForm('#pid-settings', fillData);
|
setupForm('#pid-settings', fillData);
|
||||||
setupForm('#opentherm-settings', fillData);
|
setupForm('#ot-settings', fillData);
|
||||||
setupForm('#mqtt-settings', fillData, ['mqtt.user', 'mqtt.password', 'mqtt.prefix']);
|
setupForm('#mqtt-settings', fillData, ['mqtt.user', 'mqtt.password', 'mqtt.prefix']);
|
||||||
setupForm('#extpump-settings', fillData);
|
setupForm('#extpump-settings', fillData);
|
||||||
setupForm('#cc-settings', fillData);
|
setupForm('#cc-settings', fillData);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<input type="file" name="settings" id="restore-file" accept=".json">
|
<input type="file" name="settings" id="restore-file" accept=".json">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="grid">
|
<div role="group">
|
||||||
<button type="submit" data-i18n>button.restore</button>
|
<button type="submit" data-i18n>button.restore</button>
|
||||||
<button type="button" class="secondary" onclick="window.location='/api/backup/save';" data-i18n>button.backup</button>
|
<button type="button" class="secondary" onclick="window.location='/api/backup/save';" data-i18n>button.backup</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ tr.network:hover {
|
|||||||
font-family: var(--pico-font-family-monospace);
|
font-family: var(--pico-font-family-monospace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.thermostat {
|
.thermostat {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 0.5fr 2fr 0.5fr;
|
grid-template-columns: 0.5fr 2fr 0.5fr;
|
||||||
@@ -193,6 +194,92 @@ tr.network:hover {
|
|||||||
margin: 1.25rem 0;
|
margin: 1.25rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 575px) {
|
||||||
|
.notify {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: 1fr 0.5fr;
|
||||||
|
gap: 0.5rem 0.5rem;
|
||||||
|
grid-template-areas:
|
||||||
|
"notify-content"
|
||||||
|
"notify-actions";
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-content {
|
||||||
|
justify-self: center;
|
||||||
|
align-self: center;
|
||||||
|
grid-area: notify-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-actions {
|
||||||
|
justify-self: center;
|
||||||
|
align-self: center;
|
||||||
|
grid-area: notify-actions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
.notify {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 5rem 1fr 10rem;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
gap: 0rem 0.5rem;
|
||||||
|
grid-auto-flow: row;
|
||||||
|
grid-template-areas:
|
||||||
|
"notify-icon notify-content notify-actions";
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-icon {
|
||||||
|
justify-self: center;
|
||||||
|
align-self: center;
|
||||||
|
grid-area: notify-icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-content {
|
||||||
|
justify-self: center;
|
||||||
|
align-self: center;
|
||||||
|
grid-area: notify-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-actions {
|
||||||
|
justify-self: center;
|
||||||
|
align-self: center;
|
||||||
|
grid-area: notify-actions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify {
|
||||||
|
margin: 1rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border: .25rem solid var(--pico-blockquote-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-error {
|
||||||
|
border-color: var(--pico-form-element-invalid-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-error .notify-icon {
|
||||||
|
color: var(--pico-form-element-invalid-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-alarm {
|
||||||
|
border-color: #c89048;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-alarm .notify-icon {
|
||||||
|
color: #c89048;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-icon i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[class*=" icons-"],
|
[class*=" icons-"],
|
||||||
[class=icons],
|
[class=icons],
|
||||||
[class^=icons-] {
|
[class^=icons-] {
|
||||||
|
|||||||