diff --git a/qml/DeviceManagerViewer.qml b/qml/DeviceManagerViewer.qml index 21bdcbf4a..67e0832c9 100644 --- a/qml/DeviceManagerViewer.qml +++ b/qml/DeviceManagerViewer.qml @@ -209,7 +209,7 @@ PingPopup { Label { Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter - text: connection.typeToString() + " " + connection.createConfString() + text: connection.typeToString() + " " + connection.argsAsConst()[0] } StatusIndicator { diff --git a/src/devicemanager/devicemanager.cpp b/src/devicemanager/devicemanager.cpp index ac226b3fc..2252f9e76 100644 --- a/src/devicemanager/devicemanager.cpp +++ b/src/devicemanager/devicemanager.cpp @@ -29,8 +29,8 @@ DeviceManager::DeviceManager() void DeviceManager::append(const LinkConfiguration& linkConf, const QString& deviceName, const QString& detectorName) { for (int i {0}; i < _sensors[Connection].size(); i++) { - auto vectorLinkConf = _sensors[Connection][i].value>().get(); - if (*vectorLinkConf == linkConf) { + const auto vectorLinkConf = _sensors[Connection][i].value>(); + if (!vectorLinkConf.isNull() && *vectorLinkConf == linkConf) { qCDebug(DEVICEMANAGER) << "Connection configuration already exist for:" << _sensors[Name][i] << linkConf << linkConf.argsAsConst(); _sensors[Available][i] = true; @@ -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++) { - auto linkConf = _sensors[Connection][i].value>(); + 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>(); + 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; diff --git a/src/link/linkconfiguration.cpp b/src/link/linkconfiguration.cpp index 9ad67b536..5c55c7d1b 100644 --- a/src/link/linkconfiguration.cpp +++ b/src/link/linkconfiguration.cpp @@ -145,6 +145,8 @@ bool operator==(const LinkConfiguration& first, const LinkConfiguration& second) && (firstLinkconf.deviceType == secondLinkconf.deviceType); } +bool operator!=(const LinkConfiguration& first, const LinkConfiguration& second) { return !(first == second); } + QDebug operator<<(QDebug d, const LinkConfiguration& other) { QString text(QStringLiteral("LinkConfiguration{Name: %1, Sensor: %2, LinkType: %3, Arguments: (%4)}")); diff --git a/src/link/linkconfiguration.h b/src/link/linkconfiguration.h index c7a54fd27..34ce4ba4c 100644 --- a/src/link/linkconfiguration.h +++ b/src/link/linkconfiguration.h @@ -319,6 +319,7 @@ class LinkConfiguration : public QObject { }; bool operator==(const LinkConfiguration& first, const LinkConfiguration& second); +bool operator!=(const LinkConfiguration& first, const LinkConfiguration& second); QDebug operator<<(QDebug d, const LinkConfiguration& other); QDataStream& operator<<(QDataStream& out, const LinkConfiguration linkConfiguration); QDataStream& operator>>(QDataStream& in, LinkConfiguration& linkConfiguration); diff --git a/src/sensor/protocoldetector.cpp b/src/sensor/protocoldetector.cpp index 7f0464fd9..1c10bea64 100644 --- a/src/sensor/protocoldetector.cpp +++ b/src/sensor/protocoldetector.cpp @@ -68,6 +68,7 @@ void ProtocolDetector::doScan() // Scan until something is connected while (_active) { auto linksConf = updateLinkConfigurations(_linkConfigs); + qCDebug(PING_PROTOCOL_PROTOCOLDETECTOR) << "Looking for devices in:" << linksConf; for (LinkConfiguration& tryLinkConf : linksConf) { if (!_active) { break; @@ -116,13 +117,9 @@ QVector ProtocolDetector::updateLinkConfigurations(QVector