添加“scpi指令编辑功能”示例
This commit is contained in:
parent
d983067837
commit
6e308647c5
153
visa-scpi-example/File.cpp
Normal file
153
visa-scpi-example/File.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// C++ script created by FSW: 04:12:2024 14:23:36
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <visa.h>
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
static bool write_command(const ViSession& handle, const std::string& command);
|
||||||
|
static bool write_query(const ViSession& handle, const std::string& query, ViPBuf result_buffer, const ViUInt32 buffer_size, ViPUInt32 read_count = nullptr);
|
||||||
|
static bool process_system_error(const ViSession& handle);
|
||||||
|
static unsigned char get_esr(const ViSession& handle);
|
||||||
|
|
||||||
|
|
||||||
|
static ViSession g_analyzer;
|
||||||
|
|
||||||
|
// assign your own variables
|
||||||
|
static ViByte g_result[1000000];
|
||||||
|
|
||||||
|
|
||||||
|
static bool write_command( const ViSession& handle, const std::string& command )
|
||||||
|
{
|
||||||
|
ViStatus status = viWrite(handle, (ViBuf)command.c_str(), command.length(), VI_NULL);
|
||||||
|
|
||||||
|
// return true if successful
|
||||||
|
return ((status >= VI_SUCCESS) && process_system_error(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write_query( const ViSession& handle, const std::string& query, ViPBuf result_buffer, const ViUInt32 buffer_size, ViPUInt32 read_count )
|
||||||
|
{
|
||||||
|
ViStatus status = viWrite(handle, (ViBuf)query.c_str(), query.length(), VI_NULL);
|
||||||
|
if (status >= VI_SUCCESS)
|
||||||
|
{
|
||||||
|
status = viRead(handle, result_buffer, buffer_size, read_count);
|
||||||
|
}
|
||||||
|
// return true if successful
|
||||||
|
return ((status >= VI_SUCCESS) && process_system_error(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool process_system_error(const ViSession& handle)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
const unsigned char EsrErrorMask = 0x3C;
|
||||||
|
|
||||||
|
if ((get_esr(handle) & EsrErrorMask) != 0)
|
||||||
|
{
|
||||||
|
char err_buf[256];
|
||||||
|
ViUInt32 readCount;
|
||||||
|
viWrite(handle, (ViBuf)":SYST:ERR?", 10, VI_NULL);
|
||||||
|
viRead(handle, (ViPBuf)err_buf, sizeof(err_buf), &readCount);
|
||||||
|
err_buf[readCount] = '\0';
|
||||||
|
std::cout << err_buf << std::endl;
|
||||||
|
viWrite(handle, (ViBuf)"*CLS", 4, VI_NULL);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char get_esr(const ViSession& handle)
|
||||||
|
{
|
||||||
|
char esr_buf[16];
|
||||||
|
ViUInt32 readCount;
|
||||||
|
viWrite(handle, (ViBuf)"*ESR?", 5, VI_NULL);
|
||||||
|
viRead(handle, (ViPBuf)esr_buf, sizeof(esr_buf), &readCount);
|
||||||
|
esr_buf[readCount] = '\0';
|
||||||
|
return (static_cast<unsigned char>(std::stoi(std::string(esr_buf))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
ViSession defaultRM;
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
// create a VISA session and return a handle to it
|
||||||
|
viOpenDefaultRM(&defaultRM);
|
||||||
|
// create a VISA session to the connected device and return a handle to it
|
||||||
|
viOpen(defaultRM, (ViRsrc)"TCPIP::169.254.177.77::inst0::INSTR", VI_NULL, VI_NULL, &g_analyzer);
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, "*RST" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, "*CLS" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SYST:DISP:UPD ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":INIT:CONT OFF" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:FREQ:STAR 1000000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:FREQ:STOP 2000000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":DISP:WIND:TRAC:Y:SCAL:RLEV -30" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":DISP:WIND:TRAC:Y:SCAL:RLEV 30" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:BAND:RES:AUTO OFF" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:BAND:RES:AUTO ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:BAND:VID:AUTO OFF" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:BAND:VID:AUTO ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:FREQ:MODE SWE" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":DISP:WIND1:SIZE LARG" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC1:MARK1:FUNC:STR:STAT ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC1:MARK1:FUNC:STR:STAT OFF" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK:FUNC:POW:SEL CN" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:POW:ACH:BAND:CHAN 300000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:POW:ACH:PRES CN" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK1:STAT ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK1:X 1200000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK:FUNC:POW:SEL CN" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:POW:ACH:PRES CN" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:POW:ACH:PRES CN" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK:FUNC:POW:SEL CN0" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK:FUNC:POW:SEL CN" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:FREQ:SPAN 1000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":SENS:FREQ:SPAN 1000000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK1:STAT ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:MARK1:X 1200000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:DELT2:STAT ON" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":CALC:DELT2:X 1600000000" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":INIT:SPUR" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":MMEM:NAME 'C:\R_S\Instr\user\FSW_ScreenShot_2024-12-04_14-22-12.PNG'" );
|
||||||
|
|
||||||
|
success = write_command( g_analyzer, ":HCOP:IMM1" );
|
||||||
|
|
||||||
|
viClose(g_analyzer);
|
||||||
|
viClose(defaultRM);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
35
visa-scpi-example/File.inp
Normal file
35
visa-scpi-example/File.inp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
*RST
|
||||||
|
*CLS
|
||||||
|
:SYST:DISP:UPD ON
|
||||||
|
:INIT:CONT OFF
|
||||||
|
:SENS:FREQ:STAR 1000000000
|
||||||
|
:SENS:FREQ:STOP 2000000000
|
||||||
|
:DISP:WIND:TRAC:Y:SCAL:RLEV 0
|
||||||
|
:DISP:WIND:TRAC:Y:SCAL:RLEV 0
|
||||||
|
:SENS:BAND:RES:AUTO OFF
|
||||||
|
:SENS:BAND:RES:AUTO ON
|
||||||
|
:SENS:BAND:VID:AUTO OFF
|
||||||
|
:SENS:BAND:VID:AUTO ON
|
||||||
|
:SENS:FREQ:MODE SWE
|
||||||
|
:DISP:WIND1:SIZE LARG
|
||||||
|
:CALC1:MARK1:FUNC:STR:STAT ON
|
||||||
|
:CALC1:MARK1:FUNC:STR:STAT OFF
|
||||||
|
:CALC:MARK:FUNC:POW:SEL CN
|
||||||
|
:SENS:POW:ACH:BAND:CHAN 300000
|
||||||
|
:SENS:POW:ACH:PRES CN
|
||||||
|
:CALC:MARK1:STAT ON
|
||||||
|
:CALC:MARK1:X 1200000000
|
||||||
|
:CALC:MARK:FUNC:POW:SEL CN
|
||||||
|
:SENS:POW:ACH:PRES CN
|
||||||
|
:SENS:POW:ACH:PRES CN
|
||||||
|
:CALC:MARK:FUNC:POW:SEL CN0
|
||||||
|
:CALC:MARK:FUNC:POW:SEL CN
|
||||||
|
:SENS:FREQ:SPAN 1000000
|
||||||
|
:SENS:FREQ:SPAN 1000000000
|
||||||
|
:CALC:MARK1:STAT ON
|
||||||
|
:CALC:MARK1:X 1200000000
|
||||||
|
:CALC:DELT2:STAT ON
|
||||||
|
:CALC:DELT2:X 1600000000
|
||||||
|
:INIT:SPUR
|
||||||
|
:MMEM:NAME 'C:\R_S\Instr\user\FSW_ScreenShot_2024-12-04_14-22-12.PNG'
|
||||||
|
:HCOP:IMM1
|
109
visa-scpi-example/File.py
Normal file
109
visa-scpi-example/File.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# python script created by FSW: 04:12:2024 14:23:54
|
||||||
|
|
||||||
|
import pyvisa as visa
|
||||||
|
|
||||||
|
def write_command(instrument, command) :
|
||||||
|
instrument.write(command)
|
||||||
|
return process_system_error(instrument)
|
||||||
|
|
||||||
|
def write_query(instrument, command) :
|
||||||
|
buffer = instrument.query(command)
|
||||||
|
bSuccess = process_system_error(instrument)
|
||||||
|
return bSuccess, buffer
|
||||||
|
|
||||||
|
def process_system_error(instrument) :
|
||||||
|
bSuccess = True
|
||||||
|
EsrErrorMask = 0x3C
|
||||||
|
if ((get_esr(instrument) & EsrErrorMask) != 0) :
|
||||||
|
print(instrument.query(":SYST:ERR?"))
|
||||||
|
instrument.write("*CLS")
|
||||||
|
bSuccess = False
|
||||||
|
return bSuccess
|
||||||
|
|
||||||
|
def get_esr(instrument) :
|
||||||
|
esr = instrument.query("*ESR?")
|
||||||
|
return int(esr)
|
||||||
|
|
||||||
|
|
||||||
|
VisaResourceManager = visa.ResourceManager()
|
||||||
|
|
||||||
|
# connect to analyzer
|
||||||
|
Analyzer = VisaResourceManager.open_resource("TCPIP::169.254.177.77::inst0::INSTR")
|
||||||
|
|
||||||
|
success = write_command( Analyzer, "*RST" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, "*CLS" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SYST:DISP:UPD ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":INIT:CONT OFF" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:FREQ:STAR 1000000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:FREQ:STOP 2000000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":DISP:WIND:TRAC:Y:SCAL:RLEV -30" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":DISP:WIND:TRAC:Y:SCAL:RLEV 30" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:BAND:RES:AUTO OFF" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:BAND:RES:AUTO ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:BAND:VID:AUTO OFF" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:BAND:VID:AUTO ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:FREQ:MODE SWE" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":DISP:WIND1:SIZE LARG" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC1:MARK1:FUNC:STR:STAT ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC1:MARK1:FUNC:STR:STAT OFF" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK:FUNC:POW:SEL CN" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:POW:ACH:BAND:CHAN 300000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:POW:ACH:PRES CN" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK1:STAT ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK1:X 1200000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK:FUNC:POW:SEL CN" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:POW:ACH:PRES CN" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:POW:ACH:PRES CN" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK:FUNC:POW:SEL CN0" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK:FUNC:POW:SEL CN" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:FREQ:SPAN 1000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":SENS:FREQ:SPAN 1000000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK1:STAT ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:MARK1:X 1200000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:DELT2:STAT ON" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":CALC:DELT2:X 1600000000" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":INIT:SPUR" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":MMEM:NAME 'C:\R_S\Instr\user\FSW_ScreenShot_2024-12-04_14-22-12.PNG'" )
|
||||||
|
|
||||||
|
success = write_command( Analyzer, ":HCOP:IMM1" )
|
||||||
|
|
||||||
|
|
||||||
|
# back to local mode
|
||||||
|
success = write_command(Analyzer, "@LOC")
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
Analyzer.close()
|
||||||
|
VisaResourceManager.close()
|
9
visa-scpi-example/commands.json
Normal file
9
visa-scpi-example/commands.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
":SENS:FREQ:STAR": "1000000000",
|
||||||
|
":SENS:FREQ:STOP": "2000000000",
|
||||||
|
":DISP:WIND:TRAC:Y:SCAL:RLEV": "0",
|
||||||
|
":SENS:POW:ACH:BAND:CHAN": "300000",
|
||||||
|
":CALC:MARK1:X": "1200000000",
|
||||||
|
":SENS:FREQ:SPAN": "1000000000",
|
||||||
|
":CALC:DELT2:X": "1600000000"
|
||||||
|
}
|
9
visa-scpi-example/comments.json
Normal file
9
visa-scpi-example/comments.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
":SENS:FREQ:STAR": "\u8d77\u59cb\u9891\u7387",
|
||||||
|
":SENS:FREQ:STOP": " ",
|
||||||
|
":DISP:WIND:TRAC:Y:SCAL:RLEV": " ",
|
||||||
|
":SENS:POW:ACH:BAND:CHAN": " ",
|
||||||
|
":CALC:MARK1:X": " ",
|
||||||
|
":SENS:FREQ:SPAN": " ",
|
||||||
|
":CALC:DELT2:X": " "
|
||||||
|
}
|
153
visa-scpi-example/index.html
Normal file
153
visa-scpi-example/index.html
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>SCPI命令参数编辑器</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.command-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.command-row {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: inherit;
|
||||||
|
/* margin: 10px 0; */
|
||||||
|
padding: 10px ;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 30%;
|
||||||
|
flex-direction: column;
|
||||||
|
/* width: calc(30% - 20px); */
|
||||||
|
|
||||||
|
}
|
||||||
|
.comment-input {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
.command-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
font-family: monospace;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.value-input {
|
||||||
|
width: auto;
|
||||||
|
padding: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.update-btn {
|
||||||
|
width: auto;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.update-btn:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SCPI命令参数编辑器</h1>
|
||||||
|
<div class="command-container" id="commands-container"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function loadCommands() {
|
||||||
|
const response = await fetch('commands.json');
|
||||||
|
const commands = await response.json();
|
||||||
|
const commentsResponse = await fetch('comments.json');
|
||||||
|
const comments = await commentsResponse.json();
|
||||||
|
const container = document.getElementById('commands-container');
|
||||||
|
|
||||||
|
for (const [command, value] of Object.entries(commands)) {
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'command-row';
|
||||||
|
|
||||||
|
const commentDisplay = document.createElement('span');
|
||||||
|
commentDisplay.className = 'comment-input';
|
||||||
|
commentDisplay.textContent = comments[command] || '';
|
||||||
|
commentDisplay.ondblclick = () => {
|
||||||
|
const commentInput = document.createElement('input');
|
||||||
|
commentInput.type = 'text';
|
||||||
|
commentInput.value = commentDisplay.textContent;
|
||||||
|
commentInput.onblur = async () => {
|
||||||
|
comments[command] = commentInput.value;
|
||||||
|
commentDisplay.textContent = commentInput.value;
|
||||||
|
row.replaceChild(commentDisplay, commentInput);
|
||||||
|
await fetch('/save_comments', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(comments)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
row.replaceChild(commentInput, commentDisplay);
|
||||||
|
commentInput.focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
const label = document.createElement('span');
|
||||||
|
label.className = 'command-label';
|
||||||
|
label.textContent = command;
|
||||||
|
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.className = 'value-input';
|
||||||
|
input.type = 'text';
|
||||||
|
input.value = value;
|
||||||
|
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.className = 'update-btn';
|
||||||
|
button.textContent = '更新';
|
||||||
|
button.onclick = async () => {
|
||||||
|
if (confirm(`确认要将命令 ${command} 的参数更新为 ${input.value} 吗?`)) {
|
||||||
|
const response = await fetch('/update_command', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
command: command,
|
||||||
|
value: input.value
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
alert('更新成功!');
|
||||||
|
} else {
|
||||||
|
alert('更新失败!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
row.appendChild(commentDisplay);
|
||||||
|
// row.appendChild(document.createElement('br'));
|
||||||
|
row.appendChild(label);
|
||||||
|
row.appendChild(input);
|
||||||
|
row.appendChild(button);
|
||||||
|
container.appendChild(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = loadCommands;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
55
visa-scpi-example/parse_inp.py
Normal file
55
visa-scpi-example/parse_inp.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import re
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
def parse_inp_file(file_path):
|
||||||
|
commands_dict = {}
|
||||||
|
comments_dict = {}
|
||||||
|
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
# 去除首尾空格并按空格分割
|
||||||
|
parts = line.strip().split(' ')
|
||||||
|
if len(parts) == 2: # 只处理有一个参数的指令
|
||||||
|
command, value = parts
|
||||||
|
# 检查参数是否为数字(包括科学计数法)
|
||||||
|
if re.match(r'^-?\d+\.?\d*([eE][-+]?\d+)?$', value):
|
||||||
|
commands_dict[command] = value
|
||||||
|
|
||||||
|
# 读取注释文件
|
||||||
|
comments_file_path = 'visa-scpi-example/comments.json'
|
||||||
|
if not os.path.exists(comments_file_path):
|
||||||
|
with open(comments_file_path, 'w') as f:
|
||||||
|
# 为空时,创建一个空的注释文件,将commands_dict的值以“”表示
|
||||||
|
comments_dict = {key: " " for key in commands_dict.keys()}
|
||||||
|
json.dump(comments_dict, f)
|
||||||
|
else:
|
||||||
|
with open(comments_file_path, 'r') as f:
|
||||||
|
comments_dict = json.load(f)
|
||||||
|
|
||||||
|
# 保存为JSON文件
|
||||||
|
with open('visa-scpi-example/commands.json', 'w') as f:
|
||||||
|
json.dump(commands_dict, f, indent=2)
|
||||||
|
|
||||||
|
return commands_dict, comments_dict
|
||||||
|
|
||||||
|
def save_comments(comments_dict):
|
||||||
|
with open('visa-scpi-example/comments.json', 'w') as f:
|
||||||
|
json.dump(comments_dict, f, indent=2)
|
||||||
|
|
||||||
|
def update_inp_file(file_path, command, new_value):
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
updated_lines = []
|
||||||
|
for line in lines:
|
||||||
|
parts = line.strip().split(' ')
|
||||||
|
if len(parts) == 2 and parts[0] == command:
|
||||||
|
updated_lines.append(f"{command} {new_value}\n")
|
||||||
|
else:
|
||||||
|
updated_lines.append(line)
|
||||||
|
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
f.writelines(updated_lines)
|
43
visa-scpi-example/server.py
Normal file
43
visa-scpi-example/server.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from flask import Flask, request, jsonify, send_from_directory
|
||||||
|
from parse_inp import parse_inp_file, update_inp_file, save_comments
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# 确保在启动时解析inp文件
|
||||||
|
INP_FILE_PATH = 'visa-scpi-example/File.inp'
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
commands, comments = parse_inp_file(INP_FILE_PATH)
|
||||||
|
return send_from_directory(os.path.abspath('visa-scpi-example'), 'index.html')
|
||||||
|
|
||||||
|
@app.route('/commands.json')
|
||||||
|
def get_commands():
|
||||||
|
return send_from_directory(os.path.abspath('visa-scpi-example'), 'commands.json')
|
||||||
|
|
||||||
|
@app.route('/update_command', methods=['POST'])
|
||||||
|
def update_command():
|
||||||
|
data = request.json
|
||||||
|
try:
|
||||||
|
update_inp_file(INP_FILE_PATH, data['command'], data['value'])
|
||||||
|
# 更新后重新解析文件
|
||||||
|
parse_inp_file(INP_FILE_PATH)
|
||||||
|
return jsonify({'success': True})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'success': False, 'error': str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/save_comments', methods=['POST'])
|
||||||
|
def save_comments_route():
|
||||||
|
comments = request.json
|
||||||
|
save_comments(comments)
|
||||||
|
return jsonify({'success': True})
|
||||||
|
|
||||||
|
@app.route('/comments.json')
|
||||||
|
def get_comments():
|
||||||
|
return send_from_directory(os.path.abspath('visa-scpi-example'), 'comments.json')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# 启动时先解析一次文件
|
||||||
|
parse_inp_file(INP_FILE_PATH)
|
||||||
|
app.run(debug=True)
|
Loading…
Reference in New Issue
Block a user