mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-10 18:24:27 +05:00
feat: added OT option to set date and time on the boiler
This commit is contained in:
@@ -351,6 +351,35 @@ protected:
|
||||
|
||||
// These parameters will be updated every minute
|
||||
if (millis() - this->prevUpdateNonEssentialVars > 60000) {
|
||||
// Set date & time
|
||||
if (settings.opentherm.options.setDateAndTime) {
|
||||
struct tm ti;
|
||||
|
||||
if (getLocalTime(&ti)) {
|
||||
if (this->setYear(&ti)) {
|
||||
Log.sinfoln(FPSTR(L_OT), F("Year of date set successfully"));
|
||||
|
||||
} else {
|
||||
Log.sinfoln(FPSTR(L_OT), F("Failed set year of date"));
|
||||
}
|
||||
|
||||
if (this->setDayAndMonth(&ti)) {
|
||||
Log.sinfoln(FPSTR(L_OT), F("Day and month of date set successfully"));
|
||||
|
||||
} else {
|
||||
Log.sinfoln(FPSTR(L_OT), F("Failed set day and month of date"));
|
||||
}
|
||||
|
||||
if (this->setTime(&ti)) {
|
||||
Log.sinfoln(FPSTR(L_OT), F("Time set successfully"));
|
||||
|
||||
} else {
|
||||
Log.sinfoln(FPSTR(L_OT), F("Failed set time"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get min modulation level & max power
|
||||
if (this->updateMinModulationLevel()) {
|
||||
Log.snoticeln(
|
||||
FPSTR(L_OT), F("Received min modulation: %hhu%%, max power: %.2f kW"),
|
||||
@@ -1370,6 +1399,65 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setYear(const struct tm *ptm) {
|
||||
const unsigned int request = (ptm->tm_year + 1900) & 0xFFFF;
|
||||
const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||
OpenThermRequestType::WRITE_DATA,
|
||||
OpenThermMessageID::Year,
|
||||
request
|
||||
));
|
||||
|
||||
if (!CustomOpenTherm::isValidResponse(response)) {
|
||||
return false;
|
||||
|
||||
} else if (!CustomOpenTherm::isValidResponseId(response, OpenThermMessageID::Year)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CustomOpenTherm::getUInt(response) == request;
|
||||
}
|
||||
|
||||
bool setDayAndMonth(const struct tm *ptm) {
|
||||
const unsigned int request = ((ptm->tm_mon + 1) & 0xFF << 8)
|
||||
| (ptm->tm_mday & 0xFF);
|
||||
|
||||
const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||
OpenThermRequestType::WRITE_DATA,
|
||||
OpenThermMessageID::Date,
|
||||
request
|
||||
));
|
||||
|
||||
if (!CustomOpenTherm::isValidResponse(response)) {
|
||||
return false;
|
||||
|
||||
} else if (!CustomOpenTherm::isValidResponseId(response, OpenThermMessageID::Date)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CustomOpenTherm::getUInt(response) == request;
|
||||
}
|
||||
|
||||
bool setTime(const struct tm *ptm) {
|
||||
const uint8_t dayOfWeek = ptm->tm_wday == 0 ? 6 : ptm->tm_wday - 1;
|
||||
const unsigned int request = ((dayOfWeek & 0x07) << 13)
|
||||
| ((ptm->tm_hour & 0x1F) << 8)
|
||||
| (ptm->tm_min & 0x3F);
|
||||
|
||||
const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||
OpenThermRequestType::WRITE_DATA,
|
||||
OpenThermMessageID::DayTime,
|
||||
request
|
||||
));
|
||||
|
||||
if (!CustomOpenTherm::isValidResponse(response)) {
|
||||
return false;
|
||||
|
||||
} else if (!CustomOpenTherm::isValidResponseId(response, OpenThermMessageID::DayTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CustomOpenTherm::getUInt(response) == request;
|
||||
}
|
||||
|
||||
bool setMaxModulationLevel(const uint8_t value) {
|
||||
const unsigned int request = CustomOpenTherm::toFloat(value);
|
||||
|
||||
@@ -76,6 +76,7 @@ struct Settings {
|
||||
bool ignoreDiagState = false;
|
||||
bool autoFaultReset = false;
|
||||
bool autoDiagReset = false;
|
||||
bool setDateAndTime = false;
|
||||
bool nativeHeatingControl = false;
|
||||
bool immergasFix = false;
|
||||
} options;
|
||||
|
||||
@@ -175,6 +175,7 @@ const char S_SENSORS[] PROGMEM = "sensors";
|
||||
const char S_SERIAL[] PROGMEM = "serial";
|
||||
const char S_SERVER[] PROGMEM = "server";
|
||||
const char S_SETTINGS[] PROGMEM = "settings";
|
||||
const char S_SET_DATE_AND_TIME[] PROGMEM = "setDateAndTime";
|
||||
const char S_SIGNAL_QUALITY[] PROGMEM = "signalQuality";
|
||||
const char S_SIZE[] PROGMEM = "size";
|
||||
const char S_SLAVE[] PROGMEM = "slave";
|
||||
|
||||
10
src/utils.h
10
src/utils.h
@@ -466,6 +466,7 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
||||
otOptions[FPSTR(S_IGNORE_DIAG_STATE)] = src.opentherm.options.ignoreDiagState;
|
||||
otOptions[FPSTR(S_AUTO_FAULT_RESET)] = src.opentherm.options.autoFaultReset;
|
||||
otOptions[FPSTR(S_AUTO_DIAG_RESET)] = src.opentherm.options.autoDiagReset;
|
||||
otOptions[FPSTR(S_SET_DATE_AND_TIME)] = src.opentherm.options.setDateAndTime;
|
||||
otOptions[FPSTR(S_NATIVE_HEATING_CONTROL)] = src.opentherm.options.nativeHeatingControl;
|
||||
otOptions[FPSTR(S_IMMERGAS_FIX)] = src.opentherm.options.immergasFix;
|
||||
|
||||
@@ -967,6 +968,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
||||
}
|
||||
}
|
||||
|
||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SET_DATE_AND_TIME)].is<bool>()) {
|
||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SET_DATE_AND_TIME)].as<bool>();
|
||||
|
||||
if (value != dst.opentherm.options.setDateAndTime) {
|
||||
dst.opentherm.options.setDateAndTime = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_NATIVE_HEATING_CONTROL)].is<bool>()) {
|
||||
bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_NATIVE_HEATING_CONTROL)].as<bool>();
|
||||
|
||||
|
||||
@@ -409,6 +409,7 @@
|
||||
"ignoreDiagState": "Ignore diag state",
|
||||
"autoFaultReset": "Auto fault reset <small>(not recommended!)</small>",
|
||||
"autoDiagReset": "Auto diag reset <small>(not recommended!)</small>",
|
||||
"setDateAndTime": "Set date & time on boiler",
|
||||
"immergasFix": "Fix for Immergas boilers"
|
||||
},
|
||||
|
||||
|
||||
@@ -409,6 +409,7 @@
|
||||
"ignoreDiagState": "Ignora lo stato diagnostico",
|
||||
"autoFaultReset": "Ripristino automatico degli errori <small>(sconsigliato!)</small>",
|
||||
"autoDiagReset": "Ripristino diagnostico automatica <small>(sconsigliato!)</small>",
|
||||
"setDateAndTime": "Imposta data e ora sulla caldaia",
|
||||
"immergasFix": "Fix per caldiaie Immergas"
|
||||
},
|
||||
|
||||
|
||||
@@ -409,6 +409,7 @@
|
||||
"ignoreDiagState": "Игнорировать состояние диагностики",
|
||||
"autoFaultReset": "Автоматический сброс ошибок <small>(не рекомендуется!)</small>",
|
||||
"autoDiagReset": "Автоматический сброс диагностики <small>(не рекомендуется!)</small>",
|
||||
"setDateAndTime": "Устанавливать время и дату на котле",
|
||||
"immergasFix": "Фикс для котлов Immergas"
|
||||
},
|
||||
|
||||
|
||||
@@ -551,6 +551,11 @@
|
||||
<span data-i18n>settings.ot.options.autoDiagReset</span>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" name="opentherm[options][setDateAndTime]" value="true">
|
||||
<span data-i18n>settings.ot.options.setDateAndTime</span>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" name="opentherm[options][immergasFix]" value="true">
|
||||
<span data-i18n>settings.ot.options.immergasFix</span>
|
||||
@@ -818,6 +823,7 @@
|
||||
setCheckboxValue("[name='opentherm[options][ignoreDiagState]']", data.opentherm.options.ignoreDiagState);
|
||||
setCheckboxValue("[name='opentherm[options][autoFaultReset]']", data.opentherm.options.autoFaultReset);
|
||||
setCheckboxValue("[name='opentherm[options][autoDiagReset]']", data.opentherm.options.autoDiagReset);
|
||||
setCheckboxValue("[name='opentherm[options][setDateAndTime]']", data.opentherm.options.setDateAndTime);
|
||||
setCheckboxValue("[name='opentherm[options][nativeHeatingControl]']", data.opentherm.options.nativeHeatingControl);
|
||||
setCheckboxValue("[name='opentherm[options][immergasFix]']", data.opentherm.options.immergasFix);
|
||||
setBusy('#ot-settings-busy', '#ot-settings', false);
|
||||
|
||||
Reference in New Issue
Block a user