add IP address list for TCP drivers

This commit is contained in:
Jan Käberich 2023-02-12 22:58:45 +01:00
parent 9b5bb1678c
commit 952c43073e
10 changed files with 255 additions and 34 deletions

View File

@ -7,6 +7,7 @@
#include <QDateTime> #include <QDateTime>
SSA3000XDriver::SSA3000XDriver() SSA3000XDriver::SSA3000XDriver()
: DeviceTCPDriver("SSA3000X")
{ {
diffGen = new TraceDifferenceGenerator<SpectrumPoint, 10>([=](const SpectrumPoint &p){ diffGen = new TraceDifferenceGenerator<SpectrumPoint, 10>([=](const SpectrumPoint &p){
SAMeasurement m; SAMeasurement m;
@ -15,7 +16,6 @@ SSA3000XDriver::SSA3000XDriver()
m.measurements["PORT1"] = pow(10.0, p.dBm / 20.0); m.measurements["PORT1"] = pow(10.0, p.dBm / 20.0);
emit SAmeasurementReceived(m); emit SAmeasurementReceived(m);
}); });
searchAddresses.push_back(QHostAddress("192.168.22.2"));
connect(&traceTimer, &QTimer::timeout, this, &SSA3000XDriver::extractTracePoints); connect(&traceTimer, &QTimer::timeout, this, &SSA3000XDriver::extractTracePoints);
traceTimer.setSingleShot(true); traceTimer.setSingleShot(true);
} }
@ -32,7 +32,7 @@ std::set<QString> SSA3000XDriver::GetAvailableDevices()
// attempt to establish a connection to check if the device is available and extract the serial number // attempt to establish a connection to check if the device is available and extract the serial number
detectedDevices.clear(); detectedDevices.clear();
auto sock = QTcpSocket(); auto sock = QTcpSocket();
for(auto address : searchAddresses) { for(auto address : getSearchAddresses()) {
sock.connectToHost(address, 5024); sock.connectToHost(address, 5024);
if(sock.waitForConnected(50)) { if(sock.waitForConnected(50)) {
// connection successful // connection successful
@ -54,8 +54,6 @@ std::set<QString> SSA3000XDriver::GetAvailableDevices()
} }
} }
sock.disconnect(); sock.disconnect();
} else {
qDebug() << "SSA3000X failed to connect";
} }
} }
return ret; return ret;
@ -113,7 +111,7 @@ bool SSA3000XDriver::connectTo(QString serial)
info.supportedFeatures.insert(DeviceDriver::Feature::SA); info.supportedFeatures.insert(DeviceDriver::Feature::SA);
info.supportedFeatures.insert(DeviceDriver::Feature::SATrackingGenerator); info.supportedFeatures.insert(DeviceDriver::Feature::SATrackingGenerator);
info.supportedFeatures.insert(DeviceDriver::Feature::Generator); info.supportedFeatures.insert(DeviceDriver::Feature::Generator);
info.supportedFeatures.insert(DeviceDriver::Feature::ExtRefIn); // info.supportedFeatures.insert(DeviceDriver::Feature::ExtRefIn);
double maxFreq = 0; double maxFreq = 0;
if(info.hardware_version == "SSA3032X") { if(info.hardware_version == "SSA3032X") {
@ -146,27 +144,6 @@ bool SSA3000XDriver::connectTo(QString serial)
emit InfoUpdated(); emit InfoUpdated();
// // sockets are connected now
// dataBuffer.clear();
// logBuffer.clear();
// connect(&dataSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &LibreVNATCPDriver::ConnectionLost, Qt::QueuedConnection);
// connect(&logSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &LibreVNATCPDriver::ConnectionLost, Qt::QueuedConnection);
// qInfo() << "TCP connection established" << flush;
// this->serial = serial;
// connected = true;
// connect(&dataSocket, &QTcpSocket::readyRead, this, &LibreVNATCPDriver::ReceivedData, Qt::UniqueConnection);
// connect(&logSocket, &QTcpSocket::readyRead, this, &LibreVNATCPDriver::ReceivedLog, Qt::UniqueConnection);
// connect(&transmissionTimer, &QTimer::timeout, this, &LibreVNATCPDriver::transmissionTimeout, Qt::UniqueConnection);
// connect(this, &LibreVNATCPDriver::receivedAnswer, this, &LibreVNATCPDriver::transmissionFinished, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
// connect(this, &LibreVNATCPDriver::receivedPacket, this, &LibreVNATCPDriver::handleReceivedPacket, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
// transmissionTimer.setSingleShot(true);
// transmissionActive = false;
// sendWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
// sendWithoutPayload(Protocol::PacketType::RequestDeviceStatus);
// updateIFFrequencies();
return true; return true;
} }
@ -295,6 +272,7 @@ bool SSA3000XDriver::setIdle(std::function<void (bool)> cb)
if(cb) { if(cb) {
cb(true); cb(true);
} }
return true;
} }
QStringList SSA3000XDriver::availableExtRefInSettings() QStringList SSA3000XDriver::availableExtRefInSettings()

