diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts
index 4c20fd57f..ed58d0aa0 100644
--- a/interface/src/app/main/types.ts
+++ b/interface/src/app/main/types.ts
@@ -43,6 +43,7 @@ export interface Settings {
modbus_max_clients: number;
modbus_timeout: number;
developer_mode: boolean;
+ outdoorsensor: boolean;
}
export enum busConnectionStatus {
diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx
index 0789fee40..f058aee6d 100644
--- a/interface/src/app/settings/ApplicationSettings.tsx
+++ b/interface/src/app/settings/ApplicationSettings.tsx
@@ -697,6 +697,16 @@ const ApplicationSettings = () => {
}
label={LL.DEVELOPER_MODE()}
/>
+
+ }
+ label={LL.OUTDOORSENSOR()}
+ />
telegram) {
(0x0880), data: 01 04
(0x0889), data: 00 80 80 01
*/
-
+bool Connect::set_outdoorTemp(const char * value, const int8_t id) {
+ float v;
+ if (Roomctrl::has_outdoorsensor() && Helpers::value2temperature(value, v)) {
+ Roomctrl::set_outdoortemp(v * 10);
+ return true;
+ }
+ return false;
+}
} // namespace emsesp
diff --git a/src/devices/connect.h b/src/devices/connect.h
index 5db2e11d3..46cec088c 100644
--- a/src/devices/connect.h
+++ b/src/devices/connect.h
@@ -29,6 +29,7 @@ class Connect : public EMSdevice {
private:
void process_OutdoorTemp(std::shared_ptr telegram);
+ bool set_outdoorTemp(const char * value, const int8_t id);
int16_t outdoorTemp_;
};
diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp
index d8fe9209e..9c9aed04a 100644
--- a/src/emsdevice.cpp
+++ b/src/emsdevice.cpp
@@ -257,6 +257,9 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
if (!strcmp(lowtopic, F_(pool))) {
return DeviceType::POOL;
}
+ if (!strcmp(lowtopic, F_(connect))) {
+ return DeviceType::CONNECT;
+ }
// non EMS
if (!strcmp(lowtopic, F_(custom))) {
diff --git a/src/emsesp.cpp b/src/emsesp.cpp
index 4c7bc5708..1bef947bc 100644
--- a/src/emsesp.cpp
+++ b/src/emsesp.cpp
@@ -685,7 +685,7 @@ void EMSESP::publish_thermostat_timer() {
const char * name[] = {FL_(switchprog)[0], FL_(circswitchprog)[0]};
for (uint8_t i = 0; i < sizeof(name) / sizeof(char *); i++) {
if (emsdevice->get_value_info(json, name[i], tag)) {
- if (json.containsKey("value")) {
+ if (json["value"].is()) {
if ((Mqtt::is_nested())) {
if (circuit.isNull()) {
circuit = output[EMSdevice::tag_to_mqtt(tag)].to();
@@ -715,9 +715,9 @@ void EMSESP::publish_other_values() {
publish_device_values(EMSdevice::DeviceType::EXTENSION);
publish_device_values(EMSdevice::DeviceType::ALERT);
publish_device_values(EMSdevice::DeviceType::POOL);
+ publish_device_values(EMSdevice::DeviceType::CONNECT);
// other EMS devices without values yet
// publish_device_values(EMSdevice::DeviceType::GATEWAY);
- // publish_device_values(EMSdevice::DeviceType::CONNECT);
// publish_device_values(EMSdevice::DeviceType::GENERIC);
webSchedulerService.publish();
@@ -1501,6 +1501,11 @@ 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 {
+ txservice_.send_poll(); // close the bus
+ 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
@@ -1808,7 +1813,7 @@ void EMSESP::start_serial_console() {
#if defined(EMSESP_DEBUG)
shell_->log_level(uuid::log::Level::DEBUG);
#else
- shell_->log_level(uuid::log::Level::TRACE);
+ shell_->log_level(uuid::log::Level::INFO);
#endif
}
diff --git a/src/roomcontrol.cpp b/src/roomcontrol.cpp
index 72e8de6b2..0721c3bab 100644
--- a/src/roomcontrol.cpp
+++ b/src/roomcontrol.cpp
@@ -28,14 +28,22 @@ int16_t Roomctrl::remotetemp_[HCS] = {EMS_VALUE_INT16_NOTSET, EMS_VALUE_INT16
uint8_t Roomctrl::remotehum_[HCS] = {EMS_VALUE_UINT8_NOTSET, EMS_VALUE_UINT8_NOTSET, EMS_VALUE_UINT8_NOTSET, EMS_VALUE_UINT8_NOTSET};
uint8_t Roomctrl::sendtype_[HCS] = {SendType::TEMP, SendType::TEMP, SendType::TEMP, SendType::TEMP};
uint8_t Roomctrl::type_[HCS] = {RemoteType::NONE, RemoteType::NONE, RemoteType::NONE, RemoteType::NONE};
+int16_t Roomctrl::outdoortemp_ = 0; // EMS_VALUE_INT16_NOTSET;
+uint32_t Roomctrl::outdoortime_ = 0;
+bool Roomctrl::outdoorsensor_ = false;
uint32_t Roomctrl::timeout_ = 0;
/**
* set the temperature,
*/
+void Roomctrl::set_outdoortemp(const int16_t temp) {
+ outdoortemp_ = temp < 1000 ? temp : EMS_VALUE_INT16_NOTSET;
+}
+
void Roomctrl::set_timeout(uint8_t t) {
timeout_ = t * 3600000; // ms
}
+
void Roomctrl::set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp) {
if (!type_[hc] && !type) {
return;
@@ -91,11 +99,22 @@ void Roomctrl::send(uint8_t addr) {
if (addr & 0x80) {
return;
}
+ if (addr == 0x50 && outdoorsensor_) {
+ if (uuid::get_uptime() - outdoortime_ > SEND_INTERVAL && outdoortemp_ != EMS_VALUE_INT16_NOTSET) {
+ outdoortemp(addr, 0);
+ outdoortime_ = uuid::get_uptime();
+ return;
+ } else {
+ EMSuart::send_poll(addr | EMSbus::ems_mask());
+ return;
+ }
+ }
uint8_t hc = get_hc(addr);
// check address, reply only on addresses 0x18..0x1B or 0x40..0x43
if (hc >= HCS) {
return;
}
+
// no reply if the temperature is not set
if (!switch_off_[hc] && remotetemp_[hc] == EMS_VALUE_INT16_NOTSET && remotehum_[hc] == EMS_VALUE_UINT8_NOTSET) {
return;
@@ -145,6 +164,15 @@ void Roomctrl::send(uint8_t addr) {
* check if there is a message for the remote room controller
*/
void Roomctrl::check(uint8_t addr, const uint8_t * data, const uint8_t length) {
+ // check for read of outdoor temp
+ if (addr == 0xD0 && outdoorsensor_) {
+ if (data[2] == 0xD1) {
+ outdoortemp(0x50, data[0]);
+ } else if (data[2] == 0x02) {
+ wirelessversion(0x50, data[0]);
+ }
+ return;
+ }
uint8_t hc = get_hc(addr);
if (hc >= HCS || length < 5) {
return;
@@ -252,6 +280,19 @@ void Roomctrl::version(uint8_t addr, uint8_t dst, uint8_t hc) {
}
}
+void Roomctrl::wirelessversion(uint8_t addr, uint8_t dst) {
+ uint8_t data[20];
+ data[0] = addr | EMSbus::ems_mask();
+ data[1] = dst & 0x7F;
+ data[2] = 0x02;
+ data[3] = 0;
+ data[4] = 236; // product_id 236
+ data[5] = 3; // version 3.03
+ data[6] = 3;
+ data[7] = EMSbus::calculate_crc(data, 7); // append CRC
+ EMSuart::transmit(data, 8);
+}
+
/**
* unknown message id, we reply with empty message
*/
@@ -308,7 +349,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) {
data[5] = 0x2B + hc;
data[6] = (uint8_t)(remotetemp_[hc] >> 8);
data[7] = (uint8_t)(remotetemp_[hc] & 0xFF);
- uint16_t t1 = remotetemp_[hc] * 10 + 3;
+ uint16_t t1 = remotetemp_[hc] * 10;
data[8] = (uint8_t)(t1 >> 8);
data[9] = (uint8_t)(t1 & 0xFF);
data[10] = 1; // not sure what this is and if we need it, maybe mode?
@@ -339,7 +380,7 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst, uint8_t hc) {
data[5] = 0x2B + hc;
data[6] = (uint8_t)(remotetemp_[hc] >> 8);
data[7] = (uint8_t)(remotetemp_[hc] & 0xFF);
- uint16_t t1 = remotetemp_[hc] * 10 + 3;
+ uint16_t t1 = remotetemp_[hc] * 10;
data[8] = (uint8_t)(t1 >> 8);
data[9] = (uint8_t)(t1 & 0xFF);
data[10] = 1; // not sure what this is and if we need it, maybe mode?
@@ -422,5 +463,18 @@ int16_t Roomctrl::calc_dew(int16_t temp, uint8_t humi) {
return dt;
}
+void Roomctrl::outdoortemp(uint8_t addr, uint8_t dst) {
+ uint8_t data[12];
+ data[0] = addr | EMSbus::ems_mask();
+ data[1] = dst & 0x7F;
+ data[2] = 0xD1;
+ data[3] = 0;
+ data[4] = (uint8_t)(outdoortemp_ >> 8);
+ data[5] = (uint8_t)(outdoortemp_ & 0xFF);
+ data[6] = 0;
+ data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC
+ EMSuart::transmit(data, 8);
+}
+
} // namespace emsesp
diff --git a/src/roomcontrol.h b/src/roomcontrol.h
index c6c5577d2..6993f1648 100644
--- a/src/roomcontrol.h
+++ b/src/roomcontrol.h
@@ -31,6 +31,13 @@ class Roomctrl {
static void check(uint8_t addr, const uint8_t * data, const uint8_t length);
static void set_remotetemp(const uint8_t type, const uint8_t hc, const int16_t temp);
static void set_remotehum(const uint8_t type, const uint8_t hc, const int8_t hum);
+ static void set_outdoorsensor(const bool enable) {
+ outdoorsensor_ = enable;
+ }
+ static bool has_outdoorsensor() {
+ return outdoorsensor_ ;
+ }
+ static void set_outdoortemp(const int16_t temp);
static bool is_remote(const uint8_t hc) {
return (hc < 4 && remotetemp_[hc] != EMS_VALUE_INT16_NOTSET);
}
@@ -51,6 +58,8 @@ class Roomctrl {
static void ack_write();
static void replyF7(uint8_t addr, uint8_t dst, uint8_t offset, uint8_t typehh, uint8_t typeh, uint8_t typel, uint8_t hc);
static int16_t calc_dew(int16_t temp, uint8_t hum);
+ static void outdoortemp(uint8_t addr, uint8_t dst);
+ static void wirelessversion(uint8_t addr, uint8_t dst);
static bool switch_off_[HCS];
static uint32_t send_time_[HCS];
@@ -59,6 +68,9 @@ class Roomctrl {
static uint8_t remotehum_[HCS];
static uint8_t sendtype_[HCS];
static uint8_t type_[HCS]; // type is product-id 113 for RC20 or 109 for Junkers FB10
+ static int16_t outdoortemp_;
+ static uint32_t outdoortime_;
+ static bool outdoorsensor_;
static uint32_t timeout_;
};
diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp
index e33f0aeed..39f1726a6 100644
--- a/src/web/WebSettingsService.cpp
+++ b/src/web/WebSettingsService.cpp
@@ -81,6 +81,7 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["modbus_max_clients"] = settings.modbus_max_clients;
root["modbus_timeout"] = settings.modbus_timeout;
root["developer_mode"] = settings.developer_mode;
+ root["outdoorsensor"] = settings.outdoorsensor;
}
// call on initialization and also when settings are updated via web or console
@@ -365,6 +366,9 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
settings.developer_mode = root["developer_mode"];
EMSESP::system_.developer_mode(settings.developer_mode);
+ settings.outdoorsensor = root["outdoorsensor"];
+ emsesp::Roomctrl::set_outdoorsensor(settings.outdoorsensor);
+
settings.bool_dashboard = root["bool_dashboard"] | EMSESP_DEFAULT_BOOL_FORMAT;
EMSESP::system_.bool_dashboard(settings.bool_dashboard);
diff --git a/src/web/WebSettingsService.h b/src/web/WebSettingsService.h
index 57a2a00c8..8030af9b7 100644
--- a/src/web/WebSettingsService.h
+++ b/src/web/WebSettingsService.h
@@ -83,6 +83,7 @@ class WebSettings {
uint8_t eth_clock_mode;
bool developer_mode; // developer mode
+ bool outdoorsensor;
static void read(WebSettings & settings, JsonObject root);
static StateUpdateResult update(JsonObject root, WebSettings & settings);