From 5c0eeaa58bc536cc7fc53fab7c5c747abaecbbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Wed, 19 Feb 2020 17:11:43 -0300 Subject: [PATCH] devicemanager: Add max number of fails in communication and device serial filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- src/devicemanager/devicemanager.cpp | 43 +++++++++++++++++++++++++++-- src/devicemanager/devicemanager.h | 2 ++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/devicemanager/devicemanager.cpp b/src/devicemanager/devicemanager.cpp index d5347eed9..d8ab169c8 100644 --- a/src/devicemanager/devicemanager.cpp +++ b/src/devicemanager/devicemanager.cpp @@ -50,6 +50,7 @@ void DeviceManager::append(const LinkConfiguration& linkConf, const QString& dev _sensors[Connected].append(false); _sensors[DetectorName].append(detectorName); _sensors[Name].append(deviceName); + _sensors[UnavailableCounter].append(0); const auto& indexRow = index(line); endInsertRows(); @@ -151,19 +152,57 @@ void DeviceManager::updateAvailableConnections( const QVector& availableLinkConfigurations, const QString& detector) { qCDebug(DEVICEMANAGER) << "Available devices:" << availableLinkConfigurations; - // Make all connections unavailable by default + for (int i {0}; i < _sensors[Available].size(); i++) { const auto linkConf = _sensors[Connection][i].value>(); if (linkConf->isSimulation() || _sensors[DetectorName][i] != detector) { continue; } + + // Make all connections unavailable by default _sensors[Available][i] = false; const auto indexRow = index(i); emit dataChanged(indexRow, indexRow, _roles); } + // Check if the configuration already exists for a sensor + // Serial ports does not support multiple devices connected + // Some sensors, like Ping1D, can fail to answer a ABR procedure for (const auto& link : availableLinkConfigurations) { - append(link, PingHelper::nameFromDeviceType(link.deviceType()), detector); + const bool sameSerialDevice = std::any_of( + _sensors[Connection].cbegin(), _sensors[Connection].cend(), [&link](const QVariant& variantLink) { + const auto sensorLink = variantLink.value>().get(); + qCDebug(DEVICEMANAGER) << "Device" << sensorLink + << "already already provided by a different connection:" << link; + return link.serialPort() == sensorLink->serialPort() && link != *sensorLink; + }); + + if (!sameSerialDevice) { + append(link, PingHelper::nameFromDeviceType(link.deviceType()), detector); + } + } + + // We'll let the link to fail the communication attempt "a max number of fails" before making it unavailable + // This is necessary to avoid any problem related to automatic baud rates problem from the sensor side. + static const int maxNumberOfFails = 3; + for (int i {0}; i < _sensors[Available].size(); i++) { + const auto linkConf = _sensors[Connection][i].value>(); + if (linkConf->isSimulation()) { + continue; + } + + const auto indexRow = index(i); + + // The sensor was detected, we can remove unavailable counter + if (_sensors[Available][i].toBool()) { + _sensors[UnavailableCounter][i] = 0; + emit dataChanged(indexRow, indexRow, _roles); + continue; + } + _sensors[Available][i] = _sensors[UnavailableCounter][i].toInt() < maxNumberOfFails; + _sensors[UnavailableCounter][i] = _sensors[UnavailableCounter][i].toInt() + 1; + + emit dataChanged(indexRow, indexRow, _roles); } } diff --git a/src/devicemanager/devicemanager.h b/src/devicemanager/devicemanager.h index af340fe2b..ad1038bb6 100644 --- a/src/devicemanager/devicemanager.h +++ b/src/devicemanager/devicemanager.h @@ -179,6 +179,7 @@ class DeviceManager : public QAbstractListModel { Connection, Name, DetectorName, + UnavailableCounter, }; QHash _roleNames { {Available, "available"}, @@ -186,6 +187,7 @@ class DeviceManager : public QAbstractListModel { {Connection, "connection"}, {Name, "name"}, {DetectorName, "detectorName"}, + {UnavailableCounter, "unavailableCounter"}, }; QSharedPointer _primarySensor;