modbus: fix queue deduplicator erasing custom commands (#3650)

This commit is contained in:
Javier Peletier 2022-07-24 22:06:18 +02:00 committed by Jesse Hills
parent ccc13cc9e1
commit df73170e5a
No known key found for this signature in database
GPG key ID: BEAAE804EFD8E83A
2 changed files with 12 additions and 2 deletions

View file

@ -108,8 +108,7 @@ void ModbusController::queue_command(const ModbusCommandItem &command) {
// check if this commmand is already qeued. // check if this commmand is already qeued.
// not very effective but the queue is never really large // not very effective but the queue is never really large
for (auto &item : command_queue_) { for (auto &item : command_queue_) {
if (item->register_address == command.register_address && item->register_count == command.register_count && if (item->is_equal(command)) {
item->register_type == command.register_type && item->function_code == command.function_code) {
ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u", ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u",
static_cast<uint8_t>(command.register_type), command.register_address, command.register_count); static_cast<uint8_t>(command.register_type), command.register_address, command.register_count);
// update the payload of the queued command // update the payload of the queued command
@ -489,6 +488,15 @@ bool ModbusCommandItem::send() {
return true; return true;
} }
bool ModbusCommandItem::is_equal(const ModbusCommandItem &other) {
// for custom commands we have to check for identical payloads, since
// address/count/type fields will be set to zero
return this->function_code == ModbusFunctionCode::CUSTOM
? this->payload == other.payload
: other.register_address == this->register_address && other.register_count == this->register_count &&
other.register_type == this->register_type && other.function_code == this->function_code;
}
void number_to_payload(std::vector<uint16_t> &data, int64_t value, SensorValueType value_type) { void number_to_payload(std::vector<uint16_t> &data, int64_t value, SensorValueType value_type) {
switch (value_type) { switch (value_type) {
case SensorValueType::U_WORD: case SensorValueType::U_WORD:

View file

@ -395,6 +395,8 @@ class ModbusCommandItem {
ModbusController *modbusdevice, const std::vector<uint16_t> &values, ModbusController *modbusdevice, const std::vector<uint16_t> &values,
std::function<void(ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data)> std::function<void(ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data)>
&&handler = nullptr); &&handler = nullptr);
bool is_equal(const ModbusCommandItem &other);
}; };
/** Modbus controller class. /** Modbus controller class.