mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-12 11:14:28 +05:00
Compare commits
14 Commits
1.4.0-rc.1
...
1.4.0-rc.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cbc52a8b0 | ||
|
|
e090be380c | ||
|
|
0bf49d2249 | ||
|
|
a83d94d361 | ||
|
|
358980da4c | ||
|
|
f91e39d067 | ||
|
|
1d53f21d46 | ||
|
|
c225e7c2a8 | ||
|
|
6831c4331f | ||
|
|
8fb62ce8ae | ||
|
|
e829a00355 | ||
|
|
bee720386a | ||
|
|
c4b6eadb81 | ||
|
|
a5d2b9fcfa |
@@ -16,7 +16,7 @@
|
|||||||
- 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](#compatible-temperature-sensors))
|
- Ability to connect an external sensors to monitor outdoor and indoor temperature ([compatible sensors](https://github.com/Laxilef/OTGateway/wiki/Compatibility#temperature-sensors))
|
||||||
- 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. 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).
|
||||||
- Automatic error reset (not with all boilers)
|
- Automatic error reset (not with all boilers)
|
||||||
- Diagnostics:
|
- Diagnostics:
|
||||||
@@ -72,7 +72,7 @@ All available information and instructions can be found in the wiki:
|
|||||||
- [ESP32Scheduler](https://github.com/laxilef/ESP32Scheduler) (for ESP32)
|
- [ESP32Scheduler](https://github.com/laxilef/ESP32Scheduler) (for ESP32)
|
||||||
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
|
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
|
||||||
- [OpenTherm Library](https://github.com/ihormelnyk/opentherm_library)
|
- [OpenTherm Library](https://github.com/ihormelnyk/opentherm_library)
|
||||||
- [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient) /
|
- [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient)
|
||||||
- [ESPTelnet](https://github.com/LennartHennigs/ESPTelnet)
|
- [ESPTelnet](https://github.com/LennartHennigs/ESPTelnet)
|
||||||
- [FileData](https://github.com/GyverLibs/FileData)
|
- [FileData](https://github.com/GyverLibs/FileData)
|
||||||
- [GyverPID](https://github.com/GyverLibs/GyverPID)
|
- [GyverPID](https://github.com/GyverLibs/GyverPID)
|
||||||
|
|||||||
@@ -210,7 +210,7 @@
|
|||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/issue" target="_blank" class="secondary">Issue & questions</a>
|
• <a href="https://github.com/Laxilef/OTGateway/issues" target="_blank" class="secondary">Issue & questions</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
||||||
</small>
|
</small>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -145,7 +145,7 @@
|
|||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/issue" target="_blank" class="secondary">Issue & questions</a>
|
• <a href="https://github.com/Laxilef/OTGateway/issues" target="_blank" class="secondary">Issue & questions</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
||||||
</small>
|
</small>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -333,7 +333,7 @@
|
|||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/issue" target="_blank" class="secondary">Issue & questions</a>
|
• <a href="https://github.com/Laxilef/OTGateway/issues" target="_blank" class="secondary">Issue & questions</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
||||||
</small>
|
</small>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/LICENSE" target="_blank" class="secondary">License</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
• <a href="https://github.com/Laxilef/OTGateway/blob/master/" target="_blank" class="secondary">Source code</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
• <a href="https://github.com/Laxilef/OTGateway/wiki" target="_blank" class="secondary">Help</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/issue" target="_blank" class="secondary">Issue & questions</a>
|
• <a href="https://github.com/Laxilef/OTGateway/issues" target="_blank" class="secondary">Issue & questions</a>
|
||||||
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
• <a href="https://github.com/Laxilef/OTGateway/releases" target="_blank" class="secondary">Releases</a>
|
||||||
</small>
|
</small>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
float Kk = 0.0;
|
float Kk = 0.0;
|
||||||
float Kt = 0.0;
|
float Kt = 0.0;
|
||||||
|
|
||||||
Equitherm() {}
|
Equitherm() = default;
|
||||||
|
|
||||||
// kn, kk, kt
|
// kn, kk, kt
|
||||||
Equitherm(float new_kn, float new_kk, float new_kt) {
|
Equitherm(float new_kn, float new_kk, float new_kt) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class HomeAssistantHelper {
|
|||||||
public:
|
public:
|
||||||
typedef std::function<void(const char*, bool)> PublishEventCallback;
|
typedef std::function<void(const char*, bool)> PublishEventCallback;
|
||||||
|
|
||||||
HomeAssistantHelper() {}
|
HomeAssistantHelper() = default;
|
||||||
|
|
||||||
void setWriter() {
|
void setWriter() {
|
||||||
this->writer = nullptr;
|
this->writer = nullptr;
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ public:
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
sizeArgName = length - size_t(argStartPos - currentBuf) - 1;
|
sizeArgName = length - size_t(argStartPos - currentBuf) - 1;
|
||||||
Serial.printf("sizeArgName: %d\r\n", sizeArgName);
|
|
||||||
|
|
||||||
// send all content if arg len > space
|
// send all content if arg len > space
|
||||||
if (sizeArgName >= sizeof(argName)) {
|
if (sizeArgName >= sizeof(argName)) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ monitor_speed = 115200
|
|||||||
monitor_filters = direct
|
monitor_filters = direct
|
||||||
board_build.flash_mode = dio
|
board_build.flash_mode = dio
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
version = 1.4.0-rc.14
|
version = 1.4.0-rc.16
|
||||||
|
|
||||||
; Defaults
|
; Defaults
|
||||||
[esp8266_defaults]
|
[esp8266_defaults]
|
||||||
|
|||||||
139
src/HaHelper.h
139
src/HaHelper.h
@@ -6,59 +6,6 @@ public:
|
|||||||
static const byte TEMP_SOURCE_HEATING = 0;
|
static const byte TEMP_SOURCE_HEATING = 0;
|
||||||
static const byte TEMP_SOURCE_INDOOR = 1;
|
static const byte TEMP_SOURCE_INDOOR = 1;
|
||||||
|
|
||||||
bool publishNumberOutdoorSensorOffset(bool enabledByDefault = true) {
|
|
||||||
JsonDocument doc;
|
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("settings"));
|
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.sensors.outdoor.type != 1, 'online', 'offline') }}");
|
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("outdoor_sensor_offset"));
|
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("outdoor_sensor_offset"));
|
|
||||||
doc[FPSTR(HA_ENTITY_CATEGORY)] = F("config");
|
|
||||||
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature");
|
|
||||||
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("°C");
|
|
||||||
doc[FPSTR(HA_NAME)] = F("Outdoor sensor offset");
|
|
||||||
doc[FPSTR(HA_ICON)] = F("mdi:altimeter");
|
|
||||||
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("settings"));
|
|
||||||
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.sensors.outdoor.offset|float(0)|round(2) }}");
|
|
||||||
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("settings/set"));
|
|
||||||
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"sensors\": {\"outdoor\" : {\"offset\" : {{ value }}}}}");
|
|
||||||
doc[FPSTR(HA_MIN)] = -10;
|
|
||||||
doc[FPSTR(HA_MAX)] = 10;
|
|
||||||
doc[FPSTR(HA_STEP)] = 0.1;
|
|
||||||
doc[FPSTR(HA_MODE)] = "box";
|
|
||||||
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
|
||||||
doc.shrinkToFit();
|
|
||||||
|
|
||||||
return this->publish(this->getTopic(FPSTR(HA_ENTITY_NUMBER), F("outdoor_sensor_offset")).c_str(), doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool publishNumberIndoorSensorOffset(bool enabledByDefault = true) {
|
|
||||||
JsonDocument doc;
|
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("settings"));
|
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.sensors.indoor.type != 1, 'online', 'offline') }}");
|
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("indoor_sensor_offset"));
|
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("indoor_sensor_offset"));
|
|
||||||
doc[FPSTR(HA_ENTITY_CATEGORY)] = F("config");
|
|
||||||
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature");
|
|
||||||
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("°C");
|
|
||||||
doc[FPSTR(HA_NAME)] = F("Indoor sensor offset");
|
|
||||||
doc[FPSTR(HA_ICON)] = F("mdi:altimeter");
|
|
||||||
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("settings"));
|
|
||||||
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.sensors.indoor.offset|float(0)|round(2) }}");
|
|
||||||
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("settings/set"));
|
|
||||||
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"sensors\": {\"indoor\" : {\"offset\" : {{ value }}}}}");
|
|
||||||
doc[FPSTR(HA_MIN)] = -10;
|
|
||||||
doc[FPSTR(HA_MAX)] = 10;
|
|
||||||
doc[FPSTR(HA_STEP)] = 0.1;
|
|
||||||
doc[FPSTR(HA_MODE)] = "box";
|
|
||||||
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
|
||||||
doc.shrinkToFit();
|
|
||||||
|
|
||||||
return this->publish(this->getTopic(FPSTR(HA_ENTITY_NUMBER), F("indoor_sensor_offset")).c_str(), doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool publishSwitchEmergency(bool enabledByDefault = true) {
|
bool publishSwitchEmergency(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
@@ -266,7 +213,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorBoilerHeatingMinTemp(bool enabledByDefault = true) {
|
bool publishSensorBoilerHeatingMinTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("boiler_heating_min_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("boiler_heating_min_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_heating_min_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_heating_min_temp"));
|
||||||
@@ -286,7 +236,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorBoilerHeatingMaxTemp(bool enabledByDefault = true) {
|
bool publishSensorBoilerHeatingMaxTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("boiler_heating_max_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("boiler_heating_max_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_heating_max_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_heating_max_temp"));
|
||||||
@@ -415,7 +368,7 @@ public:
|
|||||||
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("settings/set"));
|
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("settings/set"));
|
||||||
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"dhw\": {\"target\" : {{ value|int(0) }}}}");
|
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"dhw\": {\"target\" : {{ value|int(0) }}}}");
|
||||||
doc[FPSTR(HA_MIN)] = minTemp;
|
doc[FPSTR(HA_MIN)] = minTemp;
|
||||||
doc[FPSTR(HA_MAX)] = maxTemp <= minTemp ? maxTemp : maxTemp;
|
doc[FPSTR(HA_MAX)] = maxTemp > minTemp ? maxTemp : minTemp;
|
||||||
doc[FPSTR(HA_STEP)] = 1;
|
doc[FPSTR(HA_STEP)] = 1;
|
||||||
doc[FPSTR(HA_MODE)] = "box";
|
doc[FPSTR(HA_MODE)] = "box";
|
||||||
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
||||||
@@ -426,7 +379,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorBoilerDhwMinTemp(bool enabledByDefault = true) {
|
bool publishSensorBoilerDhwMinTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("boiler_dhw_min_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("boiler_dhw_min_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_dhw_min_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_dhw_min_temp"));
|
||||||
@@ -446,7 +402,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorBoilerDhwMaxTemp(bool enabledByDefault = true) {
|
bool publishSensorBoilerDhwMaxTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("boiler_dhw_max_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("boiler_dhw_max_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_dhw_max_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("boiler_dhw_max_temp"));
|
||||||
@@ -780,7 +739,6 @@ public:
|
|||||||
bool publishSelectTuningRegulator(bool enabledByDefault = true) {
|
bool publishSelectTuningRegulator(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
|
||||||
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("state/set"));
|
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("state/set"));
|
||||||
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"tuning\": {\"regulator\": {% if value == 'Equitherm' %}0{% elif value == 'PID' %}1{% endif %}}}");
|
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"tuning\": {\"regulator\": {% if value == 'Equitherm' %}0{% elif value == 'PID' %}1{% endif %}}}");
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
@@ -835,7 +793,10 @@ public:
|
|||||||
|
|
||||||
bool publishBinSensorHeating(bool enabledByDefault = true) {
|
bool publishBinSensorHeating(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("heating"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("heating"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("heating"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("heating"));
|
||||||
@@ -853,7 +814,10 @@ public:
|
|||||||
|
|
||||||
bool publishBinSensorDhw(bool enabledByDefault = true) {
|
bool publishBinSensorDhw(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("dhw"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("dhw"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw"));
|
||||||
@@ -871,7 +835,10 @@ public:
|
|||||||
|
|
||||||
bool publishBinSensorFlame(bool enabledByDefault = true) {
|
bool publishBinSensorFlame(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("flame"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("flame"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("flame"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("flame"));
|
||||||
@@ -889,8 +856,10 @@ public:
|
|||||||
|
|
||||||
bool publishBinSensorFault(bool enabledByDefault = true) {
|
bool publishBinSensorFault(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("fault"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("fault"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("fault"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("fault"));
|
||||||
@@ -908,7 +877,10 @@ public:
|
|||||||
|
|
||||||
bool publishBinSensorDiagnostic(bool enabledByDefault = true) {
|
bool publishBinSensorDiagnostic(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("diagnostic"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("diagnostic"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("diagnostic"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("diagnostic"));
|
||||||
@@ -926,8 +898,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorFaultCode(bool enabledByDefault = true) {
|
bool publishSensorFaultCode(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.fault, 'online', 'offline') }}");
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus and value_json.states.fault, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("fault_code"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("fault_code"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("fault_code"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("fault_code"));
|
||||||
@@ -985,7 +959,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorModulation(bool enabledByDefault = true) {
|
bool publishSensorModulation(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("modulation_level"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("modulation_level"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("modulation_level"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("modulation_level"));
|
||||||
@@ -1005,7 +982,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorPressure(bool enabledByDefault = true) {
|
bool publishSensorPressure(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("pressure"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("pressure"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("pressure"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("pressure"));
|
||||||
@@ -1025,7 +1005,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorDhwFlowRate(bool enabledByDefault = true) {
|
bool publishSensorDhwFlowRate(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("dhw_flow_rate"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("dhw_flow_rate"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw_flow_rate"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw_flow_rate"));
|
||||||
@@ -1069,8 +1052,7 @@ public:
|
|||||||
|
|
||||||
bool publishSensorIndoorTemp(bool enabledByDefault = true) {
|
bool publishSensorIndoorTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("any");
|
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("indoor_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("indoor_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("indoor_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("indoor_temp"));
|
||||||
@@ -1113,8 +1095,7 @@ public:
|
|||||||
|
|
||||||
bool publishSensorOutdoorTemp(bool enabledByDefault = true) {
|
bool publishSensorOutdoorTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("any");
|
|
||||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("outdoor_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("outdoor_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("outdoor_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("outdoor_temp"));
|
||||||
@@ -1134,7 +1115,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorHeatingTemp(bool enabledByDefault = true) {
|
bool publishSensorHeatingTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("heating_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("heating_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("heating_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("heating_temp"));
|
||||||
@@ -1154,7 +1138,10 @@ public:
|
|||||||
|
|
||||||
bool publishSensorDhwTemp(bool enabledByDefault = true) {
|
bool publishSensorDhwTemp(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
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->getObjectId(F("dhw_temp"));
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("dhw_temp"));
|
||||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw_temp"));
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw_temp"));
|
||||||
|
|||||||
@@ -20,14 +20,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~MainTask() {
|
~MainTask() {
|
||||||
if (this->blinker != nullptr) {
|
|
||||||
delete this->blinker;
|
delete this->blinker;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const static byte REASON_PUMP_START_HEATING = 1;
|
enum class PumpStartReason {NONE, HEATING, ANTISTUCK};
|
||||||
const static byte REASON_PUMP_START_ANTISTUCK = 2;
|
|
||||||
|
|
||||||
Blinker* blinker = nullptr;
|
Blinker* blinker = nullptr;
|
||||||
bool blinkerInitialized = false;
|
bool blinkerInitialized = false;
|
||||||
@@ -38,7 +35,7 @@ protected:
|
|||||||
unsigned long restartSignalTime = 0;
|
unsigned long restartSignalTime = 0;
|
||||||
bool heatingEnabled = false;
|
bool heatingEnabled = false;
|
||||||
unsigned long heatingDisabledTime = 0;
|
unsigned long heatingDisabledTime = 0;
|
||||||
byte externalPumpStartReason;
|
PumpStartReason extPumpStartReason = PumpStartReason::NONE;
|
||||||
unsigned long externalPumpStartTime = 0;
|
unsigned long externalPumpStartTime = 0;
|
||||||
bool telnetStarted = false;
|
bool telnetStarted = false;
|
||||||
|
|
||||||
@@ -57,12 +54,12 @@ protected:
|
|||||||
void setup() {
|
void setup() {
|
||||||
#ifdef LED_STATUS_PIN
|
#ifdef LED_STATUS_PIN
|
||||||
pinMode(LED_STATUS_PIN, OUTPUT);
|
pinMode(LED_STATUS_PIN, OUTPUT);
|
||||||
digitalWrite(LED_STATUS_PIN, false);
|
digitalWrite(LED_STATUS_PIN, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (settings.externalPump.pin != 0) {
|
if (settings.externalPump.pin != 0) {
|
||||||
pinMode(settings.externalPump.pin, OUTPUT);
|
pinMode(settings.externalPump.pin, OUTPUT);
|
||||||
digitalWrite(settings.externalPump.pin, false);
|
digitalWrite(settings.externalPump.pin, LOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,14 +247,14 @@ protected:
|
|||||||
if (!this->blinker->running() && millis() - endBlinkTime >= 5000) {
|
if (!this->blinker->running() && millis() - endBlinkTime >= 5000) {
|
||||||
if (errCount == 0) {
|
if (errCount == 0) {
|
||||||
if (!ledOn) {
|
if (!ledOn) {
|
||||||
digitalWrite(ledPin, true);
|
digitalWrite(ledPin, HIGH);
|
||||||
ledOn = true;
|
ledOn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (ledOn) {
|
} else if (ledOn) {
|
||||||
digitalWrite(ledPin, false);
|
digitalWrite(ledPin, LOW);
|
||||||
ledOn = false;
|
ledOn = false;
|
||||||
endBlinkTime = millis();
|
endBlinkTime = millis();
|
||||||
return;
|
return;
|
||||||
@@ -289,7 +286,7 @@ protected:
|
|||||||
if (!settings.externalPump.use || settings.externalPump.pin == 0) {
|
if (!settings.externalPump.use || settings.externalPump.pin == 0) {
|
||||||
if (vars.states.externalPump) {
|
if (vars.states.externalPump) {
|
||||||
if (settings.externalPump.pin != 0) {
|
if (settings.externalPump.pin != 0) {
|
||||||
digitalWrite(settings.externalPump.pin, false);
|
digitalWrite(settings.externalPump.pin, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.states.externalPump = false;
|
vars.states.externalPump = false;
|
||||||
@@ -302,16 +299,16 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vars.states.externalPump && !this->heatingEnabled) {
|
if (vars.states.externalPump && !this->heatingEnabled) {
|
||||||
if (this->externalPumpStartReason == MainTask::REASON_PUMP_START_HEATING && millis() - this->heatingDisabledTime > (settings.externalPump.postCirculationTime * 1000u)) {
|
if (this->extPumpStartReason == MainTask::PumpStartReason::HEATING && millis() - this->heatingDisabledTime > (settings.externalPump.postCirculationTime * 1000u)) {
|
||||||
digitalWrite(settings.externalPump.pin, false);
|
digitalWrite(settings.externalPump.pin, LOW);
|
||||||
|
|
||||||
vars.states.externalPump = false;
|
vars.states.externalPump = false;
|
||||||
vars.parameters.extPumpLastEnableTime = millis();
|
vars.parameters.extPumpLastEnableTime = millis();
|
||||||
|
|
||||||
Log.sinfoln("EXTPUMP", F("Disabled: expired post circulation time"));
|
Log.sinfoln("EXTPUMP", F("Disabled: expired post circulation time"));
|
||||||
|
|
||||||
} else if (this->externalPumpStartReason == MainTask::REASON_PUMP_START_ANTISTUCK && millis() - this->externalPumpStartTime >= (settings.externalPump.antiStuckTime * 1000u)) {
|
} else if (this->extPumpStartReason == MainTask::PumpStartReason::ANTISTUCK && millis() - this->externalPumpStartTime >= (settings.externalPump.antiStuckTime * 1000u)) {
|
||||||
digitalWrite(settings.externalPump.pin, false);
|
digitalWrite(settings.externalPump.pin, LOW);
|
||||||
|
|
||||||
vars.states.externalPump = false;
|
vars.states.externalPump = false;
|
||||||
vars.parameters.extPumpLastEnableTime = millis();
|
vars.parameters.extPumpLastEnableTime = millis();
|
||||||
@@ -319,24 +316,24 @@ protected:
|
|||||||
Log.sinfoln("EXTPUMP", F("Disabled: expired anti stuck time"));
|
Log.sinfoln("EXTPUMP", F("Disabled: expired anti stuck time"));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (vars.states.externalPump && this->heatingEnabled && this->externalPumpStartReason == MainTask::REASON_PUMP_START_ANTISTUCK) {
|
} else if (vars.states.externalPump && this->heatingEnabled && this->extPumpStartReason == MainTask::PumpStartReason::ANTISTUCK) {
|
||||||
this->externalPumpStartReason = MainTask::REASON_PUMP_START_HEATING;
|
this->extPumpStartReason = MainTask::PumpStartReason::HEATING;
|
||||||
|
|
||||||
} else if (!vars.states.externalPump && this->heatingEnabled) {
|
} else if (!vars.states.externalPump && this->heatingEnabled) {
|
||||||
vars.states.externalPump = true;
|
vars.states.externalPump = true;
|
||||||
this->externalPumpStartTime = millis();
|
this->externalPumpStartTime = millis();
|
||||||
this->externalPumpStartReason = MainTask::REASON_PUMP_START_HEATING;
|
this->extPumpStartReason = MainTask::PumpStartReason::HEATING;
|
||||||
|
|
||||||
digitalWrite(settings.externalPump.pin, true);
|
digitalWrite(settings.externalPump.pin, HIGH);
|
||||||
|
|
||||||
Log.sinfoln("EXTPUMP", F("Enabled: heating on"));
|
Log.sinfoln("EXTPUMP", F("Enabled: heating on"));
|
||||||
|
|
||||||
} else if (!vars.states.externalPump && (vars.parameters.extPumpLastEnableTime == 0 || millis() - vars.parameters.extPumpLastEnableTime >= (settings.externalPump.antiStuckInterval * 1000ul))) {
|
} else if (!vars.states.externalPump && (vars.parameters.extPumpLastEnableTime == 0 || millis() - vars.parameters.extPumpLastEnableTime >= (settings.externalPump.antiStuckInterval * 1000ul))) {
|
||||||
vars.states.externalPump = true;
|
vars.states.externalPump = true;
|
||||||
this->externalPumpStartTime = millis();
|
this->externalPumpStartTime = millis();
|
||||||
this->externalPumpStartReason = MainTask::REASON_PUMP_START_ANTISTUCK;
|
this->extPumpStartReason = MainTask::PumpStartReason::ANTISTUCK;
|
||||||
|
|
||||||
digitalWrite(settings.externalPump.pin, true);
|
digitalWrite(settings.externalPump.pin, HIGH);
|
||||||
|
|
||||||
Log.sinfoln("EXTPUMP", F("Enabled: anti stuck"));
|
Log.sinfoln("EXTPUMP", F("Enabled: anti stuck"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~MqttTask() {
|
~MqttTask() {
|
||||||
if (this->haHelper != nullptr) {
|
|
||||||
delete this->haHelper;
|
delete this->haHelper;
|
||||||
}
|
|
||||||
|
|
||||||
if (this->client != nullptr) {
|
if (this->client != nullptr) {
|
||||||
if (this->client->connected()) {
|
if (this->client->connected()) {
|
||||||
@@ -27,14 +25,9 @@ public:
|
|||||||
delete this->client;
|
delete this->client;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->writer != nullptr) {
|
|
||||||
delete this->writer;
|
delete this->writer;
|
||||||
}
|
|
||||||
|
|
||||||
if (this->wifiClient != nullptr) {
|
|
||||||
delete this->wifiClient;
|
delete this->wifiClient;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void disable() {
|
void disable() {
|
||||||
this->client->stop();
|
this->client->stop();
|
||||||
@@ -208,12 +201,7 @@ protected:
|
|||||||
|
|
||||||
// publish variables and status
|
// publish variables and status
|
||||||
if (this->newConnection || millis() - this->prevPubVarsTime > (settings.mqtt.interval * 1000u)) {
|
if (this->newConnection || millis() - this->prevPubVarsTime > (settings.mqtt.interval * 1000u)) {
|
||||||
this->writer->publish(
|
this->writer->publish(this->haHelper->getDeviceTopic("status").c_str(), "online", false);
|
||||||
this->haHelper->getDeviceTopic("status").c_str(),
|
|
||||||
!vars.states.otStatus ? "offline" : vars.states.fault ? "fault" : "online",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
this->publishVariables(this->haHelper->getDeviceTopic("state").c_str());
|
this->publishVariables(this->haHelper->getDeviceTopic("state").c_str());
|
||||||
this->prevPubVarsTime = millis();
|
this->prevPubVarsTime = millis();
|
||||||
}
|
}
|
||||||
@@ -328,10 +316,6 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publishHaEntities() {
|
void publishHaEntities() {
|
||||||
// main
|
|
||||||
this->haHelper->publishNumberOutdoorSensorOffset(false);
|
|
||||||
this->haHelper->publishNumberIndoorSensorOffset(false);
|
|
||||||
|
|
||||||
// emergency
|
// emergency
|
||||||
this->haHelper->publishSwitchEmergency();
|
this->haHelper->publishSwitchEmergency();
|
||||||
this->haHelper->publishNumberEmergencyTarget();
|
this->haHelper->publishNumberEmergencyTarget();
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ protected:
|
|||||||
|
|
||||||
#ifdef LED_OT_RX_PIN
|
#ifdef LED_OT_RX_PIN
|
||||||
{
|
{
|
||||||
digitalWrite(LED_OT_RX_PIN, true);
|
digitalWrite(LED_OT_RX_PIN, HIGH);
|
||||||
delayMicroseconds(2000);
|
delayMicroseconds(2000);
|
||||||
digitalWrite(LED_OT_RX_PIN, false);
|
digitalWrite(LED_OT_RX_PIN, LOW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ protected:
|
|||||||
|
|
||||||
#ifdef LED_OT_RX_PIN
|
#ifdef LED_OT_RX_PIN
|
||||||
pinMode(LED_OT_RX_PIN, OUTPUT);
|
pinMode(LED_OT_RX_PIN, OUTPUT);
|
||||||
digitalWrite(LED_OT_RX_PIN, false);
|
digitalWrite(LED_OT_RX_PIN, LOW);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~PortalTask() {
|
~PortalTask() {
|
||||||
if (this->bufferedWebServer != nullptr) {
|
|
||||||
delete this->bufferedWebServer;
|
delete this->bufferedWebServer;
|
||||||
}
|
|
||||||
|
|
||||||
if (this->webServer != nullptr) {
|
if (this->webServer != nullptr) {
|
||||||
this->stopWebServer();
|
this->stopWebServer();
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ protected:
|
|||||||
if (vars.parameters.heatingEnabled) {
|
if (vars.parameters.heatingEnabled) {
|
||||||
float pidResult = getPidTemp(
|
float pidResult = getPidTemp(
|
||||||
settings.equitherm.enable ? (settings.pid.maxTemp * -1) : settings.pid.minTemp,
|
settings.equitherm.enable ? (settings.pid.maxTemp * -1) : settings.pid.minTemp,
|
||||||
settings.equitherm.enable ? settings.pid.maxTemp : settings.pid.maxTemp
|
settings.pid.maxTemp
|
||||||
);
|
);
|
||||||
|
|
||||||
if (fabs(prevPidResult - pidResult) + 0.0001 >= 0.5) {
|
if (fabs(prevPidResult - pidResult) + 0.0001 >= 0.5) {
|
||||||
|
|||||||
@@ -3,13 +3,6 @@
|
|||||||
|
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
#include <NimBLEDevice.h>
|
#include <NimBLEDevice.h>
|
||||||
|
|
||||||
// BLE services and characterstics that we are interested in
|
|
||||||
const uint16_t bleUuidServiceBattery = 0x180F;
|
|
||||||
const uint16_t bleUuidServiceEnvironment = 0x181AU;
|
|
||||||
const uint16_t bleUuidCharacteristicBatteryLevel = 0x2A19;
|
|
||||||
const uint16_t bleUuidCharacteristicTemperature = 0x2A6E;
|
|
||||||
const uint16_t bleUuidCharacteristicHumidity = 0x2A6F;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class SensorsTask : public LeanTask {
|
class SensorsTask : public LeanTask {
|
||||||
@@ -25,22 +18,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~SensorsTask() {
|
~SensorsTask() {
|
||||||
if (this->outdoorSensor != nullptr) {
|
|
||||||
delete this->outdoorSensor;
|
delete this->outdoorSensor;
|
||||||
}
|
|
||||||
|
|
||||||
if (this->oneWireOutdoorSensor != nullptr) {
|
|
||||||
delete this->oneWireOutdoorSensor;
|
delete this->oneWireOutdoorSensor;
|
||||||
}
|
|
||||||
|
|
||||||
if (this->indoorSensor != nullptr) {
|
|
||||||
delete this->indoorSensor;
|
delete this->indoorSensor;
|
||||||
}
|
|
||||||
|
|
||||||
if (this->oneWireIndoorSensor != nullptr) {
|
|
||||||
delete this->oneWireIndoorSensor;
|
delete this->oneWireIndoorSensor;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OneWire* oneWireOutdoorSensor = nullptr;
|
OneWire* oneWireOutdoorSensor = nullptr;
|
||||||
@@ -61,9 +43,8 @@ protected:
|
|||||||
|
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
BLEClient* pBleClient = nullptr;
|
BLEClient* pBleClient = nullptr;
|
||||||
BLERemoteService* pBleServiceBattery = nullptr;
|
|
||||||
BLERemoteService* pBleServiceEnvironment = nullptr;
|
|
||||||
bool initBleSensor = false;
|
bool initBleSensor = false;
|
||||||
|
bool initBleNotify = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* getTaskName() {
|
const char* getTaskName() {
|
||||||
@@ -79,67 +60,150 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
bool needUpdateIndoorTemp = false;
|
||||||
|
bool needUpdateOutdoorTemp = false;
|
||||||
|
|
||||||
if (settings.sensors.outdoor.type == 2 && settings.sensors.outdoor.pin) {
|
if (settings.sensors.outdoor.type == 2 && settings.sensors.outdoor.pin) {
|
||||||
outdoorTemperatureSensor();
|
outdoorTemperatureSensor();
|
||||||
|
needUpdateOutdoorTemp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.sensors.indoor.type == 2 && settings.sensors.indoor.pin) {
|
if (settings.sensors.indoor.type == 2 && settings.sensors.indoor.pin) {
|
||||||
indoorTemperatureSensor();
|
indoorTemperatureSensor();
|
||||||
|
needUpdateIndoorTemp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
if (settings.sensors.indoor.type == 3 && strlen(settings.sensors.indoor.bleAddresss)) {
|
if (settings.sensors.indoor.type == 3) {
|
||||||
bluetoothSensor();
|
bluetoothSensor();
|
||||||
|
needUpdateIndoorTemp = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (needUpdateOutdoorTemp && fabs(vars.temperatures.outdoor - this->filteredOutdoorTemp) > 0.099) {
|
||||||
|
vars.temperatures.outdoor = this->filteredOutdoorTemp + settings.sensors.outdoor.offset;
|
||||||
|
Log.sinfoln(FPSTR(L_SENSORS_OUTDOOR), F("New temp: %f"), vars.temperatures.outdoor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needUpdateIndoorTemp && fabs(vars.temperatures.indoor - this->filteredIndoorTemp) > 0.099) {
|
||||||
|
vars.temperatures.indoor = this->filteredIndoorTemp + settings.sensors.indoor.offset;
|
||||||
|
Log.sinfoln(FPSTR(L_SENSORS_INDOOR), F("New temp: %f"), vars.temperatures.indoor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
void bluetoothSensor() {
|
void bluetoothSensor() {
|
||||||
|
static bool initBleNotify = false;
|
||||||
if (!initBleSensor && millis() > 5000) {
|
if (!initBleSensor && millis() > 5000) {
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_BLE), "Init BLE. Free heap %u bytes", ESP.getFreeHeap());
|
Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Init BLE"));
|
||||||
BLEDevice::init("");
|
BLEDevice::init("");
|
||||||
|
|
||||||
pBleClient = BLEDevice::createClient();
|
pBleClient = BLEDevice::createClient();
|
||||||
|
pBleClient->setConnectTimeout(5);
|
||||||
// Connect to the remote BLE Server.
|
|
||||||
BLEAddress bleServerAddress(std::string(settings.sensors.indoor.bleAddresss));
|
|
||||||
if (pBleClient->connect(bleServerAddress)) {
|
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_BLE), "Connected to BLE device at %s", bleServerAddress.toString().c_str());
|
|
||||||
// Obtain a reference to the services we are interested in
|
|
||||||
pBleServiceBattery = pBleClient->getService(BLEUUID(bleUuidServiceBattery));
|
|
||||||
if (pBleServiceBattery == nullptr) {
|
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_BLE), "Failed to find battery service");
|
|
||||||
}
|
|
||||||
pBleServiceEnvironment = pBleClient->getService(BLEUUID(bleUuidServiceEnvironment));
|
|
||||||
if (pBleServiceEnvironment == nullptr) {
|
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_BLE), "Failed to find environmental service");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.swarningln(FPSTR(L_SENSORS_BLE), "Error connecting to BLE device at %s", bleServerAddress.toString().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
initBleSensor = true;
|
initBleSensor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBleClient && pBleClient->isConnected()) {
|
if (!initBleSensor || pBleClient->isConnected()) {
|
||||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Connected. Free heap %u bytes", ESP.getFreeHeap());
|
return;
|
||||||
if (pBleServiceBattery) {
|
|
||||||
uint8_t batteryLevel = *reinterpret_cast<const uint8_t *>(pBleServiceBattery->getValue(bleUuidCharacteristicBatteryLevel).data());
|
|
||||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Battery: %d", batteryLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBleServiceEnvironment) {
|
// Reset init notify flag
|
||||||
float temperature = *reinterpret_cast<const int16_t *>(pBleServiceEnvironment->getValue(bleUuidCharacteristicTemperature).data()) / 100.0f;
|
this->initBleNotify = false;
|
||||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Temperature: %.2f", temperature);
|
|
||||||
float humidity = *reinterpret_cast<const int16_t *>(pBleServiceEnvironment->getValue(bleUuidCharacteristicHumidity).data()) / 100.0f;
|
|
||||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Humidity: %.2f", humidity);
|
|
||||||
|
|
||||||
vars.temperatures.indoor = temperature + settings.sensors.indoor.offset;
|
// Connect to the remote BLE Server.
|
||||||
|
BLEAddress bleServerAddress(settings.sensors.indoor.bleAddresss);
|
||||||
|
if (!pBleClient->connect(bleServerAddress)) {
|
||||||
|
Log.swarningln(FPSTR(L_SENSORS_BLE), "Failed connecting to device at %s", bleServerAddress.toString().c_str());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.sinfoln(FPSTR(L_SENSORS_BLE), "Connected to device at %s", bleServerAddress.toString().c_str());
|
||||||
|
|
||||||
|
NimBLEUUID serviceUUID((uint16_t) 0x181AU);
|
||||||
|
BLERemoteService* pRemoteService = pBleClient->getService(serviceUUID);
|
||||||
|
if (!pRemoteService) {
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_BLE), F("Failed to find service UUID: %s"), serviceUUID.toString().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_BLE), F("Found service UUID: %s"), serviceUUID.toString().c_str());
|
||||||
|
|
||||||
|
// 0x2A6E - Notify temperature x0.01C (pvvx)
|
||||||
|
if (!this->initBleNotify) {
|
||||||
|
NimBLEUUID charUUID((uint16_t) 0x2A6E);
|
||||||
|
BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
|
||||||
|
if (pRemoteCharacteristic && pRemoteCharacteristic->canNotify()) {
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_BLE), F("Found characteristic UUID: %s"), charUUID.toString().c_str());
|
||||||
|
|
||||||
|
this->initBleNotify = pRemoteCharacteristic->subscribe(true, [this](NimBLERemoteCharacteristic*, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (length != 2) {
|
||||||
|
Log.swarningln(FPSTR(L_SENSORS_BLE), F("Invalid notification data"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rawTemp = ((pData[0] | (pData[1] << 8)) * 0.01);
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_INDOOR), F("Raw temp: %f"), rawTemp);
|
||||||
|
|
||||||
|
if (this->emptyIndoorTemp) {
|
||||||
|
this->filteredIndoorTemp = rawTemp;
|
||||||
|
this->emptyIndoorTemp = false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Not connected");
|
this->filteredIndoorTemp += (rawTemp - this->filteredIndoorTemp) * EXT_SENSORS_FILTER_K;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->filteredIndoorTemp = floor(this->filteredIndoorTemp * 100) / 100;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this->initBleNotify) {
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_BLE), F("Subscribed to characteristic UUID: %s"), charUUID.toString().c_str());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.swarningln(FPSTR(L_SENSORS_BLE), F("Failed to subscribe to characteristic UUID: %s"), charUUID.toString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x2A1F - Notify temperature x0.1C (atc1441/pvvx)
|
||||||
|
if (!this->initBleNotify) {
|
||||||
|
NimBLEUUID charUUID((uint16_t) 0x2A1F);
|
||||||
|
BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
|
||||||
|
if (pRemoteCharacteristic && pRemoteCharacteristic->canNotify()) {
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_BLE), F("Found characteristic UUID: %s"), charUUID.toString().c_str());
|
||||||
|
|
||||||
|
this->initBleNotify = pRemoteCharacteristic->subscribe(true, [this](NimBLERemoteCharacteristic*, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (length != 2) {
|
||||||
|
Log.swarningln(FPSTR(L_SENSORS_BLE), F("Invalid notification data"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rawTemp = ((pData[0] | (pData[1] << 8)) * 0.1);
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_INDOOR), F("Raw temp: %f"), rawTemp);
|
||||||
|
|
||||||
|
if (this->emptyIndoorTemp) {
|
||||||
|
this->filteredIndoorTemp = rawTemp;
|
||||||
|
this->emptyIndoorTemp = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->filteredIndoorTemp += (rawTemp - this->filteredIndoorTemp) * EXT_SENSORS_FILTER_K;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->filteredIndoorTemp = floor(this->filteredIndoorTemp * 100) / 100;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this->initBleNotify) {
|
||||||
|
Log.straceln(FPSTR(L_SENSORS_BLE), F("Subscribed to characteristic UUID: %s"), charUUID.toString().c_str());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.swarningln(FPSTR(L_SENSORS_BLE), F("Failed to subscribe to characteristic UUID: %s"), charUUID.toString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->initBleNotify) {
|
||||||
|
Log.swarningln(FPSTR(L_SENSORS_BLE), F("Not found supported characteristics"));
|
||||||
|
pBleClient->disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -205,12 +269,6 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->filteredOutdoorTemp = floor(this->filteredOutdoorTemp * 100) / 100;
|
this->filteredOutdoorTemp = floor(this->filteredOutdoorTemp * 100) / 100;
|
||||||
|
|
||||||
if (fabs(vars.temperatures.outdoor - this->filteredOutdoorTemp) > 0.099) {
|
|
||||||
vars.temperatures.outdoor = this->filteredOutdoorTemp + settings.sensors.outdoor.offset;
|
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_OUTDOOR), F("New temp: %f"), this->filteredOutdoorTemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->outdoorSensor->requestTemperatures();
|
this->outdoorSensor->requestTemperatures();
|
||||||
this->startOutdoorConversionTime = millis();
|
this->startOutdoorConversionTime = millis();
|
||||||
}
|
}
|
||||||
@@ -277,12 +335,6 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->filteredIndoorTemp = floor(this->filteredIndoorTemp * 100) / 100;
|
this->filteredIndoorTemp = floor(this->filteredIndoorTemp * 100) / 100;
|
||||||
|
|
||||||
if (fabs(vars.temperatures.indoor - this->filteredIndoorTemp) > 0.099) {
|
|
||||||
vars.temperatures.indoor = this->filteredIndoorTemp + settings.sensors.indoor.offset;
|
|
||||||
Log.sinfoln(FPSTR(L_SENSORS_INDOOR), F("New temp: %f"), this->filteredIndoorTemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->indoorSensor->requestTemperatures();
|
this->indoorSensor->requestTemperatures();
|
||||||
this->startIndoorConversionTime = millis();
|
this->startIndoorConversionTime = millis();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ struct Settings {
|
|||||||
// 1 - manual, 2 - ds18b20, 3 - ble
|
// 1 - manual, 2 - ds18b20, 3 - ble
|
||||||
byte type = 1;
|
byte type = 1;
|
||||||
byte pin = SENSOR_INDOOR_PIN_DEFAULT;
|
byte pin = SENSOR_INDOOR_PIN_DEFAULT;
|
||||||
char bleAddresss[18] = "00:00:00:00:00:00";
|
uint8_t bleAddresss[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
float offset = 0.0f;
|
float offset = 0.0f;
|
||||||
} indoor;
|
} indoor;
|
||||||
} sensors;
|
} sensors;
|
||||||
@@ -166,17 +166,17 @@ struct Variables {
|
|||||||
unsigned long extPumpLastEnableTime = 0;
|
unsigned long extPumpLastEnableTime = 0;
|
||||||
byte dhwMinTemp = DEFAULT_DHW_MIN_TEMP;
|
byte dhwMinTemp = DEFAULT_DHW_MIN_TEMP;
|
||||||
byte dhwMaxTemp = DEFAULT_DHW_MAX_TEMP;
|
byte dhwMaxTemp = DEFAULT_DHW_MAX_TEMP;
|
||||||
byte maxModulation;
|
byte maxModulation = 0;
|
||||||
uint8_t slaveMemberId;
|
uint8_t slaveMemberId = 0;
|
||||||
uint8_t slaveFlags;
|
uint8_t slaveFlags = 0;
|
||||||
uint8_t slaveType;
|
uint8_t slaveType = 0;
|
||||||
uint8_t slaveVersion;
|
uint8_t slaveVersion = 0;
|
||||||
float slaveOtVersion;
|
float slaveOtVersion = 0.0f;
|
||||||
uint8_t masterMemberId;
|
uint8_t masterMemberId = 0;
|
||||||
uint8_t masterFlags;
|
uint8_t masterFlags = 0;
|
||||||
uint8_t masterType;
|
uint8_t masterType = 0;
|
||||||
uint8_t masterVersion;
|
uint8_t masterVersion = 0;
|
||||||
float masterOtVersion;
|
float masterOtVersion = 0;
|
||||||
} parameters;
|
} parameters;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define PROJECT_NAME "OpenTherm Gateway"
|
#define PROJECT_NAME "OpenTherm Gateway"
|
||||||
#define PROJECT_VERSION "1.4.0-rc.14"
|
#define PROJECT_VERSION "1.4.0-rc.16"
|
||||||
#define PROJECT_REPO "https://github.com/Laxilef/OTGateway"
|
#define PROJECT_REPO "https://github.com/Laxilef/OTGateway"
|
||||||
|
|
||||||
#define EMERGENCY_TIME_TRESHOLD 120000
|
#define EMERGENCY_TIME_TRESHOLD 120000
|
||||||
|
|||||||
25
src/utils.h
25
src/utils.h
@@ -232,7 +232,7 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ap
|
// sta
|
||||||
if (!src["sta"]["ssid"].isNull()) {
|
if (!src["sta"]["ssid"].isNull()) {
|
||||||
String value = src["sta"]["ssid"].as<String>();
|
String value = src["sta"]["ssid"].as<String>();
|
||||||
|
|
||||||
@@ -329,7 +329,19 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
|||||||
|
|
||||||
dst["sensors"]["indoor"]["type"] = src.sensors.indoor.type;
|
dst["sensors"]["indoor"]["type"] = src.sensors.indoor.type;
|
||||||
dst["sensors"]["indoor"]["pin"] = src.sensors.indoor.pin;
|
dst["sensors"]["indoor"]["pin"] = src.sensors.indoor.pin;
|
||||||
dst["sensors"]["indoor"]["bleAddresss"] = src.sensors.indoor.bleAddresss;
|
|
||||||
|
char bleAddress[18];
|
||||||
|
sprintf(
|
||||||
|
bleAddress,
|
||||||
|
"%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
src.sensors.indoor.bleAddresss[0],
|
||||||
|
src.sensors.indoor.bleAddresss[1],
|
||||||
|
src.sensors.indoor.bleAddresss[2],
|
||||||
|
src.sensors.indoor.bleAddresss[3],
|
||||||
|
src.sensors.indoor.bleAddresss[4],
|
||||||
|
src.sensors.indoor.bleAddresss[5]
|
||||||
|
);
|
||||||
|
dst["sensors"]["indoor"]["bleAddresss"] = String(bleAddress);
|
||||||
dst["sensors"]["indoor"]["offset"] = roundd(src.sensors.indoor.offset, 2);
|
dst["sensors"]["indoor"]["offset"] = roundd(src.sensors.indoor.offset, 2);
|
||||||
|
|
||||||
if (!safe) {
|
if (!safe) {
|
||||||
@@ -486,7 +498,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
if (!src["mqtt"]["port"].isNull()) {
|
if (!src["mqtt"]["port"].isNull()) {
|
||||||
unsigned short value = src["mqtt"]["port"].as<unsigned short>();
|
unsigned short value = src["mqtt"]["port"].as<unsigned short>();
|
||||||
|
|
||||||
if (value >= 0 && value <= 65536) {
|
if (value > 0 && value <= 65535) {
|
||||||
dst.mqtt.port = value;
|
dst.mqtt.port = value;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
@@ -821,9 +833,12 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
if (!src["sensors"]["indoor"]["bleAddresss"].isNull()) {
|
if (!src["sensors"]["indoor"]["bleAddresss"].isNull()) {
|
||||||
String value = src["sensors"]["indoor"]["bleAddresss"].as<String>();
|
String value = src["sensors"]["indoor"]["bleAddresss"].as<String>();
|
||||||
|
int tmp[6];
|
||||||
|
if(sscanf(value.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]) == 6) {
|
||||||
|
for(uint8_t i = 0; i < 6; i++) {
|
||||||
|
dst.sensors.indoor.bleAddresss[i] = (uint8_t) tmp[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (value.length() < sizeof(dst.sensors.indoor.bleAddresss)) {
|
|
||||||
strcpy(dst.sensors.indoor.bleAddresss, value.c_str());
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user