diff --git a/rotator/drivers/HamlibRotDrv.cpp b/rotator/drivers/HamlibRotDrv.cpp index 9dc755ea..b3310624 100644 --- a/rotator/drivers/HamlibRotDrv.cpp +++ b/rotator/drivers/HamlibRotDrv.cpp @@ -84,6 +84,10 @@ HamlibRotDrv::HamlibRotDrv(const RotProfile &profile, } rig_set_debug(RIG_DEBUG_BUG); + + connect(&errorTimer, &QTimer::timeout, + this, &HamlibRotDrv::checkErrorCounter); + } HamlibRotDrv::~HamlibRotDrv() @@ -147,16 +151,10 @@ bool HamlibRotDrv::open() int status = rot_open(rot); - if ( status != RIG_OK ) - { - lastErrorText = hamlibErrorString(status); - qCDebug(runtime) << "Rot Open Error" << lastErrorText; + if ( !isRotRespOK(status, tr("Rot Open Error"), false) ) return false; - } - else - { - qCDebug(runtime) << "Rot Open - OK"; - } + + qCDebug(runtime) << "Rot Open - OK"; opened = true; @@ -243,13 +241,7 @@ void HamlibRotDrv::setPosition(double in_azimuth, double in_elevation) static_cast(newAzimuth), static_cast(newElevation)); - if ( status != RIG_OK ) - { - lastErrorText = hamlibErrorString(status); - qCWarning(runtime) << "Set Az/El error" << lastErrorText; - emit errorOccured(tr("Set Possition Error"), - lastErrorText); - } + isRotRespOK(status, tr("Set Possition Error"), false); // wait a moment because Rotators are slow and they are not possible to set and get // mode so quickly (get mode is called in the main thread's update() function @@ -261,6 +253,7 @@ void HamlibRotDrv::stopTimers() FCT_IDENTIFICATION; timer.stop(); + errorTimer.stop(); } void HamlibRotDrv::checkRotStateChange() @@ -284,6 +277,21 @@ void HamlibRotDrv::checkRotStateChange() drvLock.unlock(); } +void HamlibRotDrv::checkErrorCounter() +{ + FCT_IDENTIFICATION; + + if ( postponedErrors.isEmpty() ) + return; + + qCDebug(runtime) << postponedErrors; + + // emit only one error + auto it = postponedErrors.constBegin(); + emit errorOccured(it.key(), it.value()); + postponedErrors.clear(); +} + void HamlibRotDrv::checkChanges() { FCT_IDENTIFICATION; @@ -307,7 +315,7 @@ void HamlibRotDrv::checkAzEl() elevation_t el; int status = rot_get_position(rot, &az, &el); - if ( status == RIG_OK ) + if ( isRotRespOK(status, tr("Get Possition Error")) ) { double newAzimuth = az; double newElevation = el; @@ -328,18 +336,49 @@ void HamlibRotDrv::checkAzEl() emit positioningChanged(azimuth, elevation); } } - else - { - lastErrorText = hamlibErrorString(status); - qCWarning(runtime) << "Get AZ/EL error" << lastErrorText; - emit errorOccured(tr("Get Possition Error"), - lastErrorText); - } } else - { qCDebug(runtime) << "Get POSITION is disabled"; +} + +bool HamlibRotDrv::isRotRespOK(int errorStatus, const QString errorName, bool emitError) +{ + FCT_IDENTIFICATION; + + qCDebug(function_parameters) << errorStatus << errorName << emitError; + + if ( errorStatus == RIG_OK ) // there are no special codes for ROT, use RIG codes + { + if ( emitError ) + postponedErrors.remove(errorName); + return true; } + + lastErrorText = hamlibErrorString(errorStatus); + + if ( emitError ) + { + qCDebug(runtime) << "Emit Error detected"; + + if ( !RIG_IS_SOFT_ERRCODE(-errorStatus) ) + { + // hard error, emit error now + qCDebug(runtime) << "Hard Error"; + emit errorOccured(errorName, lastErrorText); + } + else + { + // soft error + postponedErrors[errorName] = lastErrorText; + + if ( !errorTimer.isActive() ) + { + qCDebug(runtime) << "Starting Error Timer"; + errorTimer.start(15 * 1000); //15s + } + } + } + return false; } serial_handshake_e HamlibRotDrv::stringToHamlibFlowControl(const QString &in_flowcontrol) @@ -384,17 +423,22 @@ QString HamlibRotDrv::hamlibErrorString(int errorCode) qCDebug(function_parameters) << errorCode; - static QRegularExpression re("[\r\n]"); - - const QStringList &errorList = QString(rigerror(errorCode)).split(re); QString ret; + QString detail(rigerror(errorCode)); + +#if ( HAMLIBVERSION_MAJOR >= 4 && HAMLIBVERSION_MINOR >= 5 ) + // The rigerror has different behavior since 4.5. It contains the stack trace in the first part + // Need to use rigerror2 + ret = QString(rigerror2(errorCode)); +#else + static QRegularExpression re("[\r\n]"); + QStringList errorList = detail.split(re); if ( errorList.size() >= 1 ) - { ret = errorList.at(0); - } - - qCDebug(runtime) << ret; +#endif + qWarning() << "Detail" << detail; + qCWarning(runtime) << ret; return ret; } diff --git a/rotator/drivers/HamlibRotDrv.h b/rotator/drivers/HamlibRotDrv.h index bf702ea0..b274c9b9 100644 --- a/rotator/drivers/HamlibRotDrv.h +++ b/rotator/drivers/HamlibRotDrv.h @@ -24,12 +24,16 @@ class HamlibRotDrv : public GenericRotDrv private slots: void checkRotStateChange(); + void checkErrorCounter(); private: static int addRig(const struct rot_caps* caps, void* data); void checkChanges(); void checkAzEl(); + bool isRotRespOK(int errorStatus, + const QString errorName, + bool emitError = true); serial_handshake_e stringToHamlibFlowControl(const QString &in_flowcontrol); serial_parity_e stringToHamlibParity(const QString &in_parity); @@ -38,9 +42,11 @@ private slots: ROT* rot; QTimer timer; + QTimer errorTimer; QMutex drvLock; bool forceSendState; + QHashpostponedErrors; }; #endif // QLOG_ROTATOR_DRIVERS_HAMLIBROTDRV_H