整合执行逻辑

This commit is contained in:
hsc 2025-11-20 14:49:32 +08:00
parent d2bf7ab4c0
commit 0f32957416
9 changed files with 195 additions and 114 deletions

View File

@ -56,8 +56,8 @@ namespace BOB
containerRegistry.RegisterDialog<DeviceSetting, DeviceSettingViewModel>("DeviceSetting"); containerRegistry.RegisterDialog<DeviceSetting, DeviceSettingViewModel>("DeviceSetting");
//注册全局变量 //注册全局变量
containerRegistry.RegisterSingleton<GlobalVariables>(); containerRegistry.RegisterSingleton<GlobalVariables>();
containerRegistry.RegisterSingleton<StepRunning>();
containerRegistry.RegisterSingleton<Devices>(); containerRegistry.RegisterSingleton<Devices>();
containerRegistry.RegisterSingleton<StepRunning>();
} }
protected override void OnExit(ExitEventArgs e) protected override void OnExit(ExitEventArgs e)
{ {

View File

@ -1,52 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
namespace BOB.Models
{
public class DeviceModel
{
public DeviceModel()
{
}
public DeviceModel(DeviceModel source)
{
ID = source.ID;
ParameterID = source.ParameterID;
Name = source.Name;
Connected = source.Connected;
ErrorMessage = source.ErrorMessage;
Type = source.Type;
ConnectString = source.ConnectString;
CommunicationProtocol = source.CommunicationProtocol;
Description = source.Description;
}
public Guid ID { get; set; } = Guid.NewGuid();
public Guid ParameterID { get; set; }
public string Name { get; set; } = "";
[JsonIgnore]
public bool Connected { get; set; }
[JsonIgnore]
public string? ErrorMessage { get; set; }
public string Type { get; set; } = "Tcp";
public string ConnectString { get; set; } = "";
[JsonIgnore]
public object? CommunicationProtocol { get; set; }
public string Description { get; set; } = "";
}
}

View File

@ -18,7 +18,6 @@ namespace BOB.Models
{ {
ID = source.ID; ID = source.ID;
StepCollection = new ObservableCollection<StepModel>(source.StepCollection.Select(p => new StepModel(p))); StepCollection = new ObservableCollection<StepModel>(source.StepCollection.Select(p => new StepModel(p)));
Devices = new ObservableCollection<DeviceModel>(source.Devices.Select(p => new DeviceModel(p)));
Parameters = new ObservableCollection<ParameterModel>(source.Parameters.Select(p => new ParameterModel(p))); Parameters = new ObservableCollection<ParameterModel>(source.Parameters.Select(p => new ParameterModel(p)));
} }
@ -40,11 +39,6 @@ namespace BOB.Models
set => SetProperty(ref _parameters, value); set => SetProperty(ref _parameters, value);
} }
private ObservableCollection<DeviceModel> _devices = new ObservableCollection<DeviceModel>();
public ObservableCollection<DeviceModel> Devices
{
get => _devices;
set => SetProperty(ref _devices, value);
}
} }
} }

View File

