Files
602_WGJ/JinYuan.ControlCenter/ControlCenter.cs
T

1917 lines
82 KiB
C#
Raw Normal View History

2025-07-16 18:08:40 +08:00
using JinYuan.CommunicationLib.Enum;
using JinYuan.CommunicationLib.Helper;
using JinYuan.DataConvertLib;
using JinYuan.Helper;
using JinYuan.MES.Enums;
using JinYuan.MES.Models;
using JinYuan.Models;
using JinYuan.VirtualDataLibrary;
using Newtonsoft.Json;
using PLCCommunication;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Runtime.CompilerServices.RuntimeHelpers;
namespace JinYuan.ControlCenters
{
public partial class ControlCenter
{
/// <summary>
/// 打印日志方法
/// </summary>
/// <param name="Message"></param>日志信息
/// <param name="FileName"></param>文件夹名字
public static void LogMessage(string Message, string FileName)
{
string filePath = FileName + "//" + DateTime.Now.ToString("yyyy-MM-dd"); // 日志文件存放路径,默认在debug目录下
string filePath2 = FileName + "//" + DateTime.Now.ToString("yyyy-MM-dd") + "//Mylog.txt";//也可以加上时间
//string file=DateTime.Now+"log.txt";
//检查文件夹是否存在,否则新建
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
string logMessage = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}: {Message}";//打印出现的时间
2025-07-29 15:14:39 +08:00
// 将消息写入日志文件
2025-07-16 18:08:40 +08:00
using (StreamWriter writer = new StreamWriter(filePath2, true))
{
writer.WriteLine(logMessage);
}
}
/// <summary>
/// 打印错误日志方法
/// </summary>
/// <param name="errorMessage"></param>
public static void LogErrorMessage(string errorMessage)
{
string filePath = "Mylog.txt"; // 日志文件存放路径,默认在debug目录下
//也可以加上时间
//string file=DateTime.Now+"log.txt";
string logMessage = $"{DateTime.Now}: {errorMessage}";//打印出现问题的时间
// 将错误消息写入日志文件
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine(logMessage);
}
}
private static object uiLock = new object();
private Dictionary<string, dgStationFunction> DicStationFunction;
/// <summary>
/// 定时器-定时刷新状态和数据
/// </summary>
private System.Timers.Timer Timer_RefreshData;
/// <summary>
/// 智能电表
/// </summary>
private System.Timers.Timer ProcessMeter = null;
//创建委托对象
private Action<SysLog> AddAlarmDelegate;
//创建实时报警集合
private ObservableCollection<string> actualAlarmList = new ObservableCollection<string>();
//所有归档变量的名称l集合
private List<string> varNameList;
/// <summary>
/// 窗体实例
/// </summary>
private static ControlCenter _instance;
public static ControlCenter Instance
{
get
{
lock (uiLock)
{
if (_instance == null)
{
_instance = new ControlCenter();
}
return _instance;
}
}
}
private ControlCenter()
{
GetAlarmData();
InitFunc();
IntiDevice();
Timer_RefreshData = new System.Timers.Timer(1000);
Timer_RefreshData.Elapsed += Timer_RefreshData_Elapsed;
Timer_RefreshData.Start();
//删除30天内日志
DeleteLog.Start(CommonMethods.strDeletepath);
if (!CommonMethods.IsRun)
{
CommonMethods.ResetEventRecv.Reset();
}
}
/// <summary>
/// 初始化 工位方法,添加到字典里面
/// </summary>
private void InitFunc()
{
DicStationFunction = new Dictionary<string, dgStationFunction>();
2025-07-29 15:14:39 +08:00
DicStationFunction.Add("电芯进站", FeedingStation);
//DicStationFunction.Add("NG出站", NGStation);
//DicStationFunction.Add("外观检测出站", BlankingStation);
2025-07-16 18:08:40 +08:00
for (int i = 0; i < CommonMethods.ChatLineCount; i++)
{
Queue<double> doubles = new Queue<double>();
CommonMethods.QPlanenessData.Add(doubles);
}
}
public static string devPath = Application.StartupPath + "\\Config\\Device.ini";
public static string groupPath = Application.StartupPath + "\\Config\\Group.xlsx";
public static string variablePath = Application.StartupPath + "\\Config\\Variable.xlsx";
#region PLC
public void IntiDevice()
{
//var result = GetDeviceByPath(CommonMethods.settingPath);
var result = LoadDevice(devPath, groupPath, variablePath);
if (result.IsSuccess)
{
//获取到设备对象
CommonMethods.plcDevice = result.Content;
//设置一下大小端
CommonMethods.plcDevice.DataFormat = (int)DataFormat.CDAB;
//初始化
CommonMethods.plcDevice.Init();
//报警处理
//CommonMethods.plcDevice.AlarmTriggerEvent += PlcDevice_AlarmTriggerEvent;
//开启多线程
CommonMethods.plcDevice.Cts = new CancellationTokenSource();
//按工位读取通信组
CommonMethods.ListOmronGroups = CommonMethods.plcDevice.WorkVarList;
//风速仪器
//CommonMethods.AntiDustAirSpeed = GetList<float>(1);
//按工位读取数据线程
CreatePLCThread();
}
else
{
CommonMethods.AddLog(true, "加载配置文件失败:" + result.Message);
}
}
private void PlcDevice_AlarmTriggerEvent(object sender, AlarmEventArgs e)
{
switch (actualAlarmList.Count)
{
case 0:
CommonMethods.SlideAlarmText = "当前无报警";
break;
default:
CommonMethods.SlideAlarmText = string.Join(" ", actualAlarmList);
break;
}
}
#region 创建PLC线程 几个工位就几个线程
/// <summary>
/// 按工位读取线程
/// </summary>
private void CreatePLCThread()
{
//开启工位读取线程
if (CommonMethods.ListOmronGroups != null)
{
foreach (var item in CommonMethods.ListOmronGroups)
{
if (item.IsActive)
{
Thread thread = new Thread(new ParameterizedThreadStart(ReadPLCMWorkModel));
thread.IsBackground = true;
thread.Priority = ThreadPriority.Highest;
thread.Start(item);
}
}
}
//开启循环读取线程
Task.Run(new Action(() =>
{
PLCCommunication(CommonMethods.plcDevice);
}), CommonMethods.plcDevice.Cts.Token);
//开启监控焊机功率
//GetDataFromDatabasePower();
}
#endregion
#region 循环读取PLC工位状态
/// <summary>
/// 读取PLC循环工位
/// </summary>
/// <param name="plcModel"></param>
///
Stopwatch sw1 = new Stopwatch();
Stopwatch sw3 = new Stopwatch();
private void ReadPLCMWorkModel(object plcModel)
{
//as 类型转换
Group pf = plcModel as Group;
bool sta = CommonMethods.IsExit;
2025-07-29 15:14:39 +08:00
while (!CommonMethods.IsExit)
2025-07-16 18:08:40 +08:00
{
CommonMethods.ResetEventRecv.WaitOne();
if (CommonMethods.IsRun)
{
if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
{
try
{
//开始读取信号判断
JYResult<short> OpenValue = CommonMethods.PlcLink.ReadValue<JYResult<short>>(pf.VarList[0].VarAddress, Data_Type.Short);//当读取值为就执行操作
if (OpenValue.IsSuccess && OpenValue.Content == 1)//读取先置位
{
sw1.Restart();
JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>($"{pf.VarList[1].VarAddress}", Data_Type.ArrByte, Convert.ToUInt16(pf.VarList[1].OffsetOrLenght));
sw1.Stop();
CommonMethods.AddDataMonitorLog(0, $"{pf.GroupName},耗时:{sw1.Elapsed.TotalMilliseconds}ms");
LogHelper.Instance.WriteLog("循环读取PLC工位", $"读取工位:{pf.GroupName},启动读取字节共耗时:" + sw1.Elapsed.TotalMilliseconds);
//置位 PLC-防止重复读取
CommonMethods.PlcLink.WriteInt16(pf.VarList[0].VarAddress, 2);//置位,读取进行中的标志
if (resByte == null)
{
CommonMethods.AddDataMonitorLog(0, $"上料工位:{pf.GroupName},起始地址:{pf.VarList[1].VarAddress},得到空字节数组");
LogHelper.Instance.WriteLog("循环读取PLC上料工位", $"读取工位:{pf.GroupName},起始地址:{pf.VarList[1].VarAddress},得到空字节数组");
}
else
{
2025-07-29 15:14:39 +08:00
//if (DicStationFunction.TryGetValue(pf.GroupName, out var func))
//{
// func.BeginInvoke(resByte, pf, ar =>
// {
// try { func.EndInvoke(ar); }
// catch (Exception ex)
// {
// CommonMethods.AddLog(true, ex.Message);
// LogHelper.Instance.WriteEX(ex);
// }
// }, null);
//}
//// private Dictionary<string, dgStationFunction> DicStationFunction;
DicStationFunction[pf.GroupName].BeginInvoke(resByte, pf, null, null);//信息解析
}
2025-07-16 18:08:40 +08:00
}
}
catch (Exception ex)
{
CommonMethods.AddLog(true, ex.Message);
LogHelper.Instance.WriteEX(ex);
}
}
Thread.Sleep(200);
}
}
}
#endregion
private void PLCCommunication(Device device)
{
while (!CommonMethods.plcDevice.Cts.IsCancellationRequested)
{
CommonMethods.ResetEventRecv.WaitOne();
if (CommonMethods.IsRun)
{
if (device.IsConnected)
{
//读取
//LogErrorMessage("Ready read 1 s");
JYResult<short> result = CommonMethods.PlcLink.ReadValue<JYResult<short>>("D100", Data_Type.Short);
if (result.IsSuccess)
{
//if(result.Content == 0)
{
//延时2s发送心跳
Thread.Sleep(2000);
//LogErrorMessage("Ready write");
device.ErrorTimes = 0;
JYResult res = CommonMethods.PlcLink.WriteValue("D100", 1, Data_Type.Short);
if (!res.IsSuccess)
{
device.IsConnected = false;
CommonMethods.AddLog(true, "心跳写入异常:" + res.Message);
}
//LogErrorMessage("Write done");
}
2025-07-29 15:14:39 +08:00
2025-07-16 18:08:40 +08:00
}
else
{
device.ErrorTimes++;
//容错次数的意思是指连续多少次错误,会触发重连(连续3次)
if (device.ErrorTimes >= device.AllowErrorTimes)
{
device.IsConnected = false;
CommonMethods.AddLog(true, "PLC链接异常:" + result.Message);
break;
}
}
}
else
{
//判断是否为第一次连接
if (!device.IsFirstConnect)
{
Thread.Sleep(device.ReConnectTime);
CommonMethods.PlcLink.Disconnect();
}
string msg = "";
var result = CommonMethods.PlcLink.Connect(ref msg);
if (result)
{
device.IsConnected = true;
CommonMethods.AddLog(false, device.IsFirstConnect ? $"PLC初次连接成功{msg}" : $"PLC重新连接成功{msg}");
}
else
{
device.IsConnected = false;
CommonMethods.AddLog(true, device.IsFirstConnect ? "PLC初次连接失败" : "PLC重新连接失败");
new MsgshowTip("与PLC链接断开,请检查通讯线路!").ShowDialog();
}
}
//如果是第一次连接,将标志位复位
if (device.IsFirstConnect)
{
device.IsFirstConnect = false;
}
}
}
}
#region 屏蔽
/// <summary>
/// 多线程执行方法
/// </summary>
/// <param name="plcDevice"></param>
//private void PLCCommunication(OmronDevice device)
//{
// while (!CommonMethods.plcDevice.Cts.IsCancellationRequested)
// {
// CommonMethods.ResetEventRecv.WaitOne();
// if (CommonMethods.IsRun)
// {
// if (device.IsConnected)
// {
// //读取
// foreach (var gp in device.GroupList)
// {
// if (gp.IsActive)
// {
// if (!gp.IsWorkRead)
// {
// var result = GetGroupValue(device, gp);
// if (result.IsSuccess)
// {
// device.ErrorTimes = 0;
// }
// else
// {
// device.ErrorTimes++;
// //容错次数的意思是指连续多少次错误,会触发重连
// if (device.ErrorTimes >= device.AllowErrorTimes)
// {
// device.IsConnected = false;
// CommonMethods.AddLog(true, "PLC链接异常:" + result.Message);
// break;
// }
// }
// }
// }
// Thread.Sleep(50);
// }
// }
// else
// {
// //判断是否为第一次连接
// if (!device.IsFirstConnect)
// {
// Thread.Sleep(device.ReConnectTime);
// CommonMethods.plc.DisConnect();
// }
// byte[] bytes = null;
// var result = CommonMethods.plc.Connect(device.IpAddress, device.Port, ref bytes);
// if (result)
// {
// device.IsConnected = true;
// CommonMethods.AddLog(false, device.IsFirstConnect ? $"PLC初次连接成功:SA1-{bytes[0]},DA1-{bytes[1]}" : $"PLC重新连接成功:SA1-{bytes[0]},DA1-{bytes[1]}");
// }
// else
// {
// device.IsConnected = false;
// CommonMethods.AddLog(true, device.IsFirstConnect ? "PLC初次连接失败" : "PLC重新连接失败");
// new MsgshowTip("与PLC链接断开,请检查通讯线路!").ShowDialog();
// }
// }
// //如果是第一次连接,将标志位复位
// if (device.IsFirstConnect)
// {
// device.IsFirstConnect = false;
// }
// }
// }
//}
//private void PLCCommunication(Device device)
//{
// while (!CommonMethods.plcDevice.Cts.IsCancellationRequested)
// {
// CommonMethods.ResetEventRecv.WaitOne();
// if (CommonMethods.IsRun)
// {
// if (device.IsConnected)
// {
// 读取
// foreach (var gp in device.GroupList)
// {
// if (gp.IsActive)
// {
// if (!gp.IsTiggerRead)
// {
// var result = GetHSLGroupValue(device, gp);
// if (result.IsSuccess)
// {
// device.ErrorTimes = 0;
// }
// else
// {
// device.ErrorTimes++;
// 容错次数的意思是指连续多少次错误,会触发重连
// if (device.ErrorTimes >= device.AllowErrorTimes)
// {
// device.IsConnected = false;
// CommonMethods.AddLog(true, "PLC链接异常:" + result.Message);
// break;
// }
// }
// }
// }
// }
// }
// else
// {
// 判断是否为第一次连接
// if (!device.IsFirstConnect)
// {
// Thread.Sleep(device.ReConnectTime);
// CommonMethods.PlcLink.Disconnect();
// }
// string msg = "";
// var result = CommonMethods.PlcLink.Connect(ref msg);
// if (result)
// {
// device.IsConnected = true;
// CommonMethods.AddLog(false, device.IsFirstConnect ? $"PLC初次连接成功{msg}" : $"PLC重新连接成功{msg}");
// }
// else
// {
// device.IsConnected = false;
// CommonMethods.AddLog(true, device.IsFirstConnect ? "PLC初次连接失败" : "PLC重新连接失败");
// new MsgshowTip("与PLC链接断开,请检查通讯线路!").ShowDialog();
// }
// }
// 如果是第一次连接,将标志位复位
// if (device.IsFirstConnect)
// {
// device.IsFirstConnect = false;
// }
// }
// }
//}
//private OperateResult GetHSLGroupValue(Device device, Group group)
//{
// var addResult = OmronHelper.OmronFinsAnalysisAddress(group.Start, false);
// if (addResult.IsSuccess == false) return OperateResult.CreateFailResult();
// var result = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>(group.Start, Data_Type.ArrByte, (ushort)group.Length);
// if (result.IsSuccess && result.Content.Length == group.Length * 2)
// {
// foreach (var variable in group.VarList)
// {
// var analysis = AnalysisStartAddress(variable.Start);
// if (analysis.IsSuccess)
// {
// int start = analysis.Content1;
// int offset = analysis.Content2;
// start -= BitConverter.ToInt16(new byte[] { addResult.Content2[1], addResult.Content2[0], addResult.Content2[2] }, 0);
// start *= 2;
// switch (variable.DataType.ToUpper())
// {
// case "BOOL":
// variable.VarValue = BitLib.GetBitFrom2BytesArray(result.Content, start, offset, false);
// break;
// case "BYTE":
// variable.VarValue = ByteLib.GetByteFromByteArray(result.Content, start);
// break;
// case "SHORT":
// variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "USHORT":
// variable.VarValue = UShortLib.GetUShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "INT":
// variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "UINT":
// variable.VarValue = UIntLib.GetUIntFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "FLOAT":
// variable.VarValue = FloatLib.GetFloatFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "LONG":
// variable.VarValue = LongLib.GetLongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "ULONG":
// variable.VarValue = ULongLib.GetULongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "DOUBLE":
// variable.VarValue = DoubleLib.GetDoubleFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "STRING":
// variable.VarValue = StringLib.GetStringFromByteArrayByEncoding(result.Content, start, (int)variable.Offset * 2, Encoding.ASCII);
// break;
// case "BYTEARRAY":
// variable.VarValue = ByteArrayLib.GetByteArrayFromByteArray(result.Content, start, (int)variable.Offset * 2);
// break;
// default:
// break;
// }
// var operateResult = MigrationLib.GetMigrationValue(variable.VarValue, variable.Scale.ToString(), variable.Offset.ToString());
// if (operateResult.IsSuccess)
// {
// variable.VarValue = operateResult.Content;
// }
// else
// {
// variable.VarValue = null;
// }
// //更新报警
// device.Update(variable);
// }
// else
// {
// return OperateResult.CreateFailResult(analysis.Message);
// }
// }
// }
// else
// {
// CommonMethods.Statues = new List<bool> { false, false, false, false };
// return OperateResult.CreateFailResult($"{group.GroupName}-通信组读取失败");
// }
// return OperateResult.CreateSuccessResult();
//}
/// <summary>
/// 单个组通信的方法
/// </summary>
/// <param name="device"></param>
/// <param name="group"></param>
/// <returns></returns>
//private OperateResult GetGroupValue(Device device, Group group)
//{
// var addResult = OmronHelper.OmronFinsAnalysisAddress(group.Start, false);
// if (addResult.IsSuccess == false) return OperateResult.CreateFailResult();
// var result = CommonMethods.plc.ReadByteArray(group.Start,(ushort)group.Length);
// if (result.IsSuccess && result.Content.Length == group.Length * 2)
// {
// foreach (var variable in group.VarList)
// {
// var analysis = AnalysisStartAddress(variable.Start);
// if (analysis.IsSuccess)
// {
// int start = analysis.Content1;
// int offset = analysis.Content2;
// start -= BitConverter.ToInt16(new byte[] { addResult.Content2[1], addResult.Content2[0], addResult.Content2[2] }, 0);
// start *= 2;
// switch (variable.DataType.ToUpper())
// {
// case "BOOL":
// variable.VarValue = BitLib.GetBitFrom2BytesArray(result.Content, start, offset, false);
// break;
// case "BYTE":
// variable.VarValue = ByteLib.GetByteFromByteArray(result.Content, start);
// break;
// case "SHORT":
// variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "USHORT":
// variable.VarValue = UShortLib.GetUShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "INT":
// variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "UINT":
// variable.VarValue = UIntLib.GetUIntFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "FLOAT":
// variable.VarValue = FloatLib.GetFloatFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "LONG":
// variable.VarValue = LongLib.GetLongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "ULONG":
// variable.VarValue = ULongLib.GetULongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "DOUBLE":
// variable.VarValue = DoubleLib.GetDoubleFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
// break;
// case "STRING":
// variable.VarValue = StringLib.GetStringFromByteArrayByEncoding(result.Content, start, (int)variable.Offset * 2, Encoding.ASCII);
// break;
// case "BYTEARRAY":
// variable.VarValue = ByteArrayLib.GetByteArrayFromByteArray(result.Content, start, (int)variable.Offset * 2);
// break;
// default:
// break;
// }
// var operateResult = MigrationLib.GetMigrationValue(variable.VarValue, variable.Scale.ToString(), variable.Offset.ToString());
// if (operateResult.IsSuccess)
// {
// variable.VarValue = operateResult.Content;
// }
// else
// {
// variable.VarValue = null;
// }
// //更新报警
// device.Update(variable);
// }
// else
// {
// return OperateResult.CreateFailResult(analysis.Message);
// }
// }
// }
// else
// {
// CommonMethods.Statues = new List<bool> { false, false, false, false };
// return OperateResult.CreateFailResult($"{group.GroupName}-通信组读取失败");
// }
// return OperateResult.CreateSuccessResult();
//}
/// <summary>
/// 解析起始地址,获取索引 和 位偏移
/// </summary>
/// <param name="start">0 1 2 10.0 10.10</param>
/// <param name="frombase"></param>
/// <returns></returns>
//private OperateResult<int, int> AnalysisStartAddress(string start, int frombase = 10)
//{
// try
// {
// if (start.Contains("."))
// {
// string[] result = start.Split('.');
// if (result.Length == 2)
// {
// return OperateResult.CreateSuccessResult(Convert.ToInt32(result[0], frombase), Convert.ToInt32(result[1]));
// }
// else
// {
// return OperateResult.CreateFailResult<int, int>($"变量地址格式填写不正确:{start}");
// }
// }
// else
// {
// return OperateResult.CreateSuccessResult<int, int>(Convert.ToInt32(start, frombase), 0);
// }
// }
// catch (Exception ex)
// {
// return OperateResult.CreateFailResult<int, int>($"变量地址 {start} 格式填写不正确:" + ex.Message);
// }
//}
#endregion
#region 加载设备信息
private OperateResult<Device> LoadDevice(string devicepath, string groupPath, string variablePath)
{
if (!File.Exists(devicepath))
{
CommonMethods.AddLog(true, "设备文件不存在");
return null;
}
Device device = new Device();
List<Group> gpList = LoadGroup(groupPath, variablePath);
if (gpList != null && gpList.Count > 0)
{
try
{
device.IPAddress = IniConfigHelper.ReadIniData("设备参数", "IP地址", "127.0.0.1", devicepath);
device.Port = Convert.ToInt32(IniConfigHelper.ReadIniData("设备参数", "端口号", "502", devicepath));
device.PLCType = IniConfigHelper.ReadIniData("设备参数", "PLC类型", "OmronFinsTcp_HSL", devicepath);
CommonMethods.mesConfig.siteCode = IniConfigHelper.ReadIniData("MES配置", "工厂代码", "1");
CommonMethods.mesConfig.lineCode = IniConfigHelper.ReadIniData("MES配置", "产线编号", "1");
CommonMethods.mesConfig.equipNum = IniConfigHelper.ReadIniData("MES配置", "设备编号", "1");
device.GroupList = gpList;
return OperateResult.CreateSuccessResult(device);
}
catch (Exception ex)
{
return OperateResult.CreateFailResult<Device>("请检查配置文件是否正确");
}
}
else
{
return OperateResult.CreateFailResult<Device>("请检查配置是否包含欧姆龙PLC");
}
}
///// <summary>
///// 通信组及通信变量的解析
///// </summary>
///// <param name="groupPath"></param>
///// <param name="variablePath"></param>
///// <returns></returns>
private List<Group> LoadGroup(string groupPath, string variablePath)
{
//判断文件是否存在
if (!File.Exists(groupPath))
{
CommonMethods.AddLog(true, "通信组文件不存在");
return null;
}
if (!File.Exists(variablePath))
{
CommonMethods.AddLog(true, "通信变量文件不存在");
return null;
}
//先解析通信组
List<Group> GpList = null;
try
{
GpList = MiniExcelLibs.MiniExcel.Query<Group>(groupPath).ToList();
}
catch (Exception ex)
{
CommonMethods.AddLog(true, $"通信组加载失败:{ex.Message}");
return null;
}
List<Variable> VarList = null;
try
{
VarList = MiniExcelLibs.MiniExcel.Query<Variable>(variablePath).ToList();
}
catch (Exception ex)
{
CommonMethods.AddLog(true, $"通信变量加载失败:{ex.Message}");
return null;
}
if (GpList != null && VarList != null)
{
foreach (var group in GpList)
{
group.VarList = VarList.FindAll(c => c.GroupName == group.GroupName).ToList();
}
return GpList;
}
else
{
return null;
}
}
#endregion
#region 屏蔽
/// <summary>
/// 读取配置文件,返回设备对象
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
///
//private OperateResult<OmronDevice> GetDeviceByPath(string path)
//{
// List<Project> projects = new ConfigManage().LoadProjects(path);
// if (projects != null && projects.Count >= 1)
// {
// Project project = projects[0];
// if (project.OmronList.Count > 0)
// {
// var device = project.OmronList[0];
// if (device.IsActive)
// {
// return OperateResult.CreateSuccessResult(device);
// }
// else
// {
// return OperateResult.CreateFailResult<OmronDevice>("请检查配置是否激活");
// }
// }
// else
// {
// return OperateResult.CreateFailResult<OmronDevice>("请检查配置是否包含欧姆龙PLC");
// }
// }
// else
// {
// return OperateResult.CreateFailResult<OmronDevice>("请检查配置文件是否正确");
// }
//}
#endregion
#endregion
#region 定时刷新数据
int TotalNum = 0;
int Regular = 0;
bool firstFresh = false;
bool freshed = false;
private void Timer_RefreshData_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var nowDate = DateTime.Now;
if (Regular >= 300)
{
Task.Run(() =>
{
UploadEquEnergy();
UPloadAnemograph();
});
Regular = 0;
}
if (TotalNum > 4)
{
GetEnergyData();
Refresh12HourProdQty();
GetDefectTypeQty();
ReadPLCComm();
//ClearNGData0();
GetASqlAlarmData(DateTime.Today, CommonMethods.strClass);
TotalNum = 0;
}
else if (TotalNum == 2)//设备状态读取
{
SetClass(); //变更班次
}
Task.Run(() =>
{
if (CommonMethods.plcDevice.IsConnected)
{
//PingEMCLink();
}
ShowStateEven_Run();
});
TotalNum++;
Regular++;
}
#endregion
#region 服务器连接状态检测
/// <summary>
/// 服务器连接状态检测
/// </summary>
bool isNgral = false;
//private void PingEMCLink()
//{
// try
// {
// string ipAddress = CommonMethods.mesConfig.RotueServerIP; // 要 ping 的 IP 地址
// Ping pingSender = new Ping();
// PingReply reply = pingSender.Send(ipAddress);
// if (reply.Status == IPStatus.Success)
// {
// CommonMethods.EMCStatues = true;
// if (!isNgral)
// {
// if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
// {
// JYResult result = CommonMethods.PlcLink.WriteValue("D80", 0, Data_Type.Short);//反馈PLC结果
// }
// CommonMethods.AddDataMonitorLog(0, $"服务器连接成功!");
// LogHelper.Instance.WriteLog($"服务器连接成功!");
// isNgral = true;
// }
// }
// else
// {
// CommonMethods.EMCStatues = false;
// if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
// {
// JYResult result = CommonMethods.PlcLink.WriteValue("D80", 1, Data_Type.Short);//反馈PLC结果
// }
// //CommonMethods.AddDataMonitorLog(1, $"服务器连接失败!解决办法:1、请检查MES网络,2、查看服务器是否正常!");
// LogHelper.Instance.WriteError($"服务器连接失败!", "系统报错");
// isNgral = true;
// //new MsgshowTip("与数据服务器链接断开!\n请检查MES网络或存储服务器!").ShowDialog();
// }
// }
// catch (Exception ex)
// {
// CommonMethods.EMCStatues = false;
// if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
// {
// JYResult result = CommonMethods.PlcLink.WriteValue("D80", 1, Data_Type.Short);//反馈PLC结果
// }
// //CommonMethods.AddDataMonitorLog(1, $"服务器连接失败!解决办法:1、请检查MES网络,2、查看服务器是否正常!");
// LogHelper.Instance.WriteError($"服务器连接失败!{ex}", "系统报错");
// isNgral = false;
// //new MsgshowTip("与数据服务器链接断开!\n请检查MES网络或存储服务器!").ShowDialog();
// }
//}
#endregion
#region 设备综合信息
/// <summary>
/// 读取PLC通用信息
/// </summary>
internal void ReadPLCComm()
{
if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
{
Task.Run(() =>
{
UpTotalCount(null);
});
CommonMethods.TotalQty = CommonMethods.PlcLink.ReadInt32("D15");//生产总数
CommonMethods.ProOKQty = CommonMethods.PlcLink.ReadInt32("D17");//良品总数
2025-07-29 15:14:39 +08:00
2025-07-16 18:08:40 +08:00
CommonMethods.Ppm = CommonMethods.PlcLink.ReadInt32("D13");
2025-07-28 11:12:06 +08:00
//CommonMethods.JiaDL = Convert.ToDouble(CommonMethods.PlcLink.ReadFloat("D11").ToString("F2"))/100;
2025-07-29 15:14:39 +08:00
CommonMethods.JiaDL = Convert.ToDouble(CommonMethods.PlcLink.ReadInt32("D11").ToString("F2")) / 100;
2025-07-16 18:08:40 +08:00
#region 开机时间/运行时间
CommonMethods.PlcOpenAndRunTime = GetList<int>(6, 0);
JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>($"D50", Data_Type.ArrByte, 12);
if (resByte.IsSuccess)
{
for (int i = 0; i < CommonMethods.PlcOpenAndRunTimeAdress.Count; i++)
{
CommonMethods.PlcOpenAndRunTime[i] = ShortLib.GetShortFromByteArray(resByte.Content, i * 4, DataFormat.CDAB);
}
}
#endregion
}
}
#endregion
#region 保存12小时产能数据
public int totalNum = 0; // 总数
public int okNum = 0; // 良品数
/// <summary>
/// 储存数据到数据库
/// </summary>
/// <param name="DataCount"></param>
public void UpTotalCount(int[] DataCount)
{
string strErr = "";
DateTime dateTime = DateTime.Now;
string strDate = dateTime.ToString("yyyy-MM-dd");
int Min = dateTime.Minute;
int Hour = dateTime.Hour;
if (Min < 30)
{
Hour -= 1;
}
if (dateTime.Hour < 30 && dateTime.Hour == 0)
{
Hour = 0;
}
//读取PLC投入总数
int ProdCurrAllQty = GetToDayHourQty(Hour, true);
//读取PLC产出数
int ProdCurrOKQty = GetToDayHourQty(Hour, false);
Hourprod mh = new Hourprod();
mh.FDate = strDate;
mh.FHour = Hour;
mh.ProdIn = ProdCurrAllQty;
mh.ProdOut = ProdCurrOKQty;
mh.TestTime = DateTime.Now;
mh.Ppm = CommonMethods.Ppm;
mh.JiaDL = Convert.ToDecimal(CommonMethods.JiaDL);
//更新
int res = CommonMethods.db.UpdateSingle(mh, it => new Hourprod() { ProdIn = mh.ProdIn, ProdOut = mh.ProdOut, TestTime = DateTime.Now, Ppm = mh.Ppm, JiaDL = mh.JiaDL, },
it => it.FDate == mh.FDate && it.FHour == mh.FHour);
if (res <= 0) //更新失败就新增保存
{
CommonMethods.db.AddReturnBool<Hourprod>(mh);
}
#region 屏蔽
// DateTime now = DateTime.Now;
// string day = now.ToString("yyyy-MM-dd HH:mm:ss");
// int Hour = 0;
// CommonMethods.LastHour = Convert.ToInt32(IniConfigHelper.ReadIniData("统计计数", "LastHour", "false"));
// CommonMethods.LastResetTime = IniConfigHelper.ReadIniData("统计计数", "LastResetTime", "false");
// CommonMethods.LastTotalNum = Convert.ToInt32(IniConfigHelper.ReadIniData("统计计数", "LastTotalOldNum", "false"));
// CommonMethods.LastOkNum = Convert.ToInt32(IniConfigHelper.ReadIniData("统计计数", "LastOkOldNum", "false"));
// if (now.Minute == 30 && (now.Second >= 0 && now.Second <= 3) && day != CommonMethods.LastResetTime)
// {
// // 每小时的0分0秒重置计数
// totalNum = 0;
// okNum = 0;
// CommonMethods.LastTotalNum = DataCount[0];
// CommonMethods.LastOkNum = DataCount[1];
// CommonMethods.LastResetTime = day;
// CommonMethods.LastHour = now.Hour;
// Hour = Convert.ToInt32($"{now.Hour}30");
// IniConfigHelper.WriteIniData("统计计数", "LastHour", CommonMethods.LastHour.ToString());
// IniConfigHelper.WriteIniData("统计计数", "LastResetTime", CommonMethods.LastResetTime);
// IniConfigHelper.WriteIniData("统计计数", "LastTotalOldNum", CommonMethods.LastTotalNum.ToString());
// IniConfigHelper.WriteIniData("统计计数", "LastOkOldNum", CommonMethods.LastOkNum.ToString());
// }
// else
// {
// // 读取PLC的数据(模拟数据)
// int[] productionData = DataCount;
// // 统计生产总数和良品数
// int newTotalNum = productionData[0] - CommonMethods.LastTotalNum;
// int newOkNum = productionData[1] - CommonMethods.LastOkNum;
// totalNum = newTotalNum;
// okNum = newOkNum;
// Hour = GetHour();
// // 计算百分比良率
// }
// Hourprod hourprod = new Hourprod();
// hourprod.FDate = now.Date.ToString("yyyy-MM-dd");
// hourprod.FHour = Hour;
// hourprod.ProdIn = totalNum;
// hourprod.ProdOut = okNum;
// hourprod.TestTime = now;
// //更新
// int res = CommonMethods.db.UpdateSingle(hourprod, it => new Hourprod() { ProdIn = hourprod.ProdIn, ProdOut = hourprod.ProdOut, TestTime = DateTime.Now },
// it => it.FDate == hourprod.FDate && it.FHour == hourprod.FHour);
// if (res == 0) //更新失败就新增保存
// {
// CommonMethods.db.AddReturnBool<Hourprod>(hourprod);
// }
#endregion
}
/// <summary>
/// 每小时产能读取处理
/// </summary>
/// <param name="hour"></param>
/// <param name="flag"></param>
/// <returns></returns>
private int GetToDayHourQty(int hour, bool flag)
{
try
{
string strAddr = "";
2025-07-29 15:14:39 +08:00
2025-07-16 18:08:40 +08:00
if (flag)//产出
{
2025-07-24 16:39:47 +08:00
//strAddr = "D" + (1032 + hour);
//1257
strAddr = "D" + (1040 + hour);
2025-07-16 18:08:40 +08:00
}
else//良品数
{
2025-07-24 16:39:47 +08:00
// strAddr = "D" + (1062 + hour);
//1257
strAddr = "D" + (1070 + hour);
2025-07-16 18:08:40 +08:00
}
int ProdNGQty = CommonMethods.PlcLink.ReadInt16(strAddr);
return ProdNGQty;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
return 0;
}
#endregion
#region 5、设备状态
/// <summary>
/// 定时获取设备状态
/// </summary>
/// <param name="mt"></param>
///
int OldStatues = CommonMethods.mesConfig.DeviceState; //默认状态是上一次退出程序是保存的状态
int StatuesCount = 0;
DateTime StatuesBeginTime = DateTime.Now.AddMinutes(-6); //默认时间是6分钟前,第一次获取状态时上传设备状态,不赋默认值,第一次打开程序会导致时间为空,首次启动不上传设备状态
bool isNewGuid = false;
string strGuidAlarm = CommonMethods.mesConfig.guidStr; //默认guid是上次退出程序保存的guid
bool isUpIdle = false;
List<AlarmData> AlarmDataTeam = new List<AlarmData>();
bool run_AlarmMark = CommonMethods.mesConfig.m_run_AlarmMark;
bool run_IdleMark = CommonMethods.mesConfig.m_run_IdelMark;
private void ShowStateEven_Run()
{
try
{
#region 上传设备状态
//设备状态 。Run:(正常运行)、Alert:(故障调试)、Idle:(闲置待机)、Maintain(停止运行)
//先确定设备是在自动还是手动状态下
if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
{
string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
bool isUpload = false;
string deviceStatus = string.Empty;
string deviceStatusDesc = string.Empty;
string strGuid = string.Empty;
short NewStatus = 100;
NewStatus = CommonMethods.PlcLink.ReadInt16("D10");
if (NewStatus != 100)
{
//新状态:故障,旧状态:正常
if (NewStatus == 3 && OldStatues == 1)
{
run_AlarmMark = true;
IniConfigHelper.WriteIniData("MES配置", "run_AlarmMark", "1");
} //第一次进入报警状态,把报警标志位true
//新状态:正常
if (NewStatus == 1)
{
run_AlarmMark = false;
IniConfigHelper.WriteIniData("MES配置", "run_AlarmMark", "0");
} //如果状态变为允许,把报警标志位false
if (run_AlarmMark)
{
NewStatus = 3;
} //有报警标志位,状态一直都是报警,直到下一次状态为运行
if (NewStatus == 4 && OldStatues == 1)
{
run_IdleMark = true;
IniConfigHelper.WriteIniData("MES配置", "run_IdleMark", "1");
} //第一次进入闲置状态,把闲置标志位true
if (NewStatus == 1)
{
run_IdleMark = false;
IniConfigHelper.WriteIniData("MES配置", "run_IdleMark", "0");
} //如果状态变为允许,把闲置标志位false
if (run_IdleMark)
{
NewStatus = 4;
} //有闲置标志位,状态一直都是闲置,直到下一次状态为运行
if (isUpIdle)
{
foreach (var item in AlarmDataTeam)
{
UpIdleData(item);
}
isUpIdle = false;
AlarmDataTeam.Clear();
}
// 判断是否需要上传设备状态
if (NewStatus != OldStatues)
{
LogMessage("OldStatues: " + OldStatues + "; NewStatus: " + NewStatus + "上传的GUID:" + strGuidAlarm, "设备状态改变日志");
if (OldStatues == 3 && NewStatus != 3)
{
ShowAlarmEven_Run(strGuidAlarm);
}
OldStatues = NewStatus;
alarmStartDate = "";
isRead = false;
isUpload = true;
StatuesBeginTime = Convert.ToDateTime(Date);
strGuidAlarm = Guid.NewGuid().ToString();
//当设备状态发生变化,保存【设备状态和guid】到本地配置文件,下次电脑重启时读取上一次设备状态和guid
IniConfigHelper.WriteIniData("MES配置", "guid", strGuidAlarm.Trim());
IniConfigHelper.WriteIniData("MES配置", "DeviceState", OldStatues.ToString());
}
else
{
if (Convert.ToDateTime(Date).Subtract(StatuesBeginTime).TotalSeconds >= 5 * 60) //时间间隔大雨5分钟
{
isUpload = true;
StatuesBeginTime = DateTime.Now;
}
//if (Convert.ToDateTime(Date).Subtract(StatuesBeginTime).TotalSeconds > 5 * 60)
//{
// isUpload = true;
// StatuesBeginTime = DateTime.Now;
//}
}
switch (NewStatus)
{
case 1:
CommonMethods.Statues = new List<bool> { true, false, false, false };
deviceStatus = "Run";
deviceStatusDesc = "正常运行";
if (isUpload)
{
CommonMethods.AddLog(false, "正常运行");
}
break;
//case 2:
// CommonMethods.Statues = new List<bool> { false, true, false, false };
// deviceStatus = "Maintain";
// deviceStatusDesc = "停止运行";
// if (isUpload)
// {
// CommonMethods.AddLog(false, "停止运行");
// }
// break;
case 3:
CommonMethods.Statues = new List<bool> { false, false, true, false };
deviceStatus = "Alert";
deviceStatusDesc = "故障调试";
if (isUpload)
{
CommonMethods.AddLog(false, "故障调试");
}
Task.Run(() =>
{
ShowAlarmEven_Run(strGuidAlarm);
});
break;
case 4:
CommonMethods.Statues = new List<bool> { false, false, false, true };
deviceStatus = "Idle";
deviceStatusDesc = "闲置待机";
Task.Run(() =>
{
ShowStuesEven_Run(Date, strGuidAlarm);
});
if (isUpload)
{
CommonMethods.AddLog(false, "闲置待机");
}
break;
default:
break;
}
if (CommonMethods.sysConfig.MesModeSwitching)
{
if (isUpload && (NewStatus == 1 || NewStatus == 3 || NewStatus == 4))//|| NewStatus == 2
{
MESDataCombin.EqpStatusParam(deviceStatus, Date, strGuidAlarm, null);
StatuesBeginTime = DateTime.Now;
}
}
}
}
#endregion
}
catch (Exception ex)
{
LogHelper.Instance.WriteEX(ex);
}
}
#region 触摸屏弹窗
private void ShowStuesEven_Run(string Date, string strGuid)
{
if (CommonMethods.plcDevice.IsConnected)
{
string strCode = "";
string strText = "";
short HMIStatus = CommonMethods.PlcLink.ReadInt16("D40");
if (HMIStatus != 0)
{
CommonMethods.AddDataMonitorLog(0, "触发了手动HMI弹窗功能!");
switch (HMIStatus) //注意:B1-D12都为闲置代码,上传代码是只需上传闲置代码
{
case 1:
strCode = "B1";
CommonMethods.AddDataMonitorLog(0, "B1 计划维护");
break;
case 2:
strCode = "B2";
CommonMethods.AddDataMonitorLog(0, "B2 无计划生产");
break;
case 3:
strCode = "B3";
CommonMethods.AddDataMonitorLog(0, "B3 样品测试");
break;
case 4:
strCode = "B4";
CommonMethods.AddDataMonitorLog(0, "B4.其他计划停机");
break;
case 5:
strCode = "D1";
CommonMethods.AddDataMonitorLog(0, "D1 设备故障");
break;
case 6:
strCode = "D2";
CommonMethods.AddDataMonitorLog(0, "D2.设备换型");
break;
case 7:
strCode = "D3";
CommonMethods.AddDataMonitorLog(0, "D3 工程变更");
break;
case 8:
strCode = "D4";
CommonMethods.AddDataMonitorLog(0, "D4.MES停机");
break;
case 9:
strCode = "D5";
CommonMethods.AddDataMonitorLog(0, "D5.来料异常");
break;
case 10:
strCode = "D6";
CommonMethods.AddDataMonitorLog(0, "D6.选择配件/物料异常");
break;
case 11:
strCode = "D7";
CommonMethods.AddDataMonitorLog(0, "D7.来料不良");
break;
case 12:
strCode = "D8";
CommonMethods.AddDataMonitorLog(0, "D8.待料");
break;
case 13:
strCode = "D9";
CommonMethods.AddDataMonitorLog(0, "D9.品质检查");
break;
case 14:
strCode = "D10";
CommonMethods.AddDataMonitorLog(0, "D10.清洁检点");
break;
case 15:
strCode = "D11";
CommonMethods.AddDataMonitorLog(0, "D11.环境不足");
break;
case 16:
strCode = "D12";
CommonMethods.AddDataMonitorLog(0, "D12.非计划停机");
break;
default:
break;
}
if (CommonMethods.mesConfig.isUpMes)
{
AlarmData alarmData = new AlarmData();
alarmData.AlarmCode = strCode;
alarmData.StartTime = Date;
alarmData.EndTime = "";
alarmData.AlarmType = "非计划损失";
alarmData.AlarmContent = strText;
alarmData.AlarmGuid = strGuid;
AlarmDataTeam.Add(alarmData);
isUpIdle = true;
string resJson = MESDataCombin.EquAlarm(alarmData, 0);
var result = JsonConvert.DeserializeObject<MesResponse>(resJson);
if (result.success)
CommonMethods.AddDataMonitorLog(0, $"HMI手动弹窗状态开始已上传成功,代码:{strCode}");
bool IsSuccesss = CommonMethods.PlcLink.WriteInt16("D40", 0);
if (IsSuccesss)
CommonMethods.AddDataMonitorLog(0, $"D40已复位0");
}
else
{
CommonMethods.AddDataMonitorLog(0, $"MES未在线,HMI手动弹窗状态未上传,代码:{strCode}");
bool IsSuccesss = CommonMethods.PlcLink.WriteInt16("D40", 0);
if (IsSuccesss) { CommonMethods.AddDataMonitorLog(0, $"D40已复位0"); }
else { CommonMethods.AddDataMonitorLog(0, $"D40未复位0"); }
}
}
}
}
#endregion
private void UpIdleData(AlarmData alarmData)
{
if (alarmData == null) { return; }
alarmData.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string resJson = MESDataCombin.EquAlarm(alarmData, 0);
var result = JsonConvert.DeserializeObject<MesResponse>(resJson);
if (result.success)
CommonMethods.AddDataMonitorLog(0, $"HMI手动弹窗状态结束已上传成功,代码:{alarmData.AlarmCode}");
}
#endregion
#region 6、设备报警
//报警表单数据
List<AlarmForm> listAlarmForm = null;
public void GetAlarmData()
{
//加载PLC报警文件
try
{
string strFileName = System.Environment.CurrentDirectory + "\\欧姆龙报警寄存器对应表.csv";
listAlarmForm = CSVHelper<AlarmForm>.ReadCSV(strFileName);
}
catch (Exception ex)
{
MessageBox.Show("加载报警文件失败!");
}
}
/// <summary>
/// 报警信息读取
/// </summary>
/// <param name="mt"></param>
/// <param name="resByte"></param>
List<AlarmData> listOld = new List<AlarmData>();
List<AlarmData> listNew = new List<AlarmData>();
List<AlarmStatus> listAlarmStatus = null;
string alarmStartDate = "";
int AlarmCount = 0;
string strAllAlarm = "";
bool isRead = false;
private void ShowAlarmEven_Run(string strGuidAlarm)
{
if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected)
{
//StringBuilder sb = new StringBuilder();
listNew.Clear();
string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>("D10010", Data_Type.ArrByte, 500);
if (resByte.IsSuccess && resByte != null)
{
if (resByte == null) { return; }
//如果未配置报警地址信息返回 TODO
if (listAlarmForm == null) { return; }
int startPlcAddr = 10010;//TODO 读取起始地址
//3.公用方法解析byte[]数据 => List<AlarmStatus>
if (resByte == null) { return; } //如果未配置报警地址信息返回
//TODO 切换三菱和欧姆龙
listAlarmStatus = PLCAlarmParseHelper.OmronFinsByte2Status(startPlcAddr, resByte.Content);
//4.判定有不良后,关联AlarmStatus 和AlarmForm
if (listAlarmStatus == null) { return; } //状态信息为空返回
//如果有报警,获取报警信息
if (listAlarmStatus.Any(p => p.Status))
{
//关联表单数据和报警记录,获取报警信息
listNew = listAlarmStatus
.Where(s => s.Status)
.Join(listAlarmForm
, s => s.PLCAdress
, f => f.PLCAdress
, (s, f) => new AlarmData()
{
AlarmGuid = strGuidAlarm,
PLCAdress = s.PLCAdress,
AlarmCode = f.AlarmCode,
AlarmContent = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
AlarmType = "停机报警",
AlarmDesc = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
AlarmState = "1",
StartTime = Date,
EndTime = Date,
Flag = 0
}).ToList();
}
string strAlarm = "";
//添加新的报警信息
if (listNew.Count > 0)
{
if (!isRead)
{
alarmStartDate = Date;
isRead = true;
}
strAllAlarm = "";
listNew.ForEach(r =>
{
strAllAlarm += $"{r.AlarmContent},";
var alarmLog = listOld.FirstOrDefault(o => o.PLCAdress == r.PLCAdress);
if (alarmLog == null)
{
listOld.Add(r);
//上传报警
if (CommonMethods.sysConfig.MesModeSwitching)
{
//上传报警
MESDataCombin.EquAlarm(r, 1);
}
//显示报警信息
CommonMethods.ShowAlarmLog(r.AlarmContent);
}
});
}
//显示报警信息
//strAlarm = sb.ToString();
if (strAllAlarm != "")
{
CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1);
}
//移除已经消除的报警信息
var saveAlarmData = new List<AlarmData>();
var listOldAlarm = new List<AlarmData>();
listOldAlarm.AddRange(listOld);
if (listOldAlarm.Count > 0)
{
foreach (var item in listOldAlarm)
{
var alarmLog = listNew.FirstOrDefault(n => n.PLCAdress == item.PLCAdress);
if (alarmLog == null)
{
item.EndTime = Date;
saveAlarmData.Add(item);
listOld.Remove(item);
}
}
}
if (saveAlarmData.Count > 0)
{
string strALLAlarm = "";
//写csv文件
var nowDate = DateTime.Now;
string basePath = $@"{CommonMethods.strAlarmLogspath}\{DateTime.Now.Year}\{DateTime.Now.Month}";
string fileName = $@"{nowDate.Day}.csv";
string title = "GUID,报警地址,故障代码,报警内容,开始时间,结束时间,是否停机";
string alarmContent = string.Empty;
List<FaultCodeList> faultCodeLists = new List<FaultCodeList>();
foreach (var m in saveAlarmData)
{
FaultCodeList item = new FaultCodeList();
item.faultCode = m.AlarmCode;
faultCodeLists.Add(item);
alarmContent += $"{m.AlarmGuid},{m.PLCAdress},{m.AlarmCode},{m.AlarmContent},{m.StartTime},{m.EndTime},{m.AlarmType}\n";
strALLAlarm += $"{m.AlarmContent},";
//上传报警
if (CommonMethods.sysConfig.MesModeSwitching)
{
//上传报警
MESDataCombin.EquAlarm(m, 0);
}
}
alarmContent = alarmContent.Substring(0, alarmContent.Length - 1);
CSVHelper<AlarmCSVData>.WriterCSV(basePath, fileName, title, alarmContent);
// 上传消除的报警信息
if (CommonMethods.sysConfig.MesModeSwitching)
{
//上传设备报警状态
MESDataCombin.EqpStatusParam("Alert", string.IsNullOrEmpty(alarmStartDate) ? Date : alarmStartDate, strGuidAlarm, faultCodeLists);
}
//报警保存
SaveAlarmCount(saveAlarmData);
}
}
}
}
/// <summary>
/// 报警保存
/// </summary>
private void SaveAlarmCount(List<AlarmData> alarmDatas)
{
bool ISAdd = false;
var recordToUpdate = new AlarmCountEntry();
DateTime today = DateTime.Today;
DateTime upTime = DateTime.Now;
var listAlarmStatistics = CommonMethods.db.QueryWhereList<AlarmCountEntry>(it => Convert.ToDateTime(it.AlarmTime.ToString("yyyy-MM-dd")) == today);
List<AlarmCountEntry> fd = new List<AlarmCountEntry>();
if (listAlarmStatistics != null)
{
alarmDatas.ForEach(r =>
{
recordToUpdate = listAlarmStatistics.FirstOrDefault(x => x.PLCAdress.Trim() == r.PLCAdress);
if (recordToUpdate != null)
{
CommonMethods.db.Update<AlarmCountEntry>(it => it.AlarmCount == it.AlarmCount + 1, it => it.PLCAdress == r.PLCAdress && Convert.ToDateTime(it.AlarmTime.ToString("yyyy-MM-dd")) == today);
}
else
{
ISAdd = true;
AlarmCountEntry alarm = new AlarmCountEntry();
alarm.PLCAdress = r.PLCAdress;
alarm.AlarmContent = r.AlarmContent;
alarm.AlarmCount = 1;
alarm.Class = CommonMethods.strClass;
alarm.AlarmTime = upTime;
fd.Add(alarm);
}
});
if (ISAdd)
{
bool res = CommonMethods.db.AddReturnBool(fd);
ISAdd = false;
}
}
else
{
foreach (var m in listNew)
{
AlarmCountEntry alarm = new AlarmCountEntry();
alarm.PLCAdress = m.PLCAdress;
alarm.AlarmContent = m.AlarmContent;
alarm.AlarmCount = 1;
alarm.Class = CommonMethods.strClass;
alarm.AlarmTime = today;
fd.Add(alarm);
}
CommonMethods.db.AddReturnBool(fd);
}
GetASqlAlarmData(DateTime.Today, CommonMethods.strClass);
}
/// <summary>
/// 读取数据库报警信息
/// </summary>
/// <param name="today"></param>
/// <param name="strClass"></param>
public void GetASqlAlarmData(DateTime today, string strClass)
{
try
{
List<ChartDataType> chartAlarms = new List<ChartDataType>();
List<AlarmCountEntry> AlarmDatas = null;
List<string> List_X = new List<string>();
List<int> List_Y = new List<int>();
DateTime baiClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 8:30:00"));
DateTime baiClassEnd = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 20:29:59"));
DateTime yeClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 20:30:00"));
DateTime yeClassEnd = Convert.ToDateTime(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd 8:29:59"));
if (strClass == "全天")
{
AlarmDatas = CommonMethods.db.QueryList<AlarmCountEntry>("AlarmCount", 10, it => Convert.ToDateTime(it.AlarmTime.ToString("yyyy-MM-dd")) == today);
}
else if (strClass == "白班")
{
AlarmDatas = CommonMethods.db.QueryList<AlarmCountEntry>("AlarmCount", 10, it => it.AlarmTime >= baiClassStart && it.AlarmTime <= baiClassEnd && it.Class == strClass);
}
else
{
AlarmDatas = CommonMethods.db.QueryList<AlarmCountEntry>("AlarmCount", 10, it => it.AlarmTime >= yeClassStart && it.AlarmTime <= yeClassEnd && it.Class == strClass);
}
if (AlarmDatas != null && AlarmDatas.Count > 0)
{
for (int i = 0; i < AlarmDatas.Count; i++)
{
chartAlarms.Add(new ChartDataType()
{
DataType = AlarmDatas[i].AlarmContent,
DataCount = (int)AlarmDatas[i].AlarmCount
});
}
CommonMethods.Lst_AlarmTop10_Qty = chartAlarms;
}
else
{
CommonMethods.Lst_AlarmTop10_Qty = null;
}
}
catch (Exception)
{
}
}
#endregion
#region 获取白夜班次
bool qiehuan = false;
bool Yeqiehuan = false;
private void SetClass()
{
try
{
var nowDate = DateTime.Now;
string strClass = "";
DateTime time1 = Convert.ToDateTime($"{nowDate.ToShortDateString()} {CommonMethods.ChangeClassTime}");
DateTime time2 = Convert.ToDateTime($"{nowDate.ToShortDateString()} {Convert.ToDateTime(CommonMethods.ChangeClassTime).AddHours(12).ToString("HH:mm:ss")}");
if (nowDate <= time1 && nowDate >= time2)
{
Yeqiehuan = false;
if (CommonMethods.plcDevice.IsConnected)
{
if (!qiehuan)
{
if (!SetPlcTime())
{
CommonMethods.AddLog(true, $"PC写入PLC时间失败!");
}
else
{
qiehuan = true;
CommonMethods.AddLog(false, "PC写入PLC时间成功!");
}
}
}
strClass = "白班";
}
else
{
qiehuan = false;
if (!Yeqiehuan || (nowDate.Hour == 0 && nowDate.Minute == 0 && nowDate.Second > 45))
{
if (!SetPlcTime())
{
CommonMethods.AddLog(true, $"PC写入PLC时间失败!");
}
else
{
Yeqiehuan = true;
CommonMethods.AddLog(false, "PC写入PLC时间成功!");
}
}
strClass = "夜班";
}
CommonMethods.strClass = strClass;
}
catch (Exception ex)
{
CommonMethods.AddLog(true, "设备状态" + ex.Message);
LogHelper.Instance.WriteEX(ex);
}
}
#endregion
#region 写入PLC时间
/// <summary>
/// 写当前时间给PLC
/// </summary>
private bool SetPlcTime()
{
var nowDate = DateTime.Now;
int nowSec = nowDate.Second;
while (nowSec == nowDate.Second)
nowDate = DateTime.Now;
string yearStr = nowDate.Year.ToString();
//byte year = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(yearStr), 1);
//byte month = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Month.ToString("00")), 0);
//byte day = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Day.ToString("00")), 0);
//byte hour = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Hour.ToString("00")), 0);
//byte minute = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Minute.ToString("00")), 0);
//byte second = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Second.ToString("00")), 0);
//byte week = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.DayOfWeek.ToString("00")), 0);
//List<byte> byteList = new List<byte> {
// // FinsTcp Header
// 0x46, 0x49, 0x4E, 0x53, // FINS Ascii编码
// 0x00,0x00,0x00,0x1B, // 后续字节数
// 0x00,0x00,0x00,0x02, // Command:客户端(上位机)连接到服务端(PLC)
// 0x00,0x00,0x00,0x00, // 错误码:表示无错误
// // Fins Header
// 0x80,
// 0x00,
// 0x02,
// 0x00,DA1,0x00,
// 0x00,SA1,0x00,
// 0xFF, // SID
// // Command
// 0x07,0x02, // 表示读取PLC时间
// // 年、月、日、时、分、秒 星期
// year,month,day,hour,minute,second,week
// };
bool IsSuccess = false;
// 为防止PLC时间出现偏差,每次自动运行的时候写PLC系统时间
short[] writeArr = new short[]
{
Convert.ToInt16(nowDate.Year),//D70
Convert.ToInt16(nowDate.Month),//D71
Convert.ToInt16(nowDate.Day),//D72
Convert.ToInt16(nowDate.Hour),//D73
Convert.ToInt16(nowDate.Minute),//D74
Convert.ToInt16(nowDate.Second + 1),//D75
(short)1 //D76
};
if (CommonMethods.plcDevice.IsConnected)
{
JYResult result = CommonMethods.PlcLink.WriteValue("D70", writeArr, Data_Type.ArrShort);
if (result.IsSuccess)
{
IsSuccess = true;
}
}
return IsSuccess;
}
#endregion
}
}