Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80a2cbd80b | ||
|
|
57db6776b8 | ||
|
|
062582e238 | ||
|
|
deb3544143 | ||
|
|
5a565f7361 |
@@ -18,6 +18,7 @@ using UIShare.GlobalVariable;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
using SqlSugar;
|
||||
using TSMasterCAN;
|
||||
|
||||
namespace ACP.ViewModels
|
||||
{
|
||||
@@ -43,6 +44,16 @@ namespace ACP.ViewModels
|
||||
private readonly DispatcherTimer _uiRefreshTimer;
|
||||
#endregion
|
||||
|
||||
#region 子程序导航
|
||||
|
||||
/// <summary>
|
||||
/// 当前台架是否可以返回上一级
|
||||
/// </summary>
|
||||
public bool CanGoBack => CurrentContext?.CanGoBack ?? false;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
public string Title
|
||||
{
|
||||
@@ -155,6 +166,7 @@ namespace ACP.ViewModels
|
||||
public ICommand MonitorValueSettingCommand { get; set; }
|
||||
public ICommand GetFileStringCommand { get; set; }
|
||||
public ICommand SilenceBuzzerCommand { get; set; }
|
||||
public ICommand SettingChannelCommand { get; set; }
|
||||
#endregion
|
||||
|
||||
public ShellViewModel(IContainerProvider containerProvider)
|
||||
@@ -204,7 +216,8 @@ namespace ACP.ViewModels
|
||||
MonitorValueSettingCommand = new DelegateCommand(MonitorValueSetting);
|
||||
GetFileStringCommand = new DelegateCommand(GetFileString);
|
||||
SilenceBuzzerCommand = new AsyncDelegateCommand(SilenceBuzzer);
|
||||
|
||||
SettingChannelCommand = new AsyncDelegateCommand(SilenceBuzzer);
|
||||
SettingChannelCommand = new DelegateCommand(SettingChannel);
|
||||
_globalInfo.ContextDic.Add("default", new ScopedContext());
|
||||
|
||||
_eventAggregator.GetEvent<LoginSuccessEvent>().Subscribe(() =>
|
||||
@@ -234,10 +247,20 @@ namespace ACP.ViewModels
|
||||
RaisePropertyChanged(nameof(RunIcon));
|
||||
RaisePropertyChanged(nameof(RunningTime));
|
||||
RaisePropertyChanged(nameof(IsTerminate));
|
||||
RaisePropertyChanged(nameof(CanGoBack));
|
||||
}
|
||||
|
||||
#region 命令处理与事件
|
||||
|
||||
private void SettingChannel()
|
||||
{
|
||||
var re = CAN.ShowChannelMappingWindow(true);
|
||||
if (re != 0)
|
||||
{
|
||||
var msg = CAN.GetErrorDescription(re);
|
||||
if(CurrentConfig!=null)
|
||||
LoggerHelper.ErrorWithNotify(CurrentConfig.Title,$"同星通道映射界面打开失败:{msg}");
|
||||
}
|
||||
}
|
||||
private async Task SilenceBuzzer()
|
||||
{
|
||||
_eventAggregator.GetEvent<SilenceBuzzerEvent>().Publish(_globalInfo.CurrentScope);
|
||||
@@ -507,6 +530,9 @@ namespace ACP.ViewModels
|
||||
targetContext.IsTerminate = false;
|
||||
}
|
||||
|
||||
// 清空子程序导航栈,回到根程序
|
||||
targetContext.ResetNavigation();
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
|
||||
@@ -589,6 +615,7 @@ namespace ACP.ViewModels
|
||||
targetContext.Program.Parameters.Clear();
|
||||
targetContext.Program.StepCollection.Clear();
|
||||
targetContext.Program.ErrorStepCollection.Clear();
|
||||
targetContext.ResetNavigation();
|
||||
foreach (var item in CurrentConfig.ParameterList)
|
||||
{
|
||||
var param = CurrentConfig.SharedParameterList.FirstOrDefault(x => x.ParameterName == item.Name);
|
||||
@@ -653,7 +680,7 @@ namespace ACP.ViewModels
|
||||
targetContext.Program.StepCollection = program.StepCollection;
|
||||
targetContext.Program.ErrorStepCollection = program.ErrorStepCollection;
|
||||
targetContext.CurrentFilePath = filePath;
|
||||
|
||||
targetContext.ResetNavigation();
|
||||
foreach (var item in CurrentConfig.SharedParameterList)
|
||||
{
|
||||
var parameter = targetContext?.Program?.Parameters?.FirstOrDefault(x => x.Name == item.ParameterName);
|
||||
|
||||
@@ -190,15 +190,19 @@
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<!-- CAN信号监控 -->
|
||||
<MenuItem Header="CAN信号监控"
|
||||
Foreground="Black"
|
||||
Command="{Binding SelectCANSignalMonitorCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Message"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
<MenuItem Header="同星CAN"
|
||||
Foreground="Black">
|
||||
<MenuItem Header="通道映射"
|
||||
Command="{Binding SettingChannelCommand}"
|
||||
Foreground="Black" />
|
||||
<MenuItem Header="CAN信号采集设置"
|
||||
Command="{Binding SelectCANSignalMonitorCommand}"
|
||||
Foreground="Black" />
|
||||
<MenuItem Header="CAN报文字符串获取"
|
||||
Command="{Binding SelectCANMessageCommand}"
|
||||
Foreground="Black" />
|
||||
</MenuItem>
|
||||
|
||||
<!-- 监控设置 -->
|
||||
<MenuItem Header="监控设置"
|
||||
Foreground="Black"
|
||||
@@ -208,15 +212,7 @@ Command="{Binding MonitorValueSettingCommand}">
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="CAN报文选择"
|
||||
Foreground="Black"
|
||||
Command="{Binding SelectCANMessageCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Message"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
|
||||
<!-- 获得文件路径字符串 -->
|
||||
<MenuItem Header="获得文件路径字符串"
|
||||
Foreground="Black"
|
||||
@@ -248,6 +244,8 @@ Command="{Binding GetFileStringCommand}">
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator/>
|
||||
|
||||
</MenuItem>
|
||||
<MenuItem Header="切换初始主界面"
|
||||
FontSize="13"
|
||||
|
||||
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 180 KiB |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 142 KiB |
@@ -0,0 +1,47 @@
|
||||
===== Sheet: Sheet1 (45行x16列) =====
|
||||
集成化测试系统:ACP交流源适应性系统控制接线图(三工位系统)
|
||||
注:以下操作是在执行就地系统合上断路器(QF1、)后按下SB1启动按钮后仪器设备得电后才能操作。
|
||||
序号 | 对应设备 | | IO输入口 | 控制对应中间继电器 | 对应输出元件通断/吸合 | 功能 | | | | 备注
|
||||
1 | 1#产品 | IO继电器模块 1# | Y1 | KA2-1 | KM2 | Y1输出控制KA2-1执行,KM2吸合,产品充电(三相) | | | | 对应控制1# (低压直流电源)/电子锁/温度检测/CC/CP信号。
|
||||
2 | | | Y2 | KA3-1 | KM3 | Y2输出控制KA3-1执行,KM3吸合,产品放电(三相)
|
||||
| | | Y3 | KA4-1 | KL30通断 | Y3输出控制KA4-1执行KL30通断
|
||||
| | | Y4 | KA5-1 | KL15通断 | Y4输出控制KA5-1执行KL15通断
|
||||
| | | Y5 | KA6-1 | 电子锁60Ω电阻 | Y5输出控制KA6-1执行电子锁信号通断(60Ω)
|
||||
| | | Y6 | KA7-1 | 温度检测1KΩ电阻 | Y6输出控制KA7-1执行温度检测信号通断(1KΩ)
|
||||
3 | | | Y7 | KA8-1 | CC信号串1KΩ电阻 | Y7输出控制KA8-1执行CC信号通断(1KΩ)
|
||||
4 | | | Y8 | KA9-1 | CP信号串1KΩ电阻 | Y8输出控制KA9-1执行CP信号通断(1KΩ)
|
||||
5 | | | Y9 | KA10-1 | CC信号串680Ω电阻 | Y9输出控制KA10-1执行CC信号通断(680Ω)
|
||||
6 | | | Y10 | KA11-1 | CC信号串220Ω电阻 | Y10输出控制KA11-1执行CC信号通断(220Ω)
|
||||
7 | | | Y11 | KA12-1 | CC信号串100Ω电阻 | Y11输出控制KA12-1执行CC信号通断(100Ω)
|
||||
8 | | | Y12 | KA13-1 | CC信号空载 | Y12输出控制KA13-1执行CC信号通断(100Ω)
|
||||
13 | | | Y13 | KA14-1 | 蜂鸣器 1#响应 | Y13输出控制KA14-1执行蜂鸣器1#信号通断
|
||||
15 | 2#产品 | IO继电器模块 2# | Y1 | KA2-2 | KM4 | Y2输出控制KA2-2执行,KM4吸合,产品充电(三相) | | | | 对应控制2# (低压直流电源)/电子锁/温度检测/CC/CP信号。
|
||||
16 | | | Y2 | KA3-2 | KM5 | Y2输出控制KA3-2执行,KM5吸合,产品放电(三相)
|
||||
| | | Y3 | KA4-2 | KL30通断 | Y3输出控制KA4-2执行KL30通断
|
||||
| | | Y4 | KA5-2 | KL15通断 | Y4输出控制KA5-2执行KL15通断
|
||||
17 | | | Y5 | KA6-2 | 电子锁60Ω电阻 | Y5输出控制KA6-2执行电子锁信号通断(60Ω)
|
||||
18 | | | Y6 | KA7-2 | 温度检测1KΩ电阻 | Y6输出控制KA7-2执行温度检测信号通断(1KΩ)
|
||||
19 | | | Y7 | KA8-2 | CC信号串1KΩ电阻 | Y7输出控制KA8-2执行CC信号通断(1KΩ)
|
||||
20 | | | Y8 | KA9-2 | CP信号串1KΩ电阻 | Y8输出控制KA9-2执行CP信号通断(1KΩ)
|
||||
21 | | | Y9 | KA10-2 | CC信号串680Ω电阻 | Y9输出控制KA10-2执行CC信号通断(680Ω)
|
||||
22 | | | Y10 | KA11-2 | CC信号串220Ω电阻 | Y10输出控制KA11-2执行CC信号通断(220Ω)
|
||||
23 | | | Y11 | KA12-2 | CC信号串100Ω电阻 | Y11输出控制KA12-2执行CC信号通断(100Ω)
|
||||
24 | | | Y12 | KA13-2 | CC信号空载 | Y12输出控制KA13-2执行CC信号通断(100Ω)
|
||||
25 | | | Y13 | KA14-2 | 蜂鸣器 2#响应 | Y13输出控制KA14-2执行蜂鸣器2#信号通断
|
||||
28 | 3#产品 | IO继电器模块 3# | Y1 | KA2-3 | KM6 | Y1输出控制KA2-3执行,KM6吸合,产品充电(三相) | | | | 对应控制3# (低压直流电源)/电子锁/温度检测/CC/CP信号。
|
||||
29 | | | Y2 | KA3-3 | KM7 | Y2输出控制KA3-3执行,KM7吸合,产品放电(三相)
|
||||
30 | | | Y3 | KA4-3 | KL30通断 | Y3输出控制KA4-3执行KL30通断
|
||||
31 | | | Y4 | KA5-3 | KL15通断 | Y4输出控制KA5-3执行KL15通断
|
||||
32 | | | Y5 | KA6-3 | 电子锁60Ω电阻 | Y5输出控制KA6-3执行电子锁信号通断(60Ω)
|
||||
33 | | | Y6 | KA7-3 | 温度检测1KΩ电阻 | Y6输出控制KA7-3执行温度检测信号通断(1KΩ)
|
||||
34 | | | Y7 | KA8-3 | CC信号串1KΩ电阻 | Y7输出控制KA8-3执行CC信号通断(1KΩ)
|
||||
35 | | | Y8 | KA9-3 | CP信号串1KΩ电阻 | Y8输出控制KA9-3执行CP信号通断(1KΩ)
|
||||
36 | | | Y9 | KA10-3 | CC信号串680Ω电阻 | Y9输出控制KA10-3执行CC信号通断(680Ω)
|
||||
37 | | | Y10 | KA11-3 | CC信号串220Ω电阻 | Y10输出控制KA11-3执行CC信号通断(220Ω)
|
||||
38 | | | Y11 | KA12-3 | CC信号串100Ω电阻 | Y11输出控制KA12-3执行CC信号通断(100Ω)
|
||||
39 | | | Y12 | KA13-3 | CC信号空载 | Y12输出控制KA13-3执行CC信号通断(100Ω)
|
||||
40 | | | Y13 | KA14-3 | 蜂鸣器 3#响应 | Y13输出控制KA14-3执行蜂鸣器2#信号通断
|
||||
41 | | | Y14 | KA15-3 | KM8 | Y14输出控制KA15-3执行KM8抛负载通断 | | | | HV
|
||||
42 | | | Y15 | KA16-3 | KM9 | Y15输出控制KA16-3执行KM9短路测试
|
||||
43 | | | Y16 | KA17-3 | KM10 | Y16输出控制KA17-3执行KM10短路测试 | | | | LV
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""分析 D:\ACP 下所有 .ACP 测试项/子程序的结构。"""
|
||||
import json, os, glob
|
||||
|
||||
def walk_steps(steps, depth, out):
|
||||
for s in steps:
|
||||
st = s.get("StepType")
|
||||
name = s.get("Name")
|
||||
ind = " " * depth
|
||||
if st == "方法":
|
||||
m = s.get("Method") or {}
|
||||
full = m.get("FullName", "?")
|
||||
cls = full.split(".")[-1]
|
||||
params = []
|
||||
for p in (m.get("Parameters") or []):
|
||||
if p.get("Category") == 0: # Input
|
||||
v = p.get("Value")
|
||||
if p.get("IsUseVar"):
|
||||
v = f"${p.get('VariableName')}"
|
||||
params.append(f"{p.get('Name')}={v}")
|
||||
out.append(f"{ind}[方法] {name} <- {cls}({', '.join(params)})")
|
||||
elif st == "子程序":
|
||||
out.append(f"{ind}[子程序] {name}")
|
||||
sp = s.get("SubProgram")
|
||||
if sp and sp.get("StepCollection"):
|
||||
walk_steps(sp["StepCollection"], depth + 1, out)
|
||||
elif st == "循环开始":
|
||||
lc = s.get("LoopCount")
|
||||
out.append(f"{ind}[循环开始] 次数={lc}")
|
||||
elif st == "循环结束":
|
||||
out.append(f"{ind}[循环结束]")
|
||||
elif st == "跳转":
|
||||
out.append(f"{ind}[跳转] {name} expr={s.get('OKExpression')}")
|
||||
else:
|
||||
out.append(f"{ind}[{st}] {name}")
|
||||
|
||||
dirs = [r"D:\ACP\测试项", r"D:\ACP\子程序"]
|
||||
for d in dirs:
|
||||
for fp in sorted(glob.glob(os.path.join(d, "*.ACP"))):
|
||||
print("=" * 70)
|
||||
print("FILE:", os.path.basename(fp))
|
||||
with open(fp, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
out = []
|
||||
walk_steps(data.get("StepCollection") or [], 0, out)
|
||||
# 只打印前 60 行,避免过长
|
||||
for line in out[:60]:
|
||||
print(line)
|
||||
if len(out) > 60:
|
||||
print(f"... (共 {len(out)} 步,已省略)")
|
||||
# 参数
|
||||
print(" -- Parameters --")
|
||||
for p in (data.get("Parameters") or []):
|
||||
print(f" {p.get('Name')} = {p.get('Value')}")
|
||||
@@ -0,0 +1,215 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
极电子程序测试项转换脚本
|
||||
将极电子程序的 .ats 文件转换为我的项目的 .ats 文件
|
||||
|
||||
设备映射关系:
|
||||
- EA3040_40C → ANEVH80(水冷机,占位符)
|
||||
- IT6724C → IT6724C(直流源)
|
||||
- PSB11500_60 → PSB11500_60(交流源/负载)
|
||||
- SQ0090G1D1 → SQ0090G1D1(三相交流源)
|
||||
- IOBoardCard → IOBoardGroup(占位符,只传台架序号)
|
||||
- TSMasterCAN.CAN → TSMasterCAN.CAN(相同)
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import uuid
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
# 输入输出路径
|
||||
INPUT_DIR = Path(r"C:\Users\kk\Desktop\ACP\极电子程序")
|
||||
OUTPUT_DIR = Path(r"D:\ACP\测试项\极电子对应")
|
||||
|
||||
# 设备映射
|
||||
DEVICE_MAPPING = {
|
||||
"DeviceCommand.Device.EA3040_40C": "DeviceCommand.Device.ANEVH80", # 水冷机(占位符)
|
||||
"DeviceCommand.Device.IT6724C": "DeviceCommand.Device.IT6724C",
|
||||
"DeviceCommand.Device.PSB11500_60": "DeviceCommand.Device.PSB11500_60",
|
||||
"DeviceCommand.Device.SQ0090G1D1": "DeviceCommand.Device.SQ0090G1D1",
|
||||
"DeviceCommand.Device.IOBoardCard": "DeviceCommand.Device.IOBoardGroup", # IO板卡(占位符)
|
||||
"TSMasterCAN.CAN": "TSMasterCAN.CAN",
|
||||
}
|
||||
|
||||
# 方法映射(ANEVH80 占位符方法)
|
||||
ANVH80_METHOD_MAPPING = {
|
||||
"Set_RemoteMode": "Placeholder_SetRemoteMode",
|
||||
"Set_Voltage": "Placeholder_SetVoltage",
|
||||
"Set_Current": "Placeholder_SetCurrent",
|
||||
"Set_Power": "Placeholder_SetPower",
|
||||
"ON": "Placeholder_ON",
|
||||
"OFF": "Placeholder_OFF",
|
||||
}
|
||||
|
||||
# IOBoardGroup 占位符方法
|
||||
IOBOARDGROUP_METHOD_MAPPING = {
|
||||
"WriteMultiIO": "Placeholder_WriteMultiIO",
|
||||
"WriteSingleIO": "Placeholder_WriteSingleIO",
|
||||
"ReadMultiIO": "Placeholder_ReadMultiIO",
|
||||
"ReadSingleIO": "Placeholder_ReadSingleIO",
|
||||
}
|
||||
|
||||
|
||||
def generate_guid():
|
||||
"""生成新的 GUID"""
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def transform_parameter(param, add_station_var=False):
|
||||
"""转换参数格式"""
|
||||
new_param = {
|
||||
"ID": generate_guid(),
|
||||
"IsVisible": param.get("IsVisible", True),
|
||||
"Name": param.get("Name", ""),
|
||||
"Type": param.get("Type", ""),
|
||||
"Category": param.get("Category", 0),
|
||||
"IsGlobal": param.get("IsGlobal", False),
|
||||
"InitialValue": param.get("InitialValue"),
|
||||
"Value": param.get("Value"),
|
||||
"LowerLimit": param.get("LowerLimit"),
|
||||
"UpperLimit": param.get("UpperLimit"),
|
||||
"Result": param.get("Result", True),
|
||||
"IsUseVar": param.get("IsUseVar", False),
|
||||
"IsSave": param.get("IsSave", False),
|
||||
"VariableName": param.get("VariableName"),
|
||||
"VariableID": param.get("VariableID"),
|
||||
"IsOutputToReport": param.get("IsOutputToReport", False),
|
||||
}
|
||||
return new_param
|
||||
|
||||
|
||||
def transform_method(method, step_name=""):
|
||||
"""转换方法"""
|
||||
if method is None:
|
||||
return None
|
||||
|
||||
full_name = method.get("FullName", "")
|
||||
method_name = method.get("Name", "")
|
||||
|
||||
# 设备映射
|
||||
new_full_name = DEVICE_MAPPING.get(full_name, full_name) if full_name else None
|
||||
|
||||
# 方法映射(占位符)
|
||||
if new_full_name and "ANEVH80" in new_full_name:
|
||||
new_method_name = ANVH80_METHOD_MAPPING.get(method_name, method_name)
|
||||
elif new_full_name and "IOBoardGroup" in new_full_name:
|
||||
new_method_name = IOBOARDGROUP_METHOD_MAPPING.get(method_name, method_name)
|
||||
else:
|
||||
new_method_name = method_name
|
||||
|
||||
# 转换参数
|
||||
new_params = []
|
||||
for param in method.get("Parameters", []):
|
||||
new_param = transform_parameter(param)
|
||||
new_params.append(new_param)
|
||||
|
||||
new_method = {
|
||||
"Name": new_method_name,
|
||||
"FullName": new_full_name,
|
||||
"DeviceID": method.get("DeviceID"),
|
||||
"Parameters": new_params,
|
||||
}
|
||||
|
||||
return new_method
|
||||
|
||||
|
||||
def transform_step(step):
|
||||
"""转换步骤"""
|
||||
new_step = {
|
||||
"ID": generate_guid(),
|
||||
"IsUsed": step.get("IsUsed", True),
|
||||
"Index": step.get("Index", 1),
|
||||
"Name": step.get("Name", ""),
|
||||
"StepType": step.get("StepType", "方法"),
|
||||
"Method": None,
|
||||
"SubProgram": None,
|
||||
"LoopCount": step.get("LoopCount"),
|
||||
"LoopStartStepId": step.get("LoopStartStepId"),
|
||||
"OKExpression": step.get("OKExpression"),
|
||||
"GotoSettingString": step.get("GotoSettingString", ""),
|
||||
"OKGotoStepID": step.get("OKGotoStepID"),
|
||||
"NGGotoStepID": step.get("NGGotoStepID"),
|
||||
"Description": step.get("Description"),
|
||||
}
|
||||
|
||||
# 转换方法
|
||||
if step.get("Method"):
|
||||
new_step["Method"] = transform_method(step["Method"], step.get("Name", ""))
|
||||
|
||||
# 转换子程序
|
||||
if step.get("SubProgram"):
|
||||
sub_program = step["SubProgram"]
|
||||
new_sub_steps = []
|
||||
for sub_step in sub_program.get("StepCollection", []):
|
||||
new_sub_step = transform_step(sub_step)
|
||||
new_sub_steps.append(new_sub_step)
|
||||
|
||||
new_step["SubProgram"] = {
|
||||
"ID": generate_guid(),
|
||||
"StepCollection": new_sub_steps,
|
||||
"Parameters": [transform_parameter(p) for p in sub_program.get("Parameters", [])],
|
||||
"Devices": sub_program.get("Devices", []),
|
||||
}
|
||||
|
||||
return new_step
|
||||
|
||||
|
||||
def transform_program(program):
|
||||
"""转换整个程序"""
|
||||
new_steps = []
|
||||
for step in program.get("StepCollection", []):
|
||||
new_step = transform_step(step)
|
||||
new_steps.append(new_step)
|
||||
|
||||
new_program = {
|
||||
"ID": generate_guid(),
|
||||
"StepCollection": new_steps,
|
||||
"Parameters": [transform_parameter(p) for p in program.get("Parameters", [])],
|
||||
"Devices": program.get("Devices", []),
|
||||
}
|
||||
|
||||
return new_program
|
||||
|
||||
|
||||
def process_file(input_file, output_file):
|
||||
"""处理单个文件"""
|
||||
print(f"处理: {input_file.name}")
|
||||
|
||||
# 读取文件(支持 UTF-8 BOM)
|
||||
with open(input_file, 'r', encoding='utf-8-sig') as f:
|
||||
program = json.load(f)
|
||||
|
||||
# 转换
|
||||
new_program = transform_program(program)
|
||||
|
||||
# 写入文件
|
||||
with open(output_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(new_program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f" -> 已生成: {output_file.name}")
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 创建输出目录
|
||||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 获取所有 .ats 文件
|
||||
ats_files = list(INPUT_DIR.glob("*.ats"))
|
||||
|
||||
print(f"找到 {len(ats_files)} 个 .ats 文件")
|
||||
print(f"输出目录: {OUTPUT_DIR}")
|
||||
print()
|
||||
|
||||
# 处理每个文件
|
||||
for input_file in ats_files:
|
||||
output_file = OUTPUT_DIR / input_file.name
|
||||
process_file(input_file, output_file)
|
||||
|
||||
print()
|
||||
print(f"完成!共处理 {len(ats_files)} 个文件")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""将 ACP.pdf 逐页渲染为 PNG,并把 Excel 接线图导出为文本。"""
|
||||
import fitz
|
||||
import openpyxl
|
||||
import os
|
||||
|
||||
pdf_path = r"C:\Users\kk\Desktop\ACP\ACP电路图\ACP.pdf"
|
||||
xlsx_path = r"C:\Users\kk\Desktop\ACP\ACP电路图\ACP硬件接线图.xlsx"
|
||||
out_dir = r"C:\Users\kk\Desktop\ACP\ACP电路图\_pages"
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
# ---- 渲染 PDF ----
|
||||
doc = fitz.open(pdf_path)
|
||||
mat = fitz.Matrix(2.0, 2.0) # 2倍缩放,保证清晰度
|
||||
for i, page in enumerate(doc):
|
||||
pix = page.get_pixmap(matrix=mat)
|
||||
png_path = os.path.join(out_dir, f"page_{i+1:02d}.png")
|
||||
pix.save(png_path)
|
||||
print(f"saved {png_path}")
|
||||
doc.close()
|
||||
|
||||
# ---- 导出 Excel ----
|
||||
wb = openpyxl.load_workbook(xlsx_path, data_only=True)
|
||||
txt_path = os.path.join(out_dir, "接线图.txt")
|
||||
with open(txt_path, "w", encoding="utf-8") as f:
|
||||
for sheet_name in wb.sheetnames:
|
||||
ws = wb[sheet_name]
|
||||
f.write(f"===== Sheet: {sheet_name} ({ws.max_row}行x{ws.max_column}列) =====\n")
|
||||
for row in ws.iter_rows(values_only=True):
|
||||
cells = ["" if c is None else str(c).strip() for c in row]
|
||||
# 去掉行尾空单元格
|
||||
while cells and cells[-1] == "":
|
||||
cells.pop()
|
||||
if not cells:
|
||||
continue
|
||||
f.write(" | ".join(cells) + "\n")
|
||||
f.write("\n")
|
||||
print(f"saved {txt_path}")
|
||||
@@ -0,0 +1,280 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\AC侧电流检测.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ENUM_LOAD_MODE = "DeviceCommand.Devices.S7200负载模式_枚举, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def s7200_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.S7200", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_RATED_FREQ = guid() # 额定频率
|
||||
VAR_25PCT_POWER = guid() # 25%负载功率
|
||||
VAR_50PCT_POWER = guid() # 50%负载功率
|
||||
VAR_75PCT_POWER = guid() # 75%负载功率
|
||||
VAR_100PCT_POWER = guid() # 100%负载功率
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_STABLE_TIME = guid() # 稳定等待时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_RATED_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_25PCT_POWER, "IsVisible": True, "IsEditable": True, "Name": "25%负载功率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_50PCT_POWER, "IsVisible": True, "IsEditable": True, "Name": "50%负载功率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_75PCT_POWER, "IsVisible": True, "IsEditable": True, "Name": "75%负载功率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_100PCT_POWER, "IsVisible": True, "IsEditable": True, "Name": "100%负载功率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STABLE_TIME, "IsVisible": True, "IsEditable": True, "Name": "稳定等待时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源设置额定输入 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(7, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定输入)", "启动List输出", []))
|
||||
steps.append(delay_step(10, "等待OBC启动", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 三、负载(S7200)初始化 ----
|
||||
steps.append(s7200_step(11, "设置为远程模式", "设置为远程模式", []))
|
||||
steps.append(s7200_step(12, "设置负载工作模式CC", "设置负载工作模式",
|
||||
[param("模式", ENUM_LOAD_MODE, 0)])) # CC=0
|
||||
|
||||
# ---- 四、25%负载点测试 ----
|
||||
steps.append(s7200_step(13, "设置CC模式电流(25%负载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="25%负载功率", var_id=VAR_25PCT_POWER)]))
|
||||
steps.append(s7200_step(14, "打开通道(25%负载)", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", True)]))
|
||||
steps.append(delay_step(15, "等待25%负载稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(16, "测量25%负载输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、50%负载点测试 ----
|
||||
steps.append(s7200_step(17, "设置CC模式电流(50%负载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="50%负载功率", var_id=VAR_50PCT_POWER)]))
|
||||
steps.append(delay_step(18, "等待50%负载稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(19, "测量50%负载输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 六、75%负载点测试 ----
|
||||
steps.append(s7200_step(20, "设置CC模式电流(75%负载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="75%负载功率", var_id=VAR_75PCT_POWER)]))
|
||||
steps.append(delay_step(21, "等待75%负载稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(22, "测量75%负载输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 七、100%负载点测试 ----
|
||||
steps.append(s7200_step(23, "设置CC模式电流(100%负载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="100%负载功率", var_id=VAR_100PCT_POWER)]))
|
||||
steps.append(delay_step(24, "等待100%负载稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(25, "测量100%负载输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 八、收尾 ----
|
||||
steps.append(s7200_step(26, "关闭负载通道", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", False)]))
|
||||
steps.append(chroma_step(27, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(28, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(29, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\AC侧电流检测.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试负载点:")
|
||||
print(" - 25% 额定负载")
|
||||
print(" - 50% 额定负载")
|
||||
print(" - 75% 额定负载")
|
||||
print(" - 100% 额定负载")
|
||||
@@ -0,0 +1,281 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\AC侧电压检测.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_UPPER_VOLT = guid() # 输入电压上限
|
||||
VAR_LOWER_VOLT = guid() # 输入电压下限
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_HOLD_TIME = guid() # 各电压点保持时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_UPPER_VOLT, "IsVisible": True, "IsEditable": True, "Name": "输入电压上限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_LOWER_VOLT, "IsVisible": True, "IsEditable": True, "Name": "输入电压下限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_HOLD_TIME, "IsVisible": True, "IsEditable": True, "Name": "各电压点保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源初始化 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
|
||||
# ---- 三、额定电压测试点 ----
|
||||
steps.append(chroma_step(7, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定电压)", "启动List输出", []))
|
||||
steps.append(delay_step(10, "等待额定电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(11, "测量额定电压点实际电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 四、上限电压测试点 ----
|
||||
steps.append(chroma_step(12, "配置List交流起始电压(上限)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT)]))
|
||||
steps.append(chroma_step(13, "配置List交流结束电压(上限)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT)]))
|
||||
steps.append(delay_step(14, "等待上限电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(15, "测量上限电压点实际电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、下限电压测试点 ----
|
||||
steps.append(chroma_step(16, "配置List交流起始电压(下限)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT)]))
|
||||
steps.append(chroma_step(17, "配置List交流结束电压(下限)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT)]))
|
||||
steps.append(delay_step(18, "等待下限电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(19, "测量下限电压点实际电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 六、恢复额定电压 ----
|
||||
steps.append(chroma_step(20, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(21, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(delay_step(22, "等待额定电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 七、收尾 ----
|
||||
steps.append(chroma_step(23, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(24, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(25, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\AC侧电压检测.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试点:")
|
||||
print(" - 额定输入电压点")
|
||||
print(" - 输入电压上限点")
|
||||
print(" - 输入电压下限点")
|
||||
@@ -0,0 +1,253 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\输入频率范围测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量(Parameters 中 Category=0,供步骤绑定)
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_RATED_FREQ = guid() # 额定频率
|
||||
VAR_UPPER_FREQ = guid() # 频率上限
|
||||
VAR_LOWER_FREQ = guid() # 频率下限
|
||||
VAR_HOLD_TIME = guid() # 各频率点保持时间(ms)
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_RATED_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_UPPER_FREQ, "IsVisible": True, "IsEditable": True, "Name": "频率上限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_LOWER_FREQ, "IsVisible": True, "IsEditable": True, "Name": "频率下限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_HOLD_TIME, "IsVisible": True, "IsEditable": True, "Name": "各频率点保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、初始化交流源 ----
|
||||
steps.append(chroma_step(1, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(2, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(3, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(4, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
|
||||
# ---- 二、额定频率启动OBC ----
|
||||
steps.append(chroma_step(5, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(7, "启动List输出(额定频率)", "启动List输出", []))
|
||||
steps.append(delay_step(8, "等待OBC启动稳定", var_name="各频率点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 三、升频至上限 ----
|
||||
steps.append(chroma_step(9, "升频至频率上限", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率上限", var_id=VAR_UPPER_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率上限", var_id=VAR_UPPER_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率上限", var_id=VAR_UPPER_FREQ)]))
|
||||
steps.append(chroma_step(10, "保持频率上限", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率上限", var_id=VAR_UPPER_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率上限", var_id=VAR_UPPER_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率上限", var_id=VAR_UPPER_FREQ)]))
|
||||
steps.append(delay_step(11, "频率上限保持时间", var_name="各频率点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 四、降频至下限 ----
|
||||
steps.append(chroma_step(12, "降频至频率下限", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率下限", var_id=VAR_LOWER_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率下限", var_id=VAR_LOWER_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率下限", var_id=VAR_LOWER_FREQ)]))
|
||||
steps.append(chroma_step(13, "保持频率下限", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率下限", var_id=VAR_LOWER_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率下限", var_id=VAR_LOWER_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="频率下限", var_id=VAR_LOWER_FREQ)]))
|
||||
steps.append(delay_step(14, "频率下限保持时间", var_name="各频率点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 五、恢复额定频率 ----
|
||||
steps.append(chroma_step(15, "恢复额定频率", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(16, "额定频率保持", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(delay_step(17, "额定频率保持时间", var_name="各频率点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 六、收尾 ----
|
||||
steps.append(chroma_step(18, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(19, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(20, "清除错误队列", "清除错误队列", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\输入频率范围测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
@@ -0,0 +1,211 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\输入电流测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_RATED_FREQ = guid() # 额定频率
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_STABLE_TIME = guid() # 稳定等待时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_RATED_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STABLE_TIME, "IsVisible": True, "IsEditable": True, "Name": "稳定等待时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", "U1")]))
|
||||
|
||||
# ---- 二、交流源设置额定输入 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(7, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定输入)", "启动List输出", []))
|
||||
|
||||
# ---- 三、等待OBC启动并稳定在额定负载 ----
|
||||
steps.append(delay_step(10, "等待OBC启动稳定(额定负载)", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 四、功率分析仪测量输入电流(有效值) ----
|
||||
steps.append(pw8001_step(11, "测量输入电流有效值", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、收尾 ----
|
||||
steps.append(chroma_step(12, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(13, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(14, "清除错误队列", "清除错误队列", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\输入电流测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
@@ -0,0 +1,253 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\启动冲击电流试验.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ENUM_ACQ_MODE = "DeviceCommand.Devices.TekAcquisitionMode, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ENUM_MEAS_TYPE = "DeviceCommand.Devices.TekMeasurementType, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def tek_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.TektronixMSO", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, ms=None, var_name=None, var_id=None):
|
||||
if var_name and var_id:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
else:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, str(ms))])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_RATED_FREQ = guid() # 额定频率
|
||||
VAR_OSC_CHANNEL = guid() # 示波器电流通道号
|
||||
VAR_MEAS_NUM = guid() # 测量项编号
|
||||
VAR_SCREENSHOT_PATH = guid() # 截图保存路径
|
||||
VAR_TEST_COUNT = guid() # 测试次数
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_RATED_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_OSC_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "示波器电流通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_MEAS_NUM, "IsVisible": True, "IsEditable": True, "Name": "测量项编号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_SCREENSHOT_PATH, "IsVisible": True, "IsEditable": True, "Name": "截图保存路径",
|
||||
"Type": STRING_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_TEST_COUNT, "IsVisible": True, "IsEditable": True, "Name": "测试次数",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、示波器初始化(峰值检测模式) ----
|
||||
steps.append(tek_step(1, "设置采集模式为峰值检测", "设置采集模式",
|
||||
[param("模式", ENUM_ACQ_MODE, 1)])) # PEAKdetect=1
|
||||
steps.append(tek_step(2, "设置水平刻度(20ms/div)", "设置水平刻度",
|
||||
[param("秒每格", DOUBLE_TYPE, 0.02)])) # 20ms/div 捕获冲击波形
|
||||
steps.append(tek_step(3, "设置记录长度", "设置记录长度",
|
||||
[param("长度", "System.Int64, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", 10000)]))
|
||||
|
||||
# ---- 二、添加冲击电流最大值测量 ----
|
||||
steps.append(tek_step(4, "开启测量项", "开启测量项",
|
||||
[param("测量项编号", INT_TYPE, use_var=True,
|
||||
var_name="测量项编号", var_id=VAR_MEAS_NUM)]))
|
||||
steps.append(tek_step(5, "设置测量类型为MAXimum", "设置测量类型",
|
||||
[param("测量项编号", INT_TYPE, use_var=True,
|
||||
var_name="测量项编号", var_id=VAR_MEAS_NUM),
|
||||
param("类型", ENUM_MEAS_TYPE, 4)])) # MAXimum=4
|
||||
steps.append(tek_step(6, "设置测量源为电流通道", "设置测量源",
|
||||
[param("测量项编号", INT_TYPE, use_var=True,
|
||||
var_name="测量项编号", var_id=VAR_MEAS_NUM),
|
||||
param("源名称", STRING_TYPE, use_var=True,
|
||||
var_name="示波器电流通道号", var_id=VAR_OSC_CHANNEL)]))
|
||||
|
||||
# ---- 三、交流源设置额定输入(初始0V,准备突然施加) ----
|
||||
steps.append(chroma_step(7, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(8, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(9, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
# 初始电压设为0V,准备突然施加额定电压
|
||||
steps.append(chroma_step(10, "配置List交流起始电压(0V)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(11, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(12, "配置List执行时间(快速上升)", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 10.0), # 10ms 快速上升
|
||||
param("step2", DOUBLE_TYPE, 10.0),
|
||||
param("step3", DOUBLE_TYPE, 10.0)]))
|
||||
|
||||
# ---- 四、启动示波器采集,然后突然施加额定电压 ----
|
||||
steps.append(tek_step(13, "启动示波器采集", "设置采集状态",
|
||||
[param("运行", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", True)]))
|
||||
steps.append(delay_step(14, "等待示波器就绪", 100))
|
||||
steps.append(chroma_step(15, "启动List输出(突然施加额定电压)", "启动List输出", []))
|
||||
|
||||
# ---- 五、等待冲击电流事件完成,读取最大值 ----
|
||||
steps.append(delay_step(16, "等待冲击电流事件完成", 500))
|
||||
steps.append(tek_step(17, "查询冲击电流最大值", "查询测量项当前值",
|
||||
[param("测量项编号", INT_TYPE, use_var=True,
|
||||
var_name="测量项编号", var_id=VAR_MEAS_NUM)]))
|
||||
|
||||
# ---- 六、保存波形截图 ----
|
||||
steps.append(tek_step(18, "保存冲击电流波形截图", "保存屏幕截图",
|
||||
[param("上位机文件路径", STRING_TYPE, use_var=True,
|
||||
var_name="截图保存路径", var_id=VAR_SCREENSHOT_PATH)]))
|
||||
|
||||
# ---- 七、收尾 ----
|
||||
steps.append(tek_step(19, "停止示波器采集", "设置采集状态",
|
||||
[param("运行", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", False)]))
|
||||
steps.append(chroma_step(20, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(21, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(22, "清除错误队列", "清除错误队列", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\启动冲击电流试验.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
@@ -0,0 +1,247 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\负载冲击试验.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
BOOL_TYPE = "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ENUM_SRC_MODE = "DeviceCommand.Devices.S7200直流源模式_枚举, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ENUM_LOAD_MODE = "DeviceCommand.Devices.S7200负载模式_枚举, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def s7200_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.S7200", method_name, params)
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, ms):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, str(ms))])
|
||||
|
||||
|
||||
# 程序变量(Parameters 中 Category=0,供步骤绑定)
|
||||
VAR_LOAD_CURRENT = guid() # 满载电流(100%负载)
|
||||
VAR_FULL_HOLD_MS = guid() # 满载保持时间ms
|
||||
VAR_ZERO_HOLD_MS = guid() # 空载保持时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)
|
||||
{"ID": VAR_LOAD_CURRENT, "IsVisible": True, "IsEditable": True, "Name": "满载电流",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": 100.0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FULL_HOLD_MS, "IsVisible": True, "IsEditable": True, "Name": "满载保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": 100, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_ZERO_HOLD_MS, "IsVisible": True, "IsEditable": True, "Name": "空载保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": 100, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、交流源:额定输入(三相 380V/50Hz,持续输出) ----
|
||||
steps.append(chroma_step(1, "初始化三相List模式(无限循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "0")]))
|
||||
steps.append(chroma_step(2, "配置List起始频率(额定50Hz)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, 50.0),
|
||||
param("step2", DOUBLE_TYPE, 50.0),
|
||||
param("step3", DOUBLE_TYPE, 50.0)]))
|
||||
steps.append(chroma_step(3, "配置List交流起始电压(额定380V)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 380.0),
|
||||
param("step2", DOUBLE_TYPE, 380.0),
|
||||
param("step3", DOUBLE_TYPE, 380.0)]))
|
||||
steps.append(chroma_step(4, "配置List交流结束电压(额定380V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 380.0),
|
||||
param("step2", DOUBLE_TYPE, 380.0),
|
||||
param("step3", DOUBLE_TYPE, 380.0)]))
|
||||
steps.append(chroma_step(5, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(6, "启动List输出(额定输入)", "启动List输出", []))
|
||||
steps.append(delay_step(7, "等待输入稳定", 3000))
|
||||
|
||||
# ---- 二、负载(S7200):CC 模式预置 100% 满载电流,斜率最大 ----
|
||||
steps.append(s7200_step(8, "设置为远程模式", "设置为远程模式", []))
|
||||
steps.append(s7200_step(9, "清除保护状态", "清除保护状态", []))
|
||||
steps.append(s7200_step(10, "设置直流源工作模式CC", "设置直流源工作模式",
|
||||
[param("模式", ENUM_SRC_MODE, 0)])) # VOLTage=0? 见说明
|
||||
# 说明: S7200直流源模式_枚举 CC 不在该枚举,负载模式用 设置负载工作模式
|
||||
steps.pop() # 撤销上一步,改用负载模式枚举
|
||||
steps.append(s7200_step(10, "设置负载工作模式CC", "设置负载工作模式",
|
||||
[param("模式", ENUM_LOAD_MODE, 0)])) # CC=0
|
||||
steps.append(s7200_step(11, "设置CC模式电流(100%满载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="满载电流", var_id=VAR_LOAD_CURRENT)]))
|
||||
steps.append(s7200_step(12, "上升斜率设为负载最大能力", "发送自定义命令",
|
||||
[param("指令", "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"CURRent:SLEW MAX")]))
|
||||
steps.append(s7200_step(13, "打开通道(100%负载)", "设置通道开关",
|
||||
[param("开关", BOOL_TYPE, True)]))
|
||||
steps.append(delay_step(14, "等待负载稳定", 1000))
|
||||
|
||||
# ---- 三、循环 5000 次:0% ↔ 100% 跳变 ----
|
||||
loop_start_id = guid()
|
||||
loop_start_step = {
|
||||
"ID": loop_start_id,
|
||||
"IsUsed": True,
|
||||
"Index": 15,
|
||||
"Name": "循环开始",
|
||||
"StepType": "循环开始",
|
||||
"Method": {
|
||||
"Name": None,
|
||||
"FullName": None,
|
||||
"Parameters": [
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "循环次数",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": 5000, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": 5000,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": "负载0%与100%跳变冲击 5000次",
|
||||
}
|
||||
steps.append(loop_start_step)
|
||||
|
||||
steps.append(s7200_step(16, "跳变至0%负载(断开通道)", "设置通道开关",
|
||||
[param("开关", BOOL_TYPE, False)]))
|
||||
steps.append(method_step(17, "空载保持", "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name="空载保持时间ms", var_id=VAR_ZERO_HOLD_MS)]))
|
||||
steps.append(s7200_step(18, "跳变至100%负载(接通通道)", "设置通道开关",
|
||||
[param("开关", BOOL_TYPE, True)]))
|
||||
steps.append(method_step(19, "满载保持", "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name="满载保持时间ms", var_id=VAR_FULL_HOLD_MS)]))
|
||||
|
||||
loop_end_step = {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": 20,
|
||||
"Name": "循环结束",
|
||||
"StepType": "循环结束",
|
||||
"Method": None,
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": loop_start_id,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
steps.append(loop_end_step)
|
||||
|
||||
# ---- 四、收尾 ----
|
||||
steps.append(s7200_step(21, "关闭负载通道", "设置通道开关",
|
||||
[param("开关", BOOL_TYPE, False)]))
|
||||
steps.append(s7200_step(22, "清除保护状态", "清除保护状态", []))
|
||||
steps.append(chroma_step(23, "清除错误队列", "清除错误队列", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\负载冲击试验.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验:能反序列化回基本结构
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. [{s['StepType']}] {s['Name']}")
|
||||
@@ -0,0 +1,306 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\输出电流范围测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ENUM_LOAD_MODE = "DeviceCommand.Devices.S7200负载模式_枚举, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def s7200_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.S7200", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, ms=None, var_name=None, var_id=None):
|
||||
if var_name and var_id:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
else:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, str(ms))])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_HOLD_TIME = guid() # 各电压点保持时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_HOLD_TIME, "IsVisible": True, "IsEditable": True, "Name": "各电压点保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源设置额定输入 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(7, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定输入)", "启动List输出", []))
|
||||
steps.append(delay_step(10, "等待OBC启动", 5000))
|
||||
|
||||
# ---- 三、负载(S7200)初始化 ----
|
||||
steps.append(s7200_step(11, "设置为远程模式", "设置为远程模式", []))
|
||||
steps.append(s7200_step(12, "设置负载工作模式CC", "设置负载工作模式",
|
||||
[param("模式", ENUM_LOAD_MODE, 0)])) # CC=0
|
||||
|
||||
# ---- 四、测试点1:250Vdc ----
|
||||
steps.append(s7200_step(13, "设置CC模式电流(250Vdc最大电流)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, 67.0)])) # 三相模式最大67A
|
||||
steps.append(s7200_step(14, "打开通道(加载至250Vdc)", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", True)]))
|
||||
steps.append(delay_step(15, "等待250Vdc稳定", 3000))
|
||||
steps.append(pw8001_step(16, "测量250Vdc点输出电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(17, "250Vdc持续运行", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(18, "记录250Vdc最大电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、测试点2:300Vdc ----
|
||||
steps.append(s7200_step(19, "设置CC模式电流(300Vdc最大电流)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, 67.0)]))
|
||||
steps.append(delay_step(20, "等待300Vdc稳定", 3000))
|
||||
steps.append(pw8001_step(21, "测量300Vdc点输出电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(22, "300Vdc持续运行", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(23, "记录300Vdc最大电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 六、测试点3:350Vdc ----
|
||||
steps.append(s7200_step(24, "设置CC模式电流(350Vdc最大电流)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, 67.0)]))
|
||||
steps.append(delay_step(25, "等待350Vdc稳定", 3000))
|
||||
steps.append(pw8001_step(26, "测量350Vdc点输出电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(27, "350Vdc持续运行", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(28, "记录350Vdc最大电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 七、测试点4:400Vdc ----
|
||||
steps.append(s7200_step(29, "设置CC模式电流(400Vdc最大电流)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, 67.0)]))
|
||||
steps.append(delay_step(30, "等待400Vdc稳定", 3000))
|
||||
steps.append(pw8001_step(31, "测量400Vdc点输出电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(32, "400Vdc持续运行", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(33, "记录400Vdc最大电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 八、测试点5:450Vdc ----
|
||||
steps.append(s7200_step(34, "设置CC模式电流(450Vdc最大电流)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, 67.0)]))
|
||||
steps.append(delay_step(35, "等待450Vdc稳定", 3000))
|
||||
steps.append(pw8001_step(36, "测量450Vdc点输出电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(37, "450Vdc持续运行", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(38, "记录450Vdc最大电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 九、测试点6:500Vdc ----
|
||||
steps.append(s7200_step(39, "设置CC模式电流(500Vdc最大电流)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, 67.0)]))
|
||||
steps.append(delay_step(40, "等待500Vdc稳定", 3000))
|
||||
steps.append(pw8001_step(41, "测量500Vdc点输出电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(42, "500Vdc持续运行", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(43, "记录500Vdc最大电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 十、收尾 ----
|
||||
steps.append(s7200_step(44, "关闭负载通道", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", False)]))
|
||||
steps.append(chroma_step(45, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(46, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(47, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\输出电流范围测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试电压点(250Vdc - 500Vdc):")
|
||||
print(" - 250Vdc:最大持续输出电流 ≤ 67A(三相)/ ≤ 22A(单相)")
|
||||
print(" - 300Vdc:最大持续输出电流 ≤ 67A(三相)/ ≤ 22A(单相)")
|
||||
print(" - 350Vdc:最大持续输出电流 ≤ 67A(三相)/ ≤ 22A(单相)")
|
||||
print(" - 400Vdc:最大持续输出电流 ≤ 67A(三相)/ ≤ 22A(单相)")
|
||||
print(" - 450Vdc:最大持续输出电流 ≤ 67A(三相)/ ≤ 22A(单相)")
|
||||
print(" - 500Vdc:最大持续输出电流 ≤ 67A(三相)/ ≤ 22A(单相)")
|
||||
print("\n电流精度要求:")
|
||||
print(" - 0~10A:误差 ≤ ±0.2A")
|
||||
print(" - 10A以上:误差 ≤ ±2%")
|
||||
print("\n注意:步骤13-43的电流值当前为67A(三相模式),单相模式请改为22A")
|
||||
@@ -0,0 +1,269 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\输出电压范围测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ENUM_LOAD_MODE = "DeviceCommand.Devices.S7200负载模式_枚举, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def s7200_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.S7200", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, ms=None, var_name=None, var_id=None):
|
||||
if var_name and var_id:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
else:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, str(ms))])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_VOLT_LOWER = guid() # OBC输出电压下限
|
||||
VAR_VOLT_UPPER = guid() # OBC输出电压上限
|
||||
VAR_LOAD_LOWER = guid() # 达到下限电压的负载电流
|
||||
VAR_LOAD_UPPER = guid() # 达到上限电压的负载电流
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_HOLD_TIME = 60000 # 1min = 60000ms (固定值)
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_VOLT_LOWER, "IsVisible": True, "IsEditable": True, "Name": "OBC输出电压下限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_VOLT_UPPER, "IsVisible": True, "IsEditable": True, "Name": "OBC输出电压上限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_LOAD_LOWER, "IsVisible": True, "IsEditable": True, "Name": "达到下限电压的负载电流",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_LOAD_UPPER, "IsVisible": True, "IsEditable": True, "Name": "达到上限电压的负载电流",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源设置额定输入 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(7, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定输入)", "启动List输出", []))
|
||||
steps.append(delay_step(10, "等待OBC启动", 5000))
|
||||
|
||||
# ---- 三、负载(S7200)初始化 ----
|
||||
steps.append(s7200_step(11, "设置为远程模式", "设置为远程模式", []))
|
||||
steps.append(s7200_step(12, "设置负载工作模式CC", "设置负载工作模式",
|
||||
[param("模式", ENUM_LOAD_MODE, 0)])) # CC=0
|
||||
|
||||
# ---- 四、调节负载使输出电压为下限值 ----
|
||||
steps.append(s7200_step(13, "设置CC模式电流(达到下限电压)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="达到下限电压的负载电流", var_id=VAR_LOAD_LOWER)]))
|
||||
steps.append(s7200_step(14, "打开通道(加载至下限电压)", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", True)]))
|
||||
steps.append(delay_step(15, "等待输出电压稳定在下限", 3000))
|
||||
steps.append(pw8001_step(16, "测量下限电压点输出电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(17, "下限电压持续运行1min", VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(18, "记录下限电压最大值", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、调节负载使输出电压为上限值 ----
|
||||
steps.append(s7200_step(19, "设置CC模式电流(达到上限电压)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="达到上限电压的负载电流", var_id=VAR_LOAD_UPPER)]))
|
||||
steps.append(delay_step(20, "等待输出电压稳定在上限", 3000))
|
||||
steps.append(pw8001_step(21, "测量上限电压点输出电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(delay_step(22, "上限电压持续运行1min", VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(23, "记录上限电压最大值", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 六、收尾 ----
|
||||
steps.append(s7200_step(24, "关闭负载通道", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", False)]))
|
||||
steps.append(chroma_step(25, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(26, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(27, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\输出电压范围测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试点:")
|
||||
print(" - OBC输出电压下限:调节负载使输出电压达到下限,持续运行1min")
|
||||
print(" - OBC输出电压上限:调节负载使输出电压达到上限,持续运行1min")
|
||||
print("\n注意:需要用户根据OBC规格填写输出电压上下限及对应的负载电流值")
|
||||
@@ -0,0 +1,240 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\三相交流相位不平衡测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_PHASE_VOLT = guid() # 相电压
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_PHASE_DEVIATION = guid() # 相位偏差角度(如5°)
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_STABLE_TIME = guid() # 稳定等待时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_PHASE_VOLT, "IsVisible": True, "IsEditable": True, "Name": "相电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PHASE_DEVIATION, "IsVisible": True, "IsEditable": True, "Name": "相位偏差角度",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STABLE_TIME, "IsVisible": True, "IsEditable": True, "Name": "稳定等待时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源初始化 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
|
||||
# ---- 三、正常相位测试(基准) ----
|
||||
# 三相正常相位:L1=0°, L2=120°, L3=240°
|
||||
steps.append(chroma_step(5, "配置List起始角度(正常相位)", "配置List起始角度Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 120.0),
|
||||
param("step3", DOUBLE_TYPE, 240.0)]))
|
||||
steps.append(chroma_step(6, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相电压", var_id=VAR_PHASE_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相电压", var_id=VAR_PHASE_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相电压", var_id=VAR_PHASE_VOLT)]))
|
||||
steps.append(chroma_step(7, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相电压", var_id=VAR_PHASE_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相电压", var_id=VAR_PHASE_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相电压", var_id=VAR_PHASE_VOLT)]))
|
||||
steps.append(chroma_step(8, "启动List输出(正常相位)", "启动List输出", []))
|
||||
steps.append(delay_step(9, "等待正常相位稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(10, "测量正常相位输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 四、相位偏差+5°测试 ----
|
||||
# L1=0°+5°=5°, L2=120°+5°=125°, L3=240°+5°=245°
|
||||
steps.append(chroma_step(11, "配置List起始角度(+5°偏差)", "配置List起始角度Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="相位偏差角度", var_id=VAR_PHASE_DEVIATION),
|
||||
param("step2", DOUBLE_TYPE, 125.0),
|
||||
param("step3", DOUBLE_TYPE, 245.0)]))
|
||||
steps.append(delay_step(12, "等待+5°偏差稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(13, "测量+5°偏差输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、相位偏差-5°测试 ----
|
||||
# L1=0°-5°=-5°(或355°), L2=120°-5°=115°, L3=240°-5°=235°
|
||||
steps.append(chroma_step(14, "配置List起始角度(-5°偏差)", "配置List起始角度Async",
|
||||
[param("step1", DOUBLE_TYPE, -5.0),
|
||||
param("step2", DOUBLE_TYPE, 115.0),
|
||||
param("step3", DOUBLE_TYPE, 235.0)]))
|
||||
steps.append(delay_step(15, "等待-5°偏差稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(16, "测量-5°偏差输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 六、恢复正常相位 ----
|
||||
steps.append(chroma_step(17, "配置List起始角度(恢复正常)", "配置List起始角度Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 120.0),
|
||||
param("step3", DOUBLE_TYPE, 240.0)]))
|
||||
steps.append(delay_step(18, "等待恢复正常", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 七、收尾 ----
|
||||
steps.append(chroma_step(19, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(20, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(21, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\三相交流相位不平衡测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试相位点:")
|
||||
print(" - 正常相位:L1=0°, L2=120°, L3=240°")
|
||||
print(" - +5°偏差:L1=5°, L2=125°, L3=245°")
|
||||
print(" - -5°偏差:L1=-5°, L2=115°, L3=235°")
|
||||
@@ -0,0 +1,267 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\功率因数测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ENUM_LOAD_MODE = "DeviceCommand.Devices.S7200负载模式_枚举, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def s7200_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.S7200", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, ms=None, var_name=None, var_id=None):
|
||||
if var_name and var_id:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
else:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, str(ms))])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_RATED_FREQ = guid() # 额定频率
|
||||
VAR_RATED_POWER = guid() # OBC额定功率
|
||||
VAR_50PCT_POWER = guid() # 50%负载功率
|
||||
VAR_300W_OR_5PCT = guid() # 300W或5%功率(取大者)
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_STABLE_TIME = guid() # 稳定等待时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_RATED_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_RATED_POWER, "IsVisible": True, "IsEditable": True, "Name": "OBC额定功率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_50PCT_POWER, "IsVisible": True, "IsEditable": True, "Name": "50%负载功率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_300W_OR_5PCT, "IsVisible": True, "IsEditable": True, "Name": "300W或5%功率(取大者)",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STABLE_TIME, "IsVisible": True, "IsEditable": True, "Name": "稳定等待时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化(IEC模式,包含功率因数测量) ----
|
||||
steps.append(pw8001_step(1, "设置测试模式IEC", "设置测试模式_IEC", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源设置额定输入 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_RATED_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(7, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定输入)", "启动List输出", []))
|
||||
steps.append(delay_step(10, "等待OBC启动", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 三、负载(S7200)设置:50%负载点测试 ----
|
||||
steps.append(s7200_step(11, "设置为远程模式", "设置为远程模式", []))
|
||||
steps.append(s7200_step(12, "设置负载工作模式CC", "设置负载工作模式",
|
||||
[param("模式", ENUM_LOAD_MODE, 0)])) # CC=0
|
||||
steps.append(s7200_step(13, "设置CC模式电流(50%负载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="50%负载功率", var_id=VAR_50PCT_POWER)]))
|
||||
steps.append(s7200_step(14, "打开通道(50%负载)", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", True)]))
|
||||
steps.append(delay_step(15, "等待50%负载稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 四、测量50%负载点的功率因数 ----
|
||||
steps.append(pw8001_step(16, "测量50%负载有功功率", "查询功率_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(pw8001_step(17, "测量50%负载功率因数", "发送自定义命令",
|
||||
[param("命令", STRING_TYPE, ":MEAS:PF?")]))
|
||||
steps.append(delay_step(18, "记录50%负载数据", 1000))
|
||||
|
||||
# ---- 五、切换到300W或5%负载点测试 ----
|
||||
steps.append(s7200_step(19, "设置CC模式电流(300W或5%负载)", "设置CC模式电流",
|
||||
[param("电流", DOUBLE_TYPE, use_var=True,
|
||||
var_name="300W或5%功率(取大者)", var_id=VAR_300W_OR_5PCT)]))
|
||||
steps.append(delay_step(20, "等待300W/5%负载稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 六、测量300W或5%负载点的功率因数 ----
|
||||
steps.append(pw8001_step(21, "测量300W/5%负载有功功率", "查询功率_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
steps.append(pw8001_step(22, "测量300W/5%负载功率因数", "发送自定义命令",
|
||||
[param("命令", STRING_TYPE, ":MEAS:PF?")]))
|
||||
steps.append(delay_step(23, "记录300W/5%负载数据", 1000))
|
||||
|
||||
# ---- 七、收尾 ----
|
||||
steps.append(s7200_step(24, "关闭负载通道", "设置通道开关",
|
||||
[param("开关", "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", False)]))
|
||||
steps.append(chroma_step(25, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(26, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(27, "清除错误队列", "清除错误队列", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\功率因数测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n判定标准:")
|
||||
print(" - 50%负载点:功率因数 ≥ 0.99")
|
||||
print(" - 300W或5%负载点:功率因数 ≥ 0.9")
|
||||
@@ -0,0 +1,256 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\输入电压范围测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
BOOL_TYPE = "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, ms=None, var_name=None, var_id=None):
|
||||
if var_name and var_id:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
else:
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, str(ms))])
|
||||
|
||||
|
||||
# 程序变量(Parameters 中 Category=0,供步骤绑定)
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_UPPER_VOLT = guid() # 输入电压上限
|
||||
VAR_LOWER_VOLT = guid() # 输入电压下限
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_HOLD_TIME = guid() # 各电压点保持时间(ms)
|
||||
VAR_STEP_VOLT = guid() # 电压步进值
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_UPPER_VOLT, "IsVisible": True, "IsEditable": True, "Name": "输入电压上限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_LOWER_VOLT, "IsVisible": True, "IsEditable": True, "Name": "输入电压下限",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_HOLD_TIME, "IsVisible": True, "IsEditable": True, "Name": "各电压点保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STEP_VOLT, "IsVisible": True, "IsEditable": True, "Name": "电压步进值",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、初始化交流源 ----
|
||||
steps.append(chroma_step(1, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(2, "配置List起始频率", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(3, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
|
||||
# ---- 二、额定电压启动OBC ----
|
||||
steps.append(chroma_step(4, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(5, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(6, "启动List输出(额定电压)", "启动List输出", []))
|
||||
steps.append(delay_step(7, "等待OBC启动稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 三、逐步升压至上限 ----
|
||||
steps.append(chroma_step(8, "升压至上限电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT)]))
|
||||
steps.append(chroma_step(9, "保持上限电压", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压上限", var_id=VAR_UPPER_VOLT)]))
|
||||
steps.append(delay_step(10, "上限电压保持时间", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 四、逐步降压至下限 ----
|
||||
steps.append(chroma_step(11, "降压至下限电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT)]))
|
||||
steps.append(chroma_step(12, "保持下限电压", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="输入电压下限", var_id=VAR_LOWER_VOLT)]))
|
||||
steps.append(delay_step(13, "下限电压保持时间", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 五、恢复额定电压 ----
|
||||
steps.append(chroma_step(14, "恢复额定电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(15, "额定电压保持", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(delay_step(16, "额定电压保持时间", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 六、收尾 ----
|
||||
steps.append(chroma_step(17, "停止输出", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(18, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(19, "清除错误队列", "清除错误队列", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\输入电压范围测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
@@ -0,0 +1,299 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\限压特性.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定输入电压
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_LIMIT_VOLT = guid() # 限压保护阈值(预期值)
|
||||
VAR_STEP_VOLT = guid() # 电压步进值
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_HOLD_TIME = guid() # 各电压点保持时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定输入电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_LIMIT_VOLT, "IsVisible": True, "IsEditable": True, "Name": "限压保护阈值(预期)",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STEP_VOLT, "IsVisible": True, "IsEditable": True, "Name": "电压步进值",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_HOLD_TIME, "IsVisible": True, "IsEditable": True, "Name": "各电压点保持时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源初始化 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
|
||||
# ---- 三、额定电压启动OBC ----
|
||||
steps.append(chroma_step(7, "配置List交流起始电压(额定)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(8, "配置List交流结束电压(额定)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(9, "启动List输出(额定电压)", "启动List输出", []))
|
||||
steps.append(delay_step(10, "等待OBC启动稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(11, "测量额定电压点输入电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 四、逐步升压至限压阈值(示例:额定+5%、+10%、+15%...) ----
|
||||
# 这里使用固定示例值,实际需要根据用户填写的额定电压和步进值计算
|
||||
# 假设额定220V,步进10V,测试点:231V(105%)、242V(110%)、253V(115%)、264V(120%)
|
||||
steps.append(chroma_step(12, "升压至105%额定电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 231.0),
|
||||
param("step2", DOUBLE_TYPE, 231.0),
|
||||
param("step3", DOUBLE_TYPE, 231.0)]))
|
||||
steps.append(chroma_step(13, "保持105%额定电压", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 231.0),
|
||||
param("step2", DOUBLE_TYPE, 231.0),
|
||||
param("step3", DOUBLE_TYPE, 231.0)]))
|
||||
steps.append(delay_step(14, "等待105%电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(15, "测量105%电压点输入电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
steps.append(chroma_step(16, "升压至110%额定电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 242.0),
|
||||
param("step2", DOUBLE_TYPE, 242.0),
|
||||
param("step3", DOUBLE_TYPE, 242.0)]))
|
||||
steps.append(chroma_step(17, "保持110%额定电压", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 242.0),
|
||||
param("step2", DOUBLE_TYPE, 242.0),
|
||||
param("step3", DOUBLE_TYPE, 242.0)]))
|
||||
steps.append(delay_step(18, "等待110%电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(19, "测量110%电压点输入电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
steps.append(chroma_step(20, "升压至115%额定电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 253.0),
|
||||
param("step2", DOUBLE_TYPE, 253.0),
|
||||
param("step3", DOUBLE_TYPE, 253.0)]))
|
||||
steps.append(chroma_step(21, "保持115%额定电压", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 253.0),
|
||||
param("step2", DOUBLE_TYPE, 253.0),
|
||||
param("step3", DOUBLE_TYPE, 253.0)]))
|
||||
steps.append(delay_step(22, "等待115%电压稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(23, "测量115%电压点输入电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
steps.append(chroma_step(24, "升压至120%额定电压(限压点)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 264.0),
|
||||
param("step2", DOUBLE_TYPE, 264.0),
|
||||
param("step3", DOUBLE_TYPE, 264.0)]))
|
||||
steps.append(chroma_step(25, "保持120%额定电压(限压点)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 264.0),
|
||||
param("step2", DOUBLE_TYPE, 264.0),
|
||||
param("step3", DOUBLE_TYPE, 264.0)]))
|
||||
steps.append(delay_step(26, "等待限压点稳定", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
steps.append(pw8001_step(27, "测量限压点输入电压", "查询电压_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、降压恢复额定电压 ----
|
||||
steps.append(chroma_step(28, "降压至额定电压", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(29, "保持额定电压", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定输入电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(delay_step(30, "等待恢复正常", var_name="各电压点保持时间ms", var_id=VAR_HOLD_TIME))
|
||||
|
||||
# ---- 六、收尾 ----
|
||||
steps.append(chroma_step(31, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(32, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(33, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\限压特性.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试电压点(示例,220V系统):")
|
||||
print(" - 额定电压:220V (100%)")
|
||||
print(" - 105%额定:231V")
|
||||
print(" - 110%额定:242V")
|
||||
print(" - 115%额定:253V")
|
||||
print(" - 120%额定:264V (限压测试点)")
|
||||
print("\n注意:步骤12-27的电压值为示例(220V系统),请根据实际额定电压和限压阈值调整")
|
||||
@@ -0,0 +1,257 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""生成 D:\\ACP\\测试项\\三相交流电压不平衡测试.ACP"""
|
||||
import json
|
||||
import uuid
|
||||
|
||||
CT_TYPE = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
INT_TYPE = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
DOUBLE_TYPE = "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
STRING_TYPE = "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ZERO_GUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def guid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def param(name, ptype, value=None, use_var=False, var_name=None, var_id=None):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": ptype,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": use_var,
|
||||
"VariableName": var_name,
|
||||
"VariableID": var_id,
|
||||
}
|
||||
|
||||
|
||||
def ct_param():
|
||||
return param("ct", CT_TYPE)
|
||||
|
||||
|
||||
def method_step(index, name, full_name, method_name, params):
|
||||
return {
|
||||
"ID": guid(),
|
||||
"IsUsed": True,
|
||||
"Index": index,
|
||||
"Name": name,
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": method_name,
|
||||
"FullName": full_name,
|
||||
"Parameters": params + [ct_param()],
|
||||
},
|
||||
"SubProgram": None,
|
||||
"LoopCount": None,
|
||||
"LoopStartStepId": None,
|
||||
"OKExpression": None,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": ZERO_GUID,
|
||||
"NGGotoStepID": ZERO_GUID,
|
||||
"Description": None,
|
||||
}
|
||||
|
||||
|
||||
def chroma_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Devices.Chroma61800", method_name, params)
|
||||
|
||||
|
||||
def pw8001_step(index, name, method_name, params):
|
||||
return method_step(index, name, "DeviceCommand.Device.PW8001", method_name, params)
|
||||
|
||||
|
||||
def delay_step(index, name, var_name=None, var_id=None):
|
||||
return method_step(index, name, "Command.Delay", "Delay_ms",
|
||||
[param("millisecond", INT_TYPE, use_var=True,
|
||||
var_name=var_name, var_id=var_id)])
|
||||
|
||||
|
||||
# 程序变量
|
||||
VAR_RATED_VOLT = guid() # 额定相电压
|
||||
VAR_FREQ = guid() # 额定频率
|
||||
VAR_UNBALANCE_PCT = guid() # 电压不平衡度(%)
|
||||
VAR_PW_CHANNEL = guid() # 功率分析仪通道号
|
||||
VAR_STABLE_TIME = guid() # 稳定等待时间ms
|
||||
|
||||
program_params = [
|
||||
# 标准系统参数(Category=2)
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "台架序号",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 1, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "CAN通道",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "示波器通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道1",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": guid(), "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道2",
|
||||
"Type": INT_TYPE, "Category": 2, "Value": 0, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
# 测试项可调变量(Category=0)- 用户手动填值
|
||||
{"ID": VAR_RATED_VOLT, "IsVisible": True, "IsEditable": True, "Name": "额定相电压",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_FREQ, "IsVisible": True, "IsEditable": True, "Name": "额定频率",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_UNBALANCE_PCT, "IsVisible": True, "IsEditable": True, "Name": "电压不平衡度(%)",
|
||||
"Type": DOUBLE_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_PW_CHANNEL, "IsVisible": True, "IsEditable": True, "Name": "功率分析仪通道号",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
{"ID": VAR_STABLE_TIME, "IsVisible": True, "IsEditable": True, "Name": "稳定等待时间ms",
|
||||
"Type": INT_TYPE, "Category": 0, "Value": None, "LowerLimit": None,
|
||||
"UpperLimit": None, "Result": True, "IsUseVar": False,
|
||||
"VariableName": None, "VariableID": None},
|
||||
]
|
||||
|
||||
steps = []
|
||||
|
||||
# ---- 一、功率分析仪初始化 ----
|
||||
steps.append(pw8001_step(1, "设置测试模式WIDE", "设置测试模式_WIDE", []))
|
||||
steps.append(pw8001_step(2, "设置同步源U1", "设置同步源",
|
||||
[param("源", STRING_TYPE, "U1")]))
|
||||
|
||||
# ---- 二、交流源初始化 ----
|
||||
steps.append(chroma_step(3, "初始化三相List模式(单次循环)", "初始化三相List模式",
|
||||
[param("loopCount", INT_TYPE, "1")]))
|
||||
steps.append(chroma_step(4, "配置List起始频率(额定)", "配置List起始频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(5, "配置List结束频率(额定)", "配置List结束频率Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定频率", var_id=VAR_FREQ)]))
|
||||
steps.append(chroma_step(6, "配置List执行时间", "配置List执行时间Async",
|
||||
[param("step1", DOUBLE_TYPE, 100.0),
|
||||
param("step2", DOUBLE_TYPE, 100.0),
|
||||
param("step3", DOUBLE_TYPE, 100.0)]))
|
||||
steps.append(chroma_step(7, "配置List起始角度(标准120°)", "配置List起始角度Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 120.0),
|
||||
param("step3", DOUBLE_TYPE, 240.0)]))
|
||||
|
||||
# ---- 三、正常电压测试(基准) ----
|
||||
# 三相额定电压:L1=L2=L3=额定
|
||||
steps.append(chroma_step(8, "配置List交流起始电压(额定平衡)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(9, "配置List交流结束电压(额定平衡)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(10, "启动List输出(额定平衡电压)", "启动List输出", []))
|
||||
steps.append(delay_step(11, "等待额定电压稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(12, "测量额定平衡电压输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 四、5%电压不平衡测试(L1相降低5%) ----
|
||||
# 假设额定220V,5%不平衡=11V,L1=209V,L2=L3=220V
|
||||
# 这里使用固定值示例,实际需要根据用户填写的额定电压和不平衡度计算
|
||||
steps.append(chroma_step(13, "配置List交流起始电压(5%不平衡-L1降低)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 209.0), # 220V * 0.95 = 209V
|
||||
param("step2", DOUBLE_TYPE, 220.0),
|
||||
param("step3", DOUBLE_TYPE, 220.0)]))
|
||||
steps.append(chroma_step(14, "配置List交流结束电压(5%不平衡-L1降低)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 209.0),
|
||||
param("step2", DOUBLE_TYPE, 220.0),
|
||||
param("step3", DOUBLE_TYPE, 220.0)]))
|
||||
steps.append(delay_step(15, "等待5%不平衡电压稳定", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
steps.append(pw8001_step(16, "测量5%不平衡电压输入电流", "查询电流_不含变比",
|
||||
[param("通道号", INT_TYPE, use_var=True,
|
||||
var_name="功率分析仪通道号", var_id=VAR_PW_CHANNEL)]))
|
||||
|
||||
# ---- 五、恢复正常电压 ----
|
||||
steps.append(chroma_step(17, "配置List交流起始电压(恢复正常)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(chroma_step(18, "配置List交流结束电压(恢复正常)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step2", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT),
|
||||
param("step3", DOUBLE_TYPE, use_var=True,
|
||||
var_name="额定相电压", var_id=VAR_RATED_VOLT)]))
|
||||
steps.append(delay_step(19, "等待恢复正常", var_name="稳定等待时间ms", var_id=VAR_STABLE_TIME))
|
||||
|
||||
# ---- 六、收尾 ----
|
||||
steps.append(chroma_step(20, "停止输出(电压归零)", "配置List交流起始电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(chroma_step(21, "配置List交流结束电压(0V)", "配置List交流结束电压Async",
|
||||
[param("step1", DOUBLE_TYPE, 0.0),
|
||||
param("step2", DOUBLE_TYPE, 0.0),
|
||||
param("step3", DOUBLE_TYPE, 0.0)]))
|
||||
steps.append(pw8001_step(22, "清除状态", "清除状态", []))
|
||||
|
||||
program = {
|
||||
"ID": guid(),
|
||||
"StepCollection": steps,
|
||||
"ErrorStepCollection": [],
|
||||
"Parameters": program_params,
|
||||
}
|
||||
|
||||
out_path = r"D:\ACP\测试项\三相交流电压不平衡测试.ACP"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(program, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 校验
|
||||
with open(out_path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
print(f"已生成: {out_path}")
|
||||
print(f"步骤数: {len(data['StepCollection'])}, 参数数: {len(data['Parameters'])}")
|
||||
print("\n需要手动填写的变量参数:")
|
||||
for p in data["Parameters"]:
|
||||
if p["Category"] == 0:
|
||||
print(f" - {p['Name']} ({p['Type'].split(',')[0].split('.')[-1]})")
|
||||
print("\n步骤流程:")
|
||||
for s in data["StepCollection"]:
|
||||
print(f" {s['Index']:>2}. {s['Name']}")
|
||||
print("\n测试电压点:")
|
||||
print(" - 额定平衡电压:L1=L2=L3=额定")
|
||||
print(" - 5%不平衡电压:L1=95%额定,L2=L3=额定(示例:209V/220V/220V)")
|
||||
print("\n注意:步骤13-14的电压值为示例(220V系统),请根据实际额定电压调整")
|
||||
@@ -1,3 +1,4 @@
|
||||
using CANModule.ViewModels;
|
||||
using CANModule.Views;
|
||||
|
||||
namespace CANModule
|
||||
@@ -12,7 +13,9 @@ namespace CANModule
|
||||
{
|
||||
containerRegistry.RegisterDialog<SelectCanMessageView>("SelectCanMessageView");
|
||||
containerRegistry.RegisterDialog<CollectCANSignalSettingView>("CollectCANSignalSettingView");
|
||||
containerRegistry.RegisterDialog<DBCInfoView>("DBCInfo");
|
||||
containerRegistry.RegisterForNavigation<CANView>("CANView");
|
||||
containerRegistry.Register<CANViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,11 @@ using System.Windows.Threading;
|
||||
using TSMasterCAN;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.UIViewModel;
|
||||
using UIShare.ViewModelBase;
|
||||
|
||||
namespace CANModule.ViewModels
|
||||
{
|
||||
public class CANViewModel : BindableBase, IDialogAware
|
||||
public class CANViewModel : NavigateViewModelBase
|
||||
{
|
||||
|
||||
#region 属性
|
||||
@@ -269,17 +270,15 @@ namespace CANModule.ViewModels
|
||||
|
||||
#endregion
|
||||
private IEventAggregator _eventAggregator { get; set; }
|
||||
private CAN? _canfd;
|
||||
private SystemConfig? _systemConfig;
|
||||
private readonly DeviceManager _deviceManager;
|
||||
private IDialogService _dialogService { get; set; }
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
public CANViewModel(IContainerProvider containerProvider)
|
||||
public CANViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||
{
|
||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||
_systemConfig = containerProvider.Resolve<SystemConfig>();
|
||||
_deviceManager = containerProvider.Resolve<DeviceManager>();
|
||||
_canfd = _deviceManager.CANFD;
|
||||
_dialogService = containerProvider.Resolve<IDialogService>();
|
||||
SelectBLFPathCommand = new DelegateCommand(SelectBLFPath);
|
||||
SaveBLFPathCommand = new DelegateCommand(SaveBLFPath);
|
||||
@@ -299,6 +298,7 @@ namespace CANModule.ViewModels
|
||||
LoadMessageCommand = new DelegateCommand(LoadMessage);
|
||||
DeleteDcAutoLoadCommand = new DelegateCommand(DeleteDcAutoLoad);
|
||||
SendCustomMessageCommand = new DelegateCommand(SendCustomMessage);
|
||||
Task.Run(() => Refresh(cts.Token), cts.Token);
|
||||
}
|
||||
|
||||
#region 命令
|
||||
@@ -496,7 +496,7 @@ namespace CANModule.ViewModels
|
||||
{
|
||||
while (ct.IsCancellationRequested == false)
|
||||
{
|
||||
var temp = CAN.RealTimeMessages.Select(s => s.Value).ToArray();
|
||||
var temp = _deviceManager._CANMonitoringService.RealTimeMessages.Select(s => s.Value).ToArray();
|
||||
foreach (var item in temp)
|
||||
{
|
||||
var find = CanMessageList.FirstOrDefault(s => s.报文ID == item.FIdentifier);
|
||||
@@ -571,6 +571,10 @@ namespace CANModule.ViewModels
|
||||
}
|
||||
|
||||
public void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
|
||||
}
|
||||
public override void OnNavigatedTo(NavigationContext context)
|
||||
{
|
||||
Task.Run(() => Refresh(cts.Token), cts.Token);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Model;
|
||||
using Model.Models;
|
||||
using TSMasterCAN;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace CANModule.ViewModels
|
||||
{
|
||||
public class DBCInfoViewModel :BindableBase, IDialogAware
|
||||
{
|
||||
private can_network _can_Network;
|
||||
|
||||
public required can_network can_Network
|
||||
{
|
||||
get { return _can_Network; }
|
||||
set { SetProperty(ref _can_Network, value); }
|
||||
}
|
||||
private List<_Msg_> _MessageInfo;
|
||||
|
||||
public required List<_Msg_> MessageInfo
|
||||
{
|
||||
get { return _MessageInfo; }
|
||||
set { SetProperty(ref _MessageInfo, value); }
|
||||
}
|
||||
private ObservableCollection<InstructionNode> _CanNetWorkNode = new();
|
||||
public ObservableCollection<InstructionNode> CanNetWorkNode
|
||||
{
|
||||
get => _CanNetWorkNode;
|
||||
set => SetProperty(ref _CanNetWorkNode, value);
|
||||
}
|
||||
private ObservableCollection<InstructionNode> _MessgaeNode = new();
|
||||
public ObservableCollection<InstructionNode> MessgaeNode
|
||||
{
|
||||
get => _MessgaeNode;
|
||||
set => SetProperty(ref _MessgaeNode, value);
|
||||
}
|
||||
public ICommand CloseCommand { get; set; }
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
public DBCInfoViewModel()
|
||||
{
|
||||
CloseCommand = new DelegateCommand(Close);
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
RequestClose.Invoke();
|
||||
}
|
||||
|
||||
public bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnDialogClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
if (parameters.ContainsKey("can_Network"))
|
||||
{
|
||||
can_Network = parameters.GetValue<can_network>("can_Network");
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("MsgDatabase"))
|
||||
{
|
||||
MessageInfo = parameters.GetValue<List<_Msg_>>("MsgDatabase");
|
||||
}
|
||||
InitTreeNode();
|
||||
}
|
||||
|
||||
private void InitTreeNode()
|
||||
{
|
||||
foreach(var item in can_Network.can_nodes)
|
||||
{
|
||||
var tx = new ObservableCollection<InstructionNode>();
|
||||
var rx = new ObservableCollection<InstructionNode>();
|
||||
foreach (var can_Message in item.rx_can_Messages)
|
||||
{
|
||||
rx.Add(new InstructionNode
|
||||
{
|
||||
Name = can_Message.message_name
|
||||
});
|
||||
}
|
||||
foreach (var can_Message in item.tx_can_Messages)
|
||||
{
|
||||
tx.Add(new InstructionNode
|
||||
{
|
||||
Name = can_Message.message_name
|
||||
});
|
||||
}
|
||||
var children = new ObservableCollection<InstructionNode>();
|
||||
children.Add(new InstructionNode
|
||||
{
|
||||
Name = "TX",
|
||||
Children = tx
|
||||
});
|
||||
children.Add(new InstructionNode
|
||||
{
|
||||
Name = "RX",
|
||||
Children = rx
|
||||
});
|
||||
CanNetWorkNode.Add(new InstructionNode
|
||||
{
|
||||
Name = item.node_name,
|
||||
Children = children
|
||||
});
|
||||
}
|
||||
foreach(var item in MessageInfo)
|
||||
{
|
||||
var children = new ObservableCollection<InstructionNode>();
|
||||
foreach(var Signalname in item.signal_Name)
|
||||
{
|
||||
children.Add(new InstructionNode
|
||||
{
|
||||
Name = Signalname
|
||||
});
|
||||
}
|
||||
string hexValue = "[0x" + item.msg_id.ToString("X") + "]";
|
||||
MessgaeNode.Add(new InstructionNode
|
||||
{
|
||||
Name = hexValue+item.msg_name,
|
||||
Children=children
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,12 +34,12 @@
|
||||
Foreground="White"
|
||||
VerticalAlignment="Center"
|
||||
Margin="5,0,10,0" />
|
||||
<Button Content="关闭"
|
||||
<!--<Button Content="关闭"
|
||||
Grid.Column="2"
|
||||
Margin="150 0 0 0"
|
||||
Width="60"
|
||||
Command="{Binding CloseCommand}"
|
||||
Height="25" />
|
||||
Height="25" />-->
|
||||
</Grid>
|
||||
</GroupBox.Header>
|
||||
<Grid>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<UserControl x:Class="CANModule.Views.DBCInfoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:oxy="http://oxyplot.org/wpf"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:cons="clr-namespace:UIShare.Converters;assembly=UIShare"
|
||||
Background="White"
|
||||
xmlns:model="clr-namespace:Model.Models;assembly=Model"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
Height="400"
|
||||
Width="800">
|
||||
<prism:Dialog.WindowStyle>
|
||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||
TargetType="Window" />
|
||||
</prism:Dialog.WindowStyle>
|
||||
<GroupBox MouseLeftButtonDown="MouseLeftButtonDown">
|
||||
<GroupBox.Header>
|
||||
<Grid Margin="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="CAN报文查看"
|
||||
|
||||
Foreground="White"
|
||||
VerticalAlignment="Center"
|
||||
Margin="5,0,10,0" />
|
||||
<Button Content="关闭"
|
||||
Grid.Column="2"
|
||||
Margin="150 0 0 0"
|
||||
Width="60"
|
||||
Command="{Binding CloseCommand}"
|
||||
Height="25"
|
||||
/>
|
||||
</Grid>
|
||||
</GroupBox.Header>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="5" />
|
||||
<!-- Splitter 列 -->
|
||||
<ColumnDefinition Width="2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TreeView ItemsSource="{Binding MessgaeNode}">
|
||||
<TreeView.Resources>
|
||||
<HierarchicalDataTemplate DataType="{x:Type model:InstructionNode}"
|
||||
ItemsSource="{Binding Children}">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.Resources>
|
||||
</TreeView>
|
||||
<GridSplitter Grid.Column="1"
|
||||
Width="5"
|
||||
Background="Gray"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ResizeBehavior="PreviousAndNext"
|
||||
ShowsPreview="True" />
|
||||
<TreeView Grid.Column="2"
|
||||
ItemsSource="{Binding CanNetWorkNode}">
|
||||
<TreeView.Resources>
|
||||
<HierarchicalDataTemplate DataType="{x:Type model:InstructionNode}"
|
||||
ItemsSource="{Binding Children}">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.Resources>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace CANModule.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// DBCInfoView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class DBCInfoView : UserControl
|
||||
{
|
||||
public DBCInfoView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
Window.GetWindow(this)?.DragMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using DeviceCommand.Base;
|
||||
using Model.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -10,13 +11,24 @@ using System.Threading.Tasks;
|
||||
namespace DeviceCommand.Devices
|
||||
{
|
||||
/// <summary>
|
||||
/// 水冷机 一对一
|
||||
/// 负载 一对三
|
||||
/// </summary>
|
||||
[ACPCommand]
|
||||
public class ANEVH80 : Tcp
|
||||
{
|
||||
// Chroma SCPI 默认使用 \n 作为结束符
|
||||
private const string ScpiDelimiter = "\n";
|
||||
|
||||
public ANEVH80(TcpConfig config) : base(config)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// 占位符,可能的操作先占位
|
||||
/// </summary>
|
||||
public virtual async Task<double> 占位符(CancellationToken ct = default)
|
||||
{
|
||||
string resp = await WriteReadAsync($"MEAS:FREQ?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
return double.TryParse(resp, NumberStyles.Any, CultureInfo.InvariantCulture, out double val) ? val : 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,14 @@
|
||||
using DeviceCommand.Base;
|
||||
using Model.Models;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DeviceCommand.Devices
|
||||
{
|
||||
/// <summary>
|
||||
/// 交流源 一拖三
|
||||
/// 交流源 一拖三 (Chroma 61800系列)
|
||||
/// </summary>
|
||||
[ACPCommand]
|
||||
public class Chroma61800 : Tcp
|
||||
@@ -23,185 +21,187 @@ namespace DeviceCommand.Devices
|
||||
{
|
||||
}
|
||||
|
||||
#region 1. 基础系统控制
|
||||
#region 1. 基础系统与公共指令
|
||||
|
||||
public virtual async Task 清除错误队列(CancellationToken ct = default)
|
||||
/// <summary>
|
||||
/// 清除错误队列 (*CLS)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 清除错误队列Async(CancellationToken ct = default)
|
||||
{
|
||||
await SendAsync($"*CLS{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 2. LIST 模式初始化
|
||||
/// <summary>
|
||||
/// 重设仪器为初始状态 (*RST)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 复位Async(CancellationToken ct = default)
|
||||
{
|
||||
await SendAsync($"*RST{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 LIST 模式的三相独立编辑环境
|
||||
/// 查询仪器识别码 (*IDN?)[cite: 1]
|
||||
/// </summary>
|
||||
/// <param name="loopCount">循环次数,0代表无限循环</param>
|
||||
public virtual async Task 初始化三相List模式(int loopCount = 0, CancellationToken ct = default)
|
||||
public virtual async Task<string> 查询设备信息Async(CancellationToken ct = default)
|
||||
{
|
||||
await SendAsync($"INST:PHAS THRE{ScpiDelimiter}", ct); // 选择三相模式
|
||||
await SendAsync($"INST:EDIT EACH{ScpiDelimiter}", ct); // 选择编辑电压方式为分别编辑
|
||||
await SendAsync($"LIST:COUN {loopCount}{ScpiDelimiter}", ct); // 循环次数设定
|
||||
await SendAsync($"LIST:TRIG AUTO{ScpiDelimiter}", ct); // 设定触发方式
|
||||
await SendAsync($"LIST:BASE TIME{ScpiDelimiter}", ct); // 选择执行时间类别
|
||||
return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 3. LIST 步阶参数配置 (独立发送版 - 三参数固定版)
|
||||
#region 2. 基础输出与耦合控制 (OUTPut 子系统)[cite: 1]
|
||||
|
||||
/// <summary>
|
||||
/// 切换目标相位并设置波形为正弦波
|
||||
/// 建议在发送具体 LIST 参数前调用一次即可
|
||||
/// 设置输出开关状态 (OUTP ON / OFF)[cite: 1]
|
||||
/// </summary>
|
||||
/// <param name="phase">相位 (1: L1, 2: L2, 3: L3)</param>
|
||||
public virtual async Task 切换相位Async(int phase, CancellationToken ct = default)
|
||||
/// <param name="isOn">true: 开启输出, false: 关闭输出</param>
|
||||
public virtual async Task 设置输出开关Async(bool isOn, CancellationToken ct = default)
|
||||
{
|
||||
if (phase < 1 || phase > 3)
|
||||
throw new ArgumentOutOfRangeException(nameof(phase), "相位必须为 1, 2, 或 3");
|
||||
|
||||
await SendAsync($"INST:NSEL {phase}{ScpiDelimiter}", ct);
|
||||
await SendAsync($"FUNC:SHAP:A SINE{ScpiDelimiter}", ct);
|
||||
string state = isOn ? "ON" : "OFF";
|
||||
await SendAsync($"OUTP {state}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步起始角度
|
||||
/// 设置输出耦合模式 (OUTP:COUP AC | DC | ACDC)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 配置List起始角度Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
public virtual async Task 设置耦合模式Async(string couplingMode, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:DEGR {strValues}{ScpiDelimiter}", ct);
|
||||
// 有效参数: AC, DC, ACDC
|
||||
await SendAsync($"OUTP:COUP {couplingMode}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步交流起始电压
|
||||
/// 设置输出继电器状态 (OUTP:REL ON | OFF)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 配置List交流起始电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
public virtual async Task 设置输出继电器Async(bool isOn, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:VOLT:AC:STAR {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步交流结束电压
|
||||
/// </summary>
|
||||
public virtual async Task 配置List交流结束电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:VOLT:AC:END {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步直流起始电压
|
||||
/// </summary>
|
||||
public virtual async Task 配置List直流起始电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:VOLT:DC:STAR {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步直流结束电压
|
||||
/// </summary>
|
||||
public virtual async Task 配置List直流结束电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:VOLT:DC:END {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步起始频率
|
||||
/// </summary>
|
||||
public virtual async Task 配置List起始频率Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:FREQ:STAR {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步结束频率
|
||||
/// </summary>
|
||||
public virtual async Task 配置List结束频率Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:FREQ:END {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 LIST 各步执行时间 (单位: 毫秒)
|
||||
/// </summary>
|
||||
public virtual async Task 配置List执行时间Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||
{
|
||||
string strValues = JoinParameters(step1, step2, step3);
|
||||
await SendAsync($"LIST:DWEL {strValues}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 辅助方法:将三个 double 值转换为逗号分隔的字符串,确保小数点格式正确
|
||||
/// </summary>
|
||||
private string JoinParameters(double val1, double val2, double val3)
|
||||
{
|
||||
return $"{val1.ToString("0.###", CultureInfo.InvariantCulture)}," +
|
||||
$"{val2.ToString("0.###", CultureInfo.InvariantCulture)}," +
|
||||
$"{val3.ToString("0.###", CultureInfo.InvariantCulture)}";
|
||||
string state = isOn ? "ON" : "OFF";
|
||||
await SendAsync($"OUTP:REL {state}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 4. LIST 触发与状态监控
|
||||
#region 3. 电源核心参数设置 (SOURCE 子系统)[cite: 1]
|
||||
|
||||
/// <summary>
|
||||
/// 切换到 LIST 模式并触发输出
|
||||
/// 设置交流电压 (VOLT:AC)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 启动List输出(CancellationToken ct = default)
|
||||
/// <param name="voltage">电压值 (0 ~ 300V 或高压选配范围)</param>
|
||||
public virtual async Task 设置交流电压Async(double voltage, CancellationToken ct = default)
|
||||
{
|
||||
await SendAsync($"OUTP:MODE LIST{ScpiDelimiter}", ct);
|
||||
await SendAsync($"TRIG ON{ScpiDelimiter}", ct);
|
||||
string valStr = voltage.ToString("0.###", CultureInfo.InvariantCulture);
|
||||
await SendAsync($"VOLT:AC {valStr}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询 LIST 序列是否正在运行
|
||||
/// 设置直流电压 (VOLT:DC)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task<bool> 查询List是否运行中(CancellationToken ct = default)
|
||||
public virtual async Task 设置直流电压Async(double voltage, CancellationToken ct = default)
|
||||
{
|
||||
string state = await WriteReadAsync($"TRIG:STATE?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
state = state?.Trim().ToUpper();
|
||||
return state == "ON" || state == "1";
|
||||
string valStr = voltage.ToString("0.###", CultureInfo.InvariantCulture);
|
||||
await SendAsync($"VOLT:DC {valStr}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 阻塞异步等待直到 LIST 序列执行完毕 (带安全超时保护)
|
||||
/// 设置输出频率 (FREQ)[cite: 1]
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs">最大等待超时时间(建议比实际LIST总时长多5-10秒)</param>
|
||||
public virtual async Task 等待List执行结束(int timeoutMs = 60000, CancellationToken ct = default)
|
||||
/// <param name="frequency">频率值 (Hz)</param>
|
||||
public virtual async Task 设置频率Async(double frequency, CancellationToken ct = default)
|
||||
{
|
||||
// 给仪器留出响应触发的时间
|
||||
await Task.Delay(500, ct);
|
||||
string valStr = frequency.ToString("0.###", CultureInfo.InvariantCulture);
|
||||
await SendAsync($"FREQ {valStr}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
bool isRunning = true;
|
||||
|
||||
while (isRunning)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
if (sw.ElapsedMilliseconds > timeoutMs)
|
||||
{
|
||||
throw new TimeoutException($"等待 LIST 执行结束超时 ({timeoutMs} ms)。");
|
||||
}
|
||||
|
||||
// 读取当前状态
|
||||
isRunning = await 查询List是否运行中(ct);
|
||||
|
||||
if (isRunning)
|
||||
{
|
||||
// 还在运行,适当休眠后继续轮询,避免总线阻塞
|
||||
await Task.Delay(500, ct);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置波形选择 (FUNC:SHAP:A SINE / SQUA / CSIN 等)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 设置波形Async(string shape, CancellationToken ct = default)
|
||||
{
|
||||
await SendAsync($"FUNC:SHAP:A {shape}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 4. 相位与多相模式控制 (INST & PHASE 子系统)[cite: 1]
|
||||
|
||||
/// <summary>
|
||||
/// 设置单/三相工作模式 (INST:PHAS THREE / SINGLE)[cite: 1]
|
||||
/// </summary>
|
||||
/// <param name="isThreePhase">true: 三相模式, false: 单相模式</param>
|
||||
public virtual async Task 设置单三相模式Async(bool isThreePhase, CancellationToken ct = default)
|
||||
{
|
||||
string mode = isThreePhase ? "THREE" : "SINGLE";
|
||||
await SendAsync($"INST:PHAS {mode}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置三相模式下的相互关系 (PHASE:THREE INDEPEND / SAMEFREQ / BALANCE)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 设置三相关系Async(string relation, CancellationToken ct = default)
|
||||
{
|
||||
// 有效参数: INDEPEND, SAMEFREQ, BALANCE
|
||||
await SendAsync($"PHASE:THREE {relation}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置输出开启相位角 (PHASE:ON)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 设置开机角度Async(double degree, CancellationToken ct = default)
|
||||
{
|
||||
string valStr = degree.ToString("0.###", CultureInfo.InvariantCulture);
|
||||
await SendAsync($"PHASE:ON {valStr}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置输出关闭相位角 (PHASE:OFF)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task 设置关机角度Async(double degree, CancellationToken ct = default)
|
||||
{
|
||||
string valStr = degree.ToString("0.###", CultureInfo.InvariantCulture);
|
||||
await SendAsync($"PHASE:OFF {valStr}{ScpiDelimiter}", ct);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 5. 参数测量查询 (MEASure 子系统)[cite: 1]
|
||||
|
||||
/// <summary>
|
||||
/// 查询交流电压均方根值 (MEAS:VOLT:AC?)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task<double> 读取交流电压Async(CancellationToken ct = default)
|
||||
{
|
||||
string resp = await WriteReadAsync($"MEAS:VOLT:AC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
return double.TryParse(resp, NumberStyles.Any, CultureInfo.InvariantCulture, out double val) ? val : 0.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询交流电流均方根值 (MEAS:CURR:AC?)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task<double> 读取交流电流Async(CancellationToken ct = default)
|
||||
{
|
||||
string resp = await WriteReadAsync($"MEAS:CURR:AC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
return double.TryParse(resp, NumberStyles.Any, CultureInfo.InvariantCulture, out double val) ? val : 0.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询输出频率 (MEAS:FREQ?)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task<double> 读取频率Async(CancellationToken ct = default)
|
||||
{
|
||||
string resp = await WriteReadAsync($"MEAS:FREQ?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
return double.TryParse(resp, NumberStyles.Any, CultureInfo.InvariantCulture, out double val) ? val : 0.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询真实输出功率 (MEAS:POW:AC?)[cite: 1]
|
||||
/// </summary>
|
||||
public virtual async Task<double> 读取真实功率Async(CancellationToken ct = default)
|
||||
{
|
||||
string resp = await WriteReadAsync($"MEAS:POW:AC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||
return double.TryParse(resp, NumberStyles.Any, CultureInfo.InvariantCulture, out double val) ? val : 0.0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -168,8 +168,48 @@ namespace DeviceCommand.Devices
|
||||
await 目标板卡.写输出开关(_slaveAddress, io信息.Address, 开关状态);
|
||||
}
|
||||
|
||||
// =================================================================================
|
||||
// 以下为新增的原生命令透传接口,使用台架序号自动路由至对应 IOBoard
|
||||
// =================================================================================
|
||||
|
||||
/// <summary>
|
||||
/// 内部路由辅助方法:根据板卡索引安全获取当前连接的实例对象
|
||||
/// 针对指定台架直接写入单个输出开关
|
||||
/// </summary>
|
||||
public async Task 写输出开关(int 台架序号, byte 站号, ushort 开始地址, bool data)
|
||||
{
|
||||
IOBoard targetBoard = GetBoardInstance(台架序号);
|
||||
await targetBoard.写输出开关(站号, 开始地址, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 针对指定台架直接批量写入输出开关
|
||||
/// </summary>
|
||||
public async Task 批量写输出开关(int 台架序号, byte 站号, ushort 开始地址, bool[] datas)
|
||||
{
|
||||
IOBoard targetBoard = GetBoardInstance(台架序号);
|
||||
await targetBoard.批量写输出开关(站号, 开始地址, datas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 针对指定台架直接读取单个输出开关状态
|
||||
/// </summary>
|
||||
public async Task 读输出开关(int 台架序号, byte 站号, ushort 开始地址)
|
||||
{
|
||||
IOBoard targetBoard = GetBoardInstance(台架序号);
|
||||
await targetBoard.读输出开关(站号, 开始地址);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 针对指定台架直接批量读取输出开关状态
|
||||
/// </summary>
|
||||
public async Task<bool[]> 批量读输出开关(int 台架序号, byte 站号, ushort 开始地址, ushort 数量)
|
||||
{
|
||||
IOBoard targetBoard = GetBoardInstance(台架序号);
|
||||
return await targetBoard.批量读输出开关(站号, 开始地址, 数量);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 内部路由辅助方法:根据板卡/台架索引安全获取当前连接的实例对象
|
||||
/// </summary>
|
||||
private IOBoard GetBoardInstance(int moduleIndex)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace DeviceCommand.Device
|
||||
/// <summary>
|
||||
/// 功率分析仪(型号:HIOKI PW8001) 一拖三
|
||||
/// </summary>
|
||||
|
||||
[ACPCommand]
|
||||
public class PW8001 : Tcp
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -53,6 +53,28 @@ namespace DeviceCommand.Devices
|
||||
// SCPI 指令结束符 (消息终止符需使用 LF)
|
||||
private const string ScpiDelimiter = "\n";
|
||||
|
||||
#region 兼容旧 MSO44B 枚举(供 ACP 测试项反序列化)
|
||||
|
||||
public enum AcquireMode { Sample = 0, PeakDetect = 1, HiRes = 2, Average = 3, Envelope = 4 }
|
||||
public enum BandwidthLimit { Full = 0, BW20MHz = 1 }
|
||||
public enum Channel { Channel1 = 1, Channel2 = 2, Channel3 = 3, Channel4 = 4 }
|
||||
public enum CouplingMode { DC = 0, AC = 1, GND = 2 }
|
||||
public enum MeasurementType
|
||||
{
|
||||
Amplitude = 1, Frequency = 2, Mean = 3, PK2PK = 4,
|
||||
Maximum = 5, Minimum = 6, RMS = 7, Overshoot = 8,
|
||||
Undershoot = 9, PositiveOvershoot = 10, NegativeOvershoot = 11,
|
||||
RiseTime = 12, FallTime = 13, DutyCycle = 14,
|
||||
Period = 15, Phase = 16, Delay = 17,
|
||||
BurstWidth = 18, SlewRateRising = 19, SlewRateFalling = 20,
|
||||
High = 21
|
||||
}
|
||||
public enum StopAfter { Sequence = 0, RunStop = 1 }
|
||||
public enum TriggerMode { Auto = 0, Normal = 1 }
|
||||
public enum TriggerSlope { Rising = 0, Falling = 1 }
|
||||
|
||||
#endregion
|
||||
|
||||
public TektronixMSO(TcpConfig config) : base(config)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -197,7 +197,6 @@ namespace MonitorModule.ViewModels.Dialogs
|
||||
/// </summary>
|
||||
private IEnumerable<(string DisplayName, string Fingerprint, string MethodName)> DiscoverCanSignals()
|
||||
{
|
||||
if (_deviceManager?.CANFD == null) yield break;
|
||||
if (_systemConfig?.ConfigurationList == null) yield break;
|
||||
|
||||
var msgDb = DBCParse.MsgDatabase;
|
||||
@@ -331,7 +330,6 @@ namespace MonitorModule.ViewModels.Dialogs
|
||||
private void OnDbcLoaded(DBCLoadedArgs args)
|
||||
{
|
||||
if (args.Scope != _systemConfig?.Title) return;
|
||||
if (_deviceManager?.CANFD == null) return;
|
||||
|
||||
int channel = (int)args.Channel;
|
||||
var msgDb = DBCParse.MsgDatabase;
|
||||
|
||||
@@ -535,7 +535,6 @@ namespace MonitorModule.ViewModels
|
||||
private void RefreshConfiguredCanSignals()
|
||||
{
|
||||
if (_systemConfig?.ConfigurationList == null || _systemConfig.ConfigurationList.Count == 0) return;
|
||||
if (_deviceManager?.CANFD == null) return;
|
||||
|
||||
var msgDb = DBCParse.MsgDatabase;
|
||||
foreach (var channel in _systemConfig.ConfigurationList.Select(c => c.Channel).Distinct())
|
||||
@@ -633,7 +632,6 @@ namespace MonitorModule.ViewModels
|
||||
private void OnDbcLoaded(DBCLoadedArgs args)
|
||||
{
|
||||
if (args.Scope != TestStatus) return;
|
||||
if (_deviceManager?.CANFD == null) return;
|
||||
int channel = (int)args.Channel;
|
||||
var msgDb = DBCParse.MsgDatabase;
|
||||
if (channel < 0 || channel >= msgDb.Count) return;
|
||||
|
||||
@@ -11,275 +11,15 @@ using TSMaster;
|
||||
namespace TSMasterCAN
|
||||
{
|
||||
[ACPCommand]
|
||||
public class CAN : IDisposable
|
||||
public class CAN
|
||||
{
|
||||
#region 静态成员
|
||||
|
||||
public static event Action? ConnectEvent;
|
||||
public static event Action? DisConnectEvent;
|
||||
public static event Action ConnectEvent;
|
||||
public static event Action DisConnectEvent;
|
||||
public static bool ConnectFlag { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 实时接收到的 CAN 报文缓存(按报文 ID 索引,保留最新帧)。
|
||||
/// 供 CANViewModel.Refresh 等界面轮询读取。
|
||||
/// </summary>
|
||||
public static ConcurrentDictionary<int, TLIBCANFD> RealTimeMessages { get; } = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region 实例字段与属性
|
||||
|
||||
/// <summary>设备类型号(43 = USBCANFD-400U 等,TSMaster 中作为配置参考保留)</summary>
|
||||
public uint DeviceType { get; }
|
||||
/// <summary>设备索引</summary>
|
||||
public uint DeviceIndex { get; }
|
||||
/// <summary>最大通道数</summary>
|
||||
public int MaxChannels { get; }
|
||||
/// <summary>仲裁域波特率</summary>
|
||||
public string ABitBaud { get; }
|
||||
/// <summary>数据域波特率</summary>
|
||||
public string DBitBaud { get; }
|
||||
/// <summary>是否开启终端电阻</summary>
|
||||
public bool EnableTerminalResistance { get; }
|
||||
|
||||
/// <summary>DBC 解析器(提供 MsgDatabase、MaxChannels 等访问)</summary>
|
||||
public DBCParse DBCParser => DBCParse.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// DBC 报文解码事件:当接收到 CAN 帧并通过 DBC 解码后触发。
|
||||
/// 参数:(通道号, 解码后的报文信息)
|
||||
/// </summary>
|
||||
public event Action<uint, DBCMessage>? OnDbcMessageDecoded;
|
||||
|
||||
private bool _disposed;
|
||||
private bool _isOpened;
|
||||
private TCANFDQueueEvent_Win32? _instanceListener;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
|
||||
/// <summary>默认构造函数(兼容 SystemConfig.CANFD = new() 等场景)</summary>
|
||||
public CAN() : this(43, 0, 4, "500000", "2000000", true) { }
|
||||
|
||||
/// <summary>
|
||||
/// 带配置参数的构造函数(兼容原 ZLG 设备管理流程)。
|
||||
/// </summary>
|
||||
/// <param name="deviceType">设备类型号</param>
|
||||
/// <param name="deviceIndex">设备索引</param>
|
||||
/// <param name="maxChannels">最大通道数</param>
|
||||
/// <param name="aBitBaud">仲裁域波特率</param>
|
||||
/// <param name="dBitBaud">数据域波特率</param>
|
||||
/// <param name="enableTerminalResistance">是否开启终端电阻</param>
|
||||
public CAN(uint deviceType, uint deviceIndex, int maxChannels, string aBitBaud, string dBitBaud, bool enableTerminalResistance)
|
||||
{
|
||||
DeviceType = deviceType;
|
||||
DeviceIndex = deviceIndex;
|
||||
MaxChannels = maxChannels;
|
||||
ABitBaud = aBitBaud;
|
||||
DBitBaud = dBitBaud;
|
||||
EnableTerminalResistance = enableTerminalResistance;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 实例方法 — 设备管理(替代原 ZLG 实例方法)
|
||||
|
||||
/// <summary>
|
||||
/// 打开设备:初始化 TSMaster 库 → 设置通道数 → 配置波特率 → 连接 → 启动 RBS → 注册监听。
|
||||
/// </summary>
|
||||
/// <returns>true 表示成功</returns>
|
||||
public bool 打开设备()
|
||||
{
|
||||
if (_isOpened) return true;
|
||||
if (ConnectFlag) { _isOpened = true; return true; }
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 初始化 TSMaster 库
|
||||
var re = Init("ACP");
|
||||
if (re != 0)
|
||||
{
|
||||
Debug.WriteLine($"TSMaster 初始化失败,错误代码:{re}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 设置通道数
|
||||
TsMasterApi.tsapp_set_can_channel_count(MaxChannels);
|
||||
|
||||
// 3. 配置各通道波特率
|
||||
float arbKbps = float.Parse(ABitBaud) / 1000f;
|
||||
float dataKbps = float.Parse(DBitBaud) / 1000f;
|
||||
for (int ch = 0; ch < MaxChannels; ch++)
|
||||
{
|
||||
TsMasterApi.tsapp_configure_baudrate_canfd(
|
||||
ch, arbKbps, dataKbps,
|
||||
TLIBCANFDControllerType.lfdtISOCAN,
|
||||
TLIBCANFDControllerMode.lfdmNormal,
|
||||
EnableTerminalResistance);
|
||||
}
|
||||
|
||||
// 4. 连接硬件
|
||||
re = Connect();
|
||||
if (re != 0)
|
||||
{
|
||||
Debug.WriteLine($"CAN 连接失败,错误代码:{re}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 5. 注册接收监听(用于 DBC 信号解码广播)
|
||||
_instanceListener = new TCANFDQueueEvent_Win32(OnCanFdReceived);
|
||||
RegisterListener(_instanceListener);
|
||||
|
||||
_isOpened = true;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"打开设备异常:{ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭 CAN 卡设备:注销监听 → 断开连接。
|
||||
/// </summary>
|
||||
public void 关闭CAN卡设备()
|
||||
{
|
||||
if (!_isOpened && !ConnectFlag) return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_instanceListener != null)
|
||||
{
|
||||
UnRegisterListener(_instanceListener);
|
||||
_instanceListener = null;
|
||||
}
|
||||
DisConnect();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"关闭CAN卡设备异常:{ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isOpened = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化并启动指定通道(配置波特率,TSMaster 在 Connect 时已自动启动所有通道)。
|
||||
/// </summary>
|
||||
/// <param name="channel">通道号</param>
|
||||
public void 初始化并启动通道(uint channel)
|
||||
{
|
||||
if (channel >= MaxChannels) return;
|
||||
try
|
||||
{
|
||||
float arbKbps = float.Parse(ABitBaud) / 1000f;
|
||||
float dataKbps = float.Parse(DBitBaud) / 1000f;
|
||||
TsMasterApi.tsapp_configure_baudrate_canfd(
|
||||
(int)channel, arbKbps, dataKbps,
|
||||
TLIBCANFDControllerType.lfdtISOCAN,
|
||||
TLIBCANFDControllerMode.lfdmNormal,
|
||||
EnableTerminalResistance);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"初始化通道 {channel} 异常:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载通道 DBC 文件。
|
||||
/// </summary>
|
||||
/// <param name="channel">通道号</param>
|
||||
/// <param name="filePath">DBC 文件路径</param>
|
||||
/// <returns>true 表示加载成功</returns>
|
||||
public bool 加载通道DBC文件(uint channel, string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var re = LoadDBC(filePath, [(int)channel], out _);
|
||||
return re == 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"加载通道 {channel} DBC 文件异常:{ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CAN FD 接收回调:接收原始帧 → 查找 DBC → 解码信号 → 触发 OnDbcMessageDecoded 事件。
|
||||
/// </summary>
|
||||
private void OnCanFdReceived(ref int AObj, ref TLIBCANFD AData)
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
// 始终缓存最新报文,供界面轮询刷新
|
||||
int identifier = AData.FIdentifier;
|
||||
var canfdCopy = AData;
|
||||
RealTimeMessages[identifier] = canfdCopy;
|
||||
|
||||
if (OnDbcMessageDecoded == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
uint channel = AData.FIdxChn;
|
||||
if (channel >= DBCParse.MsgDatabase.Count) return;
|
||||
|
||||
// 在 DBC 数据库中查找匹配的报文
|
||||
var msgList = DBCParse.MsgDatabase[(int)channel];
|
||||
var match = msgList.FirstOrDefault(m => m.msg_id == identifier);
|
||||
if (match == null || match.signal_Name == null || match.signal_Name.Length == 0) return;
|
||||
|
||||
// 解码各信号值
|
||||
var signals = new DBCSignal[match.signal_Name.Length];
|
||||
for (int i = 0; i < match.signal_Name.Length; i++)
|
||||
{
|
||||
double value = 0;
|
||||
TsMasterApi.tsdb_get_signal_value_canfd(ref canfdCopy, match.msg_name, match.signal_Name[i], ref value);
|
||||
signals[i] = new DBCSignal
|
||||
{
|
||||
strName = Encoding.Default.GetBytes(match.signal_Name[i]),
|
||||
nRawvalue = value,
|
||||
nFactor = 1,
|
||||
nOffset = 0
|
||||
};
|
||||
}
|
||||
|
||||
var decoded = new DBCMessage
|
||||
{
|
||||
nID = (uint)identifier,
|
||||
nSignalCount = signals.Length,
|
||||
vSignals = signals
|
||||
};
|
||||
|
||||
OnDbcMessageDecoded?.Invoke(channel, decoded);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"DBC 信号解码异常:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
关闭CAN卡设备();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 初始化TSMasterCAN
|
||||
/// 初始化CAN驱动
|
||||
/// </summary>
|
||||
/// <param name="ProjectName"></param>
|
||||
/// <param name="filePath"></param>
|
||||
@@ -298,7 +38,7 @@ namespace TSMasterCAN
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放TSMasterCAN
|
||||
/// 释放CAN驱动
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public static void Release()
|
||||
@@ -391,7 +131,7 @@ namespace TSMasterCAN
|
||||
public static int LoadDBC(string filePath, int[] channel, out uint databaseID)
|
||||
{
|
||||
databaseID = 0;
|
||||
|
||||
if (!Path.Exists(filePath)) return -1;
|
||||
var re = TsMasterApi.tsdb_load_can_db(Path.GetFullPath(filePath), string.Join(",", channel), ref databaseID);
|
||||
foreach (var item in channel)
|
||||
{
|
||||
@@ -529,7 +269,7 @@ namespace TSMasterCAN
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置信号值
|
||||
/// </summary>
|
||||
|
||||
@@ -120,44 +120,8 @@ namespace TSMasterCAN
|
||||
NODE_RX_CANFD_MESSAGE_INDEX = 110,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DBC 解码后的信号信息(替代原 ZLG ZDBC.DBCSignal)。
|
||||
/// </summary>
|
||||
public struct DBCSignal
|
||||
{
|
||||
/// <summary>信号名称(原始字节,兼容 Encoding.Default 解码)</summary>
|
||||
public byte[] strName;
|
||||
/// <summary>原始值(TSMaster tsdb_get_signal_value_canfd 返回的物理值)</summary>
|
||||
public double nRawvalue;
|
||||
/// <summary>因子(TSMaster 返回物理值,因子固定为 1)</summary>
|
||||
public double nFactor;
|
||||
/// <summary>偏移(TSMaster 返回物理值,偏移固定为 0)</summary>
|
||||
public double nOffset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DBC 解码后的报文信息(替代原 ZLG ZDBC.DBCMessage)。
|
||||
/// 在 CAN 接收回调中对原始 TLIBCANFD 帧解码后构建此对象并触发 OnDbcMessageDecoded 事件。
|
||||
/// </summary>
|
||||
public class DBCMessage
|
||||
{
|
||||
/// <summary>报文 ID</summary>
|
||||
public uint nID;
|
||||
/// <summary>信号数量</summary>
|
||||
public int nSignalCount;
|
||||
/// <summary>信号数组</summary>
|
||||
public DBCSignal[] vSignals;
|
||||
}
|
||||
|
||||
public class DBCParse
|
||||
{
|
||||
private static DBCParse? _instance;
|
||||
/// <summary>单例实例,供 CAN.DBCParser 属性使用(MsgDatabase 等成员为 static,实例仅用于属性访问兼容)。</summary>
|
||||
public static DBCParse Instance => _instance ??= new DBCParse();
|
||||
|
||||
/// <summary>最大通道数(等于 MsgDatabase 的维度)</summary>
|
||||
public int MaxChannels => MsgDatabase.Count;
|
||||
|
||||
public static List<List<_Msg_>> MsgDatabase { get; set; } =
|
||||
[.. Enumerable.Range(0, 12).Select(_ => new List<_Msg_>())];
|
||||
public static can_network can_Network;
|
||||
|
||||
@@ -16,6 +16,7 @@ using System.Xml;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.ViewModelBase;
|
||||
using Prism.Events;
|
||||
using Prism.Commands;
|
||||
|
||||
namespace TestingModule.ViewModels
|
||||
{
|
||||
@@ -94,6 +95,44 @@ namespace TestingModule.ViewModels
|
||||
public ICommand DeleteStepCommand { get;set; }
|
||||
public ICommand TabSelectionChangedCommand { get;set; }
|
||||
public ICommand SelectionChangedCommand { get;set; }
|
||||
public ICommand OpenSubProgramCommand { get; set; }
|
||||
public ICommand GoBackCommand { get; set; }
|
||||
#endregion
|
||||
|
||||
#region 子程序导航
|
||||
|
||||
/// <summary>
|
||||
/// 当前显示的程序(绑定到 DataGrid 的 ItemsSource 根)。
|
||||
/// 委托到 ScopedContext.CurrentProgram,保证 ShellViewModel 也能通过 ScopedContext 访问。
|
||||
/// </summary>
|
||||
public ProgramVM CurrentProgram
|
||||
{
|
||||
get => _ScopedContext.CurrentProgram;
|
||||
set
|
||||
{
|
||||
if (_ScopedContext.CurrentProgram != value)
|
||||
{
|
||||
_ScopedContext.CurrentProgram = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string BreadcrumbPath
|
||||
{
|
||||
get => _ScopedContext.BreadcrumbPath;
|
||||
set
|
||||
{
|
||||
if (_ScopedContext.BreadcrumbPath != value)
|
||||
{
|
||||
_ScopedContext.BreadcrumbPath = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanGoBack => _ScopedContext.CanGoBack;
|
||||
|
||||
#endregion
|
||||
|
||||
public StepsManagerViewModel(IContainerProvider containerProvider, ScopedContext scopedContext, SystemConfig systemConfig, GlobalInfo globalInfo) : base(containerProvider)
|
||||
@@ -108,9 +147,31 @@ namespace TestingModule.ViewModels
|
||||
DeleteStepCommand = new DelegateCommand(DeleteStep);
|
||||
TabSelectionChangedCommand = new DelegateCommand<string>(TabSelectionChanged);
|
||||
SelectionChangedCommand = new DelegateCommand<object>(SelectionChanged);
|
||||
OpenSubProgramCommand = new DelegateCommand(OpenSubProgram);
|
||||
GoBackCommand = new DelegateCommand(GoBack);
|
||||
SubscribeStepCollections();
|
||||
Program.PropertyChanged += Program_PropertyChanged;
|
||||
Admin = _globalInfo.IsAdmin;
|
||||
|
||||
// 初始化 CurrentProgram 为根程序
|
||||
_ScopedContext.CurrentProgram = Program;
|
||||
_ScopedContext.BreadcrumbPath = "主程序";
|
||||
|
||||
// 订阅 ScopedContext 属性变化,外部(ShellViewModel)修改时转发通知给 UI
|
||||
_ScopedContext.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(ScopedContext.CurrentProgram))
|
||||
RaisePropertyChanged(nameof(CurrentProgram));
|
||||
else if (e.PropertyName == nameof(ScopedContext.BreadcrumbPath))
|
||||
RaisePropertyChanged(nameof(BreadcrumbPath));
|
||||
else if (e.PropertyName == nameof(ScopedContext.CanGoBack))
|
||||
RaisePropertyChanged(nameof(CanGoBack));
|
||||
};
|
||||
|
||||
// 订阅子程序导航事件(运行时由 StepRunning 发布)
|
||||
_eventAggregator.GetEvent<SubProgramNavigateEvent>()
|
||||
.Subscribe(OnSubProgramNavigate, ThreadOption.UIThread, false,
|
||||
payload => payload.Scope == _systemConfig.Title);
|
||||
}
|
||||
|
||||
private void SelectionChanged(object parameter)
|
||||
@@ -208,6 +269,72 @@ namespace TestingModule.ViewModels
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 子程序导航方法
|
||||
|
||||
/// <summary>
|
||||
/// 编辑模式:右键打开子程序
|
||||
/// </summary>
|
||||
private void OpenSubProgram()
|
||||
{
|
||||
if (SelectedStep == null || SelectedStep.StepType != "子程序" || SelectedStep.SubProgram == null)
|
||||
return;
|
||||
|
||||
// 压栈:保存当前程序
|
||||
_ScopedContext.SubProgramNavigationStack.Push(CurrentProgram);
|
||||
_ScopedContext.UpdateCanGoBack();
|
||||
// 更新面包屑
|
||||
var stepName = SelectedStep.Name ?? "子程序";
|
||||
BreadcrumbPath = $"{BreadcrumbPath} > {stepName}";
|
||||
// 切换到子程序
|
||||
CurrentProgram = SelectedStep.SubProgram;
|
||||
RaisePropertyChanged(nameof(CanGoBack));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回上一级程序
|
||||
/// </summary>
|
||||
private void GoBack()
|
||||
{
|
||||
if (_ScopedContext.SubProgramNavigationStack.Count == 0)
|
||||
return;
|
||||
|
||||
// 出栈:恢复上一级程序
|
||||
var parentProgram = _ScopedContext.SubProgramNavigationStack.Pop();
|
||||
_ScopedContext.UpdateCanGoBack();
|
||||
CurrentProgram = parentProgram;
|
||||
|
||||
// 更新面包屑:去掉最后一段
|
||||
var parts = BreadcrumbPath.Split(" > ");
|
||||
if (parts.Length > 1)
|
||||
BreadcrumbPath = string.Join(" > ", parts.Take(parts.Length - 1));
|
||||
else
|
||||
BreadcrumbPath = "主程序";
|
||||
|
||||
RaisePropertyChanged(nameof(CanGoBack));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 运行时:处理 StepRunning 发布的子程序导航事件
|
||||
/// </summary>
|
||||
private void OnSubProgramNavigate(SubProgramNavigatePayload payload)
|
||||
{
|
||||
if (payload.Action == NavigateAction.Enter && payload.SubProgram != null)
|
||||
{
|
||||
_ScopedContext.SubProgramNavigationStack.Push(CurrentProgram);
|
||||
_ScopedContext.UpdateCanGoBack();
|
||||
CurrentProgram = payload.SubProgram;
|
||||
var stepName = payload.StepName ?? "子程序";
|
||||
BreadcrumbPath = $"{BreadcrumbPath} > {stepName}";
|
||||
RaisePropertyChanged(nameof(CanGoBack));
|
||||
}
|
||||
else if (payload.Action == NavigateAction.Exit)
|
||||
{
|
||||
GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 辅助方法
|
||||
|
||||
/// <summary>
|
||||
@@ -304,9 +431,9 @@ namespace TestingModule.ViewModels
|
||||
Program.PropertyChanged -= Program_PropertyChanged;
|
||||
}
|
||||
|
||||
// 3. 【核心修复】必须显式退订 Prism 全局事件(AlarmEvent)
|
||||
// 注意:因为订阅时使用的是匿名 Lambda,最安全稳妥的退订方式是把整个事件上的当前 VM 订阅者全部注销
|
||||
// 3. 【核心修复】必须显式退订 Prism 全局事件
|
||||
_eventAggregator?.GetEvent<AlarmEvent>()?.Unsubscribe(null);
|
||||
_eventAggregator?.GetEvent<SubProgramNavigateEvent>()?.Unsubscribe(null);
|
||||
|
||||
// 4. 清空临时缓存集合与 UI 绑定列表,避免悬挂指针
|
||||
tmpCopyList?.Clear();
|
||||
|
||||
@@ -8,11 +8,26 @@
|
||||
xmlns:behaviors="clr-namespace:UIShare.Behaviors;assembly=UIShare"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<GroupBox Header="{Binding Title}">
|
||||
<DockPanel>
|
||||
<!-- 面包屑导航栏 -->
|
||||
<Border DockPanel.Dock="Top" Background="#F0F0F0" Padding="6,3" Visibility="{Binding CanGoBack, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<DockPanel>
|
||||
<Button DockPanel.Dock="Right" Content="↩ 返回上一级"
|
||||
Command="{Binding GoBackCommand}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
FontSize="12" Padding="8,2" Margin="8,0,0,0"/>
|
||||
<TextBlock Text="{Binding BreadcrumbPath}" VerticalAlignment="Center" FontSize="12" Foreground="#555"/>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
<TabControl SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}">
|
||||
<i:Interaction.Behaviors>
|
||||
<behaviors:TabControlSelectionChangedBehavior Command="{Binding TabSelectionChangedCommand}"
|
||||
@@ -29,7 +44,7 @@
|
||||
Background="Transparent"
|
||||
CanUserAddRows="False"
|
||||
CanUserSortColumns="False"
|
||||
ItemsSource="{Binding Program.StepCollection}"
|
||||
ItemsSource="{Binding CurrentProgram.StepCollection}"
|
||||
SelectedItem="{Binding SelectedStep, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
|
||||
SelectionMode="Extended"
|
||||
SelectionUnit="FullRow">
|
||||
@@ -120,6 +135,9 @@
|
||||
<MenuItem Header="删除"
|
||||
Foreground="Red"
|
||||
Command="{Binding DeleteStepCommand}" />
|
||||
<Separator/>
|
||||
<MenuItem Header="打开子程序"
|
||||
Command="{Binding OpenSubProgramCommand}" />
|
||||
</ContextMenu>
|
||||
</DataGrid.ContextMenu>
|
||||
|
||||
@@ -135,7 +153,7 @@
|
||||
Background="Transparent"
|
||||
CanUserAddRows="False"
|
||||
CanUserSortColumns="False"
|
||||
ItemsSource="{Binding Program.ErrorStepCollection}"
|
||||
ItemsSource="{Binding CurrentProgram.ErrorStepCollection}"
|
||||
SelectedItem="{Binding SelectedStep, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
|
||||
SelectionMode="Extended"
|
||||
SelectionUnit="FullRow">
|
||||
@@ -226,21 +244,16 @@
|
||||
<MenuItem Header="删除"
|
||||
Foreground="Red"
|
||||
Command="{Binding DeleteStepCommand}" />
|
||||
<Separator/>
|
||||
<MenuItem Header="打开子程序"
|
||||
Command="{Binding OpenSubProgramCommand}" />
|
||||
</ContextMenu>
|
||||
</DataGrid.ContextMenu>
|
||||
|
||||
<!-- 键盘 删除键绑定 Delete 命令 -->
|
||||
<!--<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="PreviewKeyDown">
|
||||
<i:InvokeCommandAction Command="{Binding DeleteStepCommand}"
|
||||
CommandParameter="{Binding SelectedStep}"
|
||||
PassEventArgsToCommand="True" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>-->
|
||||
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
|
||||
</Grid>
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TSMasterCAN;
|
||||
using TSMaster;
|
||||
namespace UIShare.GlobalVariable
|
||||
{
|
||||
public class CANMonitoringService
|
||||
{
|
||||
public bool IsStopped { get; set; } = false;
|
||||
public bool IsInitialized { get; set; } = false;
|
||||
public bool IsRegistered { get; set; } = false;
|
||||
private SystemConfig _systemConfig { get; set; }
|
||||
public CANMonitoringService(SystemConfig systemConfig)
|
||||
{
|
||||
_systemConfig = systemConfig;
|
||||
CANSignalBroadcaster.RegisterService(this);
|
||||
IsRegistered = true;
|
||||
}
|
||||
public int Init(CancellationToken ct = default)
|
||||
{
|
||||
int re = 0;
|
||||
if (IsInitialized == false)
|
||||
{
|
||||
re = CAN.Init(_systemConfig.TSMasterName);
|
||||
}
|
||||
if (IsInitialized == false)
|
||||
{
|
||||
re = CAN.RegisterListener(MonitorEvent);
|
||||
if (re == 0) IsInitialized = true;
|
||||
}
|
||||
return re;
|
||||
}
|
||||
public ConcurrentDictionary<string, TLIBCANFD> RealTimeMessages { get; set; } = new();
|
||||
public ConcurrentDictionary<string, double> RealTimeSignals { get; set; } = new();
|
||||
public void MonitorEvent(ref int AObj, ref TLIBCANFD AData)
|
||||
{
|
||||
if (IsStopped) return;
|
||||
byte[] oldbytes = null;
|
||||
|
||||
//记录至实时报文数据库
|
||||
var cpAData = AData;
|
||||
cpAData.FData = ArrayPool<byte>.Shared.Rent(64);
|
||||
Array.Copy(AData.FData, 0, cpAData.FData, 0, cpAData.FData.Length);
|
||||
var MessageName = $"{AData.FIdxChn}/{AData.FIdentifier}";
|
||||
if (RealTimeMessages.TryGetValue(MessageName, out var v))
|
||||
{
|
||||
oldbytes = v.FData;
|
||||
}
|
||||
RealTimeMessages[MessageName] = cpAData;
|
||||
|
||||
//记录至DBC数据库
|
||||
var dbcfind = DBCParse.MsgDatabase[AData.FIdxChn].FirstOrDefault(s => s.msg_id == cpAData.FIdentifier);
|
||||
if (dbcfind != null)
|
||||
{
|
||||
Array.Copy(cpAData.FData, 0, dbcfind.ACANFD.FData, 0, cpAData.FData.Length);
|
||||
dbcfind.ACANFD.FTimeUS = cpAData.FTimeUS;
|
||||
dbcfind.ACANFD.FIsFD = cpAData.FIsFD;
|
||||
dbcfind.ACANFD.FIsBRS = cpAData.FIsBRS;
|
||||
dbcfind.ACANFD.FIsESI = cpAData.FIsESI;
|
||||
dbcfind.ACANFD.FIsError = cpAData.FIsError;
|
||||
dbcfind.ACANFD.FIsRemote = cpAData.FIsRemote;
|
||||
dbcfind.ACANFD.FIsExt = cpAData.FIsExt;
|
||||
}
|
||||
|
||||
if (oldbytes is not null) ArrayPool<byte>.Shared.Return(oldbytes);
|
||||
|
||||
var id = AData.FIdentifier;
|
||||
var ch = AData.FIdxChn;
|
||||
|
||||
var canSignalList = _systemConfig.ConfigurationList.Where(s => s.MessageID == id && s.Channel == ch).ToArray();
|
||||
|
||||
if (canSignalList.Length > 0)
|
||||
{
|
||||
var find = DBCParse.MsgDatabase[ch].First(s => s.msg_id == id);
|
||||
foreach (var item in canSignalList)
|
||||
{
|
||||
double Signalre = double.NaN;
|
||||
var re = CAN.GetSignalValue(ref cpAData, item.MessageName, item.SignalName, ref Signalre);
|
||||
//Debug.Assert(re == 0);
|
||||
var SinalName = $"{AData.FIdxChn}/{item.MessageName}/{item.SignalName}";
|
||||
RealTimeSignals[SinalName] = Signalre;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止监测:从广播器注销并清理实时数据。
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
IsStopped = true;
|
||||
if (IsRegistered)
|
||||
{
|
||||
CANSignalBroadcaster.UnregisterService(this);
|
||||
IsRegistered = false;
|
||||
}
|
||||
RealTimeSignals.Clear();
|
||||
RealTimeMessages.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,131 +1,191 @@
|
||||
using Model.Models;
|
||||
using Prism.Events;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TSMasterCAN;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace UIShare.GlobalVariable
|
||||
{
|
||||
/// <summary>
|
||||
/// CAN 信号广播器(全局单例):
|
||||
/// 统一订阅 GlobalInfo.CanPool 中所有已实例化的 ZLGCANFD 设备,
|
||||
/// 将 DBC 解码后的信号值广播给所有引用该 CAN 设备的作用域,
|
||||
/// 并同步检查各作用域 ValueLimitList 的超限报警。
|
||||
/// 不再订阅 CAN 实体实例的事件,改为从所有已注册的 <see cref="CANMonitoringService"/>
|
||||
/// 的 RealTimeSignals 字典中轮询读取信号值,并通过 <see cref="HardwareDataReportedEvent"/> 广播。
|
||||
/// </summary>
|
||||
public class CANSignalBroadcaster : IDisposable
|
||||
public class CANSignalBroadcaster
|
||||
{
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly GlobalInfo _globalInfo;
|
||||
private bool _disposed;
|
||||
private readonly SystemConfig _systemConfig;
|
||||
|
||||
/// <summary>已订阅解码事件的 CANFD 实例 → 委托 映射</summary>
|
||||
private readonly Dictionary<CAN, Action<uint, DBCMessage>> _handlers = new();
|
||||
public CANSignalBroadcaster(GlobalInfo globalInfo, IEventAggregator eventAggregator)
|
||||
/// <summary>全局已注册的 CANMonitoringService 实例列表(静态,跨作用域共享)</summary>
|
||||
private static readonly ConcurrentDictionary<CANMonitoringService, byte> _registeredServices = new();
|
||||
|
||||
private CancellationTokenSource? _cts;
|
||||
private Task? _broadcastTask;
|
||||
|
||||
/// <summary>广播轮询间隔(毫秒)</summary>
|
||||
public int PollingIntervalMs { get; set; } = 100;
|
||||
|
||||
public CANSignalBroadcaster(SystemConfig systemConfig, IEventAggregator eventAggregator)
|
||||
{
|
||||
_globalInfo = globalInfo;
|
||||
_systemConfig = systemConfig;
|
||||
_eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扫描 GlobalInfo.CanPool 中已创建的 CANFD 实例并订阅解码事件。
|
||||
/// 幂等:已订阅的实例不会重复订阅。
|
||||
/// </summary>
|
||||
public void Discover()
|
||||
#region 服务注册(供 CANMonitoringService 调用)
|
||||
|
||||
/// <summary>注册一个 CANMonitoringService,使其信号纳入广播</summary>
|
||||
public static void RegisterService(CANMonitoringService service)
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
foreach (var kvp in _globalInfo.CanPool)
|
||||
{
|
||||
string fingerprint = kvp.Key;
|
||||
var lazy = kvp.Value;
|
||||
if (!lazy.IsValueCreated || lazy.Value == null) continue;
|
||||
|
||||
var canfd = lazy.Value;
|
||||
if (_handlers.ContainsKey(canfd)) continue;
|
||||
|
||||
// 使用闭包捕获指纹,回调时即可区分不同 CAN 卡
|
||||
Action<uint, DBCMessage> handler = (channel, msg) => OnDbcMessageDecoded(fingerprint, channel, msg);
|
||||
canfd.OnDbcMessageDecoded += handler;
|
||||
_handlers[canfd] = handler;
|
||||
}
|
||||
_registeredServices.TryAdd(service, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动广播器(目前 Discover 已完成订阅,此处保留以兼容 HardwareDataBroadcaster 的使用模式)。
|
||||
/// </summary>
|
||||
/// <summary>注销一个 CANMonitoringService</summary>
|
||||
public static void UnregisterService(CANMonitoringService service)
|
||||
{
|
||||
_registeredServices.TryRemove(service, out _);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 启动 / 停止
|
||||
|
||||
/// <summary>启动广播(幂等:多次调用只启动一次)</summary>
|
||||
public void Start()
|
||||
{
|
||||
Discover();
|
||||
if (_broadcastTask != null && !_broadcastTask.IsCompleted) return;
|
||||
|
||||
_cts = new CancellationTokenSource();
|
||||
_broadcastTask = Task.Run(() => BroadcastLoop(_cts.Token));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DBC 解码回调:提取所有信号,向引用该 CAN 设备的作用域广播,并检查报警。
|
||||
/// </summary>
|
||||
private void OnDbcMessageDecoded(string canFingerprint, uint channel, DBCMessage msg)
|
||||
/// <summary>停止广播</summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_cts?.Cancel();
|
||||
_broadcastTask = null;
|
||||
}
|
||||
|
||||
string signalFingerprint = BuildFingerprint(canFingerprint, channel);
|
||||
var now = DateTime.Now;
|
||||
/// <summary>兼容旧接口:Discover 已无需执行任何操作</summary>
|
||||
public void Discover() { }
|
||||
|
||||
// 获取引用该 CAN 设备的所有作用域
|
||||
var scopes = GetScopesForFingerprint(canFingerprint);
|
||||
if (scopes.Count == 0) return;
|
||||
#endregion
|
||||
|
||||
for (int i = 0; i < msg.nSignalCount; i++)
|
||||
#region 广播核心逻辑
|
||||
|
||||
/// <summary>
|
||||
/// 轮询所有已注册的 CANMonitoringService 的 RealTimeSignals,
|
||||
/// 结合 ConfigurationList 映射出 MessageID/Channel,广播 HardwareDataReportedEvent。
|
||||
/// </summary>
|
||||
private async Task BroadcastLoop(CancellationToken ct)
|
||||
{
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
var signal = msg.vSignals[i];
|
||||
string signalName = Encoding.Default.GetString(signal.strName).TrimEnd('\0');
|
||||
if (string.IsNullOrEmpty(signalName)) continue;
|
||||
|
||||
double physicalValue = signal.nRawvalue * signal.nFactor + signal.nOffset;
|
||||
string methodName = BuildMethodName(msg.nID, signalName);
|
||||
|
||||
foreach (var scope in scopes)
|
||||
try
|
||||
{
|
||||
_eventAggregator.GetEvent<HardwareDataReportedEvent>().Publish(new HardwareReportArgs
|
||||
{
|
||||
Scope = scope,
|
||||
HardwareFingerprint = signalFingerprint,
|
||||
MethodName = methodName,
|
||||
Value = physicalValue,
|
||||
Time = now
|
||||
});
|
||||
// 预构建信号名 → 配置 的映射(避免内层循环重复查找)
|
||||
var configMap = BuildConfigMap();
|
||||
|
||||
string MonitorStatus = ValueLimitAlarmHelper.CheckAlarm(scope, signalFingerprint, methodName, physicalValue, _globalInfo);
|
||||
if (MonitorStatus != "" && MonitorStatus != "未报警")
|
||||
string scope = _systemConfig.Title;
|
||||
|
||||
foreach (var service in _registeredServices.Keys)
|
||||
{
|
||||
_eventAggregator.GetEvent<AlarmEvent>().Publish((scope,canFingerprint, MonitorStatus));
|
||||
if (service.IsStopped) continue;
|
||||
|
||||
foreach (var kvp in service.RealTimeSignals)
|
||||
{
|
||||
if (ct.IsCancellationRequested) return;
|
||||
|
||||
// 信号 Key 格式: "{channel}/{MessageName}/{SignalName}"
|
||||
if (!TryParseSignalKey(kvp.Key, out int channel, out string? messageName, out string? signalName))
|
||||
continue;
|
||||
|
||||
// 从配置映射中查找对应的 MessageID
|
||||
if (!configMap.TryGetValue($"{channel}/{messageName}/{signalName}", out var cfg))
|
||||
continue;
|
||||
|
||||
string canFingerprint = $"CAN:{channel}";
|
||||
string fingerprint = BuildFingerprint(canFingerprint, (uint)channel);
|
||||
string methodName = BuildMethodName((uint)cfg.MessageID, signalName);
|
||||
|
||||
// 广播信号值
|
||||
_eventAggregator.GetEvent<HardwareDataReportedEvent>().Publish(new HardwareReportArgs
|
||||
{
|
||||
Scope = scope,
|
||||
HardwareFingerprint = fingerprint,
|
||||
MethodName = methodName,
|
||||
Value = kvp.Value,
|
||||
Time = DateTime.Now
|
||||
});
|
||||
|
||||
// 报警检查
|
||||
string alarmStatus = ValueLimitAlarmHelper.CheckAlarm(fingerprint, methodName, kvp.Value, _systemConfig);
|
||||
if (!string.IsNullOrEmpty(alarmStatus) && alarmStatus != "未报警")
|
||||
{
|
||||
_eventAggregator.GetEvent<AlarmEvent>().Publish((scope, canFingerprint, alarmStatus));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(PollingIntervalMs, ct);
|
||||
}
|
||||
catch (OperationCanceledException) { break; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LoggerHelper.Error($"CANSignalBroadcaster 广播异常: {ex.Message}");
|
||||
await Task.Delay(1000, ct); // 异常后等待一段时间再重试
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>获取指定硬件指纹当前被哪些作用域引用</summary>
|
||||
private List<string> GetScopesForFingerprint(string fingerprint)
|
||||
/// <summary>
|
||||
/// 从 SystemConfig.ConfigurationList 构建 "channel/MessageName/SignalName" → CANSignalConfig 的映射
|
||||
/// </summary>
|
||||
private Dictionary<string, CANSignalConfig> BuildConfigMap()
|
||||
{
|
||||
if (_globalInfo.DeviceAndScopeDic.TryGetValue(fingerprint, out var lazy))
|
||||
var map = new Dictionary<string, CANSignalConfig>(StringComparer.OrdinalIgnoreCase);
|
||||
if (_systemConfig?.ConfigurationList == null) return map;
|
||||
|
||||
foreach (var cfg in _systemConfig.ConfigurationList)
|
||||
{
|
||||
var scopeList = lazy.Value;
|
||||
lock (scopeList) return scopeList.ToList();
|
||||
if (string.IsNullOrEmpty(cfg.SignalName) || string.IsNullOrEmpty(cfg.MessageName)) continue;
|
||||
string key = $"{cfg.Channel}/{cfg.MessageName}/{cfg.SignalName}";
|
||||
map.TryAdd(key, cfg); // 第一个匹配的优先
|
||||
}
|
||||
return new List<string>();
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成 CAN 信号的 DisplayName 格式:"{MessageName}.{SignalName}"
|
||||
/// </summary>
|
||||
/// <summary>解析信号 Key: "{channel}/{MessageName}/{SignalName}"</summary>
|
||||
private static bool TryParseSignalKey(string key, out int channel, out string? messageName, out string? signalName)
|
||||
{
|
||||
channel = 0;
|
||||
messageName = null;
|
||||
signalName = null;
|
||||
|
||||
var parts = key.Split('/');
|
||||
if (parts.Length < 3) return false;
|
||||
|
||||
if (!int.TryParse(parts[0], out channel)) return false;
|
||||
messageName = parts[1];
|
||||
signalName = parts[2];
|
||||
return !string.IsNullOrEmpty(messageName) && !string.IsNullOrEmpty(signalName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 静态工具方法(保持向后兼容)
|
||||
|
||||
/// <summary>生成 CAN 信号的 DisplayName 格式:"{MessageName}.{SignalName}"</summary>
|
||||
public static string BuildDisplayName(string messageName, string signalName)
|
||||
{
|
||||
return $"{messageName}.{signalName}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成 CAN 信号的 MethodName 格式:"{MessageId:X}.{SignalName}"
|
||||
/// </summary>
|
||||
/// <summary>生成 CAN 信号的 MethodName 格式:"{MessageId:X}.{SignalName}"</summary>
|
||||
public static string BuildMethodName(uint messageId, string signalName)
|
||||
{
|
||||
return $"{messageId:X}.{signalName}";
|
||||
@@ -140,17 +200,6 @@ namespace UIShare.GlobalVariable
|
||||
return $"{canDeviceFingerprint}:{channel}";
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
|
||||
foreach (var kvp in _handlers)
|
||||
{
|
||||
if (kvp.Key != null)
|
||||
kvp.Key.OnDbcMessageDecoded -= kvp.Value;
|
||||
}
|
||||
_handlers.Clear();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ using System.Reflection;
|
||||
using TSMasterCAN;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
using TSMasterCAN;
|
||||
|
||||
namespace UIShare.GlobalVariable
|
||||
{
|
||||
@@ -25,6 +24,7 @@ namespace UIShare.GlobalVariable
|
||||
{
|
||||
private object _lockObj = new object();
|
||||
public SystemConfig _systemConfig { get; set; }
|
||||
public CANMonitoringService _CANMonitoringService { get; set; }
|
||||
private readonly GlobalInfo _globalInfo;
|
||||
private readonly string _scopeName;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
@@ -35,7 +35,6 @@ namespace UIShare.GlobalVariable
|
||||
|
||||
/// <summary>类名 → Type 的反射缓存(仅扫描一次)。</summary>
|
||||
private static readonly IReadOnlyDictionary<string, Type> _deviceTypeMap = BuildDeviceTypeMap();
|
||||
public CAN CANFD { get; set; }
|
||||
public IOBoardGroup IOGroup { get; set; }
|
||||
|
||||
public DeviceManager(SystemConfig systemConfig, GlobalInfo globalInfo, IEventAggregator eventAggregator)
|
||||
@@ -43,11 +42,17 @@ namespace UIShare.GlobalVariable
|
||||
_systemConfig = systemConfig;
|
||||
_globalInfo = globalInfo;
|
||||
_eventAggregator = eventAggregator;
|
||||
_CANMonitoringService=new CANMonitoringService(_systemConfig);
|
||||
// 用 SystemConfig.Title 作为作用域唯一标识,无需反查 ConfigDic
|
||||
_scopeName = _systemConfig.Title;
|
||||
InitDevices();
|
||||
InitCAN();
|
||||
}
|
||||
|
||||
public void InitCAN()
|
||||
{
|
||||
var re1 = _CANMonitoringService.Init();
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据设备配置提取唯一的硬件指纹字符串。
|
||||
/// <para>Tcp → "Tcp:IP:Port";Serial → "Serial:PortName";无法识别则返回空字符串。</para>
|
||||
@@ -98,55 +103,6 @@ namespace UIShare.GlobalVariable
|
||||
{
|
||||
if (config == null || !config.IsEnabled) continue;
|
||||
|
||||
// CAN 设备:ZLGCANFD 不实现 IBaseInterface,通过 SystemConfig.CANFD 单独管理,
|
||||
// 按指纹从全局 CanPool 创建/复用实例,并注册作用域引用计数。
|
||||
if (string.Equals(config.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var fingerprint = ExtractHardwareFingerprint(config);
|
||||
if (string.IsNullOrEmpty(fingerprint))
|
||||
{
|
||||
LoggerHelper.Warn($"设备 [{config.DeviceName}] 无法提取硬件指纹(连接方式={config.ConnectionType}),已跳过。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config.CANConfig == null)
|
||||
{
|
||||
LoggerHelper.Warn($"设备 [{config.DeviceName}] 缺少 CAN 连接参数,已跳过。");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 按指纹全局唯一创建同星 CAN 实例(maxChannels 默认 4,对应 USBCANFD-400U)
|
||||
// 波特率与终端电阻从 CANConfigVM 传入,初始化并启动通道 时直接使用
|
||||
var canLazy = _globalInfo.CanPool.GetOrAdd(fingerprint, key => new Lazy<CAN>(() =>
|
||||
new CAN(config.CANConfig.DeviceType, config.CANConfig.DeviceIndex, 4,
|
||||
config.CANConfig.ABitBaud, config.CANConfig.DBitBaud, config.CANConfig.EnableTerminalResistance)));
|
||||
|
||||
_systemConfig.CANFD = canLazy.Value;
|
||||
CANFD = canLazy.Value;
|
||||
|
||||
// 注册作用域引用计数
|
||||
if (!string.IsNullOrEmpty(_scopeName))
|
||||
{
|
||||
var scopeList = _globalInfo.DeviceAndScopeDic.GetOrAdd(fingerprint,
|
||||
_ => new Lazy<List<string>>(() => new List<string>())).Value;
|
||||
lock (scopeList)
|
||||
{
|
||||
if (!scopeList.Contains(_scopeName))
|
||||
scopeList.Add(_scopeName);
|
||||
}
|
||||
}
|
||||
|
||||
LoggerHelper.Info($"已加载 CAN 设备 [{config.DeviceName}] 指纹={fingerprint}(通过 SystemConfig.CANFD 管理)");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify(_scopeName, $"CAN 设备 [{config.DeviceName}] 实例化失败:{ex.Message}");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(config.DeviceType) ||
|
||||
!_deviceTypeMap.TryGetValue(config.DeviceType, out var deviceType))
|
||||
{
|
||||
@@ -302,7 +258,7 @@ namespace UIShare.GlobalVariable
|
||||
// CAN 设备:直接关闭 CAN 卡
|
||||
if (info != null && string.Equals(info.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await CloseCanAsync(info);
|
||||
CloseCan();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -325,7 +281,7 @@ namespace UIShare.GlobalVariable
|
||||
|
||||
lock (_lockObj)
|
||||
{
|
||||
if (DeviceMap.Count == 0 && (CANFD == null)) return;
|
||||
if (DeviceMap.Count == 0 ) return;
|
||||
|
||||
foreach (var kvp in DeviceMap)
|
||||
{
|
||||
@@ -338,17 +294,7 @@ namespace UIShare.GlobalVariable
|
||||
}
|
||||
}
|
||||
|
||||
// CAN 设备:直接关闭 CAN 卡
|
||||
if (CANFD != null)
|
||||
{
|
||||
var canInfo = _systemConfig?.DeviceList?
|
||||
.FirstOrDefault(d => d != null && string.Equals(d.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase));
|
||||
if (canInfo != null)
|
||||
{
|
||||
tasks.Add(CloseCanAsync(canInfo));
|
||||
}
|
||||
}
|
||||
|
||||
CAN.DisConnect();
|
||||
await Task.WhenAll(tasks);
|
||||
LoggerHelper.Info("所有设备已执行关闭操作。");
|
||||
}
|
||||
@@ -456,26 +402,11 @@ namespace UIShare.GlobalVariable
|
||||
/// </summary>
|
||||
private async Task<bool> ConnectCanAsync(DeviceInfoVM info)
|
||||
{
|
||||
string name = info.DeviceName ?? "CAN";
|
||||
|
||||
try
|
||||
{
|
||||
if (CANFD == null)
|
||||
{
|
||||
LoggerHelper.Warn($"CAN 设备 [{name}] 尚未实例化,无法连接。");
|
||||
info.IsConnected = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.IsConnected)
|
||||
{
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 已连接,跳过。");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ok = await Task.Run(() =>
|
||||
{
|
||||
if (!CANFD.打开设备()) return false;
|
||||
// 自动加载 DBC 文件
|
||||
if (_systemConfig?.DBCAutoLoadList != null)
|
||||
{
|
||||
@@ -495,8 +426,7 @@ namespace UIShare.GlobalVariable
|
||||
LoggerHelper.Warn($"CAN 通道 {item.DBCChannel} 自动加载 DBC 失败:文件不存在 [{item.DBCFilePath}]");
|
||||
continue;
|
||||
}
|
||||
CANFD.初始化并启动通道((uint)item.DBCChannel);
|
||||
bool loadOk = CANFD.加载通道DBC文件((uint)item.DBCChannel, item.DBCFilePath);
|
||||
bool loadOk = CAN.LoadDBC(item.DBCFilePath,new int[] { item.DBCChannel },out _ )==0;
|
||||
if (loadOk)
|
||||
{
|
||||
LoggerHelper.Info($"CAN 通道 {item.DBCChannel} 已自动加载 DBC:{item.DBCFilePath}");
|
||||
@@ -518,16 +448,16 @@ namespace UIShare.GlobalVariable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CAN.Connect() != 0) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
info.IsConnected = ok;
|
||||
|
||||
if (ok)
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 连接成功,已初始化 {CANFD.DBCParser.MaxChannels} 个通道。");
|
||||
LoggerHelper.Info($"CAN 设备 连接成功");
|
||||
else
|
||||
LoggerHelper.Warn($"CAN 设备 [{name}] 连接失败。");
|
||||
LoggerHelper.Warn($"CAN 设备连接失败。");
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -535,7 +465,7 @@ namespace UIShare.GlobalVariable
|
||||
{
|
||||
info.IsConnected = false;
|
||||
var inner = ex.InnerException?.Message ?? ex.Message;
|
||||
LoggerHelper.ErrorWithNotify(_scopeName, $"CAN 设备 [{name}] 连接异常:{inner}");
|
||||
LoggerHelper.ErrorWithNotify(_scopeName, $"CAN 设备 连接异常:{inner}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -543,36 +473,9 @@ namespace UIShare.GlobalVariable
|
||||
/// <summary>
|
||||
/// 关闭 CAN 卡
|
||||
/// </summary>
|
||||
private async Task CloseCanAsync(DeviceInfoVM info)
|
||||
private void CloseCan()
|
||||
{
|
||||
string name = info.DeviceName ?? "CAN";
|
||||
|
||||
try
|
||||
{
|
||||
if (CANFD == null)
|
||||
{
|
||||
info.IsConnected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info.IsConnected)
|
||||
{
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 本就处于断开状态。");
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Run(() => CANFD.关闭CAN卡设备());
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 已成功关闭连接。");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var inner = ex.InnerException?.Message ?? ex.Message;
|
||||
LoggerHelper.Error($"CAN 设备 [{name}] 关闭连接时出现异常: {inner}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
info.IsConnected = false;
|
||||
}
|
||||
CAN.DisConnect();
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, Type> BuildDeviceTypeMap()
|
||||
@@ -620,6 +523,9 @@ namespace UIShare.GlobalVariable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// 停止 CAN 信号监测服务
|
||||
_CANMonitoringService?.Stop();
|
||||
|
||||
if (string.IsNullOrEmpty(_scopeName)) return;
|
||||
|
||||
// 遍历当前作用域用到的所有指纹,逐一移除本作用域的引用
|
||||
@@ -655,16 +561,6 @@ namespace UIShare.GlobalVariable
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试从 CanPool 取出并销毁
|
||||
if (_globalInfo.CanPool.TryRemove(fingerprint, out var canLazy))
|
||||
{
|
||||
if (canLazy.IsValueCreated)
|
||||
{
|
||||
try { canLazy.Value.Dispose(); }
|
||||
catch { /* 销毁时忽略异常 */ }
|
||||
LoggerHelper.Info($"指纹 [{fingerprint}] 无作用域引用,已销毁 CAN 设备实例。");
|
||||
}
|
||||
}
|
||||
|
||||
// 同步清除 DeviceAndScopeDic 中的空条目
|
||||
_globalInfo.DeviceAndScopeDic.TryRemove(fingerprint, out _);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using DeviceCommand.Base;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,9 +15,72 @@ using UIShare.UIViewModel;
|
||||
|
||||
namespace UIShare.GlobalVariable
|
||||
{
|
||||
public class ScopedContext
|
||||
public class ScopedContext : BindableBase
|
||||
{
|
||||
private static readonly Random _randomSeed = new Random();
|
||||
|
||||
#region 子程序导航栈(台架隔离)
|
||||
|
||||
/// <summary>
|
||||
/// 子程序导航栈:记录从根程序进入子程序的路径。
|
||||
/// 每个台架(ScopedContext 实例)各自维护一个独立的栈,互不干扰。
|
||||
/// </summary>
|
||||
public Stack<ProgramVM> SubProgramNavigationStack { get; } = new();
|
||||
|
||||
private ProgramVM _currentProgram;
|
||||
/// <summary>
|
||||
/// 当前在 StepManager 中显示的程序(可能是根程序,也可能是某层子程序)。
|
||||
/// UI 的 DataGrid 绑定此属性,而非直接绑定 Program。
|
||||
/// </summary>
|
||||
public ProgramVM CurrentProgram
|
||||
{
|
||||
get => _currentProgram;
|
||||
set => SetProperty(ref _currentProgram, value);
|
||||
}
|
||||
|
||||
private string _breadcrumbPath = "主程序";
|
||||
/// <summary>
|
||||
/// 面包屑导航路径,如 "主程序 > 连接流程 > 初始化"
|
||||
/// </summary>
|
||||
public string BreadcrumbPath
|
||||
{
|
||||
get => _breadcrumbPath;
|
||||
set => SetProperty(ref _breadcrumbPath, value);
|
||||
}
|
||||
|
||||
private bool _canGoBack;
|
||||
/// <summary>
|
||||
/// 是否可以返回上一级(导航栈不为空时为 true)
|
||||
/// </summary>
|
||||
public bool CanGoBack
|
||||
{
|
||||
get => _canGoBack;
|
||||
set => SetProperty(ref _canGoBack, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空导航栈,回到根程序界面
|
||||
/// </summary>
|
||||
public void ResetNavigation()
|
||||
{
|
||||
SubProgramNavigationStack.Clear();
|
||||
CurrentProgram = Program;
|
||||
BreadcrumbPath = "主程序";
|
||||
CanGoBack = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据栈状态刷新 CanGoBack
|
||||
/// </summary>
|
||||
public void UpdateCanGoBack() => CanGoBack = SubProgramNavigationStack.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// 当前导航深度(0 = 根程序,1 = 第一层子程序,以此类推)
|
||||
/// </summary>
|
||||
public int NavigationDepth => SubProgramNavigationStack.Count;
|
||||
|
||||
#endregion
|
||||
|
||||
public ProgramVM Program { get; set; } = new();
|
||||
public String SelectedStepList { get; set; } = "主程序";
|
||||
public string CurrentFilePath { get; set; }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using UIShare.PubEvent;
|
||||
using Common.Tools;
|
||||
using Logger;
|
||||
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Model.Entity;
|
||||
using Service.Interface;
|
||||
@@ -181,7 +182,21 @@ namespace UIShare
|
||||
_scopedContext.SingleStep = false;
|
||||
}
|
||||
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"开始执行子程序 [ {step.Index} ] [ {step.Name} ] ", depth);
|
||||
// 发布进入子程序导航事件
|
||||
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
|
||||
{
|
||||
Scope = _systemConfig.Title,
|
||||
Action = NavigateAction.Enter,
|
||||
SubProgram = step.SubProgram,
|
||||
StepName = step.Name
|
||||
});
|
||||
stepSuccess = await ExecuteSteps(step.SubProgram, depth + 1, cancellationToken);
|
||||
// 发布退出子程序导航事件
|
||||
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
|
||||
{
|
||||
Scope = _systemConfig.Title,
|
||||
Action = NavigateAction.Exit
|
||||
});
|
||||
UpdateCurrentStepResult(step, true, stepSuccess, depth);
|
||||
if (SubSingleStep)
|
||||
{
|
||||
@@ -239,6 +254,7 @@ namespace UIShare
|
||||
tmpParameters.Clear();
|
||||
TestRoundID = Guid.NewGuid();
|
||||
}
|
||||
int initialLoopStackCount = loopStack.Count;
|
||||
foreach (var item in program.Parameters)
|
||||
{
|
||||
tmpParameters.TryAdd(item.ID, item);
|
||||
@@ -356,7 +372,21 @@ namespace UIShare
|
||||
_scopedContext.SingleStep = false;
|
||||
}
|
||||
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"开始执行子程序 [ {step.Index} ] [ {step.Name} ] ", depth);
|
||||
// 发布进入子程序导航事件
|
||||
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
|
||||
{
|
||||
Scope = _systemConfig.Title,
|
||||
Action = NavigateAction.Enter,
|
||||
SubProgram = step.SubProgram,
|
||||
StepName = step.Name
|
||||
});
|
||||
stepSuccess = await ExecuteSteps(step.SubProgram, depth + 1, cancellationToken);
|
||||
// 发布退出子程序导航事件
|
||||
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
|
||||
{
|
||||
Scope = _systemConfig.Title,
|
||||
Action = NavigateAction.Exit
|
||||
});
|
||||
UpdateCurrentStepResult(step, true, stepSuccess, depth);
|
||||
if (SubSingleStep)
|
||||
{
|
||||
@@ -403,9 +433,15 @@ namespace UIShare
|
||||
_eventAggregator.GetEvent<RunSingalCompletedEvent>().Publish("Play");
|
||||
}
|
||||
await SaveStepRecordAsync(step, depth, false);
|
||||
// 仅检查本层执行期间压入的循环是否全部弹出,不关心父程序遗留的循环上下文
|
||||
}
|
||||
}
|
||||
bool finalResult = loopStack.Count == initialLoopStackCount && stepSuccess;
|
||||
|
||||
if (depth > 0) // 子程序
|
||||
{
|
||||
return finalResult;
|
||||
}
|
||||
return loopStack.Count == 0 && stepSuccess;
|
||||
}
|
||||
|
||||
@@ -578,11 +614,7 @@ namespace UIShare
|
||||
{
|
||||
try
|
||||
{
|
||||
if(targetType.Name== "ZLGCANFD")
|
||||
{
|
||||
instance = _deviceManager.CANFD;
|
||||
}
|
||||
else if (targetType.Name == "IOBoardGroup")
|
||||
if (targetType.Name == "IOBoardGroup")
|
||||
{
|
||||
instance = _deviceManager.IOGroup;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,22 @@ namespace UIShare.GlobalVariable
|
||||
{
|
||||
if (globalInfo?.ConfigDic == null) return "";
|
||||
if (!globalInfo.ConfigDic.TryGetValue(scope, out var systemConfig)) return "";
|
||||
if (systemConfig.ValueLimitList == null) return "";
|
||||
return CheckAlarm(fingerprint, methodName, value, systemConfig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接根据 SystemConfig 的 ValueLimitList 检查当前值是否超限。
|
||||
/// 适用于不持有 GlobalInfo 引用的场景(如 CANSignalBroadcaster)。
|
||||
/// </summary>
|
||||
public static string CheckAlarm(string fingerprint, string methodName, double value, SystemConfig systemConfig)
|
||||
{
|
||||
if (systemConfig?.ValueLimitList == null) return "";
|
||||
|
||||
var limit = systemConfig.ValueLimitList.FirstOrDefault(x =>
|
||||
x.Fingerprint == fingerprint && x.MethodName == methodName);
|
||||
if (limit == null) return "";
|
||||
if (value > limit.UpperExtreme)
|
||||
|
||||
if (value > limit.UpperExtreme)
|
||||
{
|
||||
limit.IsAlarm = true;
|
||||
limit.AlarmSatus = AlarmStatus.超上极限;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using Prism.Events;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace UIShare.PubEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 子程序导航事件:运行时进入/退出子程序时发布,
|
||||
/// StepsManagerViewModel 订阅后自动切换显示。
|
||||
/// </summary>
|
||||
public class SubProgramNavigateEvent : PubSubEvent<SubProgramNavigatePayload>
|
||||
{
|
||||
}
|
||||
|
||||
public class SubProgramNavigatePayload
|
||||
{
|
||||
/// <summary>目标台架的作用域标识</summary>
|
||||
public string Scope { get; set; } = "";
|
||||
|
||||
/// <summary>Enter = 进入子程序,Exit = 退出回到上一级</summary>
|
||||
public NavigateAction Action { get; set; }
|
||||
|
||||
/// <summary>进入时:子程序的 ProgramVM;退出时可为 null</summary>
|
||||
public ProgramVM? SubProgram { get; set; }
|
||||
|
||||
/// <summary>子程序步骤的名称(用于面包屑显示)</summary>
|
||||
public string? StepName { get; set; }
|
||||
}
|
||||
|
||||
public enum NavigateAction
|
||||
{
|
||||
Enter,
|
||||
Exit
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
@@ -26,4 +26,9 @@
|
||||
<ProjectReference Include="..\Service\Service.csproj" />
|
||||
<ProjectReference Include="..\TSMasterCAN\TSMasterCAN.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Interop.TSMasterAPI">
|
||||
<HintPath>..\TSMasterCAN\Interop.TSMasterAPI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,443 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
将极电子程序 .ats 文件转换为 ACP 项目 .ACP 文件
|
||||
- 设备 FullName 映射
|
||||
- 方法名映射
|
||||
- 参数格式转换(.ats → .ACP)
|
||||
- IOBoardGroup 只保留台架序号参数
|
||||
"""
|
||||
|
||||
import json
|
||||
import glob
|
||||
import os
|
||||
import uuid
|
||||
import copy
|
||||
|
||||
# ============================================================
|
||||
# 1. 设备 FullName 映射
|
||||
# ============================================================
|
||||
DEVICE_MAPPING = {
|
||||
# 相同设备(无需改 FullName)
|
||||
"TSMasterCAN.CAN": "TSMasterCAN.CAN",
|
||||
"Command.Delay": "Command.Delay",
|
||||
"Command.CommandMath": "Command.CommandMath",
|
||||
"DeviceCommand.Device.PW8001": "DeviceCommand.Device.PW8001",
|
||||
|
||||
# 需要映射的设备
|
||||
"DeviceCommand.Device.IOBoardCard": "DeviceCommand.Device.IOBoardGroup",
|
||||
"DeviceCommand.Device.IT6724C": "DeviceCommand.Devices.IT6720",
|
||||
"DeviceCommand.Device.SQ0090G1D1": "DeviceCommand.Devices.Chroma61800", # 三相交流源 → Chroma61800
|
||||
"DeviceCommand.Device.PSB11500_60": "DeviceCommand.Devices.S7200", # 交流源/负载 → S7200 直流源载一体机
|
||||
"DeviceCommand.Device.MSO44B": "DeviceCommand.Devices.TektronixMSO",
|
||||
"DeviceCommand.Device.EA3040_40C": "DeviceCommand.Devices.ANEVH80", # 水冷机/负载 → ANEVH80
|
||||
"DeviceCommand.Device.Chroma_63206A": "DeviceCommand.Devices.ANEVH80", # 电子负载 → ANEVH80
|
||||
|
||||
# 暂无对应设备,保持原 FullName(方法名使用占位符)
|
||||
"DeviceCommand.Device.WS_68070": "DeviceCommand.Device.WS_68070",
|
||||
"DeviceCommand.Device.AFV33030": "DeviceCommand.Device.AFV33030",
|
||||
"DeviceCommand.Device.DAQ970A": "DeviceCommand.Device.DAQ970A",
|
||||
"DeviceCommand.Device.XcpDevice": "DeviceCommand.Device.XcpDevice",
|
||||
"ATS.Commands.CurveMonitorCommands": "ATS.Commands.CurveMonitorCommands",
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 2. 方法名映射 {(旧FullName): {旧方法名: 新方法名}}
|
||||
# ============================================================
|
||||
|
||||
# --- IOBoardCard → IOBoardGroup ---
|
||||
IOBOARD_METHOD_MAP = {
|
||||
"WriteMultiIO": "批量写输出开关",
|
||||
"WriteSingleIO": "写输出开关",
|
||||
}
|
||||
|
||||
# --- IT6724C → IT6720 ---
|
||||
IT6720_METHOD_MAP = {
|
||||
"RemoteMode": "切换远程控制模式",
|
||||
"DCOutput_OFF": "设置输出开关", # 参数值 false
|
||||
"OFF": "设置输出开关", # 参数值 false
|
||||
"ON": "设置输出开关", # 参数值 true
|
||||
"SetVoltage": "设置输出电压",
|
||||
"SetCurrent": "设置输出电流",
|
||||
}
|
||||
|
||||
# --- PSB11500_60 → S7200 (直流源载一体机) ---
|
||||
S7200_METHOD_MAP = {
|
||||
"Set_RemoteMode": "设置为远程模式",
|
||||
"Set_SourceMode_SetVoltage": "设置电压",
|
||||
"Set_SourceMode_SetCurrent": "设置CC模式电流",
|
||||
"Set_SourceMode_SetPower": "设置正向功率阈值",
|
||||
"Set_SinkMode_SetVoltage": "设置电压",
|
||||
"Set_SinkMode_SetCurrent": "设置CC模式电流",
|
||||
"Set_SinkMode_SetPower": "设置反向功率阈值",
|
||||
"Set_DC_Input": "设置电压",
|
||||
"Set_DC_Output": "设置电压",
|
||||
"LoadOn": "设置通道开关", # 开启负载
|
||||
"LoadOff": "设置通道开关", # 关闭负载
|
||||
"Get_ActualVoltage": "查询实时电压",
|
||||
"Get_ActualCurrent": "查询实时电流",
|
||||
"Get_ActualPower": "查询功率",
|
||||
"MeasureVoltage": "查询实时电压",
|
||||
"MeasureCurrent": "查询实时电流",
|
||||
"MeasurePower": "查询功率",
|
||||
}
|
||||
|
||||
# --- SQ0090G1D1 → Chroma61800 (交流源) ---
|
||||
CHROMA61800_METHOD_MAP = {
|
||||
"RemoteMode": "设置输出开关Async", # true=远程
|
||||
"ON": "设置输出开关Async", # true=开启
|
||||
"OFF": "设置输出开关Async", # false=关闭
|
||||
"SetVoltage": "设置交流电压Async",
|
||||
"SetFrequency": "设置频率Async",
|
||||
"SetOutputMode": "设置单三相模式Async",
|
||||
"SetPhaseAngle": "设置开机角度Async",
|
||||
"SetIndividualVoltage": "设置交流电压Async",
|
||||
"MeasureVoltage": "读取交流电压Async",
|
||||
"MeasureCurrent": "读取交流电流Async",
|
||||
}
|
||||
|
||||
# --- EA3040_40C → ANEVH80 ---
|
||||
ANEVH80_METHOD_MAP = {
|
||||
"Set_RemoteMode": "占位符",
|
||||
"Set_Voltage": "占位符",
|
||||
"Set_Current": "占位符",
|
||||
"DCOutput_ON": "占位符",
|
||||
"DCOutput_OFF": "占位符",
|
||||
}
|
||||
|
||||
# --- Chroma_63206A → ANEVH80 ---
|
||||
CHROMA63206A_METHOD_MAP = {
|
||||
"SetModeCC": "占位符",
|
||||
"SetModeCV": "占位符",
|
||||
"SetModeCR": "占位符",
|
||||
"ON": "占位符",
|
||||
"OFF": "占位符",
|
||||
"SetVoltageL1": "占位符",
|
||||
"SetVoltageL2": "占位符",
|
||||
"SetCurrentL1": "占位符",
|
||||
"SetCurrentL2": "占位符",
|
||||
"SetResistanceL1": "占位符",
|
||||
"SetResistanceL2": "占位符",
|
||||
"SetCurrentSlewRatePositive": "占位符",
|
||||
"SetCurrentSlewRateNegative": "占位符",
|
||||
"MeasureVoltage": "占位符",
|
||||
"MeasureCurrent": "占位符",
|
||||
"MeasurePower": "占位符",
|
||||
}
|
||||
|
||||
# --- MSO44B → TektronixMSO ---
|
||||
TEKTRONIX_METHOD_MAP = {
|
||||
"Acquire_Run": "设置采集状态",
|
||||
"Acquire_Stop": "设置采集状态",
|
||||
"ClearStatus": "清除状态",
|
||||
"Reset": "清除状态",
|
||||
"Set_AcquireMode": "设置采集模式",
|
||||
"Set_ChannelState": "设置通道显示开关",
|
||||
"Set_ChannelScale": "设置通道垂直刻度",
|
||||
"Set_ChannelUnit": "设置通道垂直刻度",
|
||||
"Set_ChannelCoupling": "设置通道垂直刻度",
|
||||
"Set_ChannelProbe": "设置通道垂直刻度",
|
||||
"Set_ChannelBandwidth": "设置通道垂直刻度",
|
||||
"Set_HorizontalScale": "设置水平刻度",
|
||||
"Set_RecordLength": "设置记录长度",
|
||||
"Set_StopAfter": "设置采集状态",
|
||||
"Set_TriggerMode": "设置采集模式",
|
||||
"Set_TriggerType_Edge": "设置采集模式",
|
||||
"Set_TriggerEdgeSource": "设置测量源",
|
||||
"Set_TriggerEdgeSlope": "设置测量类型",
|
||||
"Set_TriggerLevel": "设置通道垂直位置",
|
||||
"Set_WaveformSource": "设置测量源",
|
||||
"Setup_Measurement": "开启测量项",
|
||||
"Get_MeasurementValue": "查询测量项当前值",
|
||||
"Save_Screenshot": "保存屏幕截图",
|
||||
"Save_Waveform": "保存屏幕截图",
|
||||
}
|
||||
|
||||
# --- PW8001 → PW8001 (同设备,方法名需适配) ---
|
||||
PW8001_METHOD_MAP = {
|
||||
"Set_TestMode_WIDE": "设置测试模式_WIDE",
|
||||
"Set_TestMode_IEC": "设置测试模式_IEC",
|
||||
"QueryVoltageWithRatio": "查询电压_含变比",
|
||||
"QueryCurrentWithRatio": "查询电流_含变比",
|
||||
"QueryPowerWithoutRatio": "查询功率_不含变比",
|
||||
"QueryTotalPowerP123": "查询总功率P123",
|
||||
"QueryVoltageTHD": "查询电压THD",
|
||||
"QueryCurrentTHD": "查询电流THD",
|
||||
}
|
||||
|
||||
# --- WS_68070 (占位符) ---
|
||||
WS68070_METHOD_MAP = {
|
||||
"Get_ThreePhase_Frequency": "占位符_GetFrequency",
|
||||
"Get_ThreePhase_MaxCurrent": "占位符_GetMaxCurrent",
|
||||
"Get_ThreePhase_MaxVoltage": "占位符_GetMaxVoltage",
|
||||
"Get_ThreePhase_SumActivePower": "占位符_GetSumActivePower",
|
||||
"Set_ATE_Load_A_Current": "占位符_SetLoadCurrent",
|
||||
"Set_ATE_Load_CurrentMode": "占位符_SetLoadMode",
|
||||
"Set_ATE_Load_Load": "占位符_SetLoad",
|
||||
"Set_ATE_Load_PowerMode": "占位符_SetPowerMode",
|
||||
"Set_ATE_Load_Uninstall": "占位符_SetUninstall",
|
||||
"Set_ThreePhase_SumActivePower": "占位符_SetSumActivePower",
|
||||
}
|
||||
|
||||
# --- AFV33030 (占位符) ---
|
||||
AFV33030_METHOD_MAP = {
|
||||
"Set_General_OutputVoltage": "占位符_SetOutputVoltage",
|
||||
"Set_ThreePhase_OutputVoltage": "占位符_SetThreePhaseVoltage",
|
||||
}
|
||||
|
||||
# --- DAQ970A (占位符) ---
|
||||
DAQ970A_METHOD_MAP = {
|
||||
"Set_DCDefaultCurrent": "占位符_SetCurrent",
|
||||
"Set_DCDefaultVoltage": "占位符_SetVoltage",
|
||||
}
|
||||
|
||||
# --- XcpDevice (占位符) ---
|
||||
XCP_METHOD_MAP = {
|
||||
"Connect": "占位符_Connect",
|
||||
"Disconnect": "占位符_Disconnect",
|
||||
"ReadMemory": "占位符_ReadMemory",
|
||||
"WriteMemory": "占位符_WriteMemory",
|
||||
}
|
||||
|
||||
# --- CurveMonitorCommands (占位符) ---
|
||||
CURVE_MONITOR_METHOD_MAP = {
|
||||
"CAN曲线记录_启动": "占位符_StartCANRecord",
|
||||
"CAN曲线记录_停止": "占位符_StopCANRecord",
|
||||
"设备参数记录_启动": "占位符_StartDeviceRecord",
|
||||
"设备参数记录_停止": "占位符_StopDeviceRecord",
|
||||
}
|
||||
|
||||
# 汇总所有方法映射
|
||||
METHOD_MAPPING = {
|
||||
"DeviceCommand.Device.IOBoardCard": IOBOARD_METHOD_MAP,
|
||||
"DeviceCommand.Device.IT6724C": IT6720_METHOD_MAP,
|
||||
"DeviceCommand.Device.PSB11500_60": S7200_METHOD_MAP,
|
||||
"DeviceCommand.Device.SQ0090G1D1": CHROMA61800_METHOD_MAP,
|
||||
"DeviceCommand.Device.EA3040_40C": ANEVH80_METHOD_MAP,
|
||||
"DeviceCommand.Device.Chroma_63206A": CHROMA63206A_METHOD_MAP,
|
||||
"DeviceCommand.Device.MSO44B": TEKTRONIX_METHOD_MAP,
|
||||
"DeviceCommand.Device.PW8001": PW8001_METHOD_MAP,
|
||||
"DeviceCommand.Device.WS_68070": WS68070_METHOD_MAP,
|
||||
"DeviceCommand.Device.AFV33030": AFV33030_METHOD_MAP,
|
||||
"DeviceCommand.Device.DAQ970A": DAQ970A_METHOD_MAP,
|
||||
"DeviceCommand.Device.XcpDevice": XCP_METHOD_MAP,
|
||||
"ATS.Commands.CurveMonitorCommands": CURVE_MONITOR_METHOD_MAP,
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 3. 格式转换函数
|
||||
# ============================================================
|
||||
|
||||
def convert_param_ats_to_acp(param):
|
||||
"""将 .ats 参数格式转换为 .ACP 参数格式"""
|
||||
new_param = {}
|
||||
new_param["ID"] = param.get("ID", str(uuid.uuid4()))
|
||||
new_param["IsVisible"] = param.get("IsVisible", True)
|
||||
new_param["IsEditable"] = True # .ACP 新增字段
|
||||
new_param["Name"] = param.get("Name", "")
|
||||
new_param["Type"] = param.get("Type", "")
|
||||
new_param["Category"] = param.get("Category", 0)
|
||||
new_param["Value"] = param.get("Value", None)
|
||||
new_param["LowerLimit"] = param.get("LowerLimit", None)
|
||||
new_param["UpperLimit"] = param.get("UpperLimit", None)
|
||||
new_param["Result"] = param.get("Result", True)
|
||||
new_param["IsUseVar"] = param.get("IsUseVar", False)
|
||||
new_param["VariableName"] = param.get("VariableName", None)
|
||||
new_param["VariableID"] = param.get("VariableID", None)
|
||||
# 不包含: IsGlobal, InitialValue, IsSave, IsOutputToReport
|
||||
return new_param
|
||||
|
||||
|
||||
def convert_ioboard_params(params, old_method_name):
|
||||
"""IOBoardGroup 参数处理:
|
||||
根据 IOBoardGroup 的方法签名重新生成参数
|
||||
写输出开关(台架序号, 站号, 开始地址, data)
|
||||
批量写输出开关(台架序号, 站号, 开始地址, datas)
|
||||
只保留台架序号参数(使用公共变量),其他参数先不写
|
||||
"""
|
||||
int_type = "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
byte_type = "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ushort_type = "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
bool_type = "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
bool_arr_type = "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
ct_type = "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"
|
||||
|
||||
# 台架序号参数(使用公共变量,Value=null,IsUseVar=true)
|
||||
station_param = {
|
||||
"ID": str(uuid.uuid4()),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": "台架序号",
|
||||
"Type": int_type,
|
||||
"Category": 0,
|
||||
"Value": None,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": True,
|
||||
"VariableName": "台架序号",
|
||||
"VariableID": None
|
||||
}
|
||||
|
||||
new_params = [station_param]
|
||||
|
||||
# 根据方法类型添加对应的参数(值设为 null,用户后续填写)
|
||||
if "批量" in old_method_name or "Multi" in old_method_name:
|
||||
# 批量写输出开关: 台架序号, 站号, 开始地址, datas
|
||||
new_params.append(make_param("站号", byte_type, None))
|
||||
new_params.append(make_param("开始地址", ushort_type, None))
|
||||
new_params.append(make_param("datas", bool_arr_type, None))
|
||||
else:
|
||||
# 写输出开关: 台架序号, 站号, 开始地址, data
|
||||
new_params.append(make_param("站号", byte_type, None))
|
||||
new_params.append(make_param("开始地址", ushort_type, None))
|
||||
new_params.append(make_param("data", bool_type, None))
|
||||
|
||||
return new_params
|
||||
|
||||
|
||||
def make_param(name, type_str, value):
|
||||
"""创建一个 ACP 格式的参数"""
|
||||
return {
|
||||
"ID": str(uuid.uuid4()),
|
||||
"IsVisible": True,
|
||||
"IsEditable": True,
|
||||
"Name": name,
|
||||
"Type": type_str,
|
||||
"Category": 0,
|
||||
"Value": value,
|
||||
"LowerLimit": None,
|
||||
"UpperLimit": None,
|
||||
"Result": True,
|
||||
"IsUseVar": False,
|
||||
"VariableName": None,
|
||||
"VariableID": None
|
||||
}
|
||||
|
||||
|
||||
def convert_method(method, old_full_name):
|
||||
"""转换 Method 对象"""
|
||||
if not method:
|
||||
return None
|
||||
|
||||
new_method = {}
|
||||
old_name = method.get("Name", "")
|
||||
|
||||
# 映射 FullName
|
||||
new_full_name = DEVICE_MAPPING.get(old_full_name, old_full_name)
|
||||
new_method["Name"] = old_name
|
||||
new_method["FullName"] = new_full_name
|
||||
|
||||
# 映射方法名
|
||||
method_map = METHOD_MAPPING.get(old_full_name, {})
|
||||
if old_name in method_map:
|
||||
new_method["Name"] = method_map[old_name]
|
||||
|
||||
# 转换参数(不包含 DeviceID)
|
||||
old_params = method.get("Parameters", [])
|
||||
if old_full_name == "DeviceCommand.Device.IOBoardCard":
|
||||
new_method["Parameters"] = convert_ioboard_params(old_params, old_name)
|
||||
else:
|
||||
new_method["Parameters"] = [convert_param_ats_to_acp(p) for p in old_params]
|
||||
|
||||
return new_method
|
||||
|
||||
|
||||
def convert_step(step):
|
||||
"""转换单个 Step"""
|
||||
new_step = {}
|
||||
new_step["ID"] = step.get("ID", str(uuid.uuid4()))
|
||||
new_step["IsUsed"] = step.get("IsUsed", True)
|
||||
new_step["Index"] = step.get("Index", 0)
|
||||
new_step["Name"] = step.get("Name", "")
|
||||
new_step["StepType"] = step.get("StepType", "方法")
|
||||
|
||||
# 转换 Method
|
||||
old_method = step.get("Method")
|
||||
if old_method:
|
||||
old_full_name = old_method.get("FullName", "")
|
||||
new_step["Method"] = convert_method(old_method, old_full_name)
|
||||
else:
|
||||
new_step["Method"] = None
|
||||
|
||||
# 转换 SubProgram(嵌套的子程序)
|
||||
sub_program = step.get("SubProgram")
|
||||
if sub_program and isinstance(sub_program, dict):
|
||||
new_step["SubProgram"] = convert_program(sub_program)
|
||||
else:
|
||||
new_step["SubProgram"] = None
|
||||
|
||||
# 循环相关
|
||||
new_step["LoopCount"] = step.get("LoopCount", None)
|
||||
new_step["LoopStartStepId"] = step.get("LoopStartStepId", None)
|
||||
|
||||
# 跳转相关
|
||||
new_step["OKExpression"] = step.get("OKExpression", None)
|
||||
new_step["GotoSettingString"] = step.get("GotoSettingString", "")
|
||||
new_step["OKGotoStepID"] = step.get("OKGotoStepID", None)
|
||||
new_step["NGGotoStepID"] = step.get("NGGotoStepID", None)
|
||||
new_step["Description"] = step.get("Description", None)
|
||||
|
||||
return new_step
|
||||
|
||||
|
||||
def convert_program(program):
|
||||
"""转换整个 ProgramVM 结构"""
|
||||
new_program = {}
|
||||
new_program["ID"] = program.get("ID", str(uuid.uuid4()))
|
||||
|
||||
# 转换 StepCollection
|
||||
old_steps = program.get("StepCollection", [])
|
||||
new_program["StepCollection"] = [convert_step(s) for s in old_steps]
|
||||
|
||||
# ErrorStepCollection
|
||||
new_program["ErrorStepCollection"] = []
|
||||
|
||||
# 转换 Parameters(顶层参数)
|
||||
old_params = program.get("Parameters", [])
|
||||
new_program["Parameters"] = [convert_param_ats_to_acp(p) for p in old_params]
|
||||
|
||||
return new_program
|
||||
|
||||
|
||||
def convert_file(input_path, output_path):
|
||||
"""转换单个文件"""
|
||||
with open(input_path, encoding='utf-8-sig') as f:
|
||||
data = json.load(f)
|
||||
|
||||
result = convert_program(data)
|
||||
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(result, f, ensure_ascii=False, indent=2)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 4. 主程序
|
||||
# ============================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
input_dir = r"C:\Users\kk\Desktop\ACP\极电子程序"
|
||||
output_dir = r"D:\ACP\测试项\ACP输出"
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
files = glob.glob(os.path.join(input_dir, "*.ats"))
|
||||
print(f"找到 {len(files)} 个 .ats 文件")
|
||||
|
||||
success = 0
|
||||
failed = 0
|
||||
|
||||
for f in files:
|
||||
basename = os.path.splitext(os.path.basename(f))[0]
|
||||
output_path = os.path.join(output_dir, f"{basename}.ACP")
|
||||
|
||||
try:
|
||||
convert_file(f, output_path)
|
||||
print(f" ✓ {basename}.ats → {basename}.ACP")
|
||||
success += 1
|
||||
except Exception as e:
|
||||
print(f" ✗ {basename}.ats 失败: {e}")
|
||||
failed += 1
|
||||
|
||||
print(f"\n转换完成: 成功 {success}, 失败 {failed}")
|
||||
print(f"输出目录: {output_dir}")
|
||||
@@ -0,0 +1,40 @@
|
||||
import re, glob, json
|
||||
|
||||
files = glob.glob(r'C:\Users\kk\Desktop\ACP\极电子程序\*.ats')
|
||||
full_names = set()
|
||||
method_names = {}
|
||||
|
||||
for f in files:
|
||||
content = open(f, encoding='utf-8-sig').read()
|
||||
# Find all FullName values
|
||||
for m in re.finditer(r'"FullName":\s*"([^"]+)"', content):
|
||||
full_names.add(m.group(1))
|
||||
|
||||
# Find all Method Name + FullName pairs
|
||||
data = json.loads(content)
|
||||
def extract_methods(steps):
|
||||
for step in steps:
|
||||
method = step.get('Method')
|
||||
if method and method.get('Name') and method.get('FullName'):
|
||||
key = method['FullName']
|
||||
if key not in method_names:
|
||||
method_names[key] = set()
|
||||
method_names[key].add(method['Name'])
|
||||
# Check SubProgram (nested steps)
|
||||
sub = step.get('SubProgram')
|
||||
if sub and isinstance(sub, dict):
|
||||
sub_steps = sub.get('StepCollection', [])
|
||||
extract_methods(sub_steps)
|
||||
|
||||
steps = data.get('StepCollection', [])
|
||||
extract_methods(steps)
|
||||
|
||||
print("=== All FullName values ===")
|
||||
for name in sorted(full_names):
|
||||
print(f" {name}")
|
||||
|
||||
print("\n=== Methods per device ===")
|
||||
for device in sorted(method_names.keys()):
|
||||
print(f"\n {device}:")
|
||||
for method in sorted(method_names[device]):
|
||||
print(f" - {method}")
|
||||
@@ -0,0 +1,50 @@
|
||||
import json, glob, os
|
||||
|
||||
output_dir = r"D:\ACP\测试项\ACP输出"
|
||||
|
||||
# 验证一个文件的格式
|
||||
test_file = os.path.join(output_dir, "NCE-13——OBC放电.ACP")
|
||||
d = json.load(open(test_file, encoding='utf-8'))
|
||||
|
||||
print("=== 设备方法映射验证 ===")
|
||||
for s in d['StepCollection']:
|
||||
m = s.get('Method')
|
||||
if m:
|
||||
params_info = ", ".join([f"{p['Name']}={'VAR' if p.get('IsUseVar') else str(p.get('Value'))}" for p in m.get('Parameters', [])])
|
||||
print(f" [{s['Index']}] {m['FullName']}.{m['Name']} ({params_info})")
|
||||
|
||||
print("\n=== 格式验证 ===")
|
||||
# 检查是否有 .ats 特有字段
|
||||
has_old_fields = False
|
||||
def check_steps(steps, prefix=""):
|
||||
global has_old_fields
|
||||
for s in steps:
|
||||
m = s.get('Method')
|
||||
if m:
|
||||
if 'DeviceID' in m:
|
||||
has_old_fields = True
|
||||
print(f" ✗ {prefix}Step {s['Index']} 仍包含 DeviceID")
|
||||
for p in m.get('Parameters', []):
|
||||
for field in ['IsGlobal', 'InitialValue', 'IsSave', 'IsOutputToReport']:
|
||||
if field in p:
|
||||
has_old_fields = True
|
||||
print(f" ✗ {prefix}Step {s['Index']} 参数 {p['Name']} 仍包含 {field}")
|
||||
if 'IsEditable' not in p:
|
||||
has_old_fields = True
|
||||
print(f" ✗ {prefix}Step {s['Index']} 参数 {p.get('Name','')} 缺少 IsEditable")
|
||||
sub = s.get('SubProgram')
|
||||
if sub and isinstance(sub, dict):
|
||||
check_steps(sub.get('StepCollection', []), prefix + " Sub.")
|
||||
|
||||
check_steps(d['StepCollection'])
|
||||
|
||||
if not has_old_fields:
|
||||
print(" [OK] 无残留 .ats 字段")
|
||||
print(" [OK] 所有参数包含 IsEditable")
|
||||
print(" [OK] 无 DeviceID")
|
||||
|
||||
# 检查子程序
|
||||
sub_count = sum(1 for s in d['StepCollection'] if s.get('SubProgram'))
|
||||
print(f" 子程序步骤数: {sub_count}")
|
||||
print(f" 总步骤数: {len(d['StepCollection'])}")
|
||||
print(f" 顶层参数数: {len(d.get('Parameters', []))}")
|
||||
@@ -0,0 +1,477 @@
|
||||
{
|
||||
"ID": "d5d396fb-e531-4487-99bf-460bf8177b67",
|
||||
"StepCollection": [
|
||||
{
|
||||
"ID": "d0d63f54-dcfc-491f-918a-ac4c672f5732",
|
||||
"IsUsed": false,
|
||||
"Index": 1,
|
||||
"Name": "IO板卡(16)全开",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteMultiIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "e7ffcb06-f74c-4ddb-bfba-151203678c16",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "2d70fab8-0f5a-491b-9148-a43cbb5b7670",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "8b67a8d2-c5ee-4e0c-bd18-6150bff358d5",
|
||||
"IsVisible": true,
|
||||
"Name": "startAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "f8dc953e-83d7-4bb4-8fb5-f0b18acc9037",
|
||||
"IsVisible": true,
|
||||
"Name": "values",
|
||||
"Type": "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "02588f6e-c1a4-43c2-8c8e-0ea2fc81a43b",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "4ac2e4be-0038-46a7-b19c-ddda4a12ba78",
|
||||
"IsUsed": false,
|
||||
"Index": 2,
|
||||
"Name": "IO板卡(8)全开",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteMultiIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "179bd18e-35ca-4891-969a-fcca332bf584",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "054a5496-c2cb-4b5a-84a2-f25b36b9ffbe",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "15c798eb-1c54-43f1-8549-ea8d3eb4eeea",
|
||||
"IsVisible": true,
|
||||
"Name": "startAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "3a039b24-63de-4b73-a1b7-c5df51f50361",
|
||||
"IsVisible": true,
|
||||
"Name": "values",
|
||||
"Type": "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "[true,true,true,true,true,true,true,true]",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "07cda00a-ecd3-4e8b-a723-e2586d615b10",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "cdab9217-417d-4c56-a38a-0b396712d55f",
|
||||
"IsUsed": true,
|
||||
"Index": 3,
|
||||
"Name": "IO板卡(16)全关",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteMultiIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "e7ffcb06-f74c-4ddb-bfba-151203678c16",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "ff35f6c2-9002-48f4-887f-ed90fb690bf0",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "40bf5b67-cffd-4748-94fb-2faa26e14031",
|
||||
"IsVisible": true,
|
||||
"Name": "startAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "15053e63-d3fb-471e-924e-c6705fe087c9",
|
||||
"IsVisible": true,
|
||||
"Name": "values",
|
||||
"Type": "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "d58e8512-98fd-4eed-a0a9-7e2fea91fb73",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "5dc85c07-2b91-4ca1-a853-7824e328cce9",
|
||||
"IsUsed": true,
|
||||
"Index": 4,
|
||||
"Name": "IO板卡(8)全关",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteMultiIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "179bd18e-35ca-4891-969a-fcca332bf584",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "ec3b0ac7-9431-44f5-a960-5b353c5f4749",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "3e79134f-b6d0-4225-9c0c-26cac669877d",
|
||||
"IsVisible": true,
|
||||
"Name": "startAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "5963ce52-6e22-4631-87b1-f4f3fd524c94",
|
||||
"IsVisible": true,
|
||||
"Name": "values",
|
||||
"Type": "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "[false,false,false,false,false,false,false,false]",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "f4477e20-9bc9-4a8f-b059-b97c4125d53c",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "544f892f-f3e4-4494-8ae6-aeb67c8aca4b",
|
||||
"IsUsed": false,
|
||||
"Index": 5,
|
||||
"Name": "WriteSingleIO",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteSingleIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "179bd18e-35ca-4891-969a-fcca332bf584",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "c811b7a4-9a36-4b38-beb0-ab8895bd06f1",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "0402d8b1-f310-4db9-b8be-71529d9ccca6",
|
||||
"IsVisible": true,
|
||||
"Name": "coilAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "31071ec7-d3e7-400b-afd0-02382087107b",
|
||||
"IsVisible": true,
|
||||
"Name": "value",
|
||||
"Type": "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "true",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "a56b7490-774c-417a-aeed-0ba780b0a255",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
}
|
||||
],
|
||||
"Parameters": [],
|
||||
"Devices": []
|
||||
}
|
||||
@@ -0,0 +1,915 @@
|
||||
{
|
||||
"ID": "8e478d06-14c6-45de-9df4-c546b36b2da6",
|
||||
"StepCollection": [
|
||||
{
|
||||
"ID": "ee1dd564-757a-42e1-92ee-8ac38ffbd238",
|
||||
"IsUsed": true,
|
||||
"Index": 1,
|
||||
"Name": "CAN曲线记录停止",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "CAN曲线记录_停止",
|
||||
"FullName": "ATS.Commands.CurveMonitorCommands",
|
||||
"DeviceID": "e7ffcb06-f74c-4ddb-bfba-151203678c16",
|
||||
"Parameters": []
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "566812d1-f080-4ba5-b752-72bfc4260690",
|
||||
"IsUsed": true,
|
||||
"Index": 2,
|
||||
"Name": "设备参数记录_停止",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "设备参数记录_停止",
|
||||
"FullName": "ATS.Commands.CurveMonitorCommands",
|
||||
"DeviceID": null,
|
||||
"Parameters": []
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "0631b65e-4de9-431a-9ac8-aee3552385e4",
|
||||
"IsUsed": true,
|
||||
"Index": 3,
|
||||
"Name": "设置报文",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "SetSignalValue",
|
||||
"FullName": "TSMasterCAN.CAN",
|
||||
"DeviceID": "faa7d5ea-2a49-4c33-b57f-3f29ec0dbc18",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "37b38f93-cdb8-4b2b-9f9a-2986db04c4ac",
|
||||
"IsVisible": true,
|
||||
"Name": "channel",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "c612a729-356a-4ff6-97fd-047e498948c9",
|
||||
"IsVisible": true,
|
||||
"Name": "AMsgName",
|
||||
"Type": "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "\"PcmuHvEnergeCanFr01\"",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "8bd51944-d315-40e9-9073-819480e9e61e",
|
||||
"IsVisible": true,
|
||||
"Name": "ASgnName",
|
||||
"Type": "System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "\"ChrgrPwrModCtlMst\"",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "73125622-84c3-4fb6-b323-b6d156f83f95",
|
||||
"IsVisible": true,
|
||||
"Name": "AValue",
|
||||
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "45112e65-2e78-4fca-b5fe-8451b8b0ed6d",
|
||||
"IsVisible": true,
|
||||
"Name": "isSend",
|
||||
"Type": "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "true",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "26a3d01d-4a38-4e63-99e2-cc100d05b8e8",
|
||||
"IsVisible": true,
|
||||
"Name": "sendPeriod",
|
||||
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "20",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "44f26d57-09a2-444f-b6b2-be7a542cff6d",
|
||||
"IsVisible": true,
|
||||
"Name": "Result",
|
||||
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 1,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "3b317dbc-8ba9-4ba1-9d60-20b30367f6a4",
|
||||
"IsUsed": true,
|
||||
"Index": 4,
|
||||
"Name": "延时",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "Delay_s",
|
||||
"FullName": "Command.Delay",
|
||||
"DeviceID": null,
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "95855137-9a4d-4189-a2ce-c84480ab8ac3",
|
||||
"IsVisible": true,
|
||||
"Name": "second",
|
||||
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "a2bacfcc-4948-4afd-90a0-98d06666582b",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "88c98d7a-1abf-4356-8185-7db1ebed8e38",
|
||||
"IsUsed": true,
|
||||
"Index": 5,
|
||||
"Name": "IO板卡(8)写输出",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteMultiIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "179bd18e-35ca-4891-969a-fcca332bf584",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "0c79c43f-6803-4e1f-afd3-f0d172de5d93",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "60bf7c19-dbd4-4d7c-aa7e-55336bd93e23",
|
||||
"IsVisible": true,
|
||||
"Name": "startAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "8037e189-948c-49ae-aa94-049fa479a33a",
|
||||
"IsVisible": true,
|
||||
"Name": "values",
|
||||
"Type": "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "[false,false,false,false,false,false,false,false]",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "01df2ac1-1436-4d47-83d0-e332140bd5a5",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "044dc15d-e1ee-4f5e-85bf-bbdbddf35ce3",
|
||||
"IsUsed": true,
|
||||
"Index": 6,
|
||||
"Name": "IO板卡(16)写输出",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "WriteMultiIO",
|
||||
"FullName": "DeviceCommand.Device.IOBoardCard",
|
||||
"DeviceID": "e7ffcb06-f74c-4ddb-bfba-151203678c16",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "0c79c43f-6803-4e1f-afd3-f0d172de5d93",
|
||||
"IsVisible": true,
|
||||
"Name": "slaveAddress",
|
||||
"Type": "System.Byte, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "60bf7c19-dbd4-4d7c-aa7e-55336bd93e23",
|
||||
"IsVisible": true,
|
||||
"Name": "startAddress",
|
||||
"Type": "System.UInt16, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "0",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "8037e189-948c-49ae-aa94-049fa479a33a",
|
||||
"IsVisible": true,
|
||||
"Name": "values",
|
||||
"Type": "System.Boolean[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "01df2ac1-1436-4d47-83d0-e332140bd5a5",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "4aebb5ee-bd04-4782-b67c-91e0435cbb0a",
|
||||
"IsUsed": true,
|
||||
"Index": 7,
|
||||
"Name": "延时",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "Delay_s",
|
||||
"FullName": "Command.Delay",
|
||||
"DeviceID": null,
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "95855137-9a4d-4189-a2ce-c84480ab8ac3",
|
||||
"IsVisible": true,
|
||||
"Name": "second",
|
||||
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "a2bacfcc-4948-4afd-90a0-98d06666582b",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "de0357b3-90ff-4e3b-bb2a-1ec1215c40a3",
|
||||
"IsUsed": true,
|
||||
"Index": 8,
|
||||
"Name": "停止CAN日志记录",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "StopLogging",
|
||||
"FullName": "TSMasterCAN.CAN",
|
||||
"DeviceID": "faa7d5ea-2a49-4c33-b57f-3f29ec0dbc18",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "24ecb6b0-bf3e-487d-b724-864dd4cc42db",
|
||||
"IsVisible": true,
|
||||
"Name": "Result",
|
||||
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 1,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": 0,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "032ecf5c-e816-4a30-804e-cf89e6bf1118",
|
||||
"IsUsed": true,
|
||||
"Index": 9,
|
||||
"Name": "断开连接",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "DisConnect",
|
||||
"FullName": "TSMasterCAN.CAN",
|
||||
"DeviceID": "faa7d5ea-2a49-4c33-b57f-3f29ec0dbc18",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "5eb2684d-4c77-4c90-ab25-b878ab14723d",
|
||||
"IsVisible": true,
|
||||
"Name": "Result",
|
||||
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 1,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": 0,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "17261600-7ff2-4ec4-94e9-f95a85476a68",
|
||||
"IsUsed": true,
|
||||
"Index": 10,
|
||||
"Name": "延时",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "Delay_s",
|
||||
"FullName": "Command.Delay",
|
||||
"DeviceID": null,
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "95855137-9a4d-4189-a2ce-c84480ab8ac3",
|
||||
"IsVisible": true,
|
||||
"Name": "second",
|
||||
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "a2bacfcc-4948-4afd-90a0-98d06666582b",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "f841385c-a895-4156-b1c9-63779e7f88ec",
|
||||
"IsUsed": true,
|
||||
"Index": 11,
|
||||
"Name": "关闭AC源",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "OFF",
|
||||
"FullName": "DeviceCommand.Device.SQ0090G1D1",
|
||||
"DeviceID": "a89ed16a-32f2-48b6-9d22-8da0aad68183",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "e7fd1b17-f98c-4cba-8011-7fbec800e81d",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "fef2b22e-8ece-4be2-a2d2-dc8518b459f0",
|
||||
"IsUsed": true,
|
||||
"Index": 12,
|
||||
"Name": "延时",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "Delay_s",
|
||||
"FullName": "Command.Delay",
|
||||
"DeviceID": null,
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "95855137-9a4d-4189-a2ce-c84480ab8ac3",
|
||||
"IsVisible": true,
|
||||
"Name": "second",
|
||||
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "a2bacfcc-4948-4afd-90a0-98d06666582b",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "42e03756-b71c-4d4d-98a1-418691164eb6",
|
||||
"IsUsed": true,
|
||||
"Index": 13,
|
||||
"Name": "关闭高压双向电源",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "LoadOff",
|
||||
"FullName": "DeviceCommand.Device.PSB11500_60",
|
||||
"DeviceID": "57f4e8d9-8598-41b7-88af-3987143816b1",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "88f48df7-b8d4-4116-adbf-e24e30599a6d",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "4cfab9c1-a23f-48e1-97e3-7944c9300405",
|
||||
"IsUsed": true,
|
||||
"Index": 14,
|
||||
"Name": "延时",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "Delay_s",
|
||||
"FullName": "Command.Delay",
|
||||
"DeviceID": null,
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "95855137-9a4d-4189-a2ce-c84480ab8ac3",
|
||||
"IsVisible": true,
|
||||
"Name": "second",
|
||||
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": "1",
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
},
|
||||
{
|
||||
"ID": "a2bacfcc-4948-4afd-90a0-98d06666582b",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "dc35f9e0-8f18-4509-82b0-4e072bfc302d",
|
||||
"IsUsed": true,
|
||||
"Index": 15,
|
||||
"Name": "关闭低压电源",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "DCOutput_OFF",
|
||||
"FullName": "DeviceCommand.Device.EA3040_40C",
|
||||
"DeviceID": "ca8e197d-c5ee-4502-95b8-c15fb5145a0e",
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "d3341618-d2e0-46c6-90c2-e9b6bb6deb3f",
|
||||
"IsVisible": true,
|
||||
"Name": "ct",
|
||||
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 0,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
},
|
||||
{
|
||||
"ID": "2b510d3f-a664-47b1-bbe6-246ab254e4ad",
|
||||
"IsUsed": true,
|
||||
"Index": 16,
|
||||
"Name": "清空所有CAN报文",
|
||||
"StepType": "方法",
|
||||
"Method": {
|
||||
"Name": "DeleteCyclicMsgs",
|
||||
"FullName": "TSMasterCAN.CAN",
|
||||
"DeviceID": null,
|
||||
"Parameters": [
|
||||
{
|
||||
"ID": "02c22d25-50c5-4233-960e-d6ca6beaa0e4",
|
||||
"IsVisible": true,
|
||||
"Name": "Result",
|
||||
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
|
||||
"Category": 1,
|
||||
"IsGlobal": false,
|
||||
"InitialValue": null,
|
||||
"Value": null,
|
||||
"LowerLimit": null,
|
||||
"UpperLimit": null,
|
||||
"Result": true,
|
||||
"IsUseVar": false,
|
||||
"IsSave": false,
|
||||
"VariableName": null,
|
||||
"VariableID": null,
|
||||
"IsOutputToReport": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubProgram": null,
|
||||
"LoopCount": null,
|
||||
"LoopStartStepId": null,
|
||||
"OKExpression": null,
|
||||
"GotoSettingString": "",
|
||||
"OKGotoStepID": null,
|
||||
"NGGotoStepID": null,
|
||||
"Description": null
|
||||
}
|
||||
],
|
||||
"Parameters": [],
|
||||
"Devices": []
|
||||
}
|
||||