mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-26 01:53:35 +05:00
Compare commits
6 Commits
new-equith
...
ae434b751a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae434b751a | ||
|
|
77d80225ad | ||
|
|
dc68315166 | ||
|
|
5d0ca68dc0 | ||
|
|
d50b70c211 | ||
|
|
dd53d1ef3e |
@@ -7,7 +7,7 @@ public:
|
|||||||
typedef std::function<void(unsigned long, byte)> BeforeSendRequestCallback;
|
typedef std::function<void(unsigned long, byte)> BeforeSendRequestCallback;
|
||||||
typedef std::function<void(unsigned long, unsigned long, OpenThermResponseStatus, byte)> AfterSendRequestCallback;
|
typedef std::function<void(unsigned long, unsigned long, OpenThermResponseStatus, byte)> AfterSendRequestCallback;
|
||||||
|
|
||||||
CustomOpenTherm(int inPin = 4, int outPin = 5, bool isSlave = false) : OpenTherm(inPin, outPin, isSlave) {}
|
CustomOpenTherm(int inPin = 4, int outPin = 5, bool isSlave = false, bool alwaysReceive = false) : OpenTherm(inPin, outPin, isSlave, alwaysReceive) {}
|
||||||
~CustomOpenTherm() {}
|
~CustomOpenTherm() {}
|
||||||
|
|
||||||
CustomOpenTherm* setDelayCallback(DelayCallback callback = nullptr) {
|
CustomOpenTherm* setDelayCallback(DelayCallback callback = nullptr) {
|
||||||
@@ -28,8 +28,8 @@ public:
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long sendRequest(unsigned long request, byte attempts = 5, byte _attempt = 0) {
|
unsigned long sendRequest(unsigned long request) override {
|
||||||
_attempt++;
|
this->sendRequestAttempt++;
|
||||||
|
|
||||||
while (!this->isReady()) {
|
while (!this->isReady()) {
|
||||||
if (this->delayCallback) {
|
if (this->delayCallback) {
|
||||||
@@ -40,15 +40,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->beforeSendRequestCallback) {
|
if (this->beforeSendRequestCallback) {
|
||||||
this->beforeSendRequestCallback(request, _attempt);
|
this->beforeSendRequestCallback(request, this->sendRequestAttempt);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long _response;
|
if (this->sendRequestAsync(request)) {
|
||||||
OpenThermResponseStatus _responseStatus = OpenThermResponseStatus::NONE;
|
|
||||||
if (!this->sendRequestAsync(request)) {
|
|
||||||
_response = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
do {
|
do {
|
||||||
if (this->delayCallback) {
|
if (this->delayCallback) {
|
||||||
this->delayCallback(150);
|
this->delayCallback(150);
|
||||||
@@ -56,42 +51,25 @@ public:
|
|||||||
|
|
||||||
this->process();
|
this->process();
|
||||||
} while (this->status != OpenThermStatus::READY && this->status != OpenThermStatus::DELAY);
|
} while (this->status != OpenThermStatus::READY && this->status != OpenThermStatus::DELAY);
|
||||||
|
|
||||||
_response = this->getLastResponse();
|
|
||||||
_responseStatus = this->getLastResponseStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->afterSendRequestCallback) {
|
if (this->afterSendRequestCallback) {
|
||||||
this->afterSendRequestCallback(request, _response, _responseStatus, _attempt);
|
this->afterSendRequestCallback(request, this->response, this->responseStatus, this->sendRequestAttempt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_responseStatus == OpenThermResponseStatus::SUCCESS || _responseStatus == OpenThermResponseStatus::INVALID || _attempt >= attempts) {
|
if (this->responseStatus == OpenThermResponseStatus::SUCCESS || this->responseStatus == OpenThermResponseStatus::INVALID) {
|
||||||
return _response;
|
this->sendRequestAttempt = 0;
|
||||||
|
return this->response;
|
||||||
|
|
||||||
|
} else if (this->sendRequestAttempt >= this->sendRequestMaxAttempts) {
|
||||||
|
this->sendRequestAttempt = 0;
|
||||||
|
return this->response;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return this->sendRequest(request, attempts, _attempt);
|
return this->sendRequest(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long setBoilerStatus(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2, bool summerWinterMode, bool dhwBlocking, uint8_t lb = 0) {
|
|
||||||
unsigned int data = enableCentralHeating
|
|
||||||
| (enableHotWater << 1)
|
|
||||||
| (enableCooling << 2)
|
|
||||||
| (enableOutsideTemperatureCompensation << 3)
|
|
||||||
| (enableCentralHeating2 << 4)
|
|
||||||
| (summerWinterMode << 5)
|
|
||||||
| (dhwBlocking << 6);
|
|
||||||
|
|
||||||
data <<= 8;
|
|
||||||
data |= lb;
|
|
||||||
|
|
||||||
return this->sendRequest(buildRequest(
|
|
||||||
OpenThermMessageType::READ_DATA,
|
|
||||||
OpenThermMessageID::Status,
|
|
||||||
data
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sendBoilerReset() {
|
bool sendBoilerReset() {
|
||||||
unsigned int data = 1;
|
unsigned int data = 1;
|
||||||
data <<= 8;
|
data <<= 8;
|
||||||
@@ -134,6 +112,27 @@ public:
|
|||||||
return (byte)id == responseId;
|
return (byte)id == responseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t getResponseMessageTypeId(unsigned long response) {
|
||||||
|
return (response << 1) >> 29;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* getResponseMessageTypeString(unsigned long response) {
|
||||||
|
uint8_t msgType = getResponseMessageTypeId(response);
|
||||||
|
|
||||||
|
switch (msgType) {
|
||||||
|
case (uint8_t) OpenThermMessageType::READ_ACK:
|
||||||
|
case (uint8_t) OpenThermMessageType::WRITE_ACK:
|
||||||
|
case (uint8_t) OpenThermMessageType::DATA_INVALID:
|
||||||
|
case (uint8_t) OpenThermMessageType::UNKNOWN_DATA_ID:
|
||||||
|
return CustomOpenTherm::messageTypeToString(
|
||||||
|
static_cast<OpenThermMessageType>(msgType)
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// converters
|
// converters
|
||||||
template <class T>
|
template <class T>
|
||||||
static unsigned int toFloat(const T val) {
|
static unsigned int toFloat(const T val) {
|
||||||
@@ -145,6 +144,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const uint8_t sendRequestMaxAttempts = 5;
|
||||||
|
uint8_t sendRequestAttempt = 0;
|
||||||
DelayCallback delayCallback;
|
DelayCallback delayCallback;
|
||||||
BeforeSendRequestCallback beforeSendRequestCallback;
|
BeforeSendRequestCallback beforeSendRequestCallback;
|
||||||
AfterSendRequestCallback afterSendRequestCallback;
|
AfterSendRequestCallback afterSendRequestCallback;
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ extra_configs = secrets.default.ini
|
|||||||
core_dir = .pio
|
core_dir = .pio
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
version = 1.5.3
|
version = 1.5.4
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson@^7.3.0
|
bblanchon/ArduinoJson@^7.3.0
|
||||||
;ihormelnyk/OpenTherm Library@^1.1.5
|
;ihormelnyk/OpenTherm Library@^1.1.5
|
||||||
https://github.com/ihormelnyk/opentherm_library#master
|
https://github.com/Laxilef/opentherm_library#esp32_timer
|
||||||
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
|
||||||
|
|||||||
@@ -93,8 +93,13 @@ protected:
|
|||||||
this->instance->setAfterSendRequestCallback([this](unsigned long request, unsigned long response, OpenThermResponseStatus status, byte attempt) {
|
this->instance->setAfterSendRequestCallback([this](unsigned long request, unsigned long response, OpenThermResponseStatus status, byte attempt) {
|
||||||
Log.sverboseln(
|
Log.sverboseln(
|
||||||
FPSTR(L_OT),
|
FPSTR(L_OT),
|
||||||
F("ID: %4d Request: %8lx Response: %8lx Attempt: %2d Status: %s"),
|
F("ID: %4d Request: %8lx Response: %8lx Msg type: %s Attempt: %2d Status: %s"),
|
||||||
CustomOpenTherm::getDataID(request), request, response, attempt, CustomOpenTherm::statusToString(status)
|
CustomOpenTherm::getDataID(request),
|
||||||
|
request,
|
||||||
|
response,
|
||||||
|
CustomOpenTherm::getResponseMessageTypeString(response),
|
||||||
|
attempt,
|
||||||
|
CustomOpenTherm::statusToString(status)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (status == OpenThermResponseStatus::SUCCESS) {
|
if (status == OpenThermResponseStatus::SUCCESS) {
|
||||||
@@ -138,7 +143,12 @@ protected:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (this->instance->status == OpenThermStatus::NOT_INITIALIZED) {
|
} else if (this->instance->status == OpenThermStatus::NOT_INITIALIZED) {
|
||||||
this->instance->begin();
|
if (!this->instance->begin()) {
|
||||||
|
Log.swarningln(FPSTR(L_OT), F("Failed begin"));
|
||||||
|
|
||||||
|
this->delay(5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RX LED GPIO setup
|
// RX LED GPIO setup
|
||||||
@@ -212,6 +222,20 @@ protected:
|
|||||||
F("Failed receive boiler status: %s"),
|
F("Failed receive boiler status: %s"),
|
||||||
CustomOpenTherm::statusToString(this->instance->getLastResponseStatus())
|
CustomOpenTherm::statusToString(this->instance->getLastResponseStatus())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
vars.slave.heating.active = CustomOpenTherm::isCentralHeatingActive(response);
|
||||||
|
vars.slave.dhw.active = settings.opentherm.options.dhwSupport ? CustomOpenTherm::isHotWaterActive(response) : false;
|
||||||
|
vars.slave.flame = CustomOpenTherm::isFlameOn(response);
|
||||||
|
vars.slave.cooling = CustomOpenTherm::isCoolingActive(response);
|
||||||
|
vars.slave.fault.active = CustomOpenTherm::isFault(response);
|
||||||
|
vars.slave.diag.active = CustomOpenTherm::isDiagnostic(response);
|
||||||
|
|
||||||
|
Log.snoticeln(
|
||||||
|
FPSTR(L_OT), F("Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; cooling: %hhu; fault: %hhu; diag: %hhu"),
|
||||||
|
vars.slave.heating.active, vars.slave.dhw.active,
|
||||||
|
vars.slave.flame, vars.slave.cooling, vars.slave.fault.active, vars.slave.diag.active
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5 request retries
|
// 5 request retries
|
||||||
@@ -310,19 +334,6 @@ protected:
|
|||||||
Log.sinfoln(FPSTR(L_OT_DHW), vars.master.dhw.enabled ? F("Enabled") : F("Disabled"));
|
Log.sinfoln(FPSTR(L_OT_DHW), vars.master.dhw.enabled ? F("Enabled") : F("Disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.slave.heating.active = CustomOpenTherm::isCentralHeatingActive(response);
|
|
||||||
vars.slave.dhw.active = settings.opentherm.options.dhwSupport ? CustomOpenTherm::isHotWaterActive(response) : false;
|
|
||||||
vars.slave.flame = CustomOpenTherm::isFlameOn(response);
|
|
||||||
vars.slave.cooling = CustomOpenTherm::isCoolingActive(response);
|
|
||||||
vars.slave.fault.active = CustomOpenTherm::isFault(response);
|
|
||||||
vars.slave.diag.active = CustomOpenTherm::isDiagnostic(response);
|
|
||||||
|
|
||||||
Log.snoticeln(
|
|
||||||
FPSTR(L_OT), F("Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; cooling: %hhu; fault: %hhu; diag: %hhu"),
|
|
||||||
vars.slave.heating.active, vars.slave.dhw.active,
|
|
||||||
vars.slave.flame, vars.slave.cooling, vars.slave.fault.active, vars.slave.diag.active
|
|
||||||
);
|
|
||||||
|
|
||||||
// These parameters will be updated every minute
|
// These parameters will be updated every minute
|
||||||
if (millis() - this->prevUpdateNonEssentialVars > 60000) {
|
if (millis() - this->prevUpdateNonEssentialVars > 60000) {
|
||||||
if (this->updateMinModulationLevel()) {
|
if (this->updateMinModulationLevel()) {
|
||||||
@@ -1179,17 +1190,17 @@ protected:
|
|||||||
|
|
||||||
bool needSetDhwTemp(const float target) {
|
bool needSetDhwTemp(const float target) {
|
||||||
return millis() - this->dhwSetTempTime > this->dhwSetTempInterval
|
return millis() - this->dhwSetTempTime > this->dhwSetTempInterval
|
||||||
|| fabsf(target - vars.slave.dhw.targetTemp) > 0.001f;
|
|| fabsf(target - vars.slave.dhw.targetTemp) > 0.05f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needSetHeatingTemp(const float target) {
|
bool needSetHeatingTemp(const float target) {
|
||||||
return millis() - this->heatingSetTempTime > this->heatingSetTempInterval
|
return millis() - this->heatingSetTempTime > this->heatingSetTempInterval
|
||||||
|| fabsf(target - vars.slave.heating.targetTemp) > 0.001f;
|
|| fabsf(target - vars.slave.heating.targetTemp) > 0.05f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needSetCh2Temp(const float target) {
|
bool needSetCh2Temp(const float target) {
|
||||||
return millis() - this->ch2SetTempTime > this->ch2SetTempInterval
|
return millis() - this->ch2SetTempTime > this->ch2SetTempInterval
|
||||||
|| fabsf(target - vars.slave.ch2.targetTemp) > 0.001f;
|
|| fabsf(target - vars.slave.ch2.targetTemp) > 0.05f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateSlaveConfig() {
|
bool updateSlaveConfig() {
|
||||||
@@ -1350,7 +1361,7 @@ protected:
|
|||||||
return CustomOpenTherm::getUInt(response) == request;
|
return CustomOpenTherm::getUInt(response) == request;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setMaxHeatingTemp(const uint8_t temperature) {
|
bool setMaxHeatingTemp(const float temperature) {
|
||||||
const unsigned int request = CustomOpenTherm::temperatureToData(temperature);
|
const unsigned int request = CustomOpenTherm::temperatureToData(temperature);
|
||||||
const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
OpenThermMessageType::WRITE_DATA,
|
OpenThermMessageType::WRITE_DATA,
|
||||||
|
|||||||
Reference in New Issue
Block a user