mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-11 18:54:28 +05:00
Compare commits
7 Commits
1.4.0-rc.1
...
1.4.0-rc.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e829a00355 | ||
|
|
bee720386a | ||
|
|
c4b6eadb81 | ||
|
|
a5d2b9fcfa | ||
|
|
1a03117257 | ||
|
|
b421780f7b | ||
|
|
987c101394 |
@@ -17,7 +17,7 @@ public:
|
||||
float Kk = 0.0;
|
||||
float Kt = 0.0;
|
||||
|
||||
Equitherm() {}
|
||||
Equitherm() = default;
|
||||
|
||||
// kn, kk, kt
|
||||
Equitherm(float new_kn, float new_kk, float new_kt) {
|
||||
|
||||
@@ -6,7 +6,7 @@ class HomeAssistantHelper {
|
||||
public:
|
||||
typedef std::function<void(const char*, bool)> PublishEventCallback;
|
||||
|
||||
HomeAssistantHelper() {}
|
||||
HomeAssistantHelper() = default;
|
||||
|
||||
void setWriter() {
|
||||
this->writer = nullptr;
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace Network {
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
WiFi.setSleepMode(WIFI_NONE_SLEEP);
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
WiFi.setSleep(WIFI_PS_NONE);
|
||||
WiFi.setSleep(USE_BLE ? WIFI_PS_MIN_MODEM : WIFI_PS_NONE);
|
||||
#endif
|
||||
|
||||
WiFi.softAPdisconnect();
|
||||
@@ -309,12 +309,14 @@ namespace Network {
|
||||
Log.sinfoln(FPSTR(L_NETWORK), F("No STA credentials, start AP"));
|
||||
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
this->delayCallback(250);
|
||||
WiFi.softAP(this->apName, this->apPassword, this->apChannel);
|
||||
|
||||
} else if (!this->isApEnabled() && millis() - this->disconnectedTime > this->failedConnectTimeout) {
|
||||
Log.sinfoln(FPSTR(L_NETWORK), F("Disconnected for a long time, start AP"));
|
||||
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
this->delayCallback(250);
|
||||
WiFi.softAP(this->apName, this->apPassword, this->apChannel);
|
||||
|
||||
} else if (this->isConnecting() && millis() - this->prevReconnectingTime > this->resetConnectionTimeout) {
|
||||
|
||||
@@ -177,7 +177,6 @@ public:
|
||||
|
||||
} else {
|
||||
sizeArgName = length - size_t(argStartPos - currentBuf) - 1;
|
||||
Serial.printf("sizeArgName: %d\r\n", sizeArgName);
|
||||
|
||||
// send all content if arg len > space
|
||||
if (sizeArgName >= sizeof(argName)) {
|
||||
|
||||
@@ -15,7 +15,7 @@ extra_configs = secrets.default.ini
|
||||
[env]
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^7.0.2
|
||||
bblanchon/ArduinoJson@^7.0.3
|
||||
;ihormelnyk/OpenTherm Library@^1.1.4
|
||||
https://github.com/Laxilef/opentherm_library/archive/refs/heads/fix_start_bit.zip
|
||||
arduino-libraries/ArduinoMqttClient@^0.1.8
|
||||
@@ -51,7 +51,7 @@ monitor_speed = 115200
|
||||
monitor_filters = direct
|
||||
board_build.flash_mode = dio
|
||||
board_build.filesystem = littlefs
|
||||
version = 1.4.0-rc.13
|
||||
version = 1.4.0-rc.15
|
||||
|
||||
; Defaults
|
||||
[esp8266_defaults]
|
||||
@@ -65,8 +65,6 @@ extra_scripts =
|
||||
build_flags = ${env.build_flags}
|
||||
board_build.ldscript = eagle.flash.1m256.ld
|
||||
;board_build.ldscript = eagle.flash.4m1m.ld
|
||||
platform_packages =
|
||||
framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git
|
||||
|
||||
[esp32_defaults]
|
||||
platform = espressif32
|
||||
|
||||
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_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) {
|
||||
JsonDocument doc;
|
||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||
@@ -266,7 +213,10 @@ public:
|
||||
|
||||
bool publishSensorBoilerHeatingMinTemp(bool enabledByDefault = true) {
|
||||
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_UNIQUE_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) {
|
||||
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_UNIQUE_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_TEMPLATE)] = F("{\"dhw\": {\"target\" : {{ value|int(0) }}}}");
|
||||
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_MODE)] = "box";
|
||||
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
||||
@@ -426,7 +379,10 @@ public:
|
||||
|
||||
bool publishSensorBoilerDhwMinTemp(bool enabledByDefault = true) {
|
||||
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_UNIQUE_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) {
|
||||
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_UNIQUE_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) {
|
||||
JsonDocument doc;
|
||||
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_TEMPLATE)] = F("{\"tuning\": {\"regulator\": {% if value == 'Equitherm' %}0{% elif value == 'PID' %}1{% endif %}}}");
|
||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||
@@ -835,7 +793,10 @@ public:
|
||||
|
||||
bool publishBinSensorHeating(bool enabledByDefault = true) {
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("heating"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("heating"));
|
||||
@@ -853,7 +814,10 @@ public:
|
||||
|
||||
bool publishBinSensorDhw(bool enabledByDefault = true) {
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("dhw"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw"));
|
||||
@@ -871,7 +835,10 @@ public:
|
||||
|
||||
bool publishBinSensorFlame(bool enabledByDefault = true) {
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("flame"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("flame"));
|
||||
@@ -889,8 +856,10 @@ public:
|
||||
|
||||
bool publishBinSensorFault(bool enabledByDefault = true) {
|
||||
JsonDocument doc;
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("fault"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("fault"));
|
||||
@@ -908,7 +877,10 @@ public:
|
||||
|
||||
bool publishBinSensorDiagnostic(bool enabledByDefault = true) {
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("diagnostic"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("diagnostic"));
|
||||
@@ -926,8 +898,10 @@ public:
|
||||
|
||||
bool publishSensorFaultCode(bool enabledByDefault = true) {
|
||||
JsonDocument doc;
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.fault, 'online', 'offline') }}");
|
||||
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 and value_json.states.fault, 'online', 'offline') }}");
|
||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||
doc[FPSTR(HA_UNIQUE_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) {
|
||||
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_UNIQUE_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) {
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("pressure"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("pressure"));
|
||||
@@ -1025,7 +1005,10 @@ public:
|
||||
|
||||
bool publishSensorDhwFlowRate(bool enabledByDefault = true) {
|
||||
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_UNIQUE_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) {
|
||||
JsonDocument doc;
|
||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("any");
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||
doc[FPSTR(HA_UNIQUE_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) {
|
||||
JsonDocument doc;
|
||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("any");
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||
doc[FPSTR(HA_UNIQUE_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) {
|
||||
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_UNIQUE_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) {
|
||||
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_UNIQUE_ID)] = this->getObjectId(F("dhw_temp"));
|
||||
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("dhw_temp"));
|
||||
|
||||
@@ -20,14 +20,11 @@ public:
|
||||
}
|
||||
|
||||
~MainTask() {
|
||||
if (this->blinker != nullptr) {
|
||||
delete this->blinker;
|
||||
}
|
||||
delete this->blinker;
|
||||
}
|
||||
|
||||
protected:
|
||||
const static byte REASON_PUMP_START_HEATING = 1;
|
||||
const static byte REASON_PUMP_START_ANTISTUCK = 2;
|
||||
enum class PumpStartReason {NONE, HEATING, ANTISTUCK};
|
||||
|
||||
Blinker* blinker = nullptr;
|
||||
bool blinkerInitialized = false;
|
||||
@@ -38,7 +35,7 @@ protected:
|
||||
unsigned long restartSignalTime = 0;
|
||||
bool heatingEnabled = false;
|
||||
unsigned long heatingDisabledTime = 0;
|
||||
byte externalPumpStartReason;
|
||||
PumpStartReason extPumpStartReason = PumpStartReason::NONE;
|
||||
unsigned long externalPumpStartTime = 0;
|
||||
bool telnetStarted = false;
|
||||
|
||||
@@ -57,12 +54,12 @@ protected:
|
||||
void setup() {
|
||||
#ifdef LED_STATUS_PIN
|
||||
pinMode(LED_STATUS_PIN, OUTPUT);
|
||||
digitalWrite(LED_STATUS_PIN, false);
|
||||
digitalWrite(LED_STATUS_PIN, LOW);
|
||||
#endif
|
||||
|
||||
if (settings.externalPump.pin != 0) {
|
||||
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 (errCount == 0) {
|
||||
if (!ledOn) {
|
||||
digitalWrite(ledPin, true);
|
||||
digitalWrite(ledPin, HIGH);
|
||||
ledOn = true;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (ledOn) {
|
||||
digitalWrite(ledPin, false);
|
||||
digitalWrite(ledPin, LOW);
|
||||
ledOn = false;
|
||||
endBlinkTime = millis();
|
||||
return;
|
||||
@@ -289,7 +286,7 @@ protected:
|
||||
if (!settings.externalPump.use || settings.externalPump.pin == 0) {
|
||||
if (vars.states.externalPump) {
|
||||
if (settings.externalPump.pin != 0) {
|
||||
digitalWrite(settings.externalPump.pin, false);
|
||||
digitalWrite(settings.externalPump.pin, LOW);
|
||||
}
|
||||
|
||||
vars.states.externalPump = false;
|
||||
@@ -302,16 +299,16 @@ protected:
|
||||
}
|
||||
|
||||
if (vars.states.externalPump && !this->heatingEnabled) {
|
||||
if (this->externalPumpStartReason == MainTask::REASON_PUMP_START_HEATING && millis() - this->heatingDisabledTime > (settings.externalPump.postCirculationTime * 1000u)) {
|
||||
digitalWrite(settings.externalPump.pin, false);
|
||||
if (this->extPumpStartReason == MainTask::PumpStartReason::HEATING && millis() - this->heatingDisabledTime > (settings.externalPump.postCirculationTime * 1000u)) {
|
||||
digitalWrite(settings.externalPump.pin, LOW);
|
||||
|
||||
vars.states.externalPump = false;
|
||||
vars.parameters.extPumpLastEnableTime = millis();
|
||||
|
||||
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)) {
|
||||
digitalWrite(settings.externalPump.pin, false);
|
||||
} else if (this->extPumpStartReason == MainTask::PumpStartReason::ANTISTUCK && millis() - this->externalPumpStartTime >= (settings.externalPump.antiStuckTime * 1000u)) {
|
||||
digitalWrite(settings.externalPump.pin, LOW);
|
||||
|
||||
vars.states.externalPump = false;
|
||||
vars.parameters.extPumpLastEnableTime = millis();
|
||||
@@ -319,24 +316,24 @@ protected:
|
||||
Log.sinfoln("EXTPUMP", F("Disabled: expired anti stuck time"));
|
||||
}
|
||||
|
||||
} else if (vars.states.externalPump && this->heatingEnabled && this->externalPumpStartReason == MainTask::REASON_PUMP_START_ANTISTUCK) {
|
||||
this->externalPumpStartReason = MainTask::REASON_PUMP_START_HEATING;
|
||||
} else if (vars.states.externalPump && this->heatingEnabled && this->extPumpStartReason == MainTask::PumpStartReason::ANTISTUCK) {
|
||||
this->extPumpStartReason = MainTask::PumpStartReason::HEATING;
|
||||
|
||||
} else if (!vars.states.externalPump && this->heatingEnabled) {
|
||||
vars.states.externalPump = true;
|
||||
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"));
|
||||
|
||||
} else if (!vars.states.externalPump && (vars.parameters.extPumpLastEnableTime == 0 || millis() - vars.parameters.extPumpLastEnableTime >= (settings.externalPump.antiStuckInterval * 1000ul))) {
|
||||
vars.states.externalPump = true;
|
||||
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"));
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@ public:
|
||||
}
|
||||
|
||||
~MqttTask() {
|
||||
if (this->haHelper != nullptr) {
|
||||
delete this->haHelper;
|
||||
}
|
||||
delete this->haHelper;
|
||||
|
||||
if (this->client != nullptr) {
|
||||
if (this->client->connected()) {
|
||||
@@ -27,13 +25,8 @@ public:
|
||||
delete this->client;
|
||||
}
|
||||
|
||||
if (this->writer != nullptr) {
|
||||
delete this->writer;
|
||||
}
|
||||
|
||||
if (this->wifiClient != nullptr) {
|
||||
delete this->wifiClient;
|
||||
}
|
||||
delete this->writer;
|
||||
delete this->wifiClient;
|
||||
}
|
||||
|
||||
void disable() {
|
||||
@@ -208,12 +201,7 @@ protected:
|
||||
|
||||
// publish variables and status
|
||||
if (this->newConnection || millis() - this->prevPubVarsTime > (settings.mqtt.interval * 1000u)) {
|
||||
this->writer->publish(
|
||||
this->haHelper->getDeviceTopic("status").c_str(),
|
||||
!vars.states.otStatus ? "offline" : vars.states.fault ? "fault" : "online",
|
||||
true
|
||||
);
|
||||
|
||||
this->writer->publish(this->haHelper->getDeviceTopic("status").c_str(), "online", false);
|
||||
this->publishVariables(this->haHelper->getDeviceTopic("state").c_str());
|
||||
this->prevPubVarsTime = millis();
|
||||
}
|
||||
@@ -328,10 +316,6 @@ protected:
|
||||
}
|
||||
|
||||
void publishHaEntities() {
|
||||
// main
|
||||
this->haHelper->publishNumberOutdoorSensorOffset(false);
|
||||
this->haHelper->publishNumberIndoorSensorOffset(false);
|
||||
|
||||
// emergency
|
||||
this->haHelper->publishSwitchEmergency();
|
||||
this->haHelper->publishNumberEmergencyTarget();
|
||||
|
||||
@@ -54,9 +54,9 @@ protected:
|
||||
|
||||
#ifdef LED_OT_RX_PIN
|
||||
{
|
||||
digitalWrite(LED_OT_RX_PIN, true);
|
||||
digitalWrite(LED_OT_RX_PIN, HIGH);
|
||||
delayMicroseconds(2000);
|
||||
digitalWrite(LED_OT_RX_PIN, false);
|
||||
digitalWrite(LED_OT_RX_PIN, LOW);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -71,7 +71,7 @@ protected:
|
||||
|
||||
#ifdef LED_OT_RX_PIN
|
||||
pinMode(LED_OT_RX_PIN, OUTPUT);
|
||||
digitalWrite(LED_OT_RX_PIN, false);
|
||||
digitalWrite(LED_OT_RX_PIN, LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,7 @@ public:
|
||||
}
|
||||
|
||||
~PortalTask() {
|
||||
if (this->bufferedWebServer != nullptr) {
|
||||
delete this->bufferedWebServer;
|
||||
}
|
||||
delete this->bufferedWebServer;
|
||||
|
||||
if (this->webServer != nullptr) {
|
||||
this->stopWebServer();
|
||||
|
||||
@@ -159,7 +159,7 @@ protected:
|
||||
if (vars.parameters.heatingEnabled) {
|
||||
float pidResult = getPidTemp(
|
||||
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) {
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
|
||||
#if USE_BLE
|
||||
#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
|
||||
|
||||
class SensorsTask : public LeanTask {
|
||||
@@ -25,21 +18,10 @@ public:
|
||||
}
|
||||
|
||||
~SensorsTask() {
|
||||
if (this->outdoorSensor != nullptr) {
|
||||
delete this->outdoorSensor;
|
||||
}
|
||||
|
||||
if (this->oneWireOutdoorSensor != nullptr) {
|
||||
delete this->oneWireOutdoorSensor;
|
||||
}
|
||||
|
||||
if (this->indoorSensor != nullptr) {
|
||||
delete this->indoorSensor;
|
||||
}
|
||||
|
||||
if (this->oneWireIndoorSensor != nullptr) {
|
||||
delete this->oneWireIndoorSensor;
|
||||
}
|
||||
delete this->outdoorSensor;
|
||||
delete this->oneWireOutdoorSensor;
|
||||
delete this->indoorSensor;
|
||||
delete this->oneWireIndoorSensor;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -61,9 +43,8 @@ protected:
|
||||
|
||||
#if USE_BLE
|
||||
BLEClient* pBleClient = nullptr;
|
||||
BLERemoteService* pBleServiceBattery = nullptr;
|
||||
BLERemoteService* pBleServiceEnvironment = nullptr;
|
||||
bool initBleSensor = false;
|
||||
bool initBleNotify = false;
|
||||
#endif
|
||||
|
||||
const char* getTaskName() {
|
||||
@@ -88,58 +69,135 @@ protected:
|
||||
}
|
||||
|
||||
#if USE_BLE
|
||||
if (settings.sensors.indoor.type == 3 && strlen(settings.sensors.indoor.bleAddresss)) {
|
||||
if (settings.sensors.indoor.type == 3) {
|
||||
bluetoothSensor();
|
||||
}
|
||||
#endif
|
||||
|
||||
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"), vars.temperatures.outdoor);
|
||||
}
|
||||
|
||||
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"), vars.temperatures.indoor);
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_BLE
|
||||
void bluetoothSensor() {
|
||||
static bool initBleNotify = false;
|
||||
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("");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (pBleClient && pBleClient->isConnected()) {
|
||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Connected. Free heap %u bytes", ESP.getFreeHeap());
|
||||
if (pBleServiceBattery) {
|
||||
uint8_t batteryLevel = *reinterpret_cast<const uint8_t *>(pBleServiceBattery->getValue(bleUuidCharacteristicBatteryLevel).data());
|
||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Battery: %d", batteryLevel);
|
||||
}
|
||||
if (!initBleSensor || pBleClient->isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset init notify flag
|
||||
this->initBleNotify = false;
|
||||
|
||||
if (pBleServiceEnvironment) {
|
||||
float temperature = *reinterpret_cast<const int16_t *>(pBleServiceEnvironment->getValue(bleUuidCharacteristicTemperature).data()) / 100.0f;
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
|
||||
vars.temperatures.indoor = temperature + settings.sensors.indoor.offset;
|
||||
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 {
|
||||
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());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.straceln(FPSTR(L_SENSORS_BLE), "Not connected");
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -205,12 +263,6 @@ protected:
|
||||
}
|
||||
|
||||
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->startOutdoorConversionTime = millis();
|
||||
}
|
||||
@@ -277,12 +329,6 @@ protected:
|
||||
}
|
||||
|
||||
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->startIndoorConversionTime = millis();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ struct NetworkSettings {
|
||||
struct {
|
||||
char ssid[33] = AP_SSID_DEFAULT;
|
||||
char password[65] = AP_PASSWORD_DEFAULT;
|
||||
byte channel = 1;
|
||||
byte channel = 6;
|
||||
} ap;
|
||||
|
||||
struct {
|
||||
@@ -110,7 +110,7 @@ struct Settings {
|
||||
// 1 - manual, 2 - ds18b20, 3 - ble
|
||||
byte type = 1;
|
||||
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;
|
||||
} indoor;
|
||||
} sensors;
|
||||
@@ -166,17 +166,17 @@ struct Variables {
|
||||
unsigned long extPumpLastEnableTime = 0;
|
||||
byte dhwMinTemp = DEFAULT_DHW_MIN_TEMP;
|
||||
byte dhwMaxTemp = DEFAULT_DHW_MAX_TEMP;
|
||||
byte maxModulation;
|
||||
uint8_t slaveMemberId;
|
||||
uint8_t slaveFlags;
|
||||
uint8_t slaveType;
|
||||
uint8_t slaveVersion;
|
||||
float slaveOtVersion;
|
||||
uint8_t masterMemberId;
|
||||
uint8_t masterFlags;
|
||||
uint8_t masterType;
|
||||
uint8_t masterVersion;
|
||||
float masterOtVersion;
|
||||
byte maxModulation = 0;
|
||||
uint8_t slaveMemberId = 0;
|
||||
uint8_t slaveFlags = 0;
|
||||
uint8_t slaveType = 0;
|
||||
uint8_t slaveVersion = 0;
|
||||
float slaveOtVersion = 0.0f;
|
||||
uint8_t masterMemberId = 0;
|
||||
uint8_t masterFlags = 0;
|
||||
uint8_t masterType = 0;
|
||||
uint8_t masterVersion = 0;
|
||||
float masterOtVersion = 0;
|
||||
} parameters;
|
||||
|
||||
struct {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define PROJECT_NAME "OpenTherm Gateway"
|
||||
#define PROJECT_VERSION "1.4.0-rc.13"
|
||||
#define PROJECT_VERSION "1.4.0-rc.15"
|
||||
#define PROJECT_REPO "https://github.com/Laxilef/OTGateway"
|
||||
|
||||
#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()) {
|
||||
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"]["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);
|
||||
|
||||
if (!safe) {
|
||||
@@ -486,7 +498,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
||||
if (!src["mqtt"]["port"].isNull()) {
|
||||
unsigned short value = src["mqtt"]["port"].as<unsigned short>();
|
||||
|
||||
if (value >= 0 && value <= 65536) {
|
||||
if (value > 0 && value <= 65535) {
|
||||
dst.mqtt.port = value;
|
||||
changed = true;
|
||||
}
|
||||
@@ -821,9 +833,12 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
||||
#if USE_BLE
|
||||
if (!src["sensors"]["indoor"]["bleAddresss"].isNull()) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user