mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
remove master_thermostat
This commit is contained in:
@@ -58,6 +58,7 @@
|
|||||||
- Wired renamed to Ethernet
|
- Wired renamed to Ethernet
|
||||||
- removed system/pin command, new commands in analogsensors
|
- removed system/pin command, new commands in analogsensors
|
||||||
- system/info device-info split to name/version/brand
|
- system/info device-info split to name/version/brand
|
||||||
|
- remove master-thermostat
|
||||||
|
|
||||||
## **BREAKING CHANGES:**
|
## **BREAKING CHANGES:**
|
||||||
|
|
||||||
|
|||||||
4558
interface/package-lock.json
generated
4558
interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@ export interface Settings {
|
|||||||
syslog_mark_interval: number;
|
syslog_mark_interval: number;
|
||||||
syslog_host: string;
|
syslog_host: string;
|
||||||
syslog_port: number;
|
syslog_port: number;
|
||||||
master_thermostat: number;
|
|
||||||
shower_timer: boolean;
|
shower_timer: boolean;
|
||||||
shower_alert: boolean;
|
shower_alert: boolean;
|
||||||
rx_gpio: number;
|
rx_gpio: number;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ class DummySettings {
|
|||||||
uint32_t syslog_mark_interval = 0;
|
uint32_t syslog_mark_interval = 0;
|
||||||
String syslog_host = "192.168.1.4";
|
String syslog_host = "192.168.1.4";
|
||||||
uint16_t syslog_port = 514;
|
uint16_t syslog_port = 514;
|
||||||
uint8_t master_thermostat = 0;
|
|
||||||
bool shower_timer = true;
|
bool shower_timer = true;
|
||||||
bool shower_alert = false;
|
bool shower_alert = false;
|
||||||
bool hide_led = false;
|
bool hide_led = false;
|
||||||
|
|||||||
@@ -314,7 +314,6 @@ settings = {
|
|||||||
syslog_mark_interval: 0,
|
syslog_mark_interval: 0,
|
||||||
syslog_host: '192.168.1.4',
|
syslog_host: '192.168.1.4',
|
||||||
syslog_port: 514,
|
syslog_port: 514,
|
||||||
master_thermostat: 0,
|
|
||||||
shower_timer: true,
|
shower_timer: true,
|
||||||
shower_alert: false,
|
shower_alert: false,
|
||||||
rx_gpio: 23,
|
rx_gpio: 23,
|
||||||
|
|||||||
@@ -228,10 +228,6 @@ void EMSESPShell::add_console_commands() {
|
|||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
||||||
shell.printfln(F_(bus_id_fmt), settings.ems_bus_id);
|
shell.printfln(F_(bus_id_fmt), settings.ems_bus_id);
|
||||||
char buffer[4];
|
|
||||||
shell.printfln(F_(master_thermostat_fmt),
|
|
||||||
settings.master_thermostat == 0 ? read_flash_string(F_(auto)).c_str()
|
|
||||||
: Helpers::hextoa(buffer, settings.master_thermostat));
|
|
||||||
shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str());
|
shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -262,23 +258,6 @@ void EMSESPShell::add_console_commands() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
commands->add_command(ShellContext::MAIN,
|
|
||||||
CommandFlags::ADMIN,
|
|
||||||
flash_string_vector{F_(set), F_(master), F_(thermostat)},
|
|
||||||
flash_string_vector{F_(deviceid_mandatory)},
|
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
|
||||||
uint8_t value = Helpers::hextoint(arguments.front().c_str());
|
|
||||||
EMSESP::webSettingsService.update(
|
|
||||||
[&](WebSettings & settings) {
|
|
||||||
settings.master_thermostat = value;
|
|
||||||
EMSESP::actual_master_thermostat(value); // set the internal value too
|
|
||||||
char buffer[5];
|
|
||||||
shell.printfln(F_(master_thermostat_fmt), !value ? read_flash_string(F_(auto)).c_str() : Helpers::hextoa(buffer, value));
|
|
||||||
return StateUpdateResult::CHANGED;
|
|
||||||
},
|
|
||||||
"local");
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
commands->add_command(ShellContext::MAIN,
|
commands->add_command(ShellContext::MAIN,
|
||||||
CommandFlags::USER,
|
CommandFlags::USER,
|
||||||
|
|||||||
@@ -26,30 +26,13 @@ uuid::log::Logger Thermostat::logger_{F_(thermostat), uuid::log::Facility::CONSO
|
|||||||
|
|
||||||
Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||||
uint8_t actual_master_thermostat = EMSESP::actual_master_thermostat(); // what we're actually using
|
|
||||||
uint8_t master_thermostat = EMSESP_DEFAULT_MASTER_THERMOSTAT;
|
|
||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
|
||||||
master_thermostat = settings.master_thermostat; // what the user has defined
|
|
||||||
});
|
|
||||||
|
|
||||||
uint8_t model = this->model();
|
uint8_t model = this->model();
|
||||||
|
|
||||||
// if we're on auto mode, register this thermostat if it has a device id of 0x10, 0x17 or 0x18
|
|
||||||
// or if its the master thermostat we defined
|
|
||||||
// see https://github.com/emsesp/EMS-ESP/issues/362#issuecomment-629628161
|
|
||||||
if ((master_thermostat == device_id)
|
|
||||||
|| ((master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) && (device_id < 0x19)
|
|
||||||
&& ((actual_master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) || (device_id < actual_master_thermostat)))) {
|
|
||||||
EMSESP::actual_master_thermostat(device_id);
|
|
||||||
actual_master_thermostat = device_id;
|
|
||||||
// reserve_telegram_functions(20); // reserve some space for the telegram registries, to avoid memory fragmentation
|
|
||||||
|
|
||||||
// common telegram handlers
|
// common telegram handlers
|
||||||
register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, MAKE_PF_CB(process_RCOutdoorTemp));
|
register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, MAKE_PF_CB(process_RCOutdoorTemp));
|
||||||
register_telegram_type(EMS_TYPE_RCTime, F("RCTime"), false, MAKE_PF_CB(process_RCTime));
|
register_telegram_type(EMS_TYPE_RCTime, F("RCTime"), false, MAKE_PF_CB(process_RCTime));
|
||||||
register_telegram_type(0xA2, F("RCError"), false, MAKE_PF_CB(process_RCError));
|
register_telegram_type(0xA2, F("RCError"), false, MAKE_PF_CB(process_RCError));
|
||||||
register_telegram_type(0x12, F("RCErrorMessage"), false, MAKE_PF_CB(process_RCErrorMessage));
|
register_telegram_type(0x12, F("RCErrorMessage"), false, MAKE_PF_CB(process_RCErrorMessage));
|
||||||
}
|
|
||||||
// RC10
|
// RC10
|
||||||
if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) {
|
if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) {
|
||||||
monitor_typeids = {0xB1};
|
monitor_typeids = {0xB1};
|
||||||
@@ -82,26 +65,22 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
set_typeids = {0xA8};
|
set_typeids = {0xA8};
|
||||||
curve_typeids = {0x90};
|
curve_typeids = {0x90};
|
||||||
timer_typeids = {0x8F};
|
timer_typeids = {0x8F};
|
||||||
if (actual_master_thermostat == device_id) {
|
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
register_telegram_type(monitor_typeids[i], F("RC20Monitor"), false, MAKE_PF_CB(process_RC20Monitor));
|
register_telegram_type(monitor_typeids[i], F("RC20Monitor"), false, MAKE_PF_CB(process_RC20Monitor));
|
||||||
register_telegram_type(set_typeids[i], F("RC20Set"), false, MAKE_PF_CB(process_RC20Set));
|
register_telegram_type(set_typeids[i], F("RC20Set"), false, MAKE_PF_CB(process_RC20Set));
|
||||||
register_telegram_type(curve_typeids[i], F("RC20Temp"), false, MAKE_PF_CB(process_RC20Temp));
|
register_telegram_type(curve_typeids[i], F("RC20Temp"), false, MAKE_PF_CB(process_RC20Temp));
|
||||||
register_telegram_type(timer_typeids[i], F("RC20Timer"), false, MAKE_PF_CB(process_RC20Timer));
|
register_telegram_type(timer_typeids[i], F("RC20Timer"), false, MAKE_PF_CB(process_RC20Timer));
|
||||||
}
|
}
|
||||||
}
|
// remote thermostat uses only 0xAF
|
||||||
// remote thermostat uses only 0xAF, register it also for master (in case of early detect)
|
|
||||||
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
||||||
// RC20 newer
|
// RC20 newer
|
||||||
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) {
|
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) || (model == EMSdevice::EMS_DEVICE_FLAG_RC25)) {
|
||||||
monitor_typeids = {0xAE};
|
monitor_typeids = {0xAE};
|
||||||
set_typeids = {0xAD};
|
set_typeids = {0xAD};
|
||||||
if (actual_master_thermostat == device_id) {
|
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
register_telegram_type(monitor_typeids[i], F("RC20Monitor"), false, MAKE_PF_CB(process_RC20Monitor_2));
|
register_telegram_type(monitor_typeids[i], F("RC20Monitor"), false, MAKE_PF_CB(process_RC20Monitor_2));
|
||||||
register_telegram_type(set_typeids[i], F("RC20Set"), false, MAKE_PF_CB(process_RC20Set_2));
|
register_telegram_type(set_typeids[i], F("RC20Set"), false, MAKE_PF_CB(process_RC20Set_2));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
||||||
// RC30
|
// RC30
|
||||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
|
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC30) {
|
||||||
@@ -150,7 +129,6 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
|
|
||||||
// JUNKERS/HT3
|
// JUNKERS/HT3
|
||||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
} else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
if (actual_master_thermostat == device_id) {
|
|
||||||
monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172};
|
monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172};
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
register_telegram_type(monitor_typeids[i], F("JunkersMonitor"), false, MAKE_PF_CB(process_JunkersMonitor));
|
register_telegram_type(monitor_typeids[i], F("JunkersMonitor"), false, MAKE_PF_CB(process_JunkersMonitor));
|
||||||
@@ -168,23 +146,13 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
register_telegram_type(set_typeids[i], F("JunkersSet"), false, MAKE_PF_CB(process_JunkersSet));
|
register_telegram_type(set_typeids[i], F("JunkersSet"), false, MAKE_PF_CB(process_JunkersSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
register_telegram_type(0x123, F("JunkersRemote"), false, MAKE_PF_CB(process_JunkersRemoteMonitor));
|
register_telegram_type(0x123, F("JunkersRemote"), false, MAKE_PF_CB(process_JunkersRemoteMonitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actual_master_thermostat != device_id) {
|
|
||||||
return; // don't fetch data if more than 1 thermostat
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// this next section is only for the master thermostat....
|
|
||||||
//
|
|
||||||
LOG_DEBUG(F("Setting this thermostat (device ID 0x%02X) to be the master"), device_id);
|
|
||||||
|
|
||||||
// register device values for common values (not heating circuit)
|
// register device values for common values (not heating circuit)
|
||||||
register_device_values();
|
register_device_values();
|
||||||
|
|
||||||
// only for for the master-thermostat, go a query all the heating circuits. This is only done once.
|
// query all the heating circuits. This is only done once.
|
||||||
// The automatic fetch will from now on only update the active heating circuits
|
// The automatic fetch will from now on only update the active heating circuits
|
||||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||||
EMSESP::send_read_request(monitor_typeids[i], device_id);
|
EMSESP::send_read_request(monitor_typeids[i], device_id);
|
||||||
@@ -341,11 +309,6 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
|
|||||||
// register the device values
|
// register the device values
|
||||||
register_device_values_hc(new_hc);
|
register_device_values_hc(new_hc);
|
||||||
|
|
||||||
// don't fetch telegrams if not the master
|
|
||||||
if (device_id() != EMSESP::actual_master_thermostat()) {
|
|
||||||
return new_hc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the flag saying we want its data during the next auto fetch
|
// set the flag saying we want its data during the next auto fetch
|
||||||
// monitor is broadcasted, but not frequently in some thermostats (IVT, #356)
|
// monitor is broadcasted, but not frequently in some thermostats (IVT, #356)
|
||||||
toggle_fetch(monitor_typeids[hc_num - 1], toggle_);
|
toggle_fetch(monitor_typeids[hc_num - 1], toggle_);
|
||||||
@@ -1372,7 +1335,6 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Roomctrl::set_remotetemp(hc->hc(), hc->remotetemp);
|
Roomctrl::set_remotetemp(hc->hc(), hc->remotetemp);
|
||||||
has_update(hc->remotetemp);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3207,16 +3169,12 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
|
|||||||
seltemp_divider = FL_(div2);
|
seltemp_divider = FL_(div2);
|
||||||
roomtemp_divider = FL_(div10);
|
roomtemp_divider = FL_(div10);
|
||||||
}
|
}
|
||||||
if (has_flags(EMS_DEVICE_FLAG_NO_WRITE) || device_id() != EMSESP::actual_master_thermostat()) {
|
if (has_flags(EMS_DEVICE_FLAG_NO_WRITE)) {
|
||||||
register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES);
|
||||||
} else {
|
} else {
|
||||||
register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 5, 29);
|
register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 5, 29);
|
||||||
}
|
}
|
||||||
register_device_value(tag, &hc->roomTemp, DeviceValueType::SHORT, roomtemp_divider, FL_(roomTemp), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->roomTemp, DeviceValueType::SHORT, roomtemp_divider, FL_(roomTemp), DeviceValueUOM::DEGREES);
|
||||||
|
|
||||||
if (device_id() != EMSESP::actual_master_thermostat()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
register_device_value(tag, &hc->climate, DeviceValueType::ENUM, FL_(enum_climate), FL_(climate), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->climate, DeviceValueType::ENUM, FL_(enum_climate), FL_(climate), DeviceValueUOM::NONE);
|
||||||
|
|
||||||
switch (model) {
|
switch (model) {
|
||||||
|
|||||||
@@ -289,6 +289,15 @@ bool EMSdevice::is_fetch(uint16_t telegram_id) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EMSdevice::has_tag(const uint8_t tag) {
|
||||||
|
for (const auto & dv : devicevalues_) {
|
||||||
|
if (dv.tag == tag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// list of registered device entries
|
// list of registered device entries
|
||||||
// called from the command 'entities'
|
// called from the command 'entities'
|
||||||
void EMSdevice::list_device_entries(JsonObject & output) {
|
void EMSdevice::list_device_entries(JsonObject & output) {
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ class EMSdevice {
|
|||||||
static const std::string tag_to_string(uint8_t tag);
|
static const std::string tag_to_string(uint8_t tag);
|
||||||
static const std::string tag_to_mqtt(uint8_t tag);
|
static const std::string tag_to_mqtt(uint8_t tag);
|
||||||
|
|
||||||
|
bool has_tag(const uint8_t tag);
|
||||||
|
|
||||||
inline uint8_t device_id() const {
|
inline uint8_t device_id() const {
|
||||||
return device_id_;
|
return device_id_;
|
||||||
}
|
}
|
||||||
|
|||||||
187
src/emsesp.cpp
187
src/emsesp.cpp
@@ -60,7 +60,6 @@ AnalogSensor EMSESP::analogsensor_; // Analog sensors
|
|||||||
Shower EMSESP::shower_; // Shower logic
|
Shower EMSESP::shower_; // Shower logic
|
||||||
|
|
||||||
// static/common variables
|
// static/common variables
|
||||||
uint8_t EMSESP::actual_master_thermostat_ = EMSESP_DEFAULT_MASTER_THERMOSTAT; // which thermostat leads when multiple found
|
|
||||||
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE; // for when log is TRACE. 0 means no trace set
|
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE; // for when log is TRACE. 0 means no trace set
|
||||||
uint8_t EMSESP::watch_ = 0; // trace off
|
uint8_t EMSESP::watch_ = 0; // trace off
|
||||||
uint16_t EMSESP::read_id_ = WATCH_ID_NONE;
|
uint16_t EMSESP::read_id_ = WATCH_ID_NONE;
|
||||||
@@ -163,63 +162,6 @@ void EMSESP::scan_devices() {
|
|||||||
EMSESP::send_read_request(EMSdevice::EMS_TYPE_UBADevices, EMSdevice::EMS_DEVICE_ID_BOILER);
|
EMSESP::send_read_request(EMSdevice::EMS_TYPE_UBADevices, EMSdevice::EMS_DEVICE_ID_BOILER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* if thermostat master is 0x18 it handles only ww and hc1, hc2..hc8 handled by devices 0x19..0x1F
|
|
||||||
* we send to right device and match all reads to 0x18
|
|
||||||
*/
|
|
||||||
uint8_t EMSESP::check_master_device(const uint8_t device_id, const uint16_t type_id, const bool read) {
|
|
||||||
if (device_id != 0x10 && (device_id < 0x18 || device_id > 0x1F)) {
|
|
||||||
return device_id;
|
|
||||||
}
|
|
||||||
if (actual_master_thermostat_ == 0x18) {
|
|
||||||
uint16_t mon_ids[] = {0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC};
|
|
||||||
uint16_t set_ids[] = {0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0};
|
|
||||||
uint16_t summer_ids[] = {0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B3, 0x02B4, 0x02B5, 0x02B6};
|
|
||||||
uint16_t curve_ids[] = {0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2};
|
|
||||||
uint16_t summer2_ids[] = {0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477, 0x0478};
|
|
||||||
uint16_t master_ids[] = {0x02F5, 0x031B, 0x031D, 0x031E, 0x023A, 0x0267, 0x0240};
|
|
||||||
// look for heating circuits
|
|
||||||
for (uint8_t i = 0; i < sizeof(mon_ids) / 2; i++) {
|
|
||||||
if (type_id == mon_ids[i] || type_id == set_ids[i] || type_id == summer_ids[i] || type_id == curve_ids[i] || type_id == summer2_ids[i]) {
|
|
||||||
if (read) {
|
|
||||||
// receiving telegrams and map all to master thermostat at 0x18 (src manipulated)
|
|
||||||
return 0x18;
|
|
||||||
} else {
|
|
||||||
// sending telegrams to the individual thermostats (dst manipulated)
|
|
||||||
return 0x18 + i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// look for ids that are only handled by master
|
|
||||||
for (uint8_t i = 0; i < sizeof(master_ids) / 2; i++) {
|
|
||||||
if (type_id == master_ids[i]) {
|
|
||||||
return 0x18;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (actual_master_thermostat_ == 0x10) {
|
|
||||||
// Junkers FW200 supports hc1/hc2, hc3/hc4 handled by devices 0x1A...
|
|
||||||
// see https://github.com/emsesp/EMS-ESP32/issues/336
|
|
||||||
uint16_t mon_ids[] = {0x0171, 0x0172};
|
|
||||||
uint16_t set_ids[] = {0x0167, 0x0168};
|
|
||||||
for (uint8_t i = 0; i < sizeof(mon_ids) / 2; i++) {
|
|
||||||
if (type_id == mon_ids[i] || type_id == set_ids[i]) {
|
|
||||||
// reads to master thermostat, writes to remote thermostats
|
|
||||||
return (read ? actual_master_thermostat_ : 0x1A + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return device_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EMSESP::actual_master_thermostat(const uint8_t device_id) {
|
|
||||||
actual_master_thermostat_ = device_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t EMSESP::actual_master_thermostat() {
|
|
||||||
return actual_master_thermostat_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// to watch both type IDs and deviceIDs
|
// to watch both type IDs and deviceIDs
|
||||||
void EMSESP::watch_id(uint16_t watch_id) {
|
void EMSESP::watch_id(uint16_t watch_id) {
|
||||||
watch_id_ = watch_id;
|
watch_id_ = watch_id;
|
||||||
@@ -573,80 +515,65 @@ void EMSESP::publish_device_values(uint8_t device_type) {
|
|||||||
emsdevice->mqtt_ha_entity_config_remove();
|
emsdevice->mqtt_ha_entity_config_remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// collect all data tagged with WW
|
||||||
// if its a boiler, generate json for each group and publish it directly. not nested
|
|
||||||
if (device_type == DeviceType::BOILER) {
|
|
||||||
json = doc.to<JsonObject>();
|
|
||||||
if (emsdevice->generate_values(json, DeviceValueTAG::TAG_BOILER_DATA, false, EMSdevice::OUTPUT_TARGET::MQTT)) {
|
|
||||||
Mqtt::publish(Mqtt::tag_to_topic(device_type, DeviceValueTAG::TAG_BOILER_DATA), json);
|
|
||||||
}
|
|
||||||
json = doc.to<JsonObject>();
|
|
||||||
if (emsdevice->generate_values(json, DeviceValueTAG::TAG_DEVICE_DATA_WW, false, EMSdevice::OUTPUT_TARGET::MQTT)) {
|
|
||||||
Mqtt::publish(Mqtt::tag_to_topic(device_type, DeviceValueTAG::TAG_DEVICE_DATA_WW), json);
|
|
||||||
}
|
|
||||||
need_publish = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thermostat
|
|
||||||
else if (device_type == DeviceType::THERMOSTAT) {
|
|
||||||
// only publish the single master thermostat
|
|
||||||
if (emsdevice->device_id() == EMSESP::actual_master_thermostat()) {
|
|
||||||
if (nested) {
|
|
||||||
json = doc.to<JsonObject>();
|
|
||||||
need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::MQTT); // nested
|
|
||||||
} else {
|
|
||||||
json = doc.to<JsonObject>();
|
|
||||||
need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_THERMOSTAT_DATA, false, EMSdevice::OUTPUT_TARGET::MQTT); // not nested
|
|
||||||
need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_DEVICE_DATA_WW, false, EMSdevice::OUTPUT_TARGET::MQTT);
|
need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_DEVICE_DATA_WW, false, EMSdevice::OUTPUT_TARGET::MQTT);
|
||||||
if (need_publish) {
|
|
||||||
Mqtt::publish(Mqtt::tag_to_topic(device_type, DeviceValueTAG::TAG_NONE), json);
|
|
||||||
}
|
}
|
||||||
for (uint8_t hc_tag = DeviceValueTAG::TAG_HC1; hc_tag <= DeviceValueTAG::TAG_HC8; hc_tag++) {
|
}
|
||||||
|
// for boiler WW is an extra topic, publish now
|
||||||
|
if (need_publish && device_type == DeviceType::BOILER) {
|
||||||
|
Mqtt::publish(Mqtt::tag_to_topic(device_type, DeviceValueTAG::TAG_DEVICE_DATA_WW), json);
|
||||||
json = doc.to<JsonObject>();
|
json = doc.to<JsonObject>();
|
||||||
if (emsdevice->generate_values(json, hc_tag, false, EMSdevice::OUTPUT_TARGET::MQTT)) { // not nested
|
need_publish = false;
|
||||||
|
}
|
||||||
|
uint8_t tag = DeviceValueTAG::TAG_NONE;
|
||||||
|
if (device_type == DeviceType::BOILER) {
|
||||||
|
tag = DeviceValueTAG::TAG_BOILER_DATA;
|
||||||
|
} else if (device_type == DeviceType::THERMOSTAT || device_type == DeviceType::MIXER) {
|
||||||
|
tag = DeviceValueTAG::TAG_THERMOSTAT_DATA;
|
||||||
|
}
|
||||||
|
// collect all data tagged for device, add to ww-data from before
|
||||||
|
for (const auto & emsdevice : emsdevices) {
|
||||||
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
|
need_publish |= emsdevice->generate_values(json, tag, false, EMSdevice::OUTPUT_TARGET::MQTT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nested && need_publish) {
|
||||||
|
Mqtt::publish(Mqtt::tag_to_topic(device_type, tag), json);
|
||||||
|
json = doc.to<JsonObject>();
|
||||||
|
need_publish = false;
|
||||||
|
}
|
||||||
|
for (uint8_t hc_tag = DeviceValueTAG::TAG_HC1; hc_tag <= DeviceValueTAG::TAG_HS16; hc_tag++) {
|
||||||
|
JsonObject json_hc = json;
|
||||||
|
bool nest_created = false;
|
||||||
|
for (const auto & emsdevice : emsdevices) {
|
||||||
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
|
if (nested && !nest_created && emsdevice->has_tag(hc_tag)) {
|
||||||
|
json_hc = doc.createNestedObject(EMSdevice::tag_to_string(hc_tag));
|
||||||
|
nest_created = true;
|
||||||
|
}
|
||||||
|
need_publish |= emsdevice->generate_values(json_hc, hc_tag, false, EMSdevice::OUTPUT_TARGET::MQTT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nested && need_publish) {
|
||||||
Mqtt::publish(Mqtt::tag_to_topic(device_type, hc_tag), json);
|
Mqtt::publish(Mqtt::tag_to_topic(device_type, hc_tag), json);
|
||||||
}
|
json = doc.to<JsonObject>();
|
||||||
}
|
|
||||||
need_publish = false;
|
need_publish = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Mixer
|
|
||||||
else if (device_type == DeviceType::MIXER) {
|
|
||||||
if (nested) {
|
|
||||||
need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::MQTT); // nested
|
|
||||||
} else {
|
|
||||||
for (uint8_t hc_tag = DeviceValueTAG::TAG_HC1; hc_tag <= DeviceValueTAG::TAG_WWC4; hc_tag++) {
|
|
||||||
json = doc.to<JsonObject>();
|
|
||||||
if (emsdevice->generate_values(json, hc_tag, false, EMSdevice::OUTPUT_TARGET::MQTT)) { // not nested
|
|
||||||
Mqtt::publish(Mqtt::tag_to_topic(device_type, hc_tag), json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
need_publish = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// for all other devices add the values to the json
|
|
||||||
json = doc.to<JsonObject>();
|
|
||||||
need_publish |= emsdevice->generate_values(json, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::MQTT); // nested
|
|
||||||
}
|
|
||||||
|
|
||||||
// we want to create the /config topic after the data payload to prevent HA from throwing up a warning
|
|
||||||
if (Mqtt::ha_enabled()) {
|
|
||||||
emsdevice->mqtt_ha_entity_config_create();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// publish it under a single topic, only if we have data to publish
|
|
||||||
if (need_publish) {
|
if (need_publish) {
|
||||||
if (doc.overflowed()) {
|
if (doc.overflowed()) {
|
||||||
LOG_WARNING(F("MQTT buffer overflow, please use individual topics"));
|
LOG_WARNING(F("MQTT buffer overflow, please use individual topics"));
|
||||||
}
|
}
|
||||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
Mqtt::publish(Mqtt::tag_to_topic(device_type, tag), json);
|
||||||
snprintf(topic, sizeof(topic), "%s_data", EMSdevice::device_type_2_device_name(device_type).c_str());
|
}
|
||||||
Mqtt::publish(topic, json);
|
|
||||||
|
// we want to create the /config topic after the data payload to prevent HA from throwing up a warning
|
||||||
|
if (Mqtt::ha_enabled()) {
|
||||||
|
for (const auto & emsdevice : emsdevices) {
|
||||||
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
|
emsdevice->mqtt_ha_entity_config_create();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,10 +934,6 @@ void EMSESP::show_devices(uuid::console::Shell & shell) {
|
|||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if ((emsdevice) && (emsdevice->device_type() == device_class.first)) {
|
if ((emsdevice) && (emsdevice->device_type() == device_class.first)) {
|
||||||
shell.printf(F("%s: %s"), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str());
|
shell.printf(F("%s: %s"), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str());
|
||||||
if ((num_thermostats > 1) && (emsdevice->device_type() == EMSdevice::DeviceType::THERMOSTAT)
|
|
||||||
&& (emsdevice->device_id() == actual_master_thermostat())) {
|
|
||||||
shell.printf(F(" **master device**"));
|
|
||||||
}
|
|
||||||
shell.println();
|
shell.println();
|
||||||
emsdevice->show_telegram_handlers(shell);
|
emsdevice->show_telegram_handlers(shell);
|
||||||
|
|
||||||
@@ -1215,12 +1138,22 @@ bool EMSESP::command_info(uint8_t device_type, JsonObject & output, const int8_t
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id > 0 || output_target == EMSdevice::OUTPUT_TARGET::API_VERBOSE) {
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && (emsdevice->device_type() == device_type)
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
&& ((device_type != DeviceType::THERMOSTAT) || (emsdevice->device_id() == EMSESP::actual_master_thermostat()))) {
|
|
||||||
has_value |= emsdevice->generate_values(output, tag, (id < 1), output_target); // use nested for id -1 and 0
|
has_value |= emsdevice->generate_values(output, tag, (id < 1), output_target); // use nested for id -1 and 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return has_value;
|
||||||
|
}
|
||||||
|
// for nested output add for each tag
|
||||||
|
for (tag = DeviceValueTAG::TAG_BOILER_DATA; tag <= DeviceValueTAG::TAG_HS16; tag++) {
|
||||||
|
for (const auto & emsdevice : emsdevices) {
|
||||||
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
|
has_value |= emsdevice->generate_values(output, tag, true, output_target); // use nested for id -1 and 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return has_value;
|
return has_value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,10 +133,6 @@ class EMSESP {
|
|||||||
static uint8_t count_devices();
|
static uint8_t count_devices();
|
||||||
static uint8_t device_index(const uint8_t device_type, const uint8_t unique_id);
|
static uint8_t device_index(const uint8_t device_type, const uint8_t unique_id);
|
||||||
|
|
||||||
static uint8_t actual_master_thermostat();
|
|
||||||
static void actual_master_thermostat(const uint8_t device_id);
|
|
||||||
static uint8_t check_master_device(const uint8_t device_id, const uint16_t type_id, const bool read);
|
|
||||||
|
|
||||||
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_device_values(uuid::console::Shell & shell);
|
||||||
@@ -260,7 +256,6 @@ class EMSESP {
|
|||||||
};
|
};
|
||||||
static std::vector<Device_record> device_library_;
|
static std::vector<Device_record> device_library_;
|
||||||
|
|
||||||
static uint8_t actual_master_thermostat_;
|
|
||||||
static uint16_t watch_id_;
|
static uint16_t watch_id_;
|
||||||
static uint8_t watch_;
|
static uint8_t watch_;
|
||||||
static uint16_t read_id_;
|
static uint16_t read_id_;
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ MAKE_PSTR_WORD(reconnect)
|
|||||||
MAKE_PSTR_WORD(ssid)
|
MAKE_PSTR_WORD(ssid)
|
||||||
MAKE_PSTR_WORD(heartbeat)
|
MAKE_PSTR_WORD(heartbeat)
|
||||||
MAKE_PSTR_WORD(users)
|
MAKE_PSTR_WORD(users)
|
||||||
MAKE_PSTR_WORD(master)
|
|
||||||
MAKE_PSTR_WORD(pin)
|
|
||||||
MAKE_PSTR_WORD(publish)
|
MAKE_PSTR_WORD(publish)
|
||||||
MAKE_PSTR_WORD(timeout)
|
MAKE_PSTR_WORD(timeout)
|
||||||
MAKE_PSTR_WORD(board_profile)
|
MAKE_PSTR_WORD(board_profile)
|
||||||
@@ -105,7 +103,6 @@ MAKE_PSTR_WORD(unknown)
|
|||||||
MAKE_PSTR_WORD(dallassensor)
|
MAKE_PSTR_WORD(dallassensor)
|
||||||
|
|
||||||
// format strings
|
// format strings
|
||||||
MAKE_PSTR(master_thermostat_fmt, "Master Thermostat Device ID: %s")
|
|
||||||
MAKE_PSTR(host_fmt, "Host: %s")
|
MAKE_PSTR(host_fmt, "Host: %s")
|
||||||
MAKE_PSTR(port_fmt, "Port: %d")
|
MAKE_PSTR(port_fmt, "Port: %d")
|
||||||
MAKE_PSTR(hostname_fmt, "Hostname: %s")
|
MAKE_PSTR(hostname_fmt, "Hostname: %s")
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ MAKE_PSTR_WORD(reconnect)
|
|||||||
MAKE_PSTR_WORD(ssid)
|
MAKE_PSTR_WORD(ssid)
|
||||||
MAKE_PSTR_WORD(heartbeat)
|
MAKE_PSTR_WORD(heartbeat)
|
||||||
MAKE_PSTR_WORD(users)
|
MAKE_PSTR_WORD(users)
|
||||||
MAKE_PSTR_WORD(master)
|
|
||||||
MAKE_PSTR_WORD(pin)
|
|
||||||
MAKE_PSTR_WORD(publish)
|
MAKE_PSTR_WORD(publish)
|
||||||
MAKE_PSTR_WORD(timeout)
|
MAKE_PSTR_WORD(timeout)
|
||||||
MAKE_PSTR_WORD(board_profile)
|
MAKE_PSTR_WORD(board_profile)
|
||||||
@@ -105,7 +103,6 @@ MAKE_PSTR_WORD(unknown)
|
|||||||
MAKE_PSTR_WORD(dallassensor)
|
MAKE_PSTR_WORD(dallassensor)
|
||||||
|
|
||||||
// format strings
|
// format strings
|
||||||
MAKE_PSTR(master_thermostat_fmt, "Master Thermostat device ID: %s")
|
|
||||||
MAKE_PSTR(host_fmt, "Host: %s")
|
MAKE_PSTR(host_fmt, "Host: %s")
|
||||||
MAKE_PSTR(port_fmt, "Port: %d")
|
MAKE_PSTR(port_fmt, "Port: %d")
|
||||||
MAKE_PSTR(hostname_fmt, "Hostname: %s")
|
MAKE_PSTR(hostname_fmt, "Hostname: %s")
|
||||||
|
|||||||
@@ -981,8 +981,6 @@ bool System::command_settings(const char * value, const int8_t id, JsonObject &
|
|||||||
node["syslog_host"] = settings.syslog_host;
|
node["syslog_host"] = settings.syslog_host;
|
||||||
node["syslog_port"] = settings.syslog_port;
|
node["syslog_port"] = settings.syslog_port;
|
||||||
|
|
||||||
node["master_thermostat"] = settings.master_thermostat;
|
|
||||||
|
|
||||||
node["shower_timer"] = settings.shower_timer;
|
node["shower_timer"] = settings.shower_timer;
|
||||||
node["shower_alert"] = settings.shower_alert;
|
node["shower_alert"] = settings.shower_alert;
|
||||||
|
|
||||||
|
|||||||
@@ -221,9 +221,6 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we receive a hc2.. telegram from 0x19.. match it to master_thermostat if master is 0x18
|
|
||||||
src = EMSESP::check_master_device(src, type_id, true);
|
|
||||||
|
|
||||||
// create the telegram
|
// create the telegram
|
||||||
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length);
|
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length);
|
||||||
|
|
||||||
@@ -312,9 +309,6 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
|||||||
// fix the READ or WRITE depending on the operation
|
// fix the READ or WRITE depending on the operation
|
||||||
uint8_t dest = telegram->dest;
|
uint8_t dest = telegram->dest;
|
||||||
|
|
||||||
// check if we have to manipulate the id for thermostats > 0x18
|
|
||||||
dest = EMSESP::check_master_device(dest, telegram->type_id, false);
|
|
||||||
|
|
||||||
if (telegram->operation == Telegram::Operation::TX_READ) {
|
if (telegram->operation == Telegram::Operation::TX_READ) {
|
||||||
dest |= 0x80; // read has 8th bit set for the destination
|
dest |= 0x80; // read has 8th bit set for the destination
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) {
|
|||||||
root["syslog_mark_interval"] = settings.syslog_mark_interval;
|
root["syslog_mark_interval"] = settings.syslog_mark_interval;
|
||||||
root["syslog_host"] = settings.syslog_host;
|
root["syslog_host"] = settings.syslog_host;
|
||||||
root["syslog_port"] = settings.syslog_port;
|
root["syslog_port"] = settings.syslog_port;
|
||||||
root["master_thermostat"] = settings.master_thermostat;
|
|
||||||
root["shower_timer"] = settings.shower_timer;
|
root["shower_timer"] = settings.shower_timer;
|
||||||
root["shower_alert"] = settings.shower_alert;
|
root["shower_alert"] = settings.shower_alert;
|
||||||
root["rx_gpio"] = settings.rx_gpio;
|
root["rx_gpio"] = settings.rx_gpio;
|
||||||
@@ -195,10 +194,6 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
|||||||
settings.low_clock = root["low_clock"] | false;
|
settings.low_clock = root["low_clock"] | false;
|
||||||
check_flag(prev, settings.low_clock, ChangeFlags::RESTART);
|
check_flag(prev, settings.low_clock, ChangeFlags::RESTART);
|
||||||
|
|
||||||
prev = settings.master_thermostat;
|
|
||||||
settings.master_thermostat = root["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT;
|
|
||||||
check_flag(prev, settings.master_thermostat, ChangeFlags::RESTART);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// without checks...
|
// without checks...
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ class WebSettings {
|
|||||||
public:
|
public:
|
||||||
uint8_t tx_mode;
|
uint8_t tx_mode;
|
||||||
uint8_t ems_bus_id;
|
uint8_t ems_bus_id;
|
||||||
uint8_t master_thermostat;
|
|
||||||
bool shower_timer;
|
bool shower_timer;
|
||||||
bool shower_alert;
|
bool shower_alert;
|
||||||
bool syslog_enabled;
|
bool syslog_enabled;
|
||||||
|
|||||||
Reference in New Issue
Block a user