Add SCPI command to read/write the preferences

This commit is contained in:
Jan Käberich 2024-06-20 14:40:06 +02:00
parent aeea13347e
commit 2ba954537b
12 changed files with 160 additions and 49 deletions

View file

@ -128,6 +128,7 @@ void Math::DFT::fromJSON(nlohmann::json j)
void Math::DFT::inputSamplesChanged(unsigned int begin, unsigned int end)
{
Q_UNUSED(begin);
Q_UNUSED(end);
if(input->rData().size() < 2) {
// not enough input data

View file

@ -202,6 +202,7 @@ void TDR::setMode(Mode m)
void TDR::inputSamplesChanged(unsigned int begin, unsigned int end)
{
Q_UNUSED(begin);
Q_UNUSED(end);
if(input->rData().size() >= 2) {
// trigger calculation in thread

View file

@ -136,10 +136,10 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
}
};
connect(ui->Xauto, &QCheckBox::toggled, [this, updateXenableState](bool checked) {
connect(ui->Xauto, &QCheckBox::toggled, [this, updateXenableState](bool) {
updateXenableState(ui->Xlinear, ui->Xlog, ui->Xauto, ui->Xmin, ui->Xmax, ui->XDivs, ui->XautoDivs);
});
connect(ui->XautoDivs, &QCheckBox::toggled, [this, updateXenableState](bool checked) {
connect(ui->XautoDivs, &QCheckBox::toggled, [this, updateXenableState](bool) {
updateXenableState(ui->Xlinear, ui->Xlog, ui->Xauto, ui->Xmin, ui->Xmax, ui->XDivs, ui->XautoDivs);
});
@ -155,7 +155,7 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
XAxisTypeChanged((int) plot->xAxis.getType());
connect(ui->XType, qOverload<int>(&QComboBox::currentIndexChanged), this, &XYplotAxisDialog::XAxisTypeChanged);
connect(ui->Xlog, &QCheckBox::toggled, [=](bool checked){
connect(ui->Xlog, &QCheckBox::toggled, [=](bool){
updateXenableState(ui->Xlinear, ui->Xlog, ui->Xauto, ui->Xmin, ui->Xmax, ui->XDivs, ui->XautoDivs);
});

View file

@ -18,7 +18,7 @@ public:
QMetaType mt(destType);
mt.construct(ptr, variant.constData());
}
QVariant value() {
QVariant value() const {
return QVariant(variant.metaType(), ptr);
}
void* getPtr(){return ptr;}

View file

@ -231,50 +231,8 @@ void AppWindow::SetupMenu()
connect(ui->actionPreferences, &QAction::triggered, [=](){
// save previous SCPI settings in case they change
auto &p = Preferences::getInstance();
auto SCPIenabled = p.SCPIServer.enabled;
auto SCPIport = p.SCPIServer.port;
p.edit();
// store the updated settings
p.store();
if(SCPIenabled != p.SCPIServer.enabled || SCPIport != p.SCPIServer.port) {
StopTCPServer();
if(p.SCPIServer.enabled) {
StartTCPServer(p.SCPIServer.port);
}
}
// averaging mode may have changed, update for all relevant modes
for (auto m : modeHandler->getModes())
{
switch (m->getType())
{
case Mode::Type::VNA:
case Mode::Type::SA:
if(p.Acquisition.useMedianAveraging) {
m->setAveragingMode(Averaging::Mode::Median);
}
else {
m->setAveragingMode(Averaging::Mode::Mean);
}
break;
case Mode::Type::SG:
case Mode::Type::Last:
default:
break;
}
}
// acquisition frequencies may have changed, update
// UpdateAcquisitionFrequencies();
auto active = modeHandler->getActiveMode();
if (active)
{
active->updateGraphColors();
if(device) {
active->initializeDevice();
}
}
preferencesChanged();
});
connect(ui->actionAbout, &QAction::triggered, [=](){
@ -564,6 +522,32 @@ void AppWindow::SetupSCPI()
ret.chop(1);
return ret;
}));
scpi_dev->add(new SCPICommand("PREFerences", [=](QStringList params) -> QString {
if(params.size() != 2) {
return SCPI::getResultName(SCPI::Result::Error);
}
auto &p = Preferences::getInstance();
if(p.set(params[0], QVariant(params[1]))) {
return SCPI::getResultName(SCPI::Result::Empty);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}, [=](QStringList params) -> QString {
if(params.size() != 1) {
return SCPI::getResultName(SCPI::Result::Error);
}
auto value = Preferences::getInstance().get(params[0]).toString();
if(value.isEmpty()) {
// failed to get setting
return SCPI::getResultName(SCPI::Result::Error);
} else {
return value;
}
}, false));
scpi_dev->add(new SCPICommand("APPLYPREFerences", [=](QStringList) -> QString {
preferencesChanged();
return SCPI::getResultName(SCPI::Result::Empty);
}, nullptr));
auto scpi_setup = new SCPINode("SETUP");
scpi_dev->add(scpi_setup);
scpi_setup->add(new SCPICommand("SAVE", [=](QStringList params) -> QString {
@ -1022,6 +1006,50 @@ void AppWindow::StopTCPServer()
server = nullptr;
}
void AppWindow::preferencesChanged()
{
auto &p = Preferences::getInstance();
p.store();
if(p.SCPIServer.enabled && !server) {
StartTCPServer(p.SCPIServer.port);
} else if(!p.SCPIServer.enabled && server) {
StopTCPServer();
} else if(server && server->getPort() != p.SCPIServer.port) {
// still enabled but the port changed -> needs to restart the SCPI server
StopTCPServer();
StartTCPServer(p.SCPIServer.port);
}
// averaging mode may have changed, update for all relevant modes
for (auto m : modeHandler->getModes())
{
switch (m->getType())
{
case Mode::Type::VNA:
case Mode::Type::SA:
if(p.Acquisition.useMedianAveraging) {
m->setAveragingMode(Averaging::Mode::Median);
}
else {
m->setAveragingMode(Averaging::Mode::Mean);
}
break;
case Mode::Type::SG:
case Mode::Type::Last:
default:
break;
}
}
auto active = modeHandler->getActiveMode();
if (active)
{
active->updateGraphColors();
if(device) {
active->initializeDevice();
}
}
}
SCPI* AppWindow::getSCPI()
{
return &scpi;

View file

@ -91,6 +91,9 @@ private:
void StartTCPServer(int port);
void StopTCPServer();
// Call whenever the preferences have changed. It stores the updated preferences and applies the changes which do not take effect immediately
void preferencesChanged();
QStackedWidget *central;
struct {

View file

@ -531,6 +531,61 @@ nlohmann::json Preferences::toJSON()
return j;
}
bool Preferences::set(QString name, QVariant value)
{
QPointerVariant *ptr = nullptr;
for(auto s : descr) {
if(s.name == name) {
ptr = &s.var;
break;
}
}
if(!ptr) {
// check the driver settings
for(auto driver : DeviceDriver::getDrivers()) {
for(auto s : driver->driverSpecificSettings()) {
if(s.name == name) {
ptr = &s.var;
break;
}
}
if(ptr) {
break;
}
}
}
if(ptr) {
try {
ptr->setValue(value);
return true;
} catch (const std::runtime_error&) {
// failed to set variable, likely wrong format for the QVariant
return false;
}
} else {
// not found
return false;
}
}
QVariant Preferences::get(QString name)
{
for(auto &s : descr) {
if(s.name == name) {
return s.var.value();
}
}
for(auto driver : DeviceDriver::getDrivers()) {
for(auto &s : driver->driverSpecificSettings()) {
if(s.name == name) {
return s.var.value();
}
}
}
// not found
return QVariant();
}
void Preferences::nonTrivialParsing()
{

View file

@ -44,6 +44,7 @@ Q_DECLARE_METATYPE(MarkerSymbolStyle);
class Preferences : public Savable {
friend class PreferencesDialog;
public:
static Preferences& getInstance() {
return instance;
@ -172,12 +173,16 @@ public:
void fromJSON(nlohmann::json j) override;
nlohmann::json toJSON() override;
void nonTrivialParsing();
void nonTrivialWriting();
bool set(QString name, QVariant value);
QVariant get(QString name);
private:
Preferences() :
TCPoverride(false) {}
void nonTrivialParsing();
void nonTrivialWriting();
static Preferences instance;
// TODO remove settings that have been moved to LibreVNADriver

View file

@ -4,6 +4,7 @@
TCPServer::TCPServer(int port)
{
this->port = port;
qInfo() << "Listening on port" << port;
socket = nullptr;
server.listen(QHostAddress::Any, port);

View file

@ -11,12 +11,14 @@ class TCPServer : public QObject
public:
TCPServer(int port);
int getPort() {return port;}
public slots:
bool send(QString line);
signals:
void received(QString line);
private:
int port;
QTcpServer server;
QTcpSocket *socket;
};