mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-11 18:54:28 +05:00
Merge branch 'master' into unit-system
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||
<br>
|
<br>
|
||||||
[](https://github.com/Laxilef/OTGateway/releases)
|
[](https://github.com/Laxilef/OTGateway/releases)
|
||||||
[](https://github.com/Laxilef/OTGateway/releases/latest)
|
[](https://github.com/Laxilef/OTGateway/releases/latest)
|
||||||
[](LICENSE.txt)
|
[](LICENSE.txt)
|
||||||
[](https://t.me/otgateway)
|
[](https://t.me/otgateway)
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ extra_configs = secrets.default.ini
|
|||||||
[env]
|
[env]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson@^7.0.3
|
bblanchon/ArduinoJson@^7.0.4
|
||||||
;ihormelnyk/OpenTherm Library@^1.1.5
|
;ihormelnyk/OpenTherm Library@^1.1.5
|
||||||
https://github.com/ihormelnyk/opentherm_library.git
|
https://github.com/Laxilef/opentherm_library/archive/refs/heads/fix_lambda.zip
|
||||||
arduino-libraries/ArduinoMqttClient@^0.1.8
|
arduino-libraries/ArduinoMqttClient@^0.1.8
|
||||||
lennarthennigs/ESP Telnet@^2.2
|
lennarthennigs/ESP Telnet@^2.2
|
||||||
gyverlibs/FileData@^1.0.2
|
gyverlibs/FileData@^1.0.2
|
||||||
@@ -30,7 +30,7 @@ build_flags =
|
|||||||
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
|
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
|
||||||
-mtext-section-literals
|
-mtext-section-literals
|
||||||
-D MQTT_CLIENT_STD_FUNCTION_CALLBACK=1
|
-D MQTT_CLIENT_STD_FUNCTION_CALLBACK=1
|
||||||
;-D DEBUG_ESP_CORE -D DEBUG_ESP_WIFI -D DEBUG_ESP_PORT=Serial
|
;-D DEBUG_ESP_CORE -D DEBUG_ESP_WIFI -D DEBUG_ESP_HTTP_SERVER -D DEBUG_ESP_PORT=Serial
|
||||||
-D USE_SERIAL=${secrets.use_serial}
|
-D USE_SERIAL=${secrets.use_serial}
|
||||||
-D USE_TELNET=${secrets.use_telnet}
|
-D USE_TELNET=${secrets.use_telnet}
|
||||||
-D DEBUG_BY_DEFAULT=${secrets.debug}
|
-D DEBUG_BY_DEFAULT=${secrets.debug}
|
||||||
@@ -51,20 +51,19 @@ 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.17
|
version = 1.4.0-rc.18
|
||||||
|
|
||||||
; Defaults
|
; Defaults
|
||||||
[esp8266_defaults]
|
[esp8266_defaults]
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
nrwiersma/ESP8266Scheduler@^1.1
|
nrwiersma/ESP8266Scheduler@^1.2
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
post:tools/build.py
|
post:tools/build.py
|
||||||
build_flags = ${env.build_flags}
|
build_flags = ${env.build_flags}
|
||||||
board_build.ldscript = eagle.flash.1m256.ld
|
board_build.ldscript = eagle.flash.4m1m.ld
|
||||||
;board_build.ldscript = eagle.flash.4m1m.ld
|
|
||||||
|
|
||||||
[esp32_defaults]
|
[esp32_defaults]
|
||||||
platform = espressif32@^6.5
|
platform = espressif32@^6.5
|
||||||
|
|||||||
@@ -1276,6 +1276,36 @@ public:
|
|||||||
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("heating_temp")).c_str(), doc);
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("heating_temp")).c_str(), doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool publishSensorHeatingReturnTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) {
|
||||||
|
JsonDocument doc;
|
||||||
|
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_return_temp"));
|
||||||
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("heating_return_temp"));
|
||||||
|
doc[FPSTR(HA_ENTITY_CATEGORY)] = F("diagnostic");
|
||||||
|
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature");
|
||||||
|
doc[FPSTR(HA_STATE_CLASS)] = F("measurement");
|
||||||
|
|
||||||
|
if (unit == UnitSystem::METRIC) {
|
||||||
|
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
|
||||||
|
|
||||||
|
} else if (unit == UnitSystem::IMPERIAL) {
|
||||||
|
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F);
|
||||||
|
}
|
||||||
|
|
||||||
|
doc[FPSTR(HA_NAME)] = F("Heating return temperature");
|
||||||
|
doc[FPSTR(HA_ICON)] = F("mdi:radiator");
|
||||||
|
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.temperatures.heatingReturn|float(0)|round(2) }}");
|
||||||
|
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
||||||
|
doc.shrinkToFit();
|
||||||
|
|
||||||
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("heating_return_temp")).c_str(), doc);
|
||||||
|
}
|
||||||
|
|
||||||
bool publishSensorDhwTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) {
|
bool publishSensorDhwTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
@@ -1306,6 +1336,36 @@ public:
|
|||||||
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("dhw_temp")).c_str(), doc);
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("dhw_temp")).c_str(), doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool publishSensorExhaustTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) {
|
||||||
|
JsonDocument doc;
|
||||||
|
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("exhaust_temp"));
|
||||||
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("exhaust_temp"));
|
||||||
|
doc[FPSTR(HA_ENTITY_CATEGORY)] = F("diagnostic");
|
||||||
|
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature");
|
||||||
|
doc[FPSTR(HA_STATE_CLASS)] = F("measurement");
|
||||||
|
|
||||||
|
if (unit == UnitSystem::METRIC) {
|
||||||
|
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
|
||||||
|
|
||||||
|
} else if (unit == UnitSystem::IMPERIAL) {
|
||||||
|
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F);
|
||||||
|
}
|
||||||
|
|
||||||
|
doc[FPSTR(HA_NAME)] = F("Exhaust temperature");
|
||||||
|
doc[FPSTR(HA_ICON)] = F("mdi:smoke");
|
||||||
|
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.temperatures.exhaust|float(0)|round(2) }}");
|
||||||
|
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
||||||
|
doc.shrinkToFit();
|
||||||
|
|
||||||
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("exhaust_temp")).c_str(), doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool publishClimateHeating(byte minTemp = 20, byte maxTemp = 90, byte currentTempSource = HaHelper::TEMP_SOURCE_HEATING, bool enabledByDefault = true) {
|
bool publishClimateHeating(byte minTemp = 20, byte maxTemp = 90, byte currentTempSource = HaHelper::TEMP_SOURCE_HEATING, bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
|
|||||||
@@ -370,6 +370,8 @@ protected:
|
|||||||
// temperatures
|
// temperatures
|
||||||
this->haHelper->publishNumberIndoorTemp();
|
this->haHelper->publishNumberIndoorTemp();
|
||||||
this->haHelper->publishSensorHeatingTemp();
|
this->haHelper->publishSensorHeatingTemp();
|
||||||
|
this->haHelper->publishSensorHeatingReturnTemp(settings.system.unitSystem, false);
|
||||||
|
this->haHelper->publishSensorExhaustTemp(settings.system.unitSystem, false);
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
this->haHelper->publishButtonRestart(false);
|
this->haHelper->publishButtonRestart(false);
|
||||||
|
|||||||
@@ -253,9 +253,6 @@ protected:
|
|||||||
fsSettings.update();
|
fsSettings.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force set max heating temp
|
|
||||||
setMaxHeatingTemp(settings.heating.maxTemp);
|
|
||||||
|
|
||||||
// Get outdoor temp (if necessary)
|
// Get outdoor temp (if necessary)
|
||||||
if (settings.sensors.outdoor.type == SensorType::BOILER) {
|
if (settings.sensors.outdoor.type == SensorType::BOILER) {
|
||||||
updateOutsideTemp();
|
updateOutsideTemp();
|
||||||
@@ -293,6 +290,12 @@ protected:
|
|||||||
// Get current heating temp
|
// Get current heating temp
|
||||||
updateHeatingTemp();
|
updateHeatingTemp();
|
||||||
|
|
||||||
|
// Get heating return temp
|
||||||
|
updateHeatingReturnTemp();
|
||||||
|
|
||||||
|
// Get exhaust temp
|
||||||
|
updateExhaustTemp();
|
||||||
|
|
||||||
|
|
||||||
// Fault reset action
|
// Fault reset action
|
||||||
if (vars.actions.resetFault) {
|
if (vars.actions.resetFault) {
|
||||||
@@ -355,7 +358,7 @@ protected:
|
|||||||
Log.sinfoln(FPSTR(L_OT_HEATING), F("Set temp = %u"), vars.parameters.heatingSetpoint);
|
Log.sinfoln(FPSTR(L_OT_HEATING), F("Set temp = %u"), vars.parameters.heatingSetpoint);
|
||||||
|
|
||||||
// Set heating temp
|
// Set heating temp
|
||||||
if (this->instance->setHeatingCh1Temp(tempTo(vars.parameters.heatingSetpoint))) {
|
if (this->instance->setHeatingCh1Temp(tempTo(vars.parameters.heatingSetpoint)) || this->setMaxHeatingTemp(tempTo(vars.parameters.heatingSetpoint))) {
|
||||||
currentHeatingTemp = vars.parameters.heatingSetpoint;
|
currentHeatingTemp = vars.parameters.heatingSetpoint;
|
||||||
this->heatingSetTempTime = millis();
|
this->heatingSetTempTime = millis();
|
||||||
|
|
||||||
@@ -657,6 +660,21 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool updateExhaustTemp() {
|
||||||
|
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
|
OpenThermRequestType::READ_DATA,
|
||||||
|
OpenThermMessageID::Texhaust,
|
||||||
|
0
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!CustomOpenTherm::isValidResponse(response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vars.temperatures.exhaust = tempFrom(CustomOpenTherm::getFloat(response));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool updateHeatingTemp() {
|
bool updateHeatingTemp() {
|
||||||
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
OpenThermMessageType::READ_DATA,
|
OpenThermMessageType::READ_DATA,
|
||||||
@@ -677,6 +695,21 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool updateHeatingReturnTemp() {
|
||||||
|
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
|
OpenThermMessageType::READ_DATA,
|
||||||
|
OpenThermMessageID::Tret,
|
||||||
|
0
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!CustomOpenTherm::isValidResponse(response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vars.temperatures.heatingReturn = tempFrom(CustomOpenTherm::getFloat(response));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool updateDhwTemp() {
|
bool updateDhwTemp() {
|
||||||
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
|
|||||||
@@ -155,7 +155,9 @@ struct Variables {
|
|||||||
float indoor = 0.0f;
|
float indoor = 0.0f;
|
||||||
float outdoor = 0.0f;
|
float outdoor = 0.0f;
|
||||||
float heating = 0.0f;
|
float heating = 0.0f;
|
||||||
|
float heatingReturn = 0.0f;
|
||||||
float dhw = 0.0f;
|
float dhw = 0.0f;
|
||||||
|
float exhaust = 0.0f;
|
||||||
} temperatures;
|
} temperatures;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define PROJECT_NAME "OpenTherm Gateway"
|
#define PROJECT_NAME "OpenTherm Gateway"
|
||||||
#define PROJECT_VERSION "1.4.0-rc.17"
|
#define PROJECT_VERSION "1.4.0-rc.18"
|
||||||
#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
|
||||||
|
|||||||
@@ -1058,7 +1058,9 @@ void varsToJson(const Variables& src, JsonVariant dst) {
|
|||||||
dst["temperatures"]["indoor"] = roundd(src.temperatures.indoor, 2);
|
dst["temperatures"]["indoor"] = roundd(src.temperatures.indoor, 2);
|
||||||
dst["temperatures"]["outdoor"] = roundd(src.temperatures.outdoor, 2);
|
dst["temperatures"]["outdoor"] = roundd(src.temperatures.outdoor, 2);
|
||||||
dst["temperatures"]["heating"] = roundd(src.temperatures.heating, 2);
|
dst["temperatures"]["heating"] = roundd(src.temperatures.heating, 2);
|
||||||
|
dst["temperatures"]["heatingReturn"] = roundd(src.temperatures.heatingReturn, 2);
|
||||||
dst["temperatures"]["dhw"] = roundd(src.temperatures.dhw, 2);
|
dst["temperatures"]["dhw"] = roundd(src.temperatures.dhw, 2);
|
||||||
|
dst["temperatures"]["exhaust"] = roundd(src.temperatures.exhaust, 2);
|
||||||
|
|
||||||
dst["parameters"]["heatingEnabled"] = src.parameters.heatingEnabled;
|
dst["parameters"]["heatingEnabled"] = src.parameters.heatingEnabled;
|
||||||
dst["parameters"]["heatingMinTemp"] = src.parameters.heatingMinTemp;
|
dst["parameters"]["heatingMinTemp"] = src.parameters.heatingMinTemp;
|
||||||
|
|||||||
Reference in New Issue
Block a user