mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
response to system send telegram, redetect device, not only update from database
This commit is contained in:
@@ -710,17 +710,31 @@ void EMSESP::publish_sensor_values(const bool time, const bool force) {
|
|||||||
|
|
||||||
// MQTT publish a telegram as raw data to the topic 'response'
|
// MQTT publish a telegram as raw data to the topic 'response'
|
||||||
void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
||||||
static char * buffer = nullptr;
|
static char * buffer = nullptr;
|
||||||
static uint8_t offset;
|
static uint8_t offset = 0;
|
||||||
if (buffer == nullptr) {
|
static uint16_t type = 0;
|
||||||
offset = telegram->offset; // store offset from first part
|
// restart on mismatch while collecting telegram
|
||||||
buffer = new char[768]; // max 256 hex-codes, 255 spaces, 1 termination
|
if (buffer && (telegram->offset < offset || telegram->type_id != type)) {
|
||||||
buffer[0] = '\0';
|
delete[] buffer;
|
||||||
|
buffer = nullptr;
|
||||||
|
}
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
offset = telegram->offset; // store offset from first part
|
||||||
|
type = telegram->type_id;
|
||||||
|
buffer = new char[768]; // max 256 hex-codes, 255 spaces, 1 termination
|
||||||
|
for (uint16_t i = 0; i < 256; i++) {
|
||||||
|
buffer[i * 3] = '0';
|
||||||
|
buffer[i * 3 + 1] = '0';
|
||||||
|
buffer[i * 3 + 2] = ' ';
|
||||||
|
}
|
||||||
|
buffer[267] = '\0';
|
||||||
|
}
|
||||||
|
if (telegram->message_length > 0) {
|
||||||
|
strlcpy(&buffer[(telegram->offset - offset) * 3], Helpers::data_to_hex(telegram->message_data, telegram->message_length).c_str(), 768);
|
||||||
}
|
}
|
||||||
strlcat(buffer, Helpers::data_to_hex(telegram->message_data, telegram->message_length).c_str(), 768);
|
|
||||||
if (response_id_ != 0) {
|
if (response_id_ != 0) {
|
||||||
strlcat(buffer, " ", 768);
|
buffer[strlen(buffer)] = ' '; // overwrite termination \0
|
||||||
return; // do not delete buffer
|
return; // do not delete buffer
|
||||||
}
|
}
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
char s[10];
|
char s[10];
|
||||||
@@ -1179,31 +1193,16 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first check to see if we already have it, if so update the record
|
// first check to see if we already have it, if so update the record
|
||||||
|
auto it = emsdevices.begin();
|
||||||
for (const auto & emsdevice : emsdevices) {
|
for (const auto & emsdevice : emsdevices) {
|
||||||
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
if (emsdevice && emsdevice->is_device_id(device_id)) {
|
||||||
if (product_id == 0 || emsdevice->product_id() != 0) { // update only with valid product_id
|
if (product_id == 0 || emsdevice->product_id() != 0) { // update only with valid product_id
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
emsdevices.erase(it); // erase the old device without product_id and re detect
|
||||||
LOG_DEBUG("Updating details for already active deviceID 0x%02X", device_id);
|
break;
|
||||||
emsdevice->product_id(product_id);
|
|
||||||
emsdevice->version(version);
|
|
||||||
|
|
||||||
// only set brand if it doesn't already exist
|
|
||||||
if (emsdevice->brand() == EMSdevice::Brand::NO_BRAND) {
|
|
||||||
emsdevice->brand(brand);
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the name and flags in our device library database
|
|
||||||
for (const auto & device : device_library_) {
|
|
||||||
if (device.product_id == product_id && device.device_type == emsdevice->device_type()) {
|
|
||||||
emsdevice->default_name(device.default_name); // custom name is set later
|
|
||||||
emsdevice->add_flags(device.flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true; // finish up
|
|
||||||
}
|
}
|
||||||
|
it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up the rest of the details using the product_id and create the new device object
|
// look up the rest of the details using the product_id and create the new device object
|
||||||
|
|||||||
@@ -178,6 +178,10 @@ class EMSESP {
|
|||||||
response_id_ = id;
|
response_id_ = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t response_id() {
|
||||||
|
return response_id_;
|
||||||
|
}
|
||||||
|
|
||||||
static bool wait_validate() {
|
static bool wait_validate() {
|
||||||
return (wait_validate_ != 0);
|
return (wait_validate_ != 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,6 +208,10 @@ class Mqtt {
|
|||||||
return lastresponse_;
|
return lastresponse_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_response() {
|
||||||
|
lastresponse_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void set_qos(uint8_t mqtt_qos) const {
|
void set_qos(uint8_t mqtt_qos) const {
|
||||||
mqtt_qos_ = mqtt_qos;
|
mqtt_qos_ = mqtt_qos;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
|||||||
telegram_raw[3] = telegram->offset;
|
telegram_raw[3] = telegram->offset;
|
||||||
|
|
||||||
// EMS+ has different format for read and write
|
// EMS+ has different format for read and write
|
||||||
if (telegram->operation != Telegram::Operation::TX_READ) {
|
if (telegram->operation != Telegram::Operation::TX_READ && telegram->operation != Telegram::Operation::TX_RAW) {
|
||||||
// WRITE/NONE
|
// WRITE/NONE
|
||||||
telegram_raw[4] = (telegram->type_id >> 8) - 1; // type, 1st byte, high-byte, subtract 0x100
|
telegram_raw[4] = (telegram->type_id >> 8) - 1; // type, 1st byte, high-byte, subtract 0x100
|
||||||
telegram_raw[5] = telegram->type_id & 0xFF; // type, 2nd byte, low-byte
|
telegram_raw[5] = telegram->type_id & 0xFF; // type, 2nd byte, low-byte
|
||||||
@@ -404,6 +404,17 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (telegram->operation == Telegram::Operation::TX_RAW) {
|
||||||
|
tx_state(Telegram::Operation::TX_READ);
|
||||||
|
if (EMSESP::response_id() == 0) {
|
||||||
|
Mqtt::clear_response();
|
||||||
|
EMSESP::set_response_id(telegram->type_id);
|
||||||
|
if (telegram->message_data[0] >= (telegram->type_id > 0xFF ? 25 : 27)) {
|
||||||
|
EMSESP::set_read_id(telegram->type_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
tx_state(telegram->operation); // tx now in a wait state
|
tx_state(telegram->operation); // tx now in a wait state
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,14 +523,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
|||||||
if (src != ems_bus_id() || dest == 0) {
|
if (src != ems_bus_id() || dest == 0) {
|
||||||
operation = Telegram::Operation::NONE; // do not check reply/ack for other ids and broadcasts
|
operation = Telegram::Operation::NONE; // do not check reply/ack for other ids and broadcasts
|
||||||
} else if (dest & 0x80) {
|
} else if (dest & 0x80) {
|
||||||
operation = Telegram::Operation::TX_READ;
|
// keep RAW to set the response when sending
|
||||||
EMSESP::set_response_id(type_id);
|
|
||||||
// trigger read of all parts of telegram if requested length is more than 32
|
|
||||||
// compatibility to earlier versions
|
|
||||||
const uint8_t part_length = type_id > 0xFF ? 25 : 27;
|
|
||||||
if (message_data[0] >= part_length) {
|
|
||||||
EMSESP::set_read_id(type_id);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
operation = Telegram::Operation::TX_WRITE;
|
operation = Telegram::Operation::TX_WRITE;
|
||||||
validate_id = type_id;
|
validate_id = type_id;
|
||||||
@@ -541,7 +545,7 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
|||||||
|
|
||||||
LOG_DEBUG("New Tx [#%d] telegram, length %d", tx_telegram_id_, message_length);
|
LOG_DEBUG("New Tx [#%d] telegram, length %d", tx_telegram_id_, message_length);
|
||||||
|
|
||||||
if (front) {
|
if (front && (operation != Telegram::Operation::TX_RAW || EMSESP::response_id() == 0)) {
|
||||||
// tx_telegrams_.push_front(qtxt); // add to front of queue
|
// tx_telegrams_.push_front(qtxt); // add to front of queue
|
||||||
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram), false, validate_id); // add to front of queue
|
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram), false, validate_id); // add to front of queue
|
||||||
} else {
|
} else {
|
||||||
@@ -674,8 +678,8 @@ uint16_t TxService::post_send_query() {
|
|||||||
if (post_typeid) {
|
if (post_typeid) {
|
||||||
uint8_t dest = (this->telegram_last_->dest & 0x7F);
|
uint8_t dest = (this->telegram_last_->dest & 0x7F);
|
||||||
// when set a value with large offset before and validate on same type and offset, or complete telegram
|
// when set a value with large offset before and validate on same type and offset, or complete telegram
|
||||||
uint8_t length = (this->telegram_last_->type_id == post_typeid) ? this->telegram_last_->message_length : 0xFF;
|
uint8_t length = (this->telegram_last_->type_id == post_typeid) ? this->telegram_last_->message_length : 0xFF;
|
||||||
uint8_t offset = (this->telegram_last_->type_id == post_typeid) ? this->telegram_last_->offset : 0;
|
uint8_t offset = (this->telegram_last_->type_id == post_typeid) ? this->telegram_last_->offset : 0;
|
||||||
this->add(Telegram::Operation::TX_READ, dest, post_typeid, offset, &length, 1, 0, true); // add to top/front of queue
|
this->add(Telegram::Operation::TX_READ, dest, post_typeid, offset, &length, 1, 0, true); // add to top/front of queue
|
||||||
// read_request(telegram_last_post_send_query_, dest, 0); // no offset
|
// read_request(telegram_last_post_send_query_, dest, 0); // no offset
|
||||||
LOG_DEBUG("Sending post validate read, type ID 0x%02X to dest 0x%02X", post_typeid, dest);
|
LOG_DEBUG("Sending post validate read, type ID 0x%02X to dest 0x%02X", post_typeid, dest);
|
||||||
|
|||||||
Reference in New Issue
Block a user