@ -21,11 +21,9 @@ namespace BOB.Singleton
private readonly ProxyGenerator _proxyGen = new ProxyGenerator(); private readonly ProxyGenerator _proxyGen = new ProxyGenerator();
private readonly IInterceptor _loggingInterceptor = new LoggingInterceptor(); private readonly IInterceptor _loggingInterceptor = new LoggingInterceptor();
// 保留对单个实例引用(可选) private ITcp E36233ADevice { get; set; }
private ITcp E36233ADevice_1 { get; set; } private ISerialPort IT6724CDevice { get; set; }
private ITcp E36233ADevice_2 { get; set; } private ISerialPort IT6724CReverseDevice{ get; set; }
private ISerialPort IT6724CDevice_1 { get; set; }
private ISerialPort IT6724CDevice_2 { get; set; }
private IModbusDevice EAEL9080Device { get; set; } private IModbusDevice EAEL9080Device { get; set; }
private IModbusDevice IOBoardevice { get; set; } private IModbusDevice IOBoardevice { get; set; }
private IModbusDevice LQ7500_DDevice { get; set; } private IModbusDevice LQ7500_DDevice { get; set; }
@ -45,23 +43,11 @@ namespace BOB.Singleton
case "DeviceCommand.Device.E36233A": case "DeviceCommand.Device.E36233A":
if (device.CommunicationConfig is TcpConfig tcp1) if (device.CommunicationConfig is TcpConfig tcp1)
{ {
if (E36233ADevice_1 == null) E36233ADevice = _proxyGen.CreateInterfaceProxyWithTarget<ITcp>(
{
// 通过接口代理
E36233ADevice_1 = _proxyGen.CreateInterfaceProxyWithTarget<ITcp>(
new E36233A(tcp1.IPAddress, tcp1.Port, tcp1.ReadTimeout, tcp1.WriteTimeout), new E36233A(tcp1.IPAddress, tcp1.Port, tcp1.ReadTimeout, tcp1.WriteTimeout),
_loggingInterceptor _loggingInterceptor
); );
DeviceDic["E36233A_1"] = E36233ADevice_1; DeviceDic["E36233A"] = E36233ADevice;
}
else
{
E36233ADevice_2 = _proxyGen.CreateInterfaceProxyWithTarget<ITcp>(
new E36233A(tcp1.IPAddress, tcp1.Port, tcp1.ReadTimeout, tcp1.WriteTimeout),
_loggingInterceptor
);
DeviceDic["E36233A_2"] = E36233ADevice_2;
}
} }
else throw new InvalidOperationException("E36233A 必须使用 TcpConfig"); else throw new InvalidOperationException("E36233A 必须使用 TcpConfig");
break; break;
@ -69,22 +55,23 @@ namespace BOB.Singleton
case "DeviceCommand.Device.IT6724C": case "DeviceCommand.Device.IT6724C":
if (device.CommunicationConfig is SerialPortConfig sp1) if (device.CommunicationConfig is SerialPortConfig sp1)
{ {
if (IT6724CDevice_1 == null) IT6724CDevice = _proxyGen.CreateInterfaceProxyWithTarget<ISerialPort>(
{ new IT6724C(sp1.COMPort, sp1.BaudRate, sp1.DataBit, sp1.StopBit, sp1.ParityBit, sp1.ReadTimeout, sp1.WriteTimeout),
IT6724CDevice_1 = _proxyGen.CreateInterfaceProxyWithTarget<ISerialPort>( _loggingInterceptor
new IT6724C(sp1.COMPort, sp1.BaudRate, sp1.DataBit, sp1.StopBit, sp1.ParityBit, sp1.ReadTimeout, sp1.WriteTimeout), );
_loggingInterceptor DeviceDic["IT6724C"] = IT6724CDevice;
); }
DeviceDic["IT6724C_1"] = IT6724CDevice_1; else throw new InvalidOperationException("IT6724C 必须使用 SerialPortConfig");
} break;
else
{ case "DeviceCommand.Device.IT6724CReverse":
IT6724CDevice_2 = _proxyGen.CreateInterfaceProxyWithTarget<ISerialPort>( if (device.CommunicationConfig is SerialPortConfig sp3)
new IT6724C(sp1.COMPort, sp1.BaudRate, sp1.DataBit, sp1.StopBit, sp1.ParityBit, sp1.ReadTimeout, sp1.WriteTimeout), {
_loggingInterceptor IT6724CReverseDevice = _proxyGen.CreateInterfaceProxyWithTarget<ISerialPort>(
); new IT6724C(sp3.COMPort, sp3.BaudRate, sp3.DataBit, sp3.StopBit, sp3.ParityBit, sp3.ReadTimeout, sp3.WriteTimeout),
DeviceDic["IT6724C_2"] = IT6724CDevice_2; _loggingInterceptor
} );
DeviceDic["IT6724CReverse"] = IT6724CReverseDevice;
} }
else throw new InvalidOperationException("IT6724C 必须使用 SerialPortConfig"); else throw new InvalidOperationException("IT6724C 必须使用 SerialPortConfig");
break; break;

View File

@ -24,6 +24,5 @@ namespace BOB
public PackIconKind RunIcon { get; set; } = PackIconKind.Play; public PackIconKind RunIcon { get; set; } = PackIconKind.Play;
public StepModel SelectedStep { get; set; } public StepModel SelectedStep { get; set; }
public ParameterModel SelectedParameter { get; set; } public ParameterModel SelectedParameter { get; set; }
public DeviceModel SelectedDevice { get; set; }
} }
} }

View File

@ -1,4 +1,5 @@
using BOB.Models; using BOB.Models;
using BOB.Singleton;
using Common.PubEvent; using Common.PubEvent;
using Common.Tools; using Common.Tools;
using Logger; using Logger;
@ -19,6 +20,8 @@ namespace BOB
public class StepRunning public class StepRunning
{ {
private GlobalVariables _globalVariables; private GlobalVariables _globalVariables;
private Devices _devices;
private IContainerProvider containerProvider;
private IEventAggregator _eventAggregator; private IEventAggregator _eventAggregator;
private readonly Dictionary<Guid, ParameterModel> tmpParameters = []; private readonly Dictionary<Guid, ParameterModel> tmpParameters = [];
@ -33,10 +36,11 @@ namespace BOB
private bool SubSingleStep = false; private bool SubSingleStep = false;
private Guid TestRoundID; private Guid TestRoundID;
public StepRunning(GlobalVariables globalVariables,IEventAggregator eventAggregator) public StepRunning(GlobalVariables globalVariables,IEventAggregator eventAggregator,IContainerProvider containerProvider)
{ {
_globalVariables = globalVariables; _globalVariables = containerProvider.Resolve<GlobalVariables>();
_eventAggregator= eventAggregator; _eventAggregator = eventAggregator;
} }
public async Task<bool> ExecuteSteps(ProgramModel program, int depth = 0, CancellationToken cancellationToken = default) public async Task<bool> ExecuteSteps(ProgramModel program, int depth = 0, CancellationToken cancellationToken = default)
{ {
@ -359,7 +363,7 @@ namespace BOB
{ {
try try
{ {
instance = Activator.CreateInstance(targetType); instance = _devices.DeviceDic[targetType.Name];
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -487,13 +487,6 @@ namespace BOB.ViewModels
var tmp = JsonConvert.DeserializeObject<ProgramModel>(jsonstr); var tmp = JsonConvert.DeserializeObject<ProgramModel>(jsonstr);
if (tmp != null) if (tmp != null)
{ {
if (tmp.Devices != null && tmp.Devices.Count > 0)
{
foreach (var device in tmp.Devices)
{
// _ = DeviceConnect.InitAndConnectDevice(tmp, device);
}
}
newStep.SubProgram = tmp; newStep.SubProgram = tmp;
} }
if (insertIndex >= 0 && insertIndex <= Program.StepCollection.Count) if (insertIndex >= 0 && insertIndex <= Program.StepCollection.Count)

View File

@ -101,7 +101,6 @@ namespace BOB.ViewModels
private GlobalVariables _globalVariables; private GlobalVariables _globalVariables;
private IContainerProvider _containerProvider; private IContainerProvider _containerProvider;
private StepRunning _stepRunning; private StepRunning _stepRunning;
private Devices _devices;
private Task? currentExecutionTask; private Task? currentExecutionTask;
public ShellViewModel(IEventAggregator eventAggregator, IContainerProvider containerProvider,GlobalVariables globalVariables, StepRunning stepRunning) public ShellViewModel(IEventAggregator eventAggregator, IContainerProvider containerProvider,GlobalVariables globalVariables, StepRunning stepRunning)
{ {
@ -163,7 +162,6 @@ namespace BOB.ViewModels
{ {
_globalVariables.CurrentFilePath = null; _globalVariables.CurrentFilePath = null;
_globalVariables.Program.Parameters.Clear(); _globalVariables.Program.Parameters.Clear();
_globalVariables.Program.Devices.Clear();
_globalVariables.Program.StepCollection.Clear(); _globalVariables.Program.StepCollection.Clear();
} }
@ -207,7 +205,6 @@ namespace BOB.ViewModels
} }
_globalVariables.Program.Parameters = program.Parameters; _globalVariables.Program.Parameters = program.Parameters;
_globalVariables.Program.Devices = program.Devices;
_globalVariables.Program.StepCollection = program.StepCollection; _globalVariables.Program.StepCollection = program.StepCollection;
_globalVariables.CurrentFilePath = filePath; _globalVariables.CurrentFilePath = filePath;
LoggerHelper.SuccessWithNotify($"成功打开文件: {filePath}"); LoggerHelper.SuccessWithNotify($"成功打开文件: {filePath}");
@ -258,10 +255,6 @@ namespace BOB.ViewModels
private ProgramModel ClearDeviceParameterValue(ProgramModel program) private ProgramModel ClearDeviceParameterValue(ProgramModel program)
{ {
var tmp = new ProgramModel(program); var tmp = new ProgramModel(program);
foreach (var device in tmp.Devices)
{
tmp.Parameters.Remove(tmp.Parameters.First(x => x.ID == device.ParameterID));
}
foreach (var step in tmp.StepCollection) foreach (var step in tmp.StepCollection)
{ {
if (step.SubProgram != null) if (step.SubProgram != null)

View File

@ -0,0 +1,163 @@
using Common.Attributes;
using DeviceCommand.Base;
using System;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceCommand.Device
{
[BOBCommand]
public class IT6724CReverse : Serial_Port
{
public IT6724CReverse(string COMPort,int BaudRate,int DataBits, StopBits stopBits, Parity parity,int ReadTimeout,int ReceiveTimeout)
{
ConfigureDevice(COMPort,BaudRate,DataBits,stopBits,parity, ReadTimeout, ReceiveTimeout);
}
public IT6724CReverse()
{
}
#region
/// <summary>
/// 设置输出状态true 为开false 为关
/// </summary>
public Task SetOutputAsync(bool state, CancellationToken ct = default)
=> SendAsync($"OUTPut {(state ? 1 : 0)}\r\n", ct);
/// <summary>
/// 切换到远程控制模式
/// </summary>
public Task SetRemoteModeAsync(CancellationToken ct = default)
=> SendAsync("SYSTem:REMote\r\n", ct);
/// <summary>
/// 蜂鸣器测试
/// </summary>
public Task BeeperTestAsync(CancellationToken ct = default)
=> SendAsync("SYSTem:BEEPer\r\n", ct);
/// <summary>
/// 设置输出电流单位A
/// </summary>
public Task SetCurrentAsync(double current, CancellationToken ct = default)
=> SendAsync($"CURRent {current}\r\n", ct);
/// <summary>
/// 设置过流保护电流OCP单位A
/// </summary>
public Task SetOCPCurrentAsync(double current, CancellationToken ct = default)
=> SendAsync($"CURRent:PROTection {current}\r\n", ct);
/// <summary>
/// 设置过流保护状态true 为启用false 为禁用
/// </summary>
public Task SetOCPStateAsync(bool state, CancellationToken ct = default)
=> SendAsync($"CURRent:PROTection:STATe {(state ? 1 : 0)}\r\n", ct);
/// <summary>
/// 清除过流保护触发状态
/// </summary>
public Task ClearOCPAsync(CancellationToken ct = default)
=> SendAsync("CURRent:PROTection:CLEar\r\n", ct);
/// <summary>
/// 设置输出电压单位V
/// </summary>
public Task SetVoltageAsync(double voltage, CancellationToken ct = default)
=> SendAsync($"VOLTage {voltage}\r\n", ct);
/// <summary>
/// 设置过压保护电压OVP单位V
/// </summary>
public Task SetOVPVoltageAsync(double voltage, CancellationToken ct = default)
=> SendAsync($"VOLT:PROTection {voltage}\r\n", ct);
/// <summary>
/// 设置过压保护状态true 为启用false 为禁用
/// </summary>
public Task SetOVPStateAsync(bool state, CancellationToken ct = default)
=> SendAsync($"VOLT:PROTection:STATe {(state ? 1 : 0)}\r\n", ct);
/// <summary>
/// 清除过压保护触发状态
/// </summary>
public Task ClearOVPAsync(CancellationToken ct = default)
=> SendAsync("VOLT:PROTection:CLEar\r\n", ct);
/// <summary>
/// 发送自定义命令
/// </summary>
public Task SendCustomCommandAsync(string command, CancellationToken ct = default)
=> SendAsync($"{command}\r\n", ct);
#endregion
#region
/// <summary>
/// 查询仪器标识,返回制造商、型号、序列号、固件版本
/// </summary>
public async Task<string> QueryIDAsync(CancellationToken ct = default)
{
await SendAsync("*IDN?\r\n", ct);
return await ReadAsync(ct: ct);
}
/// <summary>
/// 查询过流保护是否触发,返回 true 表示触发
/// </summary>
public async Task<bool> QueryOCPTrippedAsync(CancellationToken ct = default)
{
await SendAsync("CURRent:PROTection:TRIPed?\r\n", ct);
var result = await ReadAsync(ct: ct);
return result == "1";
}
/// <summary>
/// 查询过压保护是否触发,返回 true 表示触发
/// </summary>
public async Task<bool> QueryOVPTrippedAsync(CancellationToken ct = default)
{
await SendAsync("VOLT:PROTection:TRIPed?\r\n", ct);
var result = await ReadAsync(ct: ct);
return result == "1";
}
/// <summary>
/// 查询实际输出电流单位A
/// </summary>
public async Task<double> QueryCurrentAsync(CancellationToken ct = default)
{
await SendAsync("MEASure:CURRent?\r\n", ct);
var result = await ReadAsync(ct: ct);
return Convert.ToDouble(result);
}
/// <summary>
/// 查询实际输出电压单位V
/// </summary>
public async Task<double> QueryVoltageAsync(CancellationToken ct = default)
{
await SendAsync("MEASure:VOLTage?\r\n", ct);
var result = await ReadAsync(ct: ct);
return Convert.ToDouble(result);
}
/// <summary>
/// 查询实际输出功率单位W
/// </summary>
public async Task<double> QueryPowerAsync(CancellationToken ct = default)
{
await SendAsync("MEASure:POWer?\r\n", ct);
var result = await ReadAsync(ct: ct);
return Convert.ToDouble(result);
}
#endregion
}
}