From aea9a4429d3f627bdd6c3450e1619ff368951b43 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 20 Nov 2024 15:25:57 +0100 Subject: [PATCH] fix modbus multiple devices (mixer) #2229 --- src/emsdevice.cpp | 7 +++--- src/modbus.cpp | 56 +++++++++++++++++++---------------------------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 70ae30a15..6e688bdd2 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1928,7 +1928,7 @@ const char * EMSdevice::telegram_type_name(std::shared_ptr teleg bool EMSdevice::handle_telegram(std::shared_ptr 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; @@ -1996,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; @@ -2082,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; } diff --git a/src/modbus.cpp b/src/modbus.cpp index 22e1ceb2f..696cfc613 100644 --- a/src/modbus.cpp +++ b/src/modbus.cpp @@ -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 & 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(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 & 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(); - - auto error_code = dev->modbus_value_to_json(tag, modbusInfo->short_name, data, input); + JsonObject input = input_doc.to(); + 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; }