diff --git a/BOB/App.xaml.cs b/BOB/App.xaml.cs index 7455af9..536f904 100644 --- a/BOB/App.xaml.cs +++ b/BOB/App.xaml.cs @@ -59,7 +59,12 @@ namespace BOB containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); } - + protected override void OnExit(ExitEventArgs e) + { + var devices = Container.Resolve(); + devices.Dispose(); + base.OnExit(e); + } } } diff --git a/BOB/Singleton/Devices.cs b/BOB/Singleton/Devices.cs index e0c8b7f..b74681e 100644 --- a/BOB/Singleton/Devices.cs +++ b/BOB/Singleton/Devices.cs @@ -13,6 +13,9 @@ namespace BOB.Singleton { public class Devices { + private CancellationTokenSource _appCancellationTokenSource = new(); + public CancellationToken AppCancellationToken => _appCancellationTokenSource.Token; + public Dictionary DeviceDic { get; private set; } = new Dictionary(); private readonly ProxyGenerator _proxyGen = new ProxyGenerator(); @@ -230,5 +233,11 @@ namespace BOB.Singleton } } + + public void Dispose() + { + _appCancellationTokenSource.Cancel(); + _appCancellationTokenSource.Dispose(); + } } } diff --git a/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs b/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs index 7f34b87..5d84ffd 100644 --- a/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs +++ b/BOB/ViewModels/Dialogs/DeviceSettingViewModel.cs @@ -1,5 +1,6 @@ using BOB.Models; using Common.PubEvent; +using Model; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -21,156 +22,30 @@ namespace BOB.ViewModels.Dialogs get => _title; set => SetProperty(ref _title, value); } - private ObservableCollection _types = ["串口", "Tcp", "ModbusRtu", "ModbusTcp", "CAN", "Udp"]; - public ObservableCollection Types - { - get => _types; - set => SetProperty(ref _types, value); - } - - private string _Mode; - public string Mode - { - get => _Mode; - set => SetProperty(ref _Mode, value); - } - private bool _IsAdd; - public bool IsAdd - { - get => _IsAdd; - set => SetProperty(ref _IsAdd, value); - } - - private ProgramModel _program; - public ProgramModel Program - { - get => _program; - set => SetProperty(ref _program, value); - } - private DeviceModel _Device; - public DeviceModel Device + private DeviceInfoModel _Device; + public DeviceInfoModel Device { get => _Device; set => SetProperty(ref _Device, value); } - private ObservableCollection _DeviceConnectSettings=new(); - public ObservableCollection DeviceConnectSettings - { - get => _DeviceConnectSettings; - set => SetProperty(ref _DeviceConnectSettings, value); - } - #endregion public DialogCloseListener RequestClose { get; set; } private GlobalVariables _globalVariables; private IEventAggregator _eventAggregator; public ICommand CancelCommand { get; set; } public ICommand SaveCommand { get; set; } - public ICommand SelectionChangedCommand { get; set; } public DeviceSettingViewModel(GlobalVariables globalVariables, IEventAggregator eventAggregator) { _eventAggregator = eventAggregator; _globalVariables = globalVariables; CancelCommand = new DelegateCommand(Cancel); SaveCommand = new DelegateCommand(Save); - SelectionChangedCommand = new DelegateCommand(SelectionChanged); } - private void SelectionChanged() - { - if (Device == null) return; - DeviceConnectSettings.Clear(); - switch (Device!.Type) - { - case "Tcp": - case "ModbusTcp": - DeviceConnectSettings.Add(new() - { - Name = "IP地址", - Value = "127.0.0.1" - }); - DeviceConnectSettings.Add(new() - { - Name = "端口号", - Value = "502" - }); - break; - case "串口": - case "ModbusRtu": - DeviceConnectSettings.Add(new() - { - Name = "COM口", - Value = "COM1" - }); - DeviceConnectSettings.Add(new() - { - Name = "波特率", - Value = "9600" - }); - DeviceConnectSettings.Add(new() - { - Name = "数据位", - Value = "8" - }); - DeviceConnectSettings.Add(new() - { - Name = "停止位", - Value = "1" - }); - DeviceConnectSettings.Add(new() - { - Name = "奇偶", - Value = "无" - }); - break; - case "Udp": - DeviceConnectSettings.Add(new() - { - Name = "远程IP地址", - Value = "127.0.0.1" - }); - DeviceConnectSettings.Add(new() - { - Name = "远程端口号", - Value = "8080" - }); - DeviceConnectSettings.Add(new() - { - Name = "本地端口号", - Value = "0" - }); - break; - } - DeviceConnectSettings.Add(new() - { - Name = "读超时", - Value = "3000" - }); - DeviceConnectSettings.Add(new() - { - Name = "写超时", - Value = "3000" - }); - } + private void Save() { - if (Mode == "ADD") - { - Program.Devices.Add(Device); - _globalVariables.SelectedDevice = Device; - } - else - { - var index = Program.Devices - .Select((x, i) => new { x, i }) - .FirstOrDefault(p => p.x.ID == _globalVariables.SelectedDevice.ID)?.i; - - if (index.HasValue) - { - Program.Devices[index.Value] = Device; - } - } RequestClose.Invoke(ButtonResult.OK); } @@ -192,20 +67,7 @@ namespace BOB.ViewModels.Dialogs public void OnDialogOpened(IDialogParameters parameters) { _eventAggregator.GetEvent().Publish(true); - Program = _globalVariables.Program; - Mode = parameters.GetValue("Mode"); - if(Mode == "ADD") - { - Device = new(); - IsAdd = true; - Device.Type = "Tcp"; - SelectionChanged(); - } - else - { - Device = new DeviceModel(_globalVariables.SelectedDevice); - IsAdd = false; - } + } #endregion } diff --git a/BOB/ViewModels/ParametersManagerViewModel.cs b/BOB/ViewModels/ParametersManagerViewModel.cs index 6987cc7..ff0ae01 100644 --- a/BOB/ViewModels/ParametersManagerViewModel.cs +++ b/BOB/ViewModels/ParametersManagerViewModel.cs @@ -1,6 +1,11 @@ using BOB.Models; +using BOB.Singleton; using Common.PubEvent; +using DeviceCommand.Base; +using DeviceCommand.Device; +using Logger; using MaterialDesignThemes.Wpf; +using Model; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -16,6 +21,21 @@ namespace BOB.ViewModels public class ParametersManagerViewModel:BindableBase { #region 属性 + private ObservableCollection _DeviceList; + + public ObservableCollection DeviceList + { + get { return _DeviceList; } + set { SetProperty(ref _DeviceList,value); } + } + private ObservableCollection _DeviceInfoModel; + + public ObservableCollection DeviceInfoModel + { + get { return _DeviceInfoModel; } + set { SetProperty(ref _DeviceInfoModel, value); } + } + public ProgramModel Program { get => _globalVariables.Program; @@ -40,84 +60,148 @@ namespace BOB.ViewModels } } } - private DeviceModel _SelectedDevice; - public DeviceModel SelectedDevice + private DeviceInfoModel _SelectedDevice; + public DeviceInfoModel SelectedDevice { - get => _SelectedDevice; - set - { - if (SetProperty(ref _SelectedDevice, value)) - { - _globalVariables.SelectedDevice = value; - } - } + get { return _SelectedDevice; } + set { SetProperty(ref _SelectedDevice, value); } } #endregion private GlobalVariables _globalVariables { get; set; } private IDialogService _dialogService { get; set; } + private Devices _devices { get; set; } private IEventAggregator _eventAggregator { get; set; } public ICommand ParameterAddCommand { get; set; } public ICommand ParameterEditCommand { get; set; } public ICommand ParameterDeleteCommand { get; set; } - public ICommand DeviceAddCommand { get; set; } public ICommand DeviceEditCommand { get; set; } - public ICommand DeviceDeleteCommand { get; set; } + public ICommand ReconnnectCommand { get; set; } - public ParametersManagerViewModel(GlobalVariables GlobalVariables,IDialogService dialogService,IEventAggregator eventAggregator) + public ParametersManagerViewModel(GlobalVariables GlobalVariables,IDialogService dialogService,IEventAggregator eventAggregator,IContainerProvider containerProvider) { _globalVariables = GlobalVariables; _eventAggregator= eventAggregator; + _devices=containerProvider.Resolve(); _dialogService = dialogService; Program = _globalVariables.Program; ParameterAddCommand = new DelegateCommand(ParameterAdd); ParameterEditCommand = new DelegateCommand(ParameterEdit); ParameterDeleteCommand = new DelegateCommand(ParameterDelete); - DeviceAddCommand = new DelegateCommand(DeviceAdd); DeviceEditCommand = new DelegateCommand(DeviceEdit); - DeviceDeleteCommand = new DelegateCommand(DeviceDelete); - - + ReconnnectCommand = new DelegateCommand(Reconnnect); + DeviceList = new ObservableCollection(SystemConfig.Instance.DeviceList); + InitData(); } + + private void Reconnnect() + { + if(SelectedDevice!=null) + { + if (_devices.DeviceDic.TryGetValue(SelectedDevice.Remark, out var device) && device != null) + { + Task.Run(async () => + { + switch (device) + { + case ITcp tcpDevice: + await tcpDevice.ConnectAsync(); + break; + + case ISerialPort serialDevice: + await serialDevice.ConnectAsync(); + break; + + case IModbusDevice modbusDevice: + await modbusDevice.ConnectAsync(); + break; + } + }); + } + } + } + + private void InitData() + { + DeviceInfoModel = new ObservableCollection(); + for (int i = 0; i < DeviceList.Count; i++) + { + DeviceInfoModel.Add(new DeviceInfoModel + { + DeviceName = DeviceList[i].DeviceName, + Remark = DeviceList[i].Remark, + IsConnected = false, + IsEnabled= DeviceList[i].IsEnabled, + DeviceType= DeviceList[i].DeviceType, + CommunicationConfig= DeviceList[i].CommunicationConfig + }); + } + + var progress = new Progress<(int index, bool isConnected)>(); + progress.ProgressChanged += (s, e) => + { + DeviceInfoModel[e.index].IsConnected = e.isConnected; + }; + + var token = _devices.AppCancellationToken; + Task.Run(() => PollingConnection(progress, token)); + } + + private async Task PollingConnection(IProgress<(int index, bool isConnected)> progress, CancellationToken token) + { + while (!token.IsCancellationRequested) + { + for (int i = 0; i < DeviceList.Count; i++) + { + bool isConnected = false; + + if (_devices.DeviceDic.TryGetValue(DeviceList[i].Remark, out var device) && device != null) + { + switch (device) + { + case ITcp tcpDevice: + isConnected = tcpDevice.TcpClient?.Connected ?? false; + break; + + case ISerialPort serialDevice: + isConnected = serialDevice.SerialPort?.IsOpen ?? false; + break; + + case IModbusDevice modbusDevice: + isConnected = (modbusDevice.TcpClient?.Connected ?? false) || (modbusDevice.SerialPort?.IsOpen ?? false); + break; + } + } + + progress.Report((i, isConnected)); + } + + await Task.Delay(200, token); // 支持取消 + } + } + + + #region 委托命令 - private void DeviceDelete() - { - Program.Devices.Remove(SelectedDevice); - } + private void DeviceEdit() { + if(SelectedDevice==null) + { + return; + } var param = new DialogParameters { - { "Mode", SelectedDevice==null?"ADD":"Edit" } + { "Devices", SelectedDevice } }; _dialogService.ShowDialog("DeviceSetting", param, (r) => { if (r.Result == ButtonResult.OK) { - _eventAggregator.GetEvent().Publish(); - } - else - { - - } - }); - - } - - private void DeviceAdd() - { - var param = new DialogParameters - { - { "Mode", "ADD" } - }; - _dialogService.ShowDialog("DeviceSetting", param, (r) => - { - if (r.Result == ButtonResult.OK) - { - _eventAggregator.GetEvent().Publish(); + } else { diff --git a/BOB/Views/Dialogs/DeviceSetting.xaml b/BOB/Views/Dialogs/DeviceSetting.xaml index d5493e7..65d393a 100644 --- a/BOB/Views/Dialogs/DeviceSetting.xaml +++ b/BOB/Views/Dialogs/DeviceSetting.xaml @@ -56,31 +56,12 @@ - - -