feature: use pid in emergency mode

This commit is contained in:
Yurii
2023-12-19 16:44:54 +03:00
parent c87e08c6af
commit 4bf3b575db
5 changed files with 89 additions and 5 deletions

View File

@@ -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;

View File

@@ -3,6 +3,8 @@
#include <MqttWriter.h>
#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<bool>()) {
settings.emergency.useEquitherm = doc["emergency"]["useEquitherm"].as<bool>();
if (settings.sensors.outdoor.type != 1) {
settings.emergency.useEquitherm = doc["emergency"]["useEquitherm"].as<bool>();
} 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<bool>()) {
if (settings.sensors.indoor.type != 1) {
settings.emergency.usePid = doc["emergency"]["usePid"].as<bool>();
} 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<unsigned char>()) {
if (doc["sensors"]["outdoor"]["type"].as<unsigned char>() >= 0 && doc["sensors"]["outdoor"]["type"].as<unsigned char>() <= 2) {
settings.sensors.outdoor.type = doc["sensors"]["outdoor"]["type"].as<unsigned char>();
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<unsigned char>()) {
if (doc["sensors"]["indoor"]["type"].as<unsigned char>() >= 1 && doc["sensors"]["indoor"]["type"].as<unsigned char>() <= 3) {
settings.sensors.indoor.type = doc["sensors"]["indoor"]["type"].as<unsigned char>();
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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -28,6 +28,7 @@ struct Settings {
bool enable = true;
float target = 40.0f;
bool useEquitherm = false;
bool usePid = false;
} emergency;
struct {