mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-14 19:59:53 +03:00
3.7.1
This commit is contained in:
@@ -138,6 +138,20 @@ void AnalogSensor::reload(bool get_nvs) {
|
||||
continue; // skip this loop pass
|
||||
}
|
||||
|
||||
if ((sensor.gpio() == 25 || sensor.gpio() == 26)
|
||||
&& (sensor.type() == AnalogType::COUNTER || sensor.type() == AnalogType::DIGITAL_IN || sensor.type() == AnalogType::RATE
|
||||
|| sensor.type() == AnalogType::TIMER)) {
|
||||
// pullup is mapped to DAC, so set to 3.3V
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
||||
dacWrite(sensor.gpio(), 255);
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
if (sensor.gpio() == 17 || sensor.gpio() == 18) {
|
||||
dacWrite(sensor.gpio(), 255);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (sensor.type() == AnalogType::ADC) {
|
||||
LOG_DEBUG("ADC Sensor on GPIO %02d", sensor.gpio());
|
||||
// analogSetPinAttenuation does not work with analogReadMilliVolts
|
||||
@@ -146,15 +160,6 @@ void AnalogSensor::reload(bool get_nvs) {
|
||||
} else if (sensor.type() == AnalogType::COUNTER) {
|
||||
LOG_DEBUG("I/O Counter on GPIO %02d", sensor.gpio());
|
||||
pinMode(sensor.gpio(), INPUT_PULLUP);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (sensor.gpio() == 25 || sensor.gpio() == 26) {
|
||||
dacWrite(sensor.gpio(), 255);
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
if (sensor.gpio() == 23 || sensor.gpio() == 24) {
|
||||
dacWrite(sensor.gpio(), 255);
|
||||
}
|
||||
#endif
|
||||
sensor.polltime_ = 0;
|
||||
sensor.poll_ = digitalRead(sensor.gpio());
|
||||
if (double_t val = EMSESP::nvs_.getDouble(sensor.name().c_str(), 0)) {
|
||||
@@ -192,7 +197,7 @@ void AnalogSensor::reload(bool get_nvs) {
|
||||
sensor.set_value(sensor.offset());
|
||||
} else
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
if (sensor.gpio() == 23 || sensor.gpio() == 24) {
|
||||
if (sensor.gpio() == 17 || sensor.gpio() == 18) {
|
||||
if (sensor.offset() > 255) {
|
||||
sensor.set_offset(255);
|
||||
} else if (sensor.offset() < 0) {
|
||||
@@ -533,7 +538,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
char val_obj[50];
|
||||
char val_cond[95];
|
||||
if (Mqtt::is_nested()) {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%02d'].value", sensor.gpio());
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%02d']['value']", sensor.gpio());
|
||||
snprintf(val_cond, sizeof(val_cond), "value_json['%02d'] is defined and %s is defined", sensor.gpio(), val_obj);
|
||||
} else {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str());
|
||||
@@ -745,7 +750,7 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
||||
dacWrite(sensor.gpio(), sensor.offset());
|
||||
} else
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
if ((sensor.gpio() == 23 || sensor.gpio() == 24) && v <= 255) {
|
||||
if ((sensor.gpio() == 17 || sensor.gpio() == 18) && v <= 255) {
|
||||
sensor.set_offset(v);
|
||||
sensor.set_value(v);
|
||||
pinMode(sensor.gpio(), OUTPUT);
|
||||
|
||||
@@ -379,17 +379,6 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
|
||||
return CommandRet::NOT_ALLOWED; // command not allowed
|
||||
}
|
||||
|
||||
// build up the log string for reporting back
|
||||
// We send the log message as Warning so it appears in the log (debug is only enabled when compiling with DEBUG)
|
||||
std::string ro = EMSESP::system_.readonly_mode() ? "[readonly] " : "";
|
||||
auto description = Helpers::translated_word(cf->description_);
|
||||
char info_s[100];
|
||||
if (strlen(description)) {
|
||||
snprintf(info_s, sizeof(info_s), "%s/%s (%s)", dname, cmd, description);
|
||||
} else {
|
||||
snprintf(info_s, sizeof(info_s), "%s/%s", dname, cmd);
|
||||
}
|
||||
|
||||
// call the function based on command function type
|
||||
// commands return true or false only (bool)
|
||||
uint8_t return_code = CommandRet::OK;
|
||||
@@ -406,7 +395,7 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
|
||||
}
|
||||
}
|
||||
|
||||
// report back. If not OK show output from error, otherwise return the HTTP code
|
||||
// report back. If not OK show output from error, otherwise return the error code
|
||||
if (return_code != CommandRet::OK) {
|
||||
char error[100];
|
||||
if (single_command) {
|
||||
@@ -418,6 +407,16 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
|
||||
output["message"] = error;
|
||||
LOG_WARNING(error);
|
||||
} else {
|
||||
// build up the log string for reporting back
|
||||
// We send the log message as Warning so it appears in the log (debug is only enabled when compiling with DEBUG)
|
||||
std::string ro = EMSESP::system_.readonly_mode() ? "[readonly] " : "";
|
||||
auto description = Helpers::translated_word(cf->description_);
|
||||
char info_s[100];
|
||||
if (strlen(description)) {
|
||||
snprintf(info_s, sizeof(info_s), "%s/%s (%s)", dname, cmd, description);
|
||||
} else {
|
||||
snprintf(info_s, sizeof(info_s), "%s/%s", dname, cmd);
|
||||
}
|
||||
if (single_command) {
|
||||
// log as DEBUG (TRACE) regardless if compiled with EMSESP_DEBUG
|
||||
logger_.debug("%sCalled command %s", ro.c_str(), info_s);
|
||||
|
||||
14
src/common.h
14
src/common.h
@@ -52,13 +52,19 @@ using string_vector = std::vector<const char *>;
|
||||
#define F_(string_name) (__pstr__##string_name)
|
||||
#define FL_(list_name) (__pstr__L_##list_name)
|
||||
|
||||
#if defined(EMSESP_TEST) || defined(EMSESP_EN_ONLY)
|
||||
// In testing just take one language (en) to save on Flash space
|
||||
// The language settings below must match system.cpp
|
||||
#if defined(EMSESP_TEST)
|
||||
// in Test mode use two languages (en & de) to save flash memory needed for the tests
|
||||
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {en, de, nullptr};
|
||||
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, de, nullptr};
|
||||
#elif defined(EMSESP_EN_ONLY)
|
||||
// EN only
|
||||
#define MAKE_WORD_TRANSLATION(list_name, en, ...) static const char * const __pstr__L_##list_name[] = {en, nullptr};
|
||||
#define MAKE_TRANSLATION(list_name, shortname, en, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, nullptr};
|
||||
#elif defined(EMSESP_DE_ONLY)
|
||||
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {de, nullptr};
|
||||
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, de, nullptr};
|
||||
// EN + DE
|
||||
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {en, de, nullptr};
|
||||
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, de, nullptr};
|
||||
#else
|
||||
#define MAKE_WORD_TRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
||||
#define MAKE_TRANSLATION(list_name, ...) static const char * const __pstr__L_##list_name[] = {__VA_ARGS__, nullptr};
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
// Mixer Modules - 0x20-0x27 for HC, 0x28-0x29 for WWC and 0x11 for the MP100
|
||||
{ 69, DeviceType::MIXER, "MM10", DeviceFlags::EMS_DEVICE_FLAG_MM10},
|
||||
{100, DeviceType::MIXER, "IPM", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{102, DeviceType::MIXER, "IPM", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{102, DeviceType::MIXER, "IPM2", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{159, DeviceType::MIXER, "MM50", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{160, DeviceType::MIXER, "MM100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{161, DeviceType::MIXER, "MM200", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
@@ -180,10 +180,23 @@
|
||||
{ 74, DeviceType::ALERT, "EM10", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Gateways - 0x48
|
||||
{17, DeviceType::GATEWAY, "MX400", DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x48 and 0x4B
|
||||
{189, DeviceType::GATEWAY, "KM200, MB LAN 2", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{252, DeviceType::GATEWAY, "K30RF, MX300", DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
|
||||
// Generic - 0x40 or other with no product-id and no version
|
||||
{0, DeviceType::GENERIC, "unknown", DeviceFlags::EMS_DEVICE_FLAG_NONE}
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
,
|
||||
{100, DeviceType::WATER, "IPM", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{102, DeviceType::WATER, "IPM2", DeviceFlags::EMS_DEVICE_FLAG_IPM},
|
||||
{160, DeviceType::WATER, "MM100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{161, DeviceType::WATER, "MM200", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{163, DeviceType::WATER, "SM100, MS100", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{164, DeviceType::WATER, "SM200, MS200", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{248, DeviceType::MIXER, "HM210", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{157, DeviceType::THERMOSTAT, "RC120", DeviceFlags::EMS_DEVICE_FLAG_CR120}
|
||||
#endif
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -520,7 +520,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &totalCompStarts_, DeviceValueType::UINT24, FL_(totalCompStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingStarts_, DeviceValueType::UINT24, FL_(heatingStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &coolingStarts_, DeviceValueType::UINT24, FL_(coolingStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &wwStarts2_, DeviceValueType::UINT24, FL_(wwStarts2), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &wwStartsHp_, DeviceValueType::UINT24, FL_(wwStartsHp), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolStarts_, DeviceValueType::UINT24, FL_(poolStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::UINT24, FL_(nrgConsTotal), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::UINT24, FL_(nrgConsCompTotal), DeviceValueUOM::KWH);
|
||||
@@ -555,6 +555,15 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
FL_(pvMaxComp),
|
||||
DeviceValueUOM::KW,
|
||||
MAKE_CF_CB(set_pvMaxComp));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&powerReduction_,
|
||||
DeviceValueType::UINT8,
|
||||
DeviceValueNumOp::DV_NUMOP_MUL10,
|
||||
FL_(powerReduction),
|
||||
DeviceValueUOM::PERCENT,
|
||||
MAKE_CF_CB(set_powerReduction),
|
||||
30,
|
||||
60);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&hpSetDiffPress_,
|
||||
DeviceValueType::UINT8,
|
||||
@@ -675,7 +684,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
FL_(auxHeaterOff),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_additionalHeater));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterStatus_, DeviceValueType::UINT8, FL_(auxHeaterStatus), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterStatus_, DeviceValueType::BOOL, FL_(auxHeaterStatus), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxHeaterLevel_, DeviceValueType::UINT8, FL_(auxHeaterLevel), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&auxHeaterDelay_,
|
||||
DeviceValueType::UINT16,
|
||||
@@ -1425,7 +1435,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
|
||||
|
||||
// at this point do a quick check to see if the hot water or heating is active
|
||||
uint8_t state = EMS_VALUE_UINT8_NOTSET;
|
||||
if (telegram->read_value(state, 11) && model() != EMSdevice::EMS_DEVICE_FLAG_HIU) {
|
||||
if (telegram->read_value(state, 11) && model() != EMSdevice::EMS_DEVICE_FLAG_HIU && model() != EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) {
|
||||
boilerState_ = state & 0x01 ? 0x08 : 0; // burnGas
|
||||
boilerState_ |= state & 0x02 ? 0x01 : 0; // heatingPump
|
||||
boilerState_ |= state & 0x04 ? 0x02 : 0; // 3-way-valve
|
||||
@@ -1464,7 +1474,7 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr<const Telegram> telegram) {
|
||||
*/
|
||||
void Boiler::process_UBAMonitorSlowPlus2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, absBurnPow_, 13); // current burner absolute power (percent of rating plate power)
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU) {
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_HIU || model() == EMSdevice::EMS_DEVICE_FLAG_HEATPUMP) {
|
||||
uint8_t state = EMS_VALUE_UINT8_NOTSET;
|
||||
boilerState_ = 0;
|
||||
if (telegram->read_value(state, 2)) {
|
||||
@@ -1605,7 +1615,7 @@ void Boiler::process_UBAInformation(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, totalCompStarts_, 20);
|
||||
has_update(telegram, heatingStarts_, 28);
|
||||
has_update(telegram, coolingStarts_, 36);
|
||||
has_update(telegram, wwStarts2_, 24);
|
||||
has_update(telegram, wwStartsHp_, 24);
|
||||
has_update(telegram, poolStarts_, 32);
|
||||
|
||||
has_update(telegram, nrgConsTotal_, 64);
|
||||
@@ -1652,7 +1662,7 @@ void Boiler::process_HpPower(std::shared_ptr<const Telegram> telegram) {
|
||||
has_bitupdate(telegram, hpEA0_, 3, 6);
|
||||
has_update(telegram, hpCircSpd_, 4);
|
||||
has_update(telegram, hpBrinePumpSpd_, 5);
|
||||
has_update(telegram, auxHeaterStatus_, 6);
|
||||
has_update(telegram, auxHeaterLevel_, 6);
|
||||
has_update(telegram, hpActivity_, 7);
|
||||
has_update(telegram, hpPower_, 11);
|
||||
has_update(telegram, hpCompSpd_, 17);
|
||||
@@ -1819,6 +1829,10 @@ void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
uint8_t min = telegram->message_data[8];
|
||||
uint16_t duration = telegram->message_data[9] * 256 + telegram->message_data[10];
|
||||
uint32_t date = (year - 2000) * 535680UL + month * 44640UL + day * 1440UL + hour * 60 + min + duration;
|
||||
// check valid https://github.com/emsesp/EMS-ESP32/issues/2189
|
||||
if (day == 0 || day > 31 || month == 0 || month > 12 || !std::isprint(code[0]) || !std::isprint(code[1])) {
|
||||
return;
|
||||
}
|
||||
// store only the newest code from telegrams 10 and 11
|
||||
if (date > lastCodeDate_ && lastCodeDate_) {
|
||||
lastCodeDate_ = date;
|
||||
@@ -1846,6 +1860,9 @@ void Boiler::process_UBAErrorMessage2(std::shared_ptr<const Telegram> telegram)
|
||||
code[2] = telegram->message_data[7];
|
||||
code[3] = 0;
|
||||
telegram->read_value(codeNo, 8);
|
||||
if (!std::isprint(code[0]) || !std::isprint(code[1]) || !std::isprint(code[2])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for valid date, https://github.com/emsesp/EMS-ESP32/issues/204
|
||||
if (telegram->message_data[10] & 0x80) {
|
||||
@@ -1937,15 +1954,16 @@ void Boiler::process_HpSilentMode(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, hpHystPool_, 33); // is / 5
|
||||
has_update(telegram, hpCircPumpWw_, 46);
|
||||
has_update(telegram, hpMaxPower_, 31);
|
||||
has_update(telegram, silentFrom_, 52); // in steps of 15 min
|
||||
has_update(telegram, silentTo_, 53); // in steps of 15 min
|
||||
has_update(telegram, pvMaxComp_, 54); // #2062
|
||||
has_update(telegram, hpshutdown_, 58); // 1 powers off
|
||||
has_update(telegram, silentFrom_, 52); // in steps of 15 min
|
||||
has_update(telegram, silentTo_, 53); // in steps of 15 min
|
||||
has_update(telegram, pvMaxComp_, 54); // #2062
|
||||
has_update(telegram, hpshutdown_, 58); // 1 powers off
|
||||
has_update(telegram, powerReduction_, 64); // 3..6 -> is *10
|
||||
}
|
||||
|
||||
// Boiler(0x08) -B-> All(0x00), ?(0x0488), data: 8E 00 00 00 00 00 01 03
|
||||
void Boiler::process_HpValve(std::shared_ptr<const Telegram> telegram) {
|
||||
// has_bitupdate(telegram, auxHeaterStatus_, 0, 2);
|
||||
has_bitupdate(telegram, auxHeaterStatus_, 0, 2);
|
||||
has_update(telegram, auxHeatMixValve_, 7);
|
||||
has_update(telegram, pc1Rate_, 13); // percent
|
||||
}
|
||||
@@ -2960,19 +2978,19 @@ bool Boiler::set_silentMode(const char * value, const int8_t id) {
|
||||
}
|
||||
|
||||
bool Boiler::set_silentFrom(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
if (value == nullptr || value[0] < '0' || value[0] > '9') {
|
||||
return false;
|
||||
}
|
||||
auto v = Helpers::string2minutes(value);
|
||||
write_command(0x484, 52, v / 15, 0x484);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Boiler::set_silentTo(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
if (value == nullptr || value[0] < '0' || value[0] > '9') {
|
||||
return false;
|
||||
}
|
||||
auto v = Helpers::string2minutes(value);
|
||||
write_command(0x484, 53, v / 15, 0x484);
|
||||
return true;
|
||||
}
|
||||
@@ -3154,6 +3172,15 @@ bool Boiler::set_hpPowerLimit(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_powerReduction(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (Helpers::value2number(value, v)) {
|
||||
write_command(0x484, 64, v / 10, 0x484);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Boiler::set_vp_cooling(const char * value, const int8_t id) {
|
||||
bool v;
|
||||
if (Helpers::value2bool(value, v)) {
|
||||
|
||||
@@ -85,7 +85,7 @@ class Boiler : public EMSdevice {
|
||||
uint8_t wwMaxPower_; // DHW maximum power
|
||||
uint8_t wwMaxTemp_; // DHW maximum temperature
|
||||
uint32_t wwStarts_; // DHW starts
|
||||
uint32_t wwStarts2_; // DHW control starts
|
||||
uint32_t wwStartsHp_; // DHW starts Heatpump
|
||||
uint32_t wwWorkM_; // DHW minutes
|
||||
int8_t wwHystOn_;
|
||||
int8_t wwHystOff_;
|
||||
@@ -256,6 +256,7 @@ class Boiler : public EMSdevice {
|
||||
uint8_t maxHeatDhw_;
|
||||
uint8_t hpMaxPower_;
|
||||
uint8_t pvMaxComp_;
|
||||
uint8_t powerReduction_;
|
||||
|
||||
uint8_t pvCooling_;
|
||||
uint8_t manDefrost_;
|
||||
@@ -265,6 +266,7 @@ class Boiler : public EMSdevice {
|
||||
uint8_t auxHeaterOnly_;
|
||||
uint8_t auxHeaterOff_;
|
||||
uint8_t auxHeaterStatus_;
|
||||
uint8_t auxHeaterLevel_;
|
||||
uint16_t auxHeaterDelay_;
|
||||
uint8_t silentMode_;
|
||||
int8_t minTempSilent_;
|
||||
@@ -332,7 +334,6 @@ class Boiler : public EMSdevice {
|
||||
uint8_t delayBoiler_; // minutes
|
||||
uint8_t tempDiffBoiler_; // relative temperature degrees
|
||||
*/
|
||||
|
||||
void process_UBAFactory(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAParameterWW(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMonitorFast(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -482,6 +483,7 @@ class Boiler : public EMSdevice {
|
||||
bool set_pvMaxComp(const char * value, const int8_t id);
|
||||
bool set_hpDiffPress(const char * value, const int8_t id);
|
||||
bool set_hpPowerLimit(const char * value, const int8_t id);
|
||||
bool set_powerReduction(const char * value, const int8_t id);
|
||||
|
||||
bool set_auxLimit(const char * value, const int8_t id);
|
||||
inline bool set_auxMaxLimit(const char * value, const int8_t id) {
|
||||
|
||||
@@ -35,6 +35,9 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
|
||||
register_telegram_type(0x99C, "HPComp", false, MAKE_PF_CB(process_HPComp));
|
||||
register_telegram_type(0x4AE, "HPEnergy", true, MAKE_PF_CB(process_HpEnergy));
|
||||
register_telegram_type(0x4AF, "HPMeters", true, MAKE_PF_CB(process_HpMeters));
|
||||
register_telegram_type(0x99A, "HPStarts", false, MAKE_PF_CB(process_HpStarts));
|
||||
register_telegram_type(0x12E, "HPEnergy1", false, MAKE_PF_CB(process_HpEnergy1));
|
||||
register_telegram_type(0x13B, "HPEnergy2", false, MAKE_PF_CB(process_HpEnergy2));
|
||||
|
||||
// device values
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT);
|
||||
@@ -81,40 +84,41 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
|
||||
FL_(lowNoiseMode),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_lowNoiseMode));
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStart_, DeviceValueType::UINT8, FL_(lowNoiseStart), DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseStart), 0, 23);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStop_, DeviceValueType::UINT8, FL_(lowNoiseStop), DeviceValueUOM::NONE, MAKE_CF_CB(set_lowNoiseStop), 0, 23);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&hybridDHW_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_comfort2),
|
||||
FL_(hybridDHW),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_hybridDHW));
|
||||
&lowNoiseStart_,
|
||||
DeviceValueType::UINT8,
|
||||
FL_(lowNoiseStart),
|
||||
DeviceValueUOM::HOURS,
|
||||
MAKE_CF_CB(set_lowNoiseStart),
|
||||
0,
|
||||
23);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_DEVICE_DATA, &lowNoiseStop_, DeviceValueType::UINT8, FL_(lowNoiseStop), DeviceValueUOM::HOURS, MAKE_CF_CB(set_lowNoiseStop), 0, 23);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_DHW1, &hybridDHW_, DeviceValueType::ENUM, FL_(enum_comfort2), FL_(hybridDHW), DeviceValueUOM::NONE, MAKE_CF_CB(set_hybridDHW));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&energyPriceGas_,
|
||||
DeviceValueType::UINT8,
|
||||
FL_(energyPriceGas),
|
||||
DeviceValueUOM::NONE,
|
||||
DeviceValueUOM::CTKWH,
|
||||
MAKE_CF_CB(set_energyPriceGas));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&energyPriceEl_,
|
||||
DeviceValueType::UINT8,
|
||||
FL_(energyPriceEl),
|
||||
DeviceValueUOM::NONE,
|
||||
DeviceValueUOM::CTKWH,
|
||||
MAKE_CF_CB(set_energyPriceEl));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&energyPricePV_,
|
||||
DeviceValueType::UINT8,
|
||||
FL_(energyPricePV),
|
||||
DeviceValueUOM::NONE,
|
||||
DeviceValueUOM::CTKWH,
|
||||
MAKE_CF_CB(set_energyPricePV));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&switchOverTemp_,
|
||||
DeviceValueType::INT8,
|
||||
FL_(switchOverTemp),
|
||||
DeviceValueUOM::NONE,
|
||||
DeviceValueUOM::DEGREES,
|
||||
MAKE_CF_CB(set_switchOverTemp));
|
||||
// Function test
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
@@ -176,6 +180,20 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
|
||||
FL_(meterHeat),
|
||||
DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &meterWw_, DeviceValueType::UINT24, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(meterWw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatStartsHp_, DeviceValueType::UINT24, FL_(heatingStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &wwStartsHp_, DeviceValueType::UINT24, FL_(wwStartsHp), DeviceValueUOM::NONE);
|
||||
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fuelHeat_, DeviceValueType::UINT32, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(fuelHeat), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &elDhw_, DeviceValueType::UINT32, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(fuelDhw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fuelHeat_, DeviceValueType::UINT32, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(elHeat), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &elDhw_, DeviceValueType::UINT32, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(elDhw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&elGenHeat_,
|
||||
DeviceValueType::UINT32,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(elGenHeat),
|
||||
DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DHW1, &elGenDhw_, DeviceValueType::UINT32, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(elGenDhw), DeviceValueUOM::KWH);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,6 +288,27 @@ void Heatpump::process_HpMeters(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, meterWw_, 32);
|
||||
}
|
||||
|
||||
// Broadcast (0x099A), data: 05 00 00 00 00 00 00 37 00 00 1D 00 00 52 00 00 13 01 00 01 7C
|
||||
void Heatpump::process_HpStarts(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, heatStartsHp_, 11, 3);
|
||||
has_update(telegram, wwStartsHp_, 14, 3);
|
||||
}
|
||||
|
||||
// 0x0112E energy consumption
|
||||
void Heatpump::process_HpEnergy1(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, fuelHeat_, 3);
|
||||
has_update(telegram, fuelDhw_, 7);
|
||||
has_update(telegram, elHeat_, 11);
|
||||
has_update(telegram, elDhw_, 15);
|
||||
}
|
||||
|
||||
// 0x013B energy generated
|
||||
void Heatpump::process_HpEnergy2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, elGenHeat_, 3);
|
||||
has_update(telegram, elGenDhw_, 7);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Broadcast (0x099A), data: 05 00 00 00 00 00 00 37 00 00 1D 00 00 52 00 00 13 01 00 01 7C
|
||||
* Broadcast (0x099B), data: 80 00 80 00 01 3C 01 38 80 00 80 00 80 00 01 37 00 00 00 00 64
|
||||
|
||||
@@ -76,6 +76,14 @@ class Heatpump : public EMSdevice {
|
||||
uint32_t meterHeat_;
|
||||
uint32_t meterWw_;
|
||||
|
||||
uint32_t heatStartsHp_;
|
||||
uint32_t wwStartsHp_;
|
||||
uint32_t fuelHeat_;
|
||||
uint32_t fuelDhw_;
|
||||
uint32_t elHeat_;
|
||||
uint32_t elDhw_;
|
||||
uint32_t elGenHeat_;
|
||||
uint32_t elGenDhw_;
|
||||
|
||||
void process_HPMonitor1(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HPMonitor2(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -86,6 +94,9 @@ class Heatpump : public EMSdevice {
|
||||
void process_HPComp(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpEnergy(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpMeters(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpStarts(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpEnergy1(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HpEnergy2(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
bool set_controlStrategy(const char * value, const int8_t id);
|
||||
bool set_lowNoiseMode(const char * value, const int8_t id);
|
||||
|
||||
@@ -206,6 +206,18 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(cyl2BottomTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&cylBottomTemp3_,
|
||||
DeviceValueType::INT16,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(cyl3BottomTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&cylTopTemp_,
|
||||
DeviceValueType::INT16,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV10,
|
||||
FL_(cylTopTemp),
|
||||
DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&heatExchangerTemp_,
|
||||
DeviceValueType::INT16,
|
||||
@@ -215,6 +227,9 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylPumpMod_, DeviceValueType::UINT8, FL_(cylPumpMod), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveStatus_, DeviceValueType::BOOL, FL_(valveStatus), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &vs1Status_, DeviceValueType::BOOL, FL_(vs1Status), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &vs3Status_, DeviceValueType::BOOL, FL_(vs3Status), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &transferPump_, DeviceValueType::BOOL, FL_(transferPump), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &transferPumpMod_, DeviceValueType::UINT8, FL_(transferPumpMod), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&collectorMaxTemp_,
|
||||
DeviceValueType::UINT8,
|
||||
@@ -580,20 +595,22 @@ void Solar::process_SM100Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, cylBottomTemp2_, 16); // is *10 - TS5: Temperature sensor 2 cylinder, bottom, or swimming pool
|
||||
has_update(telegram, heatExchangerTemp_, 20); // is *10 - TS6: Heat exchanger temperature sensor
|
||||
|
||||
has_update(telegram, collector2Temp_, 6); // is *10 - TS7: Temperature sensor for collector array 2
|
||||
has_update(telegram, cylMiddleTemp_, 8); // is *10 - TS14: cylinder middle temperature
|
||||
has_update(telegram, retHeatAssist_, 10); // is *10 - TS15: return temperature heating assistance
|
||||
has_update(telegram, collector2Temp_, 6); // is *10 - TS7: Temperature sensor for collector array 2
|
||||
has_update(telegram, cylMiddleTemp_, 8); // is *10 - TS14: cylinder middle temperature
|
||||
has_update(telegram, retHeatAssist_, 10); // is *10 - TS15: return temperature heating assistance
|
||||
has_update(telegram, cylBottomTemp3_, 24); // is *10 - TS5: Temperature sensor cylinder 3, bottom
|
||||
}
|
||||
|
||||
// SM100Monitor2 - 0x0363 Heatcounter
|
||||
// e.g. B0 00 FF 00 02 63 80 00 80 00 00 00 80 00 80 00 80 00 00 80 00 5A
|
||||
// Solar(0x30) -> All(0x00), SM100Monitor2(0x363), data: 01 E1 01 6B 00 00 01 5D 02 8E 80 00 0F 80 00
|
||||
void Solar::process_SM100Monitor2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(heatCntFlowTemp_, 0)); // is *10
|
||||
has_update(telegram->read_value(heatCntRetTemp_, 2)); // is *10
|
||||
has_update(telegram->read_value(heatCnt_, 12));
|
||||
has_update(telegram->read_value(swapRetTemp_, 6)); // is *10
|
||||
has_update(telegram->read_value(swapFlowTemp_, 8)); // is *10
|
||||
has_update(telegram, heatCntFlowTemp_, 0); // is *10
|
||||
has_update(telegram, heatCntRetTemp_, 2); // is *10
|
||||
has_update(telegram, heatCnt_, 12);
|
||||
has_update(telegram, swapRetTemp_, 6); // is *10
|
||||
has_update(telegram, swapFlowTemp_, 8); // is *10
|
||||
has_update(telegram, cylTopTemp_, 10); // is *10 - TS10: cylinder top temperature
|
||||
}
|
||||
|
||||
// SM100Config - 0x0366
|
||||
@@ -607,7 +624,7 @@ void Solar::process_SM100Config(std::shared_ptr<const Telegram> telegram) {
|
||||
// SM100Config1 - 0x035F
|
||||
// e.g. Solar(0x30) -> Me(0x0B), ?(0x35F), data: 00 00 41 01 1E 0A 0C 19 00 3C 19
|
||||
void Solar::process_SM100Config1(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(cylPriority_, 3));
|
||||
has_update(telegram, cylPriority_, 3);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -644,6 +661,8 @@ void Solar::process_SM100Status(std::shared_ptr<const Telegram> telegram) {
|
||||
solarpumpmod = solarPumpMinMod_ * 5; // set to minimum
|
||||
}
|
||||
has_update(solarPump2Mod_, solarpumpmod);
|
||||
|
||||
has_update(telegram, transferPumpMod_, 14);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -653,11 +672,12 @@ void Solar::process_SM100Status(std::shared_ptr<const Telegram> telegram) {
|
||||
* byte 10 = PS1 Solar circuit pump for collector array 1: test=b0001(1), on=b0100(4) and off=b0011(3)
|
||||
*/
|
||||
void Solar::process_SM100Status2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_bitupdate(telegram, vs1Status_, 0, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, valveStatus_, 4, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, solarPump_, 10, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, solarPump2_, 1, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, m1Valve_, 7, 2); // values 8/4 seen
|
||||
has_bitupdate(telegram, vs1Status_, 0, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, valveStatus_, 4, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, solarPump_, 10, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, solarPump2_, 1, 2); // on if bit 2 set
|
||||
has_bitupdate(telegram, m1Valve_, 7, 2); // values 8/4 seen
|
||||
has_bitupdate(telegram, transferPump_, 11, 2); // #2212
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -33,6 +33,8 @@ class Solar : public EMSdevice {
|
||||
int16_t collectorTemp_; // TS1: Temperature sensor for collector array 1
|
||||
int16_t cylBottomTemp_; // TS2: Temperature sensor 1 cylinder, bottom cyl (solar thermal system)
|
||||
int16_t cylBottomTemp2_; // TS5: Temperature sensor 2 cylinder, bottom cyl, or swimming pool (solar thermal system)
|
||||
int16_t cylBottomTemp3_; // TS11: Temperature sensor 3. cylinder
|
||||
int16_t cylTopTemp_; // TS10: Temperature sensor 1 cylinder, Top
|
||||
int16_t heatExchangerTemp_; // TS6: Heat exchanger temperature sensor
|
||||
int16_t collector2Temp_; // TS7: Temperature sensor for collector array 2
|
||||
int16_t cylMiddleTemp_; // TS14: Cylinder middle temp
|
||||
@@ -46,6 +48,9 @@ class Solar : public EMSdevice {
|
||||
uint8_t m1Valve_; // M1: heat assistance valve
|
||||
uint8_t m1Power_; // M1: heat assistance valve
|
||||
uint8_t vs1Status_; // VS1: status
|
||||
uint8_t vs3Status_; // VS3: status
|
||||
uint8_t transferPump_;
|
||||
uint8_t transferPumpMod_;
|
||||
|
||||
// 0x363 heat counter
|
||||
uint16_t heatCntFlowTemp_;
|
||||
|
||||
@@ -1561,22 +1561,34 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
return; // not supported
|
||||
}
|
||||
|
||||
static uint8_t setTimeRetry = 0;
|
||||
uint8_t dst = 0xFE;
|
||||
bool use_dst = !telegram->read_value(dst, 9) || dst == 0xFF;
|
||||
if ((telegram->message_data[7] & 0x0C) && has_command(&dateTime_)) { // date and time not valid
|
||||
set_datetime("ntp", -1); // set from NTP
|
||||
if (setTimeRetry < 3) {
|
||||
if (!use_dst) {
|
||||
set_datetime("ntp", 0); // set from NTP without dst
|
||||
} else {
|
||||
set_datetime("ntp", -1); // set from NTP
|
||||
}
|
||||
setTimeRetry++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// check clock
|
||||
time_t now = time(nullptr);
|
||||
tm * tm_ = localtime(&now);
|
||||
bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid
|
||||
tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT
|
||||
tm_->tm_mon = telegram->message_data[1] - 1;
|
||||
tm_->tm_mday = telegram->message_data[3];
|
||||
tm_->tm_hour = telegram->message_data[2];
|
||||
tm_->tm_min = telegram->message_data[4];
|
||||
tm_->tm_sec = telegram->message_data[5];
|
||||
tm_->tm_isdst = telegram->message_data[7] & 0x01;
|
||||
time_t now = time(nullptr);
|
||||
tm * tm_ = localtime(&now);
|
||||
bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid
|
||||
tm_->tm_year = (telegram->message_data[0] & 0x7F) + 100; // IVT
|
||||
tm_->tm_mon = telegram->message_data[1] - 1;
|
||||
tm_->tm_mday = telegram->message_data[3];
|
||||
tm_->tm_hour = telegram->message_data[2];
|
||||
tm_->tm_min = telegram->message_data[4];
|
||||
tm_->tm_sec = telegram->message_data[5];
|
||||
if (use_dst) {
|
||||
tm_->tm_isdst = telegram->message_data[7] & 0x01;
|
||||
}
|
||||
|
||||
// render date to DD.MM.YYYY HH:MM and publish
|
||||
char newdatetime[sizeof(dateTime_)];
|
||||
@@ -1590,8 +1602,18 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
if (!ivtclock && !junkersclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) {
|
||||
double difference = difftime(now, ttime);
|
||||
if (difference > 15 || difference < -15) {
|
||||
set_datetime("ntp", -1); // set from NTP
|
||||
LOG_INFO("thermostat time correction from ntp");
|
||||
if (setTimeRetry < 3) {
|
||||
if (!use_dst) {
|
||||
set_datetime("ntp", 0); // set from NTP without dst
|
||||
LOG_INFO("thermostat time correction from ntp, ignoring dst");
|
||||
} else {
|
||||
set_datetime("ntp", -1); // set from NTP
|
||||
LOG_INFO("thermostat time correction from ntp");
|
||||
}
|
||||
setTimeRetry++;
|
||||
}
|
||||
} else {
|
||||
setTimeRetry = 0;
|
||||
}
|
||||
}
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -2685,8 +2707,8 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
||||
data[3] = tm_->tm_mday;
|
||||
data[4] = tm_->tm_min;
|
||||
data[5] = tm_->tm_sec;
|
||||
data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su
|
||||
data[7] = tm_->tm_isdst + 2; // set DST and flag for ext. clock
|
||||
data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su
|
||||
data[7] = (id == 0) ? 2 : tm_->tm_isdst + 2; // set DST and flag for ext. clock
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
data[6]++; // Junkers use 1-7;
|
||||
data[7] = 0;
|
||||
@@ -4890,7 +4912,7 @@ void Thermostat::register_device_values_dhw(std::shared_ptr<Thermostat::DhwCircu
|
||||
DeviceValueUOM::MINUTES,
|
||||
MAKE_CF_CB(set_wwchargeduration));
|
||||
register_device_value(tag, &dhw->wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge));
|
||||
register_device_value(tag, &dhw->wwExtra_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &dhw->wwExtra_, DeviceValueType::BOOL, FL_(wwExtra), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect));
|
||||
register_device_value(
|
||||
tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay));
|
||||
|
||||
@@ -28,7 +28,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
dhw_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1;
|
||||
int8_t tag = DeviceValueTAG::TAG_DHW1 + dhw_;
|
||||
if (device_id == 0x2A) { // SM100, DHW3
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { // device_id 0x2A, DHW3
|
||||
// telegram handlers
|
||||
register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature));
|
||||
register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus));
|
||||
@@ -63,7 +63,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
register_device_value(tag, &wwDeltaTRet_, DeviceValueType::UINT8, FL_(deltaTRet), DeviceValueUOM::K, MAKE_CF_CB(set_wwDeltaTRet));
|
||||
register_device_value(tag, &errorDisp_, DeviceValueType::ENUM, FL_(enum_errorDisp), FL_(errorDisp), DeviceValueUOM::NONE, MAKE_CF_CB(set_errorDisp));
|
||||
|
||||
} else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) {
|
||||
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) { // dhw1 and dhw 2
|
||||
register_telegram_type(0x331 + dhw_, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
|
||||
register_telegram_type(0x313 + dhw_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
|
||||
// register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC));
|
||||
@@ -78,7 +78,7 @@ Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT8, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp));
|
||||
register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc));
|
||||
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
|
||||
} else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10
|
||||
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
dhw_ = 0;
|
||||
tag = DeviceValueTAG::TAG_DHW1;
|
||||
register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW));
|
||||
|
||||
@@ -135,7 +135,7 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
||||
case DeviceType::GATEWAY:
|
||||
return F_(gateway);
|
||||
case DeviceType::SWITCH:
|
||||
return F_(switch);
|
||||
return F_(switcher);
|
||||
case DeviceType::CONTROLLER:
|
||||
return F_(controller);
|
||||
case DeviceType::CONNECT:
|
||||
@@ -233,7 +233,7 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
|
||||
if (!strcmp(lowtopic, F_(mixer))) {
|
||||
return DeviceType::MIXER;
|
||||
}
|
||||
if (!strcmp(lowtopic, F_(switch))) {
|
||||
if (!strcmp(lowtopic, F_(switcher))) {
|
||||
return DeviceType::SWITCH;
|
||||
}
|
||||
if (!strcmp(lowtopic, F_(gateway))) {
|
||||
@@ -1271,7 +1271,7 @@ void EMSdevice::getCustomizationEntities(std::vector<std::string> & entity_ids)
|
||||
// pipe symbols (|) are escaped so they can be converted to Markdown in the Wiki
|
||||
// format is: device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
void EMSdevice::dump_value_info() {
|
||||
void EMSdevice::dump_devicevalue_info() {
|
||||
for (auto & dv : devicevalues_) {
|
||||
if (dv.fullname != nullptr) {
|
||||
Serial.print('\"');
|
||||
@@ -1438,15 +1438,13 @@ void EMSdevice::dump_value_info() {
|
||||
Serial.print(",");
|
||||
|
||||
// modbus specific infos
|
||||
|
||||
|
||||
Serial.print(device_type());
|
||||
Serial.print(device_type()); // modbus unit identifier
|
||||
Serial.print(',');
|
||||
|
||||
Serial.print(dv.tag);
|
||||
Serial.print(dv.tag); // modbus block
|
||||
Serial.print(',');
|
||||
|
||||
// numeric operator -> scale factor
|
||||
// numeric operator -> modbus scale factor
|
||||
if (dv.numeric_operator == 0)
|
||||
Serial.print("1");
|
||||
else if (dv.numeric_operator > 0)
|
||||
@@ -1455,10 +1453,10 @@ void EMSdevice::dump_value_info() {
|
||||
Serial.print(-dv.numeric_operator);
|
||||
Serial.print(",");
|
||||
|
||||
Serial.printf("%d", EMSESP::modbus_->getRegisterOffset(dv));
|
||||
Serial.printf("%d", EMSESP::modbus_->getRegisterOffset(dv)); // modbus offset
|
||||
Serial.print(",");
|
||||
|
||||
Serial.printf("%d", EMSESP::modbus_->getRegisterCount(dv));
|
||||
Serial.printf("%d", EMSESP::modbus_->getRegisterCount(dv)); // modbus count
|
||||
|
||||
// /modbus specific infos
|
||||
|
||||
@@ -1845,9 +1843,9 @@ void EMSdevice::mqtt_ha_entity_config_create() {
|
||||
uint16_t count = 0;
|
||||
|
||||
// check the state of each of the device values
|
||||
// create climate if roomtemp is visible
|
||||
// create the discovery topic if if hasn't already been created, not a command (like reset) and is active and visible
|
||||
for (auto & dv : devicevalues_) {
|
||||
// create climate when we reach the haclimate entity
|
||||
if (!strcmp(dv.short_name, FL_(haclimate)[0]) && !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE) && dv.has_state(DeviceValueState::DV_ACTIVE)) {
|
||||
if (*(int8_t *)(dv.value_p) == 1 && (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) || dv.has_state(DeviceValueState::DV_HA_CLIMATE_NO_RT))) {
|
||||
if (Mqtt::publish_ha_climate_config(dv.tag, true, false, dv.min, dv.max)) { // roomTemp
|
||||
@@ -1930,7 +1928,7 @@ const char * EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> teleg
|
||||
bool EMSdevice::handle_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
for (auto & tf : telegram_functions_) {
|
||||
if (tf.telegram_type_id_ == telegram->type_id) {
|
||||
// for telegram desitnation only read telegram
|
||||
// for telegram destination only read telegram
|
||||
if (telegram->dest == device_id_ && telegram->message_length > 0) {
|
||||
tf.process_function_(telegram);
|
||||
return true;
|
||||
@@ -1982,9 +1980,14 @@ void EMSdevice::read_command(const uint16_t type_id, const uint8_t offset, const
|
||||
// returns either default or custom name
|
||||
std::string EMSdevice::name() {
|
||||
if (custom_name_.empty()) {
|
||||
return default_name_;
|
||||
// return default name prefixed with a model if exists
|
||||
if (model().empty()) {
|
||||
return default_name();
|
||||
}
|
||||
return model() + "/" + default_name();
|
||||
}
|
||||
return custom_name_;
|
||||
|
||||
return custom_name();
|
||||
}
|
||||
|
||||
// copy a raw value (i.e. without applying the numeric_operator) to the output buffer.
|
||||
@@ -1993,8 +1996,9 @@ int EMSdevice::get_modbus_value(uint8_t tag, const std::string & shortname, std:
|
||||
// find device value by shortname
|
||||
// TODO replace linear search which is inefficient
|
||||
const auto & it = std::find_if(devicevalues_.begin(), devicevalues_.end(), [&](const DeviceValue & x) { return x.tag == tag && x.short_name == shortname; });
|
||||
if (it == devicevalues_.end())
|
||||
if (it == devicevalues_.end() && (it->short_name != shortname || it->tag != tag)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto & dv = *it;
|
||||
|
||||
@@ -2079,7 +2083,7 @@ int EMSdevice::modbus_value_to_json(uint8_t tag, const std::string & shortname,
|
||||
|
||||
// find device value by shortname
|
||||
const auto & it = std::find_if(devicevalues_.begin(), devicevalues_.end(), [&](const DeviceValue & x) { return x.tag == tag && x.short_name == shortname; });
|
||||
if (it == devicevalues_.end()) {
|
||||
if (it == devicevalues_.end() && (it->short_name != shortname || it->tag != tag)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
154
src/emsdevice.h
154
src/emsdevice.h
@@ -53,28 +53,48 @@ class EMSdevice {
|
||||
static uint8_t decode_brand(uint8_t value);
|
||||
static bool export_values(uint8_t device_type, JsonObject output, const int8_t id, const uint8_t output_target);
|
||||
|
||||
// non static
|
||||
// non static functions
|
||||
|
||||
const char * device_type_name(); // returns short non-translated device type name
|
||||
const char * device_type_2_device_name_translated(); // returns translated device type name
|
||||
bool has_tags(const int8_t tag) const;
|
||||
bool has_cmd(const char * cmd, const int8_t id) const;
|
||||
const char * brand_to_char();
|
||||
std::string to_string();
|
||||
std::string to_string_short();
|
||||
std::string name(); // returns either default or custom name of a device (if defined)
|
||||
|
||||
bool has_tags(const int8_t tag) const;
|
||||
bool has_cmd(const char * cmd, const int8_t id) const;
|
||||
bool is_device_id(uint8_t device_id) const {
|
||||
return ((device_id & 0x7F) == (device_id_ & 0x7F));
|
||||
}
|
||||
|
||||
inline uint8_t device_id() const {
|
||||
// Getters
|
||||
uint8_t device_id() const {
|
||||
return device_id_;
|
||||
}
|
||||
|
||||
inline uint8_t product_id() const {
|
||||
uint8_t product_id() const {
|
||||
return product_id_;
|
||||
}
|
||||
|
||||
void product_id(uint8_t product_id) {
|
||||
product_id_ = product_id;
|
||||
uint8_t device_type() const {
|
||||
return device_type_; // see enum DeviceType below
|
||||
}
|
||||
|
||||
inline bool is_device_id(uint8_t device_id) const {
|
||||
return ((device_id & 0x7F) == (device_id_ & 0x7F));
|
||||
const char * version() const {
|
||||
return version_;
|
||||
}
|
||||
|
||||
uint8_t brand() const {
|
||||
return brand_;
|
||||
}
|
||||
|
||||
void active(bool active) {
|
||||
active_ = active;
|
||||
}
|
||||
|
||||
const char * default_name() const {
|
||||
return default_name_;
|
||||
}
|
||||
|
||||
// flags
|
||||
@@ -91,66 +111,46 @@ class EMSdevice {
|
||||
return flags_;
|
||||
}
|
||||
|
||||
inline uint8_t device_type() const {
|
||||
return device_type_; // see enum DeviceType below
|
||||
}
|
||||
|
||||
inline void version(const char * version) {
|
||||
strlcpy(version_, version, sizeof(version_));
|
||||
}
|
||||
|
||||
inline const char * version() const {
|
||||
return version_;
|
||||
}
|
||||
|
||||
inline void brand(uint8_t brand) {
|
||||
brand_ = brand;
|
||||
}
|
||||
|
||||
inline uint8_t brand() const {
|
||||
return brand_;
|
||||
}
|
||||
|
||||
inline void active(bool active) {
|
||||
active_ = active;
|
||||
}
|
||||
|
||||
// set custom device name
|
||||
inline void custom_name(std::string const & custom_name) {
|
||||
void custom_name(std::string const & custom_name) {
|
||||
custom_name_ = custom_name;
|
||||
}
|
||||
std::string name(); // returns either default or custom name if defined
|
||||
|
||||
// default name
|
||||
inline void default_name(const char * default_name) {
|
||||
default_name_ = default_name;
|
||||
std::string custom_name() const {
|
||||
return custom_name_;
|
||||
}
|
||||
inline const char * default_name() const {
|
||||
return default_name_;
|
||||
|
||||
// set device model
|
||||
void model(std::string const & model) {
|
||||
model_ = model;
|
||||
}
|
||||
|
||||
std::string model() const {
|
||||
return model_;
|
||||
}
|
||||
|
||||
inline uint8_t unique_id() const {
|
||||
return unique_id_;
|
||||
}
|
||||
|
||||
inline void unique_id(uint8_t unique_id) {
|
||||
void unique_id(uint8_t unique_id) {
|
||||
unique_id_ = unique_id;
|
||||
}
|
||||
|
||||
inline bool has_update() const {
|
||||
bool has_update() const {
|
||||
return has_update_;
|
||||
}
|
||||
|
||||
inline void has_update(bool flag) {
|
||||
void has_update(bool flag) {
|
||||
has_update_ = flag;
|
||||
}
|
||||
|
||||
inline void has_update(void * value) {
|
||||
void has_update(void * value) {
|
||||
has_update_ = true;
|
||||
publish_value(value);
|
||||
}
|
||||
|
||||
inline void has_update(char * value, const char * newvalue, size_t len) {
|
||||
void has_update(char * value, const char * newvalue, size_t len) {
|
||||
if (strcmp(value, newvalue) != 0) {
|
||||
strlcpy(value, newvalue, len);
|
||||
has_update_ = true;
|
||||
@@ -158,7 +158,7 @@ class EMSdevice {
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_update(uint8_t & value, uint8_t newvalue) {
|
||||
void has_update(uint8_t & value, uint8_t newvalue) {
|
||||
if (value != newvalue) {
|
||||
value = newvalue;
|
||||
has_update_ = true;
|
||||
@@ -166,7 +166,7 @@ class EMSdevice {
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_update(uint16_t & value, uint16_t newvalue) {
|
||||
void has_update(uint16_t & value, uint16_t newvalue) {
|
||||
if (value != newvalue) {
|
||||
value = newvalue;
|
||||
has_update_ = true;
|
||||
@@ -174,7 +174,7 @@ class EMSdevice {
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_update(uint32_t & value, uint32_t newvalue) {
|
||||
void has_update(uint32_t & value, uint32_t newvalue) {
|
||||
if (value != newvalue) {
|
||||
value = newvalue;
|
||||
has_update_ = true;
|
||||
@@ -182,7 +182,7 @@ class EMSdevice {
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_enumupdate(std::shared_ptr<const Telegram> telegram, uint8_t & value, const uint8_t index, int8_t s = 0) {
|
||||
void has_enumupdate(std::shared_ptr<const Telegram> telegram, uint8_t & value, const uint8_t index, int8_t s = 0) {
|
||||
if (telegram->read_enumvalue(value, index, s)) {
|
||||
has_update_ = true;
|
||||
publish_value((void *)&value);
|
||||
@@ -190,7 +190,7 @@ class EMSdevice {
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
inline void has_update(std::shared_ptr<const Telegram> telegram, Value & value, const uint8_t index, uint8_t s = 0) {
|
||||
void has_update(std::shared_ptr<const Telegram> telegram, Value & value, const uint8_t index, uint8_t s = 0) {
|
||||
if (telegram->read_value(value, index, s)) {
|
||||
has_update_ = true;
|
||||
publish_value((void *)&value);
|
||||
@@ -198,22 +198,18 @@ class EMSdevice {
|
||||
}
|
||||
|
||||
template <typename BitValue>
|
||||
inline void has_bitupdate(std::shared_ptr<const Telegram> telegram, BitValue & value, const uint8_t index, uint8_t b) {
|
||||
void has_bitupdate(std::shared_ptr<const Telegram> telegram, BitValue & value, const uint8_t index, uint8_t b) {
|
||||
if (telegram->read_bitvalue(value, index, b)) {
|
||||
has_update_ = true;
|
||||
publish_value((void *)&value);
|
||||
}
|
||||
}
|
||||
|
||||
// modbus
|
||||
int get_modbus_value(uint8_t tag, const std::string & shortname, std::vector<uint16_t> & result);
|
||||
int modbus_value_to_json(uint8_t tag, const std::string & shortname, const std::vector<uint8_t> & modbus_data, JsonObject jsonValue);
|
||||
|
||||
const char * brand_to_char();
|
||||
std::string to_string();
|
||||
std::string to_string_short();
|
||||
|
||||
enum Handlers : uint8_t { ALL, RECEIVED, FETCHED, PENDING, IGNORED };
|
||||
|
||||
void show_telegram_handlers(uuid::console::Shell & shell) const;
|
||||
char * show_telegram_handlers(char * result, const size_t len, const uint8_t handlers);
|
||||
void show_mqtt_handlers(uuid::console::Shell & shell) const;
|
||||
@@ -227,10 +223,9 @@ class EMSdevice {
|
||||
bool handle_telegram(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
std::string get_value_uom(const std::string & shortname) const;
|
||||
|
||||
bool get_value_info(JsonObject root, const char * cmd, const int8_t id);
|
||||
void get_value_json(JsonObject output, DeviceValue & dv);
|
||||
void get_dv_info(JsonObject json);
|
||||
bool get_value_info(JsonObject root, const char * cmd, const int8_t id);
|
||||
void get_value_json(JsonObject output, DeviceValue & dv);
|
||||
void get_dv_info(JsonObject json);
|
||||
|
||||
enum OUTPUT_TARGET : uint8_t { API_VERBOSE, API_SHORTNAMES, MQTT, CONSOLE };
|
||||
bool generate_values(JsonObject output, const int8_t tag_filter, const bool nested, const uint8_t output_target);
|
||||
@@ -314,23 +309,20 @@ class EMSdevice {
|
||||
|
||||
void read_command(const uint16_t type_id, uint8_t offset = 0, uint8_t length = 0) const;
|
||||
|
||||
bool is_readable(const void * value_p) const;
|
||||
bool is_readonly(const std::string & cmd, const int8_t id) const;
|
||||
bool has_command(const void * value_p) const;
|
||||
void set_minmax(const void * value_p, int16_t min, uint32_t max);
|
||||
void publish_value(void * value_p) const;
|
||||
void publish_all_values();
|
||||
|
||||
void mqtt_ha_entity_config_create();
|
||||
|
||||
bool is_readable(const void * value_p) const;
|
||||
bool is_readonly(const std::string & cmd, const int8_t id) const;
|
||||
bool has_command(const void * value_p) const;
|
||||
void set_minmax(const void * value_p, int16_t min, uint32_t max);
|
||||
void publish_value(void * value_p) const;
|
||||
void publish_all_values();
|
||||
void mqtt_ha_entity_config_create();
|
||||
const char * telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void fetch_values();
|
||||
void toggle_fetch(uint16_t telegram_id, bool toggle);
|
||||
bool is_fetch(uint16_t telegram_id) const;
|
||||
bool is_received(uint16_t telegram_id) const;
|
||||
bool has_telegram_id(uint16_t id) const;
|
||||
void ha_config_clear();
|
||||
void fetch_values();
|
||||
void toggle_fetch(uint16_t telegram_id, bool toggle);
|
||||
bool is_fetch(uint16_t telegram_id) const;
|
||||
bool is_received(uint16_t telegram_id) const;
|
||||
bool has_telegram_id(uint16_t id) const;
|
||||
void ha_config_clear();
|
||||
|
||||
bool ha_config_done() const {
|
||||
return ha_config_done_;
|
||||
@@ -491,7 +483,7 @@ class EMSdevice {
|
||||
}
|
||||
};
|
||||
void dump_telegram_info(std::vector<TelegramFunctionDump> & telegram_functions_dump);
|
||||
void dump_value_info();
|
||||
void dump_devicevalue_info();
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -502,6 +494,7 @@ class EMSdevice {
|
||||
char version_[6];
|
||||
const char * default_name_; // the fixed name the EMS model taken from the device library
|
||||
std::string custom_name_ = ""; // custom name
|
||||
std::string model_ = ""; // model, taken from the 0x01 telegram. see process_deviceName()
|
||||
uint8_t flags_ = 0;
|
||||
uint8_t brand_ = Brand::NO_BRAND;
|
||||
bool active_ = true;
|
||||
@@ -525,14 +518,13 @@ class EMSdevice {
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
|
||||
|
||||
std::vector<uint16_t> handlers_ignored_;
|
||||
|
||||
#if defined(EMSESP_STANDALONE) || defined(EMSESP_TEST)
|
||||
public: // so we can call it from WebCustomizationService::test()
|
||||
public: // so we can call it from WebCustomizationService::test() and EMSESP::dump_all_entities()
|
||||
#endif
|
||||
std::vector<DeviceValue> devicevalues_; // all the device values
|
||||
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
|
||||
std::vector<DeviceValue> devicevalues_; // all the device values
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -108,9 +108,10 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
||||
const char * DeviceValue::DeviceValueUOM_s[] = {
|
||||
|
||||
F_(uom_blank), // 0
|
||||
F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], FL_(minutes)[0], F_(uom_ua),
|
||||
F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], F_(uom_dbm), F_(uom_fahrenheit), F_(uom_mv), F_(uom_sqm),
|
||||
F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_mbar), F_(uom_lh), F_(uom_blank)
|
||||
F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0],
|
||||
FL_(minutes)[0], F_(uom_ua), F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0],
|
||||
F_(uom_dbm), F_(uom_fahrenheit), F_(uom_mv), F_(uom_sqm), F_(uom_m3), F_(uom_l), F_(uom_kmin),
|
||||
F_(uom_k), F_(uom_volts), F_(uom_mbar), F_(uom_lh), F_(uom_ctkwh), F_(uom_blank)
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -74,10 +74,11 @@ class DeviceValue {
|
||||
VOLTS, // 23 - V
|
||||
MBAR, // 24 - mbar
|
||||
LH, // 25 - l/h
|
||||
CONNECTIVITY // 26 - used in HA
|
||||
CTKWH, // 26 - ct/kWh
|
||||
CONNECTIVITY // 27 - used in HA
|
||||
};
|
||||
|
||||
// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp
|
||||
// TAG mapping - maps to DeviceValueTAG_s in emsdevicevalue.cpp
|
||||
enum DeviceValueTAG : int8_t {
|
||||
TAG_NONE = -1, // wild card
|
||||
TAG_DEVICE_DATA = 0,
|
||||
|
||||
100
src/emsesp.cpp
100
src/emsesp.cpp
@@ -332,7 +332,7 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
|
||||
// Dump all entities to Serial out
|
||||
// this is intended to run within the OS with lots of available memory!
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
void EMSESP::dump_all_values(uuid::console::Shell & shell) {
|
||||
void EMSESP::dump_all_entities(uuid::console::Shell & shell) {
|
||||
Serial.println("---- CSV START ----"); // marker use by py script
|
||||
// add header for CSV
|
||||
Serial.println("device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4,discovery "
|
||||
@@ -343,25 +343,27 @@ void EMSESP::dump_all_values(uuid::console::Shell & shell) {
|
||||
for (const auto & device : device_library_) {
|
||||
if (device_class.first == device.device_type) {
|
||||
uint8_t device_id = 0;
|
||||
// Mixer class looks at device_id to determine type and the tag
|
||||
// so fixing to 0x28 which will give all the settings except flowSetTemp
|
||||
if (device.device_type == DeviceType::MIXER) {
|
||||
// Water class looks at device_id to determine type and the tag
|
||||
if (device.device_type == DeviceType::WATER) {
|
||||
if (device.flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
if (device.product_id == 160) { // MM100
|
||||
device_id = 0x28; // dhw
|
||||
} else {
|
||||
device_id = 0x20; // hc
|
||||
}
|
||||
} else {
|
||||
device_id = 0x20; // should cover all the other device types
|
||||
device_id = 0x28; // dhw 1/2
|
||||
} else if (device.flags == EMSdevice::EMS_DEVICE_FLAG_SM100) {
|
||||
device_id = 0x28; // fix to dhw1, normally SM100 can only use dhw 3
|
||||
} else if (device.flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
device_id = 0x40; // dhw 1, not needed
|
||||
}
|
||||
}
|
||||
|
||||
// For a Mixer, fix device_id to 0x20 to give us all the settings
|
||||
if (device.device_type == DeviceType::MIXER) {
|
||||
device_id = 0x20; // hc
|
||||
}
|
||||
|
||||
// add the device and print out all the entities
|
||||
// for testing the mixer use ... if (device.product_id == 69) {
|
||||
emsdevices.push_back(
|
||||
EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.default_name, device.flags, EMSdevice::Brand::NO_BRAND));
|
||||
emsdevices.back()->dump_value_info();
|
||||
emsdevices.back()->dump_devicevalue_info();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,20 +387,22 @@ void EMSESP::dump_all_telegrams(uuid::console::Shell & shell) {
|
||||
for (const auto & device : device_library_) {
|
||||
if (device_class.first == device.device_type) {
|
||||
uint8_t device_id = 0;
|
||||
// Mixer class looks at device_id to determine type and the tag
|
||||
// so fixing to 0x28 which will give all the settings except flowSetTemp
|
||||
if (device.device_type == DeviceType::MIXER) {
|
||||
// Water class looks at device_id to determine type and the tag
|
||||
if (device.device_type == DeviceType::WATER) {
|
||||
if (device.flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
if (device.product_id == 160) { // MM100
|
||||
device_id = 0x28; // dhw
|
||||
} else {
|
||||
device_id = 0x20; // hc
|
||||
}
|
||||
} else {
|
||||
device_id = 0x20; // should cover all the other device types
|
||||
device_id = 0x28; // dhw 1/2
|
||||
} else if (device.flags == EMSdevice::EMS_DEVICE_FLAG_SM100) {
|
||||
device_id = 0x2A; // dhw 3 needed to calculate right telegram numbers
|
||||
} else if (device.flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
device_id = 0x40; // dhw 1, not needed
|
||||
}
|
||||
}
|
||||
|
||||
// For a Mixer, fix device_id to 0x20 to give us all the settings
|
||||
if (device.device_type == DeviceType::MIXER) {
|
||||
device_id = 0x20; // hc
|
||||
}
|
||||
|
||||
// add the device and print out all the entities
|
||||
emsdevices.push_back(
|
||||
EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.default_name, device.flags, EMSdevice::Brand::NO_BRAND));
|
||||
@@ -910,14 +914,14 @@ std::string EMSESP::pretty_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
std::string str;
|
||||
str.reserve(200);
|
||||
if (telegram->operation == Telegram::Operation::RX_READ) {
|
||||
str = src_name + "(" + Helpers::hextoa(src) + ") -R-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "("
|
||||
str = src_name + "(" + Helpers::hextoa(src) + ") -> " + dest_name + "(" + Helpers::hextoa(dest) + "), R, " + type_name + "("
|
||||
+ Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::itoa(telegram->message_data[0])
|
||||
+ ((telegram->message_length > 1) ? ", data: " + Helpers::data_to_hex(telegram->message_data + 1, telegram->message_length - 1) : "");
|
||||
} else if (telegram->dest == 0) {
|
||||
str = src_name + "(" + Helpers::hextoa(src) + ") -B-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "("
|
||||
str = src_name + "(" + Helpers::hextoa(src) + ") -> " + dest_name + "(" + Helpers::hextoa(dest) + "), B, " + type_name + "("
|
||||
+ Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message();
|
||||
} else {
|
||||
str = src_name + "(" + Helpers::hextoa(src) + ") -W-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "("
|
||||
str = src_name + "(" + Helpers::hextoa(src) + ") -> " + dest_name + "(" + Helpers::hextoa(dest) + "), W, " + type_name + "("
|
||||
+ Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message();
|
||||
}
|
||||
|
||||
@@ -971,15 +975,19 @@ void EMSESP::process_deviceName(std::shared_ptr<const Telegram> telegram) {
|
||||
char name[16];
|
||||
uint8_t len = telegram->offset + telegram->message_length - 27;
|
||||
strlcpy(name, (const char *)&telegram->message_data[27 - telegram->offset], len < 16 ? len : 16);
|
||||
if (strlen(name)) {
|
||||
webCustomizationService.read([&](WebCustomization const & settings) {
|
||||
for (EntityCustomization e : settings.entityCustomizations) {
|
||||
if ((e.device_id == telegram->src) && e.custom_name.empty()) {
|
||||
e.custom_name = name;
|
||||
break;
|
||||
}
|
||||
char * c = name;
|
||||
while (isprint(*c)) {
|
||||
c++;
|
||||
};
|
||||
*c = '\0';
|
||||
if (strlen(name) > 2) { // https://github.com/emsesp/EMS-ESP32/issues/2166#issuecomment-2454488657
|
||||
LOG_DEBUG("Model name received for device 0x%02X: %s", telegram->src, name);
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice->is_device_id(telegram->src)) {
|
||||
emsdevice->model(name);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1017,13 +1025,14 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
||||
// some devices store the protocol type (HT3, Buderus) in the last byte
|
||||
uint8_t brand;
|
||||
if (telegram->message_length >= 10) {
|
||||
brand = EMSdevice::decode_brand(telegram->message_data[9]); // TODO should be offset + 9?
|
||||
brand = EMSdevice::decode_brand(telegram->message_data[9]);
|
||||
} else {
|
||||
brand = EMSdevice::Brand::NO_BRAND; // unknown
|
||||
}
|
||||
|
||||
// add it - will be overwritten if device already exists
|
||||
(void)add_device(device_id, product_id, version, brand);
|
||||
|
||||
// request the deviceName from telegram 0x01
|
||||
send_read_request(EMSdevice::EMS_TYPE_NAME, device_id, 27);
|
||||
}
|
||||
@@ -1204,8 +1213,8 @@ void EMSESP::show_devices(uuid::console::Shell & shell) {
|
||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice && (emsdevice->device_type() == device_class.first)) {
|
||||
shell.printf("%s: %s", emsdevice->device_type_name(), emsdevice->to_string().c_str());
|
||||
shell.println();
|
||||
// print header, with device type translated
|
||||
shell.printfln("%s: %s (%d)", emsdevice->device_type_2_device_name_translated(), emsdevice->to_string().c_str(), emsdevice->count_entities());
|
||||
emsdevice->show_telegram_handlers(shell);
|
||||
|
||||
#if defined(EMSESP_DEBUG)
|
||||
@@ -1462,11 +1471,12 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
} else if (first_value == TxService::TX_WRITE_FAIL) {
|
||||
LOG_ERROR("Last Tx write rejected by host");
|
||||
txservice_.send_poll(); // close the bus
|
||||
txservice_.reset_retry_count();
|
||||
tx_successful = true; // no retries
|
||||
} else {
|
||||
LOG_ERROR("Last Tx write host reply: 0x%02X", first_value);
|
||||
}
|
||||
} else if (tx_state == Telegram::Operation::TX_READ && length == 1) {
|
||||
EMSbus::tx_state(Telegram::Operation::TX_READ); // reset Tx wait state
|
||||
return;
|
||||
} else if (tx_state == Telegram::Operation::TX_READ) {
|
||||
} else if (tx_state == Telegram::Operation::TX_READ && length > 1) {
|
||||
// got a telegram with data in it. See if the src/dest matches that from the last one we sent and continue to process it
|
||||
uint8_t src = data[0];
|
||||
uint8_t dest = data[1];
|
||||
@@ -1478,7 +1488,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
|
||||
// if telegram is longer read next part with offset +25 for ems+ or +27 for ems1.0
|
||||
// not for response to raw send commands without read_id set
|
||||
if ((response_id_ == 0 || read_id_ > 0) && (txservice_.read_next_tx(data[3], length) == read_id_)) {
|
||||
if ((response_id_ == 0 || read_id_ > 0) && (txservice_.read_next_tx(data[3], length) > 0)) {
|
||||
read_next_ = true;
|
||||
txservice_.send(); // read next part withing same poll or:
|
||||
// txservice_.send_poll(); // close the bus, next request in new poll
|
||||
@@ -1528,9 +1538,11 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
// check for poll to us, if so send top message from Tx queue immediately and quit
|
||||
if (poll_id == txservice_.get_send_id()) {
|
||||
txservice_.send();
|
||||
} else {
|
||||
// send remote room temperature if active
|
||||
Roomctrl::send(poll_id);
|
||||
}
|
||||
// send remote room temperature if active
|
||||
Roomctrl::send(poll_id);
|
||||
|
||||
return;
|
||||
} else {
|
||||
#ifdef EMSESP_UART_DEBUG
|
||||
@@ -1764,10 +1776,10 @@ void EMSESP::loop() {
|
||||
void EMSESP::start_serial_console() {
|
||||
shell_ = std::make_shared<EMSESPConsole>(*this, serial_console_, true);
|
||||
shell_->maximum_log_messages(100);
|
||||
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests
|
||||
shell_->start();
|
||||
#if defined(EMSESP_DEBUG)
|
||||
shell_->log_level(uuid::log::Level::DEBUG);
|
||||
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when compiled with debug
|
||||
#else
|
||||
shell_->log_level(uuid::log::Level::TRACE);
|
||||
#endif
|
||||
|
||||
16
src/emsesp.h
16
src/emsesp.h
@@ -124,25 +124,23 @@ class EMSESP {
|
||||
static void send_write_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t value);
|
||||
static void send_write_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid);
|
||||
|
||||
static bool device_exists(const uint8_t device_id);
|
||||
static void device_active(const uint8_t device_id, const bool active);
|
||||
static bool cmd_is_readonly(const uint8_t device_type, const uint8_t device_id, const char * cmd, const int8_t id);
|
||||
|
||||
static bool device_exists(const uint8_t device_id);
|
||||
static void device_active(const uint8_t device_id, const bool active);
|
||||
static bool cmd_is_readonly(const uint8_t device_type, const uint8_t device_id, const char * cmd, const int8_t id);
|
||||
static uint8_t device_id_from_cmd(const uint8_t device_type, const char * cmd, const int8_t id);
|
||||
static uint8_t count_devices(const uint8_t device_type);
|
||||
static uint8_t count_devices();
|
||||
static uint8_t device_index(const uint8_t device_type, const uint8_t unique_id);
|
||||
|
||||
static bool get_device_value_info(JsonObject root, const char * cmd, const int8_t id, const uint8_t devicetype);
|
||||
static bool get_device_value_info(JsonObject root, const char * cmd, const int8_t id, const uint8_t devicetype);
|
||||
|
||||
static void show_device_values(uuid::console::Shell & shell);
|
||||
static void show_sensor_values(uuid::console::Shell & shell);
|
||||
static void dump_all_values(uuid::console::Shell & shell);
|
||||
static void dump_all_telegrams(uuid::console::Shell & shell);
|
||||
|
||||
static void show_devices(uuid::console::Shell & shell);
|
||||
static void show_ems(uuid::console::Shell & shell);
|
||||
|
||||
static void dump_all_entities(uuid::console::Shell & shell);
|
||||
static void dump_all_telegrams(uuid::console::Shell & shell);
|
||||
|
||||
static void uart_init();
|
||||
|
||||
static void incoming_telegram(uint8_t * data, const uint8_t length);
|
||||
|
||||
@@ -603,6 +603,10 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
|
||||
return true; // is a bool
|
||||
}
|
||||
|
||||
#ifdef EMSESP_STANDALONE
|
||||
emsesp::EMSESP::logger().debug("Error. value2bool: %s is not a boolean", value);
|
||||
#endif
|
||||
|
||||
return false; // not a bool
|
||||
}
|
||||
|
||||
@@ -764,7 +768,7 @@ uint8_t Helpers::count_items(const char * const ** list) {
|
||||
// if force_en is true always take the EN non-translated word
|
||||
const char * Helpers::translated_word(const char * const * strings, const bool force_en) {
|
||||
uint8_t language_index = EMSESP::system_.language_index();
|
||||
uint8_t index = 0;
|
||||
uint8_t index = 0; // default en
|
||||
|
||||
if (!strings) {
|
||||
return ""; // no translations
|
||||
@@ -774,6 +778,7 @@ const char * Helpers::translated_word(const char * const * strings, const bool f
|
||||
if (!force_en && (Helpers::count_items(strings) >= language_index + 1 && strlen(strings[language_index]))) {
|
||||
index = language_index;
|
||||
}
|
||||
|
||||
return strings[index];
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ MAKE_WORD(send)
|
||||
MAKE_WORD(telegram)
|
||||
MAKE_WORD(bus_id)
|
||||
MAKE_WORD(tx_mode)
|
||||
MAKE_WORD(showertimer)
|
||||
MAKE_WORD(showeralert)
|
||||
MAKE_WORD(ems)
|
||||
MAKE_WORD(devices)
|
||||
MAKE_WORD(shower)
|
||||
@@ -88,7 +90,7 @@ MAKE_WORD(coldshot)
|
||||
// device types - lowercase, used in MQTT
|
||||
MAKE_WORD(boiler)
|
||||
MAKE_WORD(thermostat)
|
||||
MAKE_WORD(switch)
|
||||
MAKE_WORD_CUSTOM(switcher, "switch")
|
||||
MAKE_WORD(solar)
|
||||
MAKE_WORD(mixer)
|
||||
MAKE_WORD(gateway)
|
||||
@@ -229,7 +231,7 @@ MAKE_NOTRANSLATION(tpl_input4, "<inv>[<comp><aux><cool><heat><dhw><pv>]")
|
||||
MAKE_NOTRANSLATION(test_cmd, "run a test")
|
||||
#endif
|
||||
|
||||
// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp
|
||||
// TAG mapping - maps to DeviceValueTAG_s in emsdevicevalue.cpp
|
||||
// use empty string if want to suppress showing tags
|
||||
// mqtt tags must not have spaces
|
||||
MAKE_NOTRANSLATION(tag_none, "")
|
||||
@@ -260,6 +262,7 @@ MAKE_WORD_CUSTOM(uom_k, "K")
|
||||
MAKE_WORD_CUSTOM(uom_volts, "V")
|
||||
MAKE_WORD_CUSTOM(uom_mbar, "mbar")
|
||||
MAKE_WORD_CUSTOM(uom_lh, "l/h")
|
||||
MAKE_WORD_CUSTOM(uom_ctkwh, "ct/kWh")
|
||||
|
||||
// MQTT topics and prefixes
|
||||
MAKE_WORD_CUSTOM(heating_active, "heating_active")
|
||||
|
||||
@@ -43,7 +43,7 @@ MAKE_WORD_TRANSLATION(thermostat_device, "Thermostat", "Thermostat", "Thermostaa
|
||||
MAKE_WORD_TRANSLATION(heatpump_device, "Heat Pump", "Wärmepumpe", "Warmtepomp", "Värmepump", "Pompa ciepła", "Varmepumpe", "", "Isı Pompası", "Pompa di Calore", "Tepelné čerpadlo", "Tepelné čerpadlo") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(solar_device, "Solar Module", "Solarmodul", "Solar Module", "Solmodul", "Moduł solarny", "Solmodul", "", "Güneş Enerjisi Cihazı", "Modulo Solare", "Solárny modul", "Solární modul") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(connect_device, "Connect Module", "Verbindungsmodul", "Connect Module", "Uppkopplingsmodul", "Moduł przyłączeń", "Sammenkoblingsmodul", "", "Güneş Enerjisi Cihazı", "Modulo connessione", "Pripojte modul", "Modul připojení") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(mixer_device, "Mixer Module", "Mischermodul", "Mixer Module", "Blandningsmodul", "Moduł mieszacza", "Miksermodul", "", "Karışım Cihazı", "Modulo Miscela", "Modul mixera", "Mixer modul") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(mixer_device, "Mixer Module", "Mischermodul", "Mixer Module", "Blandningsmodul", "Moduł mieszacza", "Miksermodul", "", "Karışım Cihazı", "Modulo Miscela", "Modul mixera", "Směšovací modul") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(controller_device, "Controller Module", "Regelmodul", "Controller Module", "Styrmodul", "Moduł sterujący", "Styremodul", "", "Kontrol Ünitesi", "Modulo Controllo", "Modul ovládača", "Řídicí modul") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(switch_device, "Switch Module", "Schaltmodul", "Switch Module", "Relämodul", "Moduł przełączający", "Switch modul", "", "Anahtar", "Modulo Switch", "Spínací modul", "Spínací modul") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(gateway_device, "Gateway Module", "Gateway-Modul", "Gateway Module", "Gateway", "Moduł IP", "Gateway", "", "Ağ Geçidi", "Modulo Gateway", "Modul brány", "Modul brány") // TODO translate
|
||||
@@ -64,7 +64,7 @@ MAKE_WORD_TRANSLATION(info_cmd, "list all values (verbose)", "Liste aller Werte"
|
||||
MAKE_WORD_TRANSLATION(commands_cmd, "list all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi", "zobraziť všetky príkazy", "vypsat všechny příkazy") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entities_cmd, "list all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità", "zobraziť všetky entity", "vypsat všechny entity") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(send_cmd, "send a telegram", "Sende EMS-Telegramm", "stuur een telegram", "", "wyślij telegram", "send et telegram", "", "Bir telegram gönder", "invia un telegramma", "poslať telegram", "odeslat telegram") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(read_cmd, "send read request", "", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(read_cmd, "send read request", "", "", "", "", "", "", "", "", "odoslať žiadosť o prečítanie", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(setiovalue_cmd, "set I/O value", "Setze Werte E/A", "instellen standaardwaarde", "", "ustaw wartość", "sett en io verdi", "", "Giriş/Çıkış değerlerini ayarla", "imposta valore io", "nastaviť hodnotu io", "nastavit hodnotu I/O") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(changeloglevel_cmd, "change log level", "Ändere Protokollebene", "aanpassen log niveau", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir", "cambia livello registrazione", "zmeniť úroveň protokolu", "změnit úroveň protokolování") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(fetch_cmd, "refresh all EMS values", "Aktualisiere alle EMS-Werte", "Verversen alle EMS waardes", "", "odśwież wszystkie wartości EMS", "oppfrisk alle EMS verdier", "", "Bütün EMS değerlerini yenile", "aggiornare tutti i valori EMS", "obnoviť všetky hodnoty EMS", "aktualizovat všechny EMS hodnoty") // TODO translate
|
||||
@@ -79,6 +79,8 @@ MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoe
|
||||
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "Zugabe einer Menge kalten Wassers", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "", "pošlite studenú dávku vody", "poslat studenou vodu") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(message_cmd, "send a message", "Eine Nachricht senden", "", "", "", "", "", "", "", "poslať správu", "odeslat zprávu") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(values_cmd, "list all values", "Liste alle Werte auf", "", "", "", "", "", "", "", "vypísať všetky hodnoty", "vypsat všechny hodnoty") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(showertimer_cmd, "enable shower timer", "aktiviere Duschzeitmessung", "", "", "", "", "", "", "", "povoliť časovač sprchovania", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(showeralert_cmd, "enable shower alert", "aktiviere Duschzeitwarnung", "", "", "", "", "", "", "", "povoliť upozornenie na sprchu", "") // TODO translate
|
||||
|
||||
// tags
|
||||
MAKE_WORD_TRANSLATION(tag_hc1, "hc1", "HK1", "hc1", "VK1", "OG1", "hc1", "hc1", "ID1", "hc1", "hc1", "hc1")
|
||||
@@ -214,7 +216,7 @@ MAKE_WORD_TRANSLATION(hot_water, "hot water", "Warmwasser", "warm water", "varmv
|
||||
MAKE_WORD_TRANSLATION(pool, "pool", "Pool", "zwembad", "pool", "basen", "basseng", "piscine", "havuz", "piscina", "bazén", "bazén")
|
||||
MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa", "vonkajšia teplota altern.", "venkovní teplota alt.")
|
||||
MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela", "paralelne s vonkajšou teplotou", "paralelně s venkovní teplotou")
|
||||
MAKE_WORD_TRANSLATION(hp_preferred, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita", "preferované tepelné čerpadlo", "preferované tepelné čerpadlo")
|
||||
MAKE_WORD_TRANSLATION(hp_preferred, "heatpump preferred", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita", "preferované tepelné čerpadlo", "preferované tepelné čerpadlo")
|
||||
MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia", "len kotol", "pouze kotel")
|
||||
MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita", "znížený výkon", "snížený výkon")
|
||||
MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore", "vypnúť tep. čerpadlo", "vypnout tepelné čerpadlo")
|
||||
@@ -362,7 +364,7 @@ MAKE_TRANSLATION(emergencyOps, "emergencyops", "emergency operation", "Notbetrie
|
||||
MAKE_TRANSLATION(emergencyTemp, "emergencytemp", "emergency temperature", "Notfalltemperatur", "Noodtemperatuur", "Nöddrift temperatur", "temperatura w trybie awaryjnym", "nødtemperatur", "température d'urgence", "acil durum sıcaklığı", "temperatura di emergenza", "núdzová teplota", "nouzová teplota")
|
||||
MAKE_TRANSLATION(pumpMode, "pumpmode", "boiler pump mode", "Kesselpumpenmodus", "Ketelpomp modus", "", "tryb pracy pompy kotła", "pumpemodus", "", "pompa modu", "modalità pompa caldaia", "režim kotlového čerpadla", "režim čerpadla kotle") // TODO translate
|
||||
MAKE_TRANSLATION(pumpCharacter, "pumpcharacter", "boiler pump characteristic", "Charakteristik der Kesselpumpe", "karakteristiek ketelpomp", "pannpumpsegenskaper", "charakterystyka pompy kotłowej", "kjelepumpekarakteristikk", "caractéristique de la pompe de la chaudière", "gazan nasosy", "caratteristica della pompa della caldaia", "charakteristika kotlového čerpadla", "charakteristika čerpadla kotle") // TODO translate
|
||||
MAKE_TRANSLATION(pumpOnTemp, "pumpontemp", "pump logic temperature", "Pumpenlogiktemperatur", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(pumpOnTemp, "pumpontemp", "pump logic temperature", "Pumpenlogiktemperatur", "", "", "", "", "", "", "", "teplota logiky čerpadla", "") // TODO translate
|
||||
MAKE_TRANSLATION(headertemp, "headertemp", "low loss header", "Hydr. Weiche", "open verdeler", "", "sprzęgło hydrauliczne", "", "bouteille de déc. hydr.", "isı bloğu gidiş suyu sıc.", "comp. idr.", "nízkostratová hlavica", "") // TODO translate
|
||||
MAKE_TRANSLATION(heatblock, "heatblock", "heating block", "Wärmezelle", "Aanvoertemp. warmtecel", "", "blok grzewczy", "", "départ corps de chauffe", "Hid.denge kabı sıcaklığı", "mandata scamb. pr.", "vykurovací blok", "blok topení") // TODO translate
|
||||
|
||||
@@ -443,6 +445,7 @@ MAKE_TRANSLATION(maxHeatDhw, "maxheat", "heat limit", "Heizstab Limit für WW",
|
||||
|
||||
MAKE_TRANSLATION(auxHeaterOff, "auxheateroff", "disable aux heater", "Zusatzheizer deaktivieren", "Bijverwarming uitsc", "Blockera eltillskott", "wyłącz dogrzewacz", "deaktiver tilleggsvarme", "Désactiver chauff. d'app", "ilave ısıtıcıyı kapat", "disattivare i riscaldatori addizionali", "vypnúť pomocný ohrievač", "zakázat pomocné topení")
|
||||
MAKE_TRANSLATION(auxHeaterStatus, "auxheaterstatus", "aux heater status", "Zusatzheizerstatus", "Bijverwarming", "Eltillskott Status", "status dogrzewacza", "status el. tillegsvarme", "Chauffage auxiliaire", "ilave ısıtıcı durumu", "stato riscaldatori addizionali", "stav pomocného ohrievača", "stav pomocného topení")
|
||||
MAKE_TRANSLATION(auxHeaterLevel, "auxheaterlevel", "aux heater level", "Zusatzheizer", "Bijverwarming", "Eltillskott", "dogrzewacza", "el. tillegsvarme", "Chauffage auxiliaire", "ilave ısıtıcı durumu", "riscaldatori addizionali", "pomocného ohrievača", "pomocného topení")
|
||||
MAKE_TRANSLATION(auxHeaterOnly, "auxheateronly", "aux heater only", "nur Zusatzheizer", "Alleen bijverwarming", "Eltillskott Enbart", "tylko dogrzewacz", "kun el tilleggsvarme", "Que chauffage auxiliaire", "sadece ilave ısıtıvcı", "solo riscaldatori addizionali", "iba pomocný ohrievač", "pouze pomocné topení")
|
||||
MAKE_TRANSLATION(auxHeaterDelay, "auxheaterdelay", "aux heater on delay", "Zusatzheizer verzögert ein", "Bijverw. vertraagd aan", "Eltillskottfördröjning på", "opóźnienie włączenia dogrzewacza", "Tilleggsvarmer forsinket på", "Chauff app tempo marche", "ilave ısıtıcı beklemede", "ritardo riscaldatori addizionali", "oneskorenie prídavného ohrievača", "zpoždění zapnutí pomocného topení")
|
||||
MAKE_TRANSLATION(silentMode, "silentmode", "silent mode", "Silentmodus", "Stiller gebruik", "Tyst läge", "tryb cichy", "stille modus", "Fct silencieux", "sessiz mod", "modalità silenziosa", "tichý režim", "tichý režim")
|
||||
@@ -492,13 +495,13 @@ MAKE_TRANSLATION(hpPumpMode, "hppumpmode", "primary heatpump mode", "primärer W
|
||||
MAKE_TRANSLATION(instantstart, "instantstart", "instant start", "Sofortstart", "", "", "natychmiastowy start", "", "", "", "", "okamžité spustenie", "okamžité spuštění") // TODO translate
|
||||
MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "Oneskorenie zapnutia kúreni", "zpoždění zapnutí topení") // TODO translate
|
||||
MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "", "opóźnienie włączania ogrzewania", "", "", "", "", "Oneskorenie vypnutia kúrenia", "zpoždění vypnutí topení") // TODO translate
|
||||
MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differental pressure", "Pumpensolldruck", "", "", "różnica ciśnień", "", "", "", "", "nastaviť diferenčný tlak", "nastavení rozdílového tlaku") // TODO translate
|
||||
MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differential pressure", "Pumpensolldruck", "", "", "różnica ciśnień", "", "", "", "", "nastaviť diferenčný tlak", "nastavení rozdílového tlaku") // TODO translate
|
||||
MAKE_TRANSLATION(hpFan, "fan", "fan", "Lüfter", "", "", "wentylator", "", "", "", "", "ventilátor", "ventilátor") // TODO translate
|
||||
MAKE_TRANSLATION(hpShutdown, "shutdown", "shutdown", "Abschalten", "", "", "wyłączenie", "", "", "", "", "vypnutie", "vypnutí") // TODO translate
|
||||
MAKE_TRANSLATION(pc0Flow, "pc0flow", "Flow PC0", "Durchfluss PC0", "", "", "", "", "", "", "", "", "průtok PC0") // TODO translate
|
||||
MAKE_TRANSLATION(pc1Flow, "pc1flow", "Flow PC1", "Durchfluss PC1", "", "", "", "", "", "", "", "", "průtok PC1") // TODO translate
|
||||
MAKE_TRANSLATION(pc1On, "pc1on", "PC1", "PC1", "", "", "", "", "", "", "", "", "PC1") // TODO translate
|
||||
MAKE_TRANSLATION(pc1Rate, "pc1rate", "PC1 rate", "PC1 Rate", "", "", "", "", "", "", "", "", "míra PC1") // TODO translate
|
||||
MAKE_TRANSLATION(pc0Flow, "pc0flow", "Flow PC0", "Durchfluss PC0", "", "", "", "", "", "", "", "prietok PC0", "průtok PC0") // TODO translate
|
||||
MAKE_TRANSLATION(pc1Flow, "pc1flow", "Flow PC1", "Durchfluss PC1", "", "", "", "", "", "", "", "prietok PC1", "průtok PC1") // TODO translate
|
||||
MAKE_TRANSLATION(pc1On, "pc1on", "PC1", "PC1", "", "", "", "", "", "", "", "PC1", "PC1") // TODO translate
|
||||
MAKE_TRANSLATION(pc1Rate, "pc1rate", "PC1 rate", "PC1 Rate", "", "", "", "", "", "", "", "sadzba PC1", "míra PC1") // TODO translate
|
||||
|
||||
// hybrid heatpump
|
||||
MAKE_TRANSLATION(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid-Steuerungsstrategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride", "hibrit kontrol stratejisi", "strategia comtrollo ibrido", "hybridná stratégia riadenia", "strategie hybridního řízení")
|
||||
@@ -574,8 +577,15 @@ MAKE_TRANSLATION(meterCool, "metercool", "meter cooling", "Messung Kühlen", "",
|
||||
MAKE_TRANSLATION(meterWw, "meter", "meter", "Messung", "", "", "licznik", "", "", "", "", "počítadlo", "počítadlo") // TODO translate
|
||||
MAKE_TRANSLATION(gasMeterHeat, "gasmeterheat", "gas meter heating", "Gaszähler Heizen", "", "", "licznik gazu na ogrzewanie", "", "", "", "", "počítadlo plynu kúrenia", "počítadlo plynu pro vytápění") // TODO translate
|
||||
MAKE_TRANSLATION(gasMeterWw, "gasmeter", "gas meter", "Gaszähler", "", "", "licznik gazu", "", "", "", "", "počítadlo plynu", "počítadlo plynu") // TODO translate
|
||||
MAKE_TRANSLATION(hpCurrPower, "hpcurrpower", "compressor current power", "akt. Kompressorleistung", "", "", "", "", "", "", "", "", "aktuální výkon kompresoru") // TODO translate
|
||||
MAKE_TRANSLATION(hpPowerLimit, "hppowerlimit", "power limit", "Leistungsgrenze", "", "", "", "", "", "", "", "", "omezení výkonu") // TODO translate
|
||||
MAKE_TRANSLATION(hpCurrPower, "hpcurrpower", "compressor current power", "akt. Kompressorleistung", "", "", "", "", "", "", "", "aktuálny výkon kompresoru", "aktuální výkon kompresoru") // TODO translate
|
||||
MAKE_TRANSLATION(hpPowerLimit, "hppowerlimit", "power limit", "Leistungsgrenze", "", "", "", "", "", "", "", "obmedzenie výkonu", "omezení výkonu") // TODO translate
|
||||
MAKE_TRANSLATION(powerReduction, "powerreduction", "power reduction", "Leistungsverringerung", "", "", "", "", "", "", "", "obmedzenie výkonu", "omezení výkonu") // TODO translate
|
||||
MAKE_TRANSLATION(fuelHeat, "fuelheat", "fuel consuption heating", "Verbrauch Heizen", "", "", "", "", "", "", "", "obmedzenie výkonu", "omezení výkonu") // TODO translate
|
||||
MAKE_TRANSLATION(fuelDhw, "fueldhw", "fuel consuption", "Verbrauch", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(elHeat, "elheat", "el. consuption heating", "el. Verbrauch Heizen", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(elDhw, "eldhw", "el consuption", "el. Verbrauch", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(elGenHeat, "elgenheat", "el. generation heating", "el. Erzeugung Heizen", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_TRANSLATION(elGenDhw, "elgendhw", "el generation", "el. Erzeugung", "", "", "", "", "", "", "", "", "") // TODO translate
|
||||
|
||||
// HIU
|
||||
MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "Systemvorlauftemperatur", "Netto aanvoertemperatuur", "", "temp. zasilania sieci cieplnej", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento", "teplota prívodu tepelnej siete", "teplota přívodu tepelné sítě") // TODO translate
|
||||
@@ -619,7 +629,7 @@ MAKE_TRANSLATION(wwActive, "active", "active", "aktiv", "Actief", "Aktiv", "akty
|
||||
MAKE_TRANSLATION(ww3wayValve, "3wayvalve", "3-way valve active", "3-Wege-Ventil aktiv", "3-wegklep actief", "Trevägsventil aktiv", "zawór 3-drogowy aktywny", "aktiv trevisventil", "vanne 3 voies active", "3 yollu vana", "valvola 3-vie", "3-cestný ventil aktívny", "aktivní 3-cestný ventil")
|
||||
MAKE_TRANSLATION(wwMixerTemp, "mixertemp", "mixer temperature", "Mischertemperatur", "Mixertemperatuur", "Blandningsventil-tempertur", "temperatura mieszacza", "temperatur blandeventil", "température mélangeur", "karıştırıcı sıcaklığı", "temperatura miscelatore", "teplota mixéra", "teplota směšovače")
|
||||
MAKE_TRANSLATION(wwStarts, "starts", "starts", "Anzahl Starts", "Aantal starts", "Antal starter", "liczba załączeń", "antall starter", "démarrages", "başlıyor", "avvii", "Počet štartov", "Počet startů")
|
||||
MAKE_TRANSLATION(wwStarts2, "starts2", "control starts2", "Anzahl Starts Kreis 2 ", "Aantal starts circuit 2", "Antal starter Krets 2", "liczba załączeń 2", "antall starter krets 2", "démarrages contrôle 2", "devre 2 başlıyor", "avvii controllati 2", "Okruh 2 počet štartov", "Počet startů okruh 2")
|
||||
MAKE_TRANSLATION(wwStartsHp, "startshp", "starts hp", "Anzahl Starts WP", "", "", "", "", "", "", "", "Počet spustení hp", "") // TODO translate
|
||||
MAKE_TRANSLATION(wwWorkM, "workm", "active time", "aktive Zeit", "Actieve tijd", "Aktiv Tid", "czas aktywności", "driftstid", "temps actif", "aktif zaman", "tempo attivo", "aktívny čas", "aktivní čas")
|
||||
MAKE_TRANSLATION(wwHystOn, "hyston", "hysteresis on temperature", "Einschalttemperaturdifferenz", "Inschakeltemperatuurverschil", "Hysteres PÅ-temperatur", "histereza załączania", "innkoblingstemperaturforskjell", "hystérésis température allumage", "çalışma sıcaklığı farkı", "differenza di temperatura di accensione", "hysterézia teploty", "hystereze zapnutí")
|
||||
MAKE_TRANSLATION(wwHystOff, "hystoff", "hysteresis off temperature", "Ausschalttemperaturdifferenz", "Uitschakeltemperatuurverschil", "Hysteres AV-temperatur", "histereza wyłączania", "utkoblingstemperaturforskjell", "hystérésis température extinction", "kapatma sıcaklığı farkı", "differenza di temperatura di spegnimento", "teplota hysterézie", "hystereze vypnutí")
|
||||
@@ -810,6 +820,10 @@ MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time",
|
||||
MAKE_TRANSLATION(energyLastHour, "energylasthour", "energy last hour", "Energie letzte Std", "Energie laatste uur", "Energi Senaste Timmen", "energia w ciągu ostatniej godziny", "energi siste time", "énergie dernière heure", "son saat enerji", "Eenergia ultima ora", "energia za poslednú hodinu", "energie za poslední hodinu")
|
||||
MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "Totale energie", "Total Energi", "energia całkowita", "total energi", "énergie totale", "toplam enerji", "energia totale", "celková energia", "celková energie")
|
||||
MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera", "celková energia dnes", "celková energie dnes")
|
||||
MAKE_TRANSLATION(cyl3BottomTemp, "cyl3bottomtemp", "third cylinder bottom temperature (TS11)", "Speichertemperatur unten (TS11)") // TODO translate
|
||||
MAKE_TRANSLATION(cylTopTemp, "cyltoptemp", "cylinder top temperature (TS10)", "Speichertemperatur oben (TS10)") // TODO translate
|
||||
MAKE_TRANSLATION(transferPumpMod, "transferpumpmod", "transfer pump modulation", "Transferpumpenmodulation") // TODO translate
|
||||
MAKE_TRANSLATION(transferPump, "transferpump", "transfer pump", "Transferpumpe") // TODO translate
|
||||
|
||||
// solar dhw
|
||||
MAKE_TRANSLATION(wwColdTemp, "coldtemp", "cold water", "Kaltwasser", "", "", "zimna woda", "", "", "", "", "studená voda", "studená voda") // TODO translate
|
||||
@@ -830,7 +844,7 @@ MAKE_TRANSLATION(wwKeepWarm, "keepwarm", "keep warm", "Warmhalten", "Warm houde"
|
||||
MAKE_TRANSLATION(wwStatus2, "status2", "status 2", "Status 2", "Status 2", "Status 2", "status 2", "status 2", "statut 2", "durum 2", "Status 2", "stav 2", "stav 2")
|
||||
MAKE_TRANSLATION(wwPumpMod, "pumpmod", "pump modulation", "Pumpenmodulation", "Pompmodulatie", "Pumpmodulering", "modulacja pompy", "pumpemodulering", "modulation de pompe", "pompa modülasyonu", "modulazione pompa", "modulácia čerpadla", "modulace čerpadla")
|
||||
MAKE_TRANSLATION(wwFlow, "flow", "flow rate", "Volumenstrom", "Doorstroomsnelheid", "Flöde", "przepływ", "strømningshastighet", "débit", "akış hızı", "portata flusso", "prietok", "průtok")
|
||||
// MAKE_TRANSLATION(wwRetValve, "retvalve", "return valve", "Rücklauf Ventil", "", "", "", "", "", "", "", "", "zpětný ventil")
|
||||
// MAKE_TRANSLATION(wwRetValve, "retvalve", "return valve", "Rücklauf Ventil", "", "", "", "", "", "", "", "spätný ventil", "zpětný ventil")
|
||||
|
||||
// extra mixer dhw
|
||||
MAKE_TRANSLATION(wwRequiredTemp, "requiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta", "požadovaná teplota", "požadovaná teplota")
|
||||
|
||||
@@ -38,7 +38,7 @@ void Modbus::start(uint8_t systemServerId, uint16_t port, uint8_t max_clients, u
|
||||
}
|
||||
}
|
||||
modbusServer_->start(port, max_clients, timeout);
|
||||
LOG_INFO("Modbus server with ID %d started on port %d", systemServerId, port);
|
||||
LOG_INFO("Starting Modbus service (ID %d, port %d)", systemServerId, port);
|
||||
#else
|
||||
if (!check_parameter_order()) {
|
||||
LOG_ERROR("Unable to enable Modbus - the parameter list order is corrupt. This is a firmware bug.");
|
||||
@@ -275,20 +275,8 @@ ModbusMessage Modbus::handleRead(const ModbusMessage & request) {
|
||||
|
||||
auto register_offset = start_address - tag * REGISTER_BLOCK_SIZE;
|
||||
|
||||
const auto & dev_it =
|
||||
std::find_if(EMSESP::emsdevices.begin(), EMSESP::emsdevices.end(), [&](const std::unique_ptr<EMSdevice> & x) { return x->device_type() == device_type; });
|
||||
|
||||
if (dev_it == EMSESP::emsdevices.end()) {
|
||||
// device not found => invalid server ID
|
||||
LOG_ERROR("device with type %d not found => invalid server ID", device_type);
|
||||
response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_DATA_ADDRESS);
|
||||
return response;
|
||||
}
|
||||
|
||||
const auto & dev = *dev_it;
|
||||
|
||||
// binary search in modbus infos
|
||||
auto key = EntityModbusInfoKey(dev->device_type(), tag_type, register_offset);
|
||||
auto key = EntityModbusInfoKey(device_type, tag_type, register_offset);
|
||||
|
||||
const auto & modbusInfo = std::lower_bound(std::begin(modbus_register_mappings),
|
||||
std::end(modbus_register_mappings),
|
||||
@@ -312,7 +300,15 @@ ModbusMessage Modbus::handleRead(const ModbusMessage & request) {
|
||||
}
|
||||
|
||||
auto buf = std::vector<uint16_t>(num_words);
|
||||
auto error_code = dev->get_modbus_value(tag, modbusInfo->short_name, buf);
|
||||
int error_code = -1;
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice->device_type() == device_type) {
|
||||
error_code = emsdevice->get_modbus_value(tag, modbusInfo->short_name, buf);
|
||||
if (!error_code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error_code) {
|
||||
LOG_ERROR("Unable to read raw device value %s for tag=%d - error_code = %d", modbusInfo->short_name, (int)tag, error_code);
|
||||
response.setError(request.getServerID(), request.getFunctionCode(), SERVER_DEVICE_FAILURE);
|
||||
@@ -370,22 +366,9 @@ ModbusMessage Modbus::handleWrite(const ModbusMessage & request) {
|
||||
|
||||
LOG_DEBUG("Tag %d, offset %d", tag, register_offset);
|
||||
|
||||
const auto & dev_it =
|
||||
std::find_if(EMSESP::emsdevices.begin(), EMSESP::emsdevices.end(), [&](const std::unique_ptr<EMSdevice> & x) { return x->device_type() == device_type; });
|
||||
|
||||
if (dev_it == EMSESP::emsdevices.end()) {
|
||||
// device not found => invalid server ID
|
||||
LOG_ERROR("device_type (%d) not found => invalid server ID", device_type);
|
||||
response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_DATA_ADDRESS);
|
||||
return response;
|
||||
}
|
||||
|
||||
const auto & dev = *dev_it;
|
||||
|
||||
LOG_DEBUG("found device '%s' of type %d", dev->name().c_str(), dev->device_type());
|
||||
|
||||
// binary search in modbus infos
|
||||
auto key = EntityModbusInfoKey(dev->device_type(), tag_type, register_offset);
|
||||
auto key = EntityModbusInfoKey(device_type, tag_type, register_offset);
|
||||
auto modbusInfo = std::lower_bound(std::begin(modbus_register_mappings),
|
||||
std::end(modbus_register_mappings),
|
||||
key,
|
||||
@@ -412,9 +395,16 @@ ModbusMessage Modbus::handleWrite(const ModbusMessage & request) {
|
||||
}
|
||||
|
||||
JsonDocument input_doc;
|
||||
JsonObject input = input_doc.to<JsonObject>();
|
||||
|
||||
auto error_code = dev->modbus_value_to_json(tag, modbusInfo->short_name, data, input);
|
||||
JsonObject input = input_doc.to<JsonObject>();
|
||||
int error_code = -1;
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice->device_type() == device_type) {
|
||||
error_code = emsdevice->modbus_value_to_json(tag, modbusInfo->short_name, data, input);
|
||||
if (!error_code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error_code) {
|
||||
// error getting modbus value as json
|
||||
LOG_ERROR("error getting modbus value as json, error code = %d", error_code);
|
||||
@@ -424,9 +414,9 @@ ModbusMessage Modbus::handleWrite(const ModbusMessage & request) {
|
||||
|
||||
std::string path;
|
||||
if (tag < DeviceValueTAG::TAG_HC1) {
|
||||
path = std::string("ems-esp/") + std::string(EMSdevice::device_type_2_device_name(dev->device_type())) + "/" + modbusInfo->short_name;
|
||||
path = std::string("ems-esp/") + std::string(EMSdevice::device_type_2_device_name(device_type)) + "/" + modbusInfo->short_name;
|
||||
} else {
|
||||
path = std::string("ems-esp/") + std::string(EMSdevice::device_type_2_device_name(dev->device_type())) + "/" + EMSdevice::tag_to_mqtt(tag) + "/"
|
||||
path = std::string("ems-esp/") + std::string(EMSdevice::device_type_2_device_name(device_type)) + "/" + EMSdevice::tag_to_mqtt(tag) + "/"
|
||||
+ modbusInfo->short_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "emsdevice.h"
|
||||
|
||||
/*
|
||||
* This file is auto-generated by the update_modbus_registers.sh script. Do not modify.
|
||||
* This file is auto-generated. Do not modify.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
@@ -87,114 +87,116 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPower), 137, 1), // hppower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpMaxPower), 138, 1), // hpmaxpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pvMaxComp), 139, 1), // pvmaxcomp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSetDiffPress), 140, 1), // hpsetdiffpress
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompOn), 141, 1), // hpcompon
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpActivity), 142, 1), // hpactivity
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrinePumpSpd), 143, 1), // hpbrinepumpspd
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSwitchValve), 144, 1), // hpswitchvalve
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompSpd), 145, 1), // hpcompspd
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCircSpd), 146, 1), // hpcircspd
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineIn), 147, 1), // hpbrinein
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineOut), 148, 1), // hpbrineout
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc0), 149, 1), // hptc0
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc1), 150, 1), // hptc1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc3), 151, 1), // hptc3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr1), 152, 1), // hptr1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr3), 153, 1), // hptr3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr4), 154, 1), // hptr4
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr5), 155, 1), // hptr5
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr6), 156, 1), // hptr6
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr7), 157, 1), // hptr7
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTl2), 158, 1), // hptl2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPl1), 159, 1), // hppl1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPh1), 160, 1), // hpph1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTa4), 161, 1), // hpta4
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTw1), 162, 1), // hptw1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(poolSetTemp), 163, 1), // poolsettemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp4wayValve), 164, 1), // hp4way
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput1), 165, 1), // hpin1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn1Opt), 166, 8), // hpin1opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput2), 174, 1), // hpin2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn2Opt), 175, 8), // hpin2opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput3), 183, 1), // hpin3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn3Opt), 184, 8), // hpin3opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput4), 192, 1), // hpin4
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn4Opt), 193, 8), // hpin4opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatComp), 201, 1), // maxheatcomp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatHeat), 202, 1), // maxheatheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(manDefrost), 203, 1), // mandefrost
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pvCooling), 204, 1), // pvcooling
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOnly), 205, 1), // auxheateronly
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOff), 206, 1), // auxheateroff
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterStatus), 207, 1), // auxheaterstatus
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 208, 1), // auxheaterdelay
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 209, 1), // auxmaxlimit
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 210, 1), // auxlimitstart
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 211, 1), // auxheatrmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 212, 1), // hphystheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 213, 1), // hphystcool
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 214, 1), // hphystpool
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 215, 1), // silentmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 216, 1), // silentfrom
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 217, 1), // silentto
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 218, 1), // mintempsilent
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 219, 1), // tempparmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 220, 1), // auxheatmix
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 221, 1), // tempdiffheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 222, 1), // tempdiffcool
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 223, 1), // vpcooling
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 224, 1), // heatcable
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 225, 1), // vc0valve
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 226, 1), // primepump
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 227, 1), // primepumpmod
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 228, 1), // hp3way
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 229, 1), // elheatstep1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 230, 1), // elheatstep2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 231, 1), // elheatstep3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 232, 1), // hpea0
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 233, 1), // hppumpmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 234, 1), // fan
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 235, 1), // shutdown
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 236, 1), // hpcurrpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 237, 1), // hppowerlimit
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc0Flow), 238, 1), // pc0flow
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Flow), 239, 1), // pc1flow
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1On), 240, 1), // pc1on
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Rate), 241, 1), // pc1rate
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 242, 1), // exhausttemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 243, 1), // burngas
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 244, 1), // burngas2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 245, 1), // flamecurr
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 246, 1), // fanwork
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 247, 1), // ignwork
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 248, 1), // oilpreheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 249, 1), // burnminpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 250, 1), // burnmaxpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 251, 1), // burnminperiod
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 252, 1), // absburnpow
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 253, 1), // heatblock
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 254, 1), // boilhyston
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 255, 1), // boilhystoff
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 256, 1), // boil2hyston
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 257, 1), // boil2hystoff
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 258, 1), // curveon
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 259, 1), // curvebase
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 260, 1), // curveend
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 261, 1), // summertemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 262, 1), // nofrostmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 263, 1), // nofrosttemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 264, 2), // gasmeterheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 266, 2), // nrgheat2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 268, 1), // nompower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 269, 1), // netflowtemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 270, 1), // heatvalve
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 271, 1), // keepwarmtemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 272, 1), // setreturntemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 273, 1), // heating
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(powerReduction), 140, 1), // powerreduction
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSetDiffPress), 141, 1), // hpsetdiffpress
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompOn), 142, 1), // hpcompon
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpActivity), 143, 1), // hpactivity
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrinePumpSpd), 144, 1), // hpbrinepumpspd
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSwitchValve), 145, 1), // hpswitchvalve
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompSpd), 146, 1), // hpcompspd
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCircSpd), 147, 1), // hpcircspd
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineIn), 148, 1), // hpbrinein
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineOut), 149, 1), // hpbrineout
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc0), 150, 1), // hptc0
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc1), 151, 1), // hptc1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc3), 152, 1), // hptc3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr1), 153, 1), // hptr1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr3), 154, 1), // hptr3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr4), 155, 1), // hptr4
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr5), 156, 1), // hptr5
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr6), 157, 1), // hptr6
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr7), 158, 1), // hptr7
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTl2), 159, 1), // hptl2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPl1), 160, 1), // hppl1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPh1), 161, 1), // hpph1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTa4), 162, 1), // hpta4
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTw1), 163, 1), // hptw1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(poolSetTemp), 164, 1), // poolsettemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp4wayValve), 165, 1), // hp4way
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput1), 166, 1), // hpin1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn1Opt), 167, 8), // hpin1opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput2), 175, 1), // hpin2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn2Opt), 176, 8), // hpin2opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput3), 184, 1), // hpin3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn3Opt), 185, 8), // hpin3opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput4), 193, 1), // hpin4
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn4Opt), 194, 8), // hpin4opt
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatComp), 202, 1), // maxheatcomp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatHeat), 203, 1), // maxheatheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(manDefrost), 204, 1), // mandefrost
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pvCooling), 205, 1), // pvcooling
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOnly), 206, 1), // auxheateronly
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOff), 207, 1), // auxheateroff
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterStatus), 208, 1), // auxheaterstatus
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterLevel), 209, 1), // auxheaterlevel
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 210, 1), // auxheaterdelay
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 211, 1), // auxmaxlimit
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 212, 1), // auxlimitstart
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 213, 1), // auxheatrmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 214, 1), // hphystheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 215, 1), // hphystcool
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 216, 1), // hphystpool
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 217, 1), // silentmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 218, 1), // silentfrom
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 219, 1), // silentto
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 220, 1), // mintempsilent
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 221, 1), // tempparmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 222, 1), // auxheatmix
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 223, 1), // tempdiffheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 224, 1), // tempdiffcool
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 225, 1), // vpcooling
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 226, 1), // heatcable
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 227, 1), // vc0valve
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 228, 1), // primepump
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 229, 1), // primepumpmod
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 230, 1), // hp3way
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 231, 1), // elheatstep1
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 232, 1), // elheatstep2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 233, 1), // elheatstep3
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 234, 1), // hpea0
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 235, 1), // hppumpmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 236, 1), // fan
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 237, 1), // shutdown
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 238, 1), // hpcurrpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 239, 1), // hppowerlimit
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc0Flow), 240, 1), // pc0flow
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Flow), 241, 1), // pc1flow
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1On), 242, 1), // pc1on
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pc1Rate), 243, 1), // pc1rate
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 244, 1), // exhausttemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 245, 1), // burngas
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 246, 1), // burngas2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 247, 1), // flamecurr
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 248, 1), // fanwork
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 249, 1), // ignwork
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 250, 1), // oilpreheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 251, 1), // burnminpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 252, 1), // burnmaxpower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 253, 1), // burnminperiod
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 254, 1), // absburnpow
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 255, 1), // heatblock
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 256, 1), // boilhyston
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 257, 1), // boilhystoff
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 258, 1), // boil2hyston
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 259, 1), // boil2hystoff
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 260, 1), // curveon
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 261, 1), // curvebase
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 262, 1), // curveend
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 263, 1), // summertemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 264, 1), // nofrostmode
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 265, 1), // nofrosttemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 266, 2), // gasmeterheat
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 268, 2), // nrgheat2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 270, 1), // nompower
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 271, 1), // netflowtemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 272, 1), // heatvalve
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 273, 1), // keepwarmtemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 274, 1), // setreturntemp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 275, 1), // heating
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(upTimeCompWw), 4, 2), // uptimecomp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwStarts2), 6, 2), // starts2
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwStartsHp), 6, 2), // startshp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgConsCompWw), 8, 2), // nrgconscomp
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(auxElecHeatNrgConsWw), 10, 2), // auxelecheatnrgcons
|
||||
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgSuppWw), 12, 2), // nrgsupp
|
||||
@@ -398,13 +400,6 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_HC, FL_(mixerSetTime), 5, 1), // valvesettime
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_HC, FL_(flowTempVf), 6, 1), // flowtempvf
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_HC, FL_(flowtempoffset), 7, 1), // flowtempoffset
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(flowTempHc), 0, 1), // flowtemphc
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(valveStatus), 1, 1), // valvestatus
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(flowSetTemp), 2, 1), // flowsettemp
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(wwPumpStatus), 3, 1), // pumpstatus
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(activated), 4, 1), // activated
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(mixerSetTime), 5, 1), // valvesettime
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_DHW, FL_(flowtempoffset), 6, 1), // flowtempoffset
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collectorTemp), 0, 1), // collectortemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cylBottomTemp), 1, 1), // cylbottomtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump), 2, 1), // solarpump
|
||||
@@ -428,40 +423,45 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2), 22, 1), // solarpump2
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2Mod), 23, 1), // solarpump2mod
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cyl2BottomTemp), 24, 1), // cyl2bottomtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatExchangerTemp), 25, 1), // heatexchangertemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cylPumpMod), 26, 1), // cylpumpmod
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(valveStatus), 27, 1), // valvestatus
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(vs1Status), 28, 1), // vs1status
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collectorMaxTemp), 29, 1), // collectormaxtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collectorMinTemp), 30, 1), // collectormintemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(energyToday), 31, 2), // energytoday
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(energyTotal), 33, 2), // energytotal
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(pump2WorkTime), 35, 2), // pump2worktime
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(m1WorkTime), 37, 2), // m1worktime
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatTransferSystem), 39, 1), // heattransfersystem
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(externalCyl), 40, 1), // externalcyl
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(thermalDisinfect), 41, 1), // thermaldisinfect
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatMetering), 42, 1), // heatmetering
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(activated), 43, 1), // activated
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpMode), 44, 1), // solarpumpmode
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpKick), 45, 1), // solarpumpkick
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(plainWaterMode), 46, 1), // plainwatermode
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(doubleMatchFlow), 47, 1), // doublematchflow
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(pump2MinMod), 48, 1), // pump2minmod
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2TurnonDiff), 49, 1), // turnondiff2
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2TurnoffDiff), 50, 1), // turnoffdiff2
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2Kick), 51, 1), // pump2kick
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(climateZone), 52, 1), // climatezone
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector1Area), 53, 1), // collector1area
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector1Type), 54, 1), // collector1type
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector2Area), 55, 1), // collector2area
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector2Type), 56, 1), // collector2type
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cylPriority), 57, 1), // cylpriority
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatCntFlowTemp), 58, 1), // heatcntflowtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatCntRetTemp), 59, 1), // heatcntrettemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatCnt), 60, 1), // heatcnt
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(swapFlowTemp), 61, 1), // swapflowtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(swapRetTemp), 62, 1), // swaprettemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cyl3BottomTemp), 25, 1), // cyl3bottomtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cylTopTemp), 26, 1), // cyltoptemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatExchangerTemp), 27, 1), // heatexchangertemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cylPumpMod), 28, 1), // cylpumpmod
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(valveStatus), 29, 1), // valvestatus
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(vs1Status), 30, 1), // vs1status
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(vs3Status), 31, 1), // vs3status
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(transferPump), 32, 1), // transferpump
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(transferPumpMod), 33, 1), // transferpumpmod
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collectorMaxTemp), 34, 1), // collectormaxtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collectorMinTemp), 35, 1), // collectormintemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(energyToday), 36, 2), // energytoday
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(energyTotal), 38, 2), // energytotal
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(pump2WorkTime), 40, 2), // pump2worktime
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(m1WorkTime), 42, 2), // m1worktime
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatTransferSystem), 44, 1), // heattransfersystem
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(externalCyl), 45, 1), // externalcyl
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(thermalDisinfect), 46, 1), // thermaldisinfect
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatMetering), 47, 1), // heatmetering
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(activated), 48, 1), // activated
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpMode), 49, 1), // solarpumpmode
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpKick), 50, 1), // solarpumpkick
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(plainWaterMode), 51, 1), // plainwatermode
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(doubleMatchFlow), 52, 1), // doublematchflow
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(pump2MinMod), 53, 1), // pump2minmod
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2TurnonDiff), 54, 1), // turnondiff2
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2TurnoffDiff), 55, 1), // turnoffdiff2
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPump2Kick), 56, 1), // pump2kick
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(climateZone), 57, 1), // climatezone
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector1Area), 58, 1), // collector1area
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector1Type), 59, 1), // collector1type
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector2Area), 60, 1), // collector2area
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(collector2Type), 61, 1), // collector2type
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(cylPriority), 62, 1), // cylpriority
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatCntFlowTemp), 63, 1), // heatcntflowtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatCntRetTemp), 64, 1), // heatcntrettemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatCnt), 65, 1), // heatcnt
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(swapFlowTemp), 66, 1), // swapflowtemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(swapRetTemp), 67, 1), // swaprettemp
|
||||
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DHW, FL_(wwMinTemp), 0, 1), // mintemp
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airHumidity), 0, 1), // airhumidity
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(dewTemperature), 1, 1), // dewtemperature
|
||||
@@ -483,25 +483,33 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseMode), 17, 1), // lownoisemode
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseStart), 18, 1), // lownoisestart
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(lowNoiseStop), 19, 1), // lownoisestop
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(hybridDHW), 20, 1), // hybriddhw
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceGas), 21, 1), // energypricegas
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceEl), 22, 1), // energypriceel
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPricePV), 23, 1), // energyfeedpv
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(switchOverTemp), 24, 1), // switchovertemp
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airPurgeMode), 25, 1), // airpurgemode
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatPumpOutput), 26, 1), // heatpumpoutput
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(coolingCircuit), 27, 1), // coolingcircuit
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(compStartMod), 28, 1), // compstartmod
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatDrainPan), 29, 1), // heatdrainpan
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 30, 1), // heatcable
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgTotal), 31, 2), // nrgtotal
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat), 33, 2), // nrgheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterTotal), 35, 2), // metertotal
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterComp), 37, 2), // metercomp
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterEHeat), 39, 2), // metereheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterHeat), 41, 2), // meterheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceGas), 20, 1), // energypricegas
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPriceEl), 21, 1), // energypriceel
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(energyPricePV), 22, 1), // energyfeedpv
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(switchOverTemp), 23, 1), // switchovertemp
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(airPurgeMode), 24, 1), // airpurgemode
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatPumpOutput), 25, 1), // heatpumpoutput
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(coolingCircuit), 26, 1), // coolingcircuit
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(compStartMod), 27, 1), // compstartmod
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatDrainPan), 28, 1), // heatdrainpan
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 29, 1), // heatcable
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgTotal), 30, 2), // nrgtotal
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat), 32, 2), // nrgheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterTotal), 34, 2), // metertotal
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterComp), 36, 2), // metercomp
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterEHeat), 38, 2), // metereheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(meterHeat), 40, 2), // meterheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(heatingStarts), 42, 2), // heatingstarts
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(fuelHeat), 44, 2), // fuelheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(elHeat), 46, 2), // elheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DEVICE_DATA, FL_(elGenHeat), 48, 2), // elgenheat
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(hybridDHW), 0, 1), // hybriddhw
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(nrgWw), 1, 2), // nrg
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(meterWw), 3, 2), // meter
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(wwStartsHp), 5, 2), // startshp
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(fuelDhw), 7, 2), // fueldhw
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(elDhw), 9, 2), // eldhw
|
||||
REGISTER_MAPPING(dt::HEATPUMP, TAG_TYPE_DHW, FL_(elGenDhw), 11, 2), // elgendhw
|
||||
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(activated), 0, 1), // activated
|
||||
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(flowTempHc), 1, 1), // flowtemphc
|
||||
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(status), 2, 1), // status
|
||||
@@ -527,6 +535,36 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::VENTILATION, TAG_TYPE_DEVICE_DATA, FL_(ventMode), 6, 1), // ventmode
|
||||
REGISTER_MAPPING(dt::VENTILATION, TAG_TYPE_DEVICE_DATA, FL_(airquality), 7, 1), // airquality
|
||||
REGISTER_MAPPING(dt::VENTILATION, TAG_TYPE_DEVICE_DATA, FL_(airHumidity), 8, 1), // airhumidity
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(selRoomTemp), 0, 1), // seltemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwTemp), 1, 1), // temp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwCurTemp2), 2, 1), // curtemp2
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(hydrTemp), 3, 1), // hydrTemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwPump), 4, 1), // pump
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(flowtempoffset), 5, 1), // flowtempoffset
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwHystOn), 6, 1), // hyston
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwHystOff), 7, 1), // hystoff
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwDisinfectionTemp), 8, 1), // disinfectiontemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwCirc), 9, 1), // circ
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwCircMode), 10, 1), // circmode
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwTempStatus), 11, 1), // tempstatus
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwMaxTemp), 12, 1), // maxtemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwDiffTemp), 13, 1), // difftemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwRedTemp), 14, 1), // redtemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwRequiredTemp), 15, 1), // requiredtemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwStorageTemp1), 16, 1), // storagetemp1
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwColdTemp), 17, 1), // coldtemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwTemp5), 18, 1), // temp5
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(retTemp), 19, 1), // rettemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwHotTemp), 20, 1), // hottemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwDailyTemp), 21, 1), // dailytemp
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwCircTc), 22, 1), // circtc
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwKeepWarm), 23, 1), // keepwarm
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwStatus2), 24, 1), // status2
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwPumpMod), 25, 1), // pumpmod
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(wwFlow), 26, 1), // flow
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(valveReturn), 27, 1), // valvereturn
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(deltaTRet), 28, 1), // deltatret
|
||||
REGISTER_MAPPING(dt::WATER, TAG_TYPE_DHW, FL_(errorDisp), 29, 1), // errordisp
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
112
src/mqtt.cpp
112
src/mqtt.cpp
@@ -386,16 +386,6 @@ void Mqtt::start() {
|
||||
// add the 'publish' command ('call system publish' in console or via API)
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, FL_(publish_cmd));
|
||||
|
||||
// create last will topic with the base prefixed. It has to be static because the client destroys the reference
|
||||
static char will_topic[MQTT_TOPIC_MAX_SIZE];
|
||||
if (!Mqtt::base().empty()) {
|
||||
snprintf(will_topic, MQTT_TOPIC_MAX_SIZE, "%s/status", Mqtt::base().c_str());
|
||||
} else {
|
||||
snprintf(will_topic, MQTT_TOPIC_MAX_SIZE, "status");
|
||||
}
|
||||
|
||||
EMSESP::esp8266React.setWill(will_topic); // with qos 1, retain true
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
Mqtt::on_connect(); // simulate an MQTT connection
|
||||
#endif
|
||||
@@ -468,6 +458,7 @@ void Mqtt::on_disconnect(espMqttClientTypes::DisconnectReason reason) {
|
||||
return;
|
||||
}
|
||||
connecting_ = false;
|
||||
connectcount_++; // count # reconnects
|
||||
|
||||
if (reason == espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) {
|
||||
LOG_WARNING("MQTT disconnected: TCP");
|
||||
@@ -499,7 +490,6 @@ void Mqtt::on_connect() {
|
||||
LOG_INFO("MQTT connected");
|
||||
|
||||
connecting_ = true;
|
||||
connectcount_++; // count # reconnects. not currently used.
|
||||
queuecount_ = mqttClient_->queueSize();
|
||||
|
||||
load_settings(); // reload MQTT settings - in case they have changes
|
||||
@@ -513,7 +503,7 @@ void Mqtt::on_connect() {
|
||||
// with disabled HA we subscribe and the broker sends all stored HA-emsesp-configs.
|
||||
// Around line 272 they are removed (search for "// remove HA topics if we don't use discover")
|
||||
// If HA is enabled the subscriptions are removed.
|
||||
// As described in the doc (https://emsesp.github.io/docs/#/Troubleshooting?id=home-assistant):
|
||||
// As described in the doc (https://docs.emsesp.org/Troubleshooting?id=home-assistant):
|
||||
// disable HA, wait 5 minutes (to allow the broker to send all), than reenable HA again.
|
||||
queue_subscribe_message(discovery_prefix_ + "/+/" + mqtt_basename_ + "/#");
|
||||
}
|
||||
@@ -584,7 +574,6 @@ void Mqtt::ha_status() {
|
||||
publish_system_ha_sensor_config(DeviceValueType::STRING, "EMS Bus", "bus_status", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "uptime", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS);
|
||||
publish_system_ha_sensor_config(DeviceValueType::BOOL, "NTP status", "ntp_status", DeviceValueUOM::CONNECTIVITY);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Free memory", "freemem", DeviceValueUOM::KB);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Max Alloc", "max_alloc", DeviceValueUOM::KB);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "MQTT fails", "mqttfails", DeviceValueUOM::NONE);
|
||||
@@ -593,8 +582,10 @@ void Mqtt::ha_status() {
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx reads", "txreads", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx writes", "txwrites", DeviceValueUOM::NONE);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx fails", "txfails", DeviceValueUOM::NONE);
|
||||
|
||||
// This comes from the info MQTT topic
|
||||
if (!EMSESP::system_.ethernet_connected()) {
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT16, "WiFi reconnects", "wifireconnects", DeviceValueUOM::NONE);
|
||||
}
|
||||
// This comes from the info MQTT topic - and handled in the publish_ha_sensor_config function
|
||||
publish_system_ha_sensor_config(DeviceValueType::STRING, "Version", "version", DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
@@ -934,14 +925,13 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
char config_topic[70];
|
||||
snprintf(config_topic, sizeof(config_topic), "%s/%s_%s/config", mqtt_basename_.c_str(), device_name, entity_with_tag);
|
||||
|
||||
bool readonly_sensors = true;
|
||||
|
||||
// create the topic
|
||||
// depending on the type and whether the device entity is writable (a command)
|
||||
// depending on the type and whether the device entity is writable (i.e. a command)
|
||||
// https://developers.home-assistant.io/docs/core/entity
|
||||
char topic[MQTT_TOPIC_MAX_SIZE];
|
||||
// if it's a command then we can use Number, Switch, Select or Text. Otherwise stick to Sensor
|
||||
topic[0] = '\0'; // nullify, making it empty
|
||||
if (has_cmd) {
|
||||
// if it's a command then we can use Number, Switch, Select or Text. Otherwise stick to Sensor
|
||||
switch (type) {
|
||||
case DeviceValueType::INT8:
|
||||
case DeviceValueType::UINT8:
|
||||
@@ -950,48 +940,40 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
case DeviceValueType::UINT24:
|
||||
case DeviceValueType::UINT32:
|
||||
// number - https://www.home-assistant.io/integrations/number.mqtt
|
||||
// older Domoticz does not support number, use sensor
|
||||
// older Domoticz does not support number, will default to Sensor
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) {
|
||||
snprintf(topic, sizeof(topic), "number/%s", config_topic);
|
||||
readonly_sensors = false;
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::BOOL:
|
||||
// switch - https://www.home-assistant.io/integrations/switch.mqtt
|
||||
snprintf(topic, sizeof(topic), "switch/%s", config_topic);
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
case DeviceValueType::ENUM:
|
||||
snprintf(topic, sizeof(topic), "select/%s", config_topic);
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
case DeviceValueType::CMD: // hardcoded commands are always ENUMS
|
||||
// select - https://www.home-assistant.io/integrations/select.mqtt
|
||||
snprintf(topic, sizeof(topic), "select/%s", config_topic);
|
||||
break;
|
||||
case DeviceValueType::CMD:
|
||||
if (uom == DeviceValueUOM::NONE) {
|
||||
snprintf(topic, sizeof(topic), "select/%s", config_topic);
|
||||
snprintf(topic, sizeof(topic), "select/%s", config_topic); // hardcoded commands are always ENUMS
|
||||
} else if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) {
|
||||
snprintf(topic, sizeof(topic), "number/%s", config_topic);
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
}
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
case DeviceValueType::STRING:
|
||||
// text - https://www.home-assistant.io/integrations/text.mqtt
|
||||
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime
|
||||
readonly_sensors = false;
|
||||
// Domoticz does not support text, will default to Sensor
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT) {
|
||||
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// plain old sensor, and make it read-only
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// For read-only sensors there are either sensor or binary_sensor
|
||||
// for both we also set the device class and state class
|
||||
if (readonly_sensors) {
|
||||
// if at this point we don't have a topic created yet, create a default sensor one. We always need a topic.
|
||||
if (!strnlen(topic, sizeof(topic))) {
|
||||
snprintf(topic, sizeof(topic), (type == DeviceValueType::BOOL) ? "binary_sensor/%s" : "sensor/%s", config_topic); // binary sensor (for booleans)
|
||||
}
|
||||
|
||||
@@ -1057,21 +1039,6 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
doc["max"] = dv_set_max;
|
||||
snprintf(sample_val, sizeof(sample_val), "%i", dv_set_min);
|
||||
}
|
||||
|
||||
// set icons
|
||||
// since these don't have a device class we need to add the icon ourselves
|
||||
switch (uom) {
|
||||
case DeviceValueUOM::DEGREES:
|
||||
case DeviceValueUOM::DEGREES_R:
|
||||
case DeviceValueUOM::K:
|
||||
doc["ic"] = F_(icondegrees);
|
||||
break;
|
||||
case DeviceValueUOM::PERCENT:
|
||||
doc["ic"] = F_(iconpercent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// friendly name = <tag> <name>
|
||||
@@ -1106,7 +1073,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
char val_obj[100];
|
||||
char val_cond[200];
|
||||
if (is_nested() && tag >= DeviceValueTAG::TAG_HC1) {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json.%s['%s']", EMSdevice::tag_to_mqtt(tag), entity);
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']['%s']", EMSdevice::tag_to_mqtt(tag), entity);
|
||||
snprintf(val_cond, sizeof(val_cond), "value_json.%s is defined and %s is defined", EMSdevice::tag_to_mqtt(tag), val_obj);
|
||||
} else {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", entity);
|
||||
@@ -1121,27 +1088,34 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
strlcpy(sample_val, "false", sizeof(sample_val)); // default is "false"
|
||||
}
|
||||
|
||||
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
|
||||
// don't bother with value template conditions if using Domoticz which doesn't fully support MQTT Discovery
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT) {
|
||||
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
|
||||
|
||||
// add the dev json object to the end, not for commands
|
||||
add_ha_sections_to_doc(nullptr, stat_t, doc, false, val_cond); // no name, since the "dev" has already been adde
|
||||
}
|
||||
|
||||
// Add the state class, device class and sometimes the icon. Used only for read-only sensors like Sensor and Binary Sensor
|
||||
if (readonly_sensors) {
|
||||
// first set the catagory for System entities
|
||||
// https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873
|
||||
if (device_type == EMSdevice::DeviceType::SYSTEM) {
|
||||
doc["ent_cat"] = "diagnostic";
|
||||
// adds availability, dev, ids to the config section to HA Discovery config
|
||||
// except for commands
|
||||
add_ha_sections_to_doc(nullptr, stat_t, doc, false, val_cond); // no name, since the "dev" has already been added
|
||||
} else {
|
||||
// Domoticz doesn't support value templates, so we just use the value directly
|
||||
// Also omit the uom and other state classes
|
||||
doc["val_tpl"] = (std::string) "{{" + val_obj + "}}";
|
||||
}
|
||||
add_ha_uom(doc.as<JsonObject>(), type, uom, entity); // add the UoM, device and state class
|
||||
}
|
||||
|
||||
// Add the state class, device class and an optional icon based on the uom
|
||||
// first set the catagory for System entities
|
||||
// https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873
|
||||
if (device_type == EMSdevice::DeviceType::SYSTEM) {
|
||||
doc["ent_cat"] = "diagnostic"; // instead of config
|
||||
}
|
||||
add_ha_uom(doc.as<JsonObject>(), type, uom, entity);
|
||||
|
||||
doc["dev"] = dev_json;
|
||||
|
||||
return queue_ha(topic, doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
// Add the state class, device class and an optional icon based on the uom
|
||||
void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) {
|
||||
const char * dc_ha = "dev_cla"; // device class
|
||||
const char * sc_ha = "stat_cla"; // state class
|
||||
@@ -1158,20 +1132,26 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con
|
||||
doc[uom_ha] = "s";
|
||||
} else if (uom != DeviceValueUOM::NONE) {
|
||||
doc[uom_ha] = EMSdevice::uom_to_string(uom); // default
|
||||
} else if (discovery_type() != discoveryType::HOMEASSISTANT) {
|
||||
// Domoticz use " " for a no-uom
|
||||
doc[uom_ha] = " ";
|
||||
}
|
||||
}
|
||||
|
||||
// set state and device class
|
||||
// also icon, when there is no device class that sets one
|
||||
switch (uom) {
|
||||
case DeviceValueUOM::DEGREES:
|
||||
case DeviceValueUOM::DEGREES_R:
|
||||
case DeviceValueUOM::K:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = "temperature";
|
||||
doc["ic"] = F_(icondegrees); // icon
|
||||
break;
|
||||
case DeviceValueUOM::PERCENT:
|
||||
doc[sc_ha] = F_(measurement);
|
||||
doc[dc_ha] = "power_factor";
|
||||
doc["ic"] = F_(iconpercent); // icon
|
||||
break;
|
||||
case DeviceValueUOM::SECONDS:
|
||||
case DeviceValueUOM::MINUTES:
|
||||
|
||||
@@ -166,24 +166,22 @@ void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) {
|
||||
// empty message back if temperature not set or unknown message type
|
||||
if (data[2] == EMSdevice::EMS_TYPE_VERSION) {
|
||||
version(addr, data[0], hc);
|
||||
} else if (length == 6 && remotetemp_[hc] == EMS_VALUE_INT16_NOTSET) {
|
||||
unknown(addr, data[0], data[2], data[3]);
|
||||
} else if (length == 8 && remotetemp_[hc] == EMS_VALUE_INT16_NOTSET) {
|
||||
unknown(addr, data[0], data[3], data[5], data[6]);
|
||||
} else if (data[2] == 0xAF && data[3] == 0) {
|
||||
temperature(addr, data[0], hc);
|
||||
} else if (length == 6) { // all other ems queries
|
||||
unknown(addr, data[0], data[2], data[3]);
|
||||
} else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 0 && data[6] == 0x23) { // Junkers
|
||||
temperature(addr, data[0], hc);
|
||||
} else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x2B + hc) { // EMS+ temperature
|
||||
temperature(addr, data[0], hc);
|
||||
} else if (length == 8 && data[2] == 0xFF && data[3] == 0 && data[5] == 3 && data[6] == 0x7B + hc && remotehum_[hc] != EMS_VALUE_UINT8_NOTSET) { // EMS+ humidity
|
||||
humidity(addr, data[0], hc);
|
||||
} else if (length == 6) { // ems query
|
||||
unknown(addr, data[0], data[2], data[3]);
|
||||
} else if (length == 8 && data[2] == 0xFF) { // ems+ query
|
||||
unknown(addr, data[0], data[3], data[5], data[6]);
|
||||
} else if (data[2] == 0xF7) { // ems+ query with 3 bytes type src dst 7F offset len=FF FF HIGH LOW
|
||||
replyF7(addr, data[0], data[3], data[5], data[6], data[7], hc);
|
||||
} else if (length == 8) {
|
||||
unknown(addr, data[0], data[3], data[5], data[6]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,48 @@ void Shower::start() {
|
||||
FL_(coldshot_cmd),
|
||||
CommandFlag::ADMIN_ONLY);
|
||||
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::SYSTEM,
|
||||
F_(showertimer),
|
||||
[&](const char * value, const int8_t id, JsonObject output) {
|
||||
bool b;
|
||||
if (!Helpers::value2bool(value, b)) {
|
||||
return false;
|
||||
}
|
||||
shower_timer_ = b;
|
||||
EMSESP::webSettingsService.update([&](WebSettings & settings) {
|
||||
if (settings.shower_timer != b) {
|
||||
settings.shower_timer = b;
|
||||
return StateUpdateResult::CHANGED;
|
||||
}
|
||||
return StateUpdateResult::UNCHANGED;
|
||||
});
|
||||
return true;
|
||||
},
|
||||
FL_(showertimer_cmd),
|
||||
CommandFlag::ADMIN_ONLY);
|
||||
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::SYSTEM,
|
||||
F_(showeralert),
|
||||
[&](const char * value, const int8_t id, JsonObject output) {
|
||||
bool b;
|
||||
if (!Helpers::value2bool(value, b)) {
|
||||
return false;
|
||||
}
|
||||
shower_alert_ = b;
|
||||
EMSESP::webSettingsService.update([&](WebSettings & settings) {
|
||||
if (settings.shower_alert != b) {
|
||||
settings.shower_alert = b;
|
||||
return StateUpdateResult::CHANGED;
|
||||
}
|
||||
return StateUpdateResult::UNCHANGED;
|
||||
});
|
||||
return true;
|
||||
},
|
||||
FL_(showeralert_cmd),
|
||||
CommandFlag::ADMIN_ONLY);
|
||||
|
||||
if (shower_timer_) {
|
||||
set_shower_state(false, true); // turns shower to off and creates HA topic if not already done
|
||||
}
|
||||
|
||||
@@ -52,12 +52,17 @@
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
// Languages supported. Note: the order is important and must match locale_translations.h
|
||||
#if defined(EMSESP_TEST) || defined(EMSESP_EN_ONLY)
|
||||
// in Debug mode use one language (en) to save flash memory needed for the tests
|
||||
// Languages supported. Note: the order is important
|
||||
// and must match locale_translations.h and common.h
|
||||
#if defined(EMSESP_TEST)
|
||||
// in Test mode use two languages (en & de) to save flash memory needed for the tests
|
||||
const char * const languages[] = {EMSESP_LOCALE_EN, EMSESP_LOCALE_DE};
|
||||
#elif defined(EMSESP_EN_ONLY)
|
||||
// EN only
|
||||
const char * const languages[] = {EMSESP_LOCALE_EN};
|
||||
#elif defined(EMSESP_DE_ONLY)
|
||||
const char * const languages[] = {EMSESP_LOCALE_DE};
|
||||
// EN + DE
|
||||
const char * const languages[] = {EMSESP_LOCALE_EN, EMSESP_LOCALE_DE};
|
||||
#else
|
||||
const char * const languages[] = {EMSESP_LOCALE_EN,
|
||||
EMSESP_LOCALE_DE,
|
||||
@@ -92,7 +97,7 @@ uint8_t System::language_index() {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0; // EN
|
||||
return 0; // EN only
|
||||
}
|
||||
|
||||
// send raw to ems
|
||||
@@ -678,15 +683,7 @@ void System::heartbeat_json(JsonObject output) {
|
||||
|
||||
output["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||
output["uptime_sec"] = uuid::get_uptime_sec();
|
||||
bool value_b = ntp_connected();
|
||||
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||
output["ntp_status"] = value_b;
|
||||
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
|
||||
output["ntp_status"] = value_b ? 1 : 0;
|
||||
} else {
|
||||
char s[12];
|
||||
output["ntp_status"] = Helpers::render_boolean(s, value_b);
|
||||
}
|
||||
|
||||
output["rxreceived"] = EMSESP::rxservice_.telegram_count();
|
||||
output["rxfails"] = EMSESP::rxservice_.telegram_error_count();
|
||||
output["txreads"] = EMSESP::txservice_.telegram_read_count();
|
||||
@@ -694,9 +691,9 @@ void System::heartbeat_json(JsonObject output) {
|
||||
output["txfails"] = EMSESP::txservice_.telegram_read_fail_count() + EMSESP::txservice_.telegram_write_fail_count();
|
||||
|
||||
if (Mqtt::enabled()) {
|
||||
output["mqttcount"] = Mqtt::publish_count();
|
||||
output["mqttfails"] = Mqtt::publish_fails();
|
||||
output["mqttconnects"] = Mqtt::connect_count();
|
||||
output["mqttcount"] = Mqtt::publish_count();
|
||||
output["mqttfails"] = Mqtt::publish_fails();
|
||||
output["mqttreconnects"] = Mqtt::connect_count();
|
||||
}
|
||||
output["apicalls"] = WebAPIService::api_count(); // + WebAPIService::api_fails();
|
||||
output["apifails"] = WebAPIService::api_fails();
|
||||
@@ -716,9 +713,10 @@ void System::heartbeat_json(JsonObject output) {
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (!ethernet_connected_) {
|
||||
int8_t rssi = WiFi.RSSI();
|
||||
output["rssi"] = rssi;
|
||||
output["wifistrength"] = wifi_quality(rssi);
|
||||
int8_t rssi = WiFi.RSSI();
|
||||
output["rssi"] = rssi;
|
||||
output["wifistrength"] = wifi_quality(rssi);
|
||||
output["wifireconnects"] = EMSESP::esp8266React.getWifiReconnects();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1135,6 +1133,7 @@ void System::show_system(uuid::console::Shell & shell) {
|
||||
}
|
||||
|
||||
// see if there is a restore of an older settings file that needs to be applied
|
||||
// note there can be only one file at a time
|
||||
bool System::check_restore() {
|
||||
bool reboot_required = false; // true if we need to reboot
|
||||
|
||||
@@ -1168,7 +1167,7 @@ bool System::check_restore() {
|
||||
// it's a custom support file - save it to /config
|
||||
new_file.close();
|
||||
if (LittleFS.rename(TEMP_FILENAME_PATH, EMSESP_CUSTOMSUPPORT_FILE)) {
|
||||
LOG_DEBUG("Custom support information found");
|
||||
LOG_INFO("Custom support file stored");
|
||||
return false; // no need to reboot
|
||||
} else {
|
||||
LOG_ERROR("Failed to save custom support file");
|
||||
@@ -1498,9 +1497,10 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
// node["IPv6 address"] = uuid::printable_to_string(ETH.localIPv6());
|
||||
// }
|
||||
} else if (WiFi.status() == WL_CONNECTED) {
|
||||
node["network"] = "WiFi";
|
||||
node["hostname"] = WiFi.getHostname();
|
||||
node["RSSI"] = WiFi.RSSI();
|
||||
node["network"] = "WiFi";
|
||||
node["hostname"] = WiFi.getHostname();
|
||||
node["RSSI"] = WiFi.RSSI();
|
||||
node["WIFIReconnects"] = EMSESP::esp8266React.getWifiReconnects();
|
||||
// node["MAC"] = WiFi.macAddress();
|
||||
// node["IPv4 address"] = uuid::printable_to_string(WiFi.localIP()) + "/" + uuid::printable_to_string(WiFi.subnetMask());
|
||||
// node["IPv4 gateway"] = uuid::printable_to_string(WiFi.gatewayIP());
|
||||
@@ -1529,6 +1529,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
node["CORSOrigin"] = settings.CORSOrigin;
|
||||
}
|
||||
});
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
EMSESP::esp8266React.getAPSettingsService()->read([&](const APSettings & settings) {
|
||||
const char * pM[] = {"always", "disconnected", "never"};
|
||||
@@ -1556,7 +1557,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
node["MQTTPublishes"] = Mqtt::publish_count();
|
||||
node["MQTTQueued"] = Mqtt::publish_queued();
|
||||
node["MQTTPublishFails"] = Mqtt::publish_fails();
|
||||
node["MQTTConnects"] = Mqtt::connect_count();
|
||||
node["MQTTReconnects"] = Mqtt::connect_count();
|
||||
}
|
||||
EMSESP::esp8266React.getMqttSettingsService()->read([&](const MqttSettings & settings) {
|
||||
node["enabled"] = settings.enabled;
|
||||
|
||||
@@ -148,7 +148,7 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
||||
// validate the CRC. if it fails then increment the number of corrupt/incomplete telegrams and only report to console/syslog
|
||||
uint8_t crc = calculate_crc(data, length - 1);
|
||||
if (data[length - 1] != crc) {
|
||||
if ((data[0] & 0x7F) != ems_bus_id()) { // do not count echos as errors
|
||||
if (data[0] != EMSuart::last_tx_src()) { // do not count echos as errors
|
||||
telegram_error_count_++;
|
||||
LOG_WARNING("Incomplete Rx: %s", Helpers::data_to_hex(data, length).c_str()); // include CRC
|
||||
} else {
|
||||
|
||||
@@ -482,7 +482,7 @@ void TemperatureSensor::publish_values(const bool force) {
|
||||
char val_obj[70];
|
||||
char val_cond[170];
|
||||
if (Mqtt::is_nested()) {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s'].temp", sensor.id().c_str());
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']['temp']", sensor.id().c_str());
|
||||
snprintf(val_cond, sizeof(val_cond), "value_json['%s'] is defined and %s is defined", sensor.id().c_str(), val_obj);
|
||||
} else {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str());
|
||||
|
||||
@@ -50,7 +50,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "general") {
|
||||
EMSESP::logger().info("Testing general. Adding a Boiler and Thermostat");
|
||||
EMSESP::logger().notice("Testing general. Adding a Boiler and Thermostat");
|
||||
|
||||
// System::test_set_all_active(true); // uncomment if we want to show all entities and give them fake values
|
||||
|
||||
@@ -77,6 +77,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// the tests take a lot of memory when built for the ESP32
|
||||
// so only including the full set in standalone, otherwise a limited selection of basic tests
|
||||
@@ -84,7 +85,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
#ifdef EMSESP_STANDALONE
|
||||
|
||||
if (cmd == "heat_exchange") {
|
||||
EMSESP::logger().info("Testing heating exchange...");
|
||||
EMSESP::logger().notice("Testing heating exchange...");
|
||||
|
||||
add_device(0x08, 219); // Greenstar HIU/Logamax kompakt WS170
|
||||
|
||||
@@ -96,7 +97,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "2thermostats") {
|
||||
EMSESP::logger().info("Testing with multiple thermostats...");
|
||||
EMSESP::logger().notice("Testing with multiple thermostats...");
|
||||
|
||||
add_device(0x08, 123); // GB072
|
||||
add_device(0x10, 158); // RC310
|
||||
@@ -128,7 +129,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "310") {
|
||||
EMSESP::logger().info("Adding a GB072/RC310 combo...");
|
||||
EMSESP::logger().notice("Adding a GB072/RC310 combo...");
|
||||
|
||||
add_device(0x08, 123); // GB072
|
||||
add_device(0x10, 158); // RC310
|
||||
@@ -155,7 +156,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "gateway") {
|
||||
EMSESP::logger().info("Adding a Gateway...");
|
||||
EMSESP::logger().notice("Adding a Gateway...");
|
||||
|
||||
// add 0x48 KM200, via a version command
|
||||
rx_telegram({0x48, 0x0B, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00});
|
||||
@@ -175,7 +176,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "mixer") {
|
||||
EMSESP::logger().info("Adding a mixer...");
|
||||
EMSESP::logger().notice("Adding a mixer...");
|
||||
|
||||
// add controller
|
||||
add_device(0x09, 114);
|
||||
@@ -197,7 +198,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "boiler") {
|
||||
EMSESP::logger().info("Adding boiler...");
|
||||
EMSESP::logger().notice("Adding boiler...");
|
||||
add_device(0x08, 123); // Nefit Trendline
|
||||
|
||||
// UBAuptime
|
||||
@@ -214,7 +215,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "thermostat") {
|
||||
EMSESP::logger().info("Adding thermostat...");
|
||||
EMSESP::logger().notice("Adding thermostat...");
|
||||
|
||||
add_device(0x10, 192); // FW120
|
||||
|
||||
@@ -227,7 +228,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "solar") {
|
||||
EMSESP::logger().info("Adding solar...");
|
||||
EMSESP::logger().notice("Adding solar...");
|
||||
|
||||
add_device(0x30, 163); // SM100
|
||||
|
||||
@@ -246,7 +247,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
}
|
||||
|
||||
if (cmd == "heatpump") {
|
||||
EMSESP::logger().info("Adding heatpump...");
|
||||
EMSESP::logger().notice("Adding heatpump...");
|
||||
|
||||
add_device(0x38, 200); // Enviline module
|
||||
add_device(0x10, 192); // FW120 thermostat
|
||||
@@ -263,7 +264,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// These next tests are run from the Consol via the test command, so inherit the Shell
|
||||
// These next tests are run from the Console via the test command, so inherit the Shell
|
||||
void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const std::string & id1_s, const std::string & id2_s) {
|
||||
bool ok = false; // default tests fail
|
||||
|
||||
@@ -307,7 +308,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
shell.printfln("Testing Adding a device (product_id %d), with all values...", id2);
|
||||
test("add", id1, id2);
|
||||
shell.invoke_command("show values");
|
||||
shell.invoke_command("show devices");
|
||||
ok = true;
|
||||
}
|
||||
|
||||
// set the language
|
||||
if (command == "locale") {
|
||||
shell.printfln("Testing setting locale to %s", id1_s.c_str());
|
||||
EMSESP::system_.locale(id1_s.c_str());
|
||||
shell.invoke_command("show");
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -315,15 +324,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
shell.printfln("Testing adding a boiler, thermostat, all sensors, scheduler and custom entities...");
|
||||
|
||||
// setup fake data
|
||||
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
|
||||
// EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
|
||||
|
||||
// add devices
|
||||
test("general");
|
||||
|
||||
EMSESP::webCustomEntityService.test(); // add custom entities
|
||||
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
|
||||
EMSESP::temperaturesensor_.test(); // add temperature sensors
|
||||
EMSESP::webSchedulerService.test(); // add scheduler items
|
||||
// EMSESP::webCustomEntityService.test(); // add custom entities
|
||||
// EMSESP::temperaturesensor_.test(); // add temperature sensors
|
||||
// EMSESP::webSchedulerService.test(); // add scheduler items
|
||||
|
||||
// shell.invoke_command("show devices");
|
||||
// shell.invoke_command("show values");
|
||||
@@ -434,7 +442,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (command == "entity_dump") {
|
||||
System::test_set_all_active(true);
|
||||
EMSESP::dump_all_values(shell);
|
||||
EMSESP::dump_all_entities(shell);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -543,7 +551,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
}
|
||||
|
||||
if (command == "620") {
|
||||
EMSESP::logger().info("Testing 620...");
|
||||
EMSESP::logger().notice("Testing 620...");
|
||||
|
||||
// Version Controller
|
||||
uart_telegram({0x09, 0x0B, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||
@@ -1006,25 +1014,35 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
// request.url("/api");
|
||||
// EMSESP::webAPIService.webAPIService(&request, doc.as<JsonVariant>());
|
||||
|
||||
char data2[] = "{\"action\":\"customSupport\", \"param\":\"hello\"}";
|
||||
char data2[] = "{\"action\":\"getCustomSupport\", \"param\":\"hello\"}";
|
||||
deserializeJson(doc, data2);
|
||||
request.url("/rest/action");
|
||||
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
|
||||
char data3[] = "{\"action\":\"export\", \"param\":\"schedule\"}";
|
||||
deserializeJson(doc, data3);
|
||||
request.url("/rest/action");
|
||||
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
// char data3[] = "{\"action\":\"export\", \"param\":\"schedule\"}";
|
||||
// deserializeJson(doc, data3);
|
||||
// request.url("/rest/action");
|
||||
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
|
||||
char data4[] = "{\"action\":\"export\", \"param\":\"allvalues\"}";
|
||||
deserializeJson(doc, data4);
|
||||
request.url("/rest/action");
|
||||
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
// char data4[] = "{\"action\":\"export\", \"param\":\"allvalues\"}";
|
||||
// deserializeJson(doc, data4);
|
||||
// request.url("/rest/action");
|
||||
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
|
||||
char data5[] = "{\"action\":\"checkUpgrade\", \"param\":\"3.7.0-dev.99\"}";
|
||||
deserializeJson(doc, data5);
|
||||
request.url("/rest/action");
|
||||
EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
// test version checks
|
||||
// test with "current_version_s = "3.7.1-dev.8" in WebStatusService::checkUpgrade()
|
||||
// request.url("/rest/action");
|
||||
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.9,3.7.0\"}"); // is upgradable
|
||||
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is not upgradable
|
||||
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
|
||||
// test with "current_version_s = "3.6.5" in WebStatusService::checkUpgrade()
|
||||
// request.url("/rest/action");
|
||||
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.9,3.6.5\"}"); // is noy upgradable
|
||||
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
// deserializeJson(doc, "{\"action\":\"checkUpgrade\", \"param\":\"3.7.1-dev.7,3.7.0\"}"); // is upgradable
|
||||
// EMSESP::webStatusService.action(&request, doc.as<JsonVariant>());
|
||||
|
||||
// char data6[] = "{\"device\":\"system\", \"cmd\":\"read\",\"value\":\"8 2 27 1\"}";
|
||||
// deserializeJson(doc, data6);
|
||||
@@ -2220,8 +2238,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
#endif
|
||||
|
||||
if (!ok) {
|
||||
shell.printfln("Unknown test command: %s", command.c_str());
|
||||
EMSESP::logger().notice("Unknown test command: %s", command.c_str());
|
||||
shell.printfln("Unknown test %s", command.c_str());
|
||||
EMSESP::logger().notice("Unknown test %s", command.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "emsesp.h"
|
||||
|
||||
namespace emsesp {
|
||||
uint8_t EMSuart::last_tx_src_ = 0;
|
||||
|
||||
static QueueHandle_t uart_queue;
|
||||
uint8_t tx_mode_ = 0xFF;
|
||||
@@ -144,6 +145,8 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
|
||||
return EMS_TX_STATUS_OK;
|
||||
}
|
||||
|
||||
last_tx_src_ = len < 4 ? 0 : buf[0];
|
||||
|
||||
if (tx_mode_ == EMS_TXMODE_HW) { // hardware controlled mode
|
||||
uart_write_bytes_with_break(EMSUART_NUM, buf, len, 10);
|
||||
return EMS_TX_STATUS_OK;
|
||||
|
||||
@@ -65,10 +65,14 @@ class EMSuart {
|
||||
static void send_poll(const uint8_t data);
|
||||
static void stop();
|
||||
static uint16_t transmit(const uint8_t * buf, const uint8_t len);
|
||||
static uint8_t last_tx_src() {
|
||||
return last_tx_src_;
|
||||
}
|
||||
|
||||
private:
|
||||
static void IRAM_ATTR uart_gen_break(uint32_t length_us);
|
||||
static void uart_event_task(void * pvParameters);
|
||||
static uint8_t last_tx_src_;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.0"
|
||||
#define EMSESP_APP_VERSION "3.7.1"
|
||||
|
||||
@@ -32,13 +32,12 @@ WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * security
|
||||
// POST|GET api/{device}
|
||||
// POST|GET api/{device}/{entity}
|
||||
void WebAPIService::webAPIService(AsyncWebServerRequest * request, JsonVariant json) {
|
||||
JsonObject input;
|
||||
JsonDocument input_doc; // has no body JSON so create dummy as empty input object
|
||||
JsonObject input;
|
||||
// if no body then treat it as a secure GET
|
||||
if ((request->method() == HTTP_GET) || (!json.is<JsonObject>())) {
|
||||
// HTTP GET
|
||||
JsonDocument input_doc; // has no body JSON so create dummy as empty input object
|
||||
input = input_doc.to<JsonObject>();
|
||||
|
||||
} else {
|
||||
// HTTP_POST
|
||||
input = json.as<JsonObject>(); // extract values from the json. these will be used as default values
|
||||
|
||||
@@ -415,7 +415,16 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) {
|
||||
|
||||
JsonObject dv = node["dv"].to<JsonObject>();
|
||||
dv["id"] = "00" + sensor.name();
|
||||
if (sensor.type() == AnalogSensor::AnalogType::DIGITAL_OUT || sensor.type() == AnalogSensor::AnalogType::DIGITAL_IN) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (sensor.type() == AnalogSensor::AnalogType::DIGITAL_OUT && (sensor.gpio() == 25 || sensor.gpio() == 26)) {
|
||||
obj["v"] = Helpers::transformNumFloat(sensor.value(), 0);
|
||||
} else
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
if (sensor.type() == AnalogSensor::AnalogType::DIGITAL_OUT && (sensor.gpio() == 17 || sensor.gpio() == 18)) {
|
||||
obj["v"] = Helpers::transformNumFloat(sensor.value(), 0);
|
||||
} else
|
||||
#endif
|
||||
if (sensor.type() == AnalogSensor::AnalogType::DIGITAL_OUT || sensor.type() == AnalogSensor::AnalogType::DIGITAL_IN) {
|
||||
char s[12];
|
||||
dv["v"] = Helpers::render_boolean(s, sensor.value() != 0, true);
|
||||
JsonArray l = dv["l"].to<JsonArray>();
|
||||
|
||||
@@ -322,8 +322,7 @@ bool WebSchedulerService::command(const char * name, const std::string & command
|
||||
JsonDocument doc;
|
||||
if (deserializeJson(doc, cmd) == DeserializationError::Ok) {
|
||||
HTTPClient http;
|
||||
int httpResult = 0;
|
||||
std::string url = doc["url"] | "";
|
||||
std::string url = doc["url"] | "";
|
||||
// for a GET with parameters replace commands with values
|
||||
// don't search the complete url, it may contain a devicename in path
|
||||
auto q = url.find_first_of('?');
|
||||
@@ -342,6 +341,7 @@ bool WebSchedulerService::command(const char * name, const std::string & command
|
||||
std::string method = doc["method"] | "GET"; // default GET
|
||||
|
||||
// if there is data, force a POST
|
||||
int httpResult = 0;
|
||||
if (value.length() || method == "post") { // we have all lowercase
|
||||
if (value.find_first_of('{') != std::string::npos) {
|
||||
http.addHeader("Content-Type", "application/json"); // auto-set to JSON
|
||||
|
||||
@@ -179,8 +179,8 @@ void WebStatusService::action(AsyncWebServerRequest * request, JsonVariant json)
|
||||
if (has_param) {
|
||||
ok = exportData(root, param);
|
||||
}
|
||||
} else if (action == "customSupport") {
|
||||
ok = customSupport(root);
|
||||
} else if (action == "getCustomSupport") {
|
||||
ok = getCustomSupport(root);
|
||||
} else if (action == "uploadURL" && is_admin) {
|
||||
ok = uploadURL(param.c_str());
|
||||
}
|
||||
@@ -203,21 +203,44 @@ void WebStatusService::action(AsyncWebServerRequest * request, JsonVariant json)
|
||||
}
|
||||
|
||||
// action = checkUpgrade
|
||||
bool WebStatusService::checkUpgrade(JsonObject root, std::string & latest_version) {
|
||||
root["emsesp_version"] = EMSESP_APP_VERSION;
|
||||
|
||||
if (!latest_version.empty()) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
emsesp::EMSESP::logger().debug("Checking for upgrade: %s > %s", EMSESP_APP_VERSION, latest_version.c_str());
|
||||
// versions holds the latest development version and stable version in one string, comma separated
|
||||
bool WebStatusService::checkUpgrade(JsonObject root, std::string & versions) {
|
||||
std::string current_version_s;
|
||||
#ifndef EMSESP_STANDALONE
|
||||
current_version_s = EMSESP_APP_VERSION;
|
||||
#else
|
||||
// for testing only - see api3 test in test.cpp
|
||||
// current_version_s = "3.6.5";
|
||||
current_version_s = "3.7.1-dev.8";
|
||||
#endif
|
||||
|
||||
version::Semver200_version settings_version(EMSESP_APP_VERSION);
|
||||
version::Semver200_version this_version(latest_version);
|
||||
if (!versions.empty()) {
|
||||
version::Semver200_version current_version(current_version_s);
|
||||
bool using_dev_version = !current_version.prerelease().find("dev"); // look for dev in the name to determine if we're using dev version
|
||||
version::Semver200_version latest_version(using_dev_version ? versions.substr(0, versions.find(',')) : versions.substr(versions.find(',') + 1));
|
||||
bool upgradeable = (latest_version > current_version);
|
||||
|
||||
root["upgradeable"] = (this_version > settings_version);
|
||||
#if defined(EMSESP_DEBUG)
|
||||
emsesp::EMSESP::logger()
|
||||
.debug("Checking Version upgrade. Using %s release branch. current version=%d.%d.%d-%s, latest version=%d.%d.%d-%s (%s upgradeable)",
|
||||
(using_dev_version ? "dev" : "stable"),
|
||||
current_version.major(),
|
||||
current_version.minor(),
|
||||
current_version.patch(),
|
||||
current_version.prerelease().c_str(),
|
||||
latest_version.major(),
|
||||
latest_version.minor(),
|
||||
latest_version.patch(),
|
||||
latest_version.prerelease().c_str(),
|
||||
upgradeable ? "IS" : "NOT");
|
||||
#endif
|
||||
|
||||
root["upgradeable"] = upgradeable;
|
||||
}
|
||||
|
||||
return true; // always ok
|
||||
root["emsesp_version"] = current_version_s; // always send back current version
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// action = allvalues
|
||||
@@ -278,19 +301,28 @@ bool WebStatusService::exportData(JsonObject root, std::string & type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// action = customSupport
|
||||
// action = getCustomSupport
|
||||
// reads any upload customSupport.json file and sends to to Help page to be shown as Guest
|
||||
bool WebStatusService::customSupport(JsonObject root) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
bool WebStatusService::getCustomSupport(JsonObject root) {
|
||||
JsonDocument doc;
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
// dummy test data for "test api3"
|
||||
deserializeJson(
|
||||
doc, "{\"type\":\"customSupport\",\"Support\":{\"html\":[\"html code\",\"here\"], \"img_url\": \"https://docs.emsesp.org/_media/images/designer.png\"}");
|
||||
#else
|
||||
// check if we have custom support file uploaded
|
||||
File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r");
|
||||
if (!file) {
|
||||
// there is no custom file, return empty object
|
||||
#if defined(EMSESP_DEBUG)
|
||||
emsesp::EMSESP::logger().debug("No custom support file found");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// read the contents of the file into the root output json object
|
||||
DeserializationError error = deserializeJson(root, file);
|
||||
// read the contents of the file into a json doc. We can't do this direct to object since 7.2.1
|
||||
DeserializationError error = deserializeJson(doc, file);
|
||||
if (error) {
|
||||
emsesp::EMSESP::logger().err("Failed to read custom support file");
|
||||
return false;
|
||||
@@ -298,6 +330,13 @@ bool WebStatusService::customSupport(JsonObject root) {
|
||||
|
||||
file.close();
|
||||
#endif
|
||||
|
||||
#if defined(EMSESP_DEBUG)
|
||||
emsesp::EMSESP::logger().debug("Showing custom support page");
|
||||
#endif
|
||||
|
||||
root.set(doc.as<JsonObject>()); // add to web response root object
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class WebStatusService {
|
||||
// actions
|
||||
bool checkUpgrade(JsonObject root, std::string & latest_version);
|
||||
bool exportData(JsonObject root, std::string & type);
|
||||
bool customSupport(JsonObject root);
|
||||
bool getCustomSupport(JsonObject root);
|
||||
bool uploadURL(const char * url);
|
||||
|
||||
void allvalues(JsonObject output);
|
||||
|
||||
Reference in New Issue
Block a user