View File

@ -1,7 +1,7 @@
#ifndef SSA3000XDRIVER_H #ifndef SSA3000XDRIVER_H
#define SSA3000XDRIVER_H #define SSA3000XDRIVER_H
#include "../devicedriver.h" #include "../devicetcpdriver.h"
#include "../tracedifferencegenerator.h" #include "../tracedifferencegenerator.h"
@ -9,7 +9,7 @@
#include <QTcpSocket> #include <QTcpSocket>
#include <QTimer> #include <QTimer>
class SSA3000XDriver : public DeviceDriver class SSA3000XDriver : public DeviceTCPDriver
{ {
public: public:
SSA3000XDriver(); SSA3000XDriver();
@ -167,7 +167,6 @@ private:
QTimer traceTimer; QTimer traceTimer;
TraceDifferenceGenerator<SpectrumPoint, 10> *diffGen; TraceDifferenceGenerator<SpectrumPoint, 10> *diffGen;
std::vector<QHostAddress> searchAddresses;
std::map<QString, QHostAddress> detectedDevices; std::map<QString, QHostAddress> detectedDevices;
}; };

View File

@ -0,0 +1,89 @@
#include "devicetcpdriver.h"
#include "ui_devicetcpdriversettings.h"
#include <QLineEdit>
DeviceTCPDriver::DeviceTCPDriver(QString driverName)
{
specificSettings.push_back(Savable::SettingDescription(&searchAddressString, driverName+".searchAddressString", ""));
}
QWidget *DeviceTCPDriver::createSettingsWidget()
{
parseSearchAddressString();
auto w = new QWidget();
auto ui = new Ui::DeviceTCPDriverSettingsWidget;
ui->setupUi(w);
ui->list->clear();
for(auto &a : searchAddresses) {
auto item = new QListWidgetItem();
if(a.isNull()) {
item->setText("0.0.0.0");
} else {
item->setText(a.toString());
}
item->setFlags(item->flags() | Qt::ItemIsEditable);
ui->list->addItem(item);
}
connect(ui->list->itemDelegate(), &QAbstractItemDelegate::commitData, this, [=](QWidget *pLineEdit) {
QString strNewText = reinterpret_cast<QLineEdit*>(pLineEdit)->text();
int nRow = ui->list->currentRow();
auto address = QHostAddress(strNewText);
if(!address.isNull()) {
// valid IP
searchAddresses[nRow] = address;
updateSearchAddressString();
}
ui->list->item(nRow)->setText(searchAddresses[nRow].toString());
});
connect(ui->add, &QPushButton::clicked, [=](){
searchAddresses.push_back(QHostAddress("0.0.0.0"));
auto item = new QListWidgetItem(searchAddresses.back().toString());
item->setFlags(item->flags() | Qt::ItemIsEditable);
ui->list->addItem(item);
updateSearchAddressString();
});
connect(ui->remove, &QPushButton::clicked, [=](){
auto index = ui->list->currentRow();
if(index >= 0 && index < (int) searchAddresses.size()) {
delete ui->list->takeItem(index);
searchAddresses.erase(searchAddresses.begin() + index);
updateSearchAddressString();
}
});
return w;
}
std::vector<QHostAddress> DeviceTCPDriver::getSearchAddresses()
{
parseSearchAddressString();
return searchAddresses;
}
void DeviceTCPDriver::parseSearchAddressString()
{
QStringList list = searchAddressString.split(",");
searchAddresses.clear();
for(auto &l : list) {
searchAddresses.push_back(QHostAddress(l));
}
}
void DeviceTCPDriver::updateSearchAddressString()
{
searchAddressString = "";
for(auto &a : searchAddresses) {
searchAddressString += a.toString();
searchAddressString += ",";
}
if(searchAddressString.length() > 0) {
// remove trailing comma
searchAddressString.chop(1);
}
}

