diff --git a/CapMachine.Core/DialogViewModel.cs b/CapMachine.Core/DialogViewModel.cs index df39e3a..0b1594f 100644 --- a/CapMachine.Core/DialogViewModel.cs +++ b/CapMachine.Core/DialogViewModel.cs @@ -13,7 +13,7 @@ namespace CapMachine.Core /// public class DialogViewModel : BindableBase, IDialogAware { - public string Title { get; set; } + public string? Title { get; set; } public event Action? RequestClose; @@ -40,9 +40,22 @@ namespace CapMachine.Core /// public void OnDialogClosed() { - + OnDialogClosed(ButtonResult.OK); } + public void OnDialogClosed(ButtonResult result) + { + RequestClose?.Invoke(new DialogResult(result)); + } + + public void OnDialogClosed(IDialogResult dialogResult) + { + RequestClose?.Invoke(dialogResult); + } + + //public void OnDialogClosed() => OnDialogClosed(ButtonResult.OK); + + /// /// 打开时触发 /// @@ -51,5 +64,31 @@ namespace CapMachine.Core { } + + public bool IsNotBusy => !IsBusy; + private bool isBusy; + public bool IsBusy + { + get => isBusy; + set + { + isBusy = value; + RaisePropertyChanged(); + RaisePropertyChanged(nameof(IsNotBusy)); + } + } + + public virtual async Task SetBusyAsync(Func func, string loadingMessage = null) + { + IsBusy = true; + try + { + await func(); + } + finally + { + IsBusy = false; + } + } } } diff --git a/CapMachine.Model/CANLIN/CanLinConfigPro.cs b/CapMachine.Model/CANLIN/CanLinConfigPro.cs index 882cdc0..249ecb8 100644 --- a/CapMachine.Model/CANLIN/CanLinConfigPro.cs +++ b/CapMachine.Model/CANLIN/CanLinConfigPro.cs @@ -46,11 +46,18 @@ namespace CapMachine.Model.CANLIN /// - /// ///////////////////////////////////////////导航属性 一对一/////////////////////////////////////////////////////// + /// ///////////////////////////////////////////导航属性 CAN 一对一/////////////////////////////////////////////////////// /// - public long CANConfigExdId { get; set; } // 外键字段,必要 public CANConfigExd CANConfigExd { get; set; } + + + + /// + /// ///////////////////////////////////////////导航属性 LIN 一对一/////////////////////////////////////////////////////// + /// + public long LINConfigExdId { get; set; } // 外键字段,必要 + public LINConfigExd LINConfigExd { get; set; } } } diff --git a/CapMachine.Model/CANLIN/CanLinEmun.cs b/CapMachine.Model/CANLIN/CanLinEmun.cs index 5613239..42802ed 100644 --- a/CapMachine.Model/CANLIN/CanLinEmun.cs +++ b/CapMachine.Model/CANLIN/CanLinEmun.cs @@ -6,11 +6,6 @@ using System.Threading.Tasks; namespace CapMachine.Model.CANLIN { - public class CanLinEnum - { - - } - /// /// CANLIN的枚举 /// diff --git a/CapMachine.Model/CANLIN/LINConfigExd.cs b/CapMachine.Model/CANLIN/LINConfigExd.cs new file mode 100644 index 0000000..f681e0e --- /dev/null +++ b/CapMachine.Model/CANLIN/LINConfigExd.cs @@ -0,0 +1,35 @@ +using FreeSql.DataAnnotations; + +namespace CapMachine.Model.CANLIN +{ + /// + /// LIN配置拓展数据 + /// + [Table(Name = "LINConfigExd")] + public class LINConfigExd + { + /// + /// 主键 + /// + [Column(IsPrimary = true, IsIdentity = true)] + public long Id { get; set; } + + /// + /// 波特率 + /// + [Column(Name = "BaudRate")] + public int BaudRate { get; set; } + + /// + /// 周期 + /// + [Column(Name = "Cycle")] + public int Cycle { get; set; } + + /// + /// Ldf 文件路径 + /// + [Column(Name = "LdfPath", IsNullable = false, StringLength = 500)] + public string? LdfPath { get; set; } + } +} diff --git a/CapMachine.Shared/Controls/Meter.xaml b/CapMachine.Shared/Controls/Meter.xaml index a29f0e4..67fe2c8 100644 --- a/CapMachine.Shared/Controls/Meter.xaml +++ b/CapMachine.Shared/Controls/Meter.xaml @@ -111,16 +111,29 @@ Text="{Binding ElementName=MeterInstance, Path=AutoStateMsg}" Command="{Binding ElementName=MeterInstance, Path=AutoHandCommand}" CommandParameter="{Binding ElementName=MeterInstance}" - 把整个控件作为参数传递进去 + 把整个控件作为参数传递进去 Text="{Binding ElementName=MeterInstance, Path=HandValueMVParameter}" --> + Visibility="{Binding ElementName=MeterInstance, Path=IsHandValueShow}"> + + + + + Visibility="{Binding ElementName=MeterInstance, Path=IsHandValueShow}"> + + + + /// 手动设置的是值是否显示 /// @@ -275,6 +275,42 @@ namespace CapMachine.Shared.Controls public static readonly DependencyProperty HandValueSVParameterProperty = DependencyProperty.Register("HandValueSVParameter", typeof(object), typeof(Meter), new PropertyMetadata(0)); + /// + /// 手自给值 临时输入用参数 SV + /// + public object HandValueTempSVParameter + { + get + { + return (object)base.GetValue(Meter.HandValueTempSVParameterProperty); + } + set + { + base.SetValue(Meter.HandValueTempSVParameterProperty, value); + } + } + public static readonly DependencyProperty HandValueTempSVParameterProperty = DependencyProperty.Register("HandValueTempSVParameter", typeof(object), typeof(Meter), new PropertyMetadata(0)); + + + + /// + /// 手自给值 临时输入用参数 MV + /// + public object HandValueTempMVParameter + { + get + { + return (object)base.GetValue(Meter.HandValueTempMVParameterProperty); + } + set + { + base.SetValue(Meter.HandValueTempMVParameterProperty, value); + } + } + public static readonly DependencyProperty HandValueTempMVParameterProperty = DependencyProperty.Register("HandValueTempMVParameter", typeof(object), typeof(Meter), new PropertyMetadata(0)); + + + /// /// 手动给值回车检测 /// @@ -291,7 +327,7 @@ namespace CapMachine.Shared.Controls if (double.TryParse(HandValueMV.Text, out double Result)) { //把整个控件打包发送过去,无法访问Textbox的值,那么直接传送模型的数据给ViewModel - HandValueCommand.Execute(new MeterChannelValue() { Name = MeterName, Value = Result,Type="MV" }); + HandValueCommand.Execute(new MeterChannelValue() { Name = MeterName, Value = Result, Type = "MV" }); } } @@ -309,6 +345,7 @@ namespace CapMachine.Shared.Controls { if (HandValueCommand != null && HandValueCommand.CanExecute(HandValueSVParameter)) { + //HandValueTempSVParameter = HandValueSVParameter; //HandValueParameter 此时无法更新到最新的值(旧值),可能因为RaisePropertyChanged在ViewModel上,不受这边的控制了,所以直接取控件的数据 //HandValueParameter 没有使用,直接取控件的值,HandValueParameter作为初始值使用 if (double.TryParse(HandValueSV.Text, out double Result)) @@ -316,8 +353,9 @@ namespace CapMachine.Shared.Controls //把整个控件打包发送过去,无法访问Textbox的值,那么直接传送模型的数据给ViewModel HandValueCommand.Execute(new MeterChannelValue() { Name = MeterName, Value = Result, Type = "SV" }); } - } + + } } } diff --git a/CapMachine.Wpf/App.xaml b/CapMachine.Wpf/App.xaml index d791b16..6d4a68e 100644 --- a/CapMachine.Wpf/App.xaml +++ b/CapMachine.Wpf/App.xaml @@ -2,9 +2,11 @@ x:Class="CapMachine.Wpf.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:bar="http://www.hardcodet.net/taskbar" xmlns:local="clr-namespace:CapMachine.Wpf" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" - xmlns:prism="http://prismlibrary.com/"> + xmlns:prism="http://prismlibrary.com/" + xmlns:viewmodels="clr-namespace:CapMachine.Wpf.ViewModels"> @@ -20,6 +22,28 @@ + + + diff --git a/CapMachine.Wpf/App.xaml.cs b/CapMachine.Wpf/App.xaml.cs index 6150690..e476066 100644 --- a/CapMachine.Wpf/App.xaml.cs +++ b/CapMachine.Wpf/App.xaml.cs @@ -8,6 +8,7 @@ using CapMachine.Wpf.ViewModels; using CapMachine.Wpf.Views; using FreeSql; using FreeSql.Internal; +using Hardcodet.Wpf.TaskbarNotification; using Prism.DryIoc; using Prism.Ioc; using Prism.Regions; @@ -24,6 +25,8 @@ namespace CapMachine.Wpf /// public partial class App : PrismApplication { + private TaskbarIcon taskBar; + /// /// 日志服务 /// @@ -38,7 +41,7 @@ namespace CapMachine.Wpf //24.2.7 //Syncfusion.SfSkinManager.SfSkinManager.ApplyStylesOnApplication = true; Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("MzEyMzM3NkAzMjM0MmUzMDJlMzBHdjVKNUNpNWZxYXQwR05ZbVYvUEtzbGxXMnVxRjYvRGtLSlZUOGpjQW44PQ=="); - + //System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN"); // 授权 a717c797-59e3-48de-b6b4-574a4e03dc79 @@ -89,19 +92,26 @@ namespace CapMachine.Wpf { ////注册日志服务 containerRegistry.RegisterSingleton(); + + //注册基础的服务 + //containerRegistry.RegisterSingleton(); + //containerRegistry.RegisterSingleton(); + //containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); - containerRegistry.RegisterSingleton(); ////注册设备服务 //containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); + + containerRegistry.RegisterSingleton(); - //注册AutoMapper 将IAutoMapperProvider注入IOC容器,并对外提供IMapper注入类型。 containerRegistry.RegisterSingleton(); @@ -145,7 +155,9 @@ namespace CapMachine.Wpf containerRegistry.RegisterForNavigation(); containerRegistry.RegisterForNavigation(); containerRegistry.RegisterForNavigation(); - + containerRegistry.RegisterForNavigation(); + + //注册Dialog视图时绑定VM containerRegistry.RegisterDialog(); containerRegistry.RegisterDialog(); @@ -162,7 +174,9 @@ namespace CapMachine.Wpf containerRegistry.RegisterDialog(); containerRegistry.RegisterDialog(); - + containerRegistry.RegisterDialog(); + + //注册AutoMapper //containerRegistry.RegisterSingleton(); //containerRegistry.Register(typeof(IMapper), GetMapper); @@ -191,6 +205,15 @@ namespace CapMachine.Wpf /// protected override void OnInitialized() { + + //初始加载资源的窗口 *******起始弹窗******** + //var appStart = ContainerLocator.Container.Resolve(); + //appStart.CreateShell(); + + + + //#region 初版 + //Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); //从容器中获取MainView的实例对象 @@ -222,8 +245,7 @@ namespace CapMachine.Wpf //先加载服务,防止在ViewModel中使用时速度慢 var appVersionService = ContainerLocator.Container.Resolve(); - //var appVersionService1 = ContainerLocator.Container.Resolve(); - //var appVersionService2 = ContainerLocator.Container.Resolve(); + var appVersionService2 = ContainerLocator.Container.Resolve(); var appVersionService12 = ContainerLocator.Container.Resolve(); var appVersionService3 = ContainerLocator.Container.Resolve(); var appVersionService4 = ContainerLocator.Container.Resolve(); @@ -235,15 +257,21 @@ namespace CapMachine.Wpf var appVersionService10 = ContainerLocator.Container.Resolve(); var appVersionService11 = ContainerLocator.Container.Resolve(); var appVersionService15 = ContainerLocator.Container.Resolve(); - - + + //给当前的全局异常捕捉服务使用 LogService = ContainerLocator.Container.Resolve(); LogService.Error("ex.ToString()"); base.OnInitialized(); + //#endregion + //*******起始弹窗 * ******* + //LogService = ContainerLocator.Container.Resolve(); + //LogService.Error("Start-->"); + + //base.OnInitialized(); } #region 全局异常捕捉 @@ -258,9 +286,11 @@ namespace CapMachine.Wpf AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); } + void App_Exit(object sender, ExitEventArgs e) { //程序退出时需要处理的业务 + LogService.Error("程序退出"); } @@ -370,8 +400,26 @@ namespace CapMachine.Wpf } + + #endregion + + ///// + ///// *******起始弹窗******** + ///// + //public void Initialization() + //{ + // taskBar = (TaskbarIcon)FindResource("taskBar"); + + //} + ///// + ///// *******起始弹窗******** + ///// + //public void Dispose() + //{ + // taskBar?.Dispose(); + //} } } diff --git a/CapMachine.Wpf/Assets/Images/Logo.png b/CapMachine.Wpf/Assets/Images/Logo.png new file mode 100644 index 0000000..b3459b1 Binary files /dev/null and b/CapMachine.Wpf/Assets/Images/Logo.png differ diff --git a/CapMachine.Wpf/CanDrive/ToomossCan.cs b/CapMachine.Wpf/CanDrive/ToomossCan.cs index 930cdde..29f9e07 100644 --- a/CapMachine.Wpf/CanDrive/ToomossCan.cs +++ b/CapMachine.Wpf/CanDrive/ToomossCan.cs @@ -151,6 +151,15 @@ namespace CapMachine.Wpf.CanDrive set { _OpenState = value; RaisePropertyChanged(); } } + private bool _DbcParserState; + /// + /// DBC解析的状态 + /// + public bool DbcParserState + { + get { return _DbcParserState; } + set { _DbcParserState = value; RaisePropertyChanged(); } + } /// /// 扫描到设备个数 @@ -325,6 +334,7 @@ namespace CapMachine.Wpf.CanDrive if (DBCHandle == 0) { Console.WriteLine("Parser DBC File error!"); + DbcParserState = false; return; } else @@ -368,6 +378,9 @@ namespace CapMachine.Wpf.CanDrive } Console.WriteLine(""); } + + //Dbc解析成功 + DbcParserState = true; } /// @@ -676,6 +689,7 @@ namespace CapMachine.Wpf.CanDrive //关闭设备 USB_DEVICE.USB_CloseDevice(DevHandle); OpenState = false; + DbcParserState = false; IsCycleRevice = false; IsCycleSend = false; } diff --git a/CapMachine.Wpf/CapMachine.Wpf.csproj b/CapMachine.Wpf/CapMachine.Wpf.csproj index 3776fa6..9aeae28 100644 --- a/CapMachine.Wpf/CapMachine.Wpf.csproj +++ b/CapMachine.Wpf/CapMachine.Wpf.csproj @@ -13,6 +13,7 @@ + @@ -180,6 +181,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -666,6 +670,7 @@ + @@ -679,6 +684,7 @@ + diff --git a/CapMachine.Wpf/Dtos/LINConfigExdDto.cs b/CapMachine.Wpf/Dtos/LINConfigExdDto.cs new file mode 100644 index 0000000..8288ac9 --- /dev/null +++ b/CapMachine.Wpf/Dtos/LINConfigExdDto.cs @@ -0,0 +1,47 @@ +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Dtos +{ + public class LINConfigExdDto : BindableBase + { + /// + /// 主键 + /// + public long Id { get; set; } + + private int _BaudRate; + /// + /// 波特率 + /// + public int BaudRate + { + get { return _BaudRate; } + set { _BaudRate = value; RaisePropertyChanged(); } + } + + private int _Cycle; + /// + /// 周期 + /// + public int Cycle + { + get { return _Cycle; } + set { _Cycle = value; RaisePropertyChanged(); } + } + + private string? _LdfPath; + /// + /// Ldf文件路径 + /// + public string? LdfPath + { + get { return _LdfPath; } + set { _LdfPath = value; RaisePropertyChanged(); } + } + } +} diff --git a/CapMachine.Wpf/LinDrive/LDFParser.cs b/CapMachine.Wpf/LinDrive/LDFParser.cs new file mode 100644 index 0000000..3334e7f --- /dev/null +++ b/CapMachine.Wpf/LinDrive/LDFParser.cs @@ -0,0 +1,73 @@ +using System.Runtime.InteropServices; +using System.Text; + +namespace CapMachine.Wpf.LinDrive +{ + /// + /// LDF文件解析 + /// + public class LDFParser + { + public const Int32 LDF_PARSER_OK = 0;//没有错误 + public const Int32 LDF_PARSER_FILE_OPEN = (-1);//打开文件出错 + public const Int32 LDF_PARSER_FILE_FORMAT = (-2);//文件格式错误 + public const Int32 LDF_PARSER_DEV_DISCONNECT = (-3);//设备未连接 + public const Int32 LDF_PARSER_HANDLE_ERROR = (-4);//LDF Handle错误 + public const Int32 LDF_PARSER_GET_INFO_ERROR = (-5);//获取解析后的数据出错 + public const Int32 LDF_PARSER_DATA_ERROR = (-6);//数据处理错误 + public const Int32 LDF_PARSER_SLAVE_NACK = (-7);//从机未响应数据 + + [DllImport("USB2XXX.dll")] + public static extern UInt64 LDF_ParserFile(int DevHandle, int LINIndex, byte isMaster, StringBuilder pLDFFileName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetProtocolVersion(UInt64 LDFHandle); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetLINSpeed(UInt64 LDFHandle); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetFrameQuantity(UInt64 LDFHandle); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetFrameName(UInt64 LDFHandle, int index, StringBuilder pFrameName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetFrameSignalQuantity(UInt64 LDFHandle, StringBuilder pFrameName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetFrameSignalName(UInt64 LDFHandle, StringBuilder pFrameName, int index, StringBuilder pSignalName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_SetSignalValue(UInt64 LDFHandle, StringBuilder pFrameName, StringBuilder pSignalName, double Value); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetSignalValue(UInt64 LDFHandle, StringBuilder pFrameName, StringBuilder pSignalName, double[] pValue); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetSignalValueStr(UInt64 LDFHandle, StringBuilder pFrameName, StringBuilder pSignalName, StringBuilder pValueStr); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_SetFrameRawValue(UInt64 LDFHandle, StringBuilder pFrameName, StringBuilder pRawData); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetFrameRawValue(UInt64 LDFHandle, StringBuilder pFrameName, StringBuilder pRawData); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetFramePublisher(UInt64 LDFHandle, StringBuilder pFrameName, StringBuilder pPublisher); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetMasterName(UInt64 LDFHandle, StringBuilder pMasterName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetSchQuantity(UInt64 LDFHandle); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetSchName(UInt64 LDFHandle, int index, StringBuilder pSchName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetSchFrameQuantity(UInt64 LDFHandle, StringBuilder pSchName); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_GetSchFrameName(UInt64 LDFHandle, StringBuilder pSchName, int index, StringBuilder pFrameName); + + /// + ///将帧数据发送到LIN总线,或者向从机读取数据,内部会根据主机名称和帧发布者自动判断是发送数据还是读取数据,发送数据校验模式是通过协议版本号自动判断的。 + // 若是发送数据给从机,需要先调用LDF_SetSignalValue函数设置该帧里面每个信号的值。 + //若是向从机读数据,调用该函数后,可以通过调用LDF_GetSignalValue函数获取读到的值。 + /// LDFHandle ldf文件解析句柄,通过LDF_ParserFile函数获取 。 + /// pFrameName 帧名称。 + /// + /// + /// + /// + /// + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_ExeFrameToBus(UInt64 LDFHandle, StringBuilder pFrameName, byte FillBitValue); + [DllImport("USB2XXX.dll")] + public static extern Int32 LDF_ExeSchToBus(UInt64 LDFHandle, StringBuilder pSchName, byte FillBitValue); + } +} diff --git a/CapMachine.Wpf/LinDrive/LinCmdData.cs b/CapMachine.Wpf/LinDrive/LinCmdData.cs new file mode 100644 index 0000000..8a37f98 --- /dev/null +++ b/CapMachine.Wpf/LinDrive/LinCmdData.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.LinDrive +{ + /// + /// Lin指令数据 + /// + public class LinCmdData + { + /// + /// 配置项名称-比如转速、功率限制等 + /// + public string? ConfigName { get; set; } + + /// + /// 消息名称/Frame名称/帧名称 + /// + public string? MsgName { get; set; } + + /// + /// 信号名称 + /// + public string? SignalName { get; set; } + + /// + /// 指令值 + /// 没有的话,则给默认值 + /// + public double SignalCmdValue { get; set; } + } +} diff --git a/CapMachine.Wpf/LinDrive/LinLdfModel.cs b/CapMachine.Wpf/LinDrive/LinLdfModel.cs new file mode 100644 index 0000000..376a766 --- /dev/null +++ b/CapMachine.Wpf/LinDrive/LinLdfModel.cs @@ -0,0 +1,93 @@ +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.LinDrive +{ + /// + /// LDF消息 + /// + public class LinLdfModel : BindableBase + { + /// + /// 消息Id + /// + public string? MsgId { get; set; } + + /// + /// 配置的中文名称:速度,转速限制,使能等常用的信息数据 + /// 但不是所有的SignalName都会配置一个Name,只是需要时才会配置名称 + /// 但是CanDbcModel集合会包括所有的SignalName名称的 + /// + public string? Name { get; set; } + + /// + /// 消息名称/Frame名称/帧名称 + /// + public string? MsgName { get; set; } + + /// + /// 信号名称 + /// + public string? SignalName { get; set; } + + /// + /// 信号描述 + /// + public string? SignalDesc { get; set; } + + /// + /// 信号单位 + /// + public string? SignalUnit { get; set; } + + + private string? _SignalRtValue = "--"; + /// + /// 信号实时值 + /// + public string? SignalRtValue + { + get { return _SignalRtValue; } + set + { + if (_SignalRtValue != value) + { + _SignalRtValue = value; + RaisePropertyChanged(); + } + } + } + + private StringBuilder _SignalRtValueSb = new StringBuilder(10); + /// + /// 信号实时值 StringBuilder + /// + public StringBuilder SignalRtValueSb + { + get { return _SignalRtValueSb; } + set + { + //if (_SignalRtValueSb != value) + //{ + SignalRtValue = value.ToString(); + _SignalRtValueSb = value; + //} + + } + } + + /// + /// 发布者 + /// + public string? Publisher { get; set; } + + /// + /// 是否主机帧 + /// + public string? IsMasterFrame { get; set; } + } +} diff --git a/CapMachine.Wpf/LinDrive/ToomossLin.cs b/CapMachine.Wpf/LinDrive/ToomossLin.cs new file mode 100644 index 0000000..13fba95 --- /dev/null +++ b/CapMachine.Wpf/LinDrive/ToomossLin.cs @@ -0,0 +1,423 @@ +using CapMachine.Wpf.CanDrive; +using CapMachine.Wpf.Services; +using Microsoft.VisualBasic; +using Prism.Ioc; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.Cryptography.Xml; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.LinDrive +{ + /// + /// Toomoss 的LIN驱动 + /// + public class ToomossLin : BindableBase + { + /// + /// 设备Handles集合 + /// + public Int32[] DevHandles { get; set; } = new Int32[20]; + /// + /// 设备Handles + /// 设备句柄,本质为设备序号的低4字节,可以通过调用USB_ScanDevice函数获得 + /// + public Int32 DevHandle { get; set; } = 0; + /// + /// Lin的Index + /// LIN通道索引号,填0或者1,若只有一个通道LIN,则填0. + /// + public Byte LINIndex { get; set; } = 0; + /// + /// Lin的连接State + /// + public bool state { get; set; } + /// + /// Lin的连接设备数量 + /// + public Int32 DevNum { get; set; } + /// + /// Lin的Dll文件的路径 + /// + public string dllFilePath { get; set; } = "USB2XXX.dll"; + + private readonly IContainerProvider ContainerProvider; + + public ToomossLin(IContainerProvider containerProvider) + { + ContainerProvider = containerProvider; + HighSpeedDataService = ContainerProvider.Resolve(); + } + + /// + /// HighSpeedDataService 实例 + /// + public HighSpeedDataService HighSpeedDataService { get; set; } + + /// + /// 开始LDF文件写入 + /// + public ObservableCollection StartLdf(string LdfPath) + { + LDF_Parser(LdfPath); + return ListLinLdfModel; + } + + /// + /// 开始Lin的驱动 + /// + public void StartLinDrive() + { + IsExistsDllFile(); + ScanDevice(); + OpenDevice(); + + } + + private bool _IsCycleRevice; + /// + /// 是否循环接收数据 + /// + public bool IsCycleRevice + { + get { return _IsCycleRevice; } + set { _IsCycleRevice = value; RaisePropertyChanged(); } + } + + private bool _IsCycleSend; + /// + /// 是否循环发送数据 + /// + public bool IsCycleSend + { + get { return _IsCycleSend; } + set { _IsCycleSend = value; RaisePropertyChanged(); } + } + + /// + /// 循环发送数据 + /// + public ushort SendCycle { get; set; } = 100; + + /// + /// 循环接受数据 + /// + public ushort ReviceCycle { get; set; } = 500; + + /// + /// CycleRevice 扫描Task + /// + private static Task CycleReviceTask { get; set; } + + /// + /// CycleSend 扫描Task + /// + private static Task CycleSendTask { get; set; } + + private bool _OpenState; + /// + /// 打开设备的状态 + /// + public bool OpenState + { + get { return _OpenState; } + set { _OpenState = value; RaisePropertyChanged(); } + } + + + private bool _LdfParserState; + /// + /// LDF解析的状态 + /// + public bool LdfParserState + { + get { return _LdfParserState; } + set { _LdfParserState = value; RaisePropertyChanged(); } + } + + + /// + /// LDFHandle + /// + public UInt64 LDFHandle { get; set; } + + /// + /// LDF消息集合 + /// 包括读取的实时值和数据 + /// + public ObservableCollection ListLinLdfModel { get; set; } = new ObservableCollection(); + + /// + /// 要发送的LIN数据 + /// + public List CmdData { get; set; } = new List(); + + /// + /// ******************【1】********************* + /// 是否存在Dll文件 + /// + /// + public bool IsExistsDllFile() + { + if (!File.Exists(dllFilePath)) + { + Console.WriteLine("请先将USB2XXX.dll和libusb-1.0.dll文件复制到exe程序文件输出目录下!"); + Console.WriteLine("dll文件在‘usb2can_lin_pwm_example/sdk/libs/windows’目录下!"); + Console.WriteLine("程序是32位的就复制‘x86’目录下文件,程序是64位的就复制‘x86_64’目录下文件!"); + return false; + } + return true; + } + + + /// + /// ******************【2】********************* + /// 扫描查找设备,并将每个设备的唯一设备号存放到数组中,后面的函数需要用到 + /// + /// + public bool ScanDevice() + { + DevNum = USB_DEVICE.USB_ScanDevice(DevHandles); + if (DevNum <= 0) + { + Console.WriteLine("No device connected!"); + return false; + } + else + { + Console.WriteLine("Have {0} device connected!", DevNum); + DevHandle = DevHandles[0];//获取第一个设备的设备号 + return true; + } + } + + /// + /// ******************【3】********************* + /// 打开设备 + /// + /// + public bool OpenDevice() + { + //打开设备 + OpenState = USB_DEVICE.USB_OpenDevice(DevHandle); + if (!OpenState) + { + Console.WriteLine("Open device error!"); + return false; + } + else + { + Console.WriteLine("Open device success!"); + return true; + } + } + + /// + /// ******************【4】********************* + /// 解析LDF信息 + /// + /// + public void LDF_Parser(string Path) + { + LDFHandle = LDFParser.LDF_ParserFile(DevHandle, LINIndex, 1, new StringBuilder(Path)); + if (LDFHandle == 0) + { + Console.WriteLine("解析LDF文件失败!"); + LdfParserState = false; + return; + } + + //读取LDF文件信息 + Console.WriteLine("ProtocolVersion = {0}", LDFParser.LDF_GetProtocolVersion(LDFHandle)); + Console.WriteLine("LINSpeed = {0}", LDFParser.LDF_GetLINSpeed(LDFHandle)); + + //读取主机名称 + StringBuilder MasterName = new StringBuilder(64); + LDFParser.LDF_GetMasterName(LDFHandle, MasterName); + Console.WriteLine("Master Name = {0}", MasterName); + + ListLinLdfModel.Clear(); + //读取信息 + int FrameLen = LDFParser.LDF_GetFrameQuantity(LDFHandle); + for (int i = 0; i < FrameLen; i++) + { + //读取帧名称和发布者 + StringBuilder FrameName = new StringBuilder(64); + string IsMasterFrame = ""; + if (LDFParser.LDF_PARSER_OK == LDFParser.LDF_GetFrameName(LDFHandle, i, FrameName)) + { + StringBuilder PublisherName = new StringBuilder(64); + LDFParser.LDF_GetFramePublisher(LDFHandle, FrameName, PublisherName); + if (MasterName.Equals(PublisherName)) + { + IsMasterFrame = "是"; + //当前帧为主机发送数据帧 + Console.WriteLine("[MW]Frame[{0}].Name={1},Publisher={2}", i, FrameName, PublisherName); + } + else + { + IsMasterFrame = "否"; + //当前帧为主机读数据帧 + Console.WriteLine("[MR]Frame[{0}].Name={1},Publisher={2}", i, FrameName, PublisherName); + } + + //读取信号信息 + int SignalNum = LDFParser.LDF_GetFrameSignalQuantity(LDFHandle, FrameName); + for (int j = 0; j < SignalNum; j++) + { + StringBuilder SignalName = new StringBuilder(64); + if (LDFParser.LDF_PARSER_OK == LDFParser.LDF_GetFrameSignalName(LDFHandle, FrameName, j, SignalName)) + { + Console.WriteLine("\tSignal[{0}].Name={1}", j, SignalName); + ListLinLdfModel.Add(new LinLdfModel() + { + MsgName = FrameName.ToString(), + Publisher = PublisherName.ToString(), + IsMasterFrame = IsMasterFrame, + SignalName = SignalName.ToString() + }); + } + } + } + } + + //解析成功 + LdfParserState = true; + } + + + /// + /// 发送LIN数据 + /// 发送一次 + /// + public void SendLinMsg(List CmdData) + { + try + { + //防止有多个不同的消息名称/帧,每个帧单独处理发送 + var GroupMsg = CmdData.GroupBy(x => x.MsgName); + foreach (var itemMsg in GroupMsg) + { + foreach (var itemSignal in itemMsg) + { + //主机写操作,发送数据给从机 + LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder(itemMsg.Key), new StringBuilder(itemSignal.SignalName), itemSignal.SignalCmdValue); + } + LDFParser.LDF_ExeFrameToBus(LDFHandle, new StringBuilder(itemMsg.Key), 1); + } + } + catch (Exception ex) + { + + } + } + + + /// + /// 读取信号值 + /// + private StringBuilder ReadValueStr = new StringBuilder(64); + + /// + /// 循环 + /// 主机读操作,读取从机返回的数据值 + /// + public void StartCycleReviceMsg() + { + CycleReviceTask = Task.Run(async () => + { + while (IsCycleRevice) + { + await Task.Delay(ReviceCycle); + try + { + //主机读操作,读取从机返回的数据值 + foreach (var item in ListLinLdfModel) + { + LDFParser.LDF_ExeFrameToBus(LDFHandle, new StringBuilder(item.MsgName), 1); + LDFParser.LDF_GetSignalValueStr(LDFHandle, new StringBuilder(item.MsgName), new StringBuilder(item.SignalName), ReadValueStr); + item.SignalRtValueSb = ReadValueStr; + } + + //StringBuilder ValueStr = new StringBuilder(64); + //LDFParser.LDF_ExeFrameToBus(LDFHandle, new StringBuilder("ID_DATA"), 1); + //LDFParser.LDF_GetSignalValueStr(LDFHandle, new StringBuilder("ID_DATA"), new StringBuilder("Supplier_ID"), ValueStr); + //Console.WriteLine("ID_DATA.Supplier_ID={0}", ValueStr); + //LDFParser.LDF_GetSignalValueStr(LDFHandle, new StringBuilder("ID_DATA"), new StringBuilder("Machine_ID"), ValueStr); + //Console.WriteLine("ID_DATA.Machine_ID={0}", ValueStr); + //LDFParser.LDF_GetSignalValueStr(LDFHandle, new StringBuilder("ID_DATA"), new StringBuilder("Chip_ID"), ValueStr); + //Console.WriteLine("ID_DATA.Chip_ID={0}", ValueStr); + + } + catch (Exception ex) + { + //LogService.Info($"时间:{DateTime.Now.ToString()}-【Meter】-{ex.Message}"); + } + } + }); + } + + + /// + /// 循环发送数据 + /// + public void StartCycleSendMsg() + { + CycleSendTask = Task.Run(async () => + { + while (IsCycleSend) + { + await Task.Delay(SendCycle); + try + { + //防止有多个不同的消息名称/帧,每个帧单独处理发送 + var GroupMsg = CmdData.GroupBy(x => x.MsgName); + foreach (var itemMsg in GroupMsg) + { + foreach (var itemSignal in itemMsg) + { + //主机写操作,发送数据给从机 + LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder(itemMsg.Key), new StringBuilder(itemSignal.SignalName), itemSignal.SignalCmdValue); + } + LDFParser.LDF_ExeFrameToBus(LDFHandle, new StringBuilder(itemMsg.Key), 1); + } + + ////主机写操作,发送数据给从机 + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("Reg_Set_Voltage"), 13.5); + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("Ramp_Time"), 3); + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("Cut_Off_Speed"), 4); + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("Exc_Limitation"), 15.6); + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("Derat_Shift"), 2); + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("MM_Request"), 2); + //LDFParser.LDF_SetSignalValue(LDFHandle, new StringBuilder("LIN_CONTROL"), new StringBuilder("Reg_Blind"), 1); + } + catch (Exception ex) + { + //LogService.Info($"时间:{DateTime.Now.ToString()}-【Meter】-{ex.Message}"); + } + } + }); + } + + + /// + /// 关闭设备 + /// + public void CloseDevice() + { + //关闭设备 + USB_DEVICE.USB_CloseDevice(DevHandle); + OpenState = false; + LdfParserState = false; + IsCycleRevice = false; + IsCycleSend = false; + } + + } +} diff --git a/CapMachine.Wpf/LinDrive/USB2LIN_EX.cs b/CapMachine.Wpf/LinDrive/USB2LIN_EX.cs new file mode 100644 index 0000000..73bea4a --- /dev/null +++ b/CapMachine.Wpf/LinDrive/USB2LIN_EX.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.LinDrive +{ + //注意:使用这些函数需要1.5.30及以上的固件才支持 + public class USB2LIN_EX + { + //定义函数返回错误代码 + public const Int32 LIN_EX_SUCCESS = (0); //函数执行成功 + public const Int32 LIN_EX_ERR_NOT_SUPPORT = (-1); //适配器不支持该函数 + public const Int32 LIN_EX_ERR_USB_WRITE_FAIL = (-2); //USB写数据失败 + public const Int32 LIN_EX_ERR_USB_READ_FAIL = (-3); //USB读数据失败 + public const Int32 LIN_EX_ERR_CMD_FAIL = (-4); //命令执行失败 + public const Int32 LIN_EX_ERR_CH_NO_INIT = (-5); //该通道未初始化 + public const Int32 LIN_EX_ERR_READ_DATA = (-6); //LIN读数据失败 + //LIN和校验模式 + public const Byte LIN_EX_CHECK_STD = 0; //标准校验,不含PID + public const Byte LIN_EX_CHECK_EXT = 1; //增强校验,包含PID + public const Byte LIN_EX_CHECK_USER = 2; //自定义校验类型,需要用户自己计算并传入Check,不进行自动校验 + public const Byte LIN_EX_CHECK_NONE = 3; //接收数据校验错误 + public const Byte LIN_EX_CHECK_ERROR = 4; //接收数据校验错误 + //定义主从模式 + public const Byte LIN_EX_MASTER = 1;//主机 + public const Byte LIN_EX_SLAVE = 0;//从机 + + public const Byte LIN_EX_MSG_TYPE_UN = 0; //未知类型 + public const Byte LIN_EX_MSG_TYPE_MW = 1; //主机向从机发送数据 + public const Byte LIN_EX_MSG_TYPE_MR = 2; //主机从从机读取数据 + public const Byte LIN_EX_MSG_TYPE_SW = 3; //从机发送数据 + public const Byte LIN_EX_MSG_TYPE_SR = 4; //从机接收数据 + public const Byte LIN_EX_MSG_TYPE_BK = 5; //只发送BREAK信号,若是反馈回来的数据,表明只检测到BREAK信号 + public const Byte LIN_EX_MSG_TYPE_SY = 6; //表明检测到了BREAK,SYNC信号 + public const Byte LIN_EX_MSG_TYPE_ID = 7; //表明检测到了BREAK,SYNC,PID信号 + public const Byte LIN_EX_MSG_TYPE_DT = 8; //表明检测到了BREAK,SYNC,PID,DATA信号 + public const Byte LIN_EX_MSG_TYPE_CK = 9; //表明检测到了BREAK,SYNC,PID,DATA,CHECK信号 + + //LIN数据帧格式定义 + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct LIN_EX_MSG + { + [MarshalAs(UnmanagedType.U4)] + public UInt32 Timestamp; //时间戳 + [MarshalAs(UnmanagedType.U1)] + public Byte MsgType; //帧类型 + [MarshalAs(UnmanagedType.U1)] + public Byte CheckType; //校验类型 + [MarshalAs(UnmanagedType.U1)] + public Byte DataLen; //LIN数据段有效数据字节数 + [MarshalAs(UnmanagedType.U1)] + public Byte Sync; //固定值,0x55 + [MarshalAs(UnmanagedType.U1)] + public Byte PID; //帧ID + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U1)] + public Byte[] Data; //数据 + [MarshalAs(UnmanagedType.U1)] + public Byte Check; //校验,只有校验数据类型为LIN_EX_CHECK_USER的时候才需要用户传入数据 + [MarshalAs(UnmanagedType.U1)] + public Byte BreakBits; //该帧的BRAK信号位数,有效值为10到26,若设置为其他值则默认为13位 + [MarshalAs(UnmanagedType.U1)] + public Byte Reserve1; + } + //初始化 + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_Init(Int32 DevHandle, Byte LINIndex, Int32 BaudRate, Byte MasterMode); + //主机模式操作函数 + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterSync(Int32 DevHandle, Byte LINIndex, LIN_EX_MSG[] pInMsg, IntPtr pOutMsg, Int32 MsgLen); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterBreak(Int32 DevHandle, Byte LINIndex); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterWrite(Int32 DevHandle, Byte LINIndex, Byte PID, Byte[] pData, Byte DataLen, Byte CheckType); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterRead(Int32 DevHandle, Byte LINIndex, Byte PID, Byte[] pData); + //从机模式操作函数 + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_SlaveSetIDMode(Int32 DevHandle, Byte LINIndex, LIN_EX_MSG[] pLINMsg, Int32 MsgLen); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_SlaveGetIDMode(Int32 DevHandle, Byte LINIndex, IntPtr pLINMsg); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_SlaveGetData(Int32 DevHandle, Byte LINIndex, IntPtr pLINMsg); + //电源控制相关函数 + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_CtrlPowerOut(Int32 DevHandle, Byte LINIndex, Byte State); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_GetVbatValue(Int32 DevHandle, Int16[] pBatValue); + //主机模式自动发送数据相关函数 + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterStartSch(Int32 DevHandle, Byte LINIndex, LIN_EX_MSG[] pLINMsg, Int32 MsgLen); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterStopSch(Int32 DevHandle, Byte LINIndex); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterGetSch(Int32 DevHandle, Byte LINIndex, IntPtr pLINMsg); + + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_MasterOfflineSch(Int32 DevHandle, Byte LINIndex, Int32 BaudRate, LIN_EX_MSG[] pLINMsg, Int32 MsgLen); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_DecodeListFile(string pFileName, Byte CheckType, Int32 BaudRate, Byte[] pReadDataList, Byte ReadDataListLen, Byte[] pCheckTypeList, Byte CheckTypeListLen); + [DllImport("USB2XXX.dll")] + public static extern Int32 LIN_EX_GetListFileMsg(Int32 MsgIndex, Int32 MsgLen, IntPtr pLINMsg); + } +} diff --git a/CapMachine.Wpf/LinDrive/USB_DEVICE.cs b/CapMachine.Wpf/LinDrive/USB_DEVICE.cs new file mode 100644 index 0000000..b7dc145 --- /dev/null +++ b/CapMachine.Wpf/LinDrive/USB_DEVICE.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.LinDrive +{ + public class USB_DEVICE + { + //定义电压输出值 + public const Byte POWER_LEVEL_NONE = 0; //不输出 + public const Byte POWER_LEVEL_1V8 = 1; //输出1.8V + public const Byte POWER_LEVEL_2V5 = 2; //输出2.5V + public const Byte POWER_LEVEL_3V3 = 3; //输出3.3V + public const Byte POWER_LEVEL_5V0 = 4; //输出5.0V + //设备信息定义 + public struct DEVICE_INFO + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public Byte[] FirmwareName; //固件名称字符串 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public Byte[] BuildDate; //固件编译时间字符串 + public UInt32 HardwareVersion;//硬件版本号 + public UInt32 FirmwareVersion;//固件版本号 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public UInt32[] SerialNumber; //适配器序列号 + public UInt32 Functions; //适配器当前具备的功能 + } + //方法定义 + /** + * @brief 初始化USB设备,并扫描设备连接数,必须调用 + * @param pDevHandle 每个设备的设备号存储地址 + * @retval 扫描到的设备数量 + */ + [DllImport("USB2XXX.dll")] + public static extern Int32 USB_ScanDevice(Int32[] pDevHandle); + /** + * @brief 打开设备,必须调用 + * @param DevHandle 设备索引号 + * @retval 打开设备的状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool USB_OpenDevice(Int32 DevHandle); + /** + * @brief 关闭设备 + * @param DevHandle 设备索引号 + * @retval 关闭设备的状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool USB_CloseDevice(Int32 DevHandle); + /** + * @brief 复位设备程序,复位后需要重新调用USB_ScanDevice,USB_OpenDevice函数 + * @param DevHandle 设备索引号 + * @retval 复位设备的状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool USB_ResetDevice(Int32 DevHandle); + + /** + * @brief 检测到USB断开连接后,重新连接设备 + * @param DevHandle 设备号 + * @retval 重连状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool USB_RetryConnect(Int32 DevHandle); + + /** + * @brief 获取设备信息,比如设备名称,固件版本号,设备序号,设备功能说明字符串等 + * @param DevHandle 设备索引号 + * @param pDevInfo 设备信息存储结构体指针 + * @param pFunctionStr 设备功能说明字符串 + * @retval 获取设备信息的状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_GetDeviceInfo(Int32 DevHandle, ref DEVICE_INFO pDevInfo, StringBuilder pFunctionStr); + /** + * @brief 擦出用户区数据 + * @param DevHandle 设备索引号 + * @retval 用户区数据擦出状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_EraseUserData(Int32 DevHandle); + + /** + * @brief 向用户区域写入用户自定义数据,写入数据之前需要调用擦出函数将数据擦出 + * @param DevHandle 设备索引号 + * @param OffsetAddr 数据写入偏移地址,起始地址为0x00,用户区总容量为0x10000字节,也就是64KBye + * @param pWriteData 用户数据缓冲区首地址 + * @param DataLen 待写入的数据字节数 + * @retval 写入用户自定义数据状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_WriteUserData(Int32 DevHandle, Int32 OffsetAddr, byte[] pWriteData, Int32 DataLen); + + /** + * @brief 从用户自定义数据区读出数据 + * @param DevHandle 设备索引号 + * @param OffsetAddr 数据写入偏移地址,起始地址为0x00,用户区总容量为0x10000字节,也就是64KBye + * @param pReadData 用户数据缓冲区首地址 + * @param DataLen 待读出的数据字节数 + * @retval 读出用户自定义数据的状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_ReadUserData(Int32 DevHandle, Int32 OffsetAddr, byte[] pReadData, Int32 DataLen); + + /** + * @brief 设置可变电压输出引脚输出电压值 + * @param DevHandle 设备索引号 + * @param PowerLevel 输出电压值 + * @retval 设置输出电压状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_SetPowerLevel(Int32 DevHandle, byte PowerLevel); + /** + * @brief 或者CAN或者LIN的时间戳原始值 + * @param DevHandle 设备索引号 + * @param pTimestamp 时间戳指针 + * @retval 获取时间戳状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_GetTimestamp(Int32 DevHandle, byte BusType, Int32[] pTimestamp); + + /** + * @brief 复位CAN/LIN时间戳,需要在初始化CAN/LIN之后调用 + * @param DevHandle 设备索引号 + * @retval 复位时间戳状态 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_ResetTimestamp(Int32 DevHandle); + /** + * @brief 获取dll编译日期 + * @param pDateTime 输出DLL编译日期字符串 + * @retval 获取dll编译日期字符串 + */ + [DllImport("USB2XXX.dll")] + public static extern bool DEV_GetDllBuildTime(StringBuilder pDateTime); + } +} diff --git a/CapMachine.Wpf/MapperProfile/LINConfigExdProfile.cs b/CapMachine.Wpf/MapperProfile/LINConfigExdProfile.cs new file mode 100644 index 0000000..18f4087 --- /dev/null +++ b/CapMachine.Wpf/MapperProfile/LINConfigExdProfile.cs @@ -0,0 +1,19 @@ +using AutoMapper; +using CapMachine.Model.CANLIN; +using CapMachine.Wpf.Dtos; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.MapperProfile +{ + public class LINConfigExdProfile : Profile + { + public LINConfigExdProfile() + { + CreateMap().ReverseMap(); + } + } +} diff --git a/CapMachine.Wpf/Models/CanLinRunStateModel.cs b/CapMachine.Wpf/Models/CanLinRunStateModel.cs new file mode 100644 index 0000000..2241dcf --- /dev/null +++ b/CapMachine.Wpf/Models/CanLinRunStateModel.cs @@ -0,0 +1,68 @@ +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static CapMachine.Wpf.Models.ComEnum; + +namespace CapMachine.Wpf.Models +{ + /// + /// CAN 和 LIN运行的状态汇总模型 + /// + public class CanLinRunStateModel:BindableBase + { + private CanLinEnum _CurSysSelectedCanLin; + /// + /// 当前系统选中使用的CanLin状态 + /// + public CanLinEnum CurSysSelectedCanLin + { + get { return _CurSysSelectedCanLin; } + set + { + _CurSysSelectedCanLin = value; + switch (value) + { + case CanLinEnum.No: + SelectedCanLinMsg = "无"; + CanLinRunState = false; + break; + case CanLinEnum.Can: + SelectedCanLinMsg = "CAN"; + CanLinRunState=true; + break; + case CanLinEnum.Lin: + SelectedCanLinMsg = "LIN"; + CanLinRunState = true; + break; + default: + break; + } + } + } + + private bool _CanLinRunState; + /// + /// CAN 和 LIN的运行状态 + /// + public bool CanLinRunState + { + get { return _CanLinRunState; } + set { _CanLinRunState = value;RaisePropertyChanged(); } + } + + + private string? _SelectedCanLinMsg; + /// + /// CANLIN 选择的字符串 + /// + public string? SelectedCanLinMsg + { + get { return _SelectedCanLinMsg; } + set { _SelectedCanLinMsg = value; RaisePropertyChanged(); } + } + + } +} diff --git a/CapMachine.Wpf/Models/ComEnum.cs b/CapMachine.Wpf/Models/ComEnum.cs index 93a348c..e075a00 100644 --- a/CapMachine.Wpf/Models/ComEnum.cs +++ b/CapMachine.Wpf/Models/ComEnum.cs @@ -54,5 +54,26 @@ namespace CapMachine.Wpf.Models /// Byte = 0, } + + /// + /// CAN和LIN的选择 + /// + public enum CanLinEnum + { + /// + /// 没选择 + /// + No = 0, + + /// + /// Can + /// + Can = 1, + + /// + /// Lin + /// + Lin = 2, + } } } diff --git a/CapMachine.Wpf/Models/SysExdInfo.cs b/CapMachine.Wpf/Models/SysExdInfo.cs new file mode 100644 index 0000000..39259c8 --- /dev/null +++ b/CapMachine.Wpf/Models/SysExdInfo.cs @@ -0,0 +1,65 @@ +using CapMachine.Wpf.Models.Tag; +using HslCommunication.Profinet.Siemens; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Models +{ + /// + /// 系统拓展信息 + /// 包括:运行时间,步骤等PLC等其他信息,不在实时数据集合中的其他信息 + /// + public class SysExdInfo:BindableBase + { + /// + /// 实例化函数 + /// + public SysExdInfo(SiemensS7Net siemensS7Net) + { + QuickTags = new List() + { + new QuickTag(siemensS7Net){ Name="RunTime-Sec",Group="时间",Unit="秒",ValueAddress="VW190",Precision=0,ValueType=ComEnum.DataType.Short,ByteLength=2}, + new QuickTag(siemensS7Net){ Name="RunTime-Min",Group="时间",Unit="分",ValueAddress="VW192",Precision=0,ValueType=ComEnum.DataType.Short,ByteLength=2}, + new QuickTag(siemensS7Net){ Name="RunTime-Hour",Group="时间",Unit="时",ValueAddress="VW194",Precision=0,ValueType=ComEnum.DataType.Short,ByteLength=2}, + }; + + + RunTimeSecQuickTag= QuickTags.Find(x => x.Name == "RunTime-Sec")!; + RunTimeMinQuickTag = QuickTags.Find(x => x.Name == "RunTime-Min")!; + RunTimeHourQuickTag = QuickTags.Find(x => x.Name == "RunTime-Hour")!; + } + + private QuickTag RunTimeSecQuickTag { get; set; } + private QuickTag RunTimeMinQuickTag { get; set; } + private QuickTag RunTimeHourQuickTag { get; set; } + + /// + /// 快速标签 + /// + public List QuickTags { get; set; } + + private string _RunTimeMsg; + /// + /// 运行时间消息 + /// + public string RunTimeMsg + { + get { return _RunTimeMsg; } + set { _RunTimeMsg = value;RaisePropertyChanged(); } + } + + /// + /// 合并运行时间 + /// + public void SumRunTime() + { + RunTimeMsg= RunTimeHourQuickTag.ValueStr + "时" + RunTimeMinQuickTag.ValueStr + "分" + RunTimeSecQuickTag.ValueStr + "秒"; + } + + + } +} diff --git a/CapMachine.Wpf/Models/Tag/QuickTag.cs b/CapMachine.Wpf/Models/Tag/QuickTag.cs new file mode 100644 index 0000000..c263533 --- /dev/null +++ b/CapMachine.Wpf/Models/Tag/QuickTag.cs @@ -0,0 +1,147 @@ +using HslCommunication; +using HslCommunication.Core; +using HslCommunication.Core.Device; +using HslCommunication.Profinet.Siemens; +using NPOI.SS.Formula.Functions; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static CapMachine.Wpf.Models.ComEnum; + +namespace CapMachine.Wpf.Models.Tag +{ + /// + /// 快速和简单的标签 + /// + public class QuickTag : BindableBase + { + public QuickTag(SiemensS7Net deviceTcpNet) + { + + SiemensS7Net = deviceTcpNet; + } + + /// + /// 驱动 + /// + public SiemensS7Net SiemensS7Net { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 标签组 + /// + public string? Group { get; set; } + + ///// + ///// 实时值 + ///// + //public abstract IRegisterValue RtValue { get; set; } + + private object? _Value; + /// + /// 实时值 + /// + public object? Value + { + get { return _Value; } + set + { + _Value = value; + ValueStr = value?.ToString(); + } + } + + private OperateResult? _OperateResultSource; + /// + /// 原始值实时值 + /// + public OperateResult? OperateResultSource + { + get { return _OperateResultSource; } + set + { + switch (ValueType) + { + case DataType.Short: + Value = SiemensS7Net.ByteTransform.TransInt16(value!.Content, 0); + break; + case DataType.Double: + Value = SiemensS7Net.ByteTransform.TransDouble(value!.Content, 0); + break; + case DataType.String: + Value = SiemensS7Net.ByteTransform.TransString(value!.Content, Encoding.ASCII); + break; + case DataType.Byte: + Value = SiemensS7Net.ByteTransform.TransByte(value!.Content, 0); + break; + default: + break; + } + _OperateResultSource = value; + } + } + + /// + /// 数据类型信息 + /// + public DataType ValueType { get; set; } + + /// + /// 值地址信息 + /// + public string? ValueAddress { get; set; } + + /// + /// 地址信息 Index + /// + public int Index { get; set; } + + /// + /// 字节长度 + /// + public ushort ByteLength { get; set; } + + /// + /// 最大值 + /// + public double MaxValue { get; set; } + + /// + /// 最小值 + /// + public double MinValue { get; set; } + + /// + /// 精度 到PLC的转换精度/分辨率 + /// + public short Precision { get; set; } + + /// + /// 小数点 展示时用的小数点 + /// + public short DecimalPoint { get; set; } + + /// + /// 单位 + /// + public string? Unit { get; set; } + + private string? _ValueStr; + /// + /// 值的字符串 + /// + public string? ValueStr + { + get { return _ValueStr; } + set { _ValueStr = value; RaisePropertyChanged(); } + } + + } +} diff --git a/CapMachine.Wpf/Services/AppStartService.cs b/CapMachine.Wpf/Services/AppStartService.cs new file mode 100644 index 0000000..47c2a4d --- /dev/null +++ b/CapMachine.Wpf/Services/AppStartService.cs @@ -0,0 +1,160 @@ +using Prism.Regions; +using Prism.Services.Dialogs; +using Syncfusion.Windows.Shared; +using Prism.Ioc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using CapMachine.Wpf.Views; + +namespace CapMachine.Wpf.Services +{ + /// + /// App启动服务 + /// 暂时不用 + /// + public class AppStartService:IAppStartService + { + /// + /// 退出 + /// + public void Exit() + { + if (System.Windows.Application.Current is IAppTaskBar appTaskBar) + appTaskBar.Dispose(); + + Environment.Exit(0); + } + + /// + /// 登录退出 + /// + public void Logout() + { + App.Current.MainWindow.Hide(); + SplashScreenInitialized(); + App.Current.MainWindow.Show(); + + if (App.Current.MainWindow.DataContext is INavigationAware navigationAware) + navigationAware.OnNavigatedTo(null); + } + + /// + /// CreateShell + /// + public void CreateShell() + { + var container = ContainerLocator.Container; + + //var userConfigurationService = container.Resolve(); + //userConfigurationService.OnAccessTokenRefresh = OnAccessTokenRefresh; + //userConfigurationService.OnSessionTimeOut = OnSessionTimeout; + + //初始的窗户 + SplashScreenInitialized(); + + #region 初版 + + //Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); + + //从容器中获取MainView的实例对象,系统运行的主窗体 + //var container = ContainerLocator.Container; + var shell = container.Resolve("MainView"); + + //加载种子数据 + //var SeekData = new SeekData(container.Resolve()); + + if (shell is Window view) + { + //更新Prism注册区域信息 + var regionManager = container.Resolve(); + RegionManager.SetRegionManager(view, regionManager); + RegionManager.UpdateRegions(); + + //给MainView的MainViewFooterContentRegion区域设置FooterView具体的信息 + regionManager.RequestNavigate("MainViewFooterContentRegion", nameof(FooterView)); + regionManager.RequestNavigate("MainViewContentRegion", nameof(MonitorView)); + + //调用首页的INavigationAware 接口做一个初始化操作 + if (view.DataContext is INavigationAware navigationAware) + { + navigationAware.OnNavigatedTo(null); + //呈现首页 + App.Current.MainWindow = view; + } + } + + //先加载服务,防止在ViewModel中使用时速度慢 + var appVersionService = ContainerLocator.Container.Resolve(); + //var appVersionService1 = ContainerLocator.Container.Resolve(); + //var appVersionService2 = ContainerLocator.Container.Resolve(); + var appVersionService12 = ContainerLocator.Container.Resolve(); + var appVersionService3 = ContainerLocator.Container.Resolve(); + var appVersionService4 = ContainerLocator.Container.Resolve(); + var appVersionService5 = ContainerLocator.Container.Resolve(); + var appVersionService6 = ContainerLocator.Container.Resolve(); + var appVersionService7 = ContainerLocator.Container.Resolve(); + var appVersionService8 = ContainerLocator.Container.Resolve(); + var appVersionService9 = ContainerLocator.Container.Resolve(); + var appVersionService10 = ContainerLocator.Container.Resolve(); + var appVersionService11 = ContainerLocator.Container.Resolve(); + var appVersionService15 = ContainerLocator.Container.Resolve(); + + + + //给当前的全局异常捕捉服务使用 + //LogService = ContainerLocator.Container.Resolve(); + //LogService.Error("ex.ToString()"); + //base.OnInitialized(); + + #endregion + + + //var shell = container.Resolve("MainView"); + //if (shell is ChromelessWindow view) + //{ + // var regionManager = container.Resolve(); + // RegionManager.SetRegionManager(view, regionManager); + // RegionManager.UpdateRegions(); + + // if (view.DataContext is INavigationAware navigationAware) + // { + // navigationAware.OnNavigatedTo(null); + // App.Current.MainWindow = (Window)shell; + // } + //} + + } + + private void SplashScreenInitialized() + { + var dialogService = ContainerLocator.Container.Resolve(); + var result = dialogService.ShowWindow("SplashScreenView").Result; + + if (result == ButtonResult.Ignore) + { + if (!Authorization()) Exit(); + } + else if (result == ButtonResult.No) Exit(); + } + + private bool Authorization() + { + var validationResult = Validation(); + if (validationResult == ButtonResult.Retry) + return Authorization(); + + return validationResult == ButtonResult.OK; + + static ButtonResult Validation() + { + var dialogService = ContainerLocator.Container.Resolve(); + return dialogService.ShowWindow("MainView").Result; + } + } + + } +} diff --git a/CapMachine.Wpf/Services/ApplicationContext.cs b/CapMachine.Wpf/Services/ApplicationContext.cs new file mode 100644 index 0000000..47760df --- /dev/null +++ b/CapMachine.Wpf/Services/ApplicationContext.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + /// + /// 应用程序上下文,语言,多租户,登录等信息 + /// + public class ApplicationContext: IApplicationContext + { + + } +} diff --git a/CapMachine.Wpf/Services/CanDriveService.cs b/CapMachine.Wpf/Services/CanDriveService.cs index a6ab03c..1ddec9b 100644 --- a/CapMachine.Wpf/Services/CanDriveService.cs +++ b/CapMachine.Wpf/Services/CanDriveService.cs @@ -249,7 +249,25 @@ namespace CapMachine.Wpf.Services return double.TryParse(ListCanDbcModel.FindFirst(a => a.Name == Name).SignalRtValue.Split(" ")[0], out double Result) == true ? Result : 0; } return 0; + } + /// + /// 速度的数据的获取 + /// 获取速度数据值 + /// 从DBC中获取Speed数据给数据中心集合 + /// + /// + /// + public double GetDbcSpeedValueBySpeedName(string Name) + { + if (!ToomossCanDrive.IsCycleRevice) return 0; + + if (ListCanDbcModel.Any(a => a.Name == Name)) + { + //double.TryParse(ListCanDbcModel.FindFirst(a => a.Name == Name).SignalRtValue, out double Result1); + return double.TryParse(ListCanDbcModel.FindFirst(a => a.Name == Name).SignalRtValue.Split(" ")[0], out double Result) == true ? Result : 0; + } + return 0; } #endregion diff --git a/CapMachine.Wpf/Services/ComActionService.cs b/CapMachine.Wpf/Services/ComActionService.cs index 0f5bf7e..21fb180 100644 --- a/CapMachine.Wpf/Services/ComActionService.cs +++ b/CapMachine.Wpf/Services/ComActionService.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace CapMachine.Wpf.Services { - + /// /// 公共操作的服务 /// 存放公共事件的服务 @@ -22,12 +22,14 @@ namespace CapMachine.Wpf.Services public DataRecordService DataRecordService { get; } public SysRunService SysRunServer { get; } public PPCService PPCService { get; } + public CanDriveService CanDriveService { get; } + public LinDriveService LinDriveService { get; } public MachineRtDataService MachineRtDataService { get; } public IDialogService DialogService { get; } public ComActionService(ConfigService configService, IEventAggregator eventAggregator, - DataRecordService dataRecordService, SysRunService sysRunService,PPCService pPCService, + DataRecordService dataRecordService, SysRunService sysRunService, PPCService pPCService, CanDriveService canDriveService, LinDriveService linDriveService, MachineRtDataService machineRtDataService, IDialogService dialogService) { ConfigService = configService; @@ -36,6 +38,8 @@ namespace CapMachine.Wpf.Services DataRecordService = dataRecordService; SysRunServer = sysRunService; PPCService = pPCService; + CanDriveService = canDriveService; + LinDriveService = linDriveService; MachineRtDataService = machineRtDataService; DialogService = dialogService; @@ -43,7 +47,6 @@ namespace CapMachine.Wpf.Services } - #region 公共弹窗操作 /// @@ -90,6 +93,42 @@ namespace CapMachine.Wpf.Services } + + + + #endregion + + + #region CAN和LIN协调 + + //CAN和LIN同一个时刻只能有一个在工作 + + /// + /// CAN是否可以工作 + /// + /// + public bool IsCanToDoWork() + { + if (LinDriveService.ToomossLinDrive.OpenState == true) + { + return false; + } + return true; + } + + /// + /// LIN是否可以工作 + /// + /// + public bool IsLINToDoWork() + { + if (CanDriveService.ToomossCanDrive.OpenState == true) + { + return false; + } + return true; + } + #endregion } } diff --git a/CapMachine.Wpf/Services/ConfigService.cs b/CapMachine.Wpf/Services/ConfigService.cs index 78003de..86baabc 100644 --- a/CapMachine.Wpf/Services/ConfigService.cs +++ b/CapMachine.Wpf/Services/ConfigService.cs @@ -1,9 +1,12 @@ using CapMachine.Model; +using CapMachine.Model.CANLIN; using CapMachine.Wpf.Dtos; +using CapMachine.Wpf.Models; using CapMachine.Wpf.PrismEvent; using Prism.Events; using Prism.Mvvm; using Prism.Services.Dialogs; +using static CapMachine.Wpf.Models.ComEnum; namespace CapMachine.Wpf.Services { @@ -18,10 +21,10 @@ namespace CapMachine.Wpf.Services CurUserDto = new UserDto(); EventAggregator = eventAggregator; - + DialogService = dialogService; } - + /// /// Csv文件锁 @@ -65,6 +68,31 @@ namespace CapMachine.Wpf.Services /// public int ChartRtDataCacheTimeSec { get; set; } = 3600_8; + /// + /// CAN和LIN的运行状态模型 + /// + public CanLinRunStateModel CanLinRunStateModel { get; set; } = new CanLinRunStateModel(); + + + private int _PlcCycleTime; + /// + /// PLC循环时间 + /// + public int PlcCycleTime + { + get { return _PlcCycleTime; } + set + { + if (value!= _PlcCycleTime) + { + _PlcCycleTime = value; + RaisePropertyChanged(); + } + + } + } + + private HistoryExp _CurExpInfo; /// @@ -109,7 +137,7 @@ namespace CapMachine.Wpf.Services public PPCService PPCService { get; } public IDialogService DialogService { get; } - + diff --git a/CapMachine.Wpf/Services/DialogExtensions.cs b/CapMachine.Wpf/Services/DialogExtensions.cs new file mode 100644 index 0000000..0af8f10 --- /dev/null +++ b/CapMachine.Wpf/Services/DialogExtensions.cs @@ -0,0 +1,75 @@ +using Prism.Services.Dialogs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + /// + /// 会话窗口扩展服务 + /// + public static class DialogExtensions + { + /// + /// 询问窗口 + /// + /// + /// 提示消息 + /// 会话ID + /// + public static async Task Question(this IHostDialogService hostDialogService, + string message, + string IdentifierName) + { + return await Question(hostDialogService, "确定", message, IdentifierName); + } + + /// + /// 询问窗口-指定标题 + /// + /// + /// 标题 + /// 提示消息 + /// 会话ID + /// + public static async Task Question(this IHostDialogService hostDialogService, + string title, + string message, + string IdentifierName) + { + DialogParameters param = new DialogParameters(); + param.Add("Title", title); + param.Add("Message", message); + + var dialogResult = await hostDialogService.ShowDialogAsync("AppViews.HostMessageBox", param, IdentifierName); + + return dialogResult.Result == ButtonResult.OK; + } + + /// + /// 询问窗口 + /// + /// + /// 标题 + /// 提示消息 + /// + public static bool Question(this IDialogService dialogService, string title, string message) + { + if (string.IsNullOrWhiteSpace(title)) + title = "确定"; + + DialogParameters parameters = new DialogParameters(); + parameters.Add("Title", title); + parameters.Add("Message", message); + + bool dialogResult = false; + dialogService.ShowDialog("AppViews.MessageBox", parameters, callback => + { + dialogResult = callback.Result == ButtonResult.OK; + }); + return dialogResult; + } + } +} diff --git a/CapMachine.Wpf/Services/DialogHostService.cs b/CapMachine.Wpf/Services/DialogHostService.cs new file mode 100644 index 0000000..58746aa --- /dev/null +++ b/CapMachine.Wpf/Services/DialogHostService.cs @@ -0,0 +1,108 @@ +using MaterialDesignThemes.Wpf; +using Prism.Common; +using Prism.Ioc; +using Prism.Mvvm; +using Prism.Services.Dialogs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace CapMachine.Wpf.Services +{ + /// + /// 对话主机服务 + /// + public class DialogHostService : DialogService, IHostDialogService + { + private readonly IContainerExtension _containerExtension; + + public DialogHostService(IContainerExtension containerExtension) : base(containerExtension) + { + _containerExtension = containerExtension; + } + + public IDialogResult ShowWindow(string name) + { + IDialogResult dialogResult = new DialogResult(ButtonResult.None); + + var content = _containerExtension.Resolve(name); + + if (!(content is Window dialogContent)) + throw new NullReferenceException("A dialog's content must be a Window"); + + if (dialogContent is Window view && view.DataContext is null && ViewModelLocator.GetAutoWireViewModel(view) is null) + ViewModelLocator.SetAutoWireViewModel(view, true); + + if (!(dialogContent.DataContext is IDialogAware viewModel)) + throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface"); + + if (dialogContent is IDialogWindow dialogWindow) + { + ConfigureDialogWindowEvents(dialogWindow, result => { dialogResult = result; }); + } + + MvvmHelpers.ViewAndViewModelAction(viewModel, d => d.OnDialogOpened(null)); + dialogContent.ShowDialog(); + return dialogResult; + } + + public async Task ShowDialogAsync(string name, IDialogParameters parameters = null, string IdentifierName = "Root") + { + var dialogContent = GetDialogContent(name, IdentifierName); + + if (!(dialogContent.DataContext is IHostDialogAware viewModel)) + throw new NullReferenceException("A dialog's ViewModel must implement the IDialogHostAware interface"); + + var eventHandler = GetDialogOpenedEventHandler(viewModel, parameters); + + var dialogResult = await DialogHost.Show(dialogContent, IdentifierName, eventHandler); + + if (dialogResult == null) + return new DialogResult(ButtonResult.Cancel); + + return (IDialogResult)dialogResult; + } + + private FrameworkElement GetDialogContent(string name, string IdentifierName = "Root") + { + var content = _containerExtension.Resolve(name); + if (!(content is FrameworkElement dialogContent)) + throw new NullReferenceException("A dialog's content must be a FrameworkElement"); + + if (dialogContent is FrameworkElement view && view.DataContext is null && ViewModelLocator.GetAutoWireViewModel(view) is null) + ViewModelLocator.SetAutoWireViewModel(view, true); + + if (!(dialogContent.DataContext is IHostDialogAware viewModel)) + throw new NullReferenceException("A dialog's ViewModel must implement the IDialogHostAware interface"); + + viewModel.IdentifierName = IdentifierName; + + return dialogContent; + } + + private DialogOpenedEventHandler GetDialogOpenedEventHandler(IHostDialogAware viewModel, + IDialogParameters parameters) + { + if (parameters == null) parameters = new DialogParameters(); + + DialogOpenedEventHandler eventHandler = + (sender, eventArgs) => + { + var _content = eventArgs.Session.Content; + if (viewModel is IHostDialogAware aware) + aware.OnDialogOpened(parameters); + eventArgs.Session.UpdateContent(_content); + }; + + return eventHandler; + } + + public void Close(string IdentifierName, DialogResult dialogResult) + { + DialogHost.Close(IdentifierName, dialogResult); + } + } +} diff --git a/CapMachine.Wpf/Services/IAppStartService.cs b/CapMachine.Wpf/Services/IAppStartService.cs new file mode 100644 index 0000000..fcdd66f --- /dev/null +++ b/CapMachine.Wpf/Services/IAppStartService.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + /// + /// App启动服务接口 + /// + public interface IAppStartService + { + void CreateShell(); + + void Logout(); + + void Exit(); + } +} diff --git a/CapMachine.Wpf/Services/IAppTaskBar.cs b/CapMachine.Wpf/Services/IAppTaskBar.cs new file mode 100644 index 0000000..385de6f --- /dev/null +++ b/CapMachine.Wpf/Services/IAppTaskBar.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + public interface IAppTaskBar + { + void Initialization(); + + void Dispose(); + } +} diff --git a/CapMachine.Wpf/Services/IApplicationContext.cs b/CapMachine.Wpf/Services/IApplicationContext.cs new file mode 100644 index 0000000..68b3935 --- /dev/null +++ b/CapMachine.Wpf/Services/IApplicationContext.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + public interface IApplicationContext + { + //[CanBeNull] + //TenantInformation CurrentTenant { get; } + + //AbpUserConfigurationDto Configuration { get; set; } + + //GetCurrentLoginInformationsOutput LoginInfo { get; } + + //void ClearLoginInfo(); + + //void SetLoginInfo(GetCurrentLoginInformationsOutput loginInfo); + + //void SetAsHost(); + + //void SetAsTenant(string tenancyName, int tenantId); + + //LanguageInfo CurrentLanguage { get; set; } + + //void Load(TenantInformation currentTenant, GetCurrentLoginInformationsOutput loginInfo); + } +} diff --git a/CapMachine.Wpf/Services/IHostDialogAware.cs b/CapMachine.Wpf/Services/IHostDialogAware.cs new file mode 100644 index 0000000..32c0459 --- /dev/null +++ b/CapMachine.Wpf/Services/IHostDialogAware.cs @@ -0,0 +1,37 @@ +using Prism.Services.Dialogs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + /// + /// 对话主机ViewModel基类 + /// + public interface IHostDialogAware + { + /// + /// DialogHost顶级节点 + /// + string IdentifierName { get; set; } + + /// + /// 页面初始化前传递参数事件 + /// + /// + /// + void OnDialogOpened(IDialogParameters parameters); + + /// + /// 确认 + /// + Task Save(); + + /// + /// 取消 + /// + void Cancel(); + } +} diff --git a/CapMachine.Wpf/Services/IHostDialogService.cs b/CapMachine.Wpf/Services/IHostDialogService.cs new file mode 100644 index 0000000..05ecc3a --- /dev/null +++ b/CapMachine.Wpf/Services/IHostDialogService.cs @@ -0,0 +1,31 @@ +using Prism.Services.Dialogs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + /// + /// 对话主机服务接口 + /// + public interface IHostDialogService : IDialogService + { + /// + /// 显示Dialog + /// + /// + /// + /// + /// + Task ShowDialogAsync( + string name, + IDialogParameters parameters = null, + string IdentifierName = "Root"); + + IDialogResult ShowWindow(string name); + + void Close(string IdentifierName, DialogResult dialogResult); + } +} diff --git a/CapMachine.Wpf/Services/LinDriveService.cs b/CapMachine.Wpf/Services/LinDriveService.cs new file mode 100644 index 0000000..08063a1 --- /dev/null +++ b/CapMachine.Wpf/Services/LinDriveService.cs @@ -0,0 +1,273 @@ +using CapMachine.Model.CANLIN; +using CapMachine.Wpf.LinDrive; +using ImTools; +using Prism.Ioc; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.Services +{ + /// + /// Lin驱动服务 + /// + public class LinDriveService : BindableBase + { + public HighSpeedDataService HighSpeedDataService { get; } + + /// + /// 实例化函数 + /// + public LinDriveService(HighSpeedDataService highSpeedDataService, IContainerProvider containerProvider) + { + ToomossLinDrive = new ToomossLin(containerProvider); + //高速数据服务 + HighSpeedDataService = highSpeedDataService; + + //ToomossLinDrive.StartLinDrive(); + } + + /// + /// 当前选中的CanLinConfigPro 程序 + /// + public CanLinConfigPro SelectedCanLinConfigPro { get; set; } + + + /// + /// 图莫斯 CAN Drive + /// ToomossLinDrive + /// + public ToomossLin ToomossLinDrive { get; set; } + + /// + /// Ldf消息集合 + /// 包括读取的实时值和数据 + /// + public ObservableCollection ListLinLdfModel { get; set; } = new ObservableCollection(); + + /// + /// 初始化CAN的配置信息 + /// + public void InitLinConfig(CanLinConfigPro selectedLinLinConfigPro) + { + //赋值配置数据 + SelectedCanLinConfigPro = selectedLinLinConfigPro; + //为DBC实时数据关联配置的名称 + foreach (var item in SelectedCanLinConfigPro.CanLinConfigContents) + { + var FindData = ListLinLdfModel.FindFirst(a => a.SignalName == item.SignalName); + if (FindData != null) + { + FindData.Name = item.Name; + } + } + } + + /// + /// 开始DBC 配置文件 加载 + /// + /// + public ObservableCollection StartLdf(string Path) + { + ListLinLdfModel = ToomossLinDrive.StartLdf(Path); + return ListLinLdfModel; + } + + + #region 程序驱动CAN + + /// + /// 转速 指令数据 实例 + /// + private LinCmdData SpeedLinCmdData { get; set; } + + /// + /// 功率限制 指令数据 实例 + /// + private LinCmdData PwLimitLinCmdData { get; set; } + + /// + /// 使能 指令数据 实例 + /// + private LinCmdData EnableLinCmdData { get; set; } + + /// + /// 要发送的CAN指令数据 + /// 在程序配置好后就确定要发送哪些数据 + /// + public List CmdData { get; set; } = new List(); + + /// + /// 增加发送的指令数据 + /// + /// + public void AddCmdData(LinCmdData SendLinCmdData) + { + //提取常用的实例数据 + switch (SendLinCmdData.ConfigName) + { + case "转速": + SpeedLinCmdData = SendLinCmdData; + break; + case "功率限制": + PwLimitLinCmdData = SendLinCmdData; + break; + case "使能": + EnableLinCmdData = SendLinCmdData; + break; + case "Anti_Sleep": + //SpeedLinCmdData = SendLinCmdData; + break; + default: + break; + } + //添加到发送数据集合 + CmdData.Add(SendLinCmdData); + } + + + /// + /// 更新速度信息 + /// 默认是启动 + /// + /// + public void UpdateSpeedCmdData(double SpeedData) + { + if (SpeedLinCmdData != null) + { + SpeedLinCmdData.SignalCmdValue = SpeedData; + } + if (EnableLinCmdData != null) + { + EnableLinCmdData.SignalCmdValue = 1; + } + } + + + /// + /// 发送消息给CAN 驱动 + /// + public void SendMsgToLinDrive(double SpeedData) + { + if (ToomossLinDrive.OpenState) + { + if (CmdData.Count > 0) + { + //更新速度信息 + UpdateSpeedCmdData(SpeedData); + + ToomossLinDrive.SendLinMsg(CmdData); + } + else + { + System.Windows.MessageBox.Show("未发现配置的数据内容", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + } + else + { + System.Windows.MessageBox.Show("未打开CAN通信,无法发送数据", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + } + + + /// + /// 循环发送数据到CAN + /// + public void CycleSendMsg() + { + if (ToomossLinDrive.OpenState) + { + if (ToomossLinDrive.IsCycleSend == false) + { + if (CmdData.Count > 0) + { + ToomossLinDrive.IsCycleSend = true; + ToomossLinDrive.CmdData = CmdData; + ToomossLinDrive.StartCycleSendMsg(); + } + else + { + System.Windows.MessageBox.Show("未发现配置的数据内容", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + } + else + { + ToomossLinDrive.IsCycleSend = false; + } + + } + } + + + + /// + ///循环接收数据 + /// + public void CycleReciveMsg() + { + if (ToomossLinDrive.OpenState) + { + if (ToomossLinDrive.IsCycleRevice == false) + { + if (ListLinLdfModel.Count > 0) + { + ToomossLinDrive.IsCycleRevice = true; + ToomossLinDrive.StartCycleReviceMsg(); + } + else + { + System.Windows.MessageBox.Show("未发现配置的数据内容", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + } + else + { + ToomossLinDrive.IsCycleRevice = false; + } + } + } + + + /// + /// 获取数据值 + /// 从DBC中获取数据给数据中心集合 + /// + /// + /// + public double GetLdfValueByName(string Name) + { + if (!ToomossLinDrive.IsCycleRevice) return 0; + + if (ListLinLdfModel.Any(a => a.Name == Name)) + { + //double.TryParse(ListLinLdfModel.FindFirst(a => a.Name == Name).SignalRtValue, out double Result1); + return double.TryParse(ListLinLdfModel.FindFirst(a => a.Name == Name).SignalRtValue.Split(" ")[0], out double Result) == true ? Result : 0; + } + return 0; + } + + /// + /// 速度的数据的获取 + /// 获取速度数据值 + /// 从DBC中获取Speed数据给数据中心集合 + /// + /// + /// + public double GetLdfSpeedValueBySpeedName(string Name) + { + if (!ToomossLinDrive.IsCycleRevice) return 0; + + if (ListLinLdfModel.Any(a => a.Name == Name)) + { + //double.TryParse(ListLinLdfModel.FindFirst(a => a.Name == Name).SignalRtValue, out double Result1); + return double.TryParse(ListLinLdfModel.FindFirst(a => a.Name == Name).SignalRtValue.Split(" ")[0], out double Result) == true ? Result : 0; + } + return 0; + } + + #endregion + } +} diff --git a/CapMachine.Wpf/Services/MachineRtDataService.cs b/CapMachine.Wpf/Services/MachineRtDataService.cs index 0653605..6c68c5e 100644 --- a/CapMachine.Wpf/Services/MachineRtDataService.cs +++ b/CapMachine.Wpf/Services/MachineRtDataService.cs @@ -36,7 +36,9 @@ namespace CapMachine.Wpf.Services /// private IEventAggregator _EventAggregator { get; set; } public AlarmService AlarmService { get; } + public ConfigService ConfigService { get; } public CanDriveService CanDriveService { get; } + public LinDriveService LinDriveService { get; } public SysRunService SysRunService { get; } /// @@ -74,10 +76,10 @@ namespace CapMachine.Wpf.Services /// private bool IsValueShow { get; set; } = true; - ///// - ///// 仪表数据集合 - ///// - //public List ListMeterRtData { get; set; } + /// + /// 系统拓展数据 + /// + public SysExdInfo CurSysExdInfo { get; set; } ///// ///// Tag数据集合 @@ -108,7 +110,8 @@ namespace CapMachine.Wpf.Services /// 实例化函数 /// /// - public MachineRtDataService(IEventAggregator eventAggregator, AlarmService alarmService, CanDriveService canDriveService, SysRunService sysRunService)//, AlarmService alarmService + public MachineRtDataService(IEventAggregator eventAggregator, AlarmService alarmService, ConfigService configService, + CanDriveService canDriveService, LinDriveService linDriveService, SysRunService sysRunService)//, AlarmService alarmService { //ConcurrentDictionary keyValuePairs = new ConcurrentDictionary(); @@ -122,7 +125,9 @@ namespace CapMachine.Wpf.Services //事件服务 _EventAggregator = eventAggregator; AlarmService = alarmService; + ConfigService = configService; CanDriveService = canDriveService; + LinDriveService = linDriveService; SysRunService = sysRunService; //秒触发一次 @@ -132,6 +137,7 @@ namespace CapMachine.Wpf.Services CycleTimer.Enabled = true; + #region 标签管理 //【测试】 @@ -637,7 +643,7 @@ namespace CapMachine.Wpf.Services Name = "通讯母线电压[V]",//名称带单位 NameNoUnit = "通讯母线电压",//无单位名称 EnName = "ComCapBusVol",//英文名称 - Group = "CAN",//分组 + Group = "CANLIN",//分组 MinValue = 0, MaxValue = 100, Unit = "V", @@ -656,7 +662,7 @@ namespace CapMachine.Wpf.Services Name = "通讯母线电流[A]",//名称带单位 NameNoUnit = "通讯母线电流",//无单位名称 EnName = "ComCapBusCur",//英文名称 - Group = "CAN",//分组 + Group = "CANLIN",//分组 MinValue = 0, MaxValue = 100, Unit = "A", @@ -675,7 +681,7 @@ namespace CapMachine.Wpf.Services Name = "通讯相电流[A]",//名称带单位 NameNoUnit = "通讯相电流",//无单位名称 EnName = "ComCapPhCur",//英文名称 - Group = "CAN",//分组 + Group = "CANLIN",//分组 MinValue = 0, MaxValue = 100, Unit = "A", @@ -694,7 +700,7 @@ namespace CapMachine.Wpf.Services Name = "通讯功率[W]",//名称带单位 NameNoUnit = "通讯功率",//无单位名称 EnName = "ComCapPw",//英文名称 - Group = "CAN",//分组 + Group = "CANLIN",//分组 MinValue = 0, MaxValue = 100, Unit = "W", @@ -713,7 +719,7 @@ namespace CapMachine.Wpf.Services Name = "通讯芯片温度[℃]",//名称带单位 NameNoUnit = "通讯芯片温度",//无单位名称 EnName = "ComCapChipTemp",//英文名称 - Group = "CAN",//分组 + Group = "CANLIN",//分组 MinValue = 0, MaxValue = 100, Unit = "℃", @@ -858,7 +864,10 @@ namespace CapMachine.Wpf.Services InitialPLCCom(); - PubRtDataStart(); + //拓展的参数信息 + CurSysExdInfo = new SysExdInfo(SiemensDrive); + + //PubRtDataStart(); } @@ -1060,6 +1069,11 @@ namespace CapMachine.Wpf.Services /// private OperateResult OperateResultAlarm { get; set; } + /// + /// 时间诊断 + /// + private Stopwatch DiagnosticsTime { get; set; } = new Stopwatch(); + /// /// PLC扫描线程 /// @@ -1071,10 +1085,11 @@ namespace CapMachine.Wpf.Services while (ThreadEnable) { - await Task.Delay(10); + //await Task.Delay(5); + await Task.CompletedTask; - //DiagnosticsTime.Reset(); - //DiagnosticsTime.Start(); + DiagnosticsTime.Reset(); + DiagnosticsTime.Start(); try { //TagInfo.RtValue.Value++; @@ -1114,13 +1129,34 @@ namespace CapMachine.Wpf.Services TagManger.GetTagInfoValueByName(itemTag.Value.Name)!.IsShow = IsValueShow; ////仿真数据 - ////TagManger.GetTagInfoValueByName(itemTag.Value.Name)!.Value = (short)Random.Next(1, 100); - ////TagManger.GetTagByName(itemTag.Value.Name).EngPvValue = (short)Random.Next(1, 100) * 1.0 / TagManger.GetTagByName(itemTag.Value.Name)!.Precision; - ////LinkState = false; + //TagManger.GetTagInfoValueByName(itemTag.Value.Name)!.Value = (short)Random.Next(1, 100); + //TagManger.GetTagByName(itemTag.Value.Name).EngPvValue = (short)Random.Next(1, 100) * 1.0 / TagManger.GetTagByName(itemTag.Value.Name)!.Precision; + //LinkState = false; //PLC 数据 if (!string.IsNullOrEmpty(itemTag.Value.PVAddress)) { + //反写CANLIN速度数据到PLC,提前写入PLC,后面会回读PV值 + if (itemTag.Value.NameNoUnit == "转速") + { + switch (ConfigService.CanLinRunStateModel.CurSysSelectedCanLin) + { + case CanLinEnum.Can: + //通信转速 Dbc中间配置名称的转速数据读取出来 给PLC + SiemensDrive.Write(itemTag.Value.PVAddress, (short)CanDriveService.GetDbcSpeedValueBySpeedName("通讯转速")); + //itemTag.Value.EngPvValue = 0; + break; + case CanLinEnum.Lin: + //通信转速 Dbc中间配置名称的转速数据读取出来 给PLC + SiemensDrive.Write(itemTag.Value.PVAddress, (short)LinDriveService.GetLdfSpeedValueBySpeedName("通讯转速")); + //itemTag.Value.EngPvValue = 0; + break; + default: + break; + } + + } + OperateResultShort = SiemensDrive.ReadInt16(itemTag.Value.PVAddress); if (OperateResultShort.IsSuccess) { @@ -1133,17 +1169,34 @@ namespace CapMachine.Wpf.Services LinkState = false; } - //CAN数据读取 //回读CAN通信的数据到集合中 - //CAN组合并且在循环接收数据中时,才读取数据 - if (itemTag.Value.Group == "CAN") + //根据CANLIN的选择,读取对应的解析实时数据更新到数据中心,这些数据相当于都是PV的实时数据 + switch (ConfigService.CanLinRunStateModel.CurSysSelectedCanLin) { - //回读CAN通信的DBC集合数据到集合中 - itemTag.Value.EngPvValue = CanDriveService.GetDbcValueByName(itemTag.Value.NameNoUnit); + case CanLinEnum.Can: + //CAN数据读取 //回读CAN通信的数据到集合中 + //CAN组合并且在循环接收数据中时,才读取数据 + if (itemTag.Value.Group == "CANLIN") + { + //回读CAN通信的DBC集合数据到集合中 + itemTag.Value.EngPvValue = CanDriveService.GetDbcValueByName(itemTag.Value.NameNoUnit); + } + break; + case CanLinEnum.Lin: + //LIN数据读取 //回读LIN通信的数据到集合中 + //LIN组合并且在循环接收数据中时,才读取数据 + if (itemTag.Value.Group == "CANLIN") + { + //回读LIN通信的DBC集合数据到集合中 + itemTag.Value.EngPvValue = LinDriveService.GetLdfValueByName(itemTag.Value.NameNoUnit); + } + break; + default: + break; } } else //地址为空,PLC驱动不读取数据 { - + } if (!string.IsNullOrEmpty(itemTag.Value.SVAddress)) @@ -1207,7 +1260,6 @@ namespace CapMachine.Wpf.Services } } - //循环读取手自动切换 foreach (var item in ListHandSwitchData) { @@ -1218,7 +1270,12 @@ namespace CapMachine.Wpf.Services } } - + //拓展信息的展示 + foreach (var itemQuickTag in CurSysExdInfo.QuickTags) + { + itemQuickTag.OperateResultSource = SiemensDrive.Read(itemQuickTag.ValueAddress, itemQuickTag.ByteLength); + } + CurSysExdInfo.SumRunTime(); } catch (Exception ex) @@ -1227,9 +1284,9 @@ namespace CapMachine.Wpf.Services } - - //DiagnosticsTime.Stop(); - //ScanRtTimeinfo = $"电表:{DiagnosticsTime.Elapsed.TotalMilliseconds.ToString()}"; + DiagnosticsTime.Stop(); + ConfigService.PlcCycleTime = (int)DiagnosticsTime.Elapsed.TotalMilliseconds; + //Console.WriteLine($"扫描时间:{DiagnosticsTime.Elapsed.TotalMilliseconds.ToString()}"); } }); } diff --git a/CapMachine.Wpf/Services/NavigationMenuService.cs b/CapMachine.Wpf/Services/NavigationMenuService.cs index 60c86cd..db0c4eb 100644 --- a/CapMachine.Wpf/Services/NavigationMenuService.cs +++ b/CapMachine.Wpf/Services/NavigationMenuService.cs @@ -73,6 +73,7 @@ namespace CapMachine.Wpf.Services //})); MenuItems.Add(new NavigationItem("", "工艺过程", "MonitorView")); MenuItems.Add(new NavigationItem("", "CAN配置", "CANConfigView")); + MenuItems.Add(new NavigationItem("", "LIN配置", "LINConfigView")); MenuItems.Add(new NavigationItem("", "工艺参数", "ProConfigView")); MenuItems.Add(new NavigationItem("", "工艺曲线", "RealTimeChartView")); MenuItems.Add(new NavigationItem("", "动作日志", "ActionLogView")); diff --git a/CapMachine.Wpf/ViewModels/ActionLogViewModel.cs b/CapMachine.Wpf/ViewModels/ActionLogViewModel.cs index e85168b..3e84ca2 100644 --- a/CapMachine.Wpf/ViewModels/ActionLogViewModel.cs +++ b/CapMachine.Wpf/ViewModels/ActionLogViewModel.cs @@ -42,7 +42,7 @@ namespace CapMachine.Wpf.ViewModels CategoryComboBoxList = new List() { new ComboBoxModel(){Key="0",Text="系统日志" }, - new ComboBoxModel(){Key="1",Text="程序步骤" }, + //new ComboBoxModel(){Key="1",Text="程序步骤" }, new ComboBoxModel(){Key="2",Text="历史报警" }, }; } @@ -210,12 +210,14 @@ namespace CapMachine.Wpf.ViewModels //多条件查询 if (!string.IsNullOrEmpty(SearchStartDate)) { - MulConHistoryAlarmQueryable = MulConHistoryAlarmQueryable.Where(t => t.CreateTime.Date >= Convert.ToDateTime(SearchStartDate)); + var Start = DateTime.Parse(SearchStartDate); + MulConHistoryAlarmQueryable = MulConHistoryAlarmQueryable.Where(t => t.CreateTime.Date >= Convert.ToDateTime(Start)); } //多条件查询 if (!string.IsNullOrEmpty(SearchEndDate)) { - MulConHistoryAlarmQueryable = MulConHistoryAlarmQueryable.Where(t => t.CreateTime.Date < Convert.ToDateTime(SearchEndDate).AddDays(1)); + var End = DateTime.Parse(SearchEndDate); + MulConHistoryAlarmQueryable = MulConHistoryAlarmQueryable.Where(t => t.CreateTime.Date < Convert.ToDateTime(End).AddDays(1)); } var ListHistoryAlarmDpI = MulConHistoryAlarmQueryable.OrderByDescending(a => a.CreateTime).ToList();//.Where(a => a.CreateTime >= DateTime.Now); @@ -228,12 +230,14 @@ namespace CapMachine.Wpf.ViewModels //多条件查询 if (!string.IsNullOrEmpty(SearchStartDate)) { - MulConActionLogQueryable = MulConActionLogQueryable.Where(t => t.CreateTime.Date >= Convert.ToDateTime(SearchStartDate)); + var Start = DateTime.Parse(SearchStartDate); + MulConActionLogQueryable = MulConActionLogQueryable.Where(t => t.CreateTime.Date >= Convert.ToDateTime(Start)); } //多条件查询 if (!string.IsNullOrEmpty(SearchEndDate)) { - MulConActionLogQueryable = MulConActionLogQueryable.Where(t => t.CreateTime.Date < Convert.ToDateTime(SearchEndDate).AddDays(1)); + var End = DateTime.Parse(SearchEndDate); + MulConActionLogQueryable = MulConActionLogQueryable.Where(t => t.CreateTime.Date < Convert.ToDateTime(End).AddDays(1)); } var ListActionLogDpI = MulConActionLogQueryable.OrderByDescending(a => a.CreateTime).ToList();//.Where(a => a.CreateTime >= DateTime.Now); ListModelDto = new ObservableCollection(Mapper.Map>(ListActionLogDpI)); diff --git a/CapMachine.Wpf/ViewModels/CANConfigViewModel.cs b/CapMachine.Wpf/ViewModels/CANConfigViewModel.cs index 3eb0359..01da499 100644 --- a/CapMachine.Wpf/ViewModels/CANConfigViewModel.cs +++ b/CapMachine.Wpf/ViewModels/CANConfigViewModel.cs @@ -25,6 +25,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; +using static CapMachine.Wpf.Models.ComEnum; namespace CapMachine.Wpf.ViewModels { @@ -35,6 +36,7 @@ namespace CapMachine.Wpf.ViewModels { public CANConfigViewModel(IDialogService dialogService, IFreeSql freeSql, IEventAggregator eventAggregator, IRegionManager regionManager, SysRunService sysRunService, + ComActionService actionService, ConfigService configService, CanDriveService canDriveService, IMapper mapper, MachineRtDataService machineRtDataService) { @@ -43,6 +45,7 @@ namespace CapMachine.Wpf.ViewModels EventAggregator = eventAggregator; RegionManager = regionManager; SysRunService = sysRunService; + ComActionService = actionService; ConfigService = configService; CanDriveService = canDriveService; Mapper = mapper; @@ -80,6 +83,7 @@ namespace CapMachine.Wpf.ViewModels public IEventAggregator EventAggregator { get; } public IRegionManager RegionManager { get; } public SysRunService SysRunService { get; } + public ComActionService ComActionService { get; } public ConfigService ConfigService { get; } public CanDriveService CanDriveService { get; } public IMapper Mapper { get; } @@ -329,23 +333,42 @@ namespace CapMachine.Wpf.ViewModels } break; case "Active": - if (SelectCanLinConfigPro != null) + + //激活到取消的状态的判断 + if (IsCanConfigProActive==true) { //控件的激活 IsCanConfigProActive = !IsCanConfigProActive; //控件的激活配置信息 IsCANConfigDatagridActive = !IsCanConfigProActive; - //当前使用的CAN 配置信息 - CanDriveService.InitCanConfig(SelectCanLinConfigPro); + return; + } + + if ((CanDriveService.ToomossCanDrive.OpenState == true && CanDriveService.ToomossCanDrive.DbcParserState == true)) + { + if (SelectCanLinConfigPro != null) + { + //控件的激活 + IsCanConfigProActive = !IsCanConfigProActive; + //控件的激活配置信息 + IsCANConfigDatagridActive = !IsCanConfigProActive; + + //当前使用的CAN 配置信息 + CanDriveService.InitCanConfig(SelectCanLinConfigPro); + + InitLoadCanConfigPro(); + } + else + { + System.Windows.MessageBox.Show("选中后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } - InitLoadCanConfigPro(); } else { - System.Windows.MessageBox.Show("选中后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("请确保CAN连接打开和Dbc解析成功后再激活", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); } - break; default: break; @@ -579,7 +602,7 @@ namespace CapMachine.Wpf.ViewModels } else { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); } @@ -754,10 +777,17 @@ namespace CapMachine.Wpf.ViewModels switch (Par) { case "Open": + if (ComActionService.IsCanToDoWork()==false) + { + System.Windows.MessageBox.Show("请关闭LIN连接后才能开启CAN,同一个时刻只能有一个通信驱动压缩机", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + return; + } if (SelectCanLinConfigPro != null && SelectedCANConfigExdDto != null) { //打开连接 CanDriveService.ToomossCanDrive.StartCanDrive(); + //系统使用了CAN + ConfigService.CanLinRunStateModel.CurSysSelectedCanLin = CanLinEnum.Can; //CAN DBC配置 有DBC配置的话,则直接加载DBC信息 if (!string.IsNullOrEmpty(SelectCanLinConfigPro.CANConfigExd.DbcPath)) { @@ -767,7 +797,7 @@ namespace CapMachine.Wpf.ViewModels } else { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); } break; @@ -776,11 +806,12 @@ namespace CapMachine.Wpf.ViewModels { CanDriveService.ToomossCanDrive.CloseDevice(); - + //系统取消使用了CAN + ConfigService.CanLinRunStateModel.CurSysSelectedCanLin = CanLinEnum.No; } else { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); } break; @@ -802,7 +833,7 @@ namespace CapMachine.Wpf.ViewModels } else { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); } break; @@ -837,7 +868,7 @@ namespace CapMachine.Wpf.ViewModels } else { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); } break; @@ -1004,7 +1035,7 @@ namespace CapMachine.Wpf.ViewModels { if (SelectCanLinConfigPro == null) { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); return; } @@ -1139,7 +1170,7 @@ namespace CapMachine.Wpf.ViewModels { if (SelectCanLinConfigPro == null) { - System.Windows.MessageBox.Show("新建CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + System.Windows.MessageBox.Show("选中CAN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); return; } diff --git a/CapMachine.Wpf/ViewModels/DialogCanLinConfigCreateViewModel.cs b/CapMachine.Wpf/ViewModels/DialogCanLinConfigCreateViewModel.cs index 12a847e..8c6aac2 100644 --- a/CapMachine.Wpf/ViewModels/DialogCanLinConfigCreateViewModel.cs +++ b/CapMachine.Wpf/ViewModels/DialogCanLinConfigCreateViewModel.cs @@ -16,7 +16,7 @@ namespace CapMachine.Wpf.ViewModels { public DialogCanLinConfigCreateViewModel() { - + this.Title = "Can/LIN程序名称配置"; } private string name; diff --git a/CapMachine.Wpf/ViewModels/HostDialogViewModel.cs b/CapMachine.Wpf/ViewModels/HostDialogViewModel.cs new file mode 100644 index 0000000..d3a6c02 --- /dev/null +++ b/CapMachine.Wpf/ViewModels/HostDialogViewModel.cs @@ -0,0 +1,60 @@ +using CapMachine.Wpf.Services; +using Prism.Commands; +using Prism.Mvvm; +using Prism.Services.Dialogs; +using Prism.Ioc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CapMachine.Wpf.ViewModels +{ + public abstract class HostDialogViewModel : BindableBase, IHostDialogAware + { + public string Title { get; set; } + + public string IdentifierName { get; set; } + + public DelegateCommand SaveCommand { get; private set; } + + public DelegateCommand CancelCommand { get; private set; } + + private IHostDialogService dialogService; + + public HostDialogViewModel() + { + SaveCommand = new DelegateCommand(async () => await Save()); + CancelCommand = new DelegateCommand(Cancel); + + dialogService = ContainerLocator.Container.Resolve(); + } + + public virtual void Cancel() + { + dialogService.Close(IdentifierName, new DialogResult(ButtonResult.No)); + } + + public virtual async Task Save() + { + dialogService.Close(IdentifierName, new DialogResult(ButtonResult.OK)); + await Task.CompletedTask; + } + + protected virtual void Save(object value) + { + DialogParameters param = new DialogParameters(); + param.Add("Value", value); + + dialogService.Close(IdentifierName, new DialogResult(ButtonResult.OK, param)); + } + + protected virtual void Save(DialogParameters param) + { + dialogService.Close(IdentifierName, new DialogResult(ButtonResult.OK, param)); + } + + public abstract void OnDialogOpened(IDialogParameters parameters); + } +} diff --git a/CapMachine.Wpf/ViewModels/LinConfigViewModel.cs b/CapMachine.Wpf/ViewModels/LinConfigViewModel.cs new file mode 100644 index 0000000..c54ff3b --- /dev/null +++ b/CapMachine.Wpf/ViewModels/LinConfigViewModel.cs @@ -0,0 +1,1224 @@ +using AutoMapper; +using CapMachine.Core; +using CapMachine.Model.CANLIN; +using CapMachine.Wpf.CanDrive; +using CapMachine.Wpf.Dtos; +using CapMachine.Wpf.LinDrive; +using CapMachine.Wpf.Services; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using Prism.Services.Dialogs; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using Microsoft.Win32; +using static CapMachine.Wpf.Models.ComEnum; + +namespace CapMachine.Wpf.ViewModels +{ + public class LinConfigViewModel : NavigationViewModel + { + /// + /// 实例化函数 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public LinConfigViewModel(IDialogService dialogService, IFreeSql freeSql, + IEventAggregator eventAggregator, IRegionManager regionManager, SysRunService sysRunService, + ConfigService configService, LinDriveService linDriveService,ComActionService comActionService, + IMapper mapper, MachineRtDataService machineRtDataService) + { + //LogService = logService; + FreeSql = freeSql; + EventAggregator = eventAggregator; + RegionManager = regionManager; + SysRunService = sysRunService; + ConfigService = configService; + LinDriveService = linDriveService; + ComActionService = comActionService; + Mapper = mapper; + this.MachineRtDataService = machineRtDataService; + + //MachineDataService = machineDataService; + DialogService = dialogService; + + WriteNameCbxItems = new ObservableCollection() + { + new CbxItems(){ Key="转速",Text="转速"}, + new CbxItems(){ Key="功率限制",Text="功率限制"}, + new CbxItems(){ Key="使能",Text="使能"}, + new CbxItems(){ Key="Anti_Sleep",Text="Anti_Sleep"}, + }; + + ReadNameCbxItems = new ObservableCollection() + { + new CbxItems(){ Key="通讯转速",Text="通讯转速"}, + new CbxItems(){ Key="通讯母线电压",Text="通讯母线电压"}, + new CbxItems(){ Key="通讯母线电流",Text="通讯母线电流"}, + new CbxItems(){ Key="通讯相电流",Text="通讯相电流"}, + new CbxItems(){ Key="通讯功率",Text="通讯功率"}, + new CbxItems(){ Key="通讯芯片温度",Text="通讯芯片温度"}, + }; + InitLoadLinConfigPro(); + + } + + + /// + /// FreeSQL 实例函数 + /// + public IFreeSql FreeSql { get; } + public IEventAggregator EventAggregator { get; } + public IRegionManager RegionManager { get; } + public SysRunService SysRunService { get; } + public ConfigService ConfigService { get; } + public LinDriveService LinDriveService { get; } + public ComActionService ComActionService { get; } + public IMapper Mapper { get; } + private MachineRtDataService MachineRtDataService { get; } + + /// + /// 弹窗服务 + /// + public IDialogService DialogService { get; } + + + + #region LinConfigPro + + /// + /// 初始化j加载执行方法 + /// + private void InitLoadLinConfigPro() + { + //LIN配置集合数据 + canLinConfigPros = FreeSql.Select().Where(a => a.CANLINInfo == CANLIN.LIN) + .Include(a => a.LINConfigExd) + .IncludeMany(a => a.CanLinConfigContents) + .ToList(); + + ListCanLinConfigPro = new ObservableCollection(canLinConfigPros); + if (SelectCanLinConfigPro != null) + { + SelectCanLinConfigPro = canLinConfigPros.Where(a => a.Id == SelectCanLinConfigPro.Id).FirstOrDefault()!; + + SelectedLINConfigExdDto = Mapper.Map(SelectCanLinConfigPro!.LINConfigExd); + + var WirteData = SelectCanLinConfigPro.CanLinConfigContents!.Where(a => a.RWInfo == RW.Write).ToList(); + if (WirteData != null && WirteData.Count > 0) + { + ListWriteCanLinRWConfigDto = new ObservableCollection(Mapper.Map>(WirteData)); + + //加载把当前的配置信息给指令 + LinDriveService.CmdData.Clear(); + foreach (var item in WirteData) + { + LinDriveService.AddCmdData(new LinCmdData() + { + ConfigName = item.Name, + MsgName = item.MsgFrameName, + SignalName = item.SignalName, + SignalCmdValue = double.TryParse(item.DefautValue, out double result) == true ? result : 0, + }); + //LinDriveService.CmdData.Add(new LinCmdData() + //{ + // ConfigName = item.Name, + // MsgName = item.MsgFrameName, + // SignalName = item.SignalName, + // SignalCmdValue = double.TryParse(item.DefautValue, out double result) == true ? result : 0, + //}); + } + + } + var ReadData = SelectCanLinConfigPro.CanLinConfigContents!.Where(a => a.RWInfo == RW.Read).ToList(); + if (ReadData != null && ReadData.Count > 0) + { + ListReadCanLinRWConfigDto = new ObservableCollection(Mapper.Map>(ReadData)); + + + } + } + + } + + private bool _IsLinConfigProActive = false; + /// + /// LIN 配置是否被激活 + /// + public bool IsLinConfigProActive + { + get { return _IsLinConfigProActive; } + set { _IsLinConfigProActive = value; RaisePropertyChanged(); } + } + + private bool _IsLINConfigDatagridActive = true; + /// + /// LINConfigDatagrid是否被触控 + /// 关联IsLinConfigProActive 取反 + /// + public bool IsLINConfigDatagridActive + { + get { return _IsLINConfigDatagridActive; } + set { _IsLINConfigDatagridActive = value; RaisePropertyChanged(); } + } + + private string _SelectCanLinConfigProConfigName; + /// + /// 选中的 CanLinConfigPro 名称 + /// + public string SelectCanLinConfigProConfigName + { + get { return _SelectCanLinConfigProConfigName; } + set { _SelectCanLinConfigProConfigName = value; RaisePropertyChanged(); } + } + + + private DelegateCommand _CanLinConfigPromdCmd; + /// + /// LINConfigPro操作的指令 + /// + public DelegateCommand CanLinConfigPromdCmd + { + set + { + _CanLinConfigPromdCmd = value; + } + get + { + if (_CanLinConfigPromdCmd == null) + { + _CanLinConfigPromdCmd = new DelegateCommand((Par) => CanLinConfigPromdCmdMethod(Par)); + } + return _CanLinConfigPromdCmd; + } + } + /// + /// LinConfigPro操作的指令方法 + /// + /// + private void CanLinConfigPromdCmdMethod(string Par) + { + switch (Par) + { + case "Add": + //弹窗 + DialogService.ShowDialog("DialogCanLinConfigCreateView", new DialogParameters() { { "Name", "" } }, (par) => + { + if (par.Result == ButtonResult.OK) + { + //程序名称 + var ReturnValue = par.Parameters.GetValue("Name"); + + //加载默认的数据 LINConfigExd + var InsertLINConfigExd = FreeSql.Insert(new LINConfigExd() + { + BaudRate = 250, + LdfPath = "请配置LDF路径", + Cycle = 100, + }).ExecuteInserted(); + + //返回数据,刷新Chart + var InsertData = FreeSql.Insert(new CanLinConfigPro() + { + ConfigName = ReturnValue, + CANLINInfo = CANLIN.LIN, + LINConfigExdId = InsertLINConfigExd.FirstOrDefault()!.Id + }).ExecuteInserted(); + if (InsertData != null) + { + //加载默认的数据 CanLinRWConfig + FreeSql.Insert(new CanLinRWConfig() + { + SignalName = "Speed", + DefautValue = "0", + Name = "转速", + RWInfo = RW.Write, + CanLinConfigProId = InsertData.FirstOrDefault().Id + }).ExecuteInserted(); + + FreeSql.Insert(new CanLinRWConfig() + { + SignalName = "Vol", + DefautValue = "0", + Name = "电压", + RWInfo = RW.Read, + CanLinConfigProId = InsertData.FirstOrDefault().Id + + }).ExecuteInserted(); + } + + InitLoadLinConfigPro(); + + SelectCanLinConfigPro = canLinConfigPros!.Find(a => a.Id == InsertData.FirstOrDefault()!.Id); + } + else if (par.Result == ButtonResult.Cancel) + { + //取消 + + } + + }); + + break; + case "Edit": + if (SelectCanLinConfigPro != null) + { + //弹窗 + DialogService.ShowDialog("DialogCanLinConfigCreateView", new DialogParameters() { { "Name", SelectCanLinConfigPro.ConfigName } }, (par) => + { + if (par.Result == ButtonResult.OK) + { + //程序名称 + var ReturnValue = par.Parameters.GetValue("Name"); + + FreeSql.Update() + .Set(a => a.ConfigName, ReturnValue) + .Where(a => a.Id == SelectCanLinConfigPro.Id) + .ExecuteAffrows(); + + InitLoadLinConfigPro(); + + SelectCanLinConfigPro = null; + } + else if (par.Result == ButtonResult.Cancel) + { + //取消 + + } + + }); + } + else + { + System.Windows.MessageBox.Show("选中后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + break; + + case "Save": + + case "Delete": + if (SelectCanLinConfigPro != null) + { + var repo = FreeSql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; //关键设置 + + var DeleteData = repo.Select + .Include(a => a.LINConfigExd) + .IncludeMany(a => a.CanLinConfigContents) + .Where(a => a.Id == SelectCanLinConfigPro.Id) + .ToList(); + + repo.Delete(DeleteData); + foreach (var item in DeleteData) + { + FreeSql.Delete(item.LINConfigExdId).ExecuteAffrows(); + } + InitLoadLinConfigPro(); + } + else + { + System.Windows.MessageBox.Show("选中后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + break; + case "Active": + + //激活到取消的状态的判断 + if (IsLinConfigProActive == true) + { + //控件的激活 + IsLinConfigProActive = !IsLinConfigProActive; + //控件的激活配置信息 + IsLINConfigDatagridActive = !IsLinConfigProActive; + + return; + } + + if (LinDriveService.ToomossLinDrive.OpenState == true && LinDriveService.ToomossLinDrive.LdfParserState == true) + { + if (SelectCanLinConfigPro != null) + { + //控件的激活 + IsLinConfigProActive = !IsLinConfigProActive; + //控件的激活配置信息 + IsLINConfigDatagridActive = !IsLinConfigProActive; + + //当前使用的LIN配置信息 + LinDriveService.InitLinConfig(SelectCanLinConfigPro); + + InitLoadLinConfigPro(); + } + else + { + System.Windows.MessageBox.Show("选中后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + } + else + { + System.Windows.MessageBox.Show("请确保LIN连接打开和LDF解析成功后再激活", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + break; + default: + break; + } + } + + /// + /// LIN List集合信息 + /// + private List canLinConfigPros = new List(); + + private ObservableCollection _ListCanLinConfigPro; + /// + /// LIN 配置程序集合 ObservableCollection + /// + public ObservableCollection ListCanLinConfigPro + { + get { return _ListCanLinConfigPro; } + set { _ListCanLinConfigPro = value; RaisePropertyChanged(); } + } + + /// + /// 选中的CanLinConfigPro + /// + public CanLinConfigPro SelectCanLinConfigPro { get; set; } + + private DelegateCommand _LinConfigProGridSelectionChangedCmd; + /// + /// LIN 配置程序 选中行数据命令 + /// + public DelegateCommand LinConfigProGridSelectionChangedCmd + { + set + { + _LinConfigProGridSelectionChangedCmd = value; + } + get + { + if (_LinConfigProGridSelectionChangedCmd == null) + { + _LinConfigProGridSelectionChangedCmd = new DelegateCommand((par) => LinConfigProGridSelectionChangedCmdMethod(par)); + } + return _LinConfigProGridSelectionChangedCmd; + } + } + private void LinConfigProGridSelectionChangedCmdMethod(object par) + { + if (par == null) + { + return; + } + if (par is SelectionChangedEventArgs) + { + return; + } + + if (par is CanLinConfigPro) + { + SelectCanLinConfigPro = par as CanLinConfigPro; + + //LINConfigExdDto 数据 + SelectedLINConfigExdDto = Mapper.Map(SelectCanLinConfigPro!.LINConfigExd); + + var WirteData = SelectCanLinConfigPro.CanLinConfigContents!.Where(a => a.RWInfo == RW.Write).ToList(); + if (WirteData != null && WirteData.Count > 0) + { + ListWriteCanLinRWConfigDto = new ObservableCollection(Mapper.Map>(WirteData)); + + //加载把当前的配置信息给指令 + LinDriveService.CmdData.Clear(); + foreach (var item in WirteData) + { + LinDriveService.AddCmdData(new LinCmdData() + { + ConfigName = item.Name, + MsgName = item.MsgFrameName, + SignalName = item.SignalName, + SignalCmdValue = double.TryParse(item.DefautValue, out double result) == true ? result : 0, + }); + + //LinDriveService.CmdData.Add(new LinCmdData() + //{ + // ConfigName = item.Name, + // MsgName = item.MsgFrameName, + // SignalName = item.SignalName, + // SignalCmdValue = double.TryParse(item.DefautValue, out double result) == true ? result : 0, + //}); + } + + } + var ReadData = SelectCanLinConfigPro.CanLinConfigContents!.Where(a => a.RWInfo == RW.Read).ToList(); + if (ReadData != null && ReadData.Count > 0) + { + ListReadCanLinRWConfigDto = new ObservableCollection(Mapper.Map>(ReadData)); + } + + SelectCanLinConfigProConfigName = SelectCanLinConfigPro.ConfigName; + return; + } + //先判断是否是正确的集合数据,防止DataGrid的数据源刷新导致的触发事件 + var Selecteddata = (par as SelectionChangedEventArgs)!.AddedItems[0] as CanLinConfigPro; + + if (Selecteddata != null) + { + SelectCanLinConfigPro = Selecteddata; + + SelectCanLinConfigProConfigName = SelectCanLinConfigPro.ConfigName; + + } + + + } + + + private DelegateCommand _LinConfigProGridPreviewMouseLeftButtonDownCmd; + /// + /// LIN 配置程序 选中行之前的数据命令 Preview + /// 防止LIN 打开后没有关闭就开始切换LIN 配置程序信息 + /// 要关闭后再切换 + /// + public DelegateCommand LinConfigProGridPreviewMouseLeftButtonDownCmd + { + set + { + _LinConfigProGridPreviewMouseLeftButtonDownCmd = value; + } + get + { + if (_LinConfigProGridPreviewMouseLeftButtonDownCmd == null) + { + _LinConfigProGridPreviewMouseLeftButtonDownCmd = new DelegateCommand((par) => LinConfigProGridPreviewMouseLeftButtonDownCmdMethod(par)); + } + return _LinConfigProGridPreviewMouseLeftButtonDownCmd; + } + } + /// + /// 防止LIN 打开后没有关闭就开始切换LIN 配置程序信息 + /// 要关闭后再切换 + /// + /// + private void LinConfigProGridPreviewMouseLeftButtonDownCmdMethod(object par) + { + if (par == null) + { + return; + } + if (par is System.Windows.Input.MouseButtonEventArgs) + { + var handler = par as System.Windows.Input.MouseButtonEventArgs; + + if (!LinDriveService.ToomossLinDrive.OpenState) + { + // 防止默认的行选择行为发生 + handler.Handled = false; + } + else + { + System.Windows.MessageBox.Show("关闭LIN连接后再点击切换LIN配置", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + handler.Handled = true; + } + } + } + + + #endregion + + #region Ldf操作 + + private ObservableCollection _ListLinLdfModel; + /// + /// Ldf消息集合 + /// + public ObservableCollection ListLinLdfModel + { + get { return _ListLinLdfModel; } + set { _ListLinLdfModel = value; RaisePropertyChanged(); } + } + + //private string _LdfFilePath; + ///// + ///// Ldf文件路径 + ///// + //public string LdfFilePath + //{ + // get { return _LdfFilePath; } + // set { _LdfFilePath = value; RaisePropertyChanged(); } + //} + + + private DelegateCommand _LoadLdfCmd; + /// + /// 下载Ldf文件指令 + /// + public DelegateCommand LoadLdfCmd + { + set + { + _LoadLdfCmd = value; + } + get + { + if (_LoadLdfCmd == null) + { + _LoadLdfCmd = new DelegateCommand(() => LoadLdfCmdMethod()); + } + return _LoadLdfCmd; + } + } + /// + /// 加载Ldf文件信息 + /// + private void LoadLdfCmdMethod() + { + //LdfFilePath + try + { + //var dd = ListQuickMeterStepDto; + + if (SelectCanLinConfigPro != null && SelectedLINConfigExdDto != null) + { + OpenFileDialog OpenFileDialogInfo = new OpenFileDialog(); //new一个方法 + OpenFileDialogInfo.Filter = "(*.ldf;*.ldf)|*.ldf;*.ldf|all|*.*"; //删选、设定文件显示类型 + OpenFileDialogInfo.CheckFileExists = true; + OpenFileDialogInfo.CheckPathExists = true; + + OpenFileDialogInfo.ShowDialog(); //显示打开文件的窗口 + string fileName = OpenFileDialogInfo.FileName; //获得选择的文件路径 + + SelectedLINConfigExdDto.LdfPath = fileName; + } + else + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + //System.Diagnostics.Process.Start(fileName);//打开指定路径下的文件 + } + catch (Exception ex) + { + System.Windows.MessageBox.Show("可能未选择信息", "提示", System.Windows.MessageBoxButton.OKCancel, System.Windows.MessageBoxImage.Hand); + } + } + + + /// + /// 选中的LinLdfModel + /// + public LinLdfModel SelectedLinLdfModel { get; set; } + + private DelegateCommand _LdfGridSelectionChangedCmd; + /// + /// Ldf选中行数据命令 + /// + public DelegateCommand LdfGridSelectionChangedCmd + { + set + { + _LdfGridSelectionChangedCmd = value; + } + get + { + if (_LdfGridSelectionChangedCmd == null) + { + _LdfGridSelectionChangedCmd = new DelegateCommand((par) => LdfGridSelectionChangedCmdMethod(par)); + } + return _LdfGridSelectionChangedCmd; + } + } + private void LdfGridSelectionChangedCmdMethod(object par) + { + if (par == null) + { + return; + } + if (par is LinLdfModel) + { + SelectedLinLdfModel = par as LinLdfModel; + return; + } + + + if ((par as SelectionChangedEventArgs)!.AddedItems[0] == null) + { + return; + } + //先判断是否是正确的集合数据,防止DataGrid的数据源刷新导致的触发事件 + var Selecteddata = (par as SelectionChangedEventArgs)!.AddedItems[0] as LinLdfModel; + + if (Selecteddata != null) + { + SelectedLinLdfModel = Selecteddata; + + } + } + + + private DelegateCommand _DataGridMenuCmd; + /// + /// DataGridMenu 操作的指令 + /// + public DelegateCommand DataGridMenuCmd + { + set + { + _DataGridMenuCmd = value; + } + get + { + if (_DataGridMenuCmd == null) + { + _DataGridMenuCmd = new DelegateCommand((Par) => DataGridMenuCmdMethod(Par)); + } + return _DataGridMenuCmd; + } + } + /// + /// DataGridMenu 操作的指令 + /// + /// + private void DataGridMenuCmdMethod(string Par) + { + switch (Par) + { + case "Write": + if (SelectedLinLdfModel != null && SelectCanLinConfigPro != null) + { + FreeSql.Insert(new CanLinRWConfig() + { + Name = "", + SignalName = SelectedLinLdfModel.SignalName, + MsgFrameName = SelectedLinLdfModel.MsgName, + CanLinConfigProId = SelectCanLinConfigPro.Id, + DefautValue = "", + RWInfo = RW.Write, + }).ExecuteInserted(); + + InitLoadLinConfigPro(); + } + break; + case "Read": + if (SelectedLinLdfModel != null && SelectCanLinConfigPro != null) + { + FreeSql.Insert(new CanLinRWConfig() + { + Name = "", + SignalName = SelectedLinLdfModel.SignalName, + MsgFrameName = SelectedLinLdfModel.MsgName, + CanLinConfigProId = SelectCanLinConfigPro.Id, + DefautValue = "", + RWInfo = RW.Read, + }).ExecuteInserted(); + + InitLoadLinConfigPro(); + } + break; + default: + break; + } + } + + + + #endregion + + #region LIN操作 + + private LINConfigExdDto _SelectedLINConfigExdDto; + /// + /// 选中的LIN操作 + /// + public LINConfigExdDto SelectedLINConfigExdDto + { + get { return _SelectedLINConfigExdDto; } + set { _SelectedLINConfigExdDto = value; RaisePropertyChanged(); } + } + + private DelegateCommand _LinOpCmd; + /// + /// LIN操作的指令 + /// + public DelegateCommand LinOpCmd + { + set + { + _LinOpCmd = value; + } + get + { + if (_LinOpCmd == null) + { + _LinOpCmd = new DelegateCommand((Par) => LinOpCmdMethod(Par)); + } + return _LinOpCmd; + } + } + /// + /// LIN操作的指令方法 + /// + /// + private void LinOpCmdMethod(string Par) + { + switch (Par) + { + case "Open": + if (ComActionService.IsLINToDoWork() == false) + { + System.Windows.MessageBox.Show("请关闭CAN连接后才能开启LIN,同一个时刻只能有一个通信驱动压缩机", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + return; + } + if (SelectCanLinConfigPro != null && SelectedLINConfigExdDto != null) + { + //打开连接 + LinDriveService.ToomossLinDrive.StartLinDrive(); + //系统使用了LIN + ConfigService.CanLinRunStateModel.CurSysSelectedCanLin = CanLinEnum.Lin; + //LIN LDF配置 有LDF配置的话,则直接加载LDF信息 + if (!string.IsNullOrEmpty(SelectCanLinConfigPro.LINConfigExd.LdfPath)) + { + var LdfData = LinDriveService.StartLdf(SelectedLINConfigExdDto.LdfPath); + ListLinLdfModel = LdfData; + } + } + else + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + break; + case "Close": + if (SelectCanLinConfigPro != null && SelectedLINConfigExdDto != null) + { + + LinDriveService.ToomossLinDrive.CloseDevice(); + //系统取消使用了CAN + ConfigService.CanLinRunStateModel.CurSysSelectedCanLin = CanLinEnum.No; + } + else + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + break; + case "Save": + if (SelectCanLinConfigPro != null && SelectedLINConfigExdDto != null) + { + //保存LIN 配置 + if (!string.IsNullOrEmpty(SelectedLINConfigExdDto.LdfPath)) + { + var Update = FreeSql.Update() + .Set(a => a.LdfPath, SelectedLINConfigExdDto.LdfPath) + .Set(a => a.Cycle, SelectedLINConfigExdDto.Cycle) + .Set(a => a.BaudRate, SelectedLINConfigExdDto.BaudRate) + .Where(a => a.Id == SelectedLINConfigExdDto.Id) + .ExecuteUpdated(); + } + + InitLoadLinConfigPro(); + } + else + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + break; + case "Parse": + if (SelectCanLinConfigPro != null && SelectedLINConfigExdDto != null) + { + //打开之后连接 + if (LinDriveService.ToomossLinDrive.OpenState) + { + //LIN LDF配置 有LDF配置的话,则加载LDF信息 + if (!string.IsNullOrEmpty(SelectedLINConfigExdDto.LdfPath)) + { + var LdfData = LinDriveService.StartLdf(SelectedLINConfigExdDto.LdfPath); + + ListLinLdfModel = LdfData; + } + else + { + System.Windows.MessageBox.Show("请选择LDF文件后再操作", "提示", System.Windows.MessageBoxButton.OKCancel, System.Windows.MessageBoxImage.Hand); + } + } + // ListLinLdfModel = new ObservableCollection() + //{ + // new LinLdfModel(){ MsgName="DSDF1",SignalName="FASDFA11",Publisher="DFAD1",SignalDesc="ASDFASD1"}, + // new LinLdfModel(){ MsgName="DSDF2",SignalName="FASDFA22",Publisher="DFAD2",SignalDesc="ASDFASD2"}, + // new LinLdfModel(){ MsgName="DSDF3",SignalName="FASDFA33",Publisher="DFAD3",SignalDesc="ASDFASD3"}, + // new LinLdfModel(){ MsgName="DSDF4",SignalName="FASDFA44",Publisher="DFAD4",SignalDesc="ASDFASD4"}, + // new LinLdfModel(){ MsgName="DSDF5",SignalName="FASDFA55",Publisher="DFAD5",SignalDesc="ASDFASD5"}, + //}; + // return; + + } + else + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + break; + + case "HandSend"://手动发送 + + //手动发送数据 + LinDriveService.SendMsgToLinDrive(HandSpeed); + + //LinDriveService.ToomossLinDrive.SendCanMsg(new List() + //{ + // new LinCmdData(){ MsgName="TX1",SignalName="COM_current_Power",SignalCmdValue=12}, + // new LinCmdData(){ MsgName="TX1",SignalName="COM_Curr_dc",SignalCmdValue=12}, + //}); + + break; + case "CycleSend"://循环发送你 + //循环发送数据 + LinDriveService.CycleSendMsg(); + + //Listen + break; + case "CycleRecive": + LinDriveService.CycleReciveMsg(); + + //Listen + break; + default: + break; + } + } + + + private double _HandSpeed; + /// + /// 手动转速数据 + /// + public double HandSpeed + { + get { return _HandSpeed; } + set { _HandSpeed = value; RaisePropertyChanged(); } + } + + + #endregion + + + #region 写入和读取操作 + + private ObservableCollection _WriteNameCbxItems; + /// + /// 写入的Name + /// + public ObservableCollection WriteNameCbxItems + { + get { return _WriteNameCbxItems; } + set { _WriteNameCbxItems = value; RaisePropertyChanged(); } + } + + + private ObservableCollection _ReadNameCbxItems; + /// + /// 写入的Name + /// + public ObservableCollection ReadNameCbxItems + { + get { return _ReadNameCbxItems; } + set { _ReadNameCbxItems = value; RaisePropertyChanged(); } + } + + + //private string _SelectedWriteName; + ///// + ///// 选中的写入的Name + ///// + //public string SelectedWriteName + //{ + // get { return _SelectedWriteName; } + // set { _SelectedWriteName = value; RaisePropertyChanged(); } + //} + + //private string _SelectedReadName; + ///// + ///// 选中的读取的Name + ///// + //public string SelectedReadName + //{ + // get { return _SelectedReadName; } + // set { _SelectedReadName = value; RaisePropertyChanged(); } + //} + + + private ObservableCollection _ListWriteCanLinRWConfigDto; + /// + /// LIN写入集合数据 + /// + public ObservableCollection ListWriteCanLinRWConfigDto + { + get { return _ListWriteCanLinRWConfigDto; } + set { _ListWriteCanLinRWConfigDto = value; RaisePropertyChanged(); } + } + + /// + /// 选中的CanLinRWConfigDto行 Write + /// + private CanLinRWConfigDto SelectedWriteCanLinRWConfigDto { get; set; } + + private DelegateCommand _WriteGridSelectionChangedCmd; + /// + /// 写入LIN的选中行的命令 + /// + public DelegateCommand WriteGridSelectionChangedCmd + { + set + { + _WriteGridSelectionChangedCmd = value; + } + get + { + if (_WriteGridSelectionChangedCmd == null) + { + _WriteGridSelectionChangedCmd = new DelegateCommand((Par) => WriteGridSelectionChangedCmdMethod(Par)); + } + return _WriteGridSelectionChangedCmd; + } + } + /// + /// 写入LIN的选中行执行方法 + /// + /// + /// + private void WriteGridSelectionChangedCmdMethod(object par) + { + if (par is CanLinRWConfigDto) + { + SelectedWriteCanLinRWConfigDto = par as CanLinRWConfigDto; + } + } + + private DelegateCommand _WriteCmd; + /// + /// 写入操作的指令 + /// + public DelegateCommand WriteCmd + { + set + { + _WriteCmd = value; + } + get + { + if (_WriteCmd == null) + { + _WriteCmd = new DelegateCommand((Par) => WriteCmdMethod(Par)); + } + return _WriteCmd; + } + } + /// + /// 写入操作的指令方法 + /// + /// + private void WriteCmdMethod(string Par) + { + if (SelectCanLinConfigPro == null) + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + return; + } + + + switch (Par) + { + case "Add": + //由右侧的右键LDF目录增加 + + break; + case "Edit": + if (ListWriteCanLinRWConfigDto != null && ListWriteCanLinRWConfigDto.Count() > 0) + { + foreach (var item in ListWriteCanLinRWConfigDto) + { + //直接修改 + FreeSql.Update(item.Id) + .Set(a => a.Name, item.Name) + .Set(a => a.DefautValue, item.DefautValue) + .ExecuteAffrows(); + //ListWriteCanLinRWConfigDto.Remove(SelectedWriteCanLinRWConfigDto); + + //SelectedWriteCanLinRWConfigDto = null; + + } + + InitLoadLinConfigPro(); + } + + + + break; + case "Delete": + if (SelectedWriteCanLinRWConfigDto != null) + { + //直接删除掉 + FreeSql.Delete(SelectedWriteCanLinRWConfigDto.Id).ExecuteAffrows(); + ListWriteCanLinRWConfigDto.Remove(SelectedWriteCanLinRWConfigDto); + + SelectedWriteCanLinRWConfigDto = null; + + InitLoadLinConfigPro(); + } + else + { + System.Windows.MessageBox.Show("请选中后再进行【删除】操作?", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + break; + default: + break; + } + } + + + + + + private ObservableCollection _ListReadCanLinRWConfigDto; + /// + /// LIN读取集合数据 + /// + public ObservableCollection ListReadCanLinRWConfigDto + { + get { return _ListReadCanLinRWConfigDto; } + set { _ListReadCanLinRWConfigDto = value; RaisePropertyChanged(); } + } + + /// + /// 选中的CanLinRWConfigDto行 Read + /// + private CanLinRWConfigDto SelectedReadCanLinRWConfigDto { get; set; } + + private DelegateCommand _ReadGridSelectionChangedCmd; + /// + /// 写入LIN的选中行的命令 + /// + public DelegateCommand ReadGridSelectionChangedCmd + { + set + { + _ReadGridSelectionChangedCmd = value; + } + get + { + if (_ReadGridSelectionChangedCmd == null) + { + _ReadGridSelectionChangedCmd = new DelegateCommand((Par) => ReadGridSelectionChangedCmdMethod(Par)); + } + return _ReadGridSelectionChangedCmd; + } + } + /// + /// 读取LIN的选中行执行方法 + /// + /// + /// + private void ReadGridSelectionChangedCmdMethod(object par) + { + if (par is CanLinRWConfigDto) + { + SelectedReadCanLinRWConfigDto = par as CanLinRWConfigDto; + } + } + + + + private DelegateCommand _ReadCmd; + /// + /// 读取操作的指令 + /// + public DelegateCommand ReadCmd + { + set + { + _ReadCmd = value; + } + get + { + if (_ReadCmd == null) + { + _ReadCmd = new DelegateCommand((Par) => ReadCmdMethod(Par)); + } + return _ReadCmd; + } + } + /// + /// 读取操作的指令方法 + /// + /// + private void ReadCmdMethod(string Par) + { + if (SelectCanLinConfigPro == null) + { + System.Windows.MessageBox.Show("选中LIN配置名称后再操作", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + return; + } + + switch (Par) + { + case "Add": + //由右侧的右键LDF目录增加 + + break; + case "Edit": + if (ListReadCanLinRWConfigDto != null && ListReadCanLinRWConfigDto.Count() > 0) + { + foreach (var item in ListReadCanLinRWConfigDto) + { + //直接修改 + FreeSql.Update(item.Id) + .Set(a => a.Name, item.Name) + .Set(a => a.DefautValue, item.DefautValue) + .ExecuteAffrows(); + //ListReadCanLinRWConfigDto.Remove(SelectedReadCanLinRWConfigDto); + + //SelectedReadCanLinRWConfigDto = null; + + } + + InitLoadLinConfigPro(); + } + + + + break; + case "Delete": + if (SelectedReadCanLinRWConfigDto != null) + { + //直接删除掉 + FreeSql.Delete(SelectedReadCanLinRWConfigDto.Id).ExecuteAffrows(); + ListReadCanLinRWConfigDto.Remove(SelectedReadCanLinRWConfigDto); + + SelectedReadCanLinRWConfigDto = null; + + InitLoadLinConfigPro(); + } + else + { + System.Windows.MessageBox.Show("请选中后再进行【删除】操作?", "提示", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand); + } + + break; + default: + break; + } + } + + #endregion + } +} diff --git a/CapMachine.Wpf/ViewModels/SplashScreenViewModel.cs b/CapMachine.Wpf/ViewModels/SplashScreenViewModel.cs new file mode 100644 index 0000000..b378593 --- /dev/null +++ b/CapMachine.Wpf/ViewModels/SplashScreenViewModel.cs @@ -0,0 +1,55 @@ +using CapMachine.Core; +using CapMachine.Wpf.Services; +using Prism.Services.Dialogs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CapMachine.Wpf.ViewModels +{ + public class SplashScreenViewModel : DialogViewModel + { + private readonly IApplicationContext applicationContext; + + private string displayText; + + public string DisplayText + { + get { return displayText; } + set { displayText = value; RaisePropertyChanged(); } + } + + public SplashScreenViewModel( + IApplicationContext applicationContext + ) + { + this.applicationContext = applicationContext; + + } + + public override async void OnDialogOpened(IDialogParameters parameters) + { + await SetBusyAsync(async () => + { + await Task.Delay(2000); + + //加载本地的缓存信息 + DisplayText = "Initializing"; + + OnDialogClosed(); + //OnDialogClosed(ButtonResult.OK); + + ////如果本地授权存在,直接进入系统首页 + //if (accessTokenManager.IsUserLoggedIn && applicationContext.Configuration != null) + // OnDialogClosed(); + //else if (applicationContext.Configuration != null) + // OnDialogClosed(ButtonResult.Ignore); + //else + // OnDialogClosed(ButtonResult.No); + }); + } + } +} diff --git a/CapMachine.Wpf/ViewModels/TaskBarViewModel.cs b/CapMachine.Wpf/ViewModels/TaskBarViewModel.cs new file mode 100644 index 0000000..db72deb --- /dev/null +++ b/CapMachine.Wpf/ViewModels/TaskBarViewModel.cs @@ -0,0 +1,41 @@ +using CapMachine.Wpf.Services; +using Prism.Commands; +using Prism.Mvvm; +using Prism.Ioc; + +namespace CapMachine.Wpf.ViewModels +{ + public class TaskBarViewModel : BindableBase + { + private readonly IHostDialogService dialog; + private readonly IAppStartService appStartService; + public DelegateCommand ExitCommand { get; set; } + public DelegateCommand ShowViewCommand { get; private set; } + + public TaskBarViewModel() + { + dialog = ContainerLocator.Container.Resolve(); + appStartService = ContainerLocator.Container.Resolve(); + + ExitCommand = new DelegateCommand(Exit); + ShowViewCommand = new DelegateCommand(ShowView); + } + + private async void Exit() + { + ShowView(); + + if (await dialog.Question("确定","1")) + appStartService.Exit(); + } + + private void ShowView() + { + if (!App.Current.MainWindow.IsVisible) + { + App.Current.MainWindow.Show(); + App.Current.MainWindow.WindowState = System.Windows.WindowState.Normal; + } + } + } +} diff --git a/CapMachine.Wpf/Views/CANConfigView.xaml b/CapMachine.Wpf/Views/CANConfigView.xaml index 66edb7f..ca761b4 100644 --- a/CapMachine.Wpf/Views/CANConfigView.xaml +++ b/CapMachine.Wpf/Views/CANConfigView.xaml @@ -459,7 +459,7 @@ Text="" /> @@ -476,14 +476,38 @@ + Text="连接" /> + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CapMachine.Wpf/Views/LINConfigView.xaml.cs b/CapMachine.Wpf/Views/LINConfigView.xaml.cs new file mode 100644 index 0000000..fd07d2a --- /dev/null +++ b/CapMachine.Wpf/Views/LINConfigView.xaml.cs @@ -0,0 +1,28 @@ +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 CapMachine.Wpf.Views +{ + /// + /// LINConfigView.xaml 的交互逻辑 + /// + public partial class LINConfigView : UserControl + { + public LINConfigView() + { + InitializeComponent(); + } + } +} diff --git a/CapMachine.Wpf/Views/MonitorView.xaml b/CapMachine.Wpf/Views/MonitorView.xaml index 9b4d69d..df732a2 100644 --- a/CapMachine.Wpf/Views/MonitorView.xaml +++ b/CapMachine.Wpf/Views/MonitorView.xaml @@ -168,6 +168,8 @@ AutoHandCommand="{Binding Source={StaticResource Proxy}, Path=Data.AutoHandCmd}" AutoHandState="False" HandValueCommand="{Binding Source={StaticResource Proxy}, Path=Data.HandValueCmd}" + HandValueMVParameter="{Binding EngMvValue}" + HandValueSVParameter="{Binding EngSvValue}" MeterName="{Binding NameNoUnit}" PVValue="{Binding EngPvValue}" SVValue="{Binding EngSvValue}" @@ -208,7 +210,7 @@ - - + --> - + + Foreground="LimeGreen" + Text="{Binding MachineRtDataService.CurSysExdInfo.RunTimeMsg}" /> - - + --> + -