diff --git a/src/HaHelper.h b/src/HaHelper.h index 9bc5d10..83457c4 100644 --- a/src/HaHelper.h +++ b/src/HaHelper.h @@ -199,6 +199,29 @@ public: return this->publish(this->getTopic("switch", "emergency_use_equitherm").c_str(), doc); } + bool publishSwitchEmergencyUsePid(bool enabledByDefault = true) { + JsonDocument doc; + doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic("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("emergency_use_pid"); + doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId("emergency_use_pid"); + doc[FPSTR(HA_ENTITY_CATEGORY)] = F("config"); + doc[FPSTR(HA_NAME)] = F("Use PID in emergency"); + doc[FPSTR(HA_ICON)] = F("mdi:snowflake-alert"); + doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic("settings"); + doc[FPSTR(HA_STATE_ON)] = true; + doc[FPSTR(HA_STATE_OFF)] = false; + doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.emergency.usePid }}"); + doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic("settings/set"); + doc[FPSTR(HA_PAYLOAD_ON)] = F("{\"emergency\": {\"usePid\" : true}}"); + doc[FPSTR(HA_PAYLOAD_OFF)] = F("{\"emergency\": {\"usePid\" : false}}"); + doc[FPSTR(HA_EXPIRE_AFTER)] = 120; + doc.shrinkToFit(); + + return this->publish(this->getTopic("switch", "emergency_use_pid").c_str(), doc); + } + bool publishSwitchHeating(bool enabledByDefault = true) { JsonDocument doc; diff --git a/src/MqttTask.h b/src/MqttTask.h index de01e72..6768196 100644 --- a/src/MqttTask.h +++ b/src/MqttTask.h @@ -3,6 +3,8 @@ #include #include "HaHelper.h" +extern EEManager eeSettings; + class MqttTask : public Task { public: @@ -289,7 +291,32 @@ protected: } if (!doc["emergency"]["useEquitherm"].isNull() && doc["emergency"]["useEquitherm"].is()) { - settings.emergency.useEquitherm = doc["emergency"]["useEquitherm"].as(); + if (settings.sensors.outdoor.type != 1) { + settings.emergency.useEquitherm = doc["emergency"]["useEquitherm"].as(); + + } else { + settings.emergency.useEquitherm = false; + } + + if (settings.emergency.useEquitherm && settings.emergency.usePid) { + settings.emergency.usePid = false; + } + + flag = true; + } + + if (!doc["emergency"]["usePid"].isNull() && doc["emergency"]["usePid"].is()) { + if (settings.sensors.indoor.type != 1) { + settings.emergency.usePid = doc["emergency"]["usePid"].as(); + + } else { + settings.emergency.usePid = false; + } + + if (settings.emergency.usePid && settings.emergency.useEquitherm) { + settings.emergency.useEquitherm = false; + } + flag = true; } @@ -442,6 +469,11 @@ protected: if (!doc["sensors"]["outdoor"]["type"].isNull() && doc["sensors"]["outdoor"]["type"].is()) { if (doc["sensors"]["outdoor"]["type"].as() >= 0 && doc["sensors"]["outdoor"]["type"].as() <= 2) { settings.sensors.outdoor.type = doc["sensors"]["outdoor"]["type"].as(); + + if (settings.sensors.outdoor.type == 1) { + settings.emergency.useEquitherm = false; + } + flag = true; } } @@ -456,6 +488,11 @@ protected: if (!doc["sensors"]["indoor"]["type"].isNull() && doc["sensors"]["indoor"]["type"].is()) { if (doc["sensors"]["indoor"]["type"].as() >= 1 && doc["sensors"]["indoor"]["type"].as() <= 3) { settings.sensors.indoor.type = doc["sensors"]["indoor"]["type"].as(); + + if (settings.sensors.indoor.type == 1) { + settings.emergency.usePid = false; + } + flag = true; } } @@ -547,6 +584,7 @@ protected: this->haHelper->publishSwitchEmergency(); this->haHelper->publishNumberEmergencyTarget(); this->haHelper->publishSwitchEmergencyUseEquitherm(); + this->haHelper->publishSwitchEmergencyUsePid(); // heating this->haHelper->publishSwitchHeating(false); @@ -719,6 +757,7 @@ protected: doc["emergency"]["enable"] = settings.emergency.enable; doc["emergency"]["target"] = settings.emergency.target; doc["emergency"]["useEquitherm"] = settings.emergency.useEquitherm; + doc["emergency"]["usePid"] = settings.emergency.usePid; doc["heating"]["enable"] = settings.heating.enable; doc["heating"]["turbo"] = settings.heating.turbo; diff --git a/src/OpenThermTask.h b/src/OpenThermTask.h index 1788607..0bbf226 100644 --- a/src/OpenThermTask.h +++ b/src/OpenThermTask.h @@ -341,7 +341,7 @@ protected: // коммутационная разность (hysteresis) // только для pid и/или equitherm - if (settings.heating.hysteresis > 0 && !vars.states.emergency && (settings.equitherm.enable || settings.pid.enable)) { + if (settings.heating.hysteresis > 0 && (!vars.states.emergency || settings.emergency.usePid) && (settings.equitherm.enable || settings.pid.enable)) { float halfHyst = settings.heating.hysteresis / 2; if (this->pump && vars.temperatures.indoor - settings.heating.target + 0.0001 >= halfHyst) { this->pump = false; diff --git a/src/RegulatorTask.h b/src/RegulatorTask.h index edfc6a5..82b5e19 100644 --- a/src/RegulatorTask.h +++ b/src/RegulatorTask.h @@ -91,12 +91,33 @@ protected: prevEtResult = etResult; newTemp += etResult; - Log.sinfoln("REGULATOR.EQUITHERM", F("New emergency result: %u (%f)"), (int) round(etResult), etResult); + Log.sinfoln("REGULATOR.EQUITHERM", F("New emergency result: %hhu (%f)"), (uint8_t) round(etResult), etResult); } else { newTemp += prevEtResult; } + } else if(settings.emergency.usePid && settings.sensors.indoor.type != 1) { + if (vars.parameters.heatingEnabled) { + float pidResult = getPidTemp( + settings.heating.minTemp, + settings.heating.maxTemp + ); + + if (fabs(prevPidResult - pidResult) + 0.0001 >= 0.5) { + prevPidResult = pidResult; + newTemp += pidResult; + + Log.sinfoln("REGULATOR.PID", F("New emergency result: %hhu (%f)"), (uint8_t) round(pidResult), pidResult); + + } else { + newTemp += prevPidResult; + } + + } else if (!vars.parameters.heatingEnabled && prevPidResult != 0) { + newTemp += prevPidResult; + } + } else { // default temp, manual mode newTemp = settings.emergency.target; @@ -126,7 +147,7 @@ protected: prevEtResult = etResult; newTemp += etResult; - Log.sinfoln("REGULATOR.EQUITHERM", F("New result: %u (%f)"), (int) round(etResult), etResult); + Log.sinfoln("REGULATOR.EQUITHERM", F("New result: %hhu (%f)"), (uint8_t) round(etResult), etResult); } else { newTemp += prevEtResult; @@ -144,7 +165,7 @@ protected: prevPidResult = pidResult; newTemp += pidResult; - Log.sinfoln("REGULATOR.PID", F("New result: %d (%f)"), (int) round(pidResult), pidResult); + Log.sinfoln("REGULATOR.PID", F("New result: %hh (%f)"), (int8_t) round(pidResult), pidResult); } else { newTemp += prevPidResult; diff --git a/src/Settings.h b/src/Settings.h index 40adbf3..6e8b607 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -28,6 +28,7 @@ struct Settings { bool enable = true; float target = 40.0f; bool useEquitherm = false; + bool usePid = false; } emergency; struct {