View File

@ -0,0 +1,46 @@
#ifndef DEVICETCPDRIVER_H
#define DEVICETCPDRIVER_H
#include "devicedriver.h"
#include <QHostAddress>
/**
* @brief DeviceTCPDriver
*
* This is a convenience class for device drivers that are TCP/IP based and need to search for
* connected devices at specific IP addresses. If this is the case for your device driver,
* inherit from DeviceTCPDriver instead of DeviceDriver.
* When searching for connected devices, search the IP addresses as given by getSearchAddresses().
* When overwriting createSettingsWidget in your derived driver, include the widget returned
* by DeviceTCPDriver::createSettingsWidget if you want the search addresses to be editable by
* the user.
*/
class DeviceTCPDriver : public DeviceDriver
{
public:
DeviceTCPDriver(QString driverName);
/**
* @brief Returns a widget to edit the driver specific settings.
*
* The widget is displayed in the global settings dialog and allows the user to edit the settings
* specific to this driver. The application takes ownership of the widget after returning,
* create a new widget for every call to this function. If the driver has no specific settings
* or the settings do not need to be editable by the user, return a nullptr. In this case, no
* page for this driver is created in the settings dialog
* @return newly constructed settings widget or nullptr
*/
virtual QWidget *createSettingsWidget() override;
protected:
std::vector<QHostAddress> getSearchAddresses();
private:
void parseSearchAddressString();
void updateSearchAddressString();
std::vector<QHostAddress> searchAddresses;
QString searchAddressString;
};
#endif // DEVICETCPDRIVER_H

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DeviceTCPDriverSettingsWidget</class>
<widget class="QWidget" name="DeviceTCPDriverSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>252</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>IP addresses to search for devices:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<widget class="QListWidget" name="list"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<widget class="QPushButton" name="add">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="list-add" resource="../icons.qrc">
<normaloff>:/icons/add.png</normaloff>
<normalon>:/icons/add.png</normalon>:/icons/add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="remove">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="list-remove" resource="../icons.qrc">
<normaloff>:/icons/remove.png</normaloff>
<normalon>:/icons/remove.png</normalon>:/icons/remove.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -36,6 +36,7 @@ HEADERS += \
Device/SSA3000X/ssa3000xdriver.h \ Device/SSA3000X/ssa3000xdriver.h \
Device/devicedriver.h \ Device/devicedriver.h \
Device/devicelog.h \ Device/devicelog.h \
Device/devicetcpdriver.h \
Device/tracedifferencegenerator.h \ Device/tracedifferencegenerator.h \
Generator/generator.h \ Generator/generator.h \
Generator/signalgenwidget.h \ Generator/signalgenwidget.h \
@ -189,6 +190,7 @@ SOURCES += \
Device/SSA3000X/ssa3000xdriver.cpp \ Device/SSA3000X/ssa3000xdriver.cpp \
Device/devicedriver.cpp \ Device/devicedriver.cpp \
Device/devicelog.cpp \ Device/devicelog.cpp \
Device/devicetcpdriver.cpp \
Generator/generator.cpp \ Generator/generator.cpp \
Generator/signalgenwidget.cpp \ Generator/signalgenwidget.cpp \
SpectrumAnalyzer/spectrumanalyzer.cpp \ SpectrumAnalyzer/spectrumanalyzer.cpp \
@ -325,6 +327,7 @@ FORMS += \
Device/LibreVNA/librevnadriversettingswidget.ui \ Device/LibreVNA/librevnadriversettingswidget.ui \
Device/LibreVNA/manualcontroldialog.ui \ Device/LibreVNA/manualcontroldialog.ui \
Device/devicelog.ui \ Device/devicelog.ui \
Device/devicetcpdriversettings.ui \
Generator/signalgenwidget.ui \ Generator/signalgenwidget.ui \
Tools/impedancematchdialog.ui \ Tools/impedancematchdialog.ui \
Tools/mixedmodeconversion.ui \ Tools/mixedmodeconversion.ui \

View File

