2025-09-17 20:04:00 +08:00
using JinYuan.CommunicationLib.Enum ;
using JinYuan.DataConvertLib ;
using JinYuan.Helper ;
using JinYuan.MES.Models ;
using JinYuan.Models ;
using JinYuan.VirtualDataLibrary ;
using Newtonsoft.Json ;
using PLCCommunication ;
using SqlSugar ;
using System ;
using System.Collections.Generic ;
using System.Collections.ObjectModel ;
using System.Diagnostics ;
using System.IO ;
using System.Linq ;
using System.Threading ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
namespace JinYuan.ControlCenters
{
public partial class ControlCenter
{
private static LoggerHelp _logger = new LoggerHelp ();
/// <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}" ; //打印出现的时间
// 将消息写入日志文件
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 >();
DicStationFunction . Add ( "电芯进站" , FeedingStation );
2025-09-26 19:44:13 +08:00
// DicStationFunction.Add("NG出站", NGStation);
2025-09-17 20:04:00 +08:00
DicStationFunction . Add ( "电芯出站" , BlankingStation );
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 ;
while (! CommonMethods . IsExit )
{
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" );
LoggerHelp . 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},得到空字节数组" );
LoggerHelp . WriteLog ( "循环读取PLC上料工位" + $"读取工位:{pf.GroupName},起始地址:{pf.VarList[1].VarAddress},得到空字节数组" );
}
else
{
//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 ); //信息解析
}
}
}
catch ( Exception ex )
{
CommonMethods . AddLog ( true , ex . Message );
LoggerHelp . 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");
}
}
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" ); //良品总数
CommonMethods . Ppm = CommonMethods . PlcLink . ReadInt32 ( "D13" );
//CommonMethods.JiaDL = Convert.ToDouble(CommonMethods.PlcLink.ReadFloat("D11").ToString("F2"))/100;
CommonMethods . JiaDL = Convert . ToDouble ( CommonMethods . PlcLink . ReadInt32 ( "D11" ). ToString ( "F2" )) / 100 ;
#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 = "" ;
if ( flag ) //产出
{
//strAddr = "D" + (1032 + hour);
//1257
strAddr = "D" + ( 1040 + hour );
}
else //良品数
{
// strAddr = "D" + (1062 + hour);
//1257
strAddr = "D" + ( 1070 + hour );
}
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 )
{
LoggerHelp . 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 );
LoggerHelp . 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
}
}