New SCPI command: load/save setup files
This commit is contained in:
parent
a697f65de6
commit
94482fe151
Binary file not shown.
@ -251,6 +251,22 @@ This section contains general device commands, available regardless of the curre
|
||||
VNA
|
||||
\end{example}
|
||||
|
||||
\subsubsection{DEVice:SETUP:SAVE}
|
||||
\event{Saves the GUI setup to a file}{DEVice:SETUP:SAVE}{<filename>}
|
||||
Important points when saving/loading setup files through SCPI commands:
|
||||
\begin{itemize}
|
||||
\item Filenames must be either absolute or relative to the location of the GUI application.
|
||||
\item If the LibreVNA-GUI (and thus also the SCPI server) is running on a different machine than the SCPI client, the setup files will be saved/loaded from the machine that runs the GUI.
|
||||
\item If no (or a wrong) file ending is specified, ``.setup'' is automatically added to the filename.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{DEVice:SETUP:LOAD}
|
||||
\query{Loads a setup file}{DEVice:SETUP:LOAD?}{<filename>}{TRUE or FALSE}
|
||||
\begin{itemize}
|
||||
\item Filenames must be either absolute or relative to the location of the GUI application.
|
||||
\item The filename must include the file ending ``.setup''.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{DEVice:REFerence:OUT}
|
||||
\event{Sets the reference output frequency}{DEVice:REFerence:OUT <freq>}{<freq> in MHz, either 0 (disabled), 10 or 100}
|
||||
\query{Queries the reference output frequency}{DEVice:REFerence:OUT?}{None}{Output frequency in MHz}
|
||||
@ -563,7 +579,6 @@ Any number of measurements can be specified (by their number). These measurement
|
||||
Important points when saving/loading calibration files through SCPI commands:
|
||||
\begin{itemize}
|
||||
\item Filenames must be either absolute or relative to the location of the GUI application.
|
||||
\item SCPI parsing implicitly capitalizes all commands, the file will be saved using only uppercase letters. Similarly, it is not possible to load a file whose filename contains lowercase characters.
|
||||
\item If the LibreVNA-GUI (and thus also the SCPI server) is running on a different machine than the SCPI client, the calibration files will be saved/loaded from the machine that runs the GUI.
|
||||
\end{itemize}
|
||||
|
||||
|
@ -521,6 +521,27 @@ void AppWindow::SetupSCPI()
|
||||
ret.chop(1);
|
||||
return ret;
|
||||
}));
|
||||
auto scpi_setup = new SCPINode("SETUP");
|
||||
scpi_dev->add(scpi_setup);
|
||||
scpi_setup->add(new SCPICommand("SAVE", [=](QStringList params) -> QString {
|
||||
if(params.size() != 1) {
|
||||
// no filename given
|
||||
return SCPI::getResultName(SCPI::Result::Error);
|
||||
}
|
||||
SaveSetup(params[0]);
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}, nullptr, false));
|
||||
scpi_setup->add(new SCPICommand("LOAD", nullptr, [=](QStringList params) -> QString {
|
||||
if(params.size() != 1) {
|
||||
// no filename given
|
||||
return SCPI::getResultName(SCPI::Result::False);
|
||||
}
|
||||
if(!LoadSetup(params[0])) {
|
||||
// some error when loading the setup file
|
||||
return SCPI::getResultName(SCPI::Result::False);
|
||||
}
|
||||
return SCPI::getResultName(SCPI::Result::True);
|
||||
}, false));
|
||||
auto scpi_ref = new SCPINode("REFerence");
|
||||
scpi_dev->add(scpi_ref);
|
||||
scpi_ref->add(new SCPICommand("OUT", [=](QStringList params) -> QString {
|
||||
@ -1185,13 +1206,13 @@ nlohmann::json AppWindow::SaveSetup()
|
||||
return j;
|
||||
}
|
||||
|
||||
void AppWindow::LoadSetup(QString filename)
|
||||
bool AppWindow::LoadSetup(QString filename)
|
||||
{
|
||||
ifstream file;
|
||||
file.open(filename.toStdString());
|
||||
if(!file.is_open()) {
|
||||
qWarning() << "Unable to open file:" << filename;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
nlohmann::json j;
|
||||
try {
|
||||
@ -1200,12 +1221,13 @@ void AppWindow::LoadSetup(QString filename)
|
||||
InformationBox::ShowError("Error", "Failed to parse the setup file (" + QString(e.what()) + ")");
|
||||
qWarning() << "Parsing of setup file failed: " << e.what();
|
||||
file.close();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
file.close();
|
||||
LoadSetup(j);
|
||||
QFileInfo fi(filename);
|
||||
lSetupName.setText("Setup: "+fi.fileName());
|
||||
return true;
|
||||
}
|
||||
|
||||
void AppWindow::LoadSetup(nlohmann::json j)
|
||||
|
@ -68,7 +68,7 @@ private slots:
|
||||
void DeviceFlagsUpdated();
|
||||
void DeviceInfoUpdated();
|
||||
void SaveSetup(QString filename);
|
||||
void LoadSetup(QString filename);
|
||||
bool LoadSetup(QString filename);
|
||||
private:
|
||||
nlohmann::json SaveSetup();
|
||||
void LoadSetup(nlohmann::json j);
|
||||
|
@ -105,7 +105,6 @@ void SCPI::input(QString line)
|
||||
if(cmd[0] == ':') {
|
||||
cmd.remove(0, 1);
|
||||
}
|
||||
cmd = cmd.toUpper();
|
||||
auto response = lastNode->parse(cmd, lastNode);
|
||||
emit output(response);
|
||||
}
|
||||
@ -274,7 +273,7 @@ QString SCPINode::parse(QString cmd, SCPINode* &lastNode)
|
||||
// have not reached a leaf, find next subnode
|
||||
auto subnode = cmd.left(splitPos);
|
||||
for(auto n : subnodes) {
|
||||
if(SCPI::match(n->name, subnode)) {
|
||||
if(SCPI::match(n->name, subnode.toUpper())) {
|
||||
// pass on to next level
|
||||
return n->parse(cmd.right(cmd.size() - splitPos - 1), lastNode);
|
||||
}
|
||||
@ -292,9 +291,14 @@ QString SCPINode::parse(QString cmd, SCPINode* &lastNode)
|
||||
cmd.chop(1);
|
||||
}
|
||||
for(auto c : commands) {
|
||||
if(SCPI::match(c->name(), cmd)) {
|
||||
if(SCPI::match(c->name(), cmd.toUpper())) {
|
||||
// save current node in case of non-root for the next command
|
||||
lastNode = this;
|
||||
if(c->convertToUppercase()) {
|
||||
for(auto &p : params) {
|
||||
p = p.toUpper();
|
||||
}
|
||||
}
|
||||
if(isQuery) {
|
||||
return c->query(params);
|
||||
} else {
|
||||
|
@ -8,20 +8,23 @@
|
||||
|
||||
class SCPICommand {
|
||||
public:
|
||||
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString(QStringList)> query) :
|
||||
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString(QStringList)> query, bool convertToUppercase = true) :
|
||||
_name(name),
|
||||
fn_cmd(cmd),
|
||||
fn_query(query){}
|
||||
fn_query(query),
|
||||
argAlwaysUppercase(convertToUppercase){}
|
||||
|
||||
QString execute(QStringList params);
|
||||
QString query(QStringList params);
|
||||
QString name() {return _name;}
|
||||
bool queryable() { return fn_query != nullptr;}
|
||||
bool executable() { return fn_cmd != nullptr;}
|
||||
bool convertToUppercase() { return argAlwaysUppercase;}
|
||||
private:
|
||||
const QString _name;
|
||||
std::function<QString(QStringList)> fn_cmd;
|
||||
std::function<QString(QStringList)> fn_query;
|
||||
bool argAlwaysUppercase;
|
||||
};
|
||||
|
||||
class SCPINode {
|
||||
|
Loading…
Reference in New Issue
Block a user