diff --git a/inro/integrationplugininro.cpp b/inro/integrationplugininro.cpp index 1abbba7..de06d88 100644 --- a/inro/integrationplugininro.cpp +++ b/inro/integrationplugininro.cpp @@ -163,10 +163,10 @@ void IntegrationPluginInro::executeAction(ThingActionInfo *info) if (info->action().actionTypeId() == pantaboxPowerActionTypeId) { bool power = info->action().paramValue(pantaboxPowerActionPowerParamTypeId).toBool(); - if (info->action().triggeredBy() == Action::TriggeredByUser) { - + // Play/pause charging session feature is available from Modbus Tcp version 1.1 + if (connection->modbusTcpVersion() <= 65536) { // When power is set by user, charging is going to stop or start depending on setting - qCDebug(dcInro()) << "PANTABOX: Set power by user" << (power ? 1 : 0); + qCDebug(dcInro()) << "Set power by user" << (power ? 1 : 0); QModbusReply *reply = connection->setChargingEnabled(power ? 1 : 0); if (!reply) { @@ -179,7 +179,7 @@ void IntegrationPluginInro::executeAction(ThingActionInfo *info) connect(reply, &QModbusReply::finished, info, [info, reply, power](){ if (reply->error() == QModbusDevice::NoError) { info->thing()->setStateValue(pantaboxPowerStateTypeId, power); - qCDebug(dcInro()) << "PANTABOX: Set power by user finished successfully"; + qCDebug(dcInro()) << "Set power by user finished successfully"; info->finish(Thing::ThingErrorNoError); } else { qCWarning(dcInro()) << "Error setting power by user:" << reply->error() << reply->errorString(); @@ -188,31 +188,55 @@ void IntegrationPluginInro::executeAction(ThingActionInfo *info) }); return; } else { + if (info->action().triggeredBy() == Action::TriggeredByUser) { - // When power is set to 0 by energy manager, max charging current is set to 0 otherwise take the configured max charging current - qCDebug(dcInro()) << "PANTABOX: Pause session by energy manager"; + // When power is set by user, charging is going to stop or start depending on setting + qCDebug(dcInro()) << "Set power by user" << (power ? 1 : 0); + QModbusReply *reply = connection->setChargingEnabled(power ? 1 : 0); - quint16 chargingCurrent = power ? info->action().paramValue(pantaboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt() : 0; - QModbusReply *reply = connection->setMaxChargingCurrent(chargingCurrent); + if (!reply) { + qCWarning(dcInro()) << "Execute action failed because the reply could not be created."; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } - if (!reply) { - qCWarning(dcInro()) << "Execute action failed because the reply could not be created."; - info->finish(Thing::ThingErrorHardwareFailure); + connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); + connect(reply, &QModbusReply::finished, info, [info, reply, power](){ + if (reply->error() == QModbusDevice::NoError) { + info->thing()->setStateValue(pantaboxPowerStateTypeId, power); + qCDebug(dcInro()) << "Set power by user finished successfully"; + info->finish(Thing::ThingErrorNoError); + } else { + qCWarning(dcInro()) << "Error setting power by user:" << reply->error() << reply->errorString(); + info->finish(Thing::ThingErrorHardwareFailure); + } + }); + return; + } else { + // When power is set to 0 by automatisnm, max charging current is set to 0 otherwise take the configured max charging current + qCDebug(dcInro()) << "Going to play/pause charging session"; + + quint16 chargingCurrent = power ? info->thing()->stateValue(pantaboxMaxChargingCurrentStateTypeId).toUInt() : 0; + QModbusReply *reply = connection->setMaxChargingCurrent(chargingCurrent); + + if (!reply) { + qCWarning(dcInro()) << "Execute action failed because the reply could not be created."; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); + connect(reply, &QModbusReply::finished, info, [info, reply, power](){ + if (reply->error() == QModbusDevice::NoError) { + qCDebug(dcInro()) << (power ? "Play" : "Pause") << "session by energy manager"; + info->finish(Thing::ThingErrorNoError); + } else { + qCWarning(dcInro()) << "Error setting charging current:" << reply->error() << reply->errorString(); + info->finish(Thing::ThingErrorHardwareFailure); + } + }); return; } - - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, info, [info, reply, chargingCurrent](){ - if (reply->error() == QModbusDevice::NoError) { - info->thing()->setStateValue(pantaboxMaxChargingCurrentStateTypeId, chargingCurrent); - qCDebug(dcInro()) << "PANTABOX: Set max charging current finished successfully"; - info->finish(Thing::ThingErrorNoError); - } else { - qCWarning(dcInro()) << "Error setting charging current:" << reply->error() << reply->errorString(); - info->finish(Thing::ThingErrorHardwareFailure); - } - }); - return; } } diff --git a/inro/integrationplugininro.json b/inro/integrationplugininro.json index 8f84598..0176106 100644 --- a/inro/integrationplugininro.json +++ b/inro/integrationplugininro.json @@ -146,34 +146,13 @@ "displayName": "Modbus TCP version", "type": "QString", "defaultValue": "" - }, - { - "id": "e247585c-18d2-454f-ac12-d625ce36cc52", - "name": "vendorName", - "displayName": "Vendor name", - "type": "QString", - "defaultValue": "" - }, - { - "id": "815db609-f739-4df6-aafc-6814ec12e102", - "name": "productName", - "displayName": "Product name", - "type": "QString", - "defaultValue": "" - }, + }, { "id": "8c92890f-c9fb-44dd-8665-f1502fc90912", "name": "firmwareVersion", "displayName": "Firmware version", "type": "QString", "defaultValue": "" - }, - { - "id": "e772b753-ced9-41dc-8cbd-7fc58834eaa9", - "name": "absoluteEnergy", - "displayName": "Absolute charged energy", - "type": "double", - "defaultValue": 0 } ] } diff --git a/inro/pantabox-registers.json b/inro/pantabox-registers.json index 680ac60..edb4d13 100644 --- a/inro/pantabox-registers.json +++ b/inro/pantabox-registers.json @@ -66,7 +66,6 @@ "type": "string", "registerType": "inputRegister", "description": "Name of vendor", - "readSchedule": "init", "access": "RO" }, { @@ -76,7 +75,6 @@ "type": "string", "registerType": "inputRegister", "description": "Name of product", - "readSchedule": "init", "access": "RO" }, { @@ -86,7 +84,7 @@ "type": "uint32", "registerType": "inputRegister", "description": "Firmware version", - "readSchedule": "init", + "readSchedule": "update", "access": "RO" }, { diff --git a/inro/pantabox.cpp b/inro/pantabox.cpp index 49b1912..452c09f 100644 --- a/inro/pantabox.cpp +++ b/inro/pantabox.cpp @@ -30,248 +30,30 @@ #include "pantabox.h" #include "loggingcategories.h" - -NYMEA_LOGGING_CATEGORY(dcPantabox, "Pantabox") +#include "pantaboxmodbustcpconnection.cpp" Pantabox::Pantabox(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent) : PantaboxModbusTcpConnection(hostAddress, port, slaveId, parent) { - // Note: sometimes right after the discovery / setup the check fails the first time due to server busy error, - // this is a very slow or busy device since it returns quiet often that error. Don't faile with the first busy error... - setCheckReachableRetries(3); -} -bool Pantabox::initialize() { - - if (!m_reachable) { - qCWarning(dcPantabox()) << "Tried to initialize but the device is not to be reachable."; - return false; - } - - if (m_initObject) { - qCWarning(dcPantabox()) << "Tried to initialize but the init process is already running."; - return false; - } - - m_initializing = true; - - // Parent object for the init process - m_initObject = new QObject(this); - - QModbusReply *reply = nullptr; - - // Read Serial number (hex) - qCDebug(dcPantabox()) << "--> Read init \"Serial number (hex)\" register:" << 256 << "size:" << 2; - reply = readSerialNumber(); - if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Serial number (hex)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - finishInitialization(false); - return false; - } - - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingInitReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, m_initObject, [this, reply](){ - handleModbusError(reply->error()); - m_pendingInitReplies.removeAll(reply); - if (reply->error() != QModbusDevice::NoError) { - finishInitialization(false); - return; - } - - const QModbusDataUnit unit = reply->result(); - processSerialNumberRegisterValues(unit.values()); - verifyInitFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, m_initObject, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Serial number (hex)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Serial number (hex)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); - - // Read ModbusTCP version - qCDebug(dcPantabox()) << "--> Read init \"ModbusTCP version\" register:" << 258 << "size:" << 2; - reply = readModbusTcpVersion(); - if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"ModbusTCP version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - finishInitialization(false); - return false; - } - - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingInitReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, m_initObject, [this, reply](){ - handleModbusError(reply->error()); - m_pendingInitReplies.removeAll(reply); - if (reply->error() != QModbusDevice::NoError) { - finishInitialization(false); - return; - } - - const QModbusDataUnit unit = reply->result(); - processModbusTcpVersionRegisterValues(unit.values()); - verifyInitFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, m_initObject, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"ModbusTCP version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"ModbusTCP version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); - - // Following Modbus registers are available since ModbusTcpVersion 1.1 - if (m_modbusTcpVersion < 257) - return true; - - // Read Name of vendor - qCDebug(dcPantabox()) << "--> Read init \"Name of vendor\" register:" << 260 << "size:" << 2; - reply = readVendorName(); - if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Name of vendor\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - finishInitialization(false); - return false; - } - - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingInitReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, m_initObject, [this, reply](){ - handleModbusError(reply->error()); - m_pendingInitReplies.removeAll(reply); - if (reply->error() != QModbusDevice::NoError) { - finishInitialization(false); - return; - } - - const QModbusDataUnit unit = reply->result(); - processVendorNameRegisterValues(unit.values()); - verifyInitFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, m_initObject, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Name of vendor\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Name of vendor\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); - - // Read Name of product - qCDebug(dcPantabox()) << "--> Read init \"Name of product\" register:" << 262 << "size:" << 4; - reply = readProductName(); - if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Name of product\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - finishInitialization(false); - return false; - } - - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingInitReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, m_initObject, [this, reply](){ - handleModbusError(reply->error()); - m_pendingInitReplies.removeAll(reply); - if (reply->error() != QModbusDevice::NoError) { - finishInitialization(false); - return; - } - - const QModbusDataUnit unit = reply->result(); - processProductNameRegisterValues(unit.values()); - verifyInitFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, m_initObject, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Name of product\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Name of product\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); - - // Read Firmware version - qCDebug(dcPantabox()) << "--> Read init \"Firmware version\" register:" << 266 << "size:" << 16; - reply = readFirmwareVersion(); - if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Firmware version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - finishInitialization(false); - return false; - } - - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingInitReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, m_initObject, [this, reply](){ - handleModbusError(reply->error()); - m_pendingInitReplies.removeAll(reply); - if (reply->error() != QModbusDevice::NoError) { - finishInitialization(false); - return; - } - - const QModbusDataUnit unit = reply->result(); - processFirmwareVersionRegisterValues(unit.values()); - verifyInitFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, m_initObject, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Firmware version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Firmware version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); - return true; } bool Pantabox::update() { if (!m_modbusTcpMaster->connected()) - return false; + return false; if (!m_pendingUpdateReplies.isEmpty()) { - qCDebug(dcPantabox()) << "Tried to update but there are still some update replies pending. Waiting for them to be finished..."; + qCDebug(dcPantaboxModbusTcpConnection()) << "Tried to update but there are still some update replies pending. Waiting for them to be finished..."; return true; } QModbusReply *reply = nullptr; // Read Charging state - qCDebug(dcPantabox()) << "--> Read \"Charging state\" register:" << 512 << "size:" << 1; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Charging state\" register:" << 512 << "size:" << 1; reply = readChargingState(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Charging state\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Charging state\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -298,17 +80,17 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Charging state\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Charging state\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Charging state\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Charging state\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); // Read Current charging power - qCDebug(dcPantabox()) << "--> Read \"Current charging power\" register:" << 513 << "size:" << 2; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Current charging power\" register:" << 513 << "size:" << 2; reply = readCurrentPower(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Current charging power\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Current charging power\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -335,17 +117,17 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Current charging power\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Current charging power\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Current charging power\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Current charging power\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); // Read Charged energy - qCDebug(dcPantabox()) << "--> Read \"Charged energy\" register:" << 515 << "size:" << 2; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Charged energy\" register:" << 515 << "size:" << 2; reply = readChargedEnergy(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -372,17 +154,17 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); // Read Maximal possible charging current (adapter) - qCDebug(dcPantabox()) << "--> Read \"Maximal possible charging current (adapter)\" register:" << 517 << "size:" << 1; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Maximal possible charging current (adapter)\" register:" << 517 << "size:" << 1; reply = readMaxPossibleChargingCurrent(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Maximal possible charging current (adapter)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Maximal possible charging current (adapter)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -409,17 +191,17 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Maximal possible charging current (adapter)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Maximal possible charging current (adapter)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Maximal possible charging current (adapter)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Maximal possible charging current (adapter)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); // Read Actual charging current - qCDebug(dcPantabox()) << "--> Read \"Actual charging current\" register:" << 518 << "size:" << 1; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Actual charging current\" register:" << 518 << "size:" << 1; reply = readChargingCurrent(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Actual charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Actual charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -446,58 +228,17 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Actual charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Actual charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Actual charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Actual charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); - // The Modbus register for absolute charged energy is available since Modbusversion 1.2 - if (m_modbusTcpVersion < 258) { - - // Read Absolute charged energy - qCDebug(dcPantabox()) << "--> Read \"Absolute charged energy\" register:" << 519 << "size:" << 2; - reply = readAbsoluteEnergy(); - if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - return false; - } - - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingUpdateReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, this, [this, reply](){ - m_pendingUpdateReplies.removeAll(reply); - handleModbusError(reply->error()); - if (reply->error() != QModbusDevice::NoError) { - verifyUpdateFinished(); - return; - } - - const QModbusDataUnit unit = reply->result(); - processAbsoluteEnergyRegisterValues(unit.values()); - verifyUpdateFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); - } - // Read Charging enabled (1) / disabled (0) - qCDebug(dcPantabox()) << "--> Read \"Charging enabled (1) / disabled (0)\" register:" << 768 << "size:" << 1; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Charging enabled (1) / disabled (0)\" register:" << 768 << "size:" << 1; reply = readChargingEnabled(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Charging enabled (1) / disabled (0)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Charging enabled (1) / disabled (0)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -524,17 +265,17 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Charging enabled (1) / disabled (0)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Charging enabled (1) / disabled (0)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Charging enabled (1) / disabled (0)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Charging enabled (1) / disabled (0)\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); // Read Max charging current - qCDebug(dcPantabox()) << "--> Read \"Max charging current\" register:" << 769 << "size:" << 1; + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Max charging current\" register:" << 769 << "size:" << 1; reply = readMaxChargingCurrent(); if (!reply) { - qCWarning(dcPantabox()) << "Error occurred while reading \"Max charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Max charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); return false; } @@ -561,10 +302,88 @@ bool Pantabox::update() { connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ QModbusResponse response = reply->rawResult(); if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Max charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Max charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); } else { - qCWarning(dcPantabox()) << "Modbus reply error occurred while reading \"Max charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Max charging current\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); } }); + + // The Modbus register for absolute charged energy is available since Modbusversion 1.1 + if (m_modbusTcpVersion > 65536) { + + // Read Absolute charged energy + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Absolute charged energy\" register:" << 519 << "size:" << 2; + reply = readAbsoluteEnergy(); + if (!reply) { + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + return false; + } + + if (reply->isFinished()) { + reply->deleteLater(); // Broadcast reply returns immediatly + return false; + } + + m_pendingUpdateReplies.append(reply); + connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); + connect(reply, &QModbusReply::finished, this, [this, reply](){ + m_pendingUpdateReplies.removeAll(reply); + handleModbusError(reply->error()); + if (reply->error() != QModbusDevice::NoError) { + verifyUpdateFinished(); + return; + } + + const QModbusDataUnit unit = reply->result(); + processAbsoluteEnergyRegisterValues(unit.values()); + verifyUpdateFinished(); + }); + + connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ + QModbusResponse response = reply->rawResult(); + if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + } else { + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + } + }); + + // Read Firmware version + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Firmware version\" register:" << 266 << "size:" << 16; + reply = readFirmwareVersion(); + if (!reply) { + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Firmware version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + return false; + } + + if (reply->isFinished()) { + reply->deleteLater(); // Broadcast reply returns immediatly + return false; + } + + m_pendingUpdateReplies.append(reply); + connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); + connect(reply, &QModbusReply::finished, this, [this, reply](){ + m_pendingUpdateReplies.removeAll(reply); + handleModbusError(reply->error()); + if (reply->error() != QModbusDevice::NoError) { + verifyUpdateFinished(); + return; + } + + const QModbusDataUnit unit = reply->result(); + processFirmwareVersionRegisterValues(unit.values()); + verifyUpdateFinished(); + }); + + connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ + QModbusResponse response = reply->rawResult(); + if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Firmware version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + } else { + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Firmware version\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + } + }); + } return true; } diff --git a/inro/pantabox.h b/inro/pantabox.h index bc59507..1e88d92 100644 --- a/inro/pantabox.h +++ b/inro/pantabox.h @@ -42,10 +42,6 @@ public: ~Pantabox() = default; virtual bool update() override; - virtual bool initialize() override; - -signals: - }; #endif // PANTABOX_H diff --git a/inro/pantaboxdiscovery.cpp b/inro/pantaboxdiscovery.cpp index 9c06168..0ccf067 100644 --- a/inro/pantaboxdiscovery.cpp +++ b/inro/pantaboxdiscovery.cpp @@ -33,7 +33,7 @@ PantaboxDiscovery::PantaboxDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) : QObject{parent}, - m_networkDeviceDiscovery{networkDeviceDiscovery} + m_networkDeviceDiscovery{networkDeviceDiscovery} { } @@ -88,33 +88,47 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic } // Modbus registers for vendor and product name are available since Modbus version 1.1 - if (connection->modbusTcpVersion() > 257) { + if (connection->modbusTcpVersion() > 65536) { - // Only add device to result when correct device parameters were read - if (connection->vendorName() == "INRO" && connection->productName() == "PANTABOX") { - qCDebug(dcInro()) << "Discovery: Connection initialized successfully" << connection->serialNumber(); - - Result result; - result.serialNumber = QString::number(connection->serialNumber(), 16).toUpper(); - result.modbusTcpVersion = modbusVersionToString(connection->modbusTcpVersion()); - result.networkDeviceInfo = networkDeviceInfo; - m_results.append(result); - - qCInfo(dcInro()) << "Discovery: --> Found" - << "Serial number:" << result.serialNumber - << "(" << connection->serialNumber() << ")" - << "ModbusTCP version:" << result.modbusTcpVersion - << result.networkDeviceInfo; - - // Done with this connection + QModbusReply *reply = connection->readProductName(); + if (!reply) { cleanupConnection(connection); - } else { - qCDebug(dcInro()) << "Discovery: Device not added to result because of wrong vendor or/and product name" - << connection->vendorName() - << connection->productName(); + return; } + + if (reply->isFinished()) { + reply->deleteLater(); // Broadcast reply returns immediatly + cleanupConnection(connection); + return; + } + + connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); + connect(reply, &QModbusReply::finished, this, [this, reply, connection, networkDeviceInfo](){ + if (reply->error() != QModbusDevice::NoError) { + qCDebug(dcInro()) << "Discovery: Error reading product name error on" << networkDeviceInfo.address().toString() << "Continue..."; + cleanupConnection(connection); + return; + } + + const QModbusDataUnit unit = reply->result(); + qCDebug(dcInro()) << "<-- Response from \"Name of product\" register" << 262 << "size:" << 4 << unit.values(); + if (unit.values().size() == 4) { + QString receivedProductName = ModbusDataUtils::convertToString(unit.values(), connection->stringEndianness()); + if (receivedProductName.toUpper().contains("PANTABOX")) { + addResult(connection, networkDeviceInfo); + } else { + qCDebug(dcInro()) << "Discovery: Invalid product name " << receivedProductName + << "on" << networkDeviceInfo.address().toString() << "Continue..."; + cleanupConnection(connection); + } + } else { + qCDebug(dcInro()) << "Discovery: Reading from \"Name of product\" registers" << 262 << "size:" << 4 << "returned different size than requested. Ignoring incomplete data" << unit.values(); + cleanupConnection(connection); + } + }); } else { qCDebug(dcInro()) << "Discovery: Device not added to result because of wrong ModbusTcpVersion" << modbusVersionToString(connection->modbusTcpVersion()); + addResult(connection, networkDeviceInfo); } }); @@ -162,3 +176,23 @@ void PantaboxDiscovery::finishDiscovery() << "PANTABOXE wallboxes in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz"); emit discoveryFinished(); } + +void PantaboxDiscovery::addResult(Pantabox *connection, const NetworkDeviceInfo &networkDeviceInfo) +{ + qCDebug(dcInro()) << "Discovery: Connection initialized successfully" << connection->serialNumber(); + + Result result; + result.serialNumber = QString::number(connection->serialNumber(), 16).toUpper(); + result.modbusTcpVersion = modbusVersionToString(connection->modbusTcpVersion()); + result.networkDeviceInfo = networkDeviceInfo; + m_results.append(result); + + qCInfo(dcInro()) << "Discovery: --> Found" + << "Serial number:" << result.serialNumber + << "(" << connection->serialNumber() << ")" + << "ModbusTCP version:" << result.modbusTcpVersion + << result.networkDeviceInfo; + + // Done with this connection + cleanupConnection(connection); +} diff --git a/inro/pantaboxdiscovery.h b/inro/pantaboxdiscovery.h index 95c1796..7732601 100644 --- a/inro/pantaboxdiscovery.h +++ b/inro/pantaboxdiscovery.h @@ -73,6 +73,7 @@ private: void cleanupConnection(Pantabox *connection); void finishDiscovery(); + void addResult(Pantabox *connection, const NetworkDeviceInfo &networkDeviceInfo); }; #endif // PANTABOXDISCOVERY_H