Add backwards compatibility for modbus protocol
Add verification for new registers Signed-off-by: Martin Lukas <martin.lukas@chargebyte.com>pull/179/head
parent
5affe6614e
commit
5d15fc9e16
|
|
@ -8,8 +8,10 @@ include(../modbus.pri)
|
|||
|
||||
HEADERS += \
|
||||
integrationplugininro.h \
|
||||
pantabox.h \
|
||||
pantaboxdiscovery.h
|
||||
|
||||
SOURCES += \
|
||||
integrationplugininro.cpp \
|
||||
pantabox.cpp \
|
||||
pantaboxdiscovery.cpp
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ void IntegrationPluginInro::postSetupThing(Thing *thing)
|
|||
if (!m_refreshTimer) {
|
||||
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
|
||||
connect(m_refreshTimer, &PluginTimer::timeout, this, [this] {
|
||||
foreach (PantaboxModbusTcpConnection *connection, m_connections) {
|
||||
foreach (Pantabox *connection, m_connections) {
|
||||
if (connection->reachable()) {
|
||||
connection->update();
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ void IntegrationPluginInro::executeAction(ThingActionInfo *info)
|
|||
{
|
||||
if (info->thing()->thingClassId() == pantaboxThingClassId) {
|
||||
|
||||
PantaboxModbusTcpConnection *connection = m_connections.value(info->thing());
|
||||
Pantabox *connection = m_connections.value(info->thing());
|
||||
|
||||
if (!connection->reachable()) {
|
||||
qCWarning(dcInro()) << "Cannot execute action. The PANTABOX is not reachable";
|
||||
|
|
@ -248,7 +248,7 @@ void IntegrationPluginInro::thingRemoved(Thing *thing)
|
|||
qCDebug(dcInro()) << "Thing removed" << thing->name();
|
||||
|
||||
if (m_connections.contains(thing)) {
|
||||
PantaboxModbusTcpConnection *connection = m_connections.take(thing);
|
||||
Pantabox *connection = m_connections.take(thing);
|
||||
connection->disconnectDevice();
|
||||
connection->deleteLater();
|
||||
}
|
||||
|
|
@ -269,8 +269,8 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info)
|
|||
Thing *thing = info->thing();
|
||||
NetworkDeviceMonitor *monitor = m_monitors.value(thing);
|
||||
|
||||
PantaboxModbusTcpConnection *connection = new PantaboxModbusTcpConnection(monitor->networkDeviceInfo().address(), 502, 1, this);
|
||||
connect(info, &ThingSetupInfo::aborted, connection, &PantaboxModbusTcpConnection::deleteLater);
|
||||
Pantabox *connection = new Pantabox(monitor->networkDeviceInfo().address(), 502, 1, this);
|
||||
connect(info, &ThingSetupInfo::aborted, connection, &Pantabox::deleteLater);
|
||||
|
||||
// Monitor reachability
|
||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
|
||||
|
|
@ -289,7 +289,7 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info)
|
|||
});
|
||||
|
||||
// Connection reachability
|
||||
connect(connection, &PantaboxModbusTcpConnection::reachableChanged, thing, [thing, connection](bool reachable){
|
||||
connect(connection, &Pantabox::reachableChanged, thing, [thing, connection](bool reachable){
|
||||
qCInfo(dcInro()) << "Reachable changed to" << reachable << "for" << thing;
|
||||
thing->setStateValue("connected", reachable);
|
||||
|
||||
|
|
@ -301,28 +301,28 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info)
|
|||
}
|
||||
});
|
||||
|
||||
connect(connection, &PantaboxModbusTcpConnection::updateFinished, thing, [thing, connection](){
|
||||
connect(connection, &Pantabox::updateFinished, thing, [thing, connection](){
|
||||
qCDebug(dcInro()) << "Update finished for" << thing;
|
||||
qCDebug(dcInro()) << connection;
|
||||
|
||||
QString chargingStateString;
|
||||
switch(connection->chargingState()) {
|
||||
case PantaboxModbusTcpConnection::ChargingStateA:
|
||||
case Pantabox::ChargingStateA:
|
||||
chargingStateString = "A";
|
||||
break;
|
||||
case PantaboxModbusTcpConnection::ChargingStateB:
|
||||
case Pantabox::ChargingStateB:
|
||||
chargingStateString = "B";
|
||||
break;
|
||||
case PantaboxModbusTcpConnection::ChargingStateC:
|
||||
case Pantabox::ChargingStateC:
|
||||
chargingStateString = "C";
|
||||
break;
|
||||
case PantaboxModbusTcpConnection::ChargingStateD:
|
||||
case Pantabox::ChargingStateD:
|
||||
chargingStateString = "D";
|
||||
break;
|
||||
case PantaboxModbusTcpConnection::ChargingStateE:
|
||||
case Pantabox::ChargingStateE:
|
||||
chargingStateString = "E";
|
||||
break;
|
||||
case PantaboxModbusTcpConnection::ChargingStateF:
|
||||
case Pantabox::ChargingStateF:
|
||||
chargingStateString = "F";
|
||||
break;
|
||||
}
|
||||
|
|
@ -333,8 +333,8 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info)
|
|||
// C: connected, charging
|
||||
// D: ventilation required
|
||||
// E: F: fault/error
|
||||
thing->setStateValue(pantaboxPluggedInStateTypeId, connection->chargingState() >= PantaboxModbusTcpConnection::ChargingStateB);
|
||||
thing->setStateValue(pantaboxChargingStateTypeId, connection->chargingState() >= PantaboxModbusTcpConnection::ChargingStateC);
|
||||
thing->setStateValue(pantaboxPluggedInStateTypeId, connection->chargingState() >= Pantabox::ChargingStateB);
|
||||
thing->setStateValue(pantaboxChargingStateTypeId, connection->chargingState() >= Pantabox::ChargingStateC);
|
||||
thing->setStateValue(pantaboxCurrentPowerStateTypeId, connection->currentPower()); // W
|
||||
thing->setStateValue(pantaboxTotalEnergyConsumedStateTypeId, connection->chargedEnergy() / 1000.0); // Wh
|
||||
thing->setStateMaxValue(pantaboxMaxChargingCurrentActionTypeId, connection->maxPossibleChargingCurrent());
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include <network/networkdevicemonitor.h>
|
||||
|
||||
#include "extern-plugininfo.h"
|
||||
#include "pantaboxmodbustcpconnection.h"
|
||||
#include "pantabox.h"
|
||||
|
||||
class IntegrationPluginInro: public IntegrationPlugin
|
||||
{
|
||||
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
private:
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<Thing *, PantaboxModbusTcpConnection *> m_connections;
|
||||
QHash<Thing *, Pantabox *> m_connections;
|
||||
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
|
||||
|
||||
void setupConnection(ThingSetupInfo *info);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,540 @@
|
|||
#include "pantabox.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
NYMEA_LOGGING_CATEGORY(dcPantabox, "Pantabox")
|
||||
|
||||
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;
|
||||
|
||||
if (!m_pendingUpdateReplies.isEmpty()) {
|
||||
qCDebug(dcPantabox()) << "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;
|
||||
reply = readChargingState();
|
||||
if (!reply) {
|
||||
qCWarning(dcPantabox()) << "Error occurred while reading \"Charging state\" 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();
|
||||
processChargingStateRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
|
||||
// Read Current charging power
|
||||
qCDebug(dcPantabox()) << "--> 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();
|
||||
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();
|
||||
processCurrentPowerRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
|
||||
// Read Charged energy
|
||||
qCDebug(dcPantabox()) << "--> 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();
|
||||
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();
|
||||
processChargedEnergyRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
|
||||
// Read Maximal possible charging current (adapter)
|
||||
qCDebug(dcPantabox()) << "--> 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();
|
||||
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();
|
||||
processMaxPossibleChargingCurrentRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
|
||||
// Read Actual charging current
|
||||
qCDebug(dcPantabox()) << "--> 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();
|
||||
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();
|
||||
processChargingCurrentRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
|
||||
// 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;
|
||||
reply = readChargingEnabled();
|
||||
if (!reply) {
|
||||
qCWarning(dcPantabox()) << "Error occurred while reading \"Charging enabled (1) / disabled (0)\" 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();
|
||||
processChargingEnabledRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
|
||||
// Read Max charging current
|
||||
qCDebug(dcPantabox()) << "--> 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();
|
||||
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();
|
||||
processMaxChargingCurrentRegisterValues(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 \"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();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef PANTABOX_H
|
||||
#define PANTABOX_H
|
||||
|
||||
#include "pantaboxmodbustcpconnection.h"
|
||||
|
||||
class Pantabox : public PantaboxModbusTcpConnection
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Pantabox(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent = nullptr);
|
||||
explicit Pantabox(ModbusTcpMaster *modbusTcpMaster, quint16 slaveId, QObject *parent = nullptr);
|
||||
~Pantabox() = default;
|
||||
|
||||
virtual bool update() override;
|
||||
virtual bool initialize() override;
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // PANTABOX_H
|
||||
|
|
@ -69,10 +69,10 @@ void PantaboxDiscovery::startDiscovery()
|
|||
|
||||
void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
|
||||
{
|
||||
PantaboxModbusTcpConnection *connection = new PantaboxModbusTcpConnection(networkDeviceInfo.address(), m_port, m_modbusAddress, this);
|
||||
Pantabox *connection = new Pantabox(networkDeviceInfo.address(), m_port, m_modbusAddress, this);
|
||||
m_connections.append(connection);
|
||||
|
||||
connect(connection, &PantaboxModbusTcpConnection::reachableChanged, this, [=](bool reachable){
|
||||
connect(connection, &Pantabox::reachableChanged, this, [=](bool reachable){
|
||||
if (!reachable) {
|
||||
// Disconnected ... done with this connection
|
||||
cleanupConnection(connection);
|
||||
|
|
@ -80,30 +80,42 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic
|
|||
}
|
||||
|
||||
// Modbus TCP connected...ok, let's try to initialize it!
|
||||
connect(connection, &PantaboxModbusTcpConnection::initializationFinished, this, [=](bool success){
|
||||
connect(connection, &Pantabox::initializationFinished, this, [=](bool success){
|
||||
if (!success) {
|
||||
qCDebug(dcInro()) << "Discovery: Initialization failed on" << networkDeviceInfo.address().toString() << "Continue...";
|
||||
cleanupConnection(connection);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: find a better way to discover the device besides a valid init
|
||||
qCDebug(dcInro()) << "Discovery: Connection initialized successfully" << connection->serialNumber();
|
||||
// Modbus registers for vendor and product name are available since Modbus version 1.1
|
||||
if (connection->modbusTcpVersion() > 257) {
|
||||
|
||||
Result result;
|
||||
result.serialNumber = QString::number(connection->serialNumber(), 16).toUpper();
|
||||
result.modbusTcpVersion = modbusVersionToString(connection->modbusTcpVersion());
|
||||
result.networkDeviceInfo = networkDeviceInfo;
|
||||
m_results.append(result);
|
||||
// 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();
|
||||
|
||||
qCInfo(dcInro()) << "Discovery: --> Found"
|
||||
<< "Serial number:" << result.serialNumber
|
||||
<< "(" << connection->serialNumber() << ")"
|
||||
<< "ModbusTCP version:" << result.modbusTcpVersion
|
||||
<< result.networkDeviceInfo;
|
||||
Result result;
|
||||
result.serialNumber = QString::number(connection->serialNumber(), 16).toUpper();
|
||||
result.modbusTcpVersion = modbusVersionToString(connection->modbusTcpVersion());
|
||||
result.networkDeviceInfo = networkDeviceInfo;
|
||||
m_results.append(result);
|
||||
|
||||
// Done with this connection
|
||||
cleanupConnection(connection);
|
||||
qCInfo(dcInro()) << "Discovery: --> Found"
|
||||
<< "Serial number:" << result.serialNumber
|
||||
<< "(" << connection->serialNumber() << ")"
|
||||
<< "ModbusTCP version:" << result.modbusTcpVersion
|
||||
<< result.networkDeviceInfo;
|
||||
|
||||
// Done with this connection
|
||||
cleanupConnection(connection);
|
||||
} else {
|
||||
qCDebug(dcInro()) << "Discovery: Device not added to result because of wrong vendor or/and product name"
|
||||
<< connection->vendorName()
|
||||
<< connection->productName();
|
||||
}
|
||||
} else {
|
||||
qCDebug(dcInro()) << "Discovery: Device not added to result because of wrong ModbusTcpVersion" << modbusVersionToString(connection->modbusTcpVersion());
|
||||
}
|
||||
});
|
||||
|
||||
// Initializing...
|
||||
|
|
@ -122,7 +134,7 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic
|
|||
});
|
||||
|
||||
// If check reachability failed...skip this host...
|
||||
connect(connection, &PantaboxModbusTcpConnection::checkReachabilityFailed, this, [=](){
|
||||
connect(connection, &Pantabox::checkReachabilityFailed, this, [=](){
|
||||
qCDebug(dcInro()) << "Discovery: Check reachability failed on" << networkDeviceInfo.address().toString() << "Continue...";
|
||||
cleanupConnection(connection);
|
||||
});
|
||||
|
|
@ -131,7 +143,7 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic
|
|||
connection->connectDevice();
|
||||
}
|
||||
|
||||
void PantaboxDiscovery::cleanupConnection(PantaboxModbusTcpConnection *connection)
|
||||
void PantaboxDiscovery::cleanupConnection(Pantabox *connection)
|
||||
{
|
||||
m_connections.removeAll(connection);
|
||||
connection->disconnectDevice();
|
||||
|
|
@ -143,7 +155,7 @@ void PantaboxDiscovery::finishDiscovery()
|
|||
qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();
|
||||
|
||||
// Cleanup any leftovers...we don't care any more
|
||||
foreach (PantaboxModbusTcpConnection *connection, m_connections)
|
||||
foreach (Pantabox *connection, m_connections)
|
||||
cleanupConnection(connection);
|
||||
|
||||
qCInfo(dcInro()) << "Discovery: Finished the discovery process. Found" << m_results.count()
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@
|
|||
#include <QObject>
|
||||
|
||||
#include <network/networkdevicediscovery.h>
|
||||
|
||||
#include "pantaboxmodbustcpconnection.h"
|
||||
#include "pantabox.h"
|
||||
|
||||
class PantaboxDiscovery : public QObject
|
||||
{
|
||||
|
|
@ -66,12 +65,12 @@ private:
|
|||
|
||||
QDateTime m_startDateTime;
|
||||
|
||||
QList<PantaboxModbusTcpConnection *> m_connections;
|
||||
QList<Pantabox *> m_connections;
|
||||
|
||||
QList<Result> m_results;
|
||||
|
||||
void checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo);
|
||||
void cleanupConnection(PantaboxModbusTcpConnection *connection);
|
||||
void cleanupConnection(Pantabox *connection);
|
||||
|
||||
void finishDiscovery();
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue