将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using Prism.Commands;
|
||||
using Prism.Mvvm;
|
||||
using XP.Common.Logging.Interfaces;
|
||||
using XP.Hardware.Plc.Abstractions;
|
||||
using XP.Hardware.Plc.Exceptions;
|
||||
using XP.Hardware.Plc.Services;
|
||||
using XP.Hardware.PLC.Configs;
|
||||
|
||||
namespace XP.App.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// 信号数据服务 DEMO 窗口 ViewModel
|
||||
/// </summary>
|
||||
public class SignalDataDemoViewModel : BindableBase
|
||||
{
|
||||
private readonly PlcService _plcService;
|
||||
private readonly ISignalDataService _signalService;
|
||||
private readonly ConfigLoader _configLoader;
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
// 日志
|
||||
public ObservableCollection<string> LogEntries { get; } = new();
|
||||
|
||||
// 连接状态
|
||||
public bool IsConnected => _plcService.IsConnected;
|
||||
public string StatusText => _plcService.StatusText;
|
||||
|
||||
private bool _isInitialized;
|
||||
public bool IsInitialized
|
||||
{
|
||||
get => _isInitialized;
|
||||
set => SetProperty(ref _isInitialized, value);
|
||||
}
|
||||
|
||||
// 缓存读取
|
||||
private string _readSignalName = "";
|
||||
public string ReadSignalName
|
||||
{
|
||||
get => _readSignalName;
|
||||
set => SetProperty(ref _readSignalName, value);
|
||||
}
|
||||
|
||||
private string _readResult = "";
|
||||
public string ReadResult
|
||||
{
|
||||
get => _readResult;
|
||||
set => SetProperty(ref _readResult, value);
|
||||
}
|
||||
|
||||
// 队列写入
|
||||
private string _queueSignalName = "";
|
||||
public string QueueSignalName
|
||||
{
|
||||
get => _queueSignalName;
|
||||
set => SetProperty(ref _queueSignalName, value);
|
||||
}
|
||||
|
||||
private string _queueWriteValue = "";
|
||||
public string QueueWriteValue
|
||||
{
|
||||
get => _queueWriteValue;
|
||||
set => SetProperty(ref _queueWriteValue, value);
|
||||
}
|
||||
|
||||
// 直接写入+回读校验
|
||||
private string _directSignalName = "";
|
||||
public string DirectSignalName
|
||||
{
|
||||
get => _directSignalName;
|
||||
set => SetProperty(ref _directSignalName, value);
|
||||
}
|
||||
|
||||
private string _directWriteValue = "";
|
||||
public string DirectWriteValue
|
||||
{
|
||||
get => _directWriteValue;
|
||||
set => SetProperty(ref _directWriteValue, value);
|
||||
}
|
||||
|
||||
// 信号定义文件路径
|
||||
private string _xmlFilePath = "PlcAddrDfn.xml";
|
||||
public string XmlFilePath
|
||||
{
|
||||
get => _xmlFilePath;
|
||||
set => SetProperty(ref _xmlFilePath, value);
|
||||
}
|
||||
|
||||
// 命令
|
||||
public DelegateCommand ConnectAndLoadCommand { get; }
|
||||
public DelegateCommand CacheReadCommand { get; }
|
||||
public DelegateCommand QueueWriteCommand { get; }
|
||||
public DelegateCommand DirectWriteCommand { get; }
|
||||
public DelegateCommand ClearLogCommand { get; }
|
||||
|
||||
public SignalDataDemoViewModel(
|
||||
PlcService plcService,
|
||||
ISignalDataService signalService,
|
||||
ConfigLoader configLoader,
|
||||
ILoggerService logger)
|
||||
{
|
||||
_plcService = plcService ?? throw new ArgumentNullException(nameof(plcService));
|
||||
_signalService = signalService ?? throw new ArgumentNullException(nameof(signalService));
|
||||
_configLoader = configLoader ?? throw new ArgumentNullException(nameof(configLoader));
|
||||
_logger = logger?.ForModule<SignalDataDemoViewModel>() ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_plcService.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(PlcService.IsConnected))
|
||||
RaisePropertyChanged(nameof(IsConnected));
|
||||
else if (e.PropertyName == nameof(PlcService.StatusText))
|
||||
RaisePropertyChanged(nameof(StatusText));
|
||||
};
|
||||
|
||||
ConnectAndLoadCommand = new DelegateCommand(async () => await ConnectAndLoadAsync());
|
||||
CacheReadCommand = new DelegateCommand(CacheRead);
|
||||
QueueWriteCommand = new DelegateCommand(QueueWrite);
|
||||
DirectWriteCommand = new DelegateCommand(async () => await DirectWriteAsync());
|
||||
ClearLogCommand = new DelegateCommand(() => LogEntries.Clear());
|
||||
}
|
||||
|
||||
private void Log(string msg)
|
||||
{
|
||||
var text = $"[{DateTime.Now:HH:mm:ss.fff}] {msg}";
|
||||
LogEntries.Add(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接 PLC 并加载信号定义
|
||||
/// </summary>
|
||||
private async Task ConnectAndLoadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Log("正在加载配置...");
|
||||
var config = _configLoader.LoadPlcConfig();
|
||||
Log($"配置加载成功: {config.IpAddress}:{config.Port}, DB读={config.ReadDbBlock}");
|
||||
|
||||
Log("正在连接 PLC...");
|
||||
var result = await _plcService.InitializeAsync(config);
|
||||
if (!result)
|
||||
{
|
||||
Log("ERROR: PLC 连接失败");
|
||||
return;
|
||||
}
|
||||
Log("PLC 连接成功");
|
||||
|
||||
Log($"正在加载信号定义: {XmlFilePath}");
|
||||
_plcService.LoadSignalDefinitions(XmlFilePath);
|
||||
Log("信号定义加载成功");
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"ERROR: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存读取
|
||||
/// </summary>
|
||||
private void CacheRead()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ReadSignalName))
|
||||
{
|
||||
Log("ERROR: 请输入信号名称");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var value = _signalService.GetValueByName(ReadSignalName);
|
||||
ReadResult = value?.ToString() ?? "null";
|
||||
Log($"缓存读取成功: {ReadSignalName} = {ReadResult} (类型: {value?.GetType().Name ?? "null"})");
|
||||
}
|
||||
catch (PlcException ex)
|
||||
{
|
||||
ReadResult = "ERROR";
|
||||
Log($"ERROR: 缓存读取失败 - {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReadResult = "ERROR";
|
||||
Log($"ERROR: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 队列写入
|
||||
/// </summary>
|
||||
private void QueueWrite()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(QueueSignalName))
|
||||
{
|
||||
Log("ERROR: 请输入信号名称");
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(QueueWriteValue))
|
||||
{
|
||||
Log("ERROR: 请输入写入值");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 尝试解析为数值,否则作为字符串
|
||||
object value = ParseInputValue(QueueWriteValue);
|
||||
bool enqueued = _signalService.EnqueueWrite(QueueSignalName, value);
|
||||
Log(enqueued
|
||||
? $"队列写入成功: {QueueSignalName} = {QueueWriteValue}"
|
||||
: $"WARN: 队列写入返回 false(队列未运行或已满): {QueueSignalName}");
|
||||
}
|
||||
catch (PlcException ex)
|
||||
{
|
||||
Log($"ERROR: 队列写入失败 - {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"ERROR: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接写入+回读校验
|
||||
/// </summary>
|
||||
private async Task DirectWriteAsync()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(DirectSignalName))
|
||||
{
|
||||
Log("ERROR: 请输入信号名称");
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(DirectWriteValue))
|
||||
{
|
||||
Log("ERROR: 请输入写入值");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
object value = ParseInputValue(DirectWriteValue);
|
||||
Log($"正在直接写入: {DirectSignalName} = {DirectWriteValue}...");
|
||||
bool verified = await _signalService.WriteDirectWithVerify(DirectSignalName, value);
|
||||
Log(verified
|
||||
? $"直接写入校验通过: {DirectSignalName} = {DirectWriteValue}"
|
||||
: $"WARN: 直接写入校验失败: {DirectSignalName} = {DirectWriteValue}");
|
||||
}
|
||||
catch (PlcException ex)
|
||||
{
|
||||
Log($"ERROR: 直接写入失败 - {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"ERROR: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析用户输入值:尝试 bool → int → double → string
|
||||
/// </summary>
|
||||
private object ParseInputValue(string input)
|
||||
{
|
||||
if (bool.TryParse(input, out bool bVal)) return bVal;
|
||||
if (int.TryParse(input, out int iVal)) return iVal;
|
||||
if (double.TryParse(input, out double dVal)) return dVal;
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user