Compare commits
22 Commits
SongZhi_Pr
...
HASCO_Simp
| Author | SHA1 | Date | |
|---|---|---|---|
| ab49681acd | |||
| 45bba87b4e | |||
| e77f944a16 | |||
| a7187c5e33 | |||
| 86e1148826 | |||
| 3dd0e73477 | |||
| 118e408067 | |||
| 25b2e53028 | |||
| e1d81f6aee | |||
| 2ad76399a6 | |||
| f39263c2e3 | |||
| d2ef6f9961 | |||
| c22a8cc98f | |||
| 7b027a10ea | |||
| 851b64788d | |||
| 38f4ed7622 | |||
| 2e534d8dfa | |||
| 39b4d1a0ea | |||
| 1d8215bbc1 | |||
| 50ccd21b81 | |||
| 57d194e093 | |||
| f01d829ece |
@@ -8,4 +8,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FreeSql" Version="3.5.102" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="ProExecuteModel\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
38
CapMachine.Model/ConfigAlarm.cs
Normal file
38
CapMachine.Model/ConfigAlarm.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
|
||||
namespace CapMachine.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 报警配置
|
||||
/// </summary>
|
||||
[Table(Name = "ConfigAlarm")]
|
||||
public class ConfigAlarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
[Column(IsPrimary = true, IsIdentity = true)]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 序号
|
||||
/// </summary>
|
||||
[Column(Name = "IndexNo", IsNullable = false)]
|
||||
public int IndexNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快速设置仪表名称
|
||||
/// </summary>
|
||||
[Column(Name = "MeterName", IsNullable = true, StringLength = 30)]
|
||||
public string MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alarm
|
||||
/// </summary>
|
||||
[Column(Name = "Alarm", IsNullable = true)]
|
||||
public double Alarm { get; set; }
|
||||
|
||||
[Column(ServerTime = DateTimeKind.Local, CanUpdate = false)]
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace CapMachine.Model
|
||||
{
|
||||
@@ -49,5 +50,23 @@ namespace CapMachine.Model
|
||||
/// </summary>
|
||||
public long HistoryExpId { get; set; }
|
||||
public HistoryExp? HistoryExp { get; set; }
|
||||
|
||||
[Column(IsIgnore = true)]
|
||||
public bool IsSelected
|
||||
{
|
||||
get { return _isSelected; }
|
||||
set
|
||||
{
|
||||
if (_isSelected != value)
|
||||
{
|
||||
_isSelected = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isSelected;
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,159 +7,159 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序段具体步骤执行信息
|
||||
/// </summary>
|
||||
[Table(Name = "ProStepExecute")]
|
||||
public class ProStepExecute
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
[Column(IsPrimary = true)]
|
||||
public Guid Id { get; set; }
|
||||
///// <summary>
|
||||
///// 程序段具体步骤执行信息
|
||||
///// </summary>
|
||||
//[Table(Name = "ProStepExecute")]
|
||||
//public class ProStepExecute
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 主键
|
||||
// /// </summary>
|
||||
// [Column(IsPrimary = true)]
|
||||
// public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序段名称
|
||||
/// </summary>
|
||||
[Column(Name = "ProName", IsNullable = false, StringLength = 20)]
|
||||
public string ProName { get; set; }
|
||||
// /// <summary>
|
||||
// /// 程序段名称
|
||||
// /// </summary>
|
||||
// [Column(Name = "ProName", IsNullable = false, StringLength = 20)]
|
||||
// public string ProName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序段步骤
|
||||
/// </summary>
|
||||
[Column(Name = "ProStep", IsNullable = false)]
|
||||
public int ProStep { get; set; }
|
||||
// /// <summary>
|
||||
// /// 程序段步骤
|
||||
// /// </summary>
|
||||
// [Column(Name = "ProStep", IsNullable = false)]
|
||||
// public int ProStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序段反复
|
||||
/// </summary>
|
||||
[Column(Name = "ProRepeat")]
|
||||
public int ProRepeat { get; set; }
|
||||
// /// <summary>
|
||||
// /// 程序段反复
|
||||
// /// </summary>
|
||||
// [Column(Name = "ProRepeat")]
|
||||
// public int ProRepeat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在执行当前程序段
|
||||
/// </summary>
|
||||
[Column(Name = "IsCurrentProStep")]
|
||||
public bool IsCurrentProStep { get; set; }
|
||||
// /// <summary>
|
||||
// /// 是否正在执行当前程序段
|
||||
// /// </summary>
|
||||
// [Column(Name = "IsCurrentProStep")]
|
||||
// public bool IsCurrentProStep { get; set; }
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
////////////////////////程序步骤///////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// ////////////////////////程序步骤///////////////////////////////
|
||||
// ////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在执行当前程序段
|
||||
/// </summary>
|
||||
[Column(Name = "IsCurrentMeterStep")]
|
||||
public bool IsCurrentMeterStep { get; set; }
|
||||
// /// <summary>
|
||||
// /// 是否正在执行当前程序段
|
||||
// /// </summary>
|
||||
// [Column(Name = "IsCurrentMeterStep")]
|
||||
// public bool IsCurrentMeterStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仪表功能名称
|
||||
/// </summary>
|
||||
[Column(Name = "MeterName", IsNullable = false, StringLength = 20)]
|
||||
public string MeterName { get; set; }
|
||||
// /// <summary>
|
||||
// /// 仪表功能名称
|
||||
// /// </summary>
|
||||
// [Column(Name = "MeterName", IsNullable = false, StringLength = 20)]
|
||||
// public string MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 步骤
|
||||
/// </summary>
|
||||
[Column(Name = "MeterStep", IsNullable = false)]
|
||||
public int MeterStep { get; set; }
|
||||
// /// <summary>
|
||||
// /// 步骤
|
||||
// /// </summary>
|
||||
// [Column(Name = "MeterStep", IsNullable = false)]
|
||||
// public int MeterStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 速度 DegC
|
||||
/// </summary>
|
||||
[Column(Name = "SV", IsNullable = true)]
|
||||
public int SV { get; set; }
|
||||
// /// <summary>
|
||||
// /// 速度 DegC
|
||||
// /// </summary>
|
||||
// [Column(Name = "SV", IsNullable = true)]
|
||||
// public int SV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间-分钟
|
||||
/// </summary>
|
||||
[Column(Name = "TimeMin", IsNullable = true)]
|
||||
public int TimeMin { get; set; }
|
||||
// /// <summary>
|
||||
// /// 时间-分钟
|
||||
// /// </summary>
|
||||
// [Column(Name = "TimeMin", IsNullable = true)]
|
||||
// public int TimeMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间-秒
|
||||
/// </summary>
|
||||
[Column(Name = "TimeSec", IsNullable = true)]
|
||||
public int TimeSec { get; set; }
|
||||
// /// <summary>
|
||||
// /// 时间-秒
|
||||
// /// </summary>
|
||||
// [Column(Name = "TimeSec", IsNullable = true)]
|
||||
// public int TimeSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID NO
|
||||
/// </summary>
|
||||
[Column(Name = "PIDNo", IsNullable = true)]
|
||||
public int PIDNo { get; set; }
|
||||
// /// <summary>
|
||||
// /// PID NO
|
||||
// /// </summary>
|
||||
// [Column(Name = "PIDNo", IsNullable = true)]
|
||||
// public int PIDNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit NO
|
||||
/// </summary>
|
||||
[Column(Name = "LitmitNo", IsNullable = true)]
|
||||
public int LitmitNo { get; set; }
|
||||
// /// <summary>
|
||||
// /// Limit NO
|
||||
// /// </summary>
|
||||
// [Column(Name = "LitmitNo", IsNullable = true)]
|
||||
// public int LitmitNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alarm NO
|
||||
/// </summary>
|
||||
[Column(Name = "AlarmNo", IsNullable = true)]
|
||||
public int AlarmNo { get; set; }
|
||||
// /// <summary>
|
||||
// /// Alarm NO
|
||||
// /// </summary>
|
||||
// [Column(Name = "AlarmNo", IsNullable = true)]
|
||||
// public int AlarmNo { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 时间信号
|
||||
///// </summary>
|
||||
//[Column(Name = "TimeSign1", IsNullable = true)]
|
||||
//public int TimeSign1 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 时间信号
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "TimeSign1", IsNullable = true)]
|
||||
// //public int TimeSign1 { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 时间信号
|
||||
///// </summary>
|
||||
//[Column(Name = "TimeSign2", IsNullable = true)]
|
||||
//public int TimeSign2 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 时间信号
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "TimeSign2", IsNullable = true)]
|
||||
// //public int TimeSign2 { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 时间信号
|
||||
///// </summary>
|
||||
//[Column(Name = "TimeSign3", IsNullable = true)]
|
||||
//public int TimeSign3 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 时间信号
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "TimeSign3", IsNullable = true)]
|
||||
// //public int TimeSign3 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 步进重复
|
||||
/// </summary>
|
||||
[Column(Name = "Repeat", IsNullable = true)]
|
||||
public int StepRepeat { get; set; }
|
||||
// /// <summary>
|
||||
// /// 步进重复
|
||||
// /// </summary>
|
||||
// [Column(Name = "Repeat", IsNullable = true)]
|
||||
// public int StepRepeat { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 拓展字段1
|
||||
///// </summary>
|
||||
//[Column(Name = "FeildExte1", IsNullable = true)]
|
||||
//public string FeildExte1 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 拓展字段1
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "FeildExte1", IsNullable = true)]
|
||||
// //public string FeildExte1 { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 拓展字段1
|
||||
///// </summary>
|
||||
//[Column(Name = "FeildExte2", IsNullable = true)]
|
||||
//public string FeildExte2 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 拓展字段1
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "FeildExte2", IsNullable = true)]
|
||||
// //public string FeildExte2 { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 拓展字段1
|
||||
///// </summary>
|
||||
//[Column(Name = "FeildExte3", IsNullable = true)]
|
||||
//public string FeildExte3 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 拓展字段1
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "FeildExte3", IsNullable = true)]
|
||||
// //public string FeildExte3 { get; set; }
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 拓展字段1
|
||||
///// </summary>
|
||||
//[Column(Name = "FeildExte4", IsNullable = true)]
|
||||
//public string FeildExte4 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 拓展字段1
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "FeildExte4", IsNullable = true)]
|
||||
// //public string FeildExte4 { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 拓展字段1
|
||||
///// </summary>
|
||||
//[Column(Name = "FeildExte5", IsNullable = true)]
|
||||
//public string FeildExte5 { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 拓展字段1
|
||||
// ///// </summary>
|
||||
// //[Column(Name = "FeildExte5", IsNullable = true)]
|
||||
// //public string FeildExte5 { get; set; }
|
||||
|
||||
[Column(ServerTime = DateTimeKind.Local, CanUpdate = false)]
|
||||
public DateTime CreateTime { get; set; }
|
||||
// [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)]
|
||||
// public DateTime CreateTime { get; set; }
|
||||
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using CapMachine.Core.IService;
|
||||
using CapMachine.Wpf.MapperProfile;
|
||||
using CapMachine.Wpf.Models;
|
||||
using CapMachine.Wpf.Services;
|
||||
using CapMachine.Wpf.SoftAuthorizeCore;
|
||||
using CapMachine.Wpf.ViewModels;
|
||||
using CapMachine.Wpf.Views;
|
||||
using FreeSql;
|
||||
@@ -33,6 +34,7 @@ namespace CapMachine.Wpf
|
||||
private ILogService LogService { get; set; }
|
||||
|
||||
private static System.Threading.Mutex mutex;
|
||||
private SoftAuthorizeHelper SoftAuthorizeHelper { get; set; } = SoftAuthorizeHelper.GetInstance();
|
||||
|
||||
public App()
|
||||
{
|
||||
@@ -83,6 +85,26 @@ namespace CapMachine.Wpf
|
||||
this.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
//验证文档
|
||||
try
|
||||
{
|
||||
var MachineCode = SoftAuthorizeHelper.GetMachineCode();
|
||||
SoftAuthorizeHelper.WriteMachineCodeToFile(MachineCode, "");
|
||||
var PublicKey = SoftAuthorizeHelper.GetPublicKeyDataByFilePath("");
|
||||
var Lience = SoftAuthorizeHelper.GetLienceDataByFilePath("");
|
||||
var IsOK = SoftAuthorizeHelper.CheckLience(MachineCode, PublicKey, Lience);
|
||||
if (!IsOK)
|
||||
{
|
||||
LogService.Error("授权失败");
|
||||
//this.Shutdown();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
//base.OnStartup(e);
|
||||
}
|
||||
|
||||
@@ -92,13 +114,16 @@ namespace CapMachine.Wpf
|
||||
{
|
||||
////注册日志服务
|
||||
containerRegistry.RegisterSingleton<ILogService, LogService>();
|
||||
//注册AutoMapper 将IAutoMapperProvider注入IOC容器,并对外提供IMapper注入类型。
|
||||
containerRegistry.RegisterSingleton<IMapperProvider, MapperConfig>();
|
||||
containerRegistry.Register(typeof(IMapper), GetMapper);
|
||||
|
||||
//注册基础的服务
|
||||
//containerRegistry.RegisterSingleton<IHostDialogService, DialogHostService>();
|
||||
//containerRegistry.RegisterSingleton<IAppStartService, AppStartService>();
|
||||
//containerRegistry.RegisterSingleton<IApplicationContext, ApplicationContext>();
|
||||
|
||||
|
||||
|
||||
containerRegistry.RegisterSingleton<ConfigService>();
|
||||
containerRegistry.RegisterSingleton<AlarmService>();
|
||||
////注册设备服务
|
||||
@@ -108,14 +133,12 @@ namespace CapMachine.Wpf
|
||||
containerRegistry.RegisterSingleton<MachineRtDataService>();
|
||||
containerRegistry.RegisterSingleton<DataRecordService>();
|
||||
containerRegistry.RegisterSingleton<HighSpeedDataService>();
|
||||
containerRegistry.RegisterSingleton<PPCService>();
|
||||
//containerRegistry.RegisterSingleton<PPCService>();
|
||||
containerRegistry.RegisterSingleton<SysRunService>();
|
||||
|
||||
containerRegistry.RegisterSingleton<ComActionService>();
|
||||
|
||||
//注册AutoMapper 将IAutoMapperProvider注入IOC容器,并对外提供IMapper注入类型。
|
||||
containerRegistry.RegisterSingleton<IMapperProvider, MapperConfig>();
|
||||
containerRegistry.Register(typeof(IMapper), GetMapper);
|
||||
|
||||
containerRegistry.RegisterSingleton<ProRuntimeService>();
|
||||
|
||||
string strsqllite = System.AppDomain.CurrentDomain.BaseDirectory + @"Db\CapMachine.db";
|
||||
string strslocaldb = System.AppDomain.CurrentDomain.BaseDirectory + @"Db\CapMachineDb";
|
||||
@@ -254,8 +277,9 @@ namespace CapMachine.Wpf
|
||||
var appVersionService8 = ContainerLocator.Container.Resolve<CanDriveService>();
|
||||
var appVersionService9 = ContainerLocator.Container.Resolve<DataRecordService>();
|
||||
var appVersionService10 = ContainerLocator.Container.Resolve<HighSpeedDataService>();
|
||||
var appVersionService11 = ContainerLocator.Container.Resolve<PPCService>();
|
||||
//var appVersionService11 = ContainerLocator.Container.Resolve<PPCService>();
|
||||
var appVersionService15 = ContainerLocator.Container.Resolve<ComActionService>();
|
||||
var appVersionService16 = ContainerLocator.Container.Resolve<ProRuntimeService>();
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace CapMachine.Wpf.CanDrive
|
||||
{
|
||||
ContainerProvider = containerProvider;
|
||||
HighSpeedDataService = ContainerProvider.Resolve<HighSpeedDataService>();
|
||||
|
||||
//Stopwatch.Frequency表示高精度计时器每秒的计数次数(ticks/秒)每毫秒的ticks数 = 每秒的ticks数 ÷ 1000
|
||||
TicksPerMs = Stopwatch.Frequency / 1000.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -479,6 +482,23 @@ namespace CapMachine.Wpf.CanDrive
|
||||
|
||||
StringBuilder ValueSb = new StringBuilder(16);
|
||||
|
||||
private bool _IsSendOk;
|
||||
/// <summary>
|
||||
/// 发送报文是否OK
|
||||
/// </summary>
|
||||
public bool IsSendOk
|
||||
{
|
||||
get { return _IsSendOk; }
|
||||
set
|
||||
{
|
||||
if (_IsSendOk != value)
|
||||
{
|
||||
RaisePropertyChanged();
|
||||
_IsSendOk = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 要发送的数据
|
||||
/// </summary>
|
||||
@@ -543,6 +563,193 @@ namespace CapMachine.Wpf.CanDrive
|
||||
}
|
||||
|
||||
|
||||
#region 精确发送报文数据
|
||||
|
||||
// 添加取消标记源字段用于停止任务
|
||||
private CancellationTokenSource CycleSendCts;
|
||||
|
||||
/// <summary>
|
||||
/// 计算每毫秒对应的ticks数(只需计算一次)
|
||||
/// </summary>
|
||||
private double TicksPerMs;
|
||||
|
||||
// 类成员变量定义 精确记时用
|
||||
private readonly Stopwatch Stopwatcher = new Stopwatch();
|
||||
private long NextExecutionTime;
|
||||
// 计算需要等待的时间
|
||||
private long CurrentTime;
|
||||
private long DelayTicks;
|
||||
private int DelayMs;
|
||||
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// 精确周期发送CAN数据
|
||||
/// </summary>
|
||||
public void StartPrecisionCycleSendMsg()
|
||||
{
|
||||
// 创建取消标记源 用于控制任务的取消 允许在需要时通过取消令牌来优雅停止任务
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
var token = cancellationTokenSource.Token;
|
||||
|
||||
// 保存取消标记,以便在停止时使用
|
||||
CycleSendCts = cancellationTokenSource;//将取消标记源保存到类的成员变量CycleSendCts,这样在外部调用停止方法时可以访问它
|
||||
NextExecutionTime = 0;//初始化NextExecutionTime为0,这个变量用于记录下一次执行的目标时间点
|
||||
|
||||
CycleSendTask = Task.Factory.StartNew(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// 设置当前线程为高优先级
|
||||
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
|
||||
|
||||
// 初始化完成后开始计时
|
||||
Stopwatcher.Restart();
|
||||
// 预先计算固定值
|
||||
long CycleInTicks = (long)(SendCycle * TicksPerMs);
|
||||
//临时测试用
|
||||
//long lastTicks = Stopwatcher.ElapsedTicks;
|
||||
//IsCycleSend
|
||||
while (IsCycleSend && !token.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 计算下一次执行时间点 ,将当前设置的发送周期SendCycle(毫秒)转换为Stopwatch的计时单位(tick),累加到NextExecutionTime上
|
||||
NextExecutionTime += CycleInTicks; // 转换为Stopwatch计时单位
|
||||
|
||||
// 获取当前时间点,以Stopwatch的tick为单位
|
||||
CurrentTime = Stopwatcher.ElapsedTicks;
|
||||
//计算需要等待的时间,即目标时间点(NextExecutionTime)与当前时间点(CurrentTime)的差值
|
||||
DelayTicks = NextExecutionTime - CurrentTime;
|
||||
|
||||
// 如果还有等待时间,则等待,只有在目标时间点还未到达时才执行等待
|
||||
if (DelayTicks > 0)
|
||||
{
|
||||
////此时是需要等待的,那么需要等待多久呢, 将需等待的tick数转换回毫秒
|
||||
DelayMs = (int)(DelayTicks / TicksPerMs);
|
||||
//20这个数据是预估和测试的,可能跟Windows抖动误差就是20ms左右,当然可以不用这个IF()判断,直接SpinWait.SpinUntil(() => Stopwatcher.ElapsedTicks >= NextExecutionTime);但是会导致当前独占一个CPU核心线程
|
||||
//所以设置一个20的阈值,20ms以下的延迟使用SpinWait.SpinUntil进行自旋等待,20ms以上的延迟使用Task.Delay进行异步等待,让CPU不至于一直的独占
|
||||
if (DelayMs <= 20)
|
||||
{
|
||||
SpinWait.SpinUntil(() => Stopwatcher.ElapsedTicks >= NextExecutionTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
////使用Task.Delay进行异步等待,大部分等待时间通过这种方式完成,避免线程阻塞
|
||||
await Task.Delay(DelayMs - 20, token);
|
||||
//// 使用SpinWait.SpinUntil进行精确的微调等待。自旋等待会占用CPU资源,但能提供更高的定时精度,确保在精确的时间点执行
|
||||
////上面的Task.Delay可能会因为系统调度等原因导致实际执行时间稍晚于预期,因此在这里使用SpinWait.SpinUntil来确保在精确的时间点执行
|
||||
SpinWait.SpinUntil(() => Stopwatcher.ElapsedTicks >= NextExecutionTime);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果已经超过了计划时间,立即执行并重新校准
|
||||
if (Stopwatcher.ElapsedTicks >= NextExecutionTime + CycleInTicks)
|
||||
{
|
||||
//检测是否发生了严重延迟(超过一个周期)。如果当前时间已经超过了下一次计划时间,则说明系统负载过高或其他原因导致无法按时执行,
|
||||
//此时重置NextExecutionTime为当前时间,避免连续的延迟累积
|
||||
// 严重延迟,重新校准
|
||||
NextExecutionTime = Stopwatcher.ElapsedTicks;
|
||||
Console.WriteLine("定时发送延迟过大,重新校准时间");
|
||||
}
|
||||
|
||||
// 使用Stopwatch记录实际的执行间隔,而不是DateTime
|
||||
//Console.WriteLine($"--实际间隔(ms): {(Stopwatcher.ElapsedTicks - lastTicks) / TicksPerMs:F3}, 目标: {SendCycle}");
|
||||
//lastTicks = Stopwatcher.ElapsedTicks;
|
||||
|
||||
//Console.WriteLine($"--当前时间(毫秒): {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
|
||||
|
||||
|
||||
// 执行发送CAN逻辑
|
||||
{
|
||||
|
||||
var GroupMsg = CmdData.GroupBy(x => x.MsgName);
|
||||
USB2CAN.CAN_MSG[] CanMsg = new USB2CAN.CAN_MSG[GroupMsg.Count()];
|
||||
for (int i = 0; i < GroupMsg.Count(); i++)
|
||||
{
|
||||
CanMsg[i] = new USB2CAN.CAN_MSG();
|
||||
CanMsg[i].Data = new Byte[64];
|
||||
}
|
||||
|
||||
IntPtr msgPtSend = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CAN.CAN_MSG)));
|
||||
int Index = 0;
|
||||
//循环给MSG赋值数据
|
||||
foreach (var itemMsg in GroupMsg)
|
||||
{
|
||||
foreach (var itemSignal in itemMsg)
|
||||
{
|
||||
CAN_DBCParser.DBC_SetSignalValue(DBCHandle, new StringBuilder(itemMsg.Key), new StringBuilder(itemSignal.SignalName), itemSignal.SignalCmdValue);
|
||||
}
|
||||
CAN_DBCParser.DBC_SyncValueToCANMsg(DBCHandle, new StringBuilder(itemMsg.Key), msgPtSend);
|
||||
CanMsg[Index] = (USB2CAN.CAN_MSG)Marshal.PtrToStructure(msgPtSend, typeof(USB2CAN.CAN_MSG));
|
||||
Index++;
|
||||
}
|
||||
|
||||
//通过DBC写入数据后生成CanMsg
|
||||
//将信号值填入CAN消息里面
|
||||
|
||||
//释放申请的临时缓冲区
|
||||
Marshal.FreeHGlobal(msgPtSend);
|
||||
|
||||
//发送CAN数据
|
||||
int SendedNum = USB2CAN.CAN_SendMsg(DevHandle, WriteCANIndex, CanMsg, (uint)CanMsg.Length);
|
||||
if (SendedNum >= 0)
|
||||
{
|
||||
//Console.WriteLine("Success send frames:{0}", SendedNum);
|
||||
IsSendOk = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.WriteLine("Send CAN data failed! {0}", SendedNum);
|
||||
IsSendOk = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
// 任务被取消,正常退出
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"CAN周期发送异常: {ex.Message}");
|
||||
// 短暂暂停避免异常情况下CPU占用过高
|
||||
await Task.Delay(10, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 确保在任何情况下(正常退出、异常、取消)都会停止计时器
|
||||
Stopwatcher.Stop();
|
||||
|
||||
// 清理其他可能的资源
|
||||
Console.WriteLine("CAN周期发送任务已结束,资源已清理");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 确保在任何情况下(正常退出、异常、取消)都会停止计时器
|
||||
Stopwatcher.Stop();
|
||||
}
|
||||
|
||||
}, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 修改停止发送的方法
|
||||
/// </summary>
|
||||
public void StopCycleSendMsg()
|
||||
{
|
||||
IsCycleSend = false;
|
||||
CycleSendCts?.Cancel();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 循环获取CAN消息
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
@@ -699,19 +699,22 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="Arction.DirectX">
|
||||
<HintPath>C:\Program Files (x86)\Arction\LightningChart .NET SDK v.10\LibNET4\Arction.DirectX.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Arction.Licensing">
|
||||
<HintPath>C:\Program Files (x86)\Arction\LightningChart .NET SDK v.10\LibNET4\Arction.Licensing.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Arction.RenderingDefinitions">
|
||||
<HintPath>C:\Program Files (x86)\Arction\LightningChart .NET SDK v.10\LibNET4\Arction.RenderingDefinitions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Arction.Wpf.Charting.LightningChart">
|
||||
<HintPath>C:\Program Files (x86)\Arction\LightningChart .NET SDK v.10\LibNET4\Arction.Wpf.Charting.LightningChart.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Tool\" />
|
||||
<Folder Include="LocalDll\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -735,6 +738,12 @@
|
||||
<None Update="EnvSupport\SQL2022-SSEI-Expr.exe">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Key\License.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Key\PublicKey.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
57
CapMachine.Wpf/ChannelModel/ProRunChannelData.cs
Normal file
57
CapMachine.Wpf/ChannelModel/ProRunChannelData.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using CapMachine.Wpf.Dtos;
|
||||
using CapMachine.Wpf.Models.ProModelPars;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.ChannelModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序运行管道数据
|
||||
/// </summary>
|
||||
public class ProRunChannelData
|
||||
{
|
||||
/// <summary>
|
||||
/// 参数名称
|
||||
/// </summary>
|
||||
public string? MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序Seg
|
||||
/// </summary>
|
||||
public string? ProSegName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序步骤
|
||||
/// </summary>
|
||||
public int MeterStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 斜坡打点步骤
|
||||
/// </summary>
|
||||
public int SlopStepNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 值类型
|
||||
/// </summary>
|
||||
public RunStepType RunStepType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public int? SV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID的配置信息
|
||||
/// </summary>
|
||||
public PID? CurLoadPID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alarm的配置信息
|
||||
/// </summary>
|
||||
public Limit? CurLoadLimit { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
43
CapMachine.Wpf/Dtos/ConfigAlarmDto.cs
Normal file
43
CapMachine.Wpf/Dtos/ConfigAlarmDto.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace CapMachine.Wpf.Dtos
|
||||
{
|
||||
public class ConfigAlarmDto : BindableBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
private string? _MeterName;
|
||||
/// <summary>
|
||||
/// 仪表名称
|
||||
/// </summary>
|
||||
public string? MeterName
|
||||
{
|
||||
get { return _MeterName; }
|
||||
set { _MeterName = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _IndexNo;
|
||||
/// <summary>
|
||||
/// 序号
|
||||
/// </summary>
|
||||
public int IndexNo
|
||||
{
|
||||
get { return _IndexNo; }
|
||||
set { _IndexNo = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
private double _Alarm;
|
||||
/// <summary>
|
||||
/// Alarm
|
||||
/// </summary>
|
||||
public double Alarm
|
||||
{
|
||||
get { return _Alarm; }
|
||||
set { _Alarm = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace CapMachine.Wpf.Dtos
|
||||
/// <summary>
|
||||
/// 吸气压力 信息
|
||||
/// </summary>
|
||||
[Column("吸气压力(MpaA)")]
|
||||
[Column("吸气压力(BarA)")]
|
||||
public double InhPress
|
||||
{
|
||||
get { return _InhPress; }
|
||||
@@ -81,7 +81,7 @@ namespace CapMachine.Wpf.Dtos
|
||||
/// <summary>
|
||||
/// 排气压力 信息
|
||||
/// </summary>
|
||||
[Column("排气压力(MpaA)")]
|
||||
[Column("排气压力(BarA)")]
|
||||
public double ExPress
|
||||
{
|
||||
get { return _ExPress; }
|
||||
@@ -125,7 +125,7 @@ namespace CapMachine.Wpf.Dtos
|
||||
/// <summary>
|
||||
/// COND2压力 信息
|
||||
/// </summary>
|
||||
[Column("COND2压力(MpaA)")]
|
||||
[Column("COND2压力(BarA)")]
|
||||
public double Cond2Press
|
||||
{
|
||||
get { return _Cond2Press; }
|
||||
@@ -158,7 +158,7 @@ namespace CapMachine.Wpf.Dtos
|
||||
/// <summary>
|
||||
/// 润滑油压力 信息
|
||||
/// </summary>
|
||||
[Column("润滑油压力(MpaA)")]
|
||||
[Column("润滑油压力(BarA)")]
|
||||
public double LubePress
|
||||
{
|
||||
get { return _LubePress; }
|
||||
|
||||
1
CapMachine.Wpf/Key/License.txt
Normal file
1
CapMachine.Wpf/Key/License.txt
Normal file
@@ -0,0 +1 @@
|
||||
4YAnXbKQ4mYv98fudLHlX+v6Ch+bdIjCoBKjtVYjZE1iPTysc4+zSUmoGIOX9AVjgAAGb7PWhXmsi6uCFmqeIMCt36tI+wzc3DBLOZ1f7zMVV5NagnxTqAAEzx1bUjJq9RK7LKdEoyIJhlddzRMRyZbVgLkCpToHcCGslOuMV6zvcdY0qUpvGeQGvwD7OxEBMXeJu8JGXjlZBjcDAknRCgFSDCtuuEVnXKnE2GjaggpjuTiz7gnMtT2rvnIKSnh9F8IVRWt+Ypbc++WjJiSksePrMidnkvbKK7rAMuUDTbtuZv+7oupWhFHLVlXd7ZGs5lKlfX64kmjJbeVZDU7MD52bbKcnxLJ9JU/bzoPHXxZXhy3Md2N46ZRPC275EsNPMatk5NU/GmGVkzrNDJ0yfH02VTEgi2JQoSgZl+kIWjw72yFfL90vABPh//HmYEYbelvc+K1VArJjgRNh0mpZ6qpK
|
||||
1
CapMachine.Wpf/Key/PublicKey.xml
Normal file
1
CapMachine.Wpf/Key/PublicKey.xml
Normal file
@@ -0,0 +1 @@
|
||||
<RSAKeyValue><Modulus>2avWQrPnade3HmX7dGML8n/YD5aTA3C7hhaFRETpBiV8/KEQnG6M0If2WgTiUNAyFjXI6cYUro8Q1NDy6PSmqgoQbCDyMGiT22K9DlMdcBC3SSot+pA+Wr9A1tOnuyQibFi43BFL1ZBgsn39rNbklUehncrZbyT7Rnl+q3jxYyE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
|
||||
@@ -20,9 +20,9 @@ namespace CapMachine.Wpf.Models
|
||||
public string WorkDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间
|
||||
/// 时间信息
|
||||
/// </summary>
|
||||
[Name("时间")]
|
||||
[Name("时间信息")]
|
||||
public string Time { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -33,339 +33,267 @@ namespace CapMachine.Wpf.Models
|
||||
|
||||
/// <summary>
|
||||
/// 转速[rpm]
|
||||
/// V
|
||||
/// </summary>
|
||||
[Name("转速[rpm]")]
|
||||
public int Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排气压力[MpaA]
|
||||
/// V
|
||||
/// 排气压力[BarA]
|
||||
/// </summary>
|
||||
[Name("排气压力[MpaA]")]
|
||||
[Name("排气压力[BarA]")]
|
||||
public double ExPress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吸气压力[MpaA]
|
||||
/// V
|
||||
/// 吸气压力[BarA]
|
||||
/// </summary>
|
||||
[Name("吸气压力[MpaA]")]
|
||||
[Name("吸气压力[BarA]")]
|
||||
public double InhPress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吸气温度[℃]
|
||||
/// V
|
||||
/// </summary>
|
||||
[Name("吸气温度[℃]")]
|
||||
public double InhTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 冷凝器出口水温[℃]
|
||||
/// V COND1水温
|
||||
/// COND1温度[℃]
|
||||
/// </summary>
|
||||
[Name("冷凝器出口水温[℃]")]
|
||||
[Name("COND1温度[℃]")]
|
||||
public double Cond1Temp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 润滑油压力[MpaA]
|
||||
///// </summary>
|
||||
//[Name("润滑油压力[MpaA]")]
|
||||
//public double LubePress { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// COND2压力[MpaA]
|
||||
///// </summary>
|
||||
//[Name("COND2压力[MpaA]")]
|
||||
//public double Cond2Press { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// OCR[%]
|
||||
///// </summary>
|
||||
//[Name("OCR[%]")]
|
||||
//public double OCR { get; set; }
|
||||
/// <summary>
|
||||
/// 润滑油压力[BarA]
|
||||
/// </summary>
|
||||
[Name("润滑油压力[BarA]")]
|
||||
public double LubePress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///HV_V[V] HV[V]
|
||||
/// V
|
||||
/// COND2压力[BarA]
|
||||
/// </summary>
|
||||
[Name("HV_V[V]")]
|
||||
[Name("COND2压力[BarA]")]
|
||||
public double Cond2Press { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OCR[%]
|
||||
/// </summary>
|
||||
[Name("OCR[%]")]
|
||||
public double OCR { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// HV[V]
|
||||
/// </summary>
|
||||
[Name("HV[V]")]
|
||||
public double HV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// HV_A[A] HV[A]
|
||||
/// V
|
||||
/// HV[A]
|
||||
/// </summary>
|
||||
[Name("HV_A[A]")]
|
||||
[Name("HV[A]")]
|
||||
public double HVCur { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///HV_W[W] HV[W]
|
||||
/// V
|
||||
/// HV[W]
|
||||
/// </summary>
|
||||
[Name("HV_W[W]")]
|
||||
[Name("HV[W]")]
|
||||
public double HVPw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///LV_V[V] LV[V]
|
||||
/// V
|
||||
/// LV[V]
|
||||
/// </summary>
|
||||
[Name("LV_V[V]")]
|
||||
[Name("LV[V]")]
|
||||
public double LV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///LV_A[A] LV[A]
|
||||
/// V
|
||||
/// LV[A]
|
||||
/// </summary>
|
||||
[Name("LV_A[A]")]
|
||||
[Name("LV[A]")]
|
||||
public double LVCur { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 试验箱温度[℃] 环境温度[℃]
|
||||
/// V
|
||||
/// 环境温度[℃]
|
||||
/// </summary>
|
||||
[Name("试验箱温度[℃]")]
|
||||
[Name("环境温度[℃]")]
|
||||
public double EnvTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 试验箱湿度[%] 环境湿度[%]
|
||||
/// V
|
||||
/// 环境湿度[%]
|
||||
/// </summary>
|
||||
[Name("试验箱湿度[%]")]
|
||||
[Name("环境湿度[%]")]
|
||||
public double EnvRH { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// OS1温度[℃]
|
||||
///// </summary>
|
||||
//[Name("OS1温度[℃]")]
|
||||
//public double OS1Temp { get; set; }
|
||||
/// <summary>
|
||||
/// OS1温度[℃]
|
||||
/// </summary>
|
||||
[Name("OS1温度[℃]")]
|
||||
public double OS1Temp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吸气混合器温度[℃] OS2温度[℃]
|
||||
/// V
|
||||
/// OS2温度[℃]
|
||||
/// </summary>
|
||||
[Name("吸气混合器温度[℃]")]
|
||||
[Name("OS2温度[℃]")]
|
||||
public double OS2Temp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// COND2温度[℃]
|
||||
///// </summary>
|
||||
//[Name("COND2温度[℃]")]
|
||||
//public double Cond2Temp { get; set; }
|
||||
/// <summary>
|
||||
/// COND2温度[℃]
|
||||
/// </summary>
|
||||
[Name("COND2温度[℃]")]
|
||||
public double Cond2Temp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// EVAP出口温度[℃]
|
||||
///// </summary>
|
||||
//[Name("EVAP出口温度[℃]")]
|
||||
//public double EVAPExpTemp { get; set; }
|
||||
/// <summary>
|
||||
/// EVAP出口温度[℃]
|
||||
/// </summary>
|
||||
[Name("EVAP出口温度[℃]")]
|
||||
public double EVAPExpTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 冷媒流量[L/min]
|
||||
///// </summary>
|
||||
//[Name("冷媒流量[L/min]")]
|
||||
//public double VRV { get; set; }
|
||||
/// <summary>
|
||||
/// 冷媒流量[L/min]
|
||||
/// </summary>
|
||||
[Name("冷媒流量[L/min]")]
|
||||
public double VRV { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 润滑油流量[L/min]
|
||||
///// </summary>
|
||||
//[Name("润滑油流量[L/min]")]
|
||||
//public double LubeFlow { get; set; }
|
||||
/// <summary>
|
||||
/// 润滑油流量[L/min]
|
||||
/// </summary>
|
||||
[Name("润滑油流量[L/min]")]
|
||||
public double LubeFlow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排气温度[℃]
|
||||
/// V
|
||||
/// </summary>
|
||||
[Name("排气温度[℃]")]
|
||||
public double ExTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 膨胀阀前压力[MpaA]
|
||||
/// V
|
||||
/// 膨胀阀前压力[BarA]
|
||||
/// </summary>
|
||||
[Name("膨胀阀前压力[MpaA]")]
|
||||
[Name("膨胀阀前压力[BarA]")]
|
||||
public double TxvFrPress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 膨胀阀前温度[℃]
|
||||
/// V
|
||||
/// </summary>
|
||||
[Name("膨胀阀前温度[℃]")]
|
||||
public double TxvFrTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 冷凝器进口温度[℃]
|
||||
/// V
|
||||
/// EVAP出口压力[BarA]
|
||||
/// </summary>
|
||||
[Name("冷凝器进口温度[℃]")]
|
||||
public double CondInTemp { get; set; }
|
||||
[Name("EVAP出口压力[BarA]")]
|
||||
public double EVAPExpPress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 冷凝器进口压力[MpaA]
|
||||
/// V
|
||||
/// 腔内压力[BarA]
|
||||
/// </summary>
|
||||
[Name("冷凝器进口压力[MpaA]")]
|
||||
public double CondInPress { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// EVAP出口压力[MpaA]
|
||||
///// </summary>
|
||||
//[Name("EVAP出口压力[MpaA]")]
|
||||
//public double EVAPExpPress { get; set; }
|
||||
[Name("腔内压力[BarA]")]
|
||||
public double IntrplPress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 水箱进水温度[℃]
|
||||
/// V
|
||||
/// 压缩机表面温度[℃]
|
||||
/// </summary>
|
||||
[Name("水箱进水温度[℃]")]
|
||||
public double WaterTankInTemp { get; set; }
|
||||
[Name("压缩机表面温度[℃]")]
|
||||
public double CapSurfTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 水加热温度H1[℃]
|
||||
/// V
|
||||
/// PTC流量[L/min]
|
||||
/// </summary>
|
||||
[Name("水加热温度H1[℃]")]
|
||||
public double WaterHeatTempH1 { get; set; }
|
||||
[Name("PTC流量[L/min]")]
|
||||
public double PTCFlow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 压缩机表面温度1[℃]
|
||||
/// V
|
||||
/// PTC入水温度[℃]
|
||||
/// </summary>
|
||||
[Name("压缩机表面温度1[℃]")]
|
||||
public double CapSurfTemp1 { get; set; }
|
||||
[Name("PTC入水温度[℃]")]
|
||||
public double PTCEntTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 压缩机表面温度2[℃]
|
||||
/// V
|
||||
/// PTC出水温度[℃]
|
||||
/// </summary>
|
||||
[Name("压缩机表面温度2[℃]")]
|
||||
public double CapSurfTemp2 { get; set; }
|
||||
[Name("PTC出水温度[℃]")]
|
||||
public double PTCExpTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 压缩机表面温度3[℃]
|
||||
/// V
|
||||
/// AT04_01[℃]
|
||||
/// </summary>
|
||||
[Name("压缩机表面温度3[℃]")]
|
||||
public double CapSurfTemp3 { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 腔内压力[MpaA]
|
||||
///// </summary>
|
||||
//[Name("腔内压力[MpaA]")]
|
||||
//public double IntrplPress { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 压缩机表面温度[℃]
|
||||
///// </summary>
|
||||
//[Name("压缩机表面温度[℃]")]
|
||||
//public double CapSurfTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// PTC流量[L/min]
|
||||
///// </summary>
|
||||
//[Name("PTC流量[L/min]")]
|
||||
//public double PTCFlow { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// PTC入水温度[℃]
|
||||
///// </summary>
|
||||
//[Name("PTC入水温度[℃]")]
|
||||
//public double PTCEntTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// PTC出水温度[℃]
|
||||
///// </summary>
|
||||
//[Name("PTC出水温度[℃]")]
|
||||
//public double PTCExpTemp { get; set; }
|
||||
[Name("AT04_01[℃]")]
|
||||
public double AT04_01Temp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯母线电流[A] 通讯Cmp母线电流[A]
|
||||
/// V
|
||||
/// AT04_02[℃]
|
||||
/// </summary>
|
||||
[Name("通讯母线电流[A]")]
|
||||
[Name("AT04_02[℃]")]
|
||||
public double AT04_02Temp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯Cmp母线电流[A]
|
||||
/// </summary>
|
||||
[Name("通讯Cmp母线电流[A]")]
|
||||
public double ComCapBusCur { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯母线电压[V] 通讯Cmp母线电压[V]
|
||||
/// V
|
||||
/// 通讯Cmp母线电压[V]
|
||||
/// </summary>
|
||||
[Name("通讯母线电压[V]")]
|
||||
[Name("通讯Cmp母线电压[V]")]
|
||||
public double ComCapBusVol { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯Cmp逆变器温度[℃]
|
||||
///// </summary>
|
||||
//[Name("通讯Cmp逆变器温度[℃]")]
|
||||
//public double ComCapInvTemp { get; set; }
|
||||
/// <summary>
|
||||
/// 通讯Cmp逆变器温度[℃]
|
||||
/// </summary>
|
||||
[Name("通讯Cmp逆变器温度[℃]")]
|
||||
public double ComCapInvTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯相电流[A] 通讯Cmp相电流[A]
|
||||
/// V
|
||||
/// 通讯Cmp相电流[A]
|
||||
/// </summary>
|
||||
[Name("通讯相电流[A]")]
|
||||
[Name("通讯Cmp相电流[A]")]
|
||||
public double ComCapPhCur { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯功率[W] 通讯Cmp功率[W]
|
||||
/// V
|
||||
/// 通讯Cmp功率[W]
|
||||
/// </summary>
|
||||
[Name("通讯功率[W]")]
|
||||
[Name("通讯Cmp功率[W]")]
|
||||
public double ComCapPw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯芯片温度[℃] 通讯Cmp芯片温度[℃]
|
||||
/// V
|
||||
/// 通讯Cmp芯片温度[℃]
|
||||
/// </summary>
|
||||
[Name("通讯芯片温度[℃]")]
|
||||
[Name("通讯Cmp芯片温度[℃]")]
|
||||
public double ComCapChipTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯PTC入水温度[℃]
|
||||
///// </summary>
|
||||
//[Name("通讯PTC入水温度[℃]")]
|
||||
//public double ComPTCEntTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯PTC出水温度[℃]
|
||||
///// </summary>
|
||||
//[Name("通讯PTC出水温度[℃]")]
|
||||
//public double ComPTCExpTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯PTC峰值电流[A]
|
||||
///// </summary>
|
||||
//[Name("通讯PTC峰值电流[A]")]
|
||||
//public double ComPTCPeakCur { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯PTC母线电流[A]
|
||||
///// </summary>
|
||||
//[Name("通讯PTC母线电流[A]")]
|
||||
//public double ComPTCBusCur { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯PTC膜温[℃]
|
||||
///// </summary>
|
||||
//[Name("通讯PTC膜温[℃]")]
|
||||
//public double ComPTCFlmTemp { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 通讯PTC模块温度[℃]
|
||||
///// </summary>
|
||||
//[Name("通讯PTC模块温度[℃]")]
|
||||
//public double ComPTCMdTemp { get; set; }
|
||||
/// <summary>
|
||||
/// 通讯PTC入水温度[℃]
|
||||
/// </summary>
|
||||
[Name("通讯PTC入水温度[℃]")]
|
||||
public double ComPTCEntTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过冷度[K]
|
||||
/// V
|
||||
/// 通讯PTC出水温度[℃]
|
||||
/// </summary>
|
||||
[Name("过冷度[K]")]
|
||||
public double Subcooling { get; set; }
|
||||
[Name("通讯PTC出水温度[℃]")]
|
||||
public double ComPTCExpTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过热度[K]
|
||||
/// V
|
||||
/// 通讯PTC峰值电流[A]
|
||||
/// </summary>
|
||||
[Name("过热度[K]")]
|
||||
public double Superheat { get; set; }
|
||||
[Name("通讯PTC峰值电流[A]")]
|
||||
public double ComPTCPeakCur { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯PTC母线电流[A]
|
||||
/// </summary>
|
||||
[Name("通讯PTC母线电流[A]")]
|
||||
public double ComPTCBusCur { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯PTC膜温[℃]
|
||||
/// </summary>
|
||||
[Name("通讯PTC膜温[℃]")]
|
||||
public double ComPTCFlmTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通讯PTC模块温度[℃]
|
||||
/// </summary>
|
||||
[Name("通讯PTC模块温度[℃]")]
|
||||
public double ComPTCMdTemp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
@@ -373,7 +301,6 @@ namespace CapMachine.Wpf.Models
|
||||
[Name("创建时间")]
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
|
||||
@@ -15,107 +15,53 @@ namespace CapMachine.Wpf.Models
|
||||
{
|
||||
public CsvRecordModelMap()
|
||||
{
|
||||
//Map(m => m.WorkCond).Name("工况");
|
||||
//Map(m => m.Speed).Name("转速");
|
||||
//Map(m => m.ExPress).Name("排气压力");
|
||||
//Map(m => m.InhPress).Name("吸气压力");
|
||||
//Map(m => m.InhTemp).Name("吸气温度");
|
||||
//Map(m => m.Cond1Temp).Name("COND1温度");
|
||||
//Map(m => m.LubePress).Name("润滑油压力");
|
||||
//Map(m => m.Cond2Press).Name("COND2压力");
|
||||
//Map(m => m.OCR).Name("OCR");
|
||||
//Map(m => m.HV).Name("HV");
|
||||
//Map(m => m.HVCur).Name("HV电流");
|
||||
//Map(m => m.HVPw).Name("HV功率");
|
||||
//Map(m => m.LV).Name("LV");
|
||||
//Map(m => m.LVCur).Name("LV电流");
|
||||
//Map(m => m.EnvTemp).Name("环境温度");
|
||||
//Map(m => m.EnvRH).Name("环境湿度");
|
||||
//Map(m => m.OS1Temp).Name("OS1温度");
|
||||
//Map(m => m.OS2Temp).Name("OS2温度");
|
||||
//Map(m => m.Cond2Temp).Name("COND2温度");
|
||||
//Map(m => m.EVAPExpTemp).Name("EVAP出口温度");
|
||||
//Map(m => m.VRV).Name("冷媒流量");
|
||||
//Map(m => m.LubeFlow).Name("润滑油流量");
|
||||
//Map(m => m.ExTemp).Name("排气温度");
|
||||
//Map(m => m.TxvFrPress).Name("膨胀阀前压力");
|
||||
//Map(m => m.TxvFrTemp).Name("膨胀阀前温度");
|
||||
//Map(m => m.EVAPExpPress).Name("EVAP出口压力");
|
||||
//Map(m => m.IntrplPress).Name("腔内压力");
|
||||
//Map(m => m.CapSurfTemp).Name("压缩机表面温度");
|
||||
//Map(m => m.PTCFlow).Name("PTC流量");
|
||||
//Map(m => m.PTCEntTemp).Name("PTC入水温度");
|
||||
//Map(m => m.PTCExpTemp).Name("PTC出水温度");
|
||||
//Map(m => m.ComCapBusCur).Name("通讯Cmp母线电流");
|
||||
//Map(m => m.ComCapBusVol).Name("通讯Cmp母线电压");
|
||||
//Map(m => m.ComCapInvTemp).Name("通讯Cmp逆变器温度");
|
||||
//Map(m => m.ComCapPhCur).Name("通讯Cmp相电流");
|
||||
//Map(m => m.ComCapPw).Name("通讯Cmp功率");
|
||||
//Map(m => m.ComCapChipTemp).Name("通讯Cmp芯片温度");
|
||||
//Map(m => m.ComPTCEntTemp).Name("通讯PTC入水温度");
|
||||
//Map(m => m.ComPTCExpTemp).Name("通讯PTC出水温度");
|
||||
//Map(m => m.ComPTCPeakCur).Name("通讯PTC峰值电流");
|
||||
//Map(m => m.ComPTCBusCur).Name("通讯PTC母线电流");
|
||||
//Map(m => m.ComPTCFlmTemp).Name("通讯PTC膜温");
|
||||
//Map(m => m.ComPTCMdTemp).Name("通讯PTC模块温度");
|
||||
//Map(m => m.CreateTime).Name("时间");
|
||||
|
||||
Map(m => m.WorkDay).Name("日期");
|
||||
Map(m => m.Time).Name("时间");
|
||||
Map(m => m.Time).Name("时间信息");
|
||||
Map(m => m.WorkCond).Name("工况");
|
||||
Map(m => m.Speed).Name("转速[rpm]");
|
||||
Map(m => m.ExPress).Name("排气压力[MpaA]");
|
||||
Map(m => m.InhPress).Name("吸气压力[MpaA]");
|
||||
Map(m => m.ExPress).Name("排气压力[BarA]");
|
||||
Map(m => m.InhPress).Name("吸气压力[BarA]");
|
||||
Map(m => m.InhTemp).Name("吸气温度[℃]");
|
||||
Map(m => m.Cond1Temp).Name("冷凝器出口水温[℃]");
|
||||
Map(m => m.OS2Temp).Name("吸气混合器温度[℃]");
|
||||
Map(m => m.HV).Name("HV_V[V]");
|
||||
Map(m => m.HVCur).Name("HV_A[A]");
|
||||
Map(m => m.HVPw).Name("HV_W[W]");
|
||||
Map(m => m.LV).Name("LV_V[V]");
|
||||
Map(m => m.LVCur).Name("LV_A[A]");
|
||||
Map(m => m.EnvTemp).Name("试验箱温度[℃]");
|
||||
Map(m => m.EnvRH).Name("试验箱湿度[%]");
|
||||
Map(m => m.Cond1Temp).Name("COND1温度[℃]");
|
||||
Map(m => m.LubePress).Name("润滑油压力[BarA]");
|
||||
Map(m => m.Cond2Press).Name("COND2压力[BarA]");
|
||||
Map(m => m.OCR).Name("OCR[%]");
|
||||
Map(m => m.HV).Name("HV[V]");
|
||||
Map(m => m.HVCur).Name("HV[A]");
|
||||
Map(m => m.HVPw).Name("HV[W]");
|
||||
Map(m => m.LV).Name("LV[V]");
|
||||
Map(m => m.LVCur).Name("LV[A]");
|
||||
Map(m => m.EnvTemp).Name("环境温度[℃]");
|
||||
Map(m => m.EnvRH).Name("环境湿度[%]");
|
||||
Map(m => m.OS1Temp).Name("OS1温度[℃]");
|
||||
Map(m => m.OS2Temp).Name("OS2温度[℃]");
|
||||
Map(m => m.Cond2Temp).Name("COND2温度[℃]");
|
||||
Map(m => m.EVAPExpTemp).Name("EVAP出口温度[℃]");
|
||||
Map(m => m.VRV).Name("冷媒流量[L/min]");
|
||||
Map(m => m.LubeFlow).Name("润滑油流量[L/min]");
|
||||
Map(m => m.ExTemp).Name("排气温度[℃]");
|
||||
Map(m => m.TxvFrPress).Name("膨胀阀前压力[MpaA]");
|
||||
Map(m => m.TxvFrPress).Name("膨胀阀前压力[BarA]");
|
||||
Map(m => m.TxvFrTemp).Name("膨胀阀前温度[℃]");
|
||||
|
||||
Map(m => m.CondInTemp).Name("冷凝器进口温度[℃]");
|
||||
Map(m => m.CondInPress).Name("冷凝器进口压力[MpaA]");
|
||||
Map(m => m.WaterTankInTemp).Name("水箱进水温度[℃]");
|
||||
Map(m => m.WaterHeatTempH1).Name("水加热温度H1[℃]");
|
||||
Map(m => m.CapSurfTemp1).Name("压缩机表面温度1[℃]");
|
||||
Map(m => m.CapSurfTemp2).Name("压缩机表面温度2[℃]");
|
||||
Map(m => m.CapSurfTemp3).Name("压缩机表面温度3[℃]");
|
||||
|
||||
//Map(m => m.LubePress).Name("润滑油压力[MpaA]");
|
||||
//Map(m => m.Cond2Press).Name("COND2压力[MpaA]");
|
||||
//Map(m => m.OCR).Name("OCR[%]");
|
||||
//Map(m => m.OS1Temp).Name("OS1温度[℃]");
|
||||
//Map(m => m.Cond2Temp).Name("COND2温度[℃]");
|
||||
//Map(m => m.EVAPExpTemp).Name("EVAP出口温度[℃]");
|
||||
//Map(m => m.VRV).Name("冷媒流量[L/min]");
|
||||
//Map(m => m.LubeFlow).Name("润滑油流量[L/min]");
|
||||
//Map(m => m.EVAPExpPress).Name("EVAP出口压力[MpaA]");
|
||||
//Map(m => m.IntrplPress).Name("腔内压力[MpaA]");
|
||||
//Map(m => m.CapSurfTemp).Name("压缩机表面温度[℃]");
|
||||
//Map(m => m.PTCFlow).Name("PTC流量[L/min]");
|
||||
//Map(m => m.PTCEntTemp).Name("PTC入水温度[℃]");
|
||||
//Map(m => m.PTCExpTemp).Name("PTC出水温度[℃]");
|
||||
Map(m => m.ComCapBusCur).Name("通讯母线电流[A]");
|
||||
Map(m => m.ComCapBusVol).Name("通讯母线电压[V]");
|
||||
//Map(m => m.ComCapInvTemp).Name("通讯Cmp逆变器温度[℃]");
|
||||
Map(m => m.ComCapPhCur).Name("通讯相电流[A]");
|
||||
Map(m => m.ComCapPw).Name("通讯功率[W]");
|
||||
Map(m => m.ComCapChipTemp).Name("通讯芯片温度[℃]");
|
||||
Map(m => m.Subcooling).Name("过冷度[K]");
|
||||
Map(m => m.Superheat).Name("过热度[K]");
|
||||
//Map(m => m.ComPTCEntTemp).Name("通讯PTC入水温度[℃]");
|
||||
//Map(m => m.ComPTCExpTemp).Name("通讯PTC出水温度[℃]");
|
||||
//Map(m => m.ComPTCPeakCur).Name("通讯PTC峰值电流[A]");
|
||||
//Map(m => m.ComPTCBusCur).Name("通讯PTC母线电流[A]");
|
||||
//Map(m => m.ComPTCFlmTemp).Name("通讯PTC膜温[℃]");
|
||||
//Map(m => m.ComPTCMdTemp).Name("通讯PTC模块温度[℃]");
|
||||
Map(m => m.EVAPExpPress).Name("EVAP出口压力[BarA]");
|
||||
Map(m => m.IntrplPress).Name("腔内压力[BarA]");
|
||||
Map(m => m.CapSurfTemp).Name("压缩机表面温度[℃]");
|
||||
Map(m => m.PTCFlow).Name("PTC流量[L/min]");
|
||||
Map(m => m.PTCEntTemp).Name("PTC入水温度[℃]");
|
||||
Map(m => m.PTCExpTemp).Name("PTC出水温度[℃]");
|
||||
Map(m => m.AT04_01Temp).Name("AT04_01[℃]");
|
||||
Map(m => m.AT04_02Temp).Name("AT04_02[℃]");
|
||||
Map(m => m.ComCapBusCur).Name("通讯Cmp母线电流[A]");
|
||||
Map(m => m.ComCapBusVol).Name("通讯Cmp母线电压[V]");
|
||||
Map(m => m.ComCapInvTemp).Name("通讯Cmp逆变器温度[℃]");
|
||||
Map(m => m.ComCapPhCur).Name("通讯Cmp相电流[A]");
|
||||
Map(m => m.ComCapPw).Name("通讯Cmp功率[W]");
|
||||
Map(m => m.ComCapChipTemp).Name("通讯Cmp芯片温度[℃]");
|
||||
Map(m => m.ComPTCEntTemp).Name("通讯PTC入水温度[℃]");
|
||||
Map(m => m.ComPTCExpTemp).Name("通讯PTC出水温度[℃]");
|
||||
Map(m => m.ComPTCPeakCur).Name("通讯PTC峰值电流[A]");
|
||||
Map(m => m.ComPTCBusCur).Name("通讯PTC母线电流[A]");
|
||||
Map(m => m.ComPTCFlmTemp).Name("通讯PTC膜温[℃]");
|
||||
Map(m => m.ComPTCMdTemp).Name("通讯PTC模块温度[℃]");
|
||||
Map(m => m.CreateTime).Name("时间");
|
||||
|
||||
|
||||
|
||||
@@ -203,111 +203,92 @@ namespace CapMachine.Wpf.Models.LightChart
|
||||
{
|
||||
case "转速[rpm]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Speed, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "排气压力[MpaA]":
|
||||
case "排气压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ExPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "吸气压力[MpaA]":
|
||||
case "吸气压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.InhPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "吸气温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.InhTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "冷凝器出口水温[℃]":
|
||||
case "COND1温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Cond1Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "润滑油压力[MpaA]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.LubePress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "COND2压力[MpaA]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.Cond2Press, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "OCR[%]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.OCR, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "HV_V[V]":
|
||||
case "润滑油压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.LubePress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "COND2压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Cond2Press, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "OCR[%]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.OCR, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "HV[V]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.HV, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "HV_A[A]":
|
||||
case "HV[A]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.HVCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "HV_W[W]":
|
||||
case "HV[W]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.HVPw, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "LV_V[V]":
|
||||
case "LV[V]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.LV, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "LV_A[A]":
|
||||
case "LV[A]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.LVCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "试验箱温度[℃]":
|
||||
case "环境温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.EnvTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "试验箱湿度[%]":
|
||||
case "环境湿度[%]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.EnvRH, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "OS1温度[℃]":
|
||||
//return CurHistoryData.Select(a => new ChartPoint() { Value = a.OS1Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "吸气混合器温度[℃]":
|
||||
case "OS1温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.OS1Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "OS2温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.OS2Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "COND2温度[℃]":
|
||||
//return CurHistoryData.Select(a => new ChartPoint() { Value = a.Cond2Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "EVAP出口温度[℃]":
|
||||
//return CurHistoryData.Select(a => new ChartPoint() { Value = a.EVAPExpTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "冷媒流量[L/min]":
|
||||
//return CurHistoryData.Select(a => new ChartPoint() { Value = a.VRV, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "润滑油流量[L/min]":
|
||||
//return CurHistoryData.Select(a => new ChartPoint() { Value = a.LubeFlow, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "COND2温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Cond2Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "EVAP出口温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.EVAPExpTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "冷媒流量[L/min]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.VRV, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "润滑油流量[L/min]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.LubeFlow, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "排气温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ExTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "膨胀阀前压力[MpaA]":
|
||||
case "膨胀阀前压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.TxvFrPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "膨胀阀前温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.TxvFrTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "EVAP出口压力[MpaA]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.EVAPExpPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "腔内压力[MpaA]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.IntrplPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "压缩机表面温度[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.CapSurfTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "PTC流量[L/min]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.PTCFlow, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "PTC入水温度[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.PTCEntTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "PTC出水温度[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.PTCExpTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯母线电流[A]":
|
||||
case "EVAP出口压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.EVAPExpPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "腔内压力[BarA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.IntrplPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "压缩机表面温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.CapSurfTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "PTC流量[L/min]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.PTCFlow, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "PTC入水温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.PTCEntTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "PTC出水温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.PTCExpTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "AT04_01[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.AT04_01Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "AT04_02[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.AT04_02Temp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯Cmp母线电流[A]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapBusCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯母线电压[V]":
|
||||
case "通讯Cmp母线电压[V]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapBusVol, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯Cmp逆变器温度[℃]":
|
||||
//return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapInvTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯相电流[A]":
|
||||
case "通讯Cmp逆变器温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapInvTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯Cmp相电流[A]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapPhCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯功率[W]":
|
||||
case "通讯Cmp功率[W]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapPw, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯芯片温度[℃]":
|
||||
case "通讯Cmp芯片温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComCapChipTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯PTC入水温度[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCEntTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯PTC出水温度[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCExpTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯PTC峰值电流[A]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCPeakCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯PTC母线电流[A]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCBusCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯PTC膜温[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCFlmTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
//case "通讯PTC模块温度[℃]":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCMdTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
|
||||
//case "XXXX":
|
||||
// return CurHistoryData.Select(a => new ChartPoint() { Value = a.XXXX, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
|
||||
case "冷凝器进口温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.CondInTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "冷凝器进口压力[MpaA]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.CondInPress, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "水箱进水温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.WaterTankInTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "水加热温度H1[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.WaterHeatTempH1, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "压缩机表面温度1[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.CapSurfTemp1, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "压缩机表面温度2[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.CapSurfTemp2, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "压缩机表面温度3[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.CapSurfTemp3, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "过热度[K]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Superheat, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "过冷度[K]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Subcooling, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
|
||||
case "通讯PTC入水温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCEntTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯PTC出水温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCExpTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯PTC峰值电流[A]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCPeakCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯PTC母线电流[A]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCBusCur, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯PTC膜温[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCFlmTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
case "通讯PTC模块温度[℃]":
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.ComPTCMdTemp, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
default:
|
||||
return CurHistoryData.Select(a => new ChartPoint() { Value = a.Speed, Time = a.CreateTime }).OrderBy(a => a.Time).ToList();
|
||||
break;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CapMachine.Model;
|
||||
using CapMachine.Wpf.Models.ProModelPars;
|
||||
using HslCommunication;
|
||||
using Prism.Mvvm;
|
||||
|
||||
@@ -17,12 +18,12 @@ namespace CapMachine.Wpf.Models
|
||||
/// </summary>
|
||||
public MeterRtDataModel()
|
||||
{
|
||||
ListProStepExecuteInfo = new List<ProStepExecute>();
|
||||
ListProStepExecuteInfo = new List<ProStepExe>();
|
||||
ListQuickProStepExecuteInfo = new List<QuickProStepExecute>();
|
||||
QuickRunTimeInfo = new QuickRunTime();
|
||||
QuickNextMeterStep = new QuickProStepExecute();
|
||||
RunTimeInfo = new MeterRunTime();
|
||||
NextMeterStep = new ProStepExecute();
|
||||
NextMeterStep = new ProStepExe();
|
||||
|
||||
}
|
||||
|
||||
@@ -252,7 +253,7 @@ namespace CapMachine.Wpf.Models
|
||||
/// <summary>
|
||||
/// 程序段和程序步骤执行具体方法
|
||||
/// </summary>
|
||||
public List<ProStepExecute> ListProStepExecuteInfo { get; set; }
|
||||
public List<ProStepExe> ListProStepExecuteInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 快速设置程序段和程序步骤执行具体方法
|
||||
@@ -277,7 +278,7 @@ namespace CapMachine.Wpf.Models
|
||||
/// <summary>
|
||||
/// 仪表下一步具体程序步骤
|
||||
/// </summary>
|
||||
public ProStepExecute NextMeterStep { get; set; }
|
||||
public ProStepExe NextMeterStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quick仪表下一步具体程序步骤
|
||||
|
||||
30
CapMachine.Wpf/Models/PlcLoadConfigCell.cs
Normal file
30
CapMachine.Wpf/Models/PlcLoadConfigCell.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC加载配置单元
|
||||
/// 下载PLC数据,用整型的数据下载,但是我们这边可能是浮点数,需要格式的转换,精度的转换
|
||||
/// </summary>
|
||||
public class PlcLoadConfigCell
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置字段 名称
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
public string? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 精度 1,10,100,1000
|
||||
/// </summary>
|
||||
public int Precision { get; set; }
|
||||
}
|
||||
}
|
||||
13
CapMachine.Wpf/Models/ProModelPars/Alarm.cs
Normal file
13
CapMachine.Wpf/Models/ProModelPars/Alarm.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
public class Alarm
|
||||
{
|
||||
public double AlarmValue { get; set; }
|
||||
}
|
||||
}
|
||||
26
CapMachine.Wpf/Models/ProModelPars/Limit.cs
Normal file
26
CapMachine.Wpf/Models/ProModelPars/Limit.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载时用的Limit
|
||||
/// 进制和精度也需要处理好
|
||||
/// </summary>
|
||||
public class Limit
|
||||
{
|
||||
/// <summary>
|
||||
/// Limit-Up
|
||||
/// </summary>
|
||||
public short Up { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit-Down
|
||||
/// </summary>
|
||||
public short Down { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
32
CapMachine.Wpf/Models/ProModelPars/PID.cs
Normal file
32
CapMachine.Wpf/Models/ProModelPars/PID.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载时用的PID
|
||||
/// 进制也需要处理好
|
||||
/// </summary>
|
||||
public class PID
|
||||
{
|
||||
/// <summary>
|
||||
/// PID-P
|
||||
/// </summary>
|
||||
public short P { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID-I
|
||||
/// </summary>
|
||||
public short I { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// PID-D
|
||||
/// </summary>
|
||||
public short D { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
39
CapMachine.Wpf/Models/ProModelPars/ParsConfigLimitDto.cs
Normal file
39
CapMachine.Wpf/Models/ProModelPars/ParsConfigLimitDto.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置限制Dto
|
||||
/// </summary>
|
||||
public class ParsConfigLimitDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置仪表名称
|
||||
/// </summary>
|
||||
public string? MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 序号
|
||||
/// </summary>
|
||||
public int IndexNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上限
|
||||
/// </summary>
|
||||
public decimal Up { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下限
|
||||
/// </summary>
|
||||
public decimal Down { get; set; }
|
||||
}
|
||||
}
|
||||
44
CapMachine.Wpf/Models/ProModelPars/ParsConfigPIDDto.cs
Normal file
44
CapMachine.Wpf/Models/ProModelPars/ParsConfigPIDDto.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// PID 配置模型Dto
|
||||
/// </summary>
|
||||
public class ParsConfigPIDDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置仪表名称
|
||||
/// </summary>
|
||||
public string? MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 序号
|
||||
/// </summary>
|
||||
public int IndexNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// P
|
||||
/// </summary>
|
||||
public decimal P { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// I
|
||||
/// </summary>
|
||||
public int I { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// D
|
||||
/// </summary>
|
||||
public int D { get; set; }
|
||||
}
|
||||
}
|
||||
401
CapMachine.Wpf/Models/ProModelPars/ProExModel.cs
Normal file
401
CapMachine.Wpf/Models/ProModelPars/ProExModel.cs
Normal file
@@ -0,0 +1,401 @@
|
||||
using CapMachine.Wpf.ChannelModel;
|
||||
using CapMachine.Wpf.Services;
|
||||
using ImTools;
|
||||
using Masuit.Tools;
|
||||
using Masuit.Tools.Hardware;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序执行模型
|
||||
/// 包括程序名称和程序步骤集合、程序执行信息
|
||||
/// 一个参数(速度、排气压力)对应一个程序执行模型
|
||||
/// </summary>
|
||||
public class ProExModel : BindableBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 实例化函数
|
||||
/// </summary>
|
||||
public ProExModel(Channel<ProRunChannelData> channel)
|
||||
{
|
||||
ProRunChannel = channel;
|
||||
|
||||
//秒触发一次
|
||||
CycleTimer = new System.Timers.Timer(1000);
|
||||
CycleTimer.Elapsed += SlopExCycleAction;
|
||||
CycleTimer.AutoReset = true;
|
||||
CycleTimer.Enabled = true;
|
||||
CycleTimer.Start();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 程序执行管道
|
||||
/// </summary>
|
||||
public Channel<ProRunChannelData> ProRunChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前模型是否启用
|
||||
/// 当前有很多参数都是预设,但是有些参数是为其他的项目准备的,可能在当前的项目上都不会配置和使用。
|
||||
/// 故设置Enable属性
|
||||
/// </summary>
|
||||
public bool Enable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 程序步骤集合
|
||||
/// </summary>
|
||||
public List<ProStepExe> ListProStepExe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仪表步骤执行时间信息
|
||||
/// </summary>
|
||||
public ProRunTime ProRunTimeModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下一步步骤数据执行
|
||||
/// </summary>
|
||||
public ProStepExe NextProStepExe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤数据执行
|
||||
/// 给看步骤是否变化使用
|
||||
/// </summary>
|
||||
public ProStepExe CurProStepExe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上一步步骤数据执行
|
||||
/// 给看步骤是否变化使用
|
||||
/// </summary>
|
||||
public ProStepExe LastProStepExe { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前程序段时间长
|
||||
/// </summary>
|
||||
public int CurProTimeSum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前程序段开始时间
|
||||
/// </summary>
|
||||
public DateTime CurProStartTime { set; get; }
|
||||
|
||||
|
||||
#region 仪表步骤执行时间信息
|
||||
|
||||
public EventHandler<string> RunTimeCallSglEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
public bool RunEnable { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// RunTimeCallSglEvent 是否注册关联方法
|
||||
/// </summary>
|
||||
public bool EventRegister { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤开始运行时间
|
||||
/// </summary>
|
||||
public DateTime StepStartDt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤结束运行时间
|
||||
/// </summary>
|
||||
public DateTime StepEndDt { get; set; }
|
||||
|
||||
|
||||
private DateTime _CurrentDateTime;
|
||||
/// <summary>
|
||||
/// 当前时间
|
||||
/// </summary>
|
||||
public DateTime CurrentDateTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentDateTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
//value.ToString("yyyy-MM-dd HH:mm:ss") == EndDateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
if (RunEnable == true && value >= StepEndDt)
|
||||
{
|
||||
_CurrentDateTime = value;
|
||||
//达到后不再触发
|
||||
//RunEnable = false;
|
||||
//时间到了触发下载下一步步骤
|
||||
|
||||
//不为空的数据
|
||||
if (NextProStepExe == null)
|
||||
{
|
||||
Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{MeterName} " +
|
||||
$"【Msg】:没有下一步,当前仪表参数全部执行完毕 ");
|
||||
|
||||
//为空时不执行后续的数据
|
||||
RunEnable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{MeterName} " +
|
||||
$"【程序Seg】{CurProStepExe.ProSegName} " +
|
||||
$"【程序步骤】{CurProStepExe.MeterStep} " +
|
||||
$"【Msg】:时间到,开始执行下一步步骤 ");
|
||||
|
||||
////////首先判断参数是否相同///////////
|
||||
|
||||
var SvResult = false;//True代表不同,false代表相同
|
||||
//判断PID是否跟上一次一样
|
||||
if (CurProStepExe.EndSV != NextProStepExe.EndSV)
|
||||
{
|
||||
SvResult = true;
|
||||
}
|
||||
var PidResult = false;//True代表不同,false代表相同
|
||||
//判断PID是否跟上一次一样
|
||||
if (CurProStepExe.PIDNo != NextProStepExe.PIDNo)
|
||||
{
|
||||
PidResult = true;
|
||||
}
|
||||
var LimitResult = false;//True代表不同,false代表相同
|
||||
//判断Limit是否跟上一次一样
|
||||
if (CurProStepExe.LimitNo != NextProStepExe.LimitNo)
|
||||
{
|
||||
LimitResult = true;
|
||||
}
|
||||
|
||||
////////发送步骤信息///////////
|
||||
if (NextProStepExe.ExistSlop)
|
||||
{
|
||||
//存在坡度数据
|
||||
var SecStepDur = NextProStepExe.EndSV - NextProStepExe.StartSV;
|
||||
var SecStepValue = SecStepDur * 1.0 / NextProStepExe.KeepTime;
|
||||
//先清除数据
|
||||
ListSlopExStep.Clear();
|
||||
//组装斜坡数据,按照秒为间隔发送
|
||||
for (var i = 1; i <= NextProStepExe.KeepTime; i++)
|
||||
{
|
||||
var SlopExStep = new SlopExStep()
|
||||
{
|
||||
StepNo = i,
|
||||
SV = NextProStepExe.StartSV + (int)(SecStepValue * i),
|
||||
IsHasEx = false,
|
||||
};
|
||||
ListSlopExStep.Add(SlopExStep);
|
||||
}
|
||||
//需要发送一次StartSV数据吗?
|
||||
|
||||
//组装完成开始循环打点
|
||||
StartSlopExStep();
|
||||
|
||||
}
|
||||
else//不存在斜坡数据的话,则直接发送EndSV数据即可
|
||||
{
|
||||
ProRunChannel.Writer.TryWrite(new ProRunChannelData()
|
||||
{
|
||||
MeterName = MeterName,
|
||||
SV = NextProStepExe.EndSV,
|
||||
ProSegName = NextProStepExe.ProSegName,
|
||||
MeterStep = NextProStepExe.MeterStep,
|
||||
CurLoadLimit = LimitResult == true ? new Limit() { Up = (short)NextProStepExe.CurConfigLimitDto.Up, Down = (short)NextProStepExe.CurConfigLimitDto.Down } : new Limit(),
|
||||
CurLoadPID = PidResult == true ? new PID() { P = (short)NextProStepExe.CurConfigPIDDto.P, I = (short)NextProStepExe.CurConfigPIDDto.I, D = (short)NextProStepExe.CurConfigPIDDto.D } : new PID(),
|
||||
RunStepType = GetRunStepType(PidResult, LimitResult, true),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
////////准备新的数据///////////
|
||||
|
||||
LastProStepExe = CurProStepExe.DeepClone();
|
||||
//准备下一步步骤数据
|
||||
CurProStepExe = NextProStepExe.DeepClone();
|
||||
|
||||
//标记状态-当前执行中
|
||||
if (ListProStepExe.Where(a => a.MeterStep == CurProStepExe.MeterStep).Any())
|
||||
{
|
||||
ListProStepExe.FindFirst(a => a.MeterStep == CurProStepExe.MeterStep).MeterStepIsExeing = true;
|
||||
}
|
||||
//标记状态-上一个执行完毕标记
|
||||
if (ListProStepExe.Where(a => a.MeterStep == LastProStepExe.MeterStep).Any())
|
||||
{
|
||||
ListProStepExe.FindFirst(a => a.MeterStep == LastProStepExe.MeterStep).MeterStepIsExeing = false;
|
||||
}
|
||||
//标记状态-上一个执行完成
|
||||
if (ListProStepExe.Where(a => a.MeterStep == LastProStepExe.MeterStep).Any())
|
||||
{
|
||||
ListProStepExe.FindFirst(a => a.MeterStep == LastProStepExe.MeterStep).MeterStepIsOK = true;
|
||||
}
|
||||
|
||||
|
||||
//设置下一步步骤数据
|
||||
if (ListProStepExe.Where(x => x.MeterStep == CurProStepExe.MeterStep + 1).Any())
|
||||
{
|
||||
//存在下一步数据
|
||||
NextProStepExe = ListProStepExe.FirstOrDefault(x => x.MeterStep == CurProStepExe.MeterStep + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//没有下一步数据则判定为最后一步
|
||||
NextProStepExe = null;
|
||||
}
|
||||
|
||||
//设置步骤开始时间
|
||||
StepStartDt = DateTime.Now;
|
||||
|
||||
//设置步骤结束时间
|
||||
StepEndDt = StepStartDt.AddSeconds(CurProStepExe.KeepTime);
|
||||
|
||||
//设置下一步步骤运行时间
|
||||
RunEnable = true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_CurrentDateTime = value;
|
||||
RunTime = (int)(_CurrentDateTime - StepEndDt).TotalSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤已经运行时长-秒
|
||||
/// </summary>
|
||||
public int RunTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通过组合Pid和Limit组合出运行步骤类型
|
||||
/// </summary>
|
||||
/// <param name="pid">PID是否不同</param>
|
||||
/// <param name="limit">Limit是否不同</param>
|
||||
/// <param name="sv">SV是否不同</param>
|
||||
/// <returns>运行步骤类型</returns>
|
||||
private RunStepType GetRunStepType(bool pid, bool limit, bool sv)
|
||||
{
|
||||
if (pid && limit && sv)
|
||||
{
|
||||
return RunStepType.Step;
|
||||
}
|
||||
else if (pid && sv)
|
||||
{
|
||||
return RunStepType.StepPID;
|
||||
}
|
||||
else if (limit && sv)
|
||||
{
|
||||
return RunStepType.StepLimit;
|
||||
}
|
||||
else if (sv)
|
||||
{
|
||||
return RunStepType.StepSV;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RunStepType.Step;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 步骤斜率执行 打点执行
|
||||
|
||||
/// <summary>
|
||||
/// 开始打点执行
|
||||
/// </summary>
|
||||
private void StartSlopExStep()
|
||||
{
|
||||
SlopExEnable = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 斜率执行步骤集合
|
||||
/// 打点集合
|
||||
/// </summary>
|
||||
public List<SlopExStep> ListSlopExStep { get; set; } = new List<SlopExStep>();
|
||||
|
||||
/// <summary>
|
||||
/// 斜率执行循环周期
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void SlopExCycleAction(object? sender, ElapsedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
//如果Execute执行的是一个很耗时的方法,会导致方法未执行完毕,定时器又启动了一个线程来执行Execute方法
|
||||
//CycleTimer.Stop(); //先关闭定时器
|
||||
if (SlopExEnable)
|
||||
{
|
||||
var NoExData = ListSlopExStep.Where(a => a.IsHasEx == false).OrderBy(a => a.StepNo).ToList();
|
||||
if (NoExData.Any())
|
||||
{
|
||||
//发送步骤信息
|
||||
ProRunChannel.Writer.TryWrite(new ProRunChannelData()
|
||||
{
|
||||
MeterName = MeterName,
|
||||
SV = NoExData.First().SV,
|
||||
|
||||
ProSegName = CurProStepExe.ProSegName,
|
||||
MeterStep = CurProStepExe.MeterStep,
|
||||
SlopStepNo = NoExData.First().StepNo,
|
||||
CurLoadLimit = null,
|
||||
CurLoadPID = null,
|
||||
RunStepType = RunStepType.SlopCell,
|
||||
});
|
||||
//发送完毕后进行标记数据
|
||||
NoExData.First().IsHasEx = true;
|
||||
|
||||
Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{MeterName} " +
|
||||
$"【程序Seg】{CurProStepExe.ProSegName} " +
|
||||
$"【程序步骤】{CurProStepExe.MeterStep} " +
|
||||
$"【斜坡打点步骤】{NoExData.First().StepNo} " +
|
||||
$"【斜坡打点值SV】{NoExData.First().SV} " +
|
||||
$"【Msg】:发送斜坡打点 ");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//执行完毕了,没有要执行的数据效率
|
||||
SlopExEnable = false;
|
||||
Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{MeterName} " +
|
||||
$"【程序Seg】{CurProStepExe.ProSegName} " +
|
||||
$"【程序步骤】{CurProStepExe.MeterStep} " +
|
||||
$"【Msg】:斜坡打点执行完毕 ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//CycleTimer.Start(); //执行完毕后再开启器
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//CycleTimer.Start(); //执行完毕后再开启器
|
||||
//LogService.Info($"时间:{DateTime.Now.ToString()}-【PwAnalyze-CycleAction】-{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 周期定时器
|
||||
/// </summary>
|
||||
private System.Timers.Timer CycleTimer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 步骤斜率执行使能状态
|
||||
/// </summary>
|
||||
public bool SlopExEnable { get; set; } = false;
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
88
CapMachine.Wpf/Models/ProModelPars/ProRunTime.cs
Normal file
88
CapMachine.Wpf/Models/ProModelPars/ProRunTime.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序运行时间
|
||||
/// </summary>
|
||||
public class ProRunTime
|
||||
{
|
||||
|
||||
public EventHandler<string> RunTimeCallSglEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
public bool RunEnable { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// RunTimeCallSglEvent 是否注册关联方法
|
||||
/// </summary>
|
||||
public bool EventRegister { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 当前仪表名称
|
||||
/// </summary>
|
||||
public string MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前程序段名称
|
||||
/// </summary>
|
||||
public string ProName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前仪表程序步骤
|
||||
/// </summary>
|
||||
public int MeterStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤开始运行时间
|
||||
/// </summary>
|
||||
public DateTime StartDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤结束运行时间
|
||||
/// </summary>
|
||||
public DateTime EndDateTime { get; set; }
|
||||
|
||||
|
||||
private DateTime currentDateTime;
|
||||
/// <summary>
|
||||
/// 当前时间
|
||||
/// </summary>
|
||||
public DateTime CurrentDateTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentDateTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
//value.ToString("yyyy-MM-dd HH:mm:ss") == EndDateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
if (RunEnable == true && value >= EndDateTime)
|
||||
{
|
||||
currentDateTime = value;
|
||||
RunEnable = false;
|
||||
//时间到了触发下载新的步骤
|
||||
//RunTimeCallSglEvent(ProName, MeterName, MeterStep);
|
||||
//RunTimeCallSglEvent.BeginInvoke(ProName, MeterName, MeterStep, null, null);
|
||||
//RunEnable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDateTime = value;
|
||||
RunTime = (int)(currentDateTime - StartDateTime).TotalSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤已经运行时长-秒
|
||||
/// </summary>
|
||||
public int RunTime { get; set; }
|
||||
}
|
||||
}
|
||||
135
CapMachine.Wpf/Models/ProModelPars/ProStepExe.cs
Normal file
135
CapMachine.Wpf/Models/ProModelPars/ProStepExe.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using CapMachine.Model;
|
||||
using CapMachine.Wpf.Dtos;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序分解后的执行步骤
|
||||
/// </summary>
|
||||
public class ProStepExe : BindableBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序段名称
|
||||
/// </summary>
|
||||
public string? ProSegName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序段步骤
|
||||
/// </summary>
|
||||
public int ProSegStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序段重复执行次数
|
||||
/// </summary>
|
||||
public int ProSegRepeat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序段当前是否执行中
|
||||
/// </summary>
|
||||
public bool ProSegIsExeing { get; set; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
////////////////////////程序步骤///////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
///// <summary>
|
||||
///// 程序步骤标记
|
||||
///// </summary>
|
||||
//public StepPosMark StepPosMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仪表参数当前是否执行中
|
||||
/// </summary>
|
||||
public bool MeterStepIsExeing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仪表参数是否执行完成
|
||||
/// </summary>
|
||||
public bool MeterStepIsOK { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仪表参数名称
|
||||
/// </summary>
|
||||
public string? MeterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仪表参数步骤
|
||||
/// </summary>
|
||||
public int MeterStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 这个步骤是打开具体设置步骤界面的那个层面的信息,例如:2-3,代表是程序2里面的仪表步骤3,方便调试和给液击使用
|
||||
/// </summary>
|
||||
public string? ProStepInfo { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 启用状态-没有启用就是什么数据都没有
|
||||
///// Const-常值-常值,StepValue有值,只有一个步骤,CycleTime为0
|
||||
///// MultisStep-有步骤细节-此时在一个仪表下就会有很多步骤的细节数据
|
||||
///// </summary>
|
||||
//public ConfigValueType ConfigState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StartSV- 步骤的开始SV
|
||||
/// 最终的写到PLC结果值,经过进制转换
|
||||
/// </summary>
|
||||
public int StartSV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// EndSV- 步骤的目标SV
|
||||
/// 最终的写到PLC结果值,经过进制转换
|
||||
/// </summary>
|
||||
public int EndSV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// KeepTime Sec
|
||||
/// </summary>
|
||||
public int KeepTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用坡度
|
||||
/// 存在斜坡容易判断,非斜坡是常值
|
||||
/// 常值有两种情况:
|
||||
/// 一个是设置时就直接设定为常值,
|
||||
/// 另一个是斜率步骤里面比如:起始:8000,结束:9000,那么也是常值,因为当前模型是拆分详细之后的,他可以判断详细步骤的斜坡信息
|
||||
/// </summary>
|
||||
public bool ExistSlop { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 时间-秒-斜坡时间
|
||||
///// </summary>
|
||||
//public int SlopTimeSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PIDNo
|
||||
/// </summary>
|
||||
public int PIDNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID的配置信息
|
||||
/// </summary>
|
||||
public ConfigPIDDto? CurConfigPIDDto { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// LimitNo
|
||||
/// </summary>
|
||||
public int LimitNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AlarmNo的配置信息
|
||||
/// </summary>
|
||||
public ConfigLimitDto? CurConfigLimitDto { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AlarmNo
|
||||
/// </summary>
|
||||
public int AlarmNo { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
45
CapMachine.Wpf/Models/ProModelPars/RunStepType.cs
Normal file
45
CapMachine.Wpf/Models/ProModelPars/RunStepType.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 运行和下载的数据类型
|
||||
/// </summary>
|
||||
public enum RunStepType
|
||||
{
|
||||
/// <summary>
|
||||
/// 正常的步骤信息 SV-PID-Limit 下载数据
|
||||
/// 就是:包括:SV PID和SLIMIT的数据,当然SV PID和SLIMIT跟上次是一样的话,则不需要下载
|
||||
/// </summary>
|
||||
Step = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 正常的步骤信息-SV-PID 下载数据
|
||||
/// 就是:包括:SV PID和SLIMIT的数据,当然SV PID和SLIMIT跟上次是一样的话,则不需要下载
|
||||
/// </summary>
|
||||
StepPID = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 正常的步骤信息-SV-Limit 下载数据
|
||||
/// 就是:包括:SV PID和SLIMIT的数据,当然SV PID和SLIMIT跟上次是一样的话,则不需要下载
|
||||
/// </summary>
|
||||
StepLimit = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 正常的步骤信息-SV 下载数据
|
||||
/// 就是:包括:SV PID和SLIMIT的数据,当然SV PID和SLIMIT跟上次是一样的话,则不需要下载
|
||||
/// </summary>
|
||||
StepSV = 4,
|
||||
|
||||
/// <summary>
|
||||
/// 斜率单元
|
||||
/// 带斜率的数据打点执行,只传送SV值
|
||||
/// 比如速度:0-5000 5秒,此时执行:第一秒:1000,第二秒:2000,第三秒:3000,第四秒:4000,第五秒:5000
|
||||
/// </summary>
|
||||
SlopCell = 10
|
||||
}
|
||||
}
|
||||
29
CapMachine.Wpf/Models/ProModelPars/SlopExStep.cs
Normal file
29
CapMachine.Wpf/Models/ProModelPars/SlopExStep.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 斜率执行步骤
|
||||
/// </summary>
|
||||
public class SlopExStep
|
||||
{
|
||||
/// <summary>
|
||||
/// 步骤号
|
||||
/// </summary>
|
||||
public int StepNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SV值
|
||||
/// </summary>
|
||||
public int SV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已经执行
|
||||
/// </summary>
|
||||
public bool IsHasEx { get; set; }=false;
|
||||
}
|
||||
}
|
||||
71
CapMachine.Wpf/Models/ProModelPars/StepPlcCell.cs
Normal file
71
CapMachine.Wpf/Models/ProModelPars/StepPlcCell.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC下载单元
|
||||
/// </summary>
|
||||
public class StepPlcCell : HslCommunication.IDataTransfer
|
||||
{
|
||||
public ushort ReadCount { get; set; } = 10;
|
||||
|
||||
public void ParseSource(byte[] Content)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public byte[] ToSource()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
#region 步骤数据
|
||||
|
||||
/// <summary>
|
||||
/// 时间-分钟
|
||||
/// </summary>
|
||||
public short TimeMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间-秒
|
||||
/// </summary>
|
||||
public short TimeSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SV值
|
||||
/// </summary>
|
||||
public short SV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID-P
|
||||
/// </summary>
|
||||
public short PID_P { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID-I
|
||||
/// </summary>
|
||||
public short PID_I { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PID-D
|
||||
/// </summary>
|
||||
public short PID_D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit-Up
|
||||
/// </summary>
|
||||
public short Limit_Up { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit-Down
|
||||
/// </summary>
|
||||
public short Limit_Down { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
16
CapMachine.Wpf/Models/ProModelPars/StepPosMark.cs
Normal file
16
CapMachine.Wpf/Models/ProModelPars/StepPosMark.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Models.ProModelPars
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序步骤标记
|
||||
/// </summary>
|
||||
public enum StepPosMark
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ namespace CapMachine.Wpf.Models
|
||||
new ConfigChartYAxis(){ Index=2,Min=0,Max=8000,Name="转速",Unit="rpm"},
|
||||
new ConfigChartYAxis(){ Index=3,Min=0,Max=100,Name="电压",Unit="V"},
|
||||
new ConfigChartYAxis(){ Index=4,Min=0,Max=100,Name="电流",Unit="A"},
|
||||
new ConfigChartYAxis(){ Index=5,Min=0,Max=5,Name="压力",Unit="MpaA"},
|
||||
new ConfigChartYAxis(){ Index=5,Min=0,Max=5,Name="压力",Unit="BarA"},
|
||||
new ConfigChartYAxis(){ Index=6,Min=0,Max=5,Name="流量",Unit="L/min"},
|
||||
new ConfigChartYAxis(){ Index=7,Min=0,Max=5,Name="功率",Unit="W"},
|
||||
};
|
||||
|
||||
@@ -75,6 +75,9 @@ namespace CapMachine.Wpf.ProPars
|
||||
CurStep++;
|
||||
}
|
||||
|
||||
//防止上一次下载的程序多余当前的步骤,为了清空多余的步骤数据,增加一行的数据
|
||||
ListPlcParsDataQuick = AddNullData(ListPlcParsDataQuick);
|
||||
|
||||
LoadDataToPLC(siemensS7NetStance, ListPlcParsDataQuick);
|
||||
//装载地址 VW1000
|
||||
|
||||
@@ -147,6 +150,22 @@ namespace CapMachine.Wpf.ProPars
|
||||
//siemensS7NetStance.Write();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 增加一行空的数据,作为终止的执行
|
||||
/// </summary>
|
||||
public static List<PlcParsDataQuick> AddNullData(List<PlcParsDataQuick> plcParsDatas)
|
||||
{
|
||||
var NewStep = new QuickMeterStepDto()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
return LoadPlcParsData(NewStep, plcParsDatas, plcParsDatas.First().Steps.Count()+1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 单步骤程序解析
|
||||
/// 单步骤里面包括多个仪表参数的配置信息
|
||||
|
||||
Binary file not shown.
@@ -201,7 +201,8 @@ namespace CapMachine.Wpf.Services
|
||||
{
|
||||
ToomossCanDrive.IsCycleSend = true;
|
||||
ToomossCanDrive.CmdData = CmdData;
|
||||
ToomossCanDrive.StartCycleSendMsg();
|
||||
//ToomossCanDrive.StartCycleSendMsg();
|
||||
ToomossCanDrive.StartPrecisionCycleSendMsg();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -105,12 +105,12 @@ namespace CapMachine.Wpf.Services
|
||||
new Columns(){ Name="Id",MapType="System.Int64",IsIdentity=true,IsPrimary=true},
|
||||
new Columns(){ Name="工况",MapType="System.String",IsIdentity=false,IsPrimary=false,StringLength=100},
|
||||
new Columns(){ Name="转速[rpm]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="排气压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="吸气压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="排气压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="吸气压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="吸气温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="COND1温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="润滑油压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="COND2压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="润滑油压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="COND2压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="OCR[%]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="HV[V]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="HV[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
@@ -126,14 +126,16 @@ namespace CapMachine.Wpf.Services
|
||||
new Columns(){ Name="冷媒流量[L/min]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="润滑油流量[L/min]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="排气温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="膨胀阀前压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="膨胀阀前压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="膨胀阀前温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="EVAP出口压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="腔内压力[MpaA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="EVAP出口压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="腔内压力[BarA]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="压缩机表面温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="PTC流量[L/min]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="PTC入水温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="PTC出水温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="AT04_01[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="AT04_02[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="通讯Cmp母线电流[A]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="通讯Cmp母线电压[V]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
new Columns(){ Name="通讯Cmp逆变器温度[℃]",MapType=typeof(float).ToString(),IsIdentity=false,IsPrimary=false},
|
||||
@@ -441,59 +443,11 @@ namespace CapMachine.Wpf.Services
|
||||
.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value.EngPvValue);
|
||||
DataInfo.Add("创建时间", DateTime.Now);
|
||||
|
||||
|
||||
var RecordData = new RecordChannelData()
|
||||
{
|
||||
CreateTime = DateTime.Now,
|
||||
TableName = "",
|
||||
Data = DataInfo
|
||||
|
||||
//new Dictionary<string, object>()
|
||||
//{
|
||||
// {"转速[rpm]",Random.Next(0,10)+10 +Add},
|
||||
// {"排气压力[MpaA]",Random.Next(0,10)+20 +Add},
|
||||
// {"吸气压力[MpaA]",Random.Next(0,10)+30 +Add},
|
||||
// {"吸气温度[℃]",Random.Next(0,10)+40 +Add},
|
||||
// {"COND1温度[℃]",Random.Next(0,10)+50 +Add},
|
||||
// {"润滑油压力[MpaA]",Random.Next(0,10)+60 +Add},
|
||||
// {"COND2压力[MpaA]",Random.Next(0,10)+70 +Add},
|
||||
// {"OCR[%]",Random.Next(0,10)+80 +Add},
|
||||
// {"HV[V]",Random.Next(0,10)+90 +Add},
|
||||
// {"HV[A]",Random.Next(0,10)+5 +Add},
|
||||
// {"HV[W]",Random.Next(0,10)+15 +Add},
|
||||
// {"LV[V]",Random.Next(0,10)+25 +Add},
|
||||
// {"LV[A]",Random.Next(0,10)+25 +Add},
|
||||
// {"环境温度[℃]",Random.Next(0,10)+35 +Add},
|
||||
// {"环境湿度[%]",Random.Next(0,10)+45 +Add},
|
||||
// {"OS1温度[℃]",Random.Next(0,10)+55 +Add},
|
||||
// {"OS2温度[℃]",Random.Next(0,10)+65 +Add},
|
||||
// {"COND2温度[℃]",Random.Next(0,10)+75 +Add},
|
||||
// {"EVAP出口温度[℃]",Random.Next(0,10) +85+Add},
|
||||
// {"冷媒流量[L/min]",Random.Next(0,10) +10+Add},
|
||||
// {"润滑油流量[L/min]",Random.Next(0,10)+1 +Add},
|
||||
// {"排气温度[℃]",Random.Next(0,10)+13 +Add},
|
||||
// {"膨胀阀前压力[MpaA]",Random.Next(0,10)+23 +Add},
|
||||
// {"膨胀阀前温度[℃]",Random.Next(0,10) +33+Add},
|
||||
// {"EVAP出口压力[MpaA]",Random.Next(0,10)+43 +Add},
|
||||
// {"腔内压力[MpaA]",Random.Next(0,10) +53+Add},
|
||||
// {"压缩机表面温度[℃]",Random.Next(0,10)+63 +Add},
|
||||
// {"PTC流量[L/min]",Random.Next(0,10)+73 +Add},
|
||||
// {"PTC入水温度[℃]",Random.Next(0,10)+83 +Add},
|
||||
// {"PTC出水温度[℃]",Random.Next(0,10)+7 +Add},
|
||||
// {"通讯Cmp母线电流[A]",Random.Next(0,10)+17 +Add},
|
||||
// {"通讯Cmp母线电压[V]",Random.Next(0,10)+27 +Add},
|
||||
// {"通讯Cmp逆变器温度[℃]",Random.Next(0,10)+37 +Add},
|
||||
// {"通讯Cmp相电流[A]",Random.Next(0,10)+47 +Add},
|
||||
// {"通讯Cmp功率[W]",Random.Next(0,10)+57 +Add},
|
||||
// {"通讯Cmp芯片温度[℃]",Random.Next(0,10) +67+Add},
|
||||
// {"通讯PTC入水温度[℃]",Random.Next(0,10)+77 +Add},
|
||||
// {"通讯PTC出水温度[℃]",Random.Next(0,10) +87+Add},
|
||||
// {"通讯PTC峰值电流[A]",Random.Next(0,10)+1 +Add},
|
||||
// {"通讯PTC母线电流[A]",Random.Next(0,10)+16 +Add},
|
||||
// {"通讯PTC膜温[℃]",Random.Next(0,10)+26 +Add},
|
||||
// {"通讯PTC模块温度[℃]",Random.Next(0,10)+39 +Add},
|
||||
// {"创建时间",DateTime.Now},
|
||||
//},
|
||||
};
|
||||
|
||||
if (IsRecord)
|
||||
@@ -660,8 +614,6 @@ namespace CapMachine.Wpf.Services
|
||||
IsRecord = false;
|
||||
MessageBox.Show("当前试验信息未填写,无法开始记录数据", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -54,16 +54,16 @@ namespace CapMachine.Wpf.Services
|
||||
TagManager = MachineRtDataService.TagManger;
|
||||
|
||||
//SpeedTag = TagManager.DicTags.GetValueOrDefault("转速[rpm]");
|
||||
//ExPressTag = TagManager.DicTags.GetValueOrDefault("排气压力[MpaA]");
|
||||
//ExPressTag = TagManager.DicTags.GetValueOrDefault("排气压力[BarA]");
|
||||
//ExTempTag = TagManager.DicTags.GetValueOrDefault("排气温度[℃]");
|
||||
InhPressTag = TagManager.DicTags.GetValueOrDefault("吸气压力[MpaA]")!;
|
||||
InhPressTag = TagManager.DicTags.GetValueOrDefault("吸气压力[BarA]")!;
|
||||
InhTempTag = TagManager.DicTags.GetValueOrDefault("吸气温度[℃]")!;
|
||||
//ComCapBusVolTag = TagManager.DicTags.GetValueOrDefault("通讯母线电压[V]");
|
||||
//ComCapBusCurTag = TagManager.DicTags.GetValueOrDefault("通讯母线电流[A]");
|
||||
//ComCapPwTag = TagManager.DicTags.GetValueOrDefault("通讯功率[W]");
|
||||
//OS2TempTag = TagManager.DicTags.GetValueOrDefault("吸气混合器温度[℃]");
|
||||
TxvFrTempTag = TagManager.DicTags.GetValueOrDefault("膨胀阀前温度[℃]")!;
|
||||
TxvFrPressTag = TagManager.DicTags.GetValueOrDefault("膨胀阀前压力[MpaA]")!;
|
||||
TxvFrPressTag = TagManager.DicTags.GetValueOrDefault("膨胀阀前压力[BarA]")!;
|
||||
//Cond1TempTag = TagManager.DicTags.GetValueOrDefault("冷凝器出口水温[℃]");
|
||||
//CondInTempTag = TagManager.DicTags.GetValueOrDefault("冷凝器进口温度[℃]");
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace CapMachine.Wpf.Services
|
||||
SuperHeatCoolConfig.FluidsPath = ConfigHelper.GetValue("FluidsPath");
|
||||
SuperHeatCoolConfig.Cryogen = ConfigHelper.GetValue("Cryogen");
|
||||
|
||||
RtScanDeviceStart();
|
||||
//RtScanDeviceStart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
698
CapMachine.Wpf/Services/ProRuntimeService.cs
Normal file
698
CapMachine.Wpf/Services/ProRuntimeService.cs
Normal file
@@ -0,0 +1,698 @@
|
||||
using AutoMapper;
|
||||
using CapMachine.Model;
|
||||
using CapMachine.Shared.Controls;
|
||||
using CapMachine.Wpf.ChannelModel;
|
||||
using CapMachine.Wpf.Dtos;
|
||||
using CapMachine.Wpf.Models;
|
||||
using CapMachine.Wpf.Models.ProModelPars;
|
||||
using CapMachine.Wpf.Models.Tag;
|
||||
using CapMachine.Wpf.PrismEvent;
|
||||
using CapMachine.Wpf.ProPars;
|
||||
using CapMachine.Wpf.Tool;
|
||||
using ImTools;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using static CapMachine.Wpf.Models.ComEnum;
|
||||
using System.Windows.Forms;
|
||||
using HslCommunication.Profinet.Siemens;
|
||||
using Masuit.Tools.Hardware;
|
||||
|
||||
namespace CapMachine.Wpf.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序运行时服务
|
||||
/// 负责程序的解析、运行、调度等功能
|
||||
/// </summary>
|
||||
public class ProRuntimeService
|
||||
{
|
||||
/// <summary>
|
||||
/// 实例化函数
|
||||
/// </summary>
|
||||
public ProRuntimeService(IFreeSql freeSql, IMapper mapper, MachineRtDataService machineRtDataService, ILogService logService)
|
||||
{
|
||||
FreeSql = freeSql;
|
||||
Mapper = mapper;
|
||||
MachineRtDataService = machineRtDataService;
|
||||
LogService = logService;
|
||||
|
||||
//实例化函数
|
||||
ListProExModel = new List<ProExModel>()
|
||||
{
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="速度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="COND1温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="COND2温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="COND2压力",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="EVAP出口温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="排气压力",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="HV电压",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="吸气压力",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="吸气温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="润滑油压力",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="LV电压",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="OCR",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="OS1温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="OS2温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="PTC入口温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="PTC流量",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="PTC功率",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="压缩机环境湿度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
},
|
||||
new ProExModel(ProRunChannel){
|
||||
MeterName="压缩机环境温度",
|
||||
ListProStepExe=new List<ProStepExe>(),
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
//驱动实例
|
||||
SiemensDrive = MachineRtDataService.SiemensDrive;
|
||||
|
||||
//程序运行实时管道数据监听
|
||||
Task.Run(() => ListenProRunChannelAction());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的程序运行集合
|
||||
/// </summary>
|
||||
public List<ProSegRun> SelectedListProSegRun { get; set; }
|
||||
public IFreeSql FreeSql { get; }
|
||||
public IMapper Mapper { get; }
|
||||
public MachineRtDataService MachineRtDataService { get; }
|
||||
public ILogService LogService { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 西门子连接驱动程序
|
||||
/// </summary>
|
||||
public SiemensS7Net SiemensDrive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Task扫描 程序运行时间扫描任务
|
||||
/// </summary>
|
||||
private static Task ProRunTimeScanTask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 程序运行集合
|
||||
/// </summary>
|
||||
public List<ProExModel> ListProExModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PLC加载配置数据集合
|
||||
/// </summary>
|
||||
public List<PlcLoadConfigCell> ListPlcLoadConfigCell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加载选中的程序运行集合
|
||||
/// </summary>
|
||||
public void LoadProSegRun(List<ProSegRun> SelectedListProSegRun)
|
||||
{
|
||||
if (SelectedListProSegRun == null || SelectedListProSegRun.Count() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//先清空之前的步骤数据
|
||||
foreach (var itemProExModel in ListProExModel)
|
||||
{
|
||||
itemProExModel.ListProStepExe.Clear();
|
||||
}
|
||||
|
||||
//多个选中的程序块循环
|
||||
foreach (var itemProSegRun in SelectedListProSegRun)
|
||||
{
|
||||
//获取当前程序块
|
||||
//逐个对应的程序
|
||||
var CurProgramSeg = FreeSql.Select<ProgramSeg>(itemProSegRun.ProgramSegId)
|
||||
.IncludeMany(a => a.ProSteps,
|
||||
then => then.IncludeMany(b => b.MeterSpeeds)
|
||||
.IncludeMany(b => b.MeterCond1Temps)
|
||||
.IncludeMany(b => b.MeterCond2Temps)
|
||||
.IncludeMany(b => b.MeterCond2Presss)
|
||||
.IncludeMany(b => b.MeterEVAPExpTemps)
|
||||
.IncludeMany(b => b.MeterExPresss)
|
||||
.IncludeMany(b => b.MeterHVVols)
|
||||
.IncludeMany(b => b.MeterInhPresss)
|
||||
.IncludeMany(b => b.MeterInhTemps)
|
||||
.IncludeMany(b => b.MeterLubePresss)
|
||||
.IncludeMany(b => b.MeterLVVols)
|
||||
.IncludeMany(b => b.MeterOCRs)
|
||||
.IncludeMany(b => b.MeterOS1Temps)
|
||||
.IncludeMany(b => b.MeterOS2Temps)
|
||||
.IncludeMany(b => b.MeterPTCEntTemps)
|
||||
.IncludeMany(b => b.MeterPTCFlows)
|
||||
.IncludeMany(b => b.MeterPTCPws)
|
||||
.IncludeMany(b => b.MeterEnvRHs)
|
||||
.IncludeMany(b => b.MeterEnvTemps)
|
||||
).ToList().FirstOrDefault();
|
||||
|
||||
//获取当前的程序
|
||||
if (CurProgramSeg != null && CurProgramSeg.ProSteps != null && CurProgramSeg.ProSteps.Any())
|
||||
{
|
||||
//CurProgramSeg有重复运行的次数
|
||||
for (int SegIndex = 0; SegIndex < CurProgramSeg.ProRepeat; SegIndex++)
|
||||
{
|
||||
//解析程序的多行步骤,表格中的行步骤数据,牟定速度
|
||||
foreach (var itemStep in CurProgramSeg.ProSteps.OrderBy(a => a.StepNo))
|
||||
{
|
||||
//单行步骤中包含多个仪表参数的配置,需要逐个仪表参数手动操作解析
|
||||
|
||||
//********* 单个速度步骤信息的解析 *********
|
||||
var CurMeterName = "速度";
|
||||
if (itemStep.MeterSpeeds != null && itemStep.MeterSpeeds.Any())
|
||||
{
|
||||
switch (itemStep.MeterSpeeds.FirstOrDefault()!.ValueType)
|
||||
{
|
||||
case ConfigValueType.Constant: //常值
|
||||
//常值的话就一个数据,循环执行一次
|
||||
foreach (var itemMeterValueCell in itemStep.MeterSpeeds)
|
||||
{
|
||||
var Pid = new ConfigPID();
|
||||
if (FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.ParNo).Any())
|
||||
{
|
||||
Pid = FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.ParNo).First();
|
||||
}
|
||||
var Limit = new ConfigLimit();
|
||||
if (FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).Any())
|
||||
{
|
||||
Limit = FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).First();
|
||||
}
|
||||
var Alarm = new ConfigAlarm();
|
||||
if (FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).Any())
|
||||
{
|
||||
Alarm = FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).First();
|
||||
}
|
||||
|
||||
ListProExModel.FindFirst(a => a.MeterName == CurMeterName).ListProStepExe.Add(new ProStepExe()
|
||||
{
|
||||
//程序块
|
||||
ProSegName = CurProgramSeg.Name,
|
||||
ProSegStep = SegIndex,
|
||||
ProSegRepeat = CurProgramSeg.ProRepeat,
|
||||
ProSegIsExeing = false,//配置阶段默认不执行 false
|
||||
|
||||
//程序步骤数据
|
||||
StartSV = GetSVByProcess(itemMeterValueCell.Constant, CurMeterName),
|
||||
EndSV = GetSVByProcess(itemMeterValueCell.Constant, CurMeterName),
|
||||
KeepTime = itemMeterValueCell.KeepTime,
|
||||
MeterStepIsExeing = false,//配置阶段默认不执行 false
|
||||
MeterStepIsOK = false,//配置阶段默认不完成 false
|
||||
ExistSlop = false,//常值没有斜率 //开始和结束不一样则存在斜率
|
||||
|
||||
MeterStep = ListProExModel.FindFirst(a => a.MeterName == CurMeterName).ListProStepExe.Count + 1,
|
||||
MeterName = CurMeterName,
|
||||
|
||||
LimitNo = itemMeterValueCell.ParNo,
|
||||
AlarmNo = itemMeterValueCell.Ev,
|
||||
PIDNo = itemMeterValueCell.Ev,
|
||||
|
||||
CurConfigPIDDto = Mapper.Map<ConfigPIDDto>(Pid),
|
||||
CurConfigLimitDto = Mapper.Map<ConfigLimitDto>(Limit),
|
||||
|
||||
ProStepInfo = $"{itemStep.StepNo}-{itemMeterValueCell.StepNo}",
|
||||
});
|
||||
}
|
||||
break;
|
||||
case ConfigValueType.Slope: //斜率
|
||||
//根据循环次数确定
|
||||
for (int StepIndex = 0; StepIndex < itemStep.SpeedCycle; StepIndex++)
|
||||
{
|
||||
//根据循环次数执行
|
||||
foreach (var itemMeterValueCell in itemStep.MeterSpeeds)
|
||||
{
|
||||
var Pid = new ConfigPID();
|
||||
if (FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.ParNo).Any())
|
||||
{
|
||||
Pid = FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.ParNo).First();
|
||||
}
|
||||
var Limit = new ConfigLimit();
|
||||
if (FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).Any())
|
||||
{
|
||||
Limit = FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).First();
|
||||
}
|
||||
var Alarm = new ConfigAlarm();
|
||||
if (FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).Any())
|
||||
{
|
||||
Alarm = FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.Ev).First();
|
||||
}
|
||||
|
||||
ListProExModel.FindFirst(a => a.MeterName == CurMeterName).ListProStepExe.Add(new ProStepExe()
|
||||
{
|
||||
//程序块
|
||||
ProSegName = CurProgramSeg.Name,
|
||||
ProSegStep = SegIndex,
|
||||
ProSegRepeat = CurProgramSeg.ProRepeat,
|
||||
ProSegIsExeing = false,//配置阶段默认不执行 false
|
||||
|
||||
//程序步骤数据
|
||||
//SV = CALCHelper.GetQuickSV(itemMeterValueCell.Constant, 1),
|
||||
StartSV = GetSVByProcess(itemMeterValueCell.StartValue, CurMeterName),
|
||||
EndSV = GetSVByProcess(itemMeterValueCell.EndValue, CurMeterName),
|
||||
KeepTime = itemMeterValueCell.KeepTime,
|
||||
MeterStepIsExeing = false,//配置阶段默认不执行 false
|
||||
MeterStepIsOK = false,//配置阶段默认不完成 false
|
||||
ExistSlop = itemMeterValueCell.StartValue == itemMeterValueCell.EndValue ? false : true,//开始和结束不一样则存在斜率
|
||||
|
||||
MeterStep = ListProExModel.FindFirst(a => a.MeterName == CurMeterName).ListProStepExe.Count + 1,
|
||||
|
||||
LimitNo = itemMeterValueCell.ParNo,
|
||||
AlarmNo = itemMeterValueCell.ParNo,
|
||||
PIDNo = itemMeterValueCell.Ev,
|
||||
|
||||
CurConfigPIDDto = Mapper.Map<ConfigPIDDto>(Pid),
|
||||
CurConfigLimitDto = Mapper.Map<ConfigLimitDto>(Limit),
|
||||
|
||||
ProStepInfo = $"{itemStep.StepNo}-{itemMeterValueCell.StepNo}",
|
||||
MeterName = CurMeterName,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
StartProRun();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 处理后获取SV的数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private int GetSVByProcess(double SV, string Name)
|
||||
{
|
||||
var Data = ListPlcLoadConfigCell.Where(a => a.Name == Name);
|
||||
if (Data.Any())
|
||||
{
|
||||
return (int)(SV / (Data.FirstOrDefault()!.Precision));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogService.Warn($"【名称】: {Name} - 未找到对应的参数配置,数据转换格式失败");
|
||||
//未找到的话,则直接返回
|
||||
return (int)SV;
|
||||
}
|
||||
}
|
||||
|
||||
#region 程序调度执行
|
||||
|
||||
/// <summary>
|
||||
/// 开始程序调度运行
|
||||
/// </summary>
|
||||
public void StartProRun()
|
||||
{
|
||||
//开始运行前的需要进行一些设置和数据初始化
|
||||
foreach (var itemProExModel in ListProExModel)
|
||||
{
|
||||
//被启用和有步骤时才进行运行设置
|
||||
if (itemProExModel == null && itemProExModel.Enable && itemProExModel!.ListProStepExe.Count() > 0) continue;
|
||||
itemProExModel.RunEnable = true;
|
||||
|
||||
//设置下一步数据是第一步数据,然后设置时间
|
||||
itemProExModel.NextProStepExe = itemProExModel!.ListProStepExe.OrderBy(a => a.MeterStep).FirstOrDefault()!;
|
||||
itemProExModel.CurProStepExe = new ProStepExe();
|
||||
itemProExModel.StepEndDt = DateTime.Now;
|
||||
}
|
||||
|
||||
//运行扫描任务
|
||||
ProRunTimeScan();
|
||||
}
|
||||
|
||||
private bool ProRunTaskEnable = true;
|
||||
|
||||
/// <summary>
|
||||
/// 运行时间扫描
|
||||
/// </summary>
|
||||
private void ProRunTimeScan()
|
||||
{
|
||||
ProRunTimeScanTask = Task.Run(async () =>
|
||||
{
|
||||
while (ProRunTaskEnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
//循环给模型的当前时间赋值,驱动步骤执行
|
||||
foreach (var itemProExModel in ListProExModel)
|
||||
{
|
||||
if (itemProExModel.RunEnable)
|
||||
{
|
||||
itemProExModel.CurrentDateTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//LogService.Info($"时间:{DateTime.Now.ToString()}-【Meter】-{ex.Message}");
|
||||
}
|
||||
//Console.WriteLine($"扫描时间:{DiagnosticsTime.Elapsed.TotalMilliseconds.ToString()}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 队列通道
|
||||
/// 当前队列消费触发的数据记录
|
||||
/// </summary>
|
||||
public Channel<ProRunChannelData> ProRunChannel = Channel.CreateUnbounded<ProRunChannelData>(new UnboundedChannelOptions()
|
||||
{
|
||||
SingleWriter = false,//允许一次写入多条数据
|
||||
SingleReader = true //一次只能读取一条消息
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// 程序执行管道监听方法
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private async void ListenProRunChannelAction()
|
||||
{
|
||||
while (await ProRunChannel.Reader.WaitToReadAsync())
|
||||
{
|
||||
if (ProRunChannel.Reader.TryRead(out var ProRunChannelData))
|
||||
{
|
||||
////第一次计时
|
||||
//stopwatch.Start(); //启动Stopwatch
|
||||
if (ProRunChannelData.RunStepType == RunStepType.SlopCell)
|
||||
{
|
||||
Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} " +
|
||||
$"【参数名称】:{ProRunChannelData.MeterName} " +
|
||||
$"【程序Seg】{ProRunChannelData.ProSegName} " +
|
||||
$"【程序步骤】{ProRunChannelData.MeterStep} " +
|
||||
$"【斜坡打点步骤】{ProRunChannelData.SlopStepNo} " +
|
||||
$"【斜坡打点值SV】{ProRunChannelData.SV} " +
|
||||
$"【Msg】:接受到仿真写入PLC OK ");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} " +
|
||||
$"【参数名称】:{ProRunChannelData.MeterName} " +
|
||||
$"【程序Seg】{ProRunChannelData.ProSegName} " +
|
||||
$"【程序步骤】{ProRunChannelData.MeterStep} " +
|
||||
$"【步骤SV】{ProRunChannelData.SV} " +
|
||||
$"【Msg】:接受到步骤仿真写入PLC OK ");
|
||||
}
|
||||
|
||||
|
||||
Thread.Sleep(50);
|
||||
//DownLoadPID();
|
||||
//stopwatch.Stop(); //停止Stopwatch
|
||||
//Console.WriteLine("保存数据耗时::{0}", stopwatch.Elapsed.TotalSeconds.ToString());
|
||||
//stopwatch.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 下载PID 信息
|
||||
///// </summary>
|
||||
//private void DownLoadPID(ProExModel ProExecuteModel)
|
||||
//{
|
||||
// //上一次PID信息不为空的话则进行比较后再下载
|
||||
// if (ProExecuteModel != null && ProExecuteModel.CurProStepExe != null && ProExecuteModel.LastProStepExe != null)
|
||||
// {
|
||||
// //判断是否比较PID信息
|
||||
// if (ProExecuteModel.CurProStepExe.PIDNo != ProExecuteModel.LastProStepExe.PIDNo)
|
||||
// {
|
||||
// //进行比较跟上一个是否相同
|
||||
// if (ProExecuteModel.CurProStepExe != ProExecuteModel.LastProStepExe)
|
||||
// {
|
||||
// var PlcLoadConfigCell_P = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "P")!;
|
||||
// var PlcLoadConfigCell_I = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "I")!;
|
||||
// var PlcLoadConfigCell_D = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "D")!;
|
||||
// //下载PID信息的P
|
||||
// var ResultP = SiemensDrive.Write(PlcLoadConfigCell_P!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigPIDDto!.P * 1.0 / PlcLoadConfigCell_P.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:PID-P " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigPIDDto!.P}" +
|
||||
// $"【Msg】:{ResultP.Message} ");
|
||||
|
||||
// //下载PID信息的I
|
||||
// var ResultI = SiemensDrive.Write(PlcLoadConfigCell_I!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigPIDDto!.I * 1.0 / PlcLoadConfigCell_I.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:PID-I " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigPIDDto!.I}" +
|
||||
// $"【Msg】:{ResultI.Message} ");
|
||||
|
||||
// //下载PID信息的D
|
||||
// var ResultD = SiemensDrive.Write(PlcLoadConfigCell_D!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigPIDDto!.D * 1.0 / PlcLoadConfigCell_D.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:PID-D " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigPIDDto!.D}" +
|
||||
// $"【Msg】:{ResultD.Message} ");
|
||||
// return;
|
||||
// }
|
||||
// //相同的则不需要下载,直接使用上一个的配置
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// else//Pid为空的话直接下载,可能是第一个步骤
|
||||
// {
|
||||
// var PlcLoadConfigCell_P = ProExecuteModel!.ListPlcLoadConfigCell.First(a => a.Name == "P")!;
|
||||
// var PlcLoadConfigCell_I = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "I")!;
|
||||
// var PlcLoadConfigCell_D = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "D")!;
|
||||
// //下载PID信息的P
|
||||
// var ResultP = SiemensDrive.Write(PlcLoadConfigCell_P!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigPIDDto!.P * 1.0 / PlcLoadConfigCell_P.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:PID-P " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigPIDDto!.P}" +
|
||||
// $"【Msg】:{ResultP.Message} ");
|
||||
|
||||
// //下载PID信息的I
|
||||
// var ResultI = SiemensDrive.Write(PlcLoadConfigCell_I!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigPIDDto!.I * 1.0 / PlcLoadConfigCell_I.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:PID-I " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigPIDDto!.I}" +
|
||||
// $"【Msg】:{ResultI.Message} ");
|
||||
|
||||
// //下载PID信息的D
|
||||
// var ResultD = SiemensDrive.Write(PlcLoadConfigCell_D!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigPIDDto!.D * 1.0 / PlcLoadConfigCell_D.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:PID-D " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigPIDDto!.D}" +
|
||||
// $"【Msg】:{ResultD.Message} ");
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 下载Limit 信息
|
||||
///// </summary>
|
||||
//private void DownLoadLimit(ProExModel ProExecuteModel)
|
||||
//{
|
||||
// //上一次Limit信息不为空的话则进行比较后再下载
|
||||
// if (ProExecuteModel != null && ProExecuteModel.CurProStepExe != null && ProExecuteModel.LastProStepExe != null)
|
||||
// {
|
||||
// //判断是否比较Limit信息
|
||||
// if (ProExecuteModel.CurProStepExe.LimitNo != ProExecuteModel.LastProStepExe.LimitNo)
|
||||
// {
|
||||
// //进行比较跟上一个是否相同
|
||||
// if (ProExecuteModel.CurProStepExe != ProExecuteModel.LastProStepExe)
|
||||
// {
|
||||
// var PlcLoadConfigCell_Up = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "Up")!;
|
||||
// var PlcLoadConfigCell_Down = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "Down")!;
|
||||
// //下载Limit信息的Up
|
||||
// var ResultUp = SiemensDrive.Write(PlcLoadConfigCell_Up!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Up * 1.0 / PlcLoadConfigCell_Up.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:Limit-Up " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Up}" +
|
||||
// $"【Msg】:{ResultUp.Message} ");
|
||||
|
||||
// //下载Limit信息的Down
|
||||
// var ResultDown = SiemensDrive.Write(PlcLoadConfigCell_Down!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Down * 1.0 / PlcLoadConfigCell_Down.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:Limit-Down " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Down}" +
|
||||
// $"【Msg】:{ResultUp.Message} ");
|
||||
// return;
|
||||
// }
|
||||
// //相同的则不需要下载,直接使用上一个的配置
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// else//Pid为空的话直接下载,可能是第一个步骤
|
||||
// {
|
||||
// var PlcLoadConfigCell_Up = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "Up")!;
|
||||
// var PlcLoadConfigCell_Down = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "Down")!;
|
||||
// //下载Limit信息的Up
|
||||
// var ResultUp = SiemensDrive.Write(PlcLoadConfigCell_Up!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Up * 1.0 / PlcLoadConfigCell_Up.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:Limit-Up " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Up}" +
|
||||
// $"【Msg】:{ResultUp.Message} ");
|
||||
|
||||
// //下载Limit信息的Down
|
||||
// var ResultDown = SiemensDrive.Write(PlcLoadConfigCell_Down!.Address, (double)ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Down * 1.0 / PlcLoadConfigCell_Down.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:Limit-Down " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Down}" +
|
||||
// $"【Msg】:{ResultUp.Message} ");
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 下载SV 信息
|
||||
///// </summary>
|
||||
///// <param name="ProExecuteModel"></param>
|
||||
//private void DownLoadSV(ProExModel ProExecuteModel)
|
||||
//{
|
||||
// //上一次SV信息不为空的话则进行比较后再下载
|
||||
// if (ProExecuteModel != null && ProExecuteModel.CurProStepExe != null && ProExecuteModel.LastProStepExe != null)
|
||||
// {
|
||||
// //判断比较SV信息
|
||||
// if (ProExecuteModel.CurProStepExe.EndSV != ProExecuteModel.LastProStepExe.EndSV)
|
||||
// {
|
||||
// //SV配置
|
||||
// var PlcLoadConfigCell_SV = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "SV")!;
|
||||
// //下载SV信息的
|
||||
// var ResultSV = SiemensDrive.Write(PlcLoadConfigCell_SV!.Address, (double)ProExecuteModel.CurProStepExe.EndSV * 1.0 / PlcLoadConfigCell_SV.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:SV " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Up}" +
|
||||
// $"【Msg】:{ResultSV.Message} ");
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //跟上一次的一样,不需要下载了
|
||||
// }
|
||||
// }
|
||||
// else//Pid为空的话直接下载,可能是第一个步骤
|
||||
// {
|
||||
// //SV配置
|
||||
// var PlcLoadConfigCell_SV = ProExecuteModel.ListPlcLoadConfigCell.First(a => a.Name == "SV")!;
|
||||
// //下载SV信息的
|
||||
// var ResultSV = SiemensDrive.Write(PlcLoadConfigCell_SV!.Address, (double)ProExecuteModel.CurProStepExe.EndSV * 1.0 / PlcLoadConfigCell_SV.Precision);
|
||||
// Console.WriteLine($"【时间】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} 【参数名称】:{ProExecuteModel.MeterName} " +
|
||||
// $"【程序Seg】{ProExecuteModel.CurProStepExe.ProSegName} " +
|
||||
// $"【程序步骤】{ProExecuteModel.CurProStepExe.MeterStep} " +
|
||||
// $"【类型】:{ProExecuteModel.CurProStepExe.ExistSlop.ToString()} " +
|
||||
// $"【参数】:SV " +
|
||||
// $"【值】:{ProExecuteModel.CurProStepExe.CurConfigLimitDto!.Up}" +
|
||||
// $"【Msg】:{ResultSV.Message} ");
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
34
CapMachine.Wpf/SoftAuthorizeCore/AuthorizeInfo.cs
Normal file
34
CapMachine.Wpf/SoftAuthorizeCore/AuthorizeInfo.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.SoftAuthorizeCore
|
||||
{
|
||||
/// <summary>
|
||||
/// 授权信息
|
||||
/// </summary>
|
||||
public class AuthorizeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public DateTime EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最近登录时间
|
||||
/// </summary>
|
||||
public DateTime LastTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机器码 序列号
|
||||
/// </summary>
|
||||
public string MachineCode { get; set; }
|
||||
}
|
||||
}
|
||||
527
CapMachine.Wpf/SoftAuthorizeCore/LicenseClient.cs
Normal file
527
CapMachine.Wpf/SoftAuthorizeCore/LicenseClient.cs
Normal file
@@ -0,0 +1,527 @@
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.SoftAuthorizeCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Lience客户端
|
||||
/// </summary>
|
||||
public class LicenseClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据硬件信息生成机器序列号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GenSerialNo()
|
||||
{
|
||||
try
|
||||
{
|
||||
//获取硬件信息
|
||||
string info = string.Empty;
|
||||
string cpu = GetCPUInfo();
|
||||
string gpu = GetGPUInfo();
|
||||
string baseBoard = GetBaseBoardInfo();
|
||||
string bios = GetBIOSInfo();
|
||||
string mac = GetMACInfo();
|
||||
info = string.Concat(cpu, gpu, baseBoard, bios, "mac");
|
||||
|
||||
//AES加密
|
||||
using (Aes tempAES = Aes.Create())
|
||||
{
|
||||
byte[] encrypted = EncryptStringToBytes(info, tempAES.Key, tempAES.IV);
|
||||
byte[] dataCnt = BitConverter.GetBytes(Convert.ToInt16(encrypted.Length));
|
||||
|
||||
byte[] res = new byte[tempAES.Key.Length
|
||||
+ tempAES.IV.Length
|
||||
+ dataCnt.Length
|
||||
+ encrypted.Length];
|
||||
|
||||
//拼接AES密钥 32+16 bytes
|
||||
Buffer.BlockCopy(tempAES.Key, 0, res, 0, tempAES.Key.Length);
|
||||
Buffer.BlockCopy(tempAES.IV, 0, res, tempAES.Key.Length, tempAES.IV.Length);
|
||||
//拼接加密数据
|
||||
Buffer.BlockCopy(dataCnt, 0, res, tempAES.Key.Length + tempAES.IV.Length, dataCnt.Length);
|
||||
Buffer.BlockCopy(encrypted, 0, res, tempAES.Key.Length + tempAES.IV.Length + dataCnt.Length, encrypted.Length);
|
||||
|
||||
//生成机器序列号
|
||||
info = Convert.ToBase64String(res);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验授权文件
|
||||
/// </summary>
|
||||
/// <param name="license"></param>
|
||||
/// <param name="publicKey"></param>
|
||||
/// <returns></returns>
|
||||
public static bool VerifyLicense(string license, string publicKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] lic = Convert.FromBase64String(license);
|
||||
|
||||
//获取AES密钥信息
|
||||
byte[] aesKey = lic.Skip(0).Take(32).ToArray();
|
||||
byte[] aesIV = lic.Skip(32).Take(16).ToArray();
|
||||
|
||||
//获取加密数据长度
|
||||
int dataCnt = BitConverter.ToInt16(lic, 48);
|
||||
|
||||
//获取加密数据
|
||||
byte[] data = lic.Skip(50).Take(dataCnt).ToArray();
|
||||
|
||||
//获取签名
|
||||
byte[] sign = lic.Skip(50 + dataCnt).Take(128).ToArray();
|
||||
string signStr = Convert.ToBase64String(sign);
|
||||
//Console.WriteLine("get sign: " + signStr);
|
||||
|
||||
//获取时间
|
||||
byte[] times = lic.Skip(48 + 2 + dataCnt + 128).ToArray();
|
||||
string[] timeStrs = DecryptStringFromBytes(times, aesKey, aesIV).Split('|');
|
||||
//byte[] start = lic.Skip(50 + dataCnt+128).Take(8).ToArray();
|
||||
//byte[] end = lic.Skip(50 + dataCnt + 128+8).Take(8).ToArray();
|
||||
//byte[] last = lic.Skip(50 + dataCnt + 128+16).Take(8).ToArray();
|
||||
|
||||
|
||||
//获取签名的对象
|
||||
byte[] sn = lic.Skip(0).Take(50 + dataCnt).ToArray();
|
||||
string snStr = Convert.ToBase64String(sn);
|
||||
//Console.WriteLine("get sn: " + snStr);
|
||||
|
||||
//验签
|
||||
if (VerifySign(snStr, signStr, publicKey) == false)
|
||||
return false;
|
||||
|
||||
//校验机器序列号
|
||||
if (CheckHardware(snStr, aesKey, aesIV) == false)
|
||||
return false;
|
||||
|
||||
//校验授权时间
|
||||
if (CheckTime(timeStrs[0], timeStrs[1], timeStrs[2]) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 更新登录时间
|
||||
/// </summary>
|
||||
/// <param name="license"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UpdateVerifyTime(string license, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] lic = Convert.FromBase64String(license);
|
||||
|
||||
byte[] now = BitConverter.GetBytes(new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds());
|
||||
int dataCnt = BitConverter.ToInt16(lic, 48);
|
||||
byte[] aesKey = lic.Skip(0).Take(32).ToArray();
|
||||
byte[] aesIV = lic.Skip(32).Take(16).ToArray();
|
||||
byte[] times = lic.Skip(48 + 2 + dataCnt + 128).ToArray();
|
||||
string[] timeStr = DecryptStringFromBytes(times, aesKey, aesIV).Split('|');
|
||||
|
||||
long nowTime = BitConverter.ToInt64(now, 0);
|
||||
long lastTime = Convert.ToInt64(timeStr[2]);
|
||||
|
||||
//时间只能递增
|
||||
if (lastTime >= nowTime)
|
||||
return true;
|
||||
|
||||
|
||||
timeStr[2] = nowTime.ToString();
|
||||
byte[] newtimes = EncryptStringToBytes(timeStr[0] + "|" + timeStr[1] + "|" + timeStr[2], aesKey, aesIV);
|
||||
byte[] newlic = new byte[48 + 2 + dataCnt + 128 + newtimes.Length];
|
||||
Buffer.BlockCopy(lic, 0, newlic, 0, 48 + 2 + dataCnt + 128);
|
||||
Buffer.BlockCopy(newtimes, 0, newlic, 48 + 2 + dataCnt + 128, newtimes.Length);
|
||||
|
||||
license = Convert.ToBase64String(newlic);
|
||||
using (StreamWriter writer = new StreamWriter(path))
|
||||
{
|
||||
writer.WriteLine(license);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region private methods
|
||||
|
||||
/// <summary>
|
||||
/// 检查硬件信息
|
||||
/// </summary>
|
||||
/// <param name="sn"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="Iv"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckHardware(string sn, byte[] key, byte[] Iv)
|
||||
{
|
||||
//获取硬件信息
|
||||
string info = string.Empty;
|
||||
string cpu = GetCPUInfo();
|
||||
string gpu = GetGPUInfo();
|
||||
string baseBoard = GetBaseBoardInfo();
|
||||
string bios = GetBIOSInfo();
|
||||
string mac = GetMACInfo();
|
||||
info = string.Concat(cpu, gpu, baseBoard, bios, "mac");
|
||||
|
||||
//AES加密
|
||||
byte[] encrypted = EncryptStringToBytes(info, key, Iv);
|
||||
byte[] dataCnt = BitConverter.GetBytes(Convert.ToInt16(encrypted.Length));
|
||||
|
||||
byte[] res = new byte[key.Length
|
||||
+ Iv.Length
|
||||
+ dataCnt.Length
|
||||
+ encrypted.Length];
|
||||
|
||||
//拼接AES密钥 32+16 bytes
|
||||
Buffer.BlockCopy(key, 0, res, 0, key.Length);
|
||||
Buffer.BlockCopy(Iv, 0, res, key.Length, Iv.Length);
|
||||
//拼接加密数据
|
||||
Buffer.BlockCopy(dataCnt, 0, res, key.Length + Iv.Length, dataCnt.Length);
|
||||
Buffer.BlockCopy(encrypted, 0, res, key.Length + Iv.Length + dataCnt.Length, encrypted.Length);
|
||||
|
||||
//生成机器序列号
|
||||
info = Convert.ToBase64String(res);
|
||||
|
||||
if (info != sn)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查授权时间
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="last"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckTime(string startTime, string endTime, string lastTime)
|
||||
{
|
||||
long now = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
|
||||
long start = Convert.ToInt64(startTime);
|
||||
long end = Convert.ToInt64(endTime);
|
||||
long last = Convert.ToInt64(lastTime);
|
||||
|
||||
if (end <= start)
|
||||
return false;
|
||||
if (now < start || now >= end)
|
||||
return false;
|
||||
if (now <= last)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 最大解密长度
|
||||
/// </summary>
|
||||
private const int MAX_DECRYPT_BLOCK = 256;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 公钥解密
|
||||
/// </summary>
|
||||
/// <param name="xmlPublicKey"></param>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
private static string Decrypt(string xmlPublicKey, string content)
|
||||
{
|
||||
//加载公钥
|
||||
RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
|
||||
publicRsa.FromXmlString(xmlPublicKey);
|
||||
RSAParameters rp = publicRsa.ExportParameters(false);
|
||||
|
||||
//转换密钥
|
||||
AsymmetricKeyParameter pbk = DotNetUtilities.GetRsaPublicKey(rp);
|
||||
|
||||
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
|
||||
//第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
|
||||
c.Init(false, pbk);
|
||||
|
||||
byte[] DataToDecrypt = Convert.FromBase64String(content);
|
||||
|
||||
byte[] cache;
|
||||
int time = 0;//次数
|
||||
int inputLen = DataToDecrypt.Length;
|
||||
int offSet = 0;
|
||||
MemoryStream outStream = new MemoryStream();
|
||||
while (inputLen - offSet > 0)
|
||||
{
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK)
|
||||
{
|
||||
cache = c.DoFinal(DataToDecrypt, offSet, MAX_DECRYPT_BLOCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
cache = c.DoFinal(DataToDecrypt, offSet, inputLen - offSet);
|
||||
}
|
||||
//写入
|
||||
outStream.Write(cache, 0, cache.Length);
|
||||
|
||||
time++;
|
||||
offSet = time * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] resData = outStream.ToArray();
|
||||
|
||||
string strDec = Encoding.UTF8.GetString(resData);
|
||||
return strDec;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 公钥验签
|
||||
/// </summary>
|
||||
/// <param name="str">待验证的字符串</param>
|
||||
/// <param name="sign">加签之后的字符串</param>
|
||||
/// <returns>签名是否符合</returns>
|
||||
private static bool VerifySign(string str, string sign, string publicKey)
|
||||
{
|
||||
|
||||
byte[] bt = Convert.FromBase64String(str);
|
||||
byte[] rgbHash = null;
|
||||
|
||||
var csp = new SHA256CryptoServiceProvider();
|
||||
rgbHash = csp.ComputeHash(bt);
|
||||
|
||||
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
|
||||
key.FromXmlString(publicKey);
|
||||
RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
|
||||
deformatter.SetHashAlgorithm("SHA256");
|
||||
byte[] rgbSignature = Convert.FromBase64String(sign);
|
||||
if (deformatter.VerifySignature(rgbHash, rgbSignature))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AES加密
|
||||
/// </summary>
|
||||
/// <param name="plainText"></param>
|
||||
/// <param name="Key"></param>
|
||||
/// <param name="IV"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
|
||||
{
|
||||
// Check arguments.
|
||||
if (plainText == null || plainText.Length <= 0)
|
||||
throw new ArgumentNullException("plainText");
|
||||
if (Key == null || Key.Length <= 0)
|
||||
throw new ArgumentNullException("Key");
|
||||
if (IV == null || IV.Length <= 0)
|
||||
throw new ArgumentNullException("IV");
|
||||
byte[] encrypted;
|
||||
|
||||
// Create an Aes object
|
||||
// with the specified key and IV.
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = Key;
|
||||
aesAlg.IV = IV;
|
||||
|
||||
// Create an encryptor to perform the stream transform.
|
||||
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
// Create the streams used for encryption.
|
||||
using (MemoryStream msEncrypt = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
|
||||
{
|
||||
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
|
||||
{
|
||||
//Write all data to the stream.
|
||||
swEncrypt.Write(plainText);
|
||||
}
|
||||
encrypted = msEncrypt.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the encrypted bytes from the memory stream.
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AES解密
|
||||
/// </summary>
|
||||
/// <param name="cipherText"></param>
|
||||
/// <param name="Key"></param>
|
||||
/// <param name="IV"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
|
||||
{
|
||||
// Check arguments.
|
||||
if (cipherText == null || cipherText.Length <= 0)
|
||||
throw new ArgumentNullException("cipherText");
|
||||
if (Key == null || Key.Length <= 0)
|
||||
throw new ArgumentNullException("Key");
|
||||
if (IV == null || IV.Length <= 0)
|
||||
throw new ArgumentNullException("IV");
|
||||
|
||||
// Declare the string used to hold
|
||||
// the decrypted text.
|
||||
string plaintext = null;
|
||||
|
||||
// Create an Aes object
|
||||
// with the specified key and IV.
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = Key;
|
||||
aesAlg.IV = IV;
|
||||
|
||||
// Create a decryptor to perform the stream transform.
|
||||
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
// Create the streams used for decryption.
|
||||
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
|
||||
{
|
||||
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
||||
{
|
||||
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
|
||||
{
|
||||
|
||||
// Read the decrypted bytes from the decrypting stream
|
||||
// and place them in a string.
|
||||
plaintext = srDecrypt.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取CPU序列号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetCPUInfo()
|
||||
{
|
||||
var info = string.Empty;
|
||||
var mc = new ManagementClass("Win32_Processor");
|
||||
var moc = mc.GetInstances();
|
||||
foreach (var o in moc)
|
||||
{
|
||||
var mo = (ManagementObject)o;
|
||||
info = mo.Properties["ProcessorId"].Value.ToString();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取显卡序列号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetGPUInfo()
|
||||
{
|
||||
var info = "";
|
||||
var mos = new ManagementObjectSearcher("Select * from Win32_VideoController");
|
||||
foreach (var o in mos.Get())
|
||||
{
|
||||
var mo = (ManagementObject)o;
|
||||
info = mo["PNPDeviceID"].ToString();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取主板序列号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetBaseBoardInfo()
|
||||
{
|
||||
var info = string.Empty;
|
||||
var mos = new ManagementObjectSearcher("Select * from Win32_BaseBoard");
|
||||
foreach (var o in mos.Get())
|
||||
{
|
||||
var mo = (ManagementObject)o;
|
||||
info = mo["SerialNumber"].ToString();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取BIOS序列号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetBIOSInfo()
|
||||
{
|
||||
var info = string.Empty;
|
||||
var mos = new ManagementObjectSearcher("Select * from Win32_BIOS");
|
||||
foreach (var o in mos.Get())
|
||||
{
|
||||
var mo = (ManagementObject)o;
|
||||
info = mo["SerialNumber"].ToString();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取MAC地址
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetMACInfo()
|
||||
{
|
||||
var info = string.Empty;
|
||||
var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
|
||||
var moc = mc.GetInstances();
|
||||
foreach (var o in moc)
|
||||
{
|
||||
var mo = (ManagementObject)o;
|
||||
if (!(bool)mo["IPEnabled"]) continue;
|
||||
info = mo["MacAddress"].ToString();
|
||||
break;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
315
CapMachine.Wpf/SoftAuthorizeCore/LicenseServer.cs
Normal file
315
CapMachine.Wpf/SoftAuthorizeCore/LicenseServer.cs
Normal file
@@ -0,0 +1,315 @@
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.SoftAuthorizeCore
|
||||
{
|
||||
/// <summary>
|
||||
/// LienceServer
|
||||
/// </summary>
|
||||
public class LicenseServer
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成公钥和私钥(xml)
|
||||
/// </summary>
|
||||
public static string[] GenXmlKey()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
string publicKey = rsa.ToXmlString(false); // 公钥
|
||||
string privateKey = rsa.ToXmlString(true); // 私钥
|
||||
|
||||
return new string[] { publicKey, privateKey };
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据机器序列号生成授权License
|
||||
/// </summary>
|
||||
/// <param name="SerialNo"></param>
|
||||
/// <param name="privateKey"></param>
|
||||
/// <param name="startTime"></param>
|
||||
/// <param name="endTime"></param>
|
||||
/// <returns></returns>
|
||||
public static string GenLicense(string SerialNo, string privateKey, long startTime, long endTime)
|
||||
{
|
||||
try
|
||||
{
|
||||
//生成序列号签名
|
||||
byte[] sign = Sign(SerialNo, privateKey);
|
||||
|
||||
//签名
|
||||
byte[] sn = Convert.FromBase64String(SerialNo);
|
||||
|
||||
//AES加密授权时间
|
||||
byte[] aesKey = sn.Skip(0).Take(32).ToArray();
|
||||
byte[] aesIV = sn.Skip(32).Take(16).ToArray();
|
||||
byte[] time = EncryptStringToBytes(startTime.ToString() + "|" + endTime.ToString() + "|" + startTime.ToString(), aesKey, aesIV);
|
||||
|
||||
//序列号 + 序列号签名 + 授权时间
|
||||
byte[] lic = new byte[sn.Length + sign.Length + time.Length];
|
||||
Buffer.BlockCopy(sn, 0, lic, 0, sn.Length);
|
||||
Buffer.BlockCopy(sign, 0, lic, sn.Length, sign.Length);
|
||||
Buffer.BlockCopy(time, 0, lic, sn.Length + sign.Length, time.Length);
|
||||
|
||||
//生成License
|
||||
string license = string.Empty;
|
||||
license = Convert.ToBase64String(lic);
|
||||
return license;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取license的详细信息,包括机器序列号和授权时间
|
||||
/// </summary>
|
||||
/// <param name="license"></param>
|
||||
/// <returns></returns>
|
||||
public static string[] GetLicenseDetail(string license)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] lic = Convert.FromBase64String(license);
|
||||
|
||||
//获取加密数据长度
|
||||
int dataCnt = BitConverter.ToInt16(lic, 48);
|
||||
|
||||
//获取机器码
|
||||
byte[] sn = lic.Skip(0).Take(50 + dataCnt).ToArray();
|
||||
|
||||
//获取时间
|
||||
byte[] aesKey = sn.Skip(0).Take(32).ToArray();
|
||||
byte[] aesIV = sn.Skip(32).Take(16).ToArray();
|
||||
byte[] times = lic.Skip(48 + 2 + dataCnt + 128).ToArray();
|
||||
string[] timeStr = DecryptStringFromBytes(times, aesKey, aesIV).Split('|');
|
||||
|
||||
|
||||
//依次返回机器码和三个时间
|
||||
return new string[]
|
||||
{
|
||||
Convert.ToBase64String(sn),
|
||||
timeStr[0],
|
||||
timeStr[1],
|
||||
timeStr[2]
|
||||
};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region private methods
|
||||
|
||||
/// <summary>
|
||||
/// 最大加密长度
|
||||
/// </summary>
|
||||
private const int MAX_ENCRYPT_BLOCK = 245;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 用私钥进行RSA加密
|
||||
/// </summary>
|
||||
/// <param name="xmlPrivateKey"> 私钥(XML格式字符串)</param>
|
||||
/// <param name="content">要加密的数据</param>
|
||||
/// <returns> 加密后的数据 </returns>
|
||||
private static string Encrypt(string xmlPrivateKey, string content)
|
||||
{
|
||||
//加载私钥
|
||||
RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
|
||||
privateRsa.FromXmlString(xmlPrivateKey);
|
||||
|
||||
//转换密钥
|
||||
AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);
|
||||
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); //使用RSA/ECB/PKCS1Padding格式
|
||||
|
||||
c.Init(true, keyPair.Private);//第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
|
||||
byte[] dataToEncrypt = Encoding.UTF8.GetBytes(content);//获取字节
|
||||
|
||||
byte[] cache;
|
||||
int time = 0;//次数
|
||||
int inputLen = dataToEncrypt.Length;
|
||||
int offSet = 0;
|
||||
|
||||
MemoryStream outStream = new MemoryStream();
|
||||
while (inputLen - offSet > 0)
|
||||
{
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
|
||||
{
|
||||
cache = c.DoFinal(dataToEncrypt, offSet, MAX_ENCRYPT_BLOCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
cache = c.DoFinal(dataToEncrypt, offSet, inputLen - offSet);
|
||||
}
|
||||
//写入
|
||||
outStream.Write(cache, 0, cache.Length);
|
||||
|
||||
time++;
|
||||
offSet = time * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
|
||||
byte[] resData = outStream.ToArray();
|
||||
|
||||
string strBase64 = Convert.ToBase64String(resData);
|
||||
outStream.Close();
|
||||
return strBase64;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
/// </summary>
|
||||
/// <param name="str">需签名的数据</param>
|
||||
/// <returns>签名后的值</returns>
|
||||
private static byte[] Sign(string str, string privateKey)
|
||||
{
|
||||
//根据需要加签时的哈希算法转化成对应的hash字符节
|
||||
byte[] bt = Convert.FromBase64String(str);
|
||||
byte[] rgbHash = null;
|
||||
|
||||
//SHA256
|
||||
var csp = new SHA256CryptoServiceProvider();
|
||||
rgbHash = csp.ComputeHash(bt);
|
||||
|
||||
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
|
||||
key.FromXmlString(privateKey);
|
||||
RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
|
||||
//此处是你需要加签的hash算法,需要和上边你计算的hash值的算法一致,不然会报错。
|
||||
formatter.SetHashAlgorithm("SHA256");
|
||||
byte[] inArray = formatter.CreateSignature(rgbHash);
|
||||
|
||||
return inArray;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AES加密
|
||||
/// </summary>
|
||||
/// <param name="plainText"></param>
|
||||
/// <param name="Key"></param>
|
||||
/// <param name="IV"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
|
||||
{
|
||||
// Check arguments.
|
||||
if (plainText == null || plainText.Length <= 0)
|
||||
throw new ArgumentNullException("plainText");
|
||||
if (Key == null || Key.Length <= 0)
|
||||
throw new ArgumentNullException("Key");
|
||||
if (IV == null || IV.Length <= 0)
|
||||
throw new ArgumentNullException("IV");
|
||||
byte[] encrypted;
|
||||
|
||||
// Create an Aes object
|
||||
// with the specified key and IV.
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = Key;
|
||||
aesAlg.IV = IV;
|
||||
|
||||
// Create an encryptor to perform the stream transform.
|
||||
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
// Create the streams used for encryption.
|
||||
using (MemoryStream msEncrypt = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
|
||||
{
|
||||
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
|
||||
{
|
||||
//Write all data to the stream.
|
||||
swEncrypt.Write(plainText);
|
||||
}
|
||||
encrypted = msEncrypt.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the encrypted bytes from the memory stream.
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AES解密
|
||||
/// </summary>
|
||||
/// <param name="cipherText"></param>
|
||||
/// <param name="Key"></param>
|
||||
/// <param name="IV"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
|
||||
{
|
||||
// Check arguments.
|
||||
if (cipherText == null || cipherText.Length <= 0)
|
||||
throw new ArgumentNullException("cipherText");
|
||||
if (Key == null || Key.Length <= 0)
|
||||
throw new ArgumentNullException("Key");
|
||||
if (IV == null || IV.Length <= 0)
|
||||
throw new ArgumentNullException("IV");
|
||||
|
||||
// Declare the string used to hold
|
||||
// the decrypted text.
|
||||
string plaintext = null;
|
||||
|
||||
// Create an Aes object
|
||||
// with the specified key and IV.
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = Key;
|
||||
aesAlg.IV = IV;
|
||||
|
||||
// Create a decryptor to perform the stream transform.
|
||||
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
// Create the streams used for decryption.
|
||||
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
|
||||
{
|
||||
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
||||
{
|
||||
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
|
||||
{
|
||||
|
||||
// Read the decrypted bytes from the decrypting stream
|
||||
// and place them in a string.
|
||||
plaintext = srDecrypt.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
397
CapMachine.Wpf/SoftAuthorizeCore/SoftAuthorizeHelper.cs
Normal file
397
CapMachine.Wpf/SoftAuthorizeCore/SoftAuthorizeHelper.cs
Normal file
@@ -0,0 +1,397 @@
|
||||
using HslCommunication.BasicFramework;
|
||||
using HslCommunication;
|
||||
using HslCommunication.Profinet.Melsec;
|
||||
using HslCommunication.Profinet.Siemens;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using SixLabors.ImageSharp.Drawing;
|
||||
using System.ComponentModel;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Windows.Documents;
|
||||
using SharpCompress.Common;
|
||||
|
||||
namespace CapMachine.Wpf.SoftAuthorizeCore
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序的软授权
|
||||
/// </summary>
|
||||
public class SoftAuthorizeHelper
|
||||
{
|
||||
//private HslCommunication.BasicFramework.SoftAuthorize softAuthorize = null;
|
||||
|
||||
// 定义一个静态变量来保存类的实例
|
||||
private static SoftAuthorizeHelper Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static SoftAuthorizeHelper GetInstance()
|
||||
{
|
||||
// 如果类的实例不存在则创建,否则直接返回
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = new SoftAuthorizeHelper();
|
||||
}
|
||||
return Instance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
// 或者使用类型的完全限定名
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取机器码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetMachineCode()
|
||||
{
|
||||
return LicenseClient.GenSerialNo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写机器码到指定的文件中
|
||||
/// </summary>
|
||||
/// <param name="MachineCode"></param>
|
||||
/// <param name="Path">路径</param>
|
||||
/// <returns></returns>
|
||||
public bool WriteMachineCodeToFile(string MachineCode, string TxtFilePath)
|
||||
{
|
||||
//暂时是固定的
|
||||
TxtFilePath = MachineCodePath;
|
||||
|
||||
// 参数验证
|
||||
if (string.IsNullOrEmpty(MachineCode) || string.IsNullOrEmpty(TxtFilePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 确保目录存在
|
||||
string directoryPath = System.IO.Path.GetDirectoryName(TxtFilePath);
|
||||
if (!Directory.Exists(directoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
|
||||
// 写入文件
|
||||
using (StreamWriter writer = new StreamWriter(TxtFilePath))
|
||||
{
|
||||
writer.WriteLine(MachineCode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Key文件的存放路径
|
||||
/// </summary>
|
||||
private string KeyFile { get; set; } = System.AppDomain.CurrentDomain.BaseDirectory + @"Key";
|
||||
|
||||
/// <summary>
|
||||
/// Lience文件的存放路径
|
||||
/// </summary>
|
||||
private string LiencePath { get; set; } = System.AppDomain.CurrentDomain.BaseDirectory + @"Key\License.txt";
|
||||
|
||||
/// <summary>
|
||||
/// 机器码文件的存放路径
|
||||
/// </summary>
|
||||
private string MachineCodePath { get; set; } = System.AppDomain.CurrentDomain.BaseDirectory + @"Key\MachineCode.txt";
|
||||
|
||||
/// <summary>
|
||||
/// 当前的授权信息
|
||||
/// </summary>
|
||||
public AuthorizeInfo CurAuthorizeInfo { get; set; } = new AuthorizeInfo();
|
||||
|
||||
/// <summary>
|
||||
/// 获取Xml Key 文件
|
||||
/// </summary>
|
||||
public void GetXmlKey()
|
||||
{
|
||||
var key = LicenseServer.GenXmlKey();
|
||||
if (key == null)
|
||||
{
|
||||
//MessageBox.Show("生成密钥失败!", "提示");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
////写入文件
|
||||
//using (FolderBrowserDialog dialog = new FolderBrowserDialog())
|
||||
//{
|
||||
// if (dialog.ShowDialog() == DialogResult.OK)
|
||||
// {
|
||||
|
||||
string savePath = KeyFile;
|
||||
using (StreamWriter writer = new StreamWriter(System.IO.Path.Combine(savePath, "PublicKey.xml")))
|
||||
{
|
||||
writer.WriteLine(key[0]);
|
||||
}
|
||||
using (StreamWriter writer = new StreamWriter(System.IO.Path.Combine(savePath, "PrivateKey.xml")))
|
||||
{
|
||||
writer.WriteLine(key[1]);
|
||||
}
|
||||
|
||||
// }
|
||||
// else
|
||||
// return;
|
||||
//}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
MessageBox.Show("保存密钥失败!", "提示");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 授权检验
|
||||
/// 需要:
|
||||
/// 1)机器码
|
||||
/// 2)公钥
|
||||
/// 3)授权文件
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool CheckLience(string MachineCode, string PublicKey, string Lience)
|
||||
{
|
||||
//授权测试需要 机器序列号+公钥
|
||||
if (MachineCode == string.Empty)
|
||||
{
|
||||
//MessageBox.Show("授权测试需要目标机器的序列号!", "提示");
|
||||
return false;
|
||||
}
|
||||
if (PublicKey == string.Empty)
|
||||
{
|
||||
//MessageBox.Show("授权测试需要使用公钥!", "提示");
|
||||
return false;
|
||||
}
|
||||
|
||||
//无论授权是否通过,都更新校验时间
|
||||
if (LicenseClient.VerifyLicense(Lience, PublicKey) == false)
|
||||
{
|
||||
LicenseClient.UpdateVerifyTime(Lience, LiencePath);
|
||||
//MessageBox.Show("授权文件无效!", "提示");
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LicenseClient.UpdateVerifyTime(Lience, LiencePath);
|
||||
//MessageBox.Show("授权文件有效!", "提示");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取公匙详细信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetPublicKeyDataByFilePath(string Path)
|
||||
{
|
||||
try
|
||||
{
|
||||
//using (OpenFileDialog dialog = new OpenFileDialog())
|
||||
//{
|
||||
// if (dialog.ShowDialog() == DialogResult.OK)
|
||||
// {
|
||||
|
||||
//string filePath = dialog.FileName;
|
||||
|
||||
var filePath = KeyFile + @"\PublicKey.xml";
|
||||
|
||||
using (StreamReader reader = new StreamReader(filePath))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
|
||||
// }
|
||||
//}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "";
|
||||
//MessageBox.Show("配置公钥失败!", "提示");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取授权文件详细信息
|
||||
/// </summary>
|
||||
/// <param name="Path"></param>
|
||||
/// <returns></returns>
|
||||
public string GetLienceDataByFilePath(string Path)
|
||||
{
|
||||
try
|
||||
{
|
||||
//using (OpenFileDialog dialog = new OpenFileDialog())
|
||||
//{
|
||||
// if (dialog.ShowDialog() == DialogResult.OK)
|
||||
// {
|
||||
|
||||
//string filePath = dialog.FileName;
|
||||
|
||||
var filePath = KeyFile + @"\License.txt";
|
||||
|
||||
using (StreamReader reader = new StreamReader(filePath))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
|
||||
// }
|
||||
//}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "";
|
||||
//MessageBox.Show("配置公钥失败!", "提示");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载授权文件
|
||||
/// </summary>
|
||||
public AuthorizeInfo LoadLienceFile(string LiencePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
//using (OpenFileDialog dialog = new OpenFileDialog())
|
||||
//{
|
||||
// if (dialog.ShowDialog() == DialogResult.OK)
|
||||
// {
|
||||
|
||||
//string filePath = dialog.FileName;
|
||||
//licPath = filePath;
|
||||
|
||||
var LienceData = "";
|
||||
AuthorizeInfo authorizeInfo = new AuthorizeInfo();
|
||||
|
||||
using (StreamReader reader = new StreamReader(LiencePath))
|
||||
{
|
||||
//显示授权码
|
||||
LienceData = reader.ReadToEnd();
|
||||
|
||||
//显示机器码和时间
|
||||
var strs = LicenseServer.GetLicenseDetail(LienceData);
|
||||
if (strs == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
authorizeInfo.MachineCode = strs[0];
|
||||
|
||||
//北京为东8区,比UTC快8小时,转换时要加上这8小时
|
||||
authorizeInfo.StartTime = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(Convert.ToInt64(strs[1]));
|
||||
authorizeInfo.EndTime = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(Convert.ToInt64(strs[2]));
|
||||
authorizeInfo.LastTime = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(Convert.ToInt64(strs[3]));
|
||||
|
||||
return authorizeInfo;
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MessageBox.Show("授权文件无效!", "提示");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
//}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MessageBox.Show("加载授权文件失败!", "提示");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region 生成Lience文件
|
||||
|
||||
/// <summary>
|
||||
/// 生成Lience文件
|
||||
/// 生成授权文件需要:机器序列号(用户提供)+私钥(自己保密信息)+授权时间(自己控制信息)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetLience(string MachineCode, string PrivateKey, DateTime startTime, DateTime endTime)
|
||||
{
|
||||
//生成授权文件需要:机器序列号+私钥+授权时间
|
||||
if (MachineCode == string.Empty)
|
||||
{
|
||||
MessageBox.Show("生成授权文件需要目标机器的序列号!", "提示");
|
||||
return "";
|
||||
}
|
||||
if (PrivateKey == string.Empty)
|
||||
{
|
||||
MessageBox.Show("生成授权文件需要使用私钥!", "提示");
|
||||
return "";
|
||||
}
|
||||
|
||||
//new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString();
|
||||
long start = new DateTimeOffset(startTime).ToUnixTimeSeconds();
|
||||
long end = new DateTimeOffset(endTime).ToUnixTimeSeconds();
|
||||
if (end <= start)
|
||||
{
|
||||
MessageBox.Show("授权的终止时间必须大于起始时间!", "提示");
|
||||
return "";
|
||||
}
|
||||
|
||||
string lic = string.Empty;
|
||||
|
||||
lic = LicenseServer.GenLicense(MachineCode, PrivateKey, start, end);
|
||||
if (lic == null)
|
||||
{
|
||||
MessageBox.Show("生成授权文件失败!", "提示");
|
||||
return "";
|
||||
}
|
||||
|
||||
return lic;
|
||||
|
||||
//try
|
||||
//{
|
||||
// using (FolderBrowserDialog dialog = new FolderBrowserDialog())
|
||||
// {
|
||||
// if (dialog.ShowDialog() == DialogResult.OK)
|
||||
// {
|
||||
// string savePath = dialog.SelectedPath;
|
||||
// using (StreamWriter writer = new StreamWriter(Path.Combine(savePath, "License.txt")))
|
||||
// {
|
||||
// writer.WriteLine(lic);
|
||||
// }
|
||||
// licPath = Path.Combine(savePath, "License.txt");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//catch (Exception)
|
||||
//{
|
||||
// MessageBox.Show("保存授权文件失败!", "提示");
|
||||
// return;
|
||||
//}
|
||||
|
||||
//licence = lic;
|
||||
//tbLic.Text = lic;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
287
CapMachine.Wpf/Tool/CALCHelper.cs
Normal file
287
CapMachine.Wpf/Tool/CALCHelper.cs
Normal file
@@ -0,0 +1,287 @@
|
||||
using CapMachine.Model;
|
||||
using CapMachine.Wpf.Models.ProModelPars;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CapMachine.Wpf.Tool
|
||||
{
|
||||
public class CALCHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 计算斜率-分
|
||||
/// </summary>
|
||||
public static int GetSlop(double Value1, double Value2, int TimeSed)
|
||||
{
|
||||
var diff = Value2 - Value1;
|
||||
var TimeMin = TimeSed * 1.0 / 60;
|
||||
if (TimeSed == 0) return 0;
|
||||
var Result = (int)Math.Ceiling(diff / TimeMin);
|
||||
if (Result > 9999)
|
||||
{
|
||||
return 9999;
|
||||
}
|
||||
if (Result < -1999)
|
||||
{
|
||||
return -1999;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算斜率-秒-DB表
|
||||
/// </summary>
|
||||
public static int GetSlopSed(double Value1, double Value2, int TimeSed)
|
||||
{
|
||||
var diff = Value2 - Value1;
|
||||
//var TimeMin = TimeSed * 1.0 / 60;
|
||||
if (TimeSed == 0) return 0;//0应该是OFF功能
|
||||
var Result = diff / TimeSed;
|
||||
if (Result > 2000)
|
||||
{
|
||||
return 2000;
|
||||
}
|
||||
if (Result < -1999.9)
|
||||
{
|
||||
return -1999;
|
||||
}
|
||||
if (Result >= 0)
|
||||
{
|
||||
return (int)Math.Ceiling(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)Math.Floor(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
|
||||
//return (int)Math.Ceiling(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算斜率-分鐘-DB表
|
||||
/// </summary>
|
||||
public static int GetSlopMinute(double Value1, double Value2, int TimeSed)
|
||||
{
|
||||
var diff = Value2 - Value1;
|
||||
var TimeMin = TimeSed * 1.0 / 60;
|
||||
if (TimeSed == 0) return 0;//0应该是OFF功能
|
||||
var Result = diff / TimeMin;
|
||||
if (Result > 2000)
|
||||
{
|
||||
return 2000;
|
||||
}
|
||||
if (Result < -1999.9)
|
||||
{
|
||||
return -1999;
|
||||
}
|
||||
if (Result >= 0)
|
||||
{
|
||||
return (int)Math.Ceiling(Result * 10);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)Math.Floor(Result * 10);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算斜率-小时-DB表
|
||||
/// </summary>
|
||||
public static int GetSlopHour(double Value1, double Value2, int TimeSed)
|
||||
{
|
||||
var diff = Value2 - Value1;
|
||||
var TimeHour = TimeSed * 1.0 / 3600;
|
||||
if (TimeSed == 0) return 0;//0应该是OFF功能
|
||||
var Result = diff / TimeHour;
|
||||
if (Result > 2000)
|
||||
{
|
||||
return 2000;
|
||||
}
|
||||
if (Result < -1999.9)
|
||||
{
|
||||
return -1999;
|
||||
}
|
||||
if (Result >= 0)
|
||||
{
|
||||
return (int)Math.Ceiling(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)Math.Floor(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 计算斜率-秒-DB表 CV
|
||||
/// </summary>
|
||||
public static int GetSlopCVMinute(double Value1, double Value2, int TimeSed)
|
||||
{
|
||||
var diff = Value2 - Value1;
|
||||
//var TimeMin = TimeSed * 1.0 / 60;
|
||||
if (TimeSed == 0) return 0;//0应该是OFF功能
|
||||
var Result = diff / TimeSed;
|
||||
if (Result > 2000)
|
||||
{
|
||||
return 2000;
|
||||
}
|
||||
if (Result < -1999.9)
|
||||
{
|
||||
return -1999;
|
||||
}
|
||||
if (Result >= 0)
|
||||
{
|
||||
return (int)Math.Ceiling(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)Math.Floor(Result);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 计算斜率-秒-DB表
|
||||
///// </summary>
|
||||
//public static int GetSlopSed(double Value1, double Value2, int TimeSed)
|
||||
//{
|
||||
// var diff = Value2 - Value1;
|
||||
// //var TimeMin = TimeSed * 1.0 / 60;
|
||||
// if (TimeSed == 0) return 0;//0应该是OFF功能
|
||||
// var Result = diff / TimeSed;
|
||||
// if (Result > 2000)
|
||||
// {
|
||||
// return 2000 * 10;
|
||||
// }
|
||||
// if (Result < -1999.9)
|
||||
// {
|
||||
// return -1999 * 10;
|
||||
// }
|
||||
// return (int)Math.Ceiling(Result * 10);//乘以10是DB表的通信上的范围数据要求的,实际显示x.x
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// SV值的数据获取
|
||||
/// </summary>
|
||||
/// <param name="sourceData"></param>
|
||||
/// <param name="accuracy"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetQuickSV(double sourceData, short accuracy)
|
||||
{
|
||||
return (int)(sourceData * (int)Math.Pow(10, accuracy));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 比较是否有改变的数据
|
||||
/// </summary>
|
||||
/// <param name="NextData"></param>
|
||||
/// <param name="CurrentData"></param>
|
||||
/// <param name="Field"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CpStepExecuteCompareInfo(ProStepExe NextData, ProStepExe CurrentData, string Field)
|
||||
{
|
||||
switch (Field)
|
||||
{
|
||||
case "PID":
|
||||
if (NextData.PIDNo == CurrentData.PIDNo) return true;
|
||||
return false;
|
||||
case "SV":
|
||||
if (NextData.EndSV == CurrentData.EndSV) return true;
|
||||
return false;
|
||||
case "Limit":
|
||||
if (NextData.LimitNo == CurrentData.LimitNo) return true;
|
||||
return false;
|
||||
case "Alarm":
|
||||
if (NextData.AlarmNo == CurrentData.AlarmNo) return true;
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 比较是否有改变的数据
|
||||
/// </summary>
|
||||
/// <param name="NextData"></param>
|
||||
/// <param name="CurrentData"></param>
|
||||
/// <param name="Field"></param>
|
||||
/// <returns></returns>
|
||||
public static bool KpStepExecuteCompareInfo(ProStepExe NextData, ProStepExe CurrentData, string Field)
|
||||
{
|
||||
switch (Field)
|
||||
{
|
||||
case "PID":
|
||||
if (NextData.PIDNo == CurrentData.PIDNo) return true;
|
||||
return false;
|
||||
case "SV":
|
||||
if (NextData.EndSV == CurrentData.EndSV) return true;
|
||||
return false;
|
||||
case "Limit":
|
||||
if (NextData.LimitNo == CurrentData.LimitNo) return true;
|
||||
return false;
|
||||
case "Alarm":
|
||||
if (NextData.AlarmNo == CurrentData.AlarmNo) return true;
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 判断Limit下载的次序
|
||||
/// </summary>
|
||||
/// <param name="NextData"></param>
|
||||
/// <param name="CurrentData"></param>
|
||||
/// <returns></returns>
|
||||
public static int CpStepExecuteLimitCompareInfo(ProStepExe NextData, ProStepExe CurrentData)
|
||||
{
|
||||
if (NextData.CurConfigLimitDto.Down >= CurrentData.CurConfigLimitDto.Up)
|
||||
{
|
||||
//先下载Up,后下载Down
|
||||
return 1;
|
||||
}
|
||||
if (NextData.CurConfigLimitDto.Up <= CurrentData.CurConfigLimitDto.Down)
|
||||
{
|
||||
//先下载Down,后下载Up
|
||||
return 3;
|
||||
}
|
||||
|
||||
//正常下载 Down和Up顺序都可以
|
||||
return 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断Limit下载的次序
|
||||
/// </summary>
|
||||
/// <param name="NextData"></param>
|
||||
/// <param name="CurrentData"></param>
|
||||
/// <returns></returns>
|
||||
public static int KpStepExecuteLimitCompareInfo(ProStepExe NextData, ProStepExe CurrentData)
|
||||
{
|
||||
if (NextData.CurConfigLimitDto.Down >= CurrentData.CurConfigLimitDto.Up)
|
||||
{
|
||||
//先下载Up,后下载Down
|
||||
return 1;
|
||||
}
|
||||
if (NextData.CurConfigLimitDto.Up <= CurrentData.CurConfigLimitDto.Down)
|
||||
{
|
||||
//先下载Down,后下载Up
|
||||
return 3;
|
||||
}
|
||||
|
||||
//正常下载 Down和Up顺序都可以
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//private long GetProDur(QuickStep quickStep)
|
||||
//{
|
||||
// return 0;
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,8 @@ using Prism.Events;
|
||||
using Prism.Regions;
|
||||
using Prism.Services.Dialogs;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -51,7 +51,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
/// <param name="eventAggregator"></param>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="logger"></param>
|
||||
public HistoryDataViewModel(IDialogService dialogService, IFreeSql freeSql, IEventAggregator eventAggregator, IMapper mapper,ConfigService configService)
|
||||
public HistoryDataViewModel(IDialogService dialogService, IFreeSql freeSql, IEventAggregator eventAggregator, IMapper mapper, ConfigService configService)
|
||||
{
|
||||
DialogService = dialogService;
|
||||
FreeSql = freeSql;
|
||||
@@ -132,6 +132,20 @@ namespace CapMachine.Wpf.ViewModels
|
||||
set { _IsLeftDrawerOpen = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
private bool _IsBusy;
|
||||
public bool IsBusy
|
||||
{
|
||||
get { return _IsBusy; }
|
||||
set { _IsBusy = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _BusyMessage = "正在加载,请稍候...";
|
||||
public string BusyMessage
|
||||
{
|
||||
get { return _BusyMessage; }
|
||||
set { _BusyMessage = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -224,15 +238,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
set { _SelectedHistoryExp = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
private HistoryWorkCondFile _SelectedHistoryWorkCondFile;
|
||||
/// <summary>
|
||||
/// 选中的历史数据文件
|
||||
/// </summary>
|
||||
public HistoryWorkCondFile SelectedHistoryWorkCondFile
|
||||
{
|
||||
get { return _SelectedHistoryWorkCondFile; }
|
||||
set { _SelectedHistoryWorkCondFile = value; RaisePropertyChanged(); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前搜索的工况条件
|
||||
@@ -268,7 +274,13 @@ namespace CapMachine.Wpf.ViewModels
|
||||
if (par is HistoryExp)
|
||||
{
|
||||
SelectedHistoryExp = par as HistoryExp;
|
||||
ListHistoryWorkCondFile = SelectedHistoryExp!.HistoryWorkCondFiles!;
|
||||
var files = SelectedHistoryExp!.HistoryWorkCondFiles!;
|
||||
foreach (var f in files)
|
||||
{
|
||||
if (f != null) f.IsSelected = false;
|
||||
}
|
||||
ListHistoryWorkCondFile = files.ToList();
|
||||
//ListHistoryWorkCondFile = ListHistoryWorkCondFile.ToList();
|
||||
return;
|
||||
}
|
||||
if ((par as SelectionChangedEventArgs)!.AddedItems.Count == 0)
|
||||
@@ -290,63 +302,18 @@ namespace CapMachine.Wpf.ViewModels
|
||||
if (Selecteddata != null)
|
||||
{
|
||||
SelectedHistoryExp = Selecteddata;
|
||||
ListHistoryWorkCondFile = SelectedHistoryExp.HistoryWorkCondFiles!;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DelegateCommand<object> _FileGridSelectionChangedCmd;
|
||||
/// <summary>
|
||||
/// 试验信息选中行数据命令
|
||||
/// </summary>
|
||||
public DelegateCommand<object> FileGridSelectionChangedCmd
|
||||
{
|
||||
set
|
||||
{
|
||||
_FileGridSelectionChangedCmd = value;
|
||||
}
|
||||
get
|
||||
{
|
||||
if (_FileGridSelectionChangedCmd == null)
|
||||
var files = SelectedHistoryExp.HistoryWorkCondFiles!;
|
||||
foreach (var f in files)
|
||||
{
|
||||
_FileGridSelectionChangedCmd = new DelegateCommand<object>((par) => FileGridSelectionChangedCmdMethod(par));
|
||||
if (f != null) f.IsSelected = false;
|
||||
}
|
||||
return _FileGridSelectionChangedCmd;
|
||||
ListHistoryWorkCondFile = files;
|
||||
ListHistoryWorkCondFile = ListHistoryWorkCondFile.ToList();
|
||||
}
|
||||
}
|
||||
private void FileGridSelectionChangedCmdMethod(object par)
|
||||
{
|
||||
if (par == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (par is HistoryWorkCondFile)
|
||||
{
|
||||
SelectedHistoryWorkCondFile = par as HistoryWorkCondFile;
|
||||
return;
|
||||
}
|
||||
if ((par as SelectionChangedEventArgs)!.AddedItems.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//先判断是否是正确的集合数据,防止DataGrid的数据源刷新导致的触发事件
|
||||
var Selecteddata = (par as SelectionChangedEventArgs)!.AddedItems[0] as HistoryWorkCondFile;
|
||||
|
||||
////选中的行数据
|
||||
//var Selecteddata = (par as DataGrid)!.SelectedItem as HistoryExp;
|
||||
////选中的列数据
|
||||
//var selectedColumn = (par as DataGrid)!.CurrentColumn;
|
||||
|
||||
//SelectedIndex= ProParsHelper.GetIndexByName(selectedColumn);
|
||||
|
||||
//SelectedProStepDto = par as ProStepDto;
|
||||
if (Selecteddata != null)
|
||||
{
|
||||
SelectedHistoryWorkCondFile = Selecteddata;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _FilterHistoryDataFileCmd;
|
||||
/// <summary>
|
||||
@@ -397,6 +364,48 @@ namespace CapMachine.Wpf.ViewModels
|
||||
HasHeaderRecord = false,
|
||||
};
|
||||
|
||||
private DelegateCommand<object> _SelectAllFilesCmd;
|
||||
public DelegateCommand<object> SelectAllFilesCmd
|
||||
{
|
||||
set
|
||||
{
|
||||
_SelectAllFilesCmd = value;
|
||||
}
|
||||
get
|
||||
{
|
||||
if (_SelectAllFilesCmd == null)
|
||||
{
|
||||
_SelectAllFilesCmd = new DelegateCommand<object>((par) => SelectAllFilesCmdMethod(par));
|
||||
}
|
||||
return _SelectAllFilesCmd;
|
||||
}
|
||||
}
|
||||
private void SelectAllFilesCmdMethod(object par)
|
||||
{
|
||||
bool isChecked = false;
|
||||
if (par is bool b) { isChecked = b; }
|
||||
else
|
||||
{
|
||||
var nb = par as bool?;
|
||||
if (nb.HasValue) isChecked = nb.Value;
|
||||
else
|
||||
{
|
||||
var sb = par as string;
|
||||
if (!string.IsNullOrWhiteSpace(sb))
|
||||
{
|
||||
bool.TryParse(sb, out isChecked);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ListHistoryWorkCondFile == null) return;
|
||||
foreach (var f in ListHistoryWorkCondFile)
|
||||
{
|
||||
if (f != null) f.IsSelected = isChecked;
|
||||
}
|
||||
// 触发刷新
|
||||
ListHistoryWorkCondFile = ListHistoryWorkCondFile.ToList();
|
||||
}
|
||||
|
||||
Stopwatch stopwatch = new Stopwatch();
|
||||
|
||||
private DelegateCommand _HistoryDataFileCmd;
|
||||
@@ -422,118 +431,134 @@ namespace CapMachine.Wpf.ViewModels
|
||||
/// <summary>
|
||||
/// 获取试验数据的命令的执行方法
|
||||
/// </summary>
|
||||
private void HistoryDataFileCmdMethod()
|
||||
private async void HistoryDataFileCmdMethod()
|
||||
{
|
||||
//SelectedHistoryWorkCondFile
|
||||
if (SelectedHistoryExp != null && SelectedHistoryWorkCondFile != null)
|
||||
{
|
||||
CsvRecordModels = new List<CsvRecordModel>();
|
||||
|
||||
////第一次计时
|
||||
stopwatch.Start(); //启动Stopwatch
|
||||
|
||||
if (!string.IsNullOrEmpty(SelectedHistoryWorkCondFile.FilePath))
|
||||
{
|
||||
if (File.Exists(SelectedHistoryWorkCondFile.FilePath))//是否存在文件
|
||||
{
|
||||
lock (ConfigService.CsvFileLock)
|
||||
{
|
||||
using (var reader = new StreamReader(SelectedHistoryWorkCondFile.FilePath))
|
||||
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
|
||||
{
|
||||
csv.Context.RegisterClassMap<CsvRecordModelMap>();
|
||||
//GetRecords<CsvRecordModel>().ToList();
|
||||
|
||||
CsvRecordModels.AddRange(csv.GetRecords<CsvRecordModel>().ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Windows.MessageBox.Show("没有发现地址对应的文件");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Windows.MessageBox.Show("发现空的文件地址");
|
||||
}
|
||||
|
||||
//数据加载完毕后进入到Chart曲线中
|
||||
if (CsvRecordModels.Count > 0)
|
||||
{
|
||||
EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
|
||||
}
|
||||
|
||||
stopwatch.Stop(); //停止Stopwatch
|
||||
Console.WriteLine("加载CSV数据耗时::{0}", stopwatch.Elapsed.TotalSeconds.ToString());
|
||||
stopwatch.Reset();
|
||||
|
||||
IsLeftDrawerOpen = false;
|
||||
}
|
||||
else
|
||||
if (SelectedHistoryExp == null)
|
||||
{
|
||||
System.Windows.MessageBox.Show("请选中后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
return;
|
||||
}
|
||||
|
||||
var files = new List<HistoryWorkCondFile>();
|
||||
if (ListHistoryWorkCondFile != null)
|
||||
{
|
||||
foreach (var f in ListHistoryWorkCondFile)
|
||||
{
|
||||
if (f != null && f.IsSelected)
|
||||
{
|
||||
files.Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region 整个工况
|
||||
//整个试验工况一起加载数据
|
||||
//if (SelectedHistoryExp != null && SelectedHistoryExp.HistoryWorkCondFiles != null)
|
||||
//{
|
||||
// CsvRecordModels = new List<CsvRecordModel>();
|
||||
files = files
|
||||
.Where(f => f != null)
|
||||
.GroupBy(f => string.IsNullOrWhiteSpace(f.FilePath) ? $"ID:{f.Id}" : f.FilePath)
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
|
||||
// ////第一次计时
|
||||
// stopwatch.Start(); //启动Stopwatch
|
||||
if (files.Count == 0)
|
||||
{
|
||||
System.Windows.MessageBox.Show("请先在右侧勾选至少一个CSV文件", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
// foreach (var item in SelectedHistoryExp.HistoryWorkCondFiles)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(item.FilePath))
|
||||
// {
|
||||
// if (File.Exists(item.FilePath))//是否存在文件
|
||||
// {
|
||||
// lock (ConfigService.CsvFileLock)
|
||||
// {
|
||||
// using (var reader = new StreamReader(item.FilePath))
|
||||
// using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
|
||||
// {
|
||||
// csv.Context.RegisterClassMap<CsvRecordModelMap>();
|
||||
// //GetRecords<CsvRecordModel>().ToList();
|
||||
BusyMessage = "正在加载CSV数据,请稍候...";
|
||||
IsBusy = true;
|
||||
|
||||
// CsvRecordModels.AddRange(csv.GetRecords<CsvRecordModel>().ToList());
|
||||
// }
|
||||
// }
|
||||
var loaded = new List<CsvRecordModel>();
|
||||
string errorText = string.Empty;
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// System.Windows.MessageBox.Show("没有发现地址对应的文件");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// System.Windows.MessageBox.Show("发现空的文件地址");
|
||||
// }
|
||||
// }
|
||||
stopwatch.Start();
|
||||
|
||||
// //数据加载完毕后进入到Chart曲线中
|
||||
// if (CsvRecordModels.Count > 0)
|
||||
// {
|
||||
// EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
|
||||
// }
|
||||
try
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var errors = new StringBuilder();
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
var f = files[i];
|
||||
try
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
BusyMessage = $"正在加载({i + 1}/{files.Count}):{System.IO.Path.GetFileName(f?.FilePath)}";
|
||||
});
|
||||
|
||||
// stopwatch.Stop(); //停止Stopwatch
|
||||
// Console.WriteLine("加载CSV数据耗时::{0}", stopwatch.Elapsed.TotalSeconds.ToString());
|
||||
// stopwatch.Reset();
|
||||
if (f == null) continue;
|
||||
if (string.IsNullOrWhiteSpace(f.FilePath))
|
||||
{
|
||||
errors.AppendLine("发现空的文件地址");
|
||||
continue;
|
||||
}
|
||||
if (!File.Exists(f.FilePath))
|
||||
{
|
||||
errors.AppendLine($"没有发现地址对应的文件: {f.FilePath}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// IsLeftDrawerOpen = false;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// System.Windows.MessageBox.Show("请选中后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
//}
|
||||
var rec = ReadCsvFile(f.FilePath);
|
||||
if (rec != null && rec.Count > 0)
|
||||
{
|
||||
loaded.AddRange(rec);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.AppendLine($"读取CSV失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
errorText = errors.ToString();
|
||||
});
|
||||
|
||||
#endregion
|
||||
if (!string.IsNullOrWhiteSpace(errorText))
|
||||
{
|
||||
System.Windows.MessageBox.Show(errorText, "读取提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
|
||||
CsvRecordModels = new List<CsvRecordModel>();
|
||||
if (loaded != null && loaded.Count > 0)
|
||||
{
|
||||
CsvRecordModels = loaded
|
||||
.Where(r => r != null)
|
||||
.OrderBy(r => r.CreateTime)
|
||||
.ToList();
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
|
||||
});
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
stopwatch.Stop();
|
||||
Console.WriteLine("加载CSV数据耗时::{0}", stopwatch.Elapsed.TotalSeconds.ToString());
|
||||
stopwatch.Reset();
|
||||
IsBusy = false;
|
||||
IsLeftDrawerOpen = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<CsvRecordModel> ReadCsvFile(string filePath)
|
||||
{
|
||||
var result = new List<CsvRecordModel>();
|
||||
lock (ConfigService.CsvFileLock)
|
||||
{
|
||||
using (var reader = new StreamReader(filePath, Encoding.UTF8))
|
||||
using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
|
||||
{
|
||||
csv.Context.RegisterClassMap<CsvRecordModelMap>();
|
||||
var list = csv.GetRecords<CsvRecordModel>().ToList();
|
||||
if (list != null && list.Count > 0)
|
||||
{
|
||||
// 过滤无效时间,避免排序异常
|
||||
result = list.Where(r => r != null && r.CreateTime != default && r.CreateTime != DateTime.MinValue).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1075,7 +1100,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
SeletedGroup6ListViewTabIndex = 0;
|
||||
SeletedGroup7ListViewTabIndex = 0;
|
||||
SeletedGroup8ListViewTabIndex = 0;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -51,16 +51,16 @@ namespace CapMachine.Wpf.ViewModels
|
||||
ListMeterTag = TagManager.DicTags.Values.Where(a => a.IsMeter == true).ToList();
|
||||
|
||||
SpeedTag = TagManager.DicTags.GetValueOrDefault("转速[rpm]");
|
||||
ExPressTag = TagManager.DicTags.GetValueOrDefault("排气压力[MpaA]");
|
||||
ExPressTag = TagManager.DicTags.GetValueOrDefault("排气压力[BarA]");
|
||||
ExTempTag = TagManager.DicTags.GetValueOrDefault("排气温度[℃]");
|
||||
InhPressTag = TagManager.DicTags.GetValueOrDefault("吸气压力[MpaA]");
|
||||
InhPressTag = TagManager.DicTags.GetValueOrDefault("吸气压力[BarA]");
|
||||
InhTempTag = TagManager.DicTags.GetValueOrDefault("吸气温度[℃]");
|
||||
ComCapBusVolTag = TagManager.DicTags.GetValueOrDefault("通讯母线电压[V]");
|
||||
ComCapBusCurTag = TagManager.DicTags.GetValueOrDefault("通讯母线电流[A]");
|
||||
ComCapPwTag = TagManager.DicTags.GetValueOrDefault("通讯功率[W]");
|
||||
OS2TempTag = TagManager.DicTags.GetValueOrDefault("吸气混合器温度[℃]");
|
||||
TxvFrTempTag = TagManager.DicTags.GetValueOrDefault("膨胀阀前温度[℃]");
|
||||
TxvFrPressTag = TagManager.DicTags.GetValueOrDefault("膨胀阀前压力[MpaA]");
|
||||
TxvFrPressTag = TagManager.DicTags.GetValueOrDefault("膨胀阀前压力[BarA]");
|
||||
Cond1TempTag = TagManager.DicTags.GetValueOrDefault("冷凝器出口水温[℃]");
|
||||
CondInTempTag = TagManager.DicTags.GetValueOrDefault("冷凝器进口温度[℃]");
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
public class ProConfigViewModel : NavigationViewModel
|
||||
{
|
||||
public ProConfigViewModel(IDialogService dialogService, IFreeSql freeSql,
|
||||
IEventAggregator eventAggregator, IRegionManager regionManager, SysRunService sysRunService, ConfigService configService,
|
||||
IEventAggregator eventAggregator, IRegionManager regionManager, SysRunService sysRunService, ConfigService configService, ProRuntimeService proRuntimeService,
|
||||
MachineRtDataService machineRtDataService)
|
||||
{
|
||||
//LogService = logService;
|
||||
@@ -32,6 +32,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
RegionManager = regionManager;
|
||||
SysRunService = sysRunService;
|
||||
ConfigService = configService;
|
||||
ProRuntimeService = proRuntimeService;
|
||||
this.MachineRtDataService = machineRtDataService;
|
||||
|
||||
//MachineDataService = machineDataService;
|
||||
@@ -83,6 +84,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
public IRegionManager RegionManager { get; }
|
||||
public SysRunService SysRunService { get; }
|
||||
public ConfigService ConfigService { get; }
|
||||
public ProRuntimeService ProRuntimeService { get; }
|
||||
private MachineRtDataService MachineRtDataService { get; }
|
||||
|
||||
/// <summary>
|
||||
@@ -2327,48 +2329,50 @@ namespace CapMachine.Wpf.ViewModels
|
||||
//返回的数据
|
||||
List<PlcParsData> ReturnPlcParsData = new List<PlcParsData>();
|
||||
|
||||
//var Data=FreeSql.Select<ProSegRun>(
|
||||
//以每个程序为单元循环执行
|
||||
foreach (var item in ProSegRunListViewItems)
|
||||
{
|
||||
var FindData = FreeSql.Select<ProgramSeg>(item.ProgramSegId)
|
||||
.IncludeMany(a => a.ProSteps,
|
||||
then => then.IncludeMany(b => b.MeterSpeeds)
|
||||
.IncludeMany(b => b.MeterCond1Temps)
|
||||
.IncludeMany(b => b.MeterCond2Temps)
|
||||
.IncludeMany(b => b.MeterCond2Presss)
|
||||
.IncludeMany(b => b.MeterEVAPExpTemps)
|
||||
.IncludeMany(b => b.MeterExPresss)
|
||||
.IncludeMany(b => b.MeterHVVols)
|
||||
.IncludeMany(b => b.MeterInhPresss)
|
||||
.IncludeMany(b => b.MeterInhTemps)
|
||||
.IncludeMany(b => b.MeterLubePresss)
|
||||
.IncludeMany(b => b.MeterLVVols)
|
||||
.IncludeMany(b => b.MeterOCRs)
|
||||
.IncludeMany(b => b.MeterOS1Temps)
|
||||
.IncludeMany(b => b.MeterOS2Temps)
|
||||
.IncludeMany(b => b.MeterPTCEntTemps)
|
||||
.IncludeMany(b => b.MeterPTCFlows)
|
||||
.IncludeMany(b => b.MeterPTCPws)
|
||||
.IncludeMany(b => b.MeterEnvRHs)
|
||||
.IncludeMany(b => b.MeterEnvTemps)
|
||||
).ToList().FirstOrDefault();
|
||||
ProRuntimeService.LoadProSegRun(ProSegRunListViewItems.ToList());
|
||||
|
||||
if (FindData != null && FindData.ProSteps != null && FindData.ProSteps.Any())
|
||||
{
|
||||
//执行程序的步骤集合数据
|
||||
ReturnPlcParsData = ProParsSongZhiHelper.GetPlcParsData(FindData.ProSteps, FindData.ProRepeat);
|
||||
//把次数给PLC,那么此时应该是最后一个程序给PLC了
|
||||
ProParsSongZhiHelper.LoadProCycleToPlc(MachineRtDataService.SiemensDrive, FindData.ProRepeat);
|
||||
}
|
||||
}
|
||||
////var Data=FreeSql.Select<ProSegRun>(
|
||||
////以每个程序为单元循环执行
|
||||
//foreach (var item in ProSegRunListViewItems)
|
||||
//{
|
||||
// var FindData = FreeSql.Select<ProgramSeg>(item.ProgramSegId)
|
||||
// .IncludeMany(a => a.ProSteps,
|
||||
// then => then.IncludeMany(b => b.MeterSpeeds)
|
||||
// .IncludeMany(b => b.MeterCond1Temps)
|
||||
// .IncludeMany(b => b.MeterCond2Temps)
|
||||
// .IncludeMany(b => b.MeterCond2Presss)
|
||||
// .IncludeMany(b => b.MeterEVAPExpTemps)
|
||||
// .IncludeMany(b => b.MeterExPresss)
|
||||
// .IncludeMany(b => b.MeterHVVols)
|
||||
// .IncludeMany(b => b.MeterInhPresss)
|
||||
// .IncludeMany(b => b.MeterInhTemps)
|
||||
// .IncludeMany(b => b.MeterLubePresss)
|
||||
// .IncludeMany(b => b.MeterLVVols)
|
||||
// .IncludeMany(b => b.MeterOCRs)
|
||||
// .IncludeMany(b => b.MeterOS1Temps)
|
||||
// .IncludeMany(b => b.MeterOS2Temps)
|
||||
// .IncludeMany(b => b.MeterPTCEntTemps)
|
||||
// .IncludeMany(b => b.MeterPTCFlows)
|
||||
// .IncludeMany(b => b.MeterPTCPws)
|
||||
// .IncludeMany(b => b.MeterEnvRHs)
|
||||
// .IncludeMany(b => b.MeterEnvTemps)
|
||||
// ).ToList().FirstOrDefault();
|
||||
|
||||
//防止上一次下载的程序多余当前的步骤,为了清空多余的步骤数据,增加一行的数据
|
||||
ReturnPlcParsData = ProParsSongZhiHelper.AddNullData(ReturnPlcParsData);
|
||||
//装载PLC地址
|
||||
ReturnPlcParsData = ProParsSongZhiHelper.LoadPlcCellAddress(ReturnPlcParsData);
|
||||
// if (FindData != null && FindData.ProSteps != null && FindData.ProSteps.Any())
|
||||
// {
|
||||
// //执行程序的步骤集合数据
|
||||
// ReturnPlcParsData = ProParsSongZhiHelper.GetPlcParsData(FindData.ProSteps, FindData.ProRepeat);
|
||||
// //把次数给PLC,那么此时应该是最后一个程序给PLC了
|
||||
// ProParsSongZhiHelper.LoadProCycleToPlc(MachineRtDataService.SiemensDrive, FindData.ProRepeat);
|
||||
// }
|
||||
//}
|
||||
|
||||
ProParsSongZhiHelper.LoadDataToPLC(MachineRtDataService.SiemensDrive, ReturnPlcParsData);
|
||||
////防止上一次下载的程序多余当前的步骤,为了清空多余的步骤数据,增加一行的数据
|
||||
//ReturnPlcParsData = ProParsSongZhiHelper.AddNullData(ReturnPlcParsData);
|
||||
////装载PLC地址
|
||||
//ReturnPlcParsData = ProParsSongZhiHelper.LoadPlcCellAddress(ReturnPlcParsData);
|
||||
|
||||
//ProParsSongZhiHelper.LoadDataToPLC(MachineRtDataService.SiemensDrive, ReturnPlcParsData);
|
||||
|
||||
//下载完成的话,则标记状态
|
||||
SysRunService.MachineRunState1.IsProLoad = true;
|
||||
|
||||
@@ -326,6 +326,7 @@ namespace CapMachine.Wpf.ViewModels
|
||||
}
|
||||
|
||||
ProParsHelperQuick.GetPlcParsData(ListQuickMeterStepDto.ToList(), this.MachineRtDataService.SiemensDrive);
|
||||
|
||||
//下载完成的话,则标记状态
|
||||
SysRunService.MachineRunState1.IsProLoad = true;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
</Style>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
</UserControl.Resources>
|
||||
<materialDesign:DrawerHost
|
||||
x:Name="HistoryDrawerHost"
|
||||
@@ -265,28 +266,95 @@
|
||||
AutoGenerateColumns="False"
|
||||
BorderBrush="Black"
|
||||
BorderThickness="1"
|
||||
CanUserAddRows="False"
|
||||
FontWeight="Bold"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{Binding ListHistoryWorkCondFile}"
|
||||
SelectionMode="Extended"
|
||||
SelectionMode="Single"
|
||||
SelectionUnit="FullRow">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn MinWidth="300" Binding="{Binding WorkDay}">
|
||||
<DataGridTemplateColumn Width="80">
|
||||
<DataGridTemplateColumn.Header>
|
||||
<CheckBox
|
||||
x:Name="HeaderSelectAll"
|
||||
Content="全选"
|
||||
DataContext="{Binding DataContext, ElementName=DetailDatagrid}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Checked">
|
||||
<prism:InvokeCommandAction Command="{Binding SelectAllFilesCmd}" CommandParameter="True" />
|
||||
</i:EventTrigger>
|
||||
<i:EventTrigger EventName="Unchecked">
|
||||
<prism:InvokeCommandAction Command="{Binding SelectAllFilesCmd}" CommandParameter="False" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</CheckBox>
|
||||
</DataGridTemplateColumn.Header>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Focusable="False"
|
||||
IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsThreeState="False" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Focusable="False"
|
||||
IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsThreeState="False" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn
|
||||
MinWidth="200"
|
||||
Binding="{Binding WorkDay}"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock FontWeight="Bold" Text="文件名称/日期" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
<!-- CommandParameter="{Binding ElementName=MainDatagrid, Path=SelectedItem}" -->
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="SelectionChanged">
|
||||
<prism:InvokeCommandAction Command="{Binding FileGridSelectionChangedCmd}" CommandParameter="{Binding ElementName=DetailDatagrid, Path=SelectedItem}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</DataGrid>
|
||||
|
||||
<!-- 忙碌遮罩 -->
|
||||
<Grid
|
||||
x:Name="BusyOverlay"
|
||||
Grid.Row="1"
|
||||
Panel.ZIndex="999"
|
||||
Background="#66000000"
|
||||
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Border
|
||||
Padding="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Background="White"
|
||||
CornerRadius="6">
|
||||
<StackPanel>
|
||||
<ProgressBar
|
||||
Width="220"
|
||||
Height="6"
|
||||
IsIndeterminate="True" />
|
||||
<TextBlock
|
||||
Margin="0,10,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="Black"
|
||||
Text="{Binding BusyMessage}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
HandValueCommand="{Binding Source={StaticResource Proxy}, Path=Data.HandValueCmd}"
|
||||
HandValueMVParameter="{Binding EngMvValue}"
|
||||
HandValueSVParameter="{Binding EngSvValue}"
|
||||
IsEnabled="False"
|
||||
MeterName="{Binding NameNoUnit}"
|
||||
PVValue="{Binding EngPvValue}"
|
||||
SVValue="{Binding EngSvValue}"
|
||||
@@ -837,7 +838,7 @@
|
||||
</StackPanel>
|
||||
</Grid>-->
|
||||
<materialDesign:Card Margin="0,0" materialDesign:ElevationAssist.Elevation="Dp2">
|
||||
<ItemsControl ItemsSource="{Binding ListHandSwitchData}">
|
||||
<ItemsControl IsEnabled="False" ItemsSource="{Binding ListHandSwitchData}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical" />
|
||||
@@ -867,7 +868,7 @@
|
||||
|
||||
<!--<svg1:SVGImage Grid.Column="1" Source="E:\图库资源\SVGEdit\CapMachineOutput.svg" RenderTransformOrigin="0.5,0.5" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Margin="3" />-->
|
||||
<!-- inkscape -->
|
||||
<Canvas Grid.Column="1">
|
||||
<Canvas Grid.Column="1" Visibility="Visible">
|
||||
<Canvas.Background>
|
||||
<ImageBrush ImageSource="\Assets\Images\CapMachineOutput1.png" />
|
||||
</Canvas.Background>
|
||||
@@ -1002,15 +1003,15 @@
|
||||
CellTitle="吸气口温度"
|
||||
CellUnit="{Binding InhTempTag.Unit}"
|
||||
CellValue="{Binding InhTempTag.EngPvValueStr}" />
|
||||
<Controls:ValueShow
|
||||
<!--<Controls:ValueShow
|
||||
Canvas.Left="551"
|
||||
Canvas.Top="272"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
CellTitle="吸气压力MV"
|
||||
CellUnit="%"
|
||||
CellValue="{Binding InhPressTag.EngMvValue}" />
|
||||
<Controls:ValueShow
|
||||
CellValue="{Binding InhPressTag.EngMvValue}" />-->
|
||||
<!--<Controls:ValueShow
|
||||
Canvas.Left="1003"
|
||||
Canvas.Top="152"
|
||||
HorizontalAlignment="Left"
|
||||
@@ -1065,7 +1066,7 @@
|
||||
VerticalAlignment="Center"
|
||||
CellTitle="吸气温度MV"
|
||||
CellUnit="%"
|
||||
CellValue="{Binding InhTempTag.EngMvValue}" />
|
||||
CellValue="{Binding InhTempTag.EngMvValue}" />-->
|
||||
<Label
|
||||
Canvas.Left="1339"
|
||||
Canvas.Top="225"
|
||||
|
||||
@@ -621,7 +621,7 @@
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock FontWeight="Bold" Text="排气压力
(MpaA)" />
|
||||
<TextBlock FontWeight="Bold" Text="排气压力
(BarA)" />
|
||||
</DataGridTemplateColumn.Header>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@@ -632,7 +632,7 @@
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock FontWeight="Bold" Text="吸气压力
(MpaA)" />
|
||||
<TextBlock FontWeight="Bold" Text="吸气压力
(BarA)" />
|
||||
</DataGridTemplateColumn.Header>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@@ -676,7 +676,7 @@
|
||||
|
||||
<!--<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock FontWeight="Bold" Text="润滑油压力
(MpaA)" />
|
||||
<TextBlock FontWeight="Bold" Text="润滑油压力
(BarA)" />
|
||||
</DataGridTemplateColumn.Header>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@@ -687,7 +687,7 @@
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock FontWeight="Bold" Text="COND2压力
(MpaA)" />
|
||||
<TextBlock FontWeight="Bold" Text="COND2压力
(BarA)" />
|
||||
</DataGridTemplateColumn.Header>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@@ -1371,7 +1371,7 @@
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
FontWeight="Bold"
|
||||
Text="排气压力 (MpaA)" />
|
||||
Text="排气压力 (BarA)" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<Controls:MeterConfig
|
||||
@@ -1405,7 +1405,7 @@
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
FontWeight="Bold"
|
||||
Text="吸气压力 (MpaA)" />
|
||||
Text="吸气压力 (BarA)" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<Controls:MeterConfig
|
||||
@@ -1508,7 +1508,7 @@
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
FontWeight="Bold"
|
||||
Text="润滑油压力 (MpaA)" />
|
||||
Text="润滑油压力 (BarA)" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<Controls:MeterConfig
|
||||
@@ -1576,7 +1576,7 @@
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
FontWeight="Bold"
|
||||
Text="COND2压力 (MpaA)" />
|
||||
Text="COND2压力 (BarA)" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<Controls:MeterConfig
|
||||
|
||||
@@ -167,11 +167,11 @@
|
||||
MappingName="Speed"
|
||||
NumberDecimalDigits="0" />
|
||||
<syncfusion:GridNumericColumn
|
||||
HeaderText="排气压力(MpaA)"
|
||||
HeaderText="排气压力(BarA)"
|
||||
MappingName="ExPress"
|
||||
NumberDecimalDigits="2" />
|
||||
<syncfusion:GridNumericColumn
|
||||
HeaderText="吸气压力(MpaA)"
|
||||
HeaderText="吸气压力(BarA)"
|
||||
MappingName="InhPress"
|
||||
NumberDecimalDigits="2" />
|
||||
<syncfusion:GridNumericColumn
|
||||
@@ -184,11 +184,11 @@
|
||||
MappingName="Cond1Temp"
|
||||
NumberDecimalDigits="1" />
|
||||
<syncfusion:GridNumericColumn
|
||||
HeaderText="润滑油压力(MpaA)"
|
||||
HeaderText="润滑油压力(BarA)"
|
||||
MappingName="LubePress"
|
||||
NumberDecimalDigits="2" />
|
||||
<syncfusion:GridNumericColumn
|
||||
HeaderText="COND2压力(MpaA)"
|
||||
HeaderText="COND2压力(BarA)"
|
||||
MappingName="Cond2Press"
|
||||
NumberDecimalDigits="2" />
|
||||
<syncfusion:GridNumericColumn
|
||||
|
||||
Reference in New Issue
Block a user