Files
CapMachine/CapMachine.Wpf/Services/ProRuntimeService.cs
2025-02-27 15:28:04 +08:00

1049 lines
57 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
using CapMachine.Model.MeterConfig;
using Masuit.Tools;
using System.Timers;
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;
ProRunChannel = MachineRtDataService.ProRunChannel;
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>(),
}
};
//从变量集合中加载PLC转制的配置数据
ListPlcLoadConfigCell = new List<PlcLoadConfigCell>();
foreach (var itemKeyValue in MachineRtDataService.TagManger.DicTags)
{
//是否未仪表的参数
if (itemKeyValue.Value.IsMeter)
{
ListPlcLoadConfigCell.Add(new PlcLoadConfigCell()
{
Name = itemKeyValue.Key,
Address = itemKeyValue.Value.SVAddress,
Precision = itemKeyValue.Value.Precision,
});
}
}
//驱动实例
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>
/// 加载选中的程序运行集合
/// 目前步骤设置常值是OK的但是在斜坡多步骤里面也可以设置 50-50 10秒的常值设置那么在打点时上面的两个常值都能识别
/// </summary>
public void LoadProSegRun(List<ProSegRun> SelectedListProSegRun)
{
if (SelectedListProSegRun == null || SelectedListProSegRun.Count() == 0)
{
return;
}
//取消之前的程序执行
EndProRun();
//先清空之前的步骤数据
foreach (var itemProExModel in ListProExModel)
{
itemProExModel.ListProStepExe.Clear();
itemProExModel.ListSlopExStep.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))
{
//单行步骤中包含多个仪表参数的配置,需要逐个仪表参数手动操作解析
//统计当前步骤itemStep的速度所有时间供后面的其他参数使用因为其他的参数也是牟定当前步骤速度是总时间在这个步骤中所有的参数的总时间是一样的
var SpeedStepTotaolTime = 0;
//********* 单个【速度】步骤信息的解析 *********
{
var CurMeterName = "速度";
if (itemStep.MeterSpeeds != null && itemStep.MeterSpeeds.Any())
{
switch (itemStep.MeterSpeeds.FirstOrDefault()!.ValueType)
{
case ConfigValueType.Constant: //常值
//常值没有斜率和多个步骤,就一个总时间
SpeedStepTotaolTime = itemStep.MeterSpeeds.FirstOrDefault()!.KeepTime;
//常值的话就一个数据,循环执行一次
foreach (var itemMeterValueCell in itemStep.MeterSpeeds)
{
var Pid = new ConfigPID();
if (FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).Any())
{
Pid = FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).First();
}
var Limit = new ConfigLimit();
if (FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).Any())
{
Limit = FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).First();
}
var Alarm = new ConfigAlarm();
if (FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).Any())
{
Alarm = FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).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.LimitNo,
AlarmNo = itemMeterValueCell.AlarmNo,
PIDNo = itemMeterValueCell.PIDNo,
CurConfigPIDDto = Mapper.Map<ConfigPIDDto>(Pid),
CurConfigLimitDto = Mapper.Map<ConfigLimitDto>(Limit),
CurConfigAlarmDto = Mapper.Map<ConfigAlarmDto>(Alarm),
ProStepInfo = $"{itemStep.StepNo}-{itemMeterValueCell.StepNo}",
});
}
break;
case ConfigValueType.Slope: //斜率
//斜率有多个步骤和循环的次数,统计一个总时间
SpeedStepTotaolTime = itemStep.SpeedCycle * itemStep.MeterSpeeds.Sum(a => a.KeepTime);
//根据循环次数确定
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.PIDNo).Any())
{
Pid = FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).First();
}
var Limit = new ConfigLimit();
if (FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).Any())
{
Limit = FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).First();
}
var Alarm = new ConfigAlarm();
if (FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).Any())
{
Alarm = FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).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.LimitNo,
AlarmNo = itemMeterValueCell.AlarmNo,
PIDNo = itemMeterValueCell.PIDNo,
CurConfigPIDDto = Mapper.Map<ConfigPIDDto>(Pid),
CurConfigLimitDto = Mapper.Map<ConfigLimitDto>(Limit),
CurConfigAlarmDto = Mapper.Map<ConfigAlarmDto>(Alarm),
ProStepInfo = $"{itemStep.StepNo}-{itemMeterValueCell.StepNo}",
MeterName = CurMeterName,
});
}
}
break;
default:
break;
}
}
}
//********* 单个【排气压力】步骤信息的解析 *********
{
var CurMeterName = "排气压力";
if (itemStep.MeterExPresss != null && itemStep.MeterExPresss.Any())
{
switch (itemStep.MeterExPresss.FirstOrDefault()!.ValueType)
{
case ConfigValueType.Constant: //常值
//常值的话就一个数据,循环执行一次
foreach (var itemMeterValueCell in itemStep.MeterExPresss)
{
var Pid = new ConfigPID();
if (FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).Any())
{
Pid = FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).First();
}
var Limit = new ConfigLimit();
if (FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).Any())
{
Limit = FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).First();
}
var Alarm = new ConfigAlarm();
if (FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).Any())
{
Alarm = FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).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.LimitNo,
AlarmNo = itemMeterValueCell.AlarmNo,
PIDNo = itemMeterValueCell.PIDNo,
CurConfigPIDDto = Mapper.Map<ConfigPIDDto>(Pid),
CurConfigLimitDto = Mapper.Map<ConfigLimitDto>(Limit),
CurConfigAlarmDto = Mapper.Map<ConfigAlarmDto>(Alarm),
ProStepInfo = $"{itemStep.StepNo}-{itemMeterValueCell.StepNo}",
});
}
break;
case ConfigValueType.Slope:
//带斜率
//根据循环次数确定
var Cycle = GetCycleBySpeed(itemStep.MeterSpeeds, itemStep.SpeedCycle, itemStep.MeterExPresss.Select(p => new MeterCom { Constant = p.Constant, KeepTime = p.KeepTime, StepNo = p.StepNo, ValueType = p.ValueType }).ToList());
for (int StepCycleIndex = 1; StepCycleIndex <= Cycle; StepCycleIndex++)
{
//根据循环次数执行
foreach (var itemMeterValueCell in itemStep.MeterExPresss)
{
var Pid = new ConfigPID();
if (FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).Any())
{
Pid = FreeSql.Select<ConfigPID>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.PIDNo).First();
}
var Limit = new ConfigLimit();
if (FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).Any())
{
Limit = FreeSql.Select<ConfigLimit>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.LimitNo).First();
}
var Alarm = new ConfigAlarm();
if (FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).Any())
{
Alarm = FreeSql.Select<ConfigAlarm>().Where(a => a.MeterName == CurMeterName && a.IndexNo == itemMeterValueCell.AlarmNo).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.LimitNo,
AlarmNo = itemMeterValueCell.AlarmNo,
PIDNo = itemMeterValueCell.PIDNo,
CurConfigPIDDto = Mapper.Map<ConfigPIDDto>(Pid),
CurConfigLimitDto = Mapper.Map<ConfigLimitDto>(Limit),
CurConfigAlarmDto = Mapper.Map<ConfigAlarmDto>(Alarm),
ProStepInfo = $"{itemStep.StepNo}-{itemMeterValueCell.StepNo}",
MeterName = CurMeterName,
});
}
}
break;
default:
break;
}
}
else
{
//判断当前的参数是全部都没有设置还是这一步没有设置,如果这个步骤没有设置,则沿用上一个步骤数据
var CurMeterListStepExe = ListProExModel.FindFirst(a => a.MeterName == CurMeterName).ListProStepExe;
if (CurMeterListStepExe.Any())
{
//之前有步骤数据的话,则直接使用上一步的数据
//Copy这个步骤的数据
var LastStepData = CurMeterListStepExe.OrderByDescending(a => a.MeterStep).FirstOrDefault().DeepClone();
//处理这个步骤的数据-处理按照常值的恒定的模式运行,就是维持结束的常值数据
LastStepData!.MeterStep = LastStepData.MeterStep + 1;//步骤+1
LastStepData.KeepTime = SpeedStepTotaolTime;//时间是整个时间
LastStepData.ExistSlop = false;
LastStepData.StartSV = LastStepData.EndSV;
LastStepData.ProStepInfo = $"{itemStep.StepNo}-{1}";
//添加
CurMeterListStepExe.Add(LastStepData);
//SpeedStepTotaolTime
}
else
{
//之前步骤没有数据的话,则放弃,不做任何处理
}
LogService.Warn($"【名称】: {CurMeterName} - 未找到步骤信息。步骤为空");
}
}
}
}
}
}
StartProRun();
}
/// <summary>
/// 处理后获取SV的数据
/// </summary>
/// <returns></returns>
private int GetSVByProcess(double SV, string Name)
{
var Data = ListPlcLoadConfigCell.Where(a => a.Name.Contains(Name));
if (Data.Any())
{
return (int)(SV * (Data.FirstOrDefault()!.Precision));
}
else
{
LogService.Warn($"【名称】: {Name} - 未找到对应的参数配置,数据转换格式失败");
//未找到的话,则直接返回
return (int)SV;
}
}
/// <summary>
/// 根据速度表时间获取当前参数的循环的次数
/// 只考虑斜率下的循环次数
/// 常值不考虑,调用方已经考虑了常值
/// </summary>
/// <param name="StepNo"></param>
/// <returns></returns>
private int GetCycleBySpeed(List<MeterSpeed> MeterSpeeds, int SpeedCycle, List<MeterCom> MeterComs)
{
if (MeterComs != null && MeterComs.Count > 0 && MeterSpeeds != null && MeterSpeeds.Count > 0)
{
//目标参数常值和斜坡的判断
if (MeterComs.Where(a => a.ValueType == ConfigValueType.Slope).Count() > 0)
{
//速度是常值还是斜率判断
if (MeterSpeeds != null && MeterSpeeds.Where(a => a.ValueType == ConfigValueType.Slope).Count() > 0)
{
//速度全部时间
var TotalTime = MeterSpeeds.Sum(a => a.KeepTime) * SpeedCycle;
//目标参数的全部时间
var MeterSlopTime = MeterComs.Sum(a => a.KeepTime);
if (MeterSlopTime != 0)
{
return TotalTime / MeterSlopTime;
}
else
{
//目标参数全部时间为0认为不执行不进行操作
return 0;
}
}
else
{
//速度是常值
var TotalTime = MeterSpeeds!.FirstOrDefault()!.KeepTime;
var MeterConstTime = MeterComs.Sum(a => a.KeepTime);
if (MeterConstTime != 0)
{
return TotalTime / MeterConstTime;
}
else
{
//目标参数全部时间为0认为不执行不进行操作
return 0;
}
}
}
else
{
// meterComs 常值 就一步了,执行一次,没有循环
return 1;
}
}
else
{
//集合没有数据,不进行操作
return 0;
}
}
#region
/// <summary>
/// 暂停的时间
/// </summary>
public int PauseSecTime { get; set; }
/// <summary>
/// 暂停开始时间
/// </summary>
public DateTime PauseStartDt { get; set; }
/// <summary>
/// 暂停结束时间
/// </summary>
public DateTime PauseEndDt { get; set; }
/// <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;
}
ProRunTaskScanTimeEnable = true;
//运行扫描任务
ProRunTimeScan();
}
/// <summary>
/// 结束程序调度执行
/// </summary>
public void EndProRun()
{
ProRunTaskScanTimeEnable = false;
ProRunTimeScanTokenSource.Cancel();
//先清空当前步骤数据
foreach (var itemProExModel in ListProExModel)
{
itemProExModel.ListProStepExe.Clear();
itemProExModel.ListSlopExStep.Clear();
}
}
/// <summary>
/// 暂停程序调度执行 continue
/// </summary>
public void PauseProRun()
{
//开始暂停的计时
PauseStartDt = DateTime.Now;
//取消扫描
ProRunTaskScanTimeEnable = false;
ProRunTimeScanTokenSource.Cancel();
//斜坡打点暂定
foreach (var itemProExModel in ListProExModel)
{
itemProExModel.PauseSlopExCyclePause();
}
}
/// <summary>
/// 继续程序调度执行
/// </summary>
public void ContinueProRun()
{
PauseEndDt = DateTime.Now;
//统计的暂停的时间
var PauseTime = (PauseEndDt - PauseStartDt).TotalSeconds;
//斜坡打点暂定
foreach (var itemProExModel in ListProExModel)
{
itemProExModel.ContinueSlopExCyclePause();
itemProExModel.StepEndDt = itemProExModel.StepEndDt.AddSeconds(PauseTime < 0 ? 0 : PauseTime);
}
//然后继续运行
ProRunTaskScanTimeEnable = true;
//运行扫描任务
ProRunTimeScan();
}
/// <summary>
/// 运行任务的Task扫描时间是否启用这个等级较高为False时不进行扫描整个方法取消执行
/// 扫描时间判定是否切入下一步
/// </summary>
private bool ProRunTaskScanTimeEnable { get; set; } = true;
/// <summary>
/// 任务取消管理
/// 用于管理取消操作
/// </summary>
public CancellationTokenSource ProRunTimeScanTokenSource { get; set; } = new CancellationTokenSource();
/// <summary>
/// 运行时间扫描
/// </summary>
private void ProRunTimeScan()
{
ProRunTimeScanTokenSource = new CancellationTokenSource();
ProRunTimeScanTask = Task.Run(async () =>
{
while (ProRunTaskScanTimeEnable)
{
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()}");
}
}, ProRunTimeScanTokenSource.Token);
}
/// <summary>
/// 队列通道
/// 当前队列消费触发的数据记录
/// </summary>
public Channel<ProRunChannelData> ProRunChannel { get; set; }
// = 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
}
}