Introduce check reachability retries again
This commit is contained in:
parent
8e5a639591
commit
761ff94610
@ -37,6 +37,10 @@ NYMEA_LOGGING_CATEGORY(dcHuaweiFusionSolar, "HuaweiFusionSolar")
|
||||
HuaweiFusionSolar::HuaweiFusionSolar(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent) :
|
||||
HuaweiFusionModbusTcpConnection(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);
|
||||
|
||||
connect(this, &HuaweiFusionModbusTcpConnection::connectionStateChanged, this, [=](bool connected){
|
||||
if (!connected) {
|
||||
m_registersQueue.clear();
|
||||
@ -97,13 +101,14 @@ bool HuaweiFusionSolar::update()
|
||||
|
||||
// Add the requests to queue, begin with power values, since they are most important
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterInverterActivePower);
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterPowerMeterActivePower);
|
||||
if (m_battery1Available)
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterLunaBattery1Power);
|
||||
|
||||
if (m_battery2Available)
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterLunaBattery2Power);
|
||||
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterPowerMeterActivePower);
|
||||
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterInverterEnergyProduced);
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterInverterDeviceStatus);
|
||||
m_registersQueue.enqueue(HuaweiFusionModbusTcpConnection::RegisterLunaBattery1Status);
|
||||
@ -122,6 +127,11 @@ bool HuaweiFusionSolar::update()
|
||||
return true;
|
||||
}
|
||||
|
||||
double HuaweiFusionSolar::actualInverterPower() const
|
||||
{
|
||||
return m_actualInverterPower;
|
||||
}
|
||||
|
||||
void HuaweiFusionSolar::readNextRegister()
|
||||
{
|
||||
// Check if currently a reply is pending
|
||||
@ -157,10 +167,11 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Inverter active power\" register" << 32080 << "size:" << 2 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 2) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 2)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 2 << "but received" << unit.values();
|
||||
} else {
|
||||
processInverterActivePowerRegisterValues(unit.values());
|
||||
calculatActualInverterPower();
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,8 +213,8 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Inverter device status\" register" << 32089 << "size:" << 1 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 1) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 1 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 1)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 1 << "but received" << unit.values();
|
||||
} else {
|
||||
processInverterDeviceStatusRegisterValues(unit.values());
|
||||
}
|
||||
@ -246,8 +257,8 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Inverter energy produced\" register" << 32106 << "size:" << 2 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 2) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 2)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 2 << "but received" << unit.values();
|
||||
} else {
|
||||
processInverterEnergyProducedRegisterValues(unit.values());
|
||||
}
|
||||
@ -288,10 +299,9 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
handleModbusError(reply->error());
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Power meter active power\" register" << 37113 << "size:" << 2 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 2) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 2)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 2 << "but received" << unit.values();
|
||||
} else {
|
||||
processPowerMeterActivePowerRegisterValues(unit.values());
|
||||
}
|
||||
@ -334,8 +344,8 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 1 status\" register" << 37000 << "size:" << 1 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 1) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 1 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 1)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 1 << "but received" << unit.values();
|
||||
} else {
|
||||
processLunaBattery1StatusRegisterValues(unit.values());
|
||||
}
|
||||
@ -377,10 +387,11 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 1 power\" register" << 37001 << "size:" << 2 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 2) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 2)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 2 << "but received" << unit.values();
|
||||
} else {
|
||||
processLunaBattery1PowerRegisterValues(unit.values());
|
||||
calculatActualInverterPower();
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
@ -420,8 +431,8 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 1 state of charge\" register" << 37004 << "size:" << 1 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 1) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 1 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 1)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 1 << "but received" << unit.values();
|
||||
} else {
|
||||
processLunaBattery1SocRegisterValues(unit.values());
|
||||
}
|
||||
@ -464,8 +475,8 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 status\" register" << 37741 << "size:" << 1 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 1) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 1 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 1)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 1 << "but received" << unit.values();
|
||||
} else {
|
||||
processLunaBattery2StatusRegisterValues(unit.values());
|
||||
}
|
||||
@ -507,10 +518,11 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 power\" register" << 37743 << "size:" << 2 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 2) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 1)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values();
|
||||
} else {
|
||||
processLunaBattery2PowerRegisterValues(unit.values());
|
||||
calculatActualInverterPower();
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
@ -550,8 +562,8 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 state of charge\" register" << 37738 << "size:" << 1 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
|
||||
if (unit.values().count() != 1) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 1 << "but received" << unit.values().count();
|
||||
if (!valuesAreVaild(unit.values(), 1)) {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values. Requested" << 1 << "but received" << unit.values();
|
||||
} else {
|
||||
processLunaBattery2SocRegisterValues(unit.values());
|
||||
}
|
||||
@ -574,6 +586,45 @@ void HuaweiFusionSolar::readNextRegister()
|
||||
}
|
||||
}
|
||||
|
||||
bool HuaweiFusionSolar::valuesAreVaild(const QVector<quint16> &values, int readSize)
|
||||
{
|
||||
if (values.count() != readSize)
|
||||
return false;
|
||||
|
||||
// According to the documentation:
|
||||
// 0x7FFF: invalid value of the floating point type returned by one register
|
||||
// 0xFFFF: invalid value of a type other than the floating point type returned by one register
|
||||
// 0xFFFFFFFF: invalid value returned by two registers
|
||||
|
||||
if (values.count() == 2) {
|
||||
bool floatingPointValid = (values.at(0) != 0x7fff && values.at(1) != 0xffff);
|
||||
bool otherTypesValid = (values.at(0) != 0xffff && values.at(1) != 0xffff);
|
||||
return floatingPointValid && otherTypesValid;
|
||||
}
|
||||
|
||||
if (values.count() == 1)
|
||||
return values.at(0) != 0x7fff && values.at(0) != 0xffff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HuaweiFusionSolar::calculatActualInverterPower()
|
||||
{
|
||||
double actualPower = m_inverterActivePower * -1000.0;
|
||||
if (m_battery1Available)
|
||||
actualPower += m_lunaBattery1Power;
|
||||
|
||||
if (m_battery2Available)
|
||||
actualPower += m_lunaBattery2Power;
|
||||
|
||||
qCDebug(dcHuaweiFusionSolar()) << "Inverter power:" << m_inverterActivePower << "W Battery 1:" << m_lunaBattery1Power << "W Battery 2:" << m_lunaBattery2Power << "W -->" << "Actual inverter power:" << actualPower << "W";
|
||||
if (m_actualInverterPower != actualPower)
|
||||
return;
|
||||
|
||||
m_actualInverterPower = actualPower;
|
||||
emit actualInverterPowerChanged(m_actualInverterPower);
|
||||
}
|
||||
|
||||
void HuaweiFusionSolar::finishRequest()
|
||||
{
|
||||
m_currentRegisterRequest = -1;
|
||||
|
||||
@ -46,6 +46,13 @@ public:
|
||||
bool initialize() override;
|
||||
virtual bool update() override;
|
||||
|
||||
// The inverter shows the pv power AND the power of the connected batteries if they discharge.
|
||||
// This power values represents the power taking the batteries into account.
|
||||
double actualInverterPower() const;
|
||||
|
||||
signals:
|
||||
void actualInverterPowerChanged(double actualInverterPower);
|
||||
|
||||
private:
|
||||
QQueue<HuaweiFusionModbusTcpConnection::Registers> m_registersQueue;
|
||||
QModbusReply *m_initReply = nullptr;
|
||||
@ -56,10 +63,14 @@ private:
|
||||
bool m_battery1Available = true;
|
||||
bool m_battery2Available = true;
|
||||
|
||||
double m_actualInverterPower = 0;
|
||||
|
||||
QString exceptionToString(QModbusPdu::ExceptionCode exception);
|
||||
|
||||
private slots:
|
||||
void readNextRegister();
|
||||
bool valuesAreVaild(const QVector<quint16> &values, int readSize);
|
||||
void calculatActualInverterPower();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -37,12 +37,7 @@ HuaweiFusionSolarDiscovery::HuaweiFusionSolarDiscovery(NetworkDeviceDiscovery *n
|
||||
m_port(port),
|
||||
m_modbusAddress(modbusAddress)
|
||||
{
|
||||
m_gracePeriodTimer.setSingleShot(true);
|
||||
m_gracePeriodTimer.setInterval(3000);
|
||||
connect(&m_gracePeriodTimer, &QTimer::timeout, this, [this](){
|
||||
qCDebug(dcHuawei()) << "Discovery: Grace period timer triggered.";
|
||||
finishDiscovery();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +66,11 @@ void HuaweiFusionSolarDiscovery::startDiscovery()
|
||||
}
|
||||
}
|
||||
|
||||
m_gracePeriodTimer.start();
|
||||
// Finish with some delay so the last added network device information objects still can be checked.
|
||||
QTimer::singleShot(3000, this, [this](){
|
||||
qCDebug(dcHuawei()) << "Discovery: Grace period timer triggered.";
|
||||
finishDiscovery();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -108,20 +107,18 @@ void HuaweiFusionSolarDiscovery::checkNetworkDevice(const NetworkDeviceInfo &net
|
||||
return;
|
||||
}
|
||||
|
||||
m_discoveryResults.append(networkDeviceInfo);
|
||||
|
||||
qCDebug(dcHuawei()) << "Discovery: --> Found" << networkDeviceInfo;
|
||||
m_discoveryResults.append(networkDeviceInfo);
|
||||
|
||||
// Done with this connection
|
||||
cleanupConnection(connection);
|
||||
});
|
||||
|
||||
// Initializing...
|
||||
if (!connection->initialize()) {
|
||||
qCDebug(dcHuawei()) << "Discovery: Unable to initialize connection on" << networkDeviceInfo.address().toString() << "Continue...";;
|
||||
cleanupConnection(connection);
|
||||
}
|
||||
|
||||
// Initializing...
|
||||
});
|
||||
|
||||
// If we get any error...skip this host...
|
||||
@ -138,9 +135,12 @@ void HuaweiFusionSolarDiscovery::checkNetworkDevice(const NetworkDeviceInfo &net
|
||||
cleanupConnection(connection);
|
||||
});
|
||||
|
||||
// Try to connect, maybe it works, maybe not,
|
||||
// but retry only once to communicate with the device for reachability check...
|
||||
connection->setCheckReachableRetries(1);
|
||||
|
||||
// Try to connect, maybe it works, maybe not...
|
||||
connection->connectDevice();
|
||||
|
||||
}
|
||||
|
||||
void HuaweiFusionSolarDiscovery::cleanupConnection(HuaweiFusionSolar *connection)
|
||||
@ -160,7 +160,6 @@ void HuaweiFusionSolarDiscovery::finishDiscovery()
|
||||
|
||||
qCInfo(dcHuawei()) << "Discovery: Finished the discovery process. Found" << m_discoveryResults.count()
|
||||
<< "inverters in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
||||
m_gracePeriodTimer.stop();
|
||||
|
||||
emit discoveryFinished();
|
||||
}
|
||||
|
||||
@ -55,7 +55,6 @@ private:
|
||||
quint16 m_port;
|
||||
quint16 m_modbusAddress;
|
||||
|
||||
QTimer m_gracePeriodTimer;
|
||||
QDateTime m_startDateTime;
|
||||
|
||||
NetworkDeviceInfos m_networkDeviceInfos;
|
||||
|
||||
@ -278,35 +278,35 @@ def writeTestReachabilityImplementationsRtu(fileDescriptor, className, registerD
|
||||
|
||||
writeLine(fileDescriptor, 'void %s::testReachability()' % (className))
|
||||
writeLine(fileDescriptor, '{')
|
||||
writeLine(fileDescriptor, ' if (m_testRechableReply)')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply)')
|
||||
writeLine(fileDescriptor, ' return;')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' // Try to read the check reachability register %s in order to verify if the communication is working or not.' % checkReachableRegister['id'])
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "--> Test reachability by reading \\"%s\\" register:" << %s << "size:" << %s;' % (className, checkReachableRegister['description'], checkReachableRegister['address'], checkReachableRegister['size']))
|
||||
writeLine(fileDescriptor, ' m_testRechableReply = read%s();' % (propertyName[0].upper() + propertyName[1:]))
|
||||
writeLine(fileDescriptor, ' if (!m_testRechableReply) {')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply = read%s();' % (propertyName[0].upper() + propertyName[1:]))
|
||||
writeLine(fileDescriptor, ' if (!m_checkRechableReply) {')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "Error occurred verifying reachability by reading \\"%s\\" register";' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' emit checkReachabilityFailed();')
|
||||
writeLine(fileDescriptor, ' onReachabilityCheckFailed();')
|
||||
writeLine(fileDescriptor, ' return;')
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' if (m_testRechableReply->isFinished()) {')
|
||||
writeLine(fileDescriptor, ' m_testRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' emit checkReachabilityFailed();')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply->isFinished()) {')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' onReachabilityCheckFailed();')
|
||||
writeLine(fileDescriptor, ' return;')
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(m_testRechableReply, &ModbusRtuReply::finished, this, [this](){')
|
||||
writeLine(fileDescriptor, ' connect(m_checkRechableReply, &ModbusRtuReply::finished, this, [this](){')
|
||||
writeLine(fileDescriptor, ' // Note: we don\'t care about the result here, only the error')
|
||||
writeLine(fileDescriptor, ' handleModbusError(m_testRechableReply->error());')
|
||||
writeLine(fileDescriptor, ' if (m_testRechableReply->error() != ModbusRtuReply::NoError)')
|
||||
writeLine(fileDescriptor, ' emit checkReachabilityFailed();')
|
||||
writeLine(fileDescriptor, ' handleModbusError(m_checkRechableReply->error());')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply->error() != ModbusRtuReply::NoError)')
|
||||
writeLine(fileDescriptor, ' onReachabilityCheckFailed();')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' m_testRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(m_testRechableReply, &ModbusRtuReply::errorOccurred, this, [this] (ModbusRtuReply::Error error){')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "ModbusRtu reply error occurred while verifying reachability by reading \\"%s\\" register" << error << m_testRechableReply->errorString();' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' connect(m_checkRechableReply, &ModbusRtuReply::errorOccurred, this, [this] (ModbusRtuReply::Error error){')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "ModbusRtu reply error occurred while verifying reachability by reading \\"%s\\" register" << error << m_checkRechableReply->errorString();' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor, '}')
|
||||
writeLine(fileDescriptor)
|
||||
|
||||
@ -280,36 +280,36 @@ def writeTestReachabilityImplementationsTcp(fileDescriptor, className, registerD
|
||||
|
||||
writeLine(fileDescriptor, 'void %s::testReachability()' % (className))
|
||||
writeLine(fileDescriptor, '{')
|
||||
writeLine(fileDescriptor, ' if (m_testRechableReply)')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply)')
|
||||
writeLine(fileDescriptor, ' return;')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' // Try to read the check reachability register %s in order to verify if the communication is working or not.' % checkReachableRegister['id'])
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "--> Test reachability by reading \\"%s\\" register:" << %s << "size:" << %s;' % (className, checkReachableRegister['description'], checkReachableRegister['address'], checkReachableRegister['size']))
|
||||
writeLine(fileDescriptor, ' m_testRechableReply = read%s();' % (propertyName[0].upper() + propertyName[1:]))
|
||||
writeLine(fileDescriptor, ' if (!m_testRechableReply) {')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply = read%s();' % (propertyName[0].upper() + propertyName[1:]))
|
||||
writeLine(fileDescriptor, ' if (!m_checkRechableReply) {')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "Error occurred verifying reachability by reading \\"%s\\" register";' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' emit checkReachabilityFailed();')
|
||||
writeLine(fileDescriptor, ' onReachabilityCheckFailed();')
|
||||
writeLine(fileDescriptor, ' return;')
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' if (m_testRechableReply->isFinished()) {')
|
||||
writeLine(fileDescriptor, ' m_testRechableReply->deleteLater(); // Broadcast reply returns immediatly')
|
||||
writeLine(fileDescriptor, ' m_testRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' emit checkReachabilityFailed();')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply->isFinished()) {')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply->deleteLater(); // Broadcast reply returns immediatly')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' onReachabilityCheckFailed();')
|
||||
writeLine(fileDescriptor, ' return;')
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(m_testRechableReply, &QModbusReply::finished, this, [this](){')
|
||||
writeLine(fileDescriptor, ' handleModbusError(m_testRechableReply->error());')
|
||||
writeLine(fileDescriptor, ' if (m_testRechableReply->error() != QModbusDevice::NoError)')
|
||||
writeLine(fileDescriptor, ' emit checkReachabilityFailed();')
|
||||
writeLine(fileDescriptor, ' connect(m_checkRechableReply, &QModbusReply::finished, this, [this](){')
|
||||
writeLine(fileDescriptor, ' handleModbusError(m_checkRechableReply->error());')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply->error() != QModbusDevice::NoError)')
|
||||
writeLine(fileDescriptor, ' onReachabilityCheckFailed();')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' m_testRechableReply->deleteLater();')
|
||||
writeLine(fileDescriptor, ' m_testRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply->deleteLater();')
|
||||
writeLine(fileDescriptor, ' m_checkRechableReply = nullptr;')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(m_testRechableReply, &QModbusReply::errorOccurred, this, [this] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "Modbus reply error occurred while verifying reachability by reading \\"%s\\" register" << error << m_testRechableReply->errorString();' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' connect(m_checkRechableReply, &QModbusReply::errorOccurred, this, [this] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "Modbus reply error occurred while verifying reachability by reading \\"%s\\" register" << error << m_checkRechableReply->errorString();' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor, '}')
|
||||
writeLine(fileDescriptor)
|
||||
|
||||
@ -71,6 +71,9 @@ def writeTcpHeaderFile():
|
||||
writeLine(headerFile, ' ModbusDataUtils::ByteOrder endianness() const;')
|
||||
writeLine(headerFile, ' void setEndianness(ModbusDataUtils::ByteOrder endianness);')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' uint checkReachableRetries() const;')
|
||||
writeLine(headerFile, ' void setCheckReachableRetries(uint checkReachableRetries);')
|
||||
writeLine(headerFile)
|
||||
|
||||
# Write registers get method declarations
|
||||
writePropertyGetSetMethodDeclarationsTcp(headerFile, registerJson['registers'])
|
||||
@ -108,6 +111,7 @@ def writeTcpHeaderFile():
|
||||
writeLine(headerFile, 'signals:')
|
||||
writeLine(headerFile, ' void reachableChanged(bool reachable);')
|
||||
writeLine(headerFile, ' void checkReachabilityFailed();')
|
||||
writeLine(headerFile, ' void checkReachableRetriesChanged(uint checkReachableRetries);')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' void initializationFinished(bool success);')
|
||||
writeLine(headerFile, ' void updateFinished();')
|
||||
@ -145,7 +149,11 @@ def writeTcpHeaderFile():
|
||||
writeLine(headerFile, 'private:')
|
||||
writeLine(headerFile, ' ModbusDataUtils::ByteOrder m_endianness = ModbusDataUtils::ByteOrder%s;' % endianness)
|
||||
writeLine(headerFile, ' quint16 m_slaveId = 1;')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' bool m_reachable = false;')
|
||||
writeLine(headerFile, ' QModbusReply *m_checkRechableReply = nullptr;')
|
||||
writeLine(headerFile, ' uint m_checkReachableRetries = 0;')
|
||||
writeLine(headerFile, ' uint m_checkReachableRetriesCount = 0;')
|
||||
writeLine(headerFile, ' bool m_communicationWorking = false;')
|
||||
writeLine(headerFile, ' quint8 m_communicationFailedMax = %s;' % (errorLimitUntilNotReachable))
|
||||
writeLine(headerFile, ' quint8 m_communicationFailedCounter = 0;')
|
||||
@ -159,7 +167,7 @@ def writeTcpHeaderFile():
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' void verifyUpdateFinished();')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' QModbusReply *m_testRechableReply = nullptr;')
|
||||
writeLine(headerFile, ' void onReachabilityCheckFailed();')
|
||||
writeLine(headerFile, ' void evaluateReachableState();')
|
||||
|
||||
# End of class
|
||||
@ -180,6 +188,8 @@ def writeTcpSourceFile():
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, '#include "%s"' % headerFileName)
|
||||
writeLine(sourceFile, '#include <loggingcategories.h>')
|
||||
writeLine(sourceFile, '#include <math.h>')
|
||||
writeLine(sourceFile, '#include <QTimer>')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, 'NYMEA_LOGGING_CATEGORY(dc%s, "%s")' % (className, className))
|
||||
writeLine(sourceFile)
|
||||
@ -197,11 +207,13 @@ def writeTcpSourceFile():
|
||||
writeLine(sourceFile, ' m_pendingUpdateReplies.clear();')
|
||||
writeLine(sourceFile, ' m_communicationWorking = false;')
|
||||
writeLine(sourceFile, ' m_communicationFailedCounter = 0;')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount = 0;')
|
||||
writeLine(sourceFile, ' testReachability();')
|
||||
writeLine(sourceFile, ' } else {')
|
||||
writeLine(sourceFile, ' qCWarning(dc%s()) << "Modbus TCP connection diconnected from" << m_hostAddress.toString() << ". The connection is not reachable any more.";' % (className))
|
||||
writeLine(sourceFile, ' m_communicationWorking = false;')
|
||||
writeLine(sourceFile, ' m_communicationFailedCounter = 0;')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount = 0;')
|
||||
writeLine(sourceFile, ' }')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' evaluateReachableState();')
|
||||
@ -215,6 +227,22 @@ def writeTcpSourceFile():
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'uint %s::checkReachableRetries() const' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' return m_checkReachableRetries;')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'void %s::setCheckReachableRetries(uint checkReachableRetries)' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' if (m_checkReachableRetries == checkReachableRetries)')
|
||||
writeLine(sourceFile, ' return;')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' m_checkReachableRetries = checkReachableRetries;')
|
||||
writeLine(sourceFile, ' emit checkReachableRetriesChanged(m_checkReachableRetries);')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'ModbusDataUtils::ByteOrder %s::endianness() const' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' return m_endianness;')
|
||||
@ -324,6 +352,21 @@ def writeTcpSourceFile():
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'void %s::onReachabilityCheckFailed()' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount++;')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' if (m_checkReachableRetriesCount <= m_checkReachableRetries) {')
|
||||
writeLine(sourceFile, ' qCDebug(dc%s()) << "Reachability test failed. Retry in on second" << m_checkReachableRetriesCount << "/" << m_checkReachableRetries;' % (className))
|
||||
writeLine(sourceFile, ' QTimer::singleShot(1000, this, &%s::testReachability);' % (className))
|
||||
writeLine(sourceFile, ' return;')
|
||||
writeLine(sourceFile, ' }')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' // The test reachability method failed, not retrying any more')
|
||||
writeLine(sourceFile, ' emit checkReachabilityFailed();')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'void %s::evaluateReachableState()' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' bool reachable = m_communicationWorking && connected();')
|
||||
@ -332,6 +375,7 @@ def writeTcpSourceFile():
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' m_reachable = reachable;')
|
||||
writeLine(sourceFile, ' emit reachableChanged(m_reachable);')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount = 0;')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
@ -395,6 +439,9 @@ def writeRtuHeaderFile():
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' bool reachable() const;')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' uint checkReachableRetries() const;')
|
||||
writeLine(headerFile, ' void setCheckReachableRetries(uint checkReachableRetries);')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' ModbusDataUtils::ByteOrder endianness() const;')
|
||||
writeLine(headerFile, ' void setEndianness(ModbusDataUtils::ByteOrder endianness);')
|
||||
writeLine(headerFile)
|
||||
@ -433,6 +480,7 @@ def writeRtuHeaderFile():
|
||||
writeLine(headerFile, 'signals:')
|
||||
writeLine(headerFile, ' void reachableChanged(bool reachable);')
|
||||
writeLine(headerFile, ' void checkReachabilityFailed();')
|
||||
writeLine(headerFile, ' void checkReachableRetriesChanged(uint checkReachableRetries);')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' void initializationFinished(bool success);')
|
||||
writeLine(headerFile, ' void updateFinished();')
|
||||
@ -471,7 +519,11 @@ def writeRtuHeaderFile():
|
||||
writeLine(headerFile, ' ModbusRtuMaster *m_modbusRtuMaster = nullptr;')
|
||||
writeLine(headerFile, ' ModbusDataUtils::ByteOrder m_endianness = ModbusDataUtils::ByteOrder%s;' % endianness)
|
||||
writeLine(headerFile, ' quint16 m_slaveId = 1;')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' bool m_reachable = false;')
|
||||
writeLine(headerFile, ' ModbusRtuReply *m_checkRechableReply = nullptr;')
|
||||
writeLine(headerFile, ' uint m_checkReachableRetries = 0;')
|
||||
writeLine(headerFile, ' uint m_checkReachableRetriesCount = 0;')
|
||||
writeLine(headerFile, ' bool m_communicationWorking = false;')
|
||||
writeLine(headerFile, ' quint8 m_communicationFailedMax = %s;' % (errorLimitUntilNotReachable))
|
||||
writeLine(headerFile, ' quint8 m_communicationFailedCounter = 0;')
|
||||
@ -485,7 +537,7 @@ def writeRtuHeaderFile():
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' void verifyUpdateFinished();')
|
||||
writeLine(headerFile)
|
||||
writeLine(headerFile, ' ModbusRtuReply *m_testRechableReply = nullptr;')
|
||||
writeLine(headerFile, ' void onReachabilityCheckFailed();')
|
||||
writeLine(headerFile, ' void evaluateReachableState();')
|
||||
|
||||
|
||||
@ -508,6 +560,7 @@ def writeRtuSourceFile():
|
||||
writeLine(sourceFile, '#include "%s"' % headerFileName)
|
||||
writeLine(sourceFile, '#include <loggingcategories.h>')
|
||||
writeLine(sourceFile, '#include <math.h>')
|
||||
writeLine(sourceFile, '#include <QTimer>')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, 'NYMEA_LOGGING_CATEGORY(dc%s, "%s")' % (className, className))
|
||||
writeLine(sourceFile)
|
||||
@ -525,11 +578,13 @@ def writeRtuSourceFile():
|
||||
writeLine(sourceFile, ' m_pendingUpdateReplies.clear();')
|
||||
writeLine(sourceFile, ' m_communicationWorking = false;')
|
||||
writeLine(sourceFile, ' m_communicationFailedCounter = 0;')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount = 0;')
|
||||
writeLine(sourceFile, ' testReachability();')
|
||||
writeLine(sourceFile, ' } else {')
|
||||
writeLine(sourceFile, ' qCWarning(dc%s()) << "Modbus RTU resource" << m_modbusRtuMaster->serialPort() << "disconnected. The connection is not reachable any more.";' % (className))
|
||||
writeLine(sourceFile, ' m_communicationWorking = false;')
|
||||
writeLine(sourceFile, ' m_communicationFailedCounter = 0;')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount = 0;')
|
||||
writeLine(sourceFile, ' }')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' evaluateReachableState();')
|
||||
@ -554,6 +609,22 @@ def writeRtuSourceFile():
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'uint %s::checkReachableRetries() const' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' return m_checkReachableRetries;')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'void %s::setCheckReachableRetries(uint checkReachableRetries)' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' if (m_checkReachableRetries == checkReachableRetries)')
|
||||
writeLine(sourceFile, ' return;')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' m_checkReachableRetries = checkReachableRetries;')
|
||||
writeLine(sourceFile, ' emit checkReachableRetriesChanged(m_checkReachableRetries);')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'ModbusDataUtils::ByteOrder %s::endianness() const' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' return m_endianness;')
|
||||
@ -664,6 +735,21 @@ def writeRtuSourceFile():
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'void %s::onReachabilityCheckFailed()' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount++;')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' if (m_checkReachableRetriesCount <= m_checkReachableRetries) {')
|
||||
writeLine(sourceFile, ' qCDebug(dc%s()) << "Reachability test failed. Retry in on second" << m_checkReachableRetriesCount << "/" << m_checkReachableRetries;' % (className))
|
||||
writeLine(sourceFile, ' QTimer::singleShot(1000, this, &%s::testReachability);' % (className))
|
||||
writeLine(sourceFile, ' return;')
|
||||
writeLine(sourceFile, ' }')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' // The test reachability method failed, not retrying any more')
|
||||
writeLine(sourceFile, ' emit checkReachabilityFailed();')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
writeLine(sourceFile, 'void %s::evaluateReachableState()' % (className))
|
||||
writeLine(sourceFile, '{')
|
||||
writeLine(sourceFile, ' bool reachable = m_communicationWorking && m_modbusRtuMaster->connected();')
|
||||
@ -672,6 +758,7 @@ def writeRtuSourceFile():
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, ' m_reachable = reachable;')
|
||||
writeLine(sourceFile, ' emit reachableChanged(m_reachable);')
|
||||
writeLine(sourceFile, ' m_checkReachableRetriesCount = 0;')
|
||||
writeLine(sourceFile, '}')
|
||||
writeLine(sourceFile)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user