@ -51,6 +51,7 @@
#include <QDebug> #include <QDebug>
#include <QStyle> #include <QStyle>
#include <QScrollArea> #include <QScrollArea>
#include <QStandardItemModel>
VNA::VNA(AppWindow *window, QString name) VNA::VNA(AppWindow *window, QString name)
: Mode(window, name, "VNA"), : Mode(window, name, "VNA"),
@ -267,7 +268,7 @@ VNA::VNA(AppWindow *window, QString name)
tb_sweep->addWidget(bSingle); tb_sweep->addWidget(bSingle);
tb_sweep->addWidget(new QLabel("Sweep type:")); tb_sweep->addWidget(new QLabel("Sweep type:"));
auto cbSweepType = new QComboBox(); cbSweepType = new QComboBox();
cbSweepType->addItem("Frequency"); cbSweepType->addItem("Frequency");
cbSweepType->addItem("Power"); cbSweepType->addItem("Power");
tb_sweep->addWidget(cbSweepType); tb_sweep->addWidget(cbSweepType);
@ -321,14 +322,14 @@ VNA::VNA(AppWindow *window, QString name)
connect(bZoomOut, &QPushButton::clicked, this, &VNA::SpanZoomOut); connect(bZoomOut, &QPushButton::clicked, this, &VNA::SpanZoomOut);
frequencySweepActions.push_back(tb_sweep->addWidget(bZoomOut)); frequencySweepActions.push_back(tb_sweep->addWidget(bZoomOut));
auto bZero = new QPushButton("0"); bZero = new QPushButton("0");
bZero->setToolTip("Zero span"); bZero->setToolTip("Zero span");
bZero->setMaximumWidth(28); bZero->setMaximumWidth(28);
bZero->setMaximumHeight(24); bZero->setMaximumHeight(24);
connect(bZero, &QPushButton::clicked, this, &VNA::SetZeroSpan); connect(bZero, &QPushButton::clicked, this, &VNA::SetZeroSpan);
frequencySweepActions.push_back(tb_sweep->addWidget(bZero)); frequencySweepActions.push_back(tb_sweep->addWidget(bZero));
auto cbLogSweep = new QCheckBox("Log"); cbLogSweep = new QCheckBox("Log");
cbLogSweep->setToolTip("Logarithmic sweep"); cbLogSweep->setToolTip("Logarithmic sweep");
connect(cbLogSweep, &QCheckBox::toggled, this, &VNA::SetLogSweep); connect(cbLogSweep, &QCheckBox::toggled, this, &VNA::SetLogSweep);
connect(this, &VNA::logSweepChanged, cbLogSweep, &QCheckBox::setChecked); connect(this, &VNA::logSweepChanged, cbLogSweep, &QCheckBox::setChecked);
@ -673,12 +674,33 @@ void VNA::deactivate()
Mode::deactivate(); Mode::deactivate();
} }
static void SetComboBoxItemEnabled(QComboBox * comboBox, int index, bool enabled)
{
auto * model = qobject_cast<QStandardItemModel*>(comboBox->model());
assert(model);
if(!model) return;
auto * item = model->item(index);
assert(item);
if(!item) return;
item->setEnabled(enabled);
}
void VNA::initializeDevice() void VNA::initializeDevice()
{ {
if(!window->getDevice()->supports(DeviceDriver::Feature::VNA)) { if(!window->getDevice()->supports(DeviceDriver::Feature::VNA)) {
InformationBox::ShowError("Unsupported", "The connected device does not support VNA mode"); InformationBox::ShowError("Unsupported", "The connected device does not support VNA mode");
return; return;
} }
cbLogSweep->setEnabled(window->getDevice()->supports(DeviceDriver::Feature::VNALogSweep));
if(!window->getDevice()->supports(DeviceDriver::Feature::VNALogSweep)) {
SetLogSweep(false);
}
bZero->setEnabled(window->getDevice()->supports(DeviceDriver::Feature::VNAZeroSpan));
SetComboBoxItemEnabled(cbSweepType, 0, window->getDevice()->supports(DeviceDriver::Feature::VNAFrequencySweep));
SetComboBoxItemEnabled(cbSweepType, 1, window->getDevice()->supports(DeviceDriver::Feature::VNAPowerSweep));
defaultCalMenu->setEnabled(true); defaultCalMenu->setEnabled(true);
connect(window->getDevice(), &DeviceDriver::VNAmeasurementReceived, this, &VNA::NewDatapoint, Qt::UniqueConnection); connect(window->getDevice(), &DeviceDriver::VNAmeasurementReceived, this, &VNA::NewDatapoint, Qt::UniqueConnection);
// Check if default calibration exists and attempt to load it // Check if default calibration exists and attempt to load it

View File

@ -156,6 +156,9 @@ private:
QString getCalStyle(); QString getCalStyle();
QString getCalToolTip(); QString getCalToolTip();
QComboBox *cbSweepType;
QCheckBox *cbLogSweep;
QPushButton *bZero;
QMenu *defaultCalMenu; QMenu *defaultCalMenu;
QAction *assignDefaultCal, *removeDefaultCal; QAction *assignDefaultCal, *removeDefaultCal;

View File

@ -1032,8 +1032,8 @@ void AppWindow::UpdateReferenceToolbar()
{ {
toolbars.reference.type->blockSignals(true); toolbars.reference.type->blockSignals(true);
toolbars.reference.outFreq->blockSignals(true); toolbars.reference.outFreq->blockSignals(true);
toolbars.reference.type->setEnabled(device || device->supports(DeviceDriver::Feature::ExtRefIn)); toolbars.reference.type->setEnabled(device && device->supports(DeviceDriver::Feature::ExtRefIn));
toolbars.reference.outFreq->setEnabled(device || device->supports(DeviceDriver::Feature::ExtRefOut)); toolbars.reference.outFreq->setEnabled(device && device->supports(DeviceDriver::Feature::ExtRefOut));
if(device) { if(device) {
// save current setting // save current setting
auto refInBuf = toolbars.reference.type->currentText(); auto refInBuf = toolbars.reference.type->currentText();

View File

@ -42,6 +42,7 @@ SOURCES += \
../LibreVNA-GUI/Device/devicelog.cpp \ ../LibreVNA-GUI/Device/devicelog.cpp \
../LibreVNA-GUI/Device/LibreVNA/devicepacketlog.cpp \ ../LibreVNA-GUI/Device/LibreVNA/devicepacketlog.cpp \
../LibreVNA-GUI/Device/LibreVNA/devicepacketlogview.cpp \ ../LibreVNA-GUI/Device/LibreVNA/devicepacketlogview.cpp \
../LibreVNA-GUI/Device/devicetcpdriver.cpp \
../LibreVNA-GUI/Generator/generator.cpp \ ../LibreVNA-GUI/Generator/generator.cpp \
../LibreVNA-GUI/Generator/signalgenwidget.cpp \ ../LibreVNA-GUI/Generator/signalgenwidget.cpp \
../LibreVNA-GUI/SpectrumAnalyzer/spectrumanalyzer.cpp \ ../LibreVNA-GUI/SpectrumAnalyzer/spectrumanalyzer.cpp \
@ -213,6 +214,7 @@ HEADERS += \
../LibreVNA-GUI/Device/devicelog.h \ ../LibreVNA-GUI/Device/devicelog.h \
../LibreVNA-GUI/Device/LibreVNA/devicepacketlog.h \ ../LibreVNA-GUI/Device/LibreVNA/devicepacketlog.h \
../LibreVNA-GUI/Device/LibreVNA/devicepacketlogview.h \ ../LibreVNA-GUI/Device/LibreVNA/devicepacketlogview.h \
../LibreVNA-GUI/Device/devicetcpdriver.h \
../LibreVNA-GUI/Generator/generator.h \ ../LibreVNA-GUI/Generator/generator.h \
../LibreVNA-GUI/Generator/signalgenwidget.h \ ../LibreVNA-GUI/Generator/signalgenwidget.h \
../LibreVNA-GUI/SpectrumAnalyzer/spectrumanalyzer.h \ ../LibreVNA-GUI/SpectrumAnalyzer/spectrumanalyzer.h \
@ -358,6 +360,7 @@ FORMS += \
../LibreVNA-GUI/Device/LibreVNA/Compound/compounddeviceeditdialog.ui \ ../LibreVNA-GUI/Device/LibreVNA/Compound/compounddeviceeditdialog.ui \
../LibreVNA-GUI/Device/devicelog.ui \ ../LibreVNA-GUI/Device/devicelog.ui \
../LibreVNA-GUI/Device/LibreVNA/devicepacketlogview.ui \ ../LibreVNA-GUI/Device/LibreVNA/devicepacketlogview.ui \
../LibreVNA-GUI/Device/devicetcpdriversettings.ui \
../LibreVNA-GUI/Generator/signalgenwidget.ui \ ../LibreVNA-GUI/Generator/signalgenwidget.ui \
../LibreVNA-GUI/Tools/impedancematchdialog.ui \ ../LibreVNA-GUI/Tools/impedancematchdialog.ui \
../LibreVNA-GUI/Tools/mixedmodeconversion.ui \ ../LibreVNA-GUI/Tools/mixedmodeconversion.ui \