711ed94d51
公差查不到时:EHV L-XX F 查询数据获取公差带失败!...原始测量值将保留并写入数据库,结果标记为noTol。 公差缺失保留原值时:EHV L-XX F 公差未配置,保留原始测量值=X.X,结果标记为noTol。 实测值超出异常公差时:EHV L-XX F 实测值=X.XX 超出异常公差区间[a,b],结果ng3,原值保留。 入库前汇总:[EHV完整性] 车号=XXX 测点总数=N 有值=N 空值=N ng3=N noTol=N 客户报告生成时:[GenUserReportCSV] 客户报告测量行总数=N 其中Measured_Value为空的行数=N (空值率=X.X%) 后续现场出问题时可以直接看日志的"完整性"行和"空值率"行就能马上定位是哪辆车的哪个测点出现异常。 另外提醒一点:自检 CSV 解析(AnalysisNextSenseSelfMeasureCSV)里那处 aryLineContent[2] = "" 只在 inv(NextSense 报告原本就是无效值)分支里执行,行为是合理的,没有动它。
3872 lines
142 KiB
C#
3872 lines
142 KiB
C#
using BaseFunction;
|
||
using DAL;
|
||
using HslCommunication.Profinet.Siemens;
|
||
using Newtonsoft.Json;
|
||
using NSAnalysis.Properties;
|
||
using PLCModule;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.IO.Ports;
|
||
using System.Linq;
|
||
using System.Net;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Windows.Forms;
|
||
using Telerik.WinControls;
|
||
using Telerik.WinControls.UI;
|
||
using UserControlClass;
|
||
|
||
namespace NSAnalysis
|
||
{
|
||
/// <summary>
|
||
///
|
||
///
|
||
///
|
||
/// 2025.08.29
|
||
/// --------------------------------------------------------------
|
||
/// 1、增加对 生成报告数据的备份、上传情况的记录√
|
||
/// 2、增加对IOT json报文 上传情况的记录√
|
||
/// 3、增加对 PLC 传输过点信号的 记录 (抵达,测量,离开) √
|
||
/// 4、PLC通讯阻塞问题 √
|
||
///
|
||
///
|
||
///
|
||
/// 2025.8.31
|
||
/// --------------------------------------------------------------
|
||
/// 1、增加对IOT 上传失败的重传功能 √
|
||
///
|
||
///
|
||
///
|
||
///
|
||
/// 2025.11.03
|
||
/// --------------------------------------------------------------
|
||
/// 1、修改大屏页面的后台刷新,避免长时间卡死不刷新的问题 √
|
||
///
|
||
///
|
||
///
|
||
///
|
||
///
|
||
/// 2026.03.16
|
||
/// --------------------------------------------------------------
|
||
/// 1、新增EHV车型的大屏显示,解析,与报告生成 √
|
||
/// 2、增加公差的批量导入功能 √
|
||
/// 3、修复 自定义表格控件会超出区域的问题 WorkingArea → Bounds √
|
||
/// 4、新大屏窗体要先show一下,然后hide, 否则窗体内后台刷新没有启动 √
|
||
///
|
||
///
|
||
/// </summary>
|
||
|
||
public partial class CenterControl : Telerik.WinControls.UI.ShapedForm
|
||
{
|
||
#region 全局变量
|
||
|
||
private int[] yValues = new int[3];
|
||
private string[] xValues = new string[3];
|
||
private DataTable dtCSVContent = new DataTable();
|
||
private DataTable dtRangeData = new DataTable();
|
||
private TMeasureMSSQLDAL tmdal = new TMeasureMSSQLDAL();
|
||
private string strSaveReprotPath = "";
|
||
private bool bReadCSVFlag = false;
|
||
private List<CheryIOTData> ListPostIOTData = new List<CheryIOTData>();
|
||
private FEHYLeftCarData fLEHY = null;
|
||
private FEHYRightCarData fREHY = null;
|
||
|
||
private FEH3LeftCarData fLEH3 = null;
|
||
private FEH3RightCarData fREH3 = null;
|
||
|
||
private FEHVLeftCarData fLEHV = null;
|
||
private FEHVRightCarData fREHV = null;
|
||
|
||
private int iCurrentMeasureItemsFailedCount = 0;
|
||
private BackgroundWorker m_bgwAnalysisCSVReport = new BackgroundWorker();
|
||
#region PLC相关变量
|
||
|
||
private bool bStopPlcNormal = false;
|
||
private static int HeartBeatCount = 0;
|
||
private bool bPlcLiveTickLast = false;
|
||
|
||
private Thread m_ThreadReconnectPLC = null;
|
||
private int m_ReConnectNum = 0;
|
||
private bool bTickt = true;
|
||
private int iLastNSStartMeasure = 0;
|
||
private int iLastCarPassFlag = 0;
|
||
private int iLastStation1To2 = 0;
|
||
private int iLastStation2To3 = 0;
|
||
private int iLastReadVINFinishFlag = 0;
|
||
private int iLastNoCarTypeFlag = 0;
|
||
private SerialPort serialTestPort = null;
|
||
|
||
private SerialPort serialPort = null;
|
||
private int iLastMesureCount = 0;
|
||
private System.Timers.Timer ttmrReadPLCData = new System.Timers.Timer();
|
||
private System.Timers.Timer ttmrWritePLCLive = new System.Timers.Timer();
|
||
private System.Timers.Timer ttmrReadNSCSV = new System.Timers.Timer();
|
||
#endregion PLC相关变量
|
||
|
||
#region 分页全局变量
|
||
|
||
private DataTable PageTable = new DataTable();
|
||
|
||
/// <summary>
|
||
/// 每页记录数
|
||
/// </summary>
|
||
public int pageSize = 20;
|
||
|
||
/// <summary>
|
||
/// 总记录数
|
||
/// </summary>
|
||
public int recordCount = 0;
|
||
|
||
/// <summary>
|
||
/// 总页数
|
||
/// </summary>
|
||
public int pageCount = 0;
|
||
|
||
/// <summary>
|
||
/// 当前页
|
||
/// </summary>
|
||
public int currentPage = 0;
|
||
|
||
#endregion 分页全局变量
|
||
|
||
#endregion 全局变量
|
||
|
||
#region 主窗口事件
|
||
|
||
public CenterControl()
|
||
{
|
||
InitializeComponent();
|
||
SQLHelper.connStr = DatabaseDfn.SqlConnectStr();
|
||
|
||
#region 加载皮肤
|
||
|
||
ThemeResolutionService.LoadPackageFile(ConfigDfn.strTheme);
|
||
this.ThemeName = ConfigDfn.strSkinName.Substring(0, ConfigDfn.strSkinName.Length - 5);
|
||
RPV.ThemeName = ConfigDfn.strSkinName.Substring(0, ConfigDfn.strSkinName.Length - 5);
|
||
|
||
#endregion 加载皮肤
|
||
}
|
||
|
||
private void CenterControl_Load(object sender, EventArgs e)
|
||
{
|
||
ttmrReadPLCData.Interval = 300;
|
||
ttmrReadPLCData.SynchronizingObject = this;
|
||
ttmrReadPLCData.Elapsed += ttmrReadPLCData_Elapsed;
|
||
|
||
ttmrWritePLCLive.Interval = 1000;
|
||
ttmrWritePLCLive.SynchronizingObject = this;
|
||
ttmrWritePLCLive.Elapsed += ttmrWritePLCLive_Elapsed;
|
||
|
||
ttmrReadNSCSV.Interval = 500;
|
||
ttmrReadNSCSV.SynchronizingObject = this;
|
||
ttmrReadNSCSV.Elapsed += ttmrReadNSCSV_Elapsed;
|
||
|
||
#region 初始化全局变量
|
||
fLEHY = new FEHYLeftCarData(this);
|
||
fREHY = new FEHYRightCarData(this);
|
||
fLEH3 = new FEH3LeftCarData(this);
|
||
fREH3 = new FEH3RightCarData(this);
|
||
fLEHV = new FEHVLeftCarData(this);
|
||
fREHV = new FEHVRightCarData(this);
|
||
// 触发所有大屏窗体的 Load 事件,确保后台刷新线程启动,再隐藏
|
||
fLEHV.Show(); fLEHV.Hide();
|
||
fREHV.Show(); fREHV.Hide();
|
||
fLEH3.Show(); fLEH3.Hide();
|
||
fREH3.Show(); fREH3.Hide();
|
||
fLEHY.Show(); fLEHY.Hide();
|
||
fREHY.Show(); fREHY.Hide();
|
||
MyBase.rleMessage = rleMessage;
|
||
rdtpStartTime.Text = DateTime.Now.ToString("yyyy-MM-dd");
|
||
rdtpEndTime.Text = DateTime.Now.ToString("yyyy-MM-dd");
|
||
|
||
#endregion 初始化全局变量
|
||
//需要显示车身数据 不分析csv文件
|
||
if (ConfigDfn.iShowCarDataFlag == 1)
|
||
{
|
||
MyBase.TraceWriteLine(" 进入显示车身模式!显示车身界面。");
|
||
lpcShowCarData_Click(null, null);
|
||
//serialPort = new SerialPort(ConfigDfn.strCOMPort, 115200, Parity.None, 8, StopBits.One); // 设置串口参数
|
||
//serialPort.DataReceived += new SerialDataReceivedEventHandler(DataAutoReceivedHandler); // 注册数据接收事件处理方法
|
||
//serialPort.Open(); // 打开串口
|
||
//if (serialPort.IsOpen)
|
||
//{
|
||
// MyBase.TraceWriteLine(ConfigDfn.strCOMPort + "打开成功O(∩_∩)O");
|
||
//}
|
||
//else
|
||
//{
|
||
// MyBase.TraceWriteLine(ConfigDfn.strCOMPort + "打开失败!");
|
||
// MessageBox.Show(ConfigDfn.strCOMPort + "打开失败!请检查扫抢串口设置是否正确。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
//}
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine(" 进入不显示车身模式!");
|
||
}
|
||
if (ConfigDfn.iAnalysisCSVFlag == 1)
|
||
{
|
||
btnConnectPlc_Click(null, null);
|
||
MyBase.TraceWriteLine(" 进入解析CSV文件模式,开始解析扫码CSV文件!");
|
||
//ttmrReadNSCSV.Start();
|
||
//tmdal.updateMaintenceInfoEmpty();
|
||
m_bgwAnalysisCSVReport.DoWork += new DoWorkEventHandler(m_bgwAnalysisCSVReport_DoWork);
|
||
m_bgwAnalysisCSVReport.RunWorkerAsync();
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine(" 进入不解析CSV文件模式!");
|
||
ttmrReadNSCSV.Stop();
|
||
}
|
||
|
||
if (Directory.Exists(ConfigDfn.strNextSenseCSVEH3Path))
|
||
{
|
||
MyBase.TraceWriteLine("软件首次启动, Nextsense EH3 CSV读取路径存在;不清空,读取NextSense生成 CSV报告路径下的所有文件,路径为:" + ConfigDfn.strNextSenseCSVEH3Path);
|
||
}
|
||
else
|
||
{
|
||
string strTip = "错误:软件首次启动,读取NextSense生成EH3 CSV报告的路径:" + ConfigDfn.strNextSenseCSVEH3Path + " 不存在!请检查并进行修改!点击是按钮,软件将自动创建该路径!";
|
||
MyBase.TraceWriteLine(strTip);
|
||
Directory.CreateDirectory(ConfigDfn.strNextSenseCSVEH3Path);
|
||
//DialogResult dResult = MessageBox.Show(strTip, "错误", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
|
||
//if (dResult == DialogResult.Yes)
|
||
//{
|
||
// Directory.CreateDirectory(ConfigDfn.strNextSenseCSVEH3Path);
|
||
// MyBase.TraceWriteLine(strTip + " ; 点击了是按钮,软件自动创建读取目录:" + ConfigDfn.strNextSenseCSVEH3Path);
|
||
//}
|
||
//else
|
||
//{
|
||
// MyBase.TraceWriteLine(strTip + " ;点击了否按钮,不创建目录!");
|
||
//}
|
||
}
|
||
if (Directory.Exists(ConfigDfn.strNextSenseCSVEHYPath))
|
||
{
|
||
MyBase.TraceWriteLine("软件首次启动, Nextsense EHY CSV读取路径存在;不清空,读取NextSense生成 CSV报告路径下的所有文件,路径为:" + ConfigDfn.strNextSenseCSVEHYPath);
|
||
}
|
||
else
|
||
{
|
||
string strTip = "错误:软件首次启动,读取NextSense生成EHY CSV报告的路径:" + ConfigDfn.strNextSenseCSVEHYPath + " 不存在!请检查并进行修改!点击是按钮,软件将自动创建该路径!";
|
||
MyBase.TraceWriteLine(strTip);
|
||
Directory.CreateDirectory(ConfigDfn.strNextSenseCSVEHYPath);
|
||
}
|
||
if (!string.IsNullOrWhiteSpace(ConfigDfn.strNextSenseCSVEHVPath))
|
||
{
|
||
if (Directory.Exists(ConfigDfn.strNextSenseCSVEHVPath))
|
||
{
|
||
MyBase.TraceWriteLine("软件首次启动, Nextsense EHV CSV读取路径存在;不清空,读取NextSense生成 CSV报告路径下的所有文件,路径为:" + ConfigDfn.strNextSenseCSVEHVPath);
|
||
}
|
||
else
|
||
{
|
||
string strTipEHV = "错误:软件首次启动,读取NextSense生成EHV CSV报告的路径:" + ConfigDfn.strNextSenseCSVEHVPath + " 不存在!请检查并进行修改!软件将自动创建该路径!";
|
||
MyBase.TraceWriteLine(strTipEHV);
|
||
Directory.CreateDirectory(ConfigDfn.strNextSenseCSVEHVPath);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHV CSV读取路径未配置,跳过路径检查。");
|
||
}
|
||
initLPCControl();
|
||
|
||
//tmdal.updateMaintenceInfoEmpty();
|
||
//iLastMesureCount = tmdal.SelectTMeasureResultCount();
|
||
|
||
#region 清空信息
|
||
|
||
labVIN.Text = "";
|
||
labOKCount.Text = "";
|
||
labNGCount.Text = "";
|
||
labRejectCount.Text = "";
|
||
labSumMeasureCount.Text = "";
|
||
labMeaTime.Text = "";
|
||
labResultPercent.Text = "";
|
||
labResult.Text = "";
|
||
labCarType.Text = "";
|
||
|
||
#endregion 清空信息
|
||
|
||
InitTableColumns();
|
||
strSaveReprotPath = ConfigDfn.strReportPath + @"\";
|
||
|
||
//testIotUpload();
|
||
}
|
||
|
||
private void InitTableColumns()
|
||
{
|
||
#region 测量数据表始化表
|
||
|
||
//创建虚拟表
|
||
DataColumn column2 = new DataColumn("CarID", Type.GetType("System.String"));
|
||
DataColumn dcCarType = new DataColumn("CarType", Type.GetType("System.String"));
|
||
DataColumn column3 = new DataColumn("MeasPointName", Type.GetType("System.String"));
|
||
DataColumn column4 = new DataColumn("DimensionName", Type.GetType("System.String"));
|
||
DataColumn column5 = new DataColumn("NormalValue", Type.GetType("System.String"));
|
||
DataColumn column6 = new DataColumn("LowerTolVal", Type.GetType("System.String"));
|
||
DataColumn column7 = new DataColumn("UpperTolVal", Type.GetType("System.String"));
|
||
DataColumn column8 = new DataColumn("MeasureValue", Type.GetType("System.String"));
|
||
DataColumn column10 = new DataColumn("MeasureItemResult", Type.GetType("System.String"));
|
||
DataColumn column9 = new DataColumn("MeasureDate", Type.GetType("System.DateTime"));
|
||
DataColumn column1 = new DataColumn("Remark", Type.GetType("System.String"));
|
||
//将列添加到table表中
|
||
|
||
dtCSVContent.Columns.Add(column2);
|
||
dtCSVContent.Columns.Add(dcCarType);
|
||
dtCSVContent.Columns.Add(column3);
|
||
dtCSVContent.Columns.Add(column4);
|
||
dtCSVContent.Columns.Add(column5);
|
||
dtCSVContent.Columns.Add(column6);
|
||
dtCSVContent.Columns.Add(column7);
|
||
dtCSVContent.Columns.Add(column8);
|
||
dtCSVContent.Columns.Add(column10);
|
||
dtCSVContent.Columns.Add(column9);
|
||
dtCSVContent.Columns.Add(column1);
|
||
|
||
#endregion 测量数据表始化表
|
||
|
||
#region 极差数据Table初始化
|
||
|
||
//创建虚拟表
|
||
DataColumn dcCarID = new DataColumn("CarID", Type.GetType("System.String"));
|
||
DataColumn dcRangeName = new DataColumn("RangeName", Type.GetType("System.String"));
|
||
DataColumn dcRangeValue = new DataColumn("RangeValue", Type.GetType("System.String"));
|
||
DataColumn dcRangeLowUpp = new DataColumn("RangeLowUpp", Type.GetType("System.String"));
|
||
DataColumn dcResult = new DataColumn("Result", Type.GetType("System.String"));
|
||
DataColumn dcCreateTime = new DataColumn("CreateTime", Type.GetType("System.DateTime"));
|
||
DataColumn dcRemark = new DataColumn("Remark", Type.GetType("System.String"));
|
||
//将列添加到table表中
|
||
|
||
dtRangeData.Columns.Add(dcCarID);
|
||
dtRangeData.Columns.Add(dcRangeName);
|
||
dtRangeData.Columns.Add(dcRangeValue);
|
||
dtRangeData.Columns.Add(dcRangeLowUpp);
|
||
dtRangeData.Columns.Add(dcResult);
|
||
dtRangeData.Columns.Add(dcCreateTime);
|
||
dtRangeData.Columns.Add(dcRemark);
|
||
|
||
#endregion 极差数据Table初始化
|
||
|
||
#region 分页相关
|
||
|
||
//创建分页虚拟表
|
||
DataColumn column11 = new DataColumn("CarID", Type.GetType("System.String"));
|
||
DataColumn column12 = new DataColumn("MeasPointName", Type.GetType("System.String"));
|
||
DataColumn column13 = new DataColumn("DimensionName", Type.GetType("System.String"));
|
||
DataColumn column14 = new DataColumn("NormalValue", Type.GetType("System.String"));
|
||
DataColumn column15 = new DataColumn("LowerTolVal", Type.GetType("System.String"));
|
||
DataColumn column16 = new DataColumn("UpperTolVal", Type.GetType("System.String"));
|
||
DataColumn column17 = new DataColumn("MeasureValue", Type.GetType("System.String"));
|
||
DataColumn column18 = new DataColumn("MeasureDate", Type.GetType("System.String"));
|
||
DataColumn column19 = new DataColumn("MeasureItemResult", Type.GetType("System.String"));
|
||
|
||
//将列添加到table表中
|
||
PageTable.Columns.Add(column11);
|
||
PageTable.Columns.Add(column12);
|
||
PageTable.Columns.Add(column13);
|
||
PageTable.Columns.Add(column14);
|
||
PageTable.Columns.Add(column15);
|
||
PageTable.Columns.Add(column16);
|
||
PageTable.Columns.Add(column17);
|
||
PageTable.Columns.Add(column18);
|
||
PageTable.Columns.Add(column19);
|
||
|
||
labCurrentPage.Text = "当前页:" + currentPage.ToString(); //当前页
|
||
labSumPages.Text = "共 " + pageCount.ToString() + " 页";//总页数
|
||
labSumRecorders.Text = "总共 " + recordCount.ToString() + " 条记录";//总记录数
|
||
rddlPageRecorderCount.SelectedIndex = 0;
|
||
|
||
#endregion 分页相关
|
||
}
|
||
|
||
private void DataAutoReceivedHandler(object sender, SerialDataReceivedEventArgs e)
|
||
{
|
||
SerialPort sp = (SerialPort)sender;
|
||
string strScanVIN = sp.ReadExisting();
|
||
MyBase.TraceWriteLine("扫抢获取的VIN码为:" + strScanVIN);
|
||
if (strScanVIN.Length > 0)
|
||
{
|
||
tmdal.updateMaintenceInfo(strScanVIN, 3);
|
||
MyBase.TraceWriteLine("更新数据库中存储的VIN码:" + strScanVIN);
|
||
}
|
||
}
|
||
|
||
private void initLPCControl()
|
||
{
|
||
lpcSoftwareSetup.labPicture.Click += new EventHandler(lpcSoftwareSetup_Click);
|
||
lpcSoftwareSetup.labText.Click += new EventHandler(lpcSoftwareSetup_Click);
|
||
|
||
lpcToleranceSetup.labPicture.Click += new EventHandler(lpcToleranceSetup_Click);
|
||
lpcToleranceSetup.labText.Click += new EventHandler(lpcToleranceSetup_Click);
|
||
|
||
lpcRange.labPicture.Click += new EventHandler(lpcRange_Click);
|
||
lpcRange.labText.Click += new EventHandler(lpcRange_Click);
|
||
|
||
lpcPLCAddress.labPicture.Click += new EventHandler(lpcPLCAddress_Click);
|
||
lpcPLCAddress.labText.Click += new EventHandler(lpcPLCAddress_Click);
|
||
|
||
lpcPLCTest.labPicture.Click += new EventHandler(lpcPLCTest_Click);
|
||
lpcPLCTest.labText.Click += new EventHandler(lpcPLCTest_Click);
|
||
|
||
lpcAboutSoftware.labPicture.Click += new EventHandler(lpcAboutSoftware_Click);
|
||
lpcAboutSoftware.labText.Click += new EventHandler(lpcAboutSoftware_Click);
|
||
|
||
lpcUploadIOTTest.labPicture.Click += new EventHandler(lpcUploadIOTTest_Click);
|
||
lpcUploadIOTTest.labText.Click += new EventHandler(lpcUploadIOTTest_Click);
|
||
|
||
lpcTestGetCarTye.labPicture.Click += new EventHandler(lpcTestGetCarTye_Click);
|
||
lpcTestGetCarTye.labText.Click += new EventHandler(lpcTestGetCarTye_Click);
|
||
|
||
lpcShowCarData.labPicture.Click += new EventHandler(lpcShowCarData_Click);
|
||
lpcShowCarData.labText.Click += new EventHandler(lpcShowCarData_Click);
|
||
|
||
lpcShowLog.labPicture.Click += new EventHandler(lpcShowLog_Click);
|
||
lpcShowLog.labText.Click += new EventHandler(lpcShowLog_Click);
|
||
}
|
||
|
||
private void CenterControl_FormClosed(object sender, FormClosedEventArgs e)
|
||
{
|
||
MyBase.TraceWriteLine("-------------海克斯康面隙分析软件程序关闭---------------------");
|
||
LogDebugDfn.strEndTime = DateTime.Now.ToString("yyyy.MM.dd HH-mm-ss");
|
||
string CopyFileName = ConfigDfn.strFileFolder + "\\DebugFiles\\" + "Debug(" + LogDebugDfn.strStartTime + " To " + LogDebugDfn.strEndTime + ")" + ".txt";
|
||
if (File.Exists(LogDebugDfn.strDebugFile))
|
||
File.Copy(LogDebugDfn.strDebugFile, CopyFileName);
|
||
System.Environment.Exit(0);
|
||
}
|
||
|
||
private void tmSystem_Tick(object sender, EventArgs e)
|
||
{
|
||
rleTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
if (ConfigDfn.iAnalysisCSVFlag == 1)
|
||
rleReadCSVStatus.ForeColor = bReadCSVFlag ? Color.Green : Color.White;
|
||
bReadCSVFlag = !bReadCSVFlag;
|
||
}
|
||
|
||
#endregion 主窗口事件
|
||
|
||
#region⭐⭐⭐⭐⭐ 解析Nextsense CSV文件功能 核心算法 ⭐⭐⭐⭐⭐
|
||
|
||
private double CalculateStrictLowerTolerance(double dLower, double dUpper)
|
||
{
|
||
double dStrictLower = 0;
|
||
double dNormalValue = (dLower + dUpper) / 2;
|
||
dStrictLower = dNormalValue + (dLower - dNormalValue) * ConfigDfn.dTolerancePer;
|
||
return dStrictLower;
|
||
}
|
||
|
||
private double CalculateStrictUpperTolerance(double dLower, double dUpper)
|
||
{
|
||
double dStrictUpper = 0;
|
||
double dNormalValue = (dLower + dUpper) / 2;
|
||
dStrictUpper = dNormalValue + (dUpper - dNormalValue) * ConfigDfn.dTolerancePer;
|
||
return dStrictUpper;
|
||
}
|
||
|
||
private double CalculateExceptionLowerTolerance(double dLower, double dUpper)
|
||
{
|
||
double dStrictLower = 0;
|
||
double dNormalValue = (dLower + dUpper) / 2;
|
||
dStrictLower = dNormalValue + (dLower - dNormalValue) * ConfigDfn.dExceptionTolerancePer;
|
||
return dStrictLower;
|
||
}
|
||
|
||
private double CalculateExceptionUpperTolerance(double dLower, double dUpper)
|
||
{
|
||
double dStrictUpper = 0;
|
||
double dNormalValue = (dLower + dUpper) / 2;
|
||
dStrictUpper = dNormalValue + (dUpper - dNormalValue) * ConfigDfn.dExceptionTolerancePer;
|
||
return dStrictUpper;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析EH3 CSV文件函数;后续如果Nextsense的csv报告模板变了,修改该函数的行号即可LineNum wsp
|
||
/// </summary>
|
||
private void AnalysisNextSenseEH3CSV() // 解析EH3 车型
|
||
{
|
||
try
|
||
{
|
||
Invoke((MethodInvoker)(() => { lbCSVFiles.Items.Clear(); }));
|
||
FileInfo[] fileInfos = null;
|
||
if (Directory.Exists(ConfigDfn.strNextSenseCSVEH3Path))
|
||
{
|
||
DirectoryInfo di = new DirectoryInfo(ConfigDfn.strNextSenseCSVEH3Path);
|
||
fileInfos = di.GetFiles("*.CSV");
|
||
if (fileInfos.Count() >= 1)
|
||
{
|
||
MyBase.TraceWriteLine("存在EH3 CSV文件,开始解析:");
|
||
List<string> listCSVTitleInfo = new List<string>();
|
||
string strCarID = "";
|
||
foreach (FileInfo fi in fileInfos)
|
||
{
|
||
listCSVTitleInfo.Clear();
|
||
ListPostIOTData.Clear();
|
||
dtCSVContent.Clear();
|
||
|
||
string strCSVName = fi.FullName;
|
||
try
|
||
{
|
||
File.Copy(fi.FullName, ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name, true);
|
||
}
|
||
catch (IOException ioEx)
|
||
{
|
||
MyBase.TraceWriteLine("EH3 CSV文件被占用,跳过本次解析,等待下次轮询:" + fi.Name + " | " + ioEx.Message);
|
||
Thread.Sleep(500);
|
||
continue;
|
||
}
|
||
MyBase.TraceWriteLine("Copy " + fi.FullName + " TO " + ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name + " Done. 备份完成");
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Clear();
|
||
lbCSVFiles.Items.Add(fi.Name);
|
||
}));
|
||
|
||
#region 解析EH3 CSV报告
|
||
|
||
MyBase.TraceWriteLine("开始解析NextSense EH3 CSV 报告:" + strCSVName);
|
||
Encoding encoding = GetType(strCSVName);
|
||
FileStream fs = new FileStream(strCSVName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
StreamReader sr = new StreamReader(fs, encoding);
|
||
//记录每次读取的一行记录
|
||
string strLine = "";
|
||
//记录每行记录中的各字段内容
|
||
string[] aryLineContent = null;
|
||
|
||
//逐行读取CSV中的数据
|
||
int LineNum = 0;
|
||
//表格行数
|
||
int dtRowCount = 0;
|
||
//超差个数
|
||
double OutCount = 0;
|
||
//Ok个数
|
||
double OKCount = 0;
|
||
//异常个数
|
||
double RejectedCount = 0;
|
||
//合格率
|
||
double FPYPercent = 0;
|
||
double dStrictTLower = 0;
|
||
double dStrictTUpper = 0;
|
||
double dLowerValue = 0;
|
||
double dUpperValue = 0;
|
||
double dExcepitonTLower = 0;
|
||
double dExceptionTUpper = 0;
|
||
double dMeasureValue = 0.0;
|
||
DataTable dt = null;
|
||
while ((strLine = sr.ReadLine()) != null)
|
||
{
|
||
LineNum++;
|
||
if (LineNum >= 3 & LineNum <= 16)
|
||
{
|
||
listCSVTitleInfo.Add(strLine);
|
||
}
|
||
if (LineNum == 10)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
MyBase.TraceWriteLine("解析出NextSense CSV中的VIN为:" + aryLineContent[1]);
|
||
strCarID = tmdal.SelectVINByCSVVIN(aryLineContent[1]);
|
||
MyBase.TraceWriteLine("通过CSV VIN从数据库中获取的完整VIN为:" + strCarID);
|
||
if (strCarID.ToLower().Contains("nofind"))
|
||
{
|
||
MyBase.TraceWriteLine("数据库中没有查找到VIN码,NoFind, +L 使用CSV码");
|
||
labVIN.Text = "L" + aryLineContent[1];
|
||
strCarID = "L" + aryLineContent[1];
|
||
}
|
||
else
|
||
{
|
||
labVIN.Text = strCarID;
|
||
tmdal.DeleteOneTTempVIN(strCarID);
|
||
MyBase.TraceWriteLine("在数据库表TTempSaveVIN中删除该VIN:" + strCarID);
|
||
}
|
||
}
|
||
if (LineNum >= 19)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
//ConfigDfn.strMeasureTime = aryLineContent[6].Substring(0, 4) + "-" + aryLineContent[6].Substring(4, 2) + "-" + aryLineContent[6].Substring(6, 2) + " " + aryLineContent[7].Substring(0, 2) + ":" + aryLineContent[7].Substring(2, 2) + ":" + aryLineContent[7].Substring(4, 2);
|
||
ConfigDfn.strMeasureTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
double dNormalValue = 0.0d;
|
||
|
||
bool bToleranceValid = false;
|
||
dt = tmdal.SelectOneToleranceByCondition("EH3", aryLineContent[0], aryLineContent[1]);
|
||
if (dt.Rows.Count == 1)
|
||
{
|
||
dLowerValue = double.Parse(dt.Rows[0]["TolLower"].ToString());
|
||
dUpperValue = double.Parse(dt.Rows[0]["TolUpper"].ToString());
|
||
dNormalValue = (dLowerValue + dUpperValue) / 2;
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
dExcepitonTLower = CalculateExceptionLowerTolerance(dLowerValue, dUpperValue);
|
||
dExceptionTUpper = CalculateExceptionUpperTolerance(dLowerValue, dUpperValue);
|
||
bToleranceValid = true;
|
||
}
|
||
else
|
||
{
|
||
// 修复:公差未配置时显式重置异常公差,避免上一轮循环遗留值
|
||
// 同时不再用0作为默认公差(否则后续 dMeasureValue>=0||<=0 几乎恒真,会把所有实测值误判为ng3并清空)
|
||
dStrictTLower = 0;
|
||
dStrictTUpper = 0;
|
||
dLowerValue = 0;
|
||
dUpperValue = 0;
|
||
dExcepitonTLower = 0;
|
||
dExceptionTUpper = 0;
|
||
MyBase.TraceWriteLine("EH3 " + aryLineContent[0] + " " + aryLineContent[1] + " 查询数据获取公差带失败!数据库中数量不唯一,请检查公差带配置!原始测量值将保留并写入数据库,结果标记为noTol。");
|
||
}
|
||
|
||
if (aryLineContent[2].ToLower().Contains("inv"))
|
||
{
|
||
aryLineContent[2] = "";
|
||
aryLineContent[4] = "ng2";
|
||
}
|
||
else if (!bToleranceValid)
|
||
{
|
||
// 修复:公差缺失时保留原始测量值,标记为noTol,避免数据系统性丢失
|
||
MyBase.TraceWriteLine("EH3 " + aryLineContent[0] + " " + aryLineContent[1] + " 公差未配置,保留原始测量值=" + aryLineContent[2] + ",结果标记为noTol。");
|
||
aryLineContent[4] = "noTol";
|
||
}
|
||
else
|
||
{
|
||
dMeasureValue = double.Parse(aryLineContent[2]);
|
||
if (dMeasureValue >= dLowerValue && dMeasureValue <= dUpperValue)
|
||
{
|
||
aryLineContent[4] = "good";
|
||
}
|
||
else if (dMeasureValue >= dStrictTLower && dMeasureValue <= dStrictTUpper)
|
||
{
|
||
aryLineContent[4] = "ng1";
|
||
}
|
||
else if (dMeasureValue >= dExceptionTUpper || dMeasureValue <= dExcepitonTLower)
|
||
{
|
||
// 修复:原先此处 aryLineContent[2] = "" 会把超差的实测值清空,
|
||
// 导致客户CSV报告与XML汇总测出率系统性偏低,现仅打标ng3,保留原始测量值。
|
||
aryLineContent[4] = "ng3";
|
||
MyBase.TraceWriteLine("EH3 " + aryLineContent[0] + " " + aryLineContent[1] + " 实测值=" + dMeasureValue.ToString("F2") + " 超出异常公差区间[" + dExcepitonTLower.ToString("F2") + "," + dExceptionTUpper.ToString("F2") + "],结果ng3,原值保留。");
|
||
}
|
||
else
|
||
{
|
||
aryLineContent[4] = "ng2";
|
||
}
|
||
}
|
||
|
||
//测量数据存储到table里
|
||
dtCSVContent.Rows.Add(strCarID, "EH3", aryLineContent[0], aryLineContent[1], dNormalValue.ToString("F1"), dLowerValue.ToString("F1"), dUpperValue.ToString("F1"), aryLineContent[2], aryLineContent[4], DateTime.Now, "");
|
||
string strMeasureResult = aryLineContent[4].ToLower();
|
||
if (strMeasureResult.Contains("good") || strMeasureResult.Contains("best") || strMeasureResult.Contains("ng1"))
|
||
{
|
||
OKCount++;
|
||
aryLineContent[4] = "OK";
|
||
}
|
||
else if (strMeasureResult.Contains("ng2"))
|
||
{
|
||
OutCount++;
|
||
aryLineContent[4] = "NG";
|
||
}
|
||
else
|
||
{
|
||
// ng3 / noTol 等异常分支:原先此处 aryLineContent[2] = "" 也会清空实测值,
|
||
// 现保留原始值用于追溯,仅清空结果列。
|
||
RejectedCount++;
|
||
aryLineContent[4] = "";
|
||
}
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Add(aryLineContent[0], aryLineContent[1], dNormalValue.ToString("F1"), dLowerValue.ToString("F1"), dUpperValue.ToString("F1"), aryLineContent[2], ConfigDfn.strMeasureTime, aryLineContent[4]);
|
||
}));
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = aryLineContent[1];
|
||
cIOTData.pointNumber = aryLineContent[0];
|
||
cIOTData.actualValue = aryLineContent[2];
|
||
cIOTData.controlLine = dLowerValue.ToString("F1") + @"/" + dUpperValue.ToString("F1");
|
||
if (strMeasureResult.Contains("good") || strMeasureResult.Contains("best") || strMeasureResult.Contains("ng1"))
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
cIOTData.measurementResult = "NG";
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
dtRowCount++;
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows[dtRowCount - 1].HeaderCell.Value = dtRowCount.ToString();
|
||
}));
|
||
}
|
||
}//End While
|
||
sr.Close();
|
||
fs.Close();
|
||
// 数据完整性校验日志:统计本次解析后多少测点保留了原始测量值(修复Bug前ng3/noTol会被清空)
|
||
int iEH3TotalRows = dtCSVContent.Rows.Count;
|
||
int iEH3WithValue = 0;
|
||
int iEH3EmptyValue = 0;
|
||
int iEH3NoTolCount = 0;
|
||
int iEH3Ng3Count = 0;
|
||
foreach (DataRow drCheck in dtCSVContent.Rows)
|
||
{
|
||
string sVal = drCheck["MeasureValue"]?.ToString() ?? "";
|
||
string sRes = (drCheck["MeasureItemResult"]?.ToString() ?? "").ToLower();
|
||
if (string.IsNullOrEmpty(sVal)) iEH3EmptyValue++; else iEH3WithValue++;
|
||
if (sRes.Contains("notol")) iEH3NoTolCount++;
|
||
if (sRes.Contains("ng3")) iEH3Ng3Count++;
|
||
}
|
||
MyBase.TraceWriteLine($"[EH3完整性] 车号={strCarID} 测点总数={iEH3TotalRows} 有值={iEH3WithValue} 空值={iEH3EmptyValue} ng3={iEH3Ng3Count} noTol={iEH3NoTolCount}");
|
||
tmdal.InsertTMeasureDatabyDataTable(dtCSVContent);
|
||
MyBase.TraceWriteLine("解析EH3数据完成,并将所有测量数据插入到数据库完毕。");
|
||
MyBase.TraceWriteLine("解析NextSense EH3 CSV 报告完毕!检测项数=" + dtRowCount.ToString());
|
||
if (dtRowCount <= ConfigDfn.iMeasureItemsCount)
|
||
{
|
||
iCurrentMeasureItemsFailedCount++;
|
||
}
|
||
else
|
||
{
|
||
iCurrentMeasureItemsFailedCount = 0;
|
||
}
|
||
|
||
// 连续多个车异常
|
||
if (iCurrentMeasureItemsFailedCount >= ConfigDfn.iFailedCarCount)
|
||
{
|
||
MyBase.TraceWriteLine("iCurrentMeasureItemsFailedCount=" + iCurrentMeasureItemsFailedCount.ToString() + "超过报警数量" + ConfigDfn.iFailedCarCount.ToString() + " ;给PLC发送报警10。");
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.MeasureError, (byte)10);
|
||
}
|
||
|
||
// 单个报告内 invalued 项超过某个值
|
||
|
||
// 机器人忙碌状态 且 多个小时无测量报告
|
||
|
||
#endregion 解析EH3 CSV报告
|
||
|
||
#region 计算极差
|
||
CalculateRange(strCarID, "EH3");
|
||
Thread.Sleep(20);
|
||
DataTable dtAllRangeDate = tmdal.SelectRangeDatabyCarID(strCarID);
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
if (ConfigDfn.iIncludeRangeFlag == 1)
|
||
{
|
||
if (row.ItemArray[5].ToString().Contains("OK"))
|
||
{
|
||
OKCount++;
|
||
}
|
||
else
|
||
{
|
||
OutCount++;
|
||
}
|
||
}
|
||
|
||
Invoke((MethodInvoker)(() => { dgvMeasureContent.Rows.Add(row.ItemArray[2].ToString(), "G", "0", row.ItemArray[4].ToString().Substring(0, 3), row.ItemArray[4].ToString().Substring(4, 3), row.ItemArray[3].ToString(), ConfigDfn.strMeasureTime, row.ItemArray[5].ToString()); }));
|
||
}
|
||
}
|
||
|
||
if (ConfigDfn.iIncludeRangeFlag == 1)
|
||
{
|
||
dtRowCount = dtRowCount + dtAllRangeDate.Rows.Count;
|
||
for (int i = 1; i <= dtRowCount; i++)
|
||
{
|
||
Invoke((MethodInvoker)(() => { dgvMeasureContent.Rows[i - 1].HeaderCell.Value = i.ToString(); }));
|
||
}
|
||
|
||
MyBase.TraceWriteLine("计算合格率的时:包含极差计算项!");
|
||
}
|
||
#endregion 计算极差
|
||
string strTargetRate = "";
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
#region 界面显示功能
|
||
|
||
labCarType.Text = "EH3";
|
||
TMeasureResultModel tmrm = new TMeasureResultModel();
|
||
labNGCount.Text = OutCount.ToString();
|
||
labOKCount.Text = OKCount.ToString();
|
||
labRejectCount.Text = RejectedCount.ToString();
|
||
labMeaTime.Text = ConfigDfn.strMeasureTime;
|
||
labSumMeasureCount.Text = dtRowCount.ToString();
|
||
FPYPercent = OKCount / (OKCount + OutCount);
|
||
if (FPYPercent >= ConfigDfn.dFPY)
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "合格";
|
||
labResultPercent.ForeColor = Color.LimeGreen;
|
||
labResult.ForeColor = Color.LimeGreen;
|
||
pbResult.Image = Resources.OK;
|
||
tmrm.Result = 1;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)10);
|
||
}
|
||
else if (FPYPercent >= ConfigDfn.dFPY2 && FPYPercent < ConfigDfn.dFPY)
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "合格";
|
||
labResultPercent.ForeColor = Color.Yellow;
|
||
labResult.ForeColor = Color.Yellow;
|
||
pbResult.Image = Resources.OK;
|
||
tmrm.Result = 1;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)20);
|
||
}
|
||
else
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "不合格";
|
||
labResultPercent.ForeColor = Color.Red;
|
||
labResult.ForeColor = Color.Red;
|
||
pbResult.Image = Resources.NG;
|
||
tmrm.Result = 2;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)30);
|
||
}
|
||
xValues[0] = "合格 : " + OKCount.ToString();
|
||
xValues[1] = "不合格 : " + OutCount.ToString();
|
||
xValues[2] = "异常 : " + RejectedCount.ToString();
|
||
yValues[0] = (int)OKCount;
|
||
yValues[1] = (int)OutCount;
|
||
yValues[2] = (int)RejectedCount;
|
||
chartResultPie.Series[0].Points.DataBindXY(xValues, yValues);
|
||
|
||
strTargetRate = Math.Round(ConfigDfn.dFPY2 * 100.00d, 2).ToString("F2") + "%";
|
||
|
||
tmrm.CarID = strCarID;
|
||
tmrm.CarType = "EH3";
|
||
tmrm.SumMeasureItems = dtRowCount;
|
||
tmrm.GoodMeasureItems = (int)OKCount;
|
||
tmrm.NoGoodMeasureItems = (int)OutCount;
|
||
tmrm.RejectMeasureItems = (int)RejectedCount;
|
||
tmrm.FPY = FPYPercent.ToString("F4");
|
||
tmrm.Remark = "";
|
||
tmrm.MeasureDate = ConfigDfn.strMeasureTime;
|
||
tmdal.InsertTMeasureResult(tmrm);
|
||
MyBase.TraceWriteLine("将EH3总结果插入数据库完毕。");
|
||
MyBase.TraceWriteLine("全部插入解析完毕,删除文件:" + fi.Name);
|
||
fi.Delete();
|
||
dgvMeasureContent.Rows.Add();
|
||
dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].Cells["MResult"].Value = (dtRowCount - OutCount - RejectedCount).ToString() + "/" + dtRowCount.ToString();
|
||
this.dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.White;
|
||
if (dgvMeasureContent.Rows.Count > 0)
|
||
{
|
||
SetdgvRowBgColor(dgvMeasureContent);
|
||
for (int i = 0; i < dgvMeasureContent.Rows.Count; i++)
|
||
{
|
||
//if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("ok"))
|
||
//{
|
||
// dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Orange;
|
||
//}
|
||
if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("ng"))
|
||
{
|
||
dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Orange;
|
||
}
|
||
else if (string.IsNullOrEmpty(dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString()))
|
||
{
|
||
dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Red;
|
||
}
|
||
else
|
||
{
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion 界面显示功能
|
||
}));
|
||
|
||
//生成客户的 CSV文件
|
||
if (ConfigDfn.iCreateReportFlag == 1)
|
||
{
|
||
GenUserReportCSV(strCarID, listCSVTitleInfo, dtAllRangeDate, FPYPercent);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EH3数据生成报告功能未启用!");
|
||
}
|
||
|
||
#region Update Data To IOT
|
||
|
||
if (ConfigDfn.iStartIOTFlag == 1)
|
||
{
|
||
bool bVINMeasuedFlag = tmdal.CheckVINExistInDB(strCarID);
|
||
if (bVINMeasuedFlag)
|
||
{
|
||
MyBase.TraceWriteLine("VIN:" + strCarID + " 该VIN码已经在数据库中存在了,说明已经测量过了,不再进行IOT数据上传操作。");
|
||
}
|
||
else
|
||
{
|
||
#region IOT上传功能
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = "G";
|
||
cIOTData.pointNumber = row.ItemArray[2].ToString();
|
||
cIOTData.actualValue = row.ItemArray[3].ToString();
|
||
cIOTData.controlLine = row.ItemArray[4].ToString();
|
||
cIOTData.measurementResult = row.ItemArray[5].ToString();
|
||
if (cIOTData.measurementResult.ToUpper().Contains("NG"))
|
||
{
|
||
if (!string.IsNullOrEmpty(cIOTData.actualValue) && !cIOTData.actualValue.ToLower().Contains("inv")) //避免为空的情况
|
||
{
|
||
dLowerValue = double.Parse(row.ItemArray[4].ToString().Substring(0, 3));
|
||
dUpperValue = double.Parse(row.ItemArray[4].ToString().Substring(4, 3));
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
double dValue = double.Parse(row.ItemArray[3].ToString());
|
||
if (dValue > dStrictTLower && dValue < dStrictTUpper)
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
}
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
}
|
||
}
|
||
string strGapList = JsonHelper.ObjectToJson(ListPostIOTData);
|
||
string strCaliResult = "OK";
|
||
if (labResult.Text == "合格")
|
||
{
|
||
strCaliResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
strCaliResult = "NG";
|
||
}
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"requestData\":[{\"vin\":\"" + strCarID + "\",\"model\":\"EH3\",\"equipmentNo\":\"" + ConfigDfn.strEquipNo + "\",\"equipmentName\":\"" + ConfigDfn.strEquipName + "\",\"calibrationResult\":\"" + strCaliResult + "\",\"detectionTime\":\"" + ConfigDfn.strMeasureTime + "\",\"targetRate\":\"" + strTargetRate + "\",\"rate\":\"" + labResultPercent.Text + "\",\"GapList\":" + strGapList + "}]}";
|
||
|
||
MyBase.TraceWriteLine("Update To IOT Data Content: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTAddress, strPostData, 10000);
|
||
MyBase.TraceWriteLine("EH3数据上传IOT完成,结果返回为:" + strPostResult);
|
||
if (strPostResult.Contains("成功"))
|
||
{
|
||
MyBase.TraceWriteLine("EH3数据上传IOT成功 ^_^");
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, true, labResultPercent.Text);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EH3数据上传IOT失败!");
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, false, labResultPercent.Text);
|
||
}
|
||
|
||
#endregion IOT上传功能
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("数据上传IOT功能未启用!");
|
||
}
|
||
|
||
#endregion Update Data To IOT
|
||
}
|
||
}
|
||
}
|
||
//else
|
||
//{
|
||
// MyBase.TraceWriteLine("错误:AnalysisNextSenseEH3CSV函数中,检测EH3 CSV 路径不存在:" + ConfigDfn.strNextSenseCSVPath);
|
||
//}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("AnalysisNextSenseCSV 函数分析异常:" + ex.ToString());
|
||
}
|
||
}
|
||
|
||
private void AnalysisNextSenseEHYCSV() //解析EHY 车型
|
||
{
|
||
try
|
||
{
|
||
Invoke((MethodInvoker)(() => { lbCSVFiles.Items.Clear(); }));
|
||
FileInfo[] fileInfos = null;
|
||
if (Directory.Exists(ConfigDfn.strNextSenseCSVEHYPath))
|
||
{
|
||
DirectoryInfo di = new DirectoryInfo(ConfigDfn.strNextSenseCSVEHYPath);
|
||
fileInfos = di.GetFiles("*.CSV");
|
||
if (fileInfos.Count() >= 1)
|
||
{
|
||
MyBase.TraceWriteLine("存在EHY CSV文件,开始解析:");
|
||
List<string> listCSVTitleInfo = new List<string>();
|
||
string strCarID = "";
|
||
foreach (FileInfo fi in fileInfos)
|
||
{
|
||
listCSVTitleInfo.Clear();
|
||
ListPostIOTData.Clear();
|
||
dtCSVContent.Clear();
|
||
|
||
string strCSVName = fi.FullName;
|
||
try
|
||
{
|
||
File.Copy(fi.FullName, ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name, true);
|
||
}
|
||
catch (IOException ioEx)
|
||
{
|
||
MyBase.TraceWriteLine("EHY CSV文件被占用,跳过本次解析,等待下次轮询:" + fi.Name + " | " + ioEx.Message);
|
||
Thread.Sleep(500);
|
||
continue;
|
||
}
|
||
MyBase.TraceWriteLine("Copy " + fi.FullName + " TO " + ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name + " Done. 备份完成");
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Clear();
|
||
lbCSVFiles.Items.Add(fi.Name);
|
||
}));
|
||
|
||
#region 解析EHY CSV报告
|
||
|
||
MyBase.TraceWriteLine("开始解析NextSense EHY CSV 报告:" + strCSVName);
|
||
Encoding encoding = GetType(strCSVName);
|
||
FileStream fs = new FileStream(strCSVName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
StreamReader sr = new StreamReader(fs, encoding);
|
||
//记录每次读取的一行记录
|
||
string strLine = "";
|
||
//记录每行记录中的各字段内容
|
||
string[] aryLineContent = null;
|
||
|
||
//逐行读取CSV中的数据
|
||
int LineNum = 0;
|
||
//表格行数
|
||
int dtRowCount = 0;
|
||
//超差个数
|
||
double OutCount = 0;
|
||
//Ok个数
|
||
double OKCount = 0;
|
||
//异常个数
|
||
double RejectedCount = 0;
|
||
//合格率
|
||
double FPYPercent = 0;
|
||
double dStrictTLower = 0;
|
||
double dStrictTUpper = 0;
|
||
double dLowerValue = 0;
|
||
double dUpperValue = 0;
|
||
double dExcepitonTLower = 0;
|
||
double dExceptionTUpper = 0;
|
||
double dMeasureValue = 0.0;
|
||
DataTable dt = null;
|
||
while ((strLine = sr.ReadLine()) != null)
|
||
{
|
||
LineNum++;
|
||
if (LineNum >= 3 & LineNum <= 16)
|
||
{
|
||
listCSVTitleInfo.Add(strLine);
|
||
}
|
||
if (LineNum == 10)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
MyBase.TraceWriteLine("解析出NextSense CSV中的VIN为:" + aryLineContent[1]);
|
||
strCarID = tmdal.SelectVINByCSVVIN(aryLineContent[1]);
|
||
MyBase.TraceWriteLine("通过CSV VIN从数据库中获取的完整VIN为:" + strCarID);
|
||
if (strCarID.ToLower().Contains("nofind"))
|
||
{
|
||
MyBase.TraceWriteLine("数据库中没有查找到VIN码,NoFind, +L 使用CSV码");
|
||
labVIN.Text = "L" + aryLineContent[1];
|
||
strCarID = "L" + aryLineContent[1];
|
||
}
|
||
else
|
||
{
|
||
labVIN.Text = strCarID;
|
||
tmdal.DeleteOneTTempVIN(strCarID);
|
||
MyBase.TraceWriteLine("在数据库表TTempSaveVIN中删除该VIN:" + strCarID);
|
||
}
|
||
}
|
||
if (LineNum >= 19)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
ConfigDfn.strMeasureTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
double dNormalValue = 0.0d;
|
||
|
||
bool bToleranceValid = false;
|
||
dt = tmdal.SelectOneToleranceByCondition("EHY", aryLineContent[0], aryLineContent[1]);
|
||
if (dt.Rows.Count == 1)
|
||
{
|
||
dLowerValue = double.Parse(dt.Rows[0]["TolLower"].ToString());
|
||
dUpperValue = double.Parse(dt.Rows[0]["TolUpper"].ToString());
|
||
dNormalValue = (dLowerValue + dUpperValue) / 2;
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
dExcepitonTLower = CalculateExceptionLowerTolerance(dLowerValue, dUpperValue);
|
||
dExceptionTUpper = CalculateExceptionUpperTolerance(dLowerValue, dUpperValue);
|
||
bToleranceValid = true;
|
||
}
|
||
else
|
||
{
|
||
// 修复:公差未配置时显式重置异常公差,避免上一轮循环遗留值
|
||
// 同时不再用0作为默认公差(否则后续 dMeasureValue>=0||<=0 几乎恒真,会把所有实测值误判为ng3并清空)
|
||
dStrictTLower = 0;
|
||
dStrictTUpper = 0;
|
||
dLowerValue = 0;
|
||
dUpperValue = 0;
|
||
dExcepitonTLower = 0;
|
||
dExceptionTUpper = 0;
|
||
MyBase.TraceWriteLine("EHY " + aryLineContent[0] + " " + aryLineContent[1] + " 查询数据获取公差带失败!数据库中数量不唯一或不存在,请检查公差带配置!原始测量值将保留并写入数据库,结果标记为noTol。");
|
||
}
|
||
|
||
if (aryLineContent[2].ToLower().Contains("inv"))
|
||
{
|
||
aryLineContent[2] = "";
|
||
aryLineContent[4] = "ng2";
|
||
}
|
||
else if (!bToleranceValid)
|
||
{
|
||
// 修复:公差缺失时保留原始测量值,标记为noTol,避免数据系统性丢失
|
||
MyBase.TraceWriteLine("EHY " + aryLineContent[0] + " " + aryLineContent[1] + " 公差未配置,保留原始测量值=" + aryLineContent[2] + ",结果标记为noTol。");
|
||
aryLineContent[4] = "noTol";
|
||
}
|
||
else
|
||
{
|
||
dMeasureValue = double.Parse(aryLineContent[2]);
|
||
if (dMeasureValue >= dLowerValue && dMeasureValue <= dUpperValue)
|
||
{
|
||
aryLineContent[4] = "good";
|
||
}
|
||
else if (dMeasureValue >= dStrictTLower && dMeasureValue <= dStrictTUpper)
|
||
{
|
||
aryLineContent[4] = "ng1";
|
||
}
|
||
else if (dMeasureValue >= dExceptionTUpper || dMeasureValue <= dExcepitonTLower)
|
||
{
|
||
// 修复:原先此处 aryLineContent[2] = "" 会把超差的实测值清空,
|
||
// 导致客户CSV报告与XML汇总测出率系统性偏低,现仅打标ng3,保留原始测量值。
|
||
aryLineContent[4] = "ng3";
|
||
MyBase.TraceWriteLine("EHY " + aryLineContent[0] + " " + aryLineContent[1] + " 实测值=" + dMeasureValue.ToString("F2") + " 超出异常公差区间[" + dExcepitonTLower.ToString("F2") + "," + dExceptionTUpper.ToString("F2") + "],结果ng3,原值保留。");
|
||
}
|
||
else
|
||
{
|
||
aryLineContent[4] = "ng2";
|
||
}
|
||
}
|
||
|
||
//测量数据存储到table里
|
||
dtCSVContent.Rows.Add(strCarID, "EHY", aryLineContent[0], aryLineContent[1], dNormalValue.ToString("F1"), dLowerValue.ToString("F1"), dUpperValue.ToString("F1"), aryLineContent[2], aryLineContent[4], DateTime.Now, "");
|
||
string strMeasureResult = aryLineContent[4].ToLower();
|
||
if (strMeasureResult.Contains("good") || strMeasureResult.Contains("best") || strMeasureResult.Contains("ng1"))
|
||
{
|
||
OKCount++;
|
||
aryLineContent[4] = "OK";
|
||
}
|
||
else if (strMeasureResult.Contains("ng2"))
|
||
{
|
||
OutCount++;
|
||
aryLineContent[4] = "NG";
|
||
}
|
||
else
|
||
{
|
||
// ng3 / noTol 等异常分支:原先此处 aryLineContent[2] = "" 也会清空实测值,
|
||
// 现保留原始值用于追溯,仅清空结果列。
|
||
RejectedCount++;
|
||
aryLineContent[4] = "";
|
||
}
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Add(aryLineContent[0], aryLineContent[1], dNormalValue.ToString("F1"), dLowerValue.ToString("F1"), dUpperValue.ToString("F1"), aryLineContent[2], ConfigDfn.strMeasureTime, aryLineContent[4]);
|
||
}));
|
||
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = aryLineContent[1];
|
||
cIOTData.pointNumber = aryLineContent[0];
|
||
cIOTData.actualValue = aryLineContent[2];
|
||
cIOTData.controlLine = dLowerValue.ToString("F1") + @"/" + dUpperValue.ToString("F1");
|
||
if (strMeasureResult.Contains("good") || strMeasureResult.Contains("best") || strMeasureResult.Contains("ng1"))
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
cIOTData.measurementResult = "NG";
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
dtRowCount++;
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows[dtRowCount - 1].HeaderCell.Value = dtRowCount.ToString();
|
||
}));
|
||
}
|
||
}//End While
|
||
sr.Close();
|
||
fs.Close();
|
||
// 数据完整性校验日志:统计本次解析后多少测点保留了原始测量值(修复Bug前ng3/noTol会被清空)
|
||
int iEHYTotalRows = dtCSVContent.Rows.Count;
|
||
int iEHYWithValue = 0;
|
||
int iEHYEmptyValue = 0;
|
||
int iEHYNoTolCount = 0;
|
||
int iEHYNg3Count = 0;
|
||
foreach (DataRow drCheck in dtCSVContent.Rows)
|
||
{
|
||
string sVal = drCheck["MeasureValue"]?.ToString() ?? "";
|
||
string sRes = (drCheck["MeasureItemResult"]?.ToString() ?? "").ToLower();
|
||
if (string.IsNullOrEmpty(sVal)) iEHYEmptyValue++; else iEHYWithValue++;
|
||
if (sRes.Contains("notol")) iEHYNoTolCount++;
|
||
if (sRes.Contains("ng3")) iEHYNg3Count++;
|
||
}
|
||
MyBase.TraceWriteLine($"[EHY完整性] 车号={strCarID} 测点总数={iEHYTotalRows} 有值={iEHYWithValue} 空值={iEHYEmptyValue} ng3={iEHYNg3Count} noTol={iEHYNoTolCount}");
|
||
tmdal.InsertTMeasureDatabyDataTable(dtCSVContent);
|
||
MyBase.TraceWriteLine("解析EHY数据完成,并将所有测量数据插入到数据库完毕。");
|
||
MyBase.TraceWriteLine("解析NextSense EHY CSV 报告完毕!检查数量=" + dtRowCount.ToString());
|
||
if (dtRowCount <= ConfigDfn.iMeasureItemsCount)
|
||
{
|
||
iCurrentMeasureItemsFailedCount++;
|
||
}
|
||
else
|
||
{
|
||
iCurrentMeasureItemsFailedCount = 0;
|
||
}
|
||
|
||
if (iCurrentMeasureItemsFailedCount >= ConfigDfn.iFailedCarCount)
|
||
{
|
||
MyBase.TraceWriteLine("iCurrentMeasureItemsFailedCount=" + iCurrentMeasureItemsFailedCount.ToString() + "超过报警数量" + ConfigDfn.iFailedCarCount.ToString() + " ;给PLC发送报警10。");
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.MeasureError, (byte)10);
|
||
}
|
||
#endregion 解析EHY CSV报告
|
||
|
||
#region 计算极差
|
||
CalculateRange(strCarID, "EHY");
|
||
Thread.Sleep(20);
|
||
DataTable dtAllRangeDate = tmdal.SelectRangeDatabyCarID(strCarID);
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
if (ConfigDfn.iIncludeRangeFlag == 1)
|
||
{
|
||
if (row.ItemArray[5].ToString().Contains("OK"))
|
||
{
|
||
OKCount++;
|
||
}
|
||
else
|
||
{
|
||
OutCount++;
|
||
}
|
||
}
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Add(row.ItemArray[2].ToString(), "G", "0", row.ItemArray[4].ToString().Substring(0, 3), row.ItemArray[4].ToString().Substring(4, 3), row.ItemArray[3].ToString(), ConfigDfn.strMeasureTime, row.ItemArray[5].ToString());
|
||
}));
|
||
}
|
||
}
|
||
|
||
if (ConfigDfn.iIncludeRangeFlag == 1)
|
||
{
|
||
dtRowCount = dtRowCount + dtAllRangeDate.Rows.Count;
|
||
for (int i = 1; i <= dtRowCount; i++)
|
||
{
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows[i - 1].HeaderCell.Value = i.ToString();
|
||
}));
|
||
}
|
||
MyBase.TraceWriteLine("计算合格率的时:包含极差计算项!");
|
||
}
|
||
|
||
#endregion 计算极差
|
||
string strTargetRate = "";
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
#region 界面显示功能
|
||
|
||
labCarType.Text = "EHY";
|
||
TMeasureResultModel tmrm = new TMeasureResultModel();
|
||
labNGCount.Text = OutCount.ToString();
|
||
labOKCount.Text = OKCount.ToString();
|
||
labRejectCount.Text = RejectedCount.ToString();
|
||
labMeaTime.Text = ConfigDfn.strMeasureTime;
|
||
labSumMeasureCount.Text = dtRowCount.ToString();
|
||
FPYPercent = OKCount / (OKCount + OutCount);
|
||
if (FPYPercent >= ConfigDfn.dFPY)
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "合格";
|
||
labResultPercent.ForeColor = Color.LimeGreen;
|
||
labResult.ForeColor = Color.LimeGreen;
|
||
pbResult.Image = Resources.OK;
|
||
tmrm.Result = 1;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)10);
|
||
}
|
||
else if (FPYPercent >= ConfigDfn.dFPY2 && FPYPercent < ConfigDfn.dFPY)
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "合格";
|
||
labResultPercent.ForeColor = Color.Yellow;
|
||
labResult.ForeColor = Color.Yellow;
|
||
pbResult.Image = Resources.OK;
|
||
tmrm.Result = 1;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)20);
|
||
}
|
||
else
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "不合格";
|
||
labResultPercent.ForeColor = Color.Red;
|
||
labResult.ForeColor = Color.Red;
|
||
pbResult.Image = Resources.NG;
|
||
tmrm.Result = 2;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)30);
|
||
}
|
||
xValues[0] = "合格 : " + OKCount.ToString();
|
||
xValues[1] = "不合格 : " + OutCount.ToString();
|
||
xValues[2] = "异常 : " + RejectedCount.ToString();
|
||
yValues[0] = (int)OKCount;
|
||
yValues[1] = (int)OutCount;
|
||
yValues[2] = (int)RejectedCount;
|
||
chartResultPie.Series[0].Points.DataBindXY(xValues, yValues);
|
||
|
||
strTargetRate = Math.Round(ConfigDfn.dFPY2 * 100.00d, 2).ToString("F2") + "%";
|
||
|
||
tmrm.CarID = strCarID;
|
||
tmrm.CarType = "EHY";
|
||
tmrm.SumMeasureItems = dtRowCount;
|
||
tmrm.GoodMeasureItems = (int)OKCount;
|
||
tmrm.NoGoodMeasureItems = (int)OutCount;
|
||
tmrm.RejectMeasureItems = (int)RejectedCount;
|
||
tmrm.FPY = FPYPercent.ToString("F4");
|
||
tmrm.Remark = "";
|
||
tmrm.MeasureDate = ConfigDfn.strMeasureTime;
|
||
tmdal.InsertTMeasureResult(tmrm);
|
||
MyBase.TraceWriteLine("将总结果插入数据库完毕。");
|
||
MyBase.TraceWriteLine("全部插入解析完毕,删除文件:" + fi.Name);
|
||
fi.Delete();
|
||
|
||
dgvMeasureContent.Rows.Add();
|
||
dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].Cells["MResult"].Value = (dtRowCount - OutCount - RejectedCount).ToString() + "/" + dtRowCount.ToString();
|
||
this.dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.White;
|
||
if (dgvMeasureContent.Rows.Count > 0)
|
||
{
|
||
SetdgvRowBgColor(dgvMeasureContent);
|
||
for (int i = 0; i < dgvMeasureContent.Rows.Count; i++)
|
||
{
|
||
//if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("ok"))
|
||
//{
|
||
// dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Orange;
|
||
//}
|
||
if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("ng"))
|
||
{
|
||
dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Orange;
|
||
}
|
||
else if (string.IsNullOrEmpty(dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString()))
|
||
{
|
||
dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Red;
|
||
}
|
||
else
|
||
{
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion 界面显示功能
|
||
}));
|
||
|
||
if (ConfigDfn.iCreateReportFlag == 1)
|
||
{
|
||
GenUserReportCSV(strCarID, listCSVTitleInfo, dtAllRangeDate, FPYPercent);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("iCreateReportFlag=0 : EHY数据生成报告功能未启用!");
|
||
}
|
||
|
||
#region Update Data To IOT
|
||
|
||
if (ConfigDfn.iStartIOTFlag == 1)
|
||
{
|
||
bool bVINMeasuedFlag = tmdal.CheckVINExistInDB(strCarID);
|
||
if (bVINMeasuedFlag)
|
||
{
|
||
MyBase.TraceWriteLine("VIN:" + strCarID + " 该VIN码已经在数据库中存在了,说明已经测量过了,不再进行IOT数据上传操作。");
|
||
}
|
||
else
|
||
{
|
||
// 上传 IOT功能
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = "G";
|
||
cIOTData.pointNumber = row.ItemArray[2].ToString();
|
||
cIOTData.actualValue = row.ItemArray[3].ToString();
|
||
cIOTData.controlLine = row.ItemArray[4].ToString();
|
||
cIOTData.measurementResult = row.ItemArray[5].ToString();
|
||
if (cIOTData.measurementResult.ToUpper().Contains("NG"))
|
||
{
|
||
if (!string.IsNullOrEmpty(cIOTData.actualValue) && !cIOTData.actualValue.ToLower().Contains("inv")) //避免为空的情况
|
||
{
|
||
dLowerValue = double.Parse(row.ItemArray[4].ToString().Substring(0, 3));
|
||
dUpperValue = double.Parse(row.ItemArray[4].ToString().Substring(4, 3));
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
double dValue = double.Parse(row.ItemArray[3].ToString());
|
||
if (dValue > dStrictTLower && dValue < dStrictTUpper)
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
}
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
}
|
||
}
|
||
string strGapList = JsonHelper.ObjectToJson(ListPostIOTData);
|
||
string strCaliResult = "OK";
|
||
if (labResult.Text == "合格")
|
||
{
|
||
strCaliResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
strCaliResult = "NG";
|
||
}
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"requestData\":[{\"vin\":\"" + strCarID + "\",\"model\":\"EHY\",\"equipmentNo\":\"" + ConfigDfn.strEquipNo + "\",\"equipmentName\":\"" + ConfigDfn.strEquipName + "\",\"calibrationResult\":\"" + strCaliResult + "\",\"detectionTime\":\"" + ConfigDfn.strMeasureTime + "\",\"targetRate\":\"" + strTargetRate + "\",\"rate\":\"" + labResultPercent.Text + "\",\"GapList\":" + strGapList + "}]}";
|
||
|
||
MyBase.TraceWriteLine("Update To IOT Data Content: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTAddress, strPostData, 10000);
|
||
MyBase.TraceWriteLine("EHY数据上传IOT完成,结果返回为:" + strPostResult);
|
||
if (strPostResult.Contains("成功"))
|
||
{
|
||
MyBase.TraceWriteLine("EHY数据上传IOT成功 ^_^");
|
||
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, true, labResultPercent.Text);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHY数据上传IOT失败!");
|
||
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, false, labResultPercent.Text);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHY数据上传IOT功能未启用!");
|
||
}
|
||
|
||
#endregion Update Data To IOT
|
||
}
|
||
}
|
||
}
|
||
//else
|
||
//{
|
||
// MyBase.TraceWriteLine("错误:AnalysisNextSenseEHYCSV 函数中,检测EHY CSV 路径不存在:" + ConfigDfn.strNextSenseCSVEHYPath);
|
||
//}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("AnalysisNextSenseEHYCSV 函数分析异常:" + ex.ToString());
|
||
}
|
||
}
|
||
|
||
private void AnalysisNextSenseEHVCSV() // 解析EHV 车型
|
||
{
|
||
try
|
||
{
|
||
Invoke((MethodInvoker)(() => { lbCSVFiles.Items.Clear(); }));
|
||
FileInfo[] fileInfos = null;
|
||
if (Directory.Exists(ConfigDfn.strNextSenseCSVEHVPath))
|
||
{
|
||
DirectoryInfo di = new DirectoryInfo(ConfigDfn.strNextSenseCSVEHVPath);
|
||
fileInfos = di.GetFiles("*.CSV");
|
||
if (fileInfos.Count() >= 1)
|
||
{
|
||
MyBase.TraceWriteLine("存在EHV CSV文件,开始解析:");
|
||
List<string> listCSVTitleInfo = new List<string>();
|
||
string strCarID = "";
|
||
foreach (FileInfo fi in fileInfos)
|
||
{
|
||
listCSVTitleInfo.Clear();
|
||
ListPostIOTData.Clear();
|
||
dtCSVContent.Clear();
|
||
|
||
string strCSVName = fi.FullName;
|
||
try
|
||
{
|
||
File.Copy(fi.FullName, ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name, true);
|
||
}
|
||
catch (IOException ioEx)
|
||
{
|
||
MyBase.TraceWriteLine("EHV CSV文件被占用,跳过本次解析,等待下次轮询:" + fi.Name + " | " + ioEx.Message);
|
||
Thread.Sleep(500);
|
||
continue;
|
||
}
|
||
MyBase.TraceWriteLine("Copy " + fi.FullName + " TO " + ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name + " Done. 备份完成");
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Clear();
|
||
lbCSVFiles.Items.Add(fi.Name);
|
||
}));
|
||
|
||
#region 解析EHV CSV报告
|
||
|
||
MyBase.TraceWriteLine("开始解析NextSense EHV CSV 报告:" + strCSVName);
|
||
Encoding encoding = GetType(strCSVName);
|
||
FileStream fs = new FileStream(strCSVName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
StreamReader sr = new StreamReader(fs, encoding);
|
||
string strLine = "";
|
||
string[] aryLineContent = null;
|
||
int LineNum = 0;
|
||
int dtRowCount = 0;
|
||
double OutCount = 0;
|
||
double OKCount = 0;
|
||
double RejectedCount = 0;
|
||
double FPYPercent = 0;
|
||
double dStrictTLower = 0;
|
||
double dStrictTUpper = 0;
|
||
double dLowerValue = 0;
|
||
double dUpperValue = 0;
|
||
double dExcepitonTLower = 0;
|
||
double dExceptionTUpper = 0;
|
||
double dMeasureValue = 0.0;
|
||
DataTable dt = null;
|
||
while ((strLine = sr.ReadLine()) != null)
|
||
{
|
||
LineNum++;
|
||
if (LineNum >= 3 & LineNum <= 16)
|
||
{
|
||
listCSVTitleInfo.Add(strLine);
|
||
}
|
||
if (LineNum == 10)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
MyBase.TraceWriteLine("解析出NextSense CSV中的VIN为:" + aryLineContent[1]);
|
||
strCarID = tmdal.SelectVINByCSVVIN(aryLineContent[1]);
|
||
MyBase.TraceWriteLine("通过CSV VIN从数据库中获取的完整VIN为:" + strCarID);
|
||
if (strCarID.ToLower().Contains("nofind"))
|
||
{
|
||
MyBase.TraceWriteLine("数据库中没有查找到VIN码,NoFind, +L 使用CSV码");
|
||
strCarID = "L" + aryLineContent[1];
|
||
Invoke((MethodInvoker)(() => { labVIN.Text = strCarID; }));
|
||
}
|
||
else
|
||
{
|
||
Invoke((MethodInvoker)(() => { labVIN.Text = strCarID; }));
|
||
tmdal.DeleteOneTTempVIN(strCarID);
|
||
MyBase.TraceWriteLine("在数据库表TTempSaveVIN中删除该VIN:" + strCarID);
|
||
}
|
||
}
|
||
if (LineNum >= 19)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
ConfigDfn.strMeasureTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
double dNormalValue = 0.0d;
|
||
|
||
bool bToleranceValid = false;
|
||
dt = tmdal.SelectOneToleranceByCondition("EHV", aryLineContent[0], aryLineContent[1]);
|
||
if (dt.Rows.Count == 1)
|
||
{
|
||
dLowerValue = double.Parse(dt.Rows[0]["TolLower"].ToString());
|
||
dUpperValue = double.Parse(dt.Rows[0]["TolUpper"].ToString());
|
||
dNormalValue = (dLowerValue + dUpperValue) / 2;
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
dExcepitonTLower = CalculateExceptionLowerTolerance(dLowerValue, dUpperValue);
|
||
dExceptionTUpper = CalculateExceptionUpperTolerance(dLowerValue, dUpperValue);
|
||
bToleranceValid = true;
|
||
}
|
||
else
|
||
{
|
||
// 修复:公差未配置时显式重置异常公差,避免上一轮循环遗留值
|
||
// 同时不再用0作为默认公差(否则后续 dMeasureValue>=0||<=0 几乎恒真,会把所有实测值误判为ng3并清空)
|
||
dStrictTLower = 0;
|
||
dStrictTUpper = 0;
|
||
dLowerValue = 0;
|
||
dUpperValue = 0;
|
||
dExcepitonTLower = 0;
|
||
dExceptionTUpper = 0;
|
||
MyBase.TraceWriteLine("EHV " + aryLineContent[0] + " " + aryLineContent[1] + " 查询数据获取公差带失败!数据库中数量不唯一或不存在,请检查公差带配置!原始测量值将保留并写入数据库,结果标记为noTol。");
|
||
}
|
||
|
||
if (aryLineContent[2].ToLower().Contains("inv"))
|
||
{
|
||
aryLineContent[2] = "";
|
||
aryLineContent[4] = "ng2";
|
||
}
|
||
else if (!bToleranceValid)
|
||
{
|
||
// 修复:公差缺失时保留原始测量值,标记为noTol,避免数据系统性丢失
|
||
MyBase.TraceWriteLine("EHV " + aryLineContent[0] + " " + aryLineContent[1] + " 公差未配置,保留原始测量值=" + aryLineContent[2] + ",结果标记为noTol。");
|
||
aryLineContent[4] = "noTol";
|
||
}
|
||
else
|
||
{
|
||
dMeasureValue = double.Parse(aryLineContent[2]);
|
||
if (dMeasureValue >= dLowerValue && dMeasureValue <= dUpperValue)
|
||
{
|
||
aryLineContent[4] = "good";
|
||
}
|
||
else if (dMeasureValue >= dStrictTLower && dMeasureValue <= dStrictTUpper)
|
||
{
|
||
aryLineContent[4] = "ng1";
|
||
}
|
||
else if (dMeasureValue >= dExceptionTUpper || dMeasureValue <= dExcepitonTLower)
|
||
{
|
||
// 修复:原先此处 aryLineContent[2] = "" 会把超差的实测值清空,
|
||
// 导致客户CSV报告与XML汇总测出率系统性偏低,现仅打标ng3,保留原始测量值。
|
||
aryLineContent[4] = "ng3";
|
||
MyBase.TraceWriteLine("EHV " + aryLineContent[0] + " " + aryLineContent[1] + " 实测值=" + dMeasureValue.ToString("F2") + " 超出异常公差区间[" + dExcepitonTLower.ToString("F2") + "," + dExceptionTUpper.ToString("F2") + "],结果ng3,原值保留。");
|
||
}
|
||
else
|
||
{
|
||
aryLineContent[4] = "ng2";
|
||
}
|
||
}
|
||
|
||
dtCSVContent.Rows.Add(strCarID, "EHV", aryLineContent[0], aryLineContent[1], dNormalValue.ToString("F1"), dLowerValue.ToString("F1"), dUpperValue.ToString("F1"), aryLineContent[2], aryLineContent[4], DateTime.Now, "");
|
||
string strMeasureResult = aryLineContent[4].ToLower();
|
||
if (strMeasureResult.Contains("good") || strMeasureResult.Contains("best") || strMeasureResult.Contains("ng1"))
|
||
{
|
||
OKCount++;
|
||
aryLineContent[4] = "OK";
|
||
}
|
||
else if (strMeasureResult.Contains("ng2"))
|
||
{
|
||
OutCount++;
|
||
aryLineContent[4] = "NG";
|
||
}
|
||
else
|
||
{
|
||
// ng3 / noTol 等异常分支:原先此处 aryLineContent[2] = "" 也会清空实测值,
|
||
// 现保留原始值用于追溯,仅清空结果列。
|
||
RejectedCount++;
|
||
aryLineContent[4] = "";
|
||
}
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Add(aryLineContent[0], aryLineContent[1], dNormalValue.ToString("F1"), dLowerValue.ToString("F1"), dUpperValue.ToString("F1"), aryLineContent[2], ConfigDfn.strMeasureTime, aryLineContent[4]);
|
||
}));
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = aryLineContent[1];
|
||
cIOTData.pointNumber = aryLineContent[0];
|
||
cIOTData.actualValue = aryLineContent[2];
|
||
cIOTData.controlLine = dLowerValue.ToString("F1") + @"/" + dUpperValue.ToString("F1");
|
||
if (strMeasureResult.Contains("good") || strMeasureResult.Contains("best") || strMeasureResult.Contains("ng1"))
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
cIOTData.measurementResult = "NG";
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
dtRowCount++;
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows[dtRowCount - 1].HeaderCell.Value = dtRowCount.ToString();
|
||
}));
|
||
}
|
||
}//End While
|
||
sr.Close();
|
||
fs.Close();
|
||
// 数据完整性校验日志:统计本次解析后多少测点保留了原始测量值(修复Bug前ng3/noTol会被清空)
|
||
int iEHVTotalRows = dtCSVContent.Rows.Count;
|
||
int iEHVWithValue = 0;
|
||
int iEHVEmptyValue = 0;
|
||
int iEHVNoTolCount = 0;
|
||
int iEHVNg3Count = 0;
|
||
foreach (DataRow drCheck in dtCSVContent.Rows)
|
||
{
|
||
string sVal = drCheck["MeasureValue"]?.ToString() ?? "";
|
||
string sRes = (drCheck["MeasureItemResult"]?.ToString() ?? "").ToLower();
|
||
if (string.IsNullOrEmpty(sVal)) iEHVEmptyValue++; else iEHVWithValue++;
|
||
if (sRes.Contains("notol")) iEHVNoTolCount++;
|
||
if (sRes.Contains("ng3")) iEHVNg3Count++;
|
||
}
|
||
MyBase.TraceWriteLine($"[EHV完整性] 车号={strCarID} 测点总数={iEHVTotalRows} 有值={iEHVWithValue} 空值={iEHVEmptyValue} ng3={iEHVNg3Count} noTol={iEHVNoTolCount}");
|
||
tmdal.InsertTMeasureDatabyDataTable(dtCSVContent);
|
||
MyBase.TraceWriteLine("解析EHV数据完成,并将所有测量数据插入到数据库完毕。");
|
||
MyBase.TraceWriteLine("解析NextSense EHV CSV 报告完毕!检测项数=" + dtRowCount.ToString());
|
||
if (dtRowCount <= ConfigDfn.iMeasureItemsCount)
|
||
{
|
||
iCurrentMeasureItemsFailedCount++;
|
||
}
|
||
else
|
||
{
|
||
iCurrentMeasureItemsFailedCount = 0;
|
||
}
|
||
|
||
if (iCurrentMeasureItemsFailedCount >= ConfigDfn.iFailedCarCount)
|
||
{
|
||
MyBase.TraceWriteLine("iCurrentMeasureItemsFailedCount=" + iCurrentMeasureItemsFailedCount.ToString() + "超过报警数量" + ConfigDfn.iFailedCarCount.ToString() + " ;给PLC发送报警10。");
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.MeasureError, (byte)10);
|
||
}
|
||
|
||
#endregion 解析EHV CSV报告
|
||
|
||
#region 计算极差
|
||
CalculateRange(strCarID, "EHV");
|
||
Thread.Sleep(20);
|
||
DataTable dtAllRangeDate = tmdal.SelectRangeDatabyCarID(strCarID);
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
if (ConfigDfn.iIncludeRangeFlag == 1)
|
||
{
|
||
if (row.ItemArray[5].ToString().Contains("OK"))
|
||
{
|
||
OKCount++;
|
||
}
|
||
else
|
||
{
|
||
OutCount++;
|
||
}
|
||
}
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Add(row.ItemArray[2].ToString(), "G", "0", row.ItemArray[4].ToString().Substring(0, 3), row.ItemArray[4].ToString().Substring(4, 3), row.ItemArray[3].ToString(), ConfigDfn.strMeasureTime, row.ItemArray[5].ToString());
|
||
}));
|
||
}
|
||
}
|
||
|
||
if (ConfigDfn.iIncludeRangeFlag == 1)
|
||
{
|
||
dtRowCount = dtRowCount + dtAllRangeDate.Rows.Count;
|
||
for (int i = 1; i <= dtRowCount; i++)
|
||
{
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows[i - 1].HeaderCell.Value = i.ToString();
|
||
}));
|
||
}
|
||
MyBase.TraceWriteLine("计算合格率的时:包含极差计算项!");
|
||
}
|
||
#endregion 计算极差
|
||
|
||
MyBase.TraceWriteLine($"[EHV] 准备更新UI:OKCount={OKCount}, OutCount={OutCount}, RejectedCount={RejectedCount}, dtRowCount={dtRowCount}, listCSVTitleInfo.Count={listCSVTitleInfo.Count}, dtCSVContent.Rows.Count={dtCSVContent.Rows.Count}");
|
||
string strTargetRate = "";
|
||
try
|
||
{
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
#region 界面显示功能
|
||
|
||
labCarType.Text = "EHV";
|
||
TMeasureResultModel tmrm = new TMeasureResultModel();
|
||
labNGCount.Text = OutCount.ToString();
|
||
labOKCount.Text = OKCount.ToString();
|
||
labRejectCount.Text = RejectedCount.ToString();
|
||
labMeaTime.Text = ConfigDfn.strMeasureTime;
|
||
labSumMeasureCount.Text = dtRowCount.ToString();
|
||
FPYPercent = OKCount / (OKCount + OutCount);
|
||
if (FPYPercent >= ConfigDfn.dFPY)
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "合格";
|
||
labResultPercent.ForeColor = Color.LimeGreen;
|
||
labResult.ForeColor = Color.LimeGreen;
|
||
pbResult.Image = Resources.OK;
|
||
tmrm.Result = 1;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)10);
|
||
}
|
||
else if (FPYPercent >= ConfigDfn.dFPY2 && FPYPercent < ConfigDfn.dFPY)
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "合格";
|
||
labResultPercent.ForeColor = Color.Yellow;
|
||
labResult.ForeColor = Color.Yellow;
|
||
pbResult.Image = Resources.OK;
|
||
tmrm.Result = 1;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)20);
|
||
}
|
||
else
|
||
{
|
||
labResultPercent.Text = Math.Round(FPYPercent * 100.00d, 2).ToString("F2") + "%";
|
||
labResult.Text = "不合格";
|
||
labResultPercent.ForeColor = Color.Red;
|
||
labResult.ForeColor = Color.Red;
|
||
pbResult.Image = Resources.NG;
|
||
tmrm.Result = 2;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.CMMResult, (byte)30);
|
||
}
|
||
xValues[0] = "合格 : " + OKCount.ToString();
|
||
xValues[1] = "不合格 : " + OutCount.ToString();
|
||
xValues[2] = "异常 : " + RejectedCount.ToString();
|
||
yValues[0] = (int)OKCount;
|
||
yValues[1] = (int)OutCount;
|
||
yValues[2] = (int)RejectedCount;
|
||
chartResultPie.Series[0].Points.DataBindXY(xValues, yValues);
|
||
|
||
strTargetRate = Math.Round(ConfigDfn.dFPY2 * 100.00d, 2).ToString("F2") + "%";
|
||
|
||
tmrm.CarID = strCarID;
|
||
tmrm.CarType = "EHV";
|
||
tmrm.SumMeasureItems = dtRowCount;
|
||
tmrm.GoodMeasureItems = (int)OKCount;
|
||
tmrm.NoGoodMeasureItems = (int)OutCount;
|
||
tmrm.RejectMeasureItems = (int)RejectedCount;
|
||
tmrm.FPY = FPYPercent.ToString("F4");
|
||
tmrm.Remark = "";
|
||
tmrm.MeasureDate = ConfigDfn.strMeasureTime;
|
||
tmdal.InsertTMeasureResult(tmrm);
|
||
MyBase.TraceWriteLine("将EHV总结果插入数据库完毕。");
|
||
MyBase.TraceWriteLine("全部插入解析完毕,删除文件:" + fi.Name);
|
||
fi.Delete();
|
||
dgvMeasureContent.Rows.Add();
|
||
dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].Cells["MResult"].Value = (dtRowCount - OutCount - RejectedCount).ToString() + "/" + dtRowCount.ToString();
|
||
this.dgvMeasureContent.Rows[dgvMeasureContent.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.White;
|
||
if (dgvMeasureContent.Rows.Count > 0)
|
||
{
|
||
SetdgvRowBgColor(dgvMeasureContent);
|
||
for (int i = 0; i < dgvMeasureContent.Rows.Count; i++)
|
||
{
|
||
if (dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString().ToLower().Contains("ng"))
|
||
{
|
||
dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Orange;
|
||
}
|
||
else if (string.IsNullOrEmpty(dgvMeasureContent.Rows[i].Cells["MResult"].Value.ToString()))
|
||
{
|
||
dgvMeasureContent.Rows[i].DefaultCellStyle.BackColor = Color.Red;
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion 界面显示功能
|
||
}));
|
||
}
|
||
catch (Exception exInvoke)
|
||
{
|
||
MyBase.TraceWriteLine("[EHV] Invoke UI更新异常:" + exInvoke.Message + " | StackTrace: " + exInvoke.StackTrace);
|
||
}
|
||
|
||
MyBase.TraceWriteLine($"[EHV] iCreateReportFlag={ConfigDfn.iCreateReportFlag}, strSaveReprotPath={strSaveReprotPath}, listCSVTitleInfo.Count={listCSVTitleInfo.Count}, dtAllRangeDate.Rows.Count={dtAllRangeDate.Rows.Count}, FPYPercent={FPYPercent}");
|
||
if (ConfigDfn.iCreateReportFlag == 1)
|
||
{
|
||
MyBase.TraceWriteLine("[EHV] 开始调用 GenUserReportCSV...");
|
||
GenUserReportCSV(strCarID, listCSVTitleInfo, dtAllRangeDate, FPYPercent);
|
||
MyBase.TraceWriteLine("[EHV] GenUserReportCSV 调用完毕。");
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHV数据生成报告功能未启用!");
|
||
}
|
||
|
||
#region Update Data To IOT
|
||
|
||
if (ConfigDfn.iStartIOTFlag == 1)
|
||
{
|
||
bool bVINMeasuedFlag = tmdal.CheckVINExistInDB(strCarID);
|
||
if (bVINMeasuedFlag)
|
||
{
|
||
MyBase.TraceWriteLine("VIN:" + strCarID + " 该VIN码已经在数据库中存在了,说明已经测量过了,不再进行IOT数据上传操作。");
|
||
}
|
||
else
|
||
{
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = "G";
|
||
cIOTData.pointNumber = row.ItemArray[2].ToString();
|
||
cIOTData.actualValue = row.ItemArray[3].ToString();
|
||
cIOTData.controlLine = row.ItemArray[4].ToString();
|
||
cIOTData.measurementResult = row.ItemArray[5].ToString();
|
||
if (cIOTData.measurementResult.ToUpper().Contains("NG"))
|
||
{
|
||
if (!string.IsNullOrEmpty(cIOTData.actualValue) && !cIOTData.actualValue.ToLower().Contains("inv"))
|
||
{
|
||
dLowerValue = double.Parse(row.ItemArray[4].ToString().Substring(0, 3));
|
||
dUpperValue = double.Parse(row.ItemArray[4].ToString().Substring(4, 3));
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
double dValue = double.Parse(row.ItemArray[3].ToString());
|
||
if (dValue > dStrictTLower && dValue < dStrictTUpper)
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
}
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
}
|
||
}
|
||
string strGapList = JsonHelper.ObjectToJson(ListPostIOTData);
|
||
string strCaliResult = labResult.Text == "合格" ? "OK" : "NG";
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"requestData\":[{\"vin\":\"" + strCarID + "\",\"model\":\"EHV\",\"equipmentNo\":\"" + ConfigDfn.strEquipNo + "\",\"equipmentName\":\"" + ConfigDfn.strEquipName + "\",\"calibrationResult\":\"" + strCaliResult + "\",\"detectionTime\":\"" + ConfigDfn.strMeasureTime + "\",\"targetRate\":\"" + strTargetRate + "\",\"rate\":\"" + labResultPercent.Text + "\",\"GapList\":" + strGapList + "}]}";
|
||
|
||
MyBase.TraceWriteLine("Update To IOT Data Content: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTAddress, strPostData, 10000);
|
||
MyBase.TraceWriteLine("EHV数据上传IOT完成,结果返回为:" + strPostResult);
|
||
if (strPostResult.Contains("成功"))
|
||
{
|
||
MyBase.TraceWriteLine("EHV数据上传IOT成功 ^_^");
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, true, labResultPercent.Text);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHV数据上传IOT失败!");
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, false, labResultPercent.Text);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHV数据上传IOT功能未启用!");
|
||
}
|
||
|
||
#endregion Update Data To IOT
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("AnalysisNextSenseEHVCSV 函数分析异常:" + ex.ToString());
|
||
}
|
||
}
|
||
|
||
private void AnalysisNextSenseSelfMeasureCSV() {
|
||
try
|
||
{
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
lbCSVFiles.Items.Clear();
|
||
}));
|
||
|
||
FileInfo[] fileInfos = null;
|
||
if (Directory.Exists(ConfigDfn.strNextSenseSelfMeasurePath))
|
||
{
|
||
DirectoryInfo di = new DirectoryInfo(ConfigDfn.strNextSenseSelfMeasurePath);
|
||
fileInfos = di.GetFiles("*.CSV");
|
||
if (fileInfos.Count() >= 1)
|
||
{
|
||
MyBase.TraceWriteLine("存在NS 自检报告 CSV文件,开始解析:");
|
||
List<string> listCSVTitleInfo = new List<string>();
|
||
string strCarID = "SelfMeasure" + DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
foreach (FileInfo fi in fileInfos)
|
||
{
|
||
listCSVTitleInfo.Clear();
|
||
ListPostIOTData.Clear();
|
||
dtCSVContent.Clear();
|
||
|
||
string strCSVName = fi.FullName;
|
||
File.Copy(fi.FullName, ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name, true);
|
||
MyBase.TraceWriteLine("Copy " + fi.FullName + " TO " + ConfigDfn.strFileFolder + "\\NextSenseCSVBackup\\" + fi.Name + " Done. 备份完成");
|
||
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Clear();
|
||
lbCSVFiles.Items.Add(fi.Name);
|
||
}));
|
||
#region 解析NextSense自检CSV报告
|
||
|
||
MyBase.TraceWriteLine("开始解析NextSense 自检报告 CSV 报告:" + strCSVName);
|
||
Encoding encoding = GetType(strCSVName);
|
||
FileStream fs = new FileStream(strCSVName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
StreamReader sr = new StreamReader(fs, encoding);
|
||
//记录每次读取的一行记录
|
||
string strLine = "";
|
||
//记录每行记录中的各字段内容
|
||
string[] aryLineContent = null;
|
||
|
||
//逐行读取CSV中的数据
|
||
int LineNum = 0;
|
||
//表格行数
|
||
int dtRowCount = 0;
|
||
|
||
while ((strLine = sr.ReadLine()) != null)
|
||
{
|
||
LineNum++;
|
||
if (LineNum >= 1 & LineNum <= 17)
|
||
{
|
||
listCSVTitleInfo.Add(strLine);
|
||
}
|
||
if (LineNum >= 19)
|
||
{
|
||
aryLineContent = strLine.Split(',');
|
||
ConfigDfn.strMeasureTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
if (aryLineContent[2].ToLower().Contains("inv"))
|
||
{
|
||
aryLineContent[2] = ""; //当为inv ,内容为空
|
||
aryLineContent[10] = "NG";
|
||
}
|
||
string strMeasPointName = "";
|
||
if (aryLineContent[0].ToUpper().Contains("L"))
|
||
{
|
||
strMeasPointName = "L-ZJ1";
|
||
}
|
||
else
|
||
{
|
||
strMeasPointName = "R-ZJ1";
|
||
}
|
||
//测量数据存储到table里
|
||
dtCSVContent.Rows.Add(strCarID, "SelfMeasure", strMeasPointName, aryLineContent[1], aryLineContent[4], aryLineContent[8], aryLineContent[9], aryLineContent[2], aryLineContent[10], DateTime.Now, "");
|
||
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
dgvMeasureContent.Rows.Add(strMeasPointName, aryLineContent[1], aryLineContent[4], aryLineContent[8], aryLineContent[9], aryLineContent[2], ConfigDfn.strMeasureTime, aryLineContent[10]);
|
||
|
||
dtRowCount++;
|
||
dgvMeasureContent.Rows[dtRowCount - 1].HeaderCell.Value = dtRowCount.ToString();
|
||
}));
|
||
}
|
||
}//End While
|
||
sr.Close();
|
||
fs.Close();
|
||
|
||
MyBase.TraceWriteLine("解析NextSense 自检报告完毕!检查数量=" + dtRowCount.ToString());
|
||
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
labCarType.Text = "自检报告";
|
||
}));
|
||
fi.Delete();
|
||
#endregion 解析NextSense自检CSV报告
|
||
|
||
if (ConfigDfn.iCreateReportFlag == 1)
|
||
{
|
||
#region 解析完报告后,重新生成客户模板报告
|
||
|
||
MyBase.TraceWriteLine("开始生成客户所需要的CSV格式文件:");
|
||
string targetFilePath = strSaveReprotPath + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + strCarID + ".csv"; //wsp 后期还要再改
|
||
|
||
// 创建临时路径,为应用程序目录\ReportBackup 路径下
|
||
|
||
string backupDirectoryPath = Application.StartupPath + "\\ReportBackup";
|
||
|
||
if (!Directory.Exists(backupDirectoryPath))
|
||
{
|
||
Directory.CreateDirectory(backupDirectoryPath);
|
||
//日志
|
||
MyBase.TraceWriteLine("创建ReportBackup文件夹完毕,路径为:" + backupDirectoryPath);
|
||
}
|
||
|
||
// 构造备份文件路径,\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" +
|
||
// strCarID + ".csv"
|
||
string backupFilePath = backupDirectoryPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + strCarID + ".csv";
|
||
|
||
// 记录备份文件路径
|
||
MyBase.TraceWriteLine("客户自检报告备份路径为:" + backupFilePath);
|
||
|
||
StringBuilder sb = new StringBuilder();
|
||
//添加表头
|
||
sb.Append("Measurement Info Name");
|
||
sb.Append(",");
|
||
sb.Append("Measurement Info");
|
||
sb.AppendLine();
|
||
sb.Append("Date_Time");
|
||
sb.Append(",");
|
||
sb.Append(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
|
||
sb.AppendLine();
|
||
for (int i = 2; i < listCSVTitleInfo.Count - 1; i++)
|
||
{
|
||
if (listCSVTitleInfo[i].Contains("prodnum"))
|
||
{
|
||
listCSVTitleInfo[i] = listCSVTitleInfo[i].Replace("prodnum,", "Part_ident," + DateTime.Now.ToString("yyyyMMdd"));
|
||
}
|
||
|
||
sb.Append(listCSVTitleInfo[i]);
|
||
sb.AppendLine();
|
||
}
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
//添加测量数据
|
||
sb.Append("Characteristic");
|
||
sb.Append(",");
|
||
sb.Append("Extension");
|
||
sb.Append(",");
|
||
sb.Append("Measured_Value");
|
||
sb.AppendLine();
|
||
foreach (DataRow row in dtCSVContent.Rows)
|
||
{
|
||
sb.Append(row.ItemArray[2]);
|
||
sb.Append(",");
|
||
sb.Append(row.ItemArray[3]);
|
||
sb.Append(",");
|
||
sb.Append(row.ItemArray[7]);
|
||
sb.AppendLine();
|
||
}
|
||
sb.AppendLine();
|
||
// 将数据写入CSV文件
|
||
File.WriteAllText(backupFilePath, sb.ToString());
|
||
MyBase.TraceWriteLine("客户自检报告生成完毕,备份路径为:" + targetFilePath);
|
||
|
||
// 尝试进行复制到 目标路径 往目标路径copy该文件,并记录是否成功
|
||
try
|
||
{
|
||
File.Copy(backupFilePath, targetFilePath, true);
|
||
|
||
// 记录上传情况
|
||
bool isUploaded = true;
|
||
// 记录输入情况 strCarID、目标路径、备份路径、是否上传成功
|
||
MyBase.TraceWriteLine($"车号: {strCarID} | 目标路径: {targetFilePath} | 备份路径: {backupDirectoryPath} | 上传成功: {isUploaded}");
|
||
tmdal.InsertCsvReportUploadLog(strCarID, targetFilePath, backupDirectoryPath, isUploaded);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("客户自检报告复制异常:" + ex.Message);
|
||
|
||
// 记录上传情况
|
||
bool isUploaded = false;
|
||
MyBase.TraceWriteLine($"车号: {strCarID} | 目标路径: {targetFilePath} | 备份路径: {backupDirectoryPath} | 上传成功: {isUploaded}");
|
||
tmdal.InsertCsvReportUploadLog(strCarID, targetFilePath, backupDirectoryPath, isUploaded);
|
||
}
|
||
|
||
#endregion 解析完报告后,重新生成客户模板报告
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("iCreateReportFlag=0 : 数据生成报告功能未启用!");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("AnalysisNextSenseSelfMeasureCSV 函数分析异常:" + ex.ToString());
|
||
}
|
||
}
|
||
|
||
public void GenUserReportCSV(string strCarID, List<string> listCSVTitleInfo, DataTable dtAllRangeDate, double FPYPercent)
|
||
{
|
||
#region 解析完报告后,重新生成客户模板报告
|
||
|
||
MyBase.TraceWriteLine($"[GenUserReportCSV] 进入函数:strCarID={strCarID}, listCSVTitleInfo.Count={listCSVTitleInfo.Count}, dtAllRangeDate.Rows.Count={dtAllRangeDate.Rows.Count}, FPYPercent={FPYPercent}, dtCSVContent.Rows.Count={dtCSVContent.Rows.Count}");
|
||
MyBase.TraceWriteLine($"[GenUserReportCSV] strSaveReprotPath={strSaveReprotPath}");
|
||
|
||
// 目的路径
|
||
string targetFilePath = strSaveReprotPath + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + strCarID + ".csv"; //wsp 后期还要再改
|
||
|
||
// 新建一个备份路径,应用程序根目录\ReportBackup
|
||
string backupFolderPath = Application.StartupPath + "\\ReportBackup";
|
||
if (!Directory.Exists(backupFolderPath))
|
||
{
|
||
Directory.CreateDirectory(backupFolderPath);
|
||
//日志
|
||
MyBase.TraceWriteLine("创建ReportBackup文件夹完毕,路径为:" + backupFolderPath);
|
||
}
|
||
|
||
// 构造备份文件路径,\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + strCarID + ".csv"
|
||
string backupFilePath = backupFolderPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + strCarID + ".csv";
|
||
|
||
// 记录备份文件路径
|
||
MyBase.TraceWriteLine("客户自检报告备份路径为:" + backupFilePath);
|
||
|
||
string strWithoutLCarVin = strCarID.Substring(1);
|
||
StringBuilder sb = new StringBuilder();
|
||
//添加表头
|
||
sb.Append("Measurement Info Name");
|
||
sb.Append(",");
|
||
sb.Append("Measurement Info");
|
||
sb.AppendLine();
|
||
sb.Append("Date_Time");
|
||
sb.Append(",");
|
||
sb.Append(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
|
||
sb.AppendLine();
|
||
for (int i = 0; i < listCSVTitleInfo.Count; i++)
|
||
{
|
||
if (listCSVTitleInfo[i].Contains("prodnum"))
|
||
{
|
||
listCSVTitleInfo[i] = listCSVTitleInfo[i].Replace("prodnum", "Part_ident");
|
||
}
|
||
if (listCSVTitleInfo[i].Contains(strWithoutLCarVin))
|
||
{
|
||
listCSVTitleInfo[i] = listCSVTitleInfo[i].Replace(strWithoutLCarVin, strCarID);
|
||
}
|
||
sb.Append(listCSVTitleInfo[i]);
|
||
sb.AppendLine();
|
||
}
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
//添加测量数据
|
||
sb.Append("Characteristic");
|
||
sb.Append(",");
|
||
sb.Append("Extension");
|
||
sb.Append(",");
|
||
sb.Append("Measured_Value");
|
||
sb.AppendLine();
|
||
int iReportTotal = 0;
|
||
int iReportEmpty = 0;
|
||
foreach (DataRow row in dtCSVContent.Rows)
|
||
{
|
||
sb.Append(row.ItemArray[2]);
|
||
sb.Append(",");
|
||
sb.Append(row.ItemArray[3]);
|
||
sb.Append(",");
|
||
sb.Append(row.ItemArray[7]);
|
||
sb.AppendLine();
|
||
iReportTotal++;
|
||
if (string.IsNullOrEmpty(row.ItemArray[7]?.ToString())) iReportEmpty++;
|
||
}
|
||
MyBase.TraceWriteLine($"[GenUserReportCSV] 客户报告测量行总数={iReportTotal} 其中Measured_Value为空的行数={iReportEmpty} (空值率={(iReportTotal == 0 ? 0 : iReportEmpty * 100.0 / iReportTotal):F1}%)");
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
sb.Append(row.ItemArray[2]);
|
||
sb.Append(",");
|
||
sb.Append("G");
|
||
sb.Append(",");
|
||
sb.Append(row.ItemArray[3]);
|
||
sb.AppendLine();
|
||
}
|
||
}
|
||
sb.Append("POP");
|
||
sb.Append(",");
|
||
sb.Append("P");
|
||
sb.Append(",");
|
||
sb.Append(Math.Round(FPYPercent * 100.00d, 2).ToString("F2"));
|
||
sb.AppendLine();
|
||
// 将数据写入CSV文件
|
||
File.WriteAllText(backupFilePath, sb.ToString());
|
||
// 记录日志,说明备份成功
|
||
MyBase.TraceWriteLine("客户 csv报告备份完毕,路径为:" + backupFilePath);
|
||
|
||
// 往目标路径copy该文件,并记录是否成功
|
||
try
|
||
{
|
||
if (!Directory.Exists(strSaveReprotPath))
|
||
{
|
||
Directory.CreateDirectory(strSaveReprotPath);
|
||
MyBase.TraceWriteLine("[GenUserReportCSV] 目标目录不存在,已创建:" + strSaveReprotPath);
|
||
}
|
||
File.Copy(backupFilePath, targetFilePath, true);
|
||
|
||
// 记录上传情况
|
||
bool isUploaded = true;
|
||
|
||
// 记录输入情况 strCarID、目标路径、备份路径、是否上传成功
|
||
MyBase.TraceWriteLine($"车号: {strCarID} | 目标路径: {targetFilePath} | 备份路径: {backupFilePath} | 上传成功: {isUploaded}");
|
||
|
||
tmdal.InsertCsvReportUploadLog(strCarID, targetFilePath, backupFolderPath, isUploaded);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("客户csv报告复制异常:" + ex.Message);
|
||
|
||
// 记录上传情况
|
||
bool isUploaded = false;
|
||
MyBase.TraceWriteLine($"车号: {strCarID} | 目标路径: {targetFilePath} | 备份路径: {backupFilePath} | 上传成功: {isUploaded}");
|
||
tmdal.InsertCsvReportUploadLog(strCarID, targetFilePath, backupFolderPath, isUploaded);
|
||
}
|
||
|
||
#endregion 解析完报告后,重新生成客户模板报告
|
||
}
|
||
|
||
private void UploadIOTData(string strCarID, DataTable dtAllRangeDate, string strTargetRate)
|
||
{
|
||
double dStrictTLower = 0;
|
||
double dStrictTUpper = 0;
|
||
double dLowerValue = 0;
|
||
double dUpperValue = 0;
|
||
bool bVINMeasuedFlag = tmdal.CheckVINExistInDB(strCarID);
|
||
if (bVINMeasuedFlag)
|
||
{
|
||
MyBase.TraceWriteLine("VIN:" + strCarID + " 该VIN码已经在数据库中存在了,说明已经测量过了,不再进行IOT数据上传操作。");
|
||
}
|
||
else
|
||
{
|
||
// 上传 IOT功能
|
||
if (dtAllRangeDate.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow row in dtAllRangeDate.Rows)
|
||
{
|
||
CheryIOTData cIOTData = new CheryIOTData();
|
||
cIOTData.vin = strCarID;
|
||
cIOTData.gfNo = "G";
|
||
cIOTData.pointNumber = row.ItemArray[2].ToString();
|
||
cIOTData.actualValue = row.ItemArray[3].ToString();
|
||
cIOTData.controlLine = row.ItemArray[4].ToString();
|
||
cIOTData.measurementResult = row.ItemArray[5].ToString();
|
||
if (cIOTData.measurementResult.ToUpper().Contains("NG"))
|
||
{
|
||
if (!string.IsNullOrEmpty(cIOTData.actualValue) && !cIOTData.actualValue.ToLower().Contains("inv")) // 2025.08.27 修复NG数据实际值为空时,上传IOT报错问题
|
||
{
|
||
dLowerValue = double.Parse(row.ItemArray[4].ToString().Substring(0, 3));
|
||
dUpperValue = double.Parse(row.ItemArray[4].ToString().Substring(4, 3));
|
||
dStrictTLower = CalculateStrictLowerTolerance(dLowerValue, dUpperValue);
|
||
dStrictTUpper = CalculateStrictUpperTolerance(dLowerValue, dUpperValue);
|
||
double dValue = double.Parse(row.ItemArray[3].ToString());
|
||
if (dValue > dStrictTLower && dValue < dStrictTUpper)
|
||
{
|
||
cIOTData.measurementResult = "OK";
|
||
}
|
||
}
|
||
}
|
||
ListPostIOTData.Add(cIOTData);
|
||
}
|
||
}
|
||
string strGapList = JsonHelper.ObjectToJson(ListPostIOTData);
|
||
string strCaliResult = "OK";
|
||
if (labResult.Text == "合格")
|
||
{
|
||
strCaliResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
strCaliResult = "NG";
|
||
}
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"requestData\":[{\"vin\":\"" + strCarID + "\",\"model\":\"EHY\",\"equipmentNo\":\"" + ConfigDfn.strEquipNo + "\",\"equipmentName\":\"" + ConfigDfn.strEquipName + "\",\"calibrationResult\":\"" + strCaliResult + "\",\"detectionTime\":\"" + ConfigDfn.strMeasureTime + "\",\"targetRate\":\"" + strTargetRate + "\",\"rate\":\"" + labResultPercent.Text + "\",\"GapList\":" + strGapList + "}]}";
|
||
MyBase.TraceWriteLine("Update To IOT Data Content: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTAddress, strPostData, 10000);
|
||
MyBase.TraceWriteLine("EHY数据上传IOT完成,结果返回为:" + strPostResult);
|
||
if (strPostResult.Contains("成功"))
|
||
{
|
||
MyBase.TraceWriteLine("EHY数据上传IOT成功 ^_^");
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("EHY数据上传IOT失败!");
|
||
}
|
||
}
|
||
}
|
||
|
||
private void CalculateRange(string strVIN, string strCarType)
|
||
{
|
||
MyBase.TraceWriteLine(strVIN + " " + strCarType + "开始计算极差:============");
|
||
tmdal.DeleteRangeData(strVIN);
|
||
dtRangeData.Clear();
|
||
DataTable dtRange = tmdal.SelectRangeByCarType(strCarType);
|
||
if (dtRange != null && dtRange.Rows.Count > 0)
|
||
{
|
||
string strRangeValue = "";
|
||
string strRangeLowUpp = "";
|
||
string strRangeResult = "";
|
||
DateTime dtTime = DateTime.Now;
|
||
string strRemark = "";
|
||
for (int i = 0; i < dtRange.Rows.Count; i++)
|
||
{
|
||
string[] strArrRangePoint = dtRange.Rows[i]["RangePoint"].ToString().Split(',');
|
||
double[] dMeasureData = new double[strArrRangePoint.Length];
|
||
int iCalcCount = 0;
|
||
for (int j = 0; j < strArrRangePoint.Length; j++)
|
||
{
|
||
string strMeasureValue = tmdal.SelectOneMeasureValueByCondition(strVIN, strArrRangePoint[j].Substring(0, 4));
|
||
|
||
if (string.IsNullOrEmpty(strMeasureValue) || strMeasureValue.ToLower().Contains("inv"))
|
||
{
|
||
strRangeValue = "";
|
||
strRangeResult = "NG";
|
||
MyBase.TraceWriteLine(strArrRangePoint[j] + " G 查询的测量值为inv");
|
||
break;
|
||
}
|
||
else if (strMeasureValue.ToLower().Contains("nofind"))
|
||
{
|
||
strRangeValue = "";
|
||
strRangeResult = "NG";
|
||
MyBase.TraceWriteLine(strArrRangePoint[j] + " G 查询的测量值为no find");
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
dMeasureData[j] = Convert.ToDouble(strMeasureValue);
|
||
iCalcCount++;
|
||
}
|
||
}
|
||
|
||
//iCalcCount 的作用就是确保只有全部测点都有效时才计算极差,否则提前退出。
|
||
if (iCalcCount == strArrRangePoint.Length)
|
||
{
|
||
double dMax = dMeasureData.Max();
|
||
double dMin = dMeasureData.Min();
|
||
double dRangeData = dMax - dMin;
|
||
strRangeValue = dRangeData.ToString("F1");
|
||
if (dRangeData >= Convert.ToDouble(dtRange.Rows[i]["RangeLower"]) && dRangeData <= Convert.ToDouble(dtRange.Rows[i]["RangeUpper"]))
|
||
{
|
||
strRangeResult = "OK";
|
||
}
|
||
else
|
||
{
|
||
strRangeResult = "NG";
|
||
}
|
||
}
|
||
strRangeLowUpp = dtRange.Rows[i]["RangeLower"].ToString() + @"/" + dtRange.Rows[i]["RangeUpper"].ToString();
|
||
dtRangeData.Rows.Add(strVIN, dtRange.Rows[i]["RangeName"].ToString(), strRangeValue, strRangeLowUpp, strRangeResult, dtTime, strRemark);
|
||
}
|
||
tmdal.InsertTRangeDatabyDataTable(dtRangeData);
|
||
MyBase.TraceWriteLine(strVIN + " " + strCarType + "计算极差完成,并插入数据库:============");
|
||
}
|
||
}
|
||
|
||
public string PostJsonToIOT(string url, string jsonData, int? timeout = null)
|
||
{
|
||
try
|
||
{
|
||
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
|
||
|
||
if (null != timeout && 0 != timeout)
|
||
{
|
||
req.Timeout = timeout.Value;
|
||
}
|
||
Encoding encoding = Encoding.UTF8;
|
||
byte[] bs = Encoding.UTF8.GetBytes(jsonData);
|
||
string responseData;
|
||
req.Method = "POST";
|
||
req.ContentType = "application/json";
|
||
req.ContentLength = bs.Length;
|
||
using (Stream reqStream = req.GetRequestStream())
|
||
{
|
||
reqStream.Write(bs, 0, bs.Length);
|
||
reqStream.Close();
|
||
}
|
||
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
|
||
{
|
||
using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
|
||
{
|
||
responseData = reader.ReadToEnd();
|
||
}
|
||
}
|
||
return responseData;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return "Error: " + ex.ToString();
|
||
}
|
||
}
|
||
|
||
/// 通过给定的文件流,判断文件的编码类型
|
||
/// <param name="fs">文件流</param>
|
||
/// <returns>文件的编码类型</returns>
|
||
public static Encoding GetType(FileStream fs)
|
||
{
|
||
byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
|
||
byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
|
||
byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM
|
||
System.Text.Encoding reVal = System.Text.Encoding.Default;
|
||
|
||
System.IO.BinaryReader r = new System.IO.BinaryReader(fs, System.Text.Encoding.Default);
|
||
int i;
|
||
int.TryParse(fs.Length.ToString(), out i);
|
||
byte[] ss = r.ReadBytes(i);
|
||
if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
|
||
{
|
||
reVal = System.Text.Encoding.UTF8;
|
||
}
|
||
else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
|
||
{
|
||
reVal = System.Text.Encoding.BigEndianUnicode;
|
||
}
|
||
else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
|
||
{
|
||
reVal = System.Text.Encoding.Unicode;
|
||
}
|
||
r.Close();
|
||
return reVal;
|
||
}
|
||
|
||
/// 判断是否是不带 BOM 的 UTF8 格式
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
private static bool IsUTF8Bytes(byte[] data)
|
||
{
|
||
int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
|
||
byte curByte; //当前分析的字节.
|
||
for (int i = 0; i < data.Length; i++)
|
||
{
|
||
curByte = data[i];
|
||
if (charByteCounter == 1)
|
||
{
|
||
if (curByte >= 0x80)
|
||
{
|
||
//判断当前
|
||
while (((curByte <<= 1) & 0x80) != 0)
|
||
{
|
||
charByteCounter++;
|
||
}
|
||
//标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
|
||
if (charByteCounter == 1 || charByteCounter > 6)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//若是UTF-8 此时第一位必须为1
|
||
if ((curByte & 0xC0) != 0x80)
|
||
{
|
||
return false;
|
||
}
|
||
charByteCounter--;
|
||
}
|
||
}
|
||
if (charByteCounter > 1)
|
||
{
|
||
throw new Exception("非预期的byte格式");
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public Encoding GetType(string FileName)
|
||
{
|
||
FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
Encoding er = GetType(fs);
|
||
fs.Close();
|
||
return er;
|
||
}
|
||
|
||
private void testIotUpload()
|
||
{
|
||
// 修复极差 计算问题
|
||
//LNNBBDEC7SDF49695
|
||
//string strVIN = "LNNBBDEC5SDF49694";
|
||
// string strCarType = "EHY";
|
||
//CalculateRange(strVIN, strCarType);
|
||
|
||
//修复IOt上传问题
|
||
string strCarID = "LNNBDDEF4SDF49707";
|
||
DataTable dtAllRangeDate = tmdal.SelectRangeDatabyCarID(strCarID);
|
||
string strTargetRate = "97.00%";
|
||
UploadIOTData(strCarID, dtAllRangeDate, strTargetRate);
|
||
}
|
||
|
||
#endregion 解析Nextsense CSV文件功能
|
||
|
||
#region Home Page
|
||
|
||
/// <summary>
|
||
/// 设置DataGridView各行变色
|
||
/// </summary>
|
||
/// <param name="dgv">DataGridView</param>
|
||
public void SetdgvRowBgColor(DataGridView dgv)
|
||
{
|
||
if (dgv.Rows.Count > 0)
|
||
{
|
||
foreach (DataGridViewRow item in dgv.Rows)
|
||
{
|
||
if (item.Index % 2 == 0)
|
||
{
|
||
item.DefaultCellStyle.BackColor = Color.FromArgb(19, 46, 53);
|
||
}
|
||
else
|
||
{
|
||
item.DefaultCellStyle.BackColor = Color.FromArgb(27, 60, 68);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//TODO:
|
||
|
||
#endregion Home Page
|
||
|
||
#region Search Data
|
||
|
||
#region datagridview分页功能
|
||
|
||
/// <summary>
|
||
/// LoadPage方法
|
||
/// </summary>
|
||
private void LoadPage()
|
||
{
|
||
if (currentPage < 1) currentPage = 1;
|
||
if (currentPage > pageCount) currentPage = pageCount;
|
||
|
||
int beginRecord; //开始指针
|
||
int endRecord; //结束指针
|
||
DataTable dtTemp;
|
||
dtTemp = PageTable.Clone();//Clone方法只会复制DataTable的结构(列定义),而不会复制数据行的引用。
|
||
|
||
beginRecord = pageSize * (currentPage - 1);
|
||
if (currentPage == 1) beginRecord = 0;
|
||
endRecord = pageSize * currentPage;
|
||
|
||
if (currentPage == pageCount) endRecord = recordCount;
|
||
for (int i = beginRecord; i < endRecord; i++)
|
||
{
|
||
// 使用ImportRow方法将源PageTable的行导入到目标dtTemp
|
||
dtTemp.ImportRow(PageTable.Rows[i]);
|
||
}
|
||
|
||
dgvSelectMeasureData.Rows.Clear();
|
||
|
||
for (int i = 0; i < dtTemp.Rows.Count; i++)
|
||
{
|
||
dgvSelectMeasureData.Rows.Add(new object[] { dtTemp.Rows[i][0], dtTemp.Rows[i][1], dtTemp.Rows[i][2], dtTemp.Rows[i][3], dtTemp.Rows[i][4], dtTemp.Rows[i][5], dtTemp.Rows[i][6], dtTemp.Rows[i][7], dtTemp.Rows[i][8] });
|
||
}
|
||
SetdgvRowBgColor(dgvSelectMeasureData);
|
||
for (int i = 0; i < dgvSelectMeasureData.Rows.Count; i++)
|
||
{
|
||
string strResult = dgvSelectMeasureData.Rows[i].Cells["MeasureItemResult"].Value.ToString();
|
||
if (strResult.ToLower().Contains("ng"))
|
||
{
|
||
//dgvSelectMeasureData.Rows[i].Cells["MeasureItemResult"].Style.ForeColor = Color.Orange;
|
||
dgvSelectMeasureData.Rows[i].DefaultCellStyle.BackColor = Color.Orange;
|
||
}
|
||
if (strResult.ToLower().Contains("rej"))
|
||
{
|
||
dgvSelectMeasureData.Rows[i].Cells["MeasureItemResult"].Style.ForeColor = Color.Red;
|
||
}
|
||
}
|
||
labCurrentPage.Text = "当前页:" + currentPage.ToString(); //当前页
|
||
labSumPages.Text = "共 " + pageCount.ToString() + " 页";//总页数
|
||
labSumRecorders.Text = "总共 " + recordCount.ToString() + " 条记录";//总记录数
|
||
}
|
||
|
||
private void rbtnFirtstPage_Click(object sender, EventArgs e)
|
||
{
|
||
if (currentPage == 1)
|
||
{ return; }
|
||
currentPage = 1;
|
||
LoadPage();
|
||
}
|
||
|
||
private void rbtnPrevPage_Click(object sender, EventArgs e)
|
||
{
|
||
if (currentPage == 1)
|
||
{ return; }
|
||
currentPage--;
|
||
LoadPage();
|
||
}
|
||
|
||
private void rbtnNextPage_Click(object sender, EventArgs e)
|
||
{
|
||
if (currentPage == pageCount)
|
||
{ return; }
|
||
currentPage++;
|
||
LoadPage();
|
||
}
|
||
|
||
private void rbtnLastPage_Click(object sender, EventArgs e)
|
||
{
|
||
if (currentPage == pageCount)
|
||
{ return; }
|
||
currentPage = pageCount;
|
||
LoadPage();
|
||
}
|
||
|
||
private void rddlPageRecorderCount_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e)
|
||
{
|
||
pageSize = int.Parse(rddlPageRecorderCount.Text.Trim());
|
||
//PageSorter();
|
||
}
|
||
|
||
#endregion datagridview分页功能
|
||
|
||
private void rbtnSearchMeaserData_Click(object sender, EventArgs e)
|
||
{
|
||
dgvFPYResult.Visible = false;
|
||
chartFPYLine.Visible = false;
|
||
rbtnExportCSVReport.Visible = false;
|
||
string strStartTime = rdtpStartTime.Value.ToString("yyyy-MM-dd") + " 00:00:00";
|
||
string strEndTime = rdtpEndTime.Value.ToString("yyyy-MM-dd") + " 23:59:59";
|
||
string strCarID = rtbPartID.Text.Trim();
|
||
PageTable.Clear();
|
||
PageTable = tmdal.SelectTMeasureDataByCarIDAndTime(strCarID, strStartTime, strEndTime);
|
||
if (PageTable.Rows.Count > 0)
|
||
{
|
||
recordCount = PageTable.Rows.Count; //记录总行数
|
||
pageCount = (recordCount / pageSize);
|
||
if ((recordCount % pageSize) > 0)
|
||
{
|
||
pageCount++;
|
||
}
|
||
|
||
//默认第一页
|
||
currentPage = 1;
|
||
|
||
LoadPage();//调用加载数据的方法
|
||
dgvSelectMeasureData.Visible = true;
|
||
rbtnExportCSVReport.Visible = true;
|
||
pnlPage.Visible = true;
|
||
labSearchResult.Visible = false;
|
||
pnlPage.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
dgvSelectMeasureData.Visible = false;
|
||
labSearchResult.Visible = true;
|
||
rbtnExportCSVReport.Visible = false;
|
||
pnlPage.Visible = false;
|
||
}
|
||
}
|
||
|
||
private void rbtSelectFPY_Click(object sender, EventArgs e)
|
||
{
|
||
dgvSelectMeasureData.Visible = false;
|
||
rbtnExportCSVReport.Visible = false;
|
||
pnlPage.Visible = false;
|
||
string strStartTime = rdtpStartTime.Value.ToString("yyyy-MM-dd") + " 00:00:00";
|
||
string strEndTime = rdtpEndTime.Value.ToString("yyyy-MM-dd") + " 23:59:59";
|
||
string strCarID = rtbPartID.Text.Trim();
|
||
DataTable dtFPY = new DataTable();
|
||
dtFPY = tmdal.SelectTMeasureResultByTime(strCarID, strStartTime, strEndTime);
|
||
if (dtFPY.Rows.Count > 0)
|
||
{
|
||
dgvFPYResult.Visible = true;
|
||
labSearchResult.Visible = false;
|
||
rbtnExportCSVReport.Visible = true;
|
||
chartFPYLine.Visible = true;
|
||
dgvFPYResult.DataSource = dtFPY;
|
||
SetdgvRowBgColor(dgvFPYResult);
|
||
for (int i = 0; i < dgvFPYResult.Rows.Count; i++)
|
||
{
|
||
if (dgvFPYResult.Rows[i].Cells["SMResult"].Value.ToString().ToLower().Contains("不合格"))
|
||
{
|
||
dgvFPYResult.Rows[i].Cells["SMResult"].Style.ForeColor = Color.Red;
|
||
}
|
||
}
|
||
|
||
#region 合格率折线图
|
||
|
||
//合格率折线图
|
||
string[] strXDate = new string[dtFPY.Rows.Count];
|
||
double[] dFPYResult = new double[dtFPY.Rows.Count];
|
||
for (int i = 0; i < dtFPY.Rows.Count; i++)
|
||
{
|
||
strXDate[i] = dtFPY.Rows[i]["CarID"].ToString();
|
||
}
|
||
for (int i = 0; i < dtFPY.Rows.Count; i++)
|
||
{
|
||
double dResult = double.Parse(dtFPY.Rows[i]["FPY"].ToString());
|
||
dFPYResult[i] = dResult * 100.00;
|
||
}
|
||
chartFPYLine.ChartAreas[0].AxisX.LabelStyle.Angle = -50; //X轴标签倾斜角度设置
|
||
chartFPYLine.ChartAreas[0].AxisY.LabelStyle.Format = "{0:F2}" + "%"; //设置Y轴值的格式化 带%
|
||
chartFPYLine.Series[0].Label = "#VAL%"; //设置显示Y的值
|
||
chartFPYLine.Series[0].LabelForeColor = Color.White;
|
||
chartFPYLine.Series[0].ToolTip = "车身编号 : #VALX \r\n合格率 : #VAL%"; //鼠标移动到对应点显示数值
|
||
chartFPYLine.Series[0].Points.DataBindXY(strXDate, dFPYResult);
|
||
|
||
#endregion 合格率折线图
|
||
}
|
||
else
|
||
{
|
||
dgvFPYResult.Visible = false;
|
||
labSearchResult.Visible = true;
|
||
rbtnExportCSVReport.Visible = false;
|
||
chartFPYLine.Visible = false;
|
||
}
|
||
}
|
||
|
||
public static void ExportdgvDataToCsv(DataGridView dataGridView, string filePath)
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
// 添加列标题
|
||
foreach (DataGridViewColumn column in dataGridView.Columns)
|
||
{
|
||
sb.Append(column.HeaderText);
|
||
sb.Append(",");
|
||
}
|
||
sb.Remove(sb.Length - 1, 1);
|
||
sb.AppendLine();
|
||
|
||
// 添加行数据
|
||
foreach (DataGridViewRow row in dataGridView.Rows)
|
||
{
|
||
foreach (DataGridViewCell cell in row.Cells)
|
||
{
|
||
sb.Append(cell.Value);
|
||
sb.Append(",");
|
||
}
|
||
sb.Remove(sb.Length - 1, 1);
|
||
sb.AppendLine();
|
||
}
|
||
|
||
// 将数据写入CSV文件
|
||
File.WriteAllText(filePath, sb.ToString());
|
||
}
|
||
|
||
public static void ExportDataTableDataToCsv(DataTable dt, string filePath)
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
// 添加列标题
|
||
foreach (DataColumn column in dt.Columns)
|
||
{
|
||
sb.Append(column.ColumnName);
|
||
sb.Append(",");
|
||
}
|
||
sb.Remove(sb.Length - 1, 1);
|
||
sb.AppendLine();
|
||
|
||
// 添加行数据
|
||
foreach (DataRow row in dt.Rows)
|
||
{
|
||
foreach (object item in row.ItemArray)
|
||
{
|
||
sb.Append(item);
|
||
sb.Append(",");
|
||
}
|
||
sb.Remove(sb.Length - 1, 1);
|
||
sb.AppendLine();
|
||
}
|
||
|
||
// 将数据写入CSV文件
|
||
File.WriteAllText(filePath, sb.ToString());
|
||
}
|
||
|
||
private void rbtnExportCSVReport_Click(object sender, EventArgs e)
|
||
{
|
||
string strCSVExportPath = "";
|
||
string strExportTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
||
FolderBrowserDialog m_Folder = new FolderBrowserDialog();
|
||
m_Folder.Description = "请选择要导出的CSV文件的路径";
|
||
m_Folder.RootFolder = Environment.SpecialFolder.Desktop;
|
||
if (dgvFPYResult.Visible == true && dgvFPYResult.Rows.Count > 0)
|
||
{
|
||
m_Folder.ShowDialog();
|
||
if (Directory.Exists(m_Folder.SelectedPath))
|
||
{
|
||
strCSVExportPath = m_Folder.SelectedPath + "\\合格率" + strExportTime + ".CSV";
|
||
ExportdgvDataToCsv(dgvFPYResult, strCSVExportPath);
|
||
}
|
||
}
|
||
if (dgvSelectMeasureData.Visible == true && dgvSelectMeasureData.Rows.Count > 0)
|
||
{
|
||
m_Folder.ShowDialog();
|
||
if (Directory.Exists(m_Folder.SelectedPath))
|
||
{
|
||
strCSVExportPath = m_Folder.SelectedPath + "\\车身尺寸数据" + strExportTime + ".CSV";
|
||
ExportDataTableDataToCsv(PageTable, strCSVExportPath);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void dgvFPYResult_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
|
||
{
|
||
e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1);
|
||
}
|
||
|
||
private void dgvSelectMeasureData_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
|
||
{
|
||
e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1);
|
||
}
|
||
|
||
#endregion Search Data
|
||
|
||
#region IOT数据的重传
|
||
|
||
private void ReSendIotData()
|
||
{
|
||
DataTable dtUnuploaded = tmdal.SelectUnuploadedIOTLogs();
|
||
foreach (DataRow row in dtUnuploaded.Rows)
|
||
{
|
||
string carId = row["CarID"].ToString();
|
||
string content = row["Content"].ToString();
|
||
string fpy = row["FPY"]?.ToString();
|
||
int id = Convert.ToInt32(row["Id"]);
|
||
|
||
// 调用上传接口
|
||
string result = PostJsonToIOT(ConfigDfn.strIOTAddress, content, 10000);
|
||
bool isSuccess = result.Contains("成功");
|
||
|
||
// 更新上传状态
|
||
if (isSuccess)
|
||
{
|
||
tmdal.UpdateIOTUploadStatus(id, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region CP CPK
|
||
|
||
private void rbtnSearchCPCPK_Click(object sender, EventArgs e)
|
||
{
|
||
DataTable dtCPCPK = new DataTable();
|
||
string strMeasureName = rddlMeasurePoint.Text;
|
||
string strSizeName = rddlSizeName.Text.Trim().Substring(0, 1);
|
||
int iLimitCount = (int)nudMeasureCount.Value;
|
||
dtCPCPK = tmdal.SelectMeasureValuebyMeasureNameAndSize(strMeasureName, strSizeName, iLimitCount);
|
||
int iSelectRows = dtCPCPK.Rows.Count;
|
||
if (iSelectRows < 5)
|
||
{
|
||
chartCPCPK.Visible = false;
|
||
labSearchCPCPKResult.Visible = true;
|
||
pnlCPCPK.Visible = false;
|
||
}
|
||
else
|
||
{
|
||
double dNormalValue = double.Parse(dtCPCPK.Rows[0]["NormalValue"].ToString());
|
||
double dLowerTolValue = double.Parse(dtCPCPK.Rows[0]["LowerTolVal"].ToString());
|
||
double dUpperTolValue = double.Parse(dtCPCPK.Rows[0]["UpperTolVal"].ToString());
|
||
double dLSL = dNormalValue + dLowerTolValue;
|
||
double dUSL = dNormalValue + dUpperTolValue;
|
||
|
||
List<double> listMDoubleData = new List<double>();
|
||
List<string> listMStrData = new List<string>();
|
||
listMStrData.Clear();
|
||
listMDoubleData.Clear();
|
||
for (int i = 0; i < iSelectRows; i++)
|
||
{
|
||
listMDoubleData.Add(double.Parse(dtCPCPK.Rows[i]["MeasureValue"].ToString()));
|
||
listMStrData.Add(dtCPCPK.Rows[i]["MeasureValue"].ToString());
|
||
}
|
||
|
||
#region 数据赋值
|
||
|
||
labLSL.Text = dLSL.ToString("F2");
|
||
labUSL.Text = dUSL.ToString("F2");
|
||
labTarget.Text = dNormalValue.ToString("F2");
|
||
labSampleSize.Text = iSelectRows.ToString();
|
||
labAverage.Text = CpCpkHelper.GetAverage(listMStrData).ToString("F4");
|
||
labStdDev.Text = CpCpkHelper.GetSigma(listMStrData).ToString("F4");
|
||
List<double> listCpCpk = CpCpkHelper.GetCpList(listMStrData, dUSL, dLSL);
|
||
labCp.Text = listCpCpk[0].ToString("F4");
|
||
labCpl.Text = listCpCpk[1].ToString("F4");
|
||
labCpu.Text = listCpCpk[2].ToString("F4");
|
||
labCpk.Text = listCpCpk[3].ToString("F4");
|
||
List<double> listPpPpk = CpCpkHelper.GetPpList(listMStrData, dUSL, dLSL);
|
||
labPp.Text = listPpPpk[0].ToString("F4");
|
||
labPpl.Text = listPpPpk[1].ToString("F4");
|
||
labPpu.Text = listPpPpk[2].ToString("F4");
|
||
labPpk.Text = listPpPpk[3].ToString("F4");
|
||
|
||
#endregion 数据赋值
|
||
|
||
#region 画柱状图
|
||
|
||
Dictionary<string, string> histogramDataDic = new Dictionary<string, string>();
|
||
histogramDataDic = CpCpkHelper.GetHistogramData(listMDoubleData);
|
||
string[] strXValue = new string[histogramDataDic.Count];
|
||
int[] dYValue = new int[histogramDataDic.Count];
|
||
for (int i = 0; i <= histogramDataDic.Count - 1; i++)
|
||
{
|
||
strXValue[i] = (histogramDataDic.ElementAt(i).Key);
|
||
dYValue[i] = int.Parse(histogramDataDic.ElementAt(i).Value);
|
||
}
|
||
chartCPCPK.Series[0].Label = "#VAL"; //设置显示Y的值
|
||
chartCPCPK.Series[0].LabelForeColor = Color.White;
|
||
chartCPCPK.Series[0].ToolTip = "区间范围 : #VALX \r\n数量 : #VAL"; //鼠标移动到对应点显示数值
|
||
chartCPCPK.Series[0].Points.DataBindXY(strXValue, dYValue);
|
||
|
||
#endregion 画柱状图
|
||
|
||
chartCPCPK.Visible = true;
|
||
labSearchCPCPKResult.Visible = false;
|
||
pnlCPCPK.Visible = true;
|
||
}
|
||
}
|
||
|
||
#endregion CP CPK
|
||
|
||
#region 软件设置
|
||
|
||
private void lpcSoftwareSetup_Click(object sender, EventArgs e)
|
||
{
|
||
string strInputPwd = MyBase.InputBox("密码", "请输入密码 : ", "", "确定", "取消");
|
||
if (strInputPwd.Contains("-999.999"))
|
||
{
|
||
return;
|
||
}
|
||
else if (strInputPwd == ConfigDfn.strPwd)
|
||
{
|
||
FSoftwareSetup fss = new FSoftwareSetup();
|
||
fss.ShowDialog(this);
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("密码错误! ", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
|
||
private void lpcToleranceSetup_Click(object sender, EventArgs e)
|
||
{
|
||
string strInputPwd = MyBase.InputBox("密码", "请输入密码 : ", "", "确定", "取消");
|
||
if (strInputPwd.Contains("-999.999"))
|
||
{
|
||
return;
|
||
}
|
||
else if (strInputPwd == ConfigDfn.strPwd)
|
||
{
|
||
FToleranceSetup fts = new FToleranceSetup();
|
||
fts.ShowDialog(this);
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("密码错误! ", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
|
||
private void lpcRange_Click(object sender, EventArgs e)
|
||
{
|
||
string strInputPwd = MyBase.InputBox("密码", "请输入密码 : ", "", "确定", "取消");
|
||
if (strInputPwd.Contains("-999.999"))
|
||
{
|
||
return;
|
||
}
|
||
else if (strInputPwd == ConfigDfn.strPwd)
|
||
{
|
||
FRangeSetup frs = new FRangeSetup();
|
||
frs.ShowDialog(this);
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("密码错误! ", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
|
||
private void lpcPLCAddress_Click(object sender, EventArgs e)
|
||
{
|
||
string strInputPwd = MyBase.InputBox("密码", "请输入密码 : ", "", "确定", "取消");
|
||
if (strInputPwd.Contains("-999.999"))
|
||
{
|
||
return;
|
||
}
|
||
else if (strInputPwd == ConfigDfn.strPwd)
|
||
{
|
||
PlcAddrSetup PLCAS = new PlcAddrSetup(3, ConfigDfn.strConfigFile);
|
||
PLCAS.Show();
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("密码错误! ", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
|
||
private void lpcPLCTest_Click(object sender, EventArgs e)
|
||
{
|
||
FormDebugSiemensS7 FDS7 = new FormDebugSiemensS7(SiemensPLCS.S1200);
|
||
FDS7.Show();
|
||
}
|
||
|
||
private void lpcAboutSoftware_Click(object sender, EventArgs e)
|
||
{
|
||
AboutSoftwareInfo asi = new AboutSoftwareInfo();
|
||
asi.ShowDialog();
|
||
}
|
||
|
||
private void lpcShowLog_Click(object sender, EventArgs e)
|
||
{
|
||
System.Diagnostics.Process.Start("notepad.exe", LogDebugDfn.strDebugFile);
|
||
}
|
||
|
||
#endregion 软件设置
|
||
|
||
#region RadButton鼠标事件
|
||
|
||
private void btn_MouseHover(object sender, EventArgs e)
|
||
{
|
||
RadButton btn = sender as RadButton;
|
||
btn.BackColor = Color.FromArgb(0, 151, 186);
|
||
}
|
||
|
||
private void btn_MouseLeave(object sender, EventArgs e)
|
||
{
|
||
RadButton btn = sender as RadButton;
|
||
btn.BackColor = Color.FromArgb(19, 46, 53);
|
||
}
|
||
|
||
#endregion RadButton鼠标事件
|
||
|
||
#region PLC相关函数
|
||
|
||
#region PLC重连操作
|
||
|
||
private void ttmrReadPLCData_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||
{
|
||
ttmrReadPLCData.Stop();
|
||
ReadAndProcessPlcData();
|
||
ttmrReadPLCData.Start();
|
||
}
|
||
|
||
private void ttmrWritePLCLive_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||
{
|
||
ttmrWritePLCLive.Stop();
|
||
bTickt = !bTickt;
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.SoftLive, Convert.ToByte(bTickt ? 1 : 0));
|
||
ttmrWritePLCLive.Start();
|
||
}
|
||
|
||
private void m_bgwAnalysisCSVReport_DoWork(object sender, DoWorkEventArgs e)
|
||
{
|
||
while (true)
|
||
{
|
||
AnalysisNextSenseSelfMeasureCSV();
|
||
AnalysisNextSenseEH3CSV();
|
||
AnalysisNextSenseEHYCSV();
|
||
AnalysisNextSenseEHVCSV();
|
||
}
|
||
}
|
||
|
||
private void ttmrReadNSCSV_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||
{
|
||
ttmrReadNSCSV.Stop();
|
||
//AnalysisNextSenseSelfMeasureCSV();
|
||
//AnalysisNextSenseEH3CSV();
|
||
//AnalysisNextSenseEHYCSV();
|
||
ttmrReadNSCSV.Start();
|
||
}
|
||
|
||
private void ReadAndProcessPlcData()
|
||
{
|
||
#region 判断PLC是否正常运行
|
||
|
||
if (ConfigPlc.PlcType == 3 && ConfigPlc.bReConnect && !HslSiemensS7Obj.bConnected)
|
||
{
|
||
MyBase.TraceWriteLine("PLC断开,重连!");
|
||
tmrHeartBeatConnect.Stop();
|
||
ReConnectPLC();
|
||
return;
|
||
}
|
||
|
||
byte[] m_Datas = null;
|
||
if (!HslSiemensS7Obj.ReadDatas(PlcAddrSetup.S7ReadStartAddr, (ushort)PlcAddrSetup.S7ReadByteCount, ref m_Datas))
|
||
{
|
||
//tmrReadPLCData.Start();
|
||
ttmrReadPLCData.Start();
|
||
ttmrReadPLCData.Start();
|
||
return;
|
||
}
|
||
if (m_Datas == null)
|
||
{
|
||
//tmrReadPLCData.Start();
|
||
ttmrReadPLCData.Start();
|
||
ttmrReadPLCData.Start();
|
||
MyBase.TraceWriteLine("PLC读取数据对象为空,退出!");
|
||
return;
|
||
}
|
||
|
||
#endregion 判断PLC是否正常运行
|
||
|
||
try
|
||
{
|
||
#region 循环读取PLC数据块中的信息
|
||
|
||
if (m_Datas.Length >= PlcAddrSetup.S7ReadByteCount)
|
||
{
|
||
PLCDfn.bPlcLiveTick = PlcObject.GetS7ByteData(PlcSignalDfn.PlcLive) == 1;
|
||
PLCDfn.ReadVINFinishFlag = PlcObject.GetS7ByteData(PlcSignalDfn.ReadVINFinishFlag);
|
||
PLCDfn.NSStartMeasure = PlcObject.GetS7ByteData(PlcSignalDfn.NSStartMeasure);
|
||
PLCDfn.CarPassFlag = PlcObject.GetS7ByteData(PlcSignalDfn.CarPassFlag);
|
||
PLCDfn.NoCarTypeFlag = PlcObject.GetS7ByteData(PlcSignalDfn.NoCarTypeFlag);
|
||
//从PLC获取VIN码后,通过访问IOT接口 获取汽车类型,再反馈给PLC
|
||
if (iLastReadVINFinishFlag == 0 && PLCDfn.ReadVINFinishFlag == 10) //到达信号
|
||
{
|
||
string strCarID = PlcObject.GetS7StringData(PlcSignalDfn.PartID);
|
||
//PLCDfn.CarType = PlcObject.GetS7ByteData(PlcSignalDfn.CarType);
|
||
MyBase.TraceWriteLine("PLC读码完成信号:0->10;Read PLC VIN is: " + strCarID);
|
||
if (strCarID.Length > 10)
|
||
{
|
||
string strCarColor = "";
|
||
string strCarType = GetCarTypeByIOTAPI(strCarID, out strCarColor);
|
||
if (!strCarType.ToUpper().Contains("ERR"))
|
||
{
|
||
if (strCarType.ToUpper().Contains("EH3"))
|
||
{
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.WCarType, (byte)1);
|
||
}
|
||
else if (strCarType.ToUpper().Contains("EHY"))
|
||
{
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.WCarType, (byte)2);
|
||
}
|
||
else if (strCarType.ToUpper().Contains("EHV"))
|
||
{
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.WCarType, (byte)3);
|
||
}
|
||
else
|
||
{
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.WCarType, (byte)0);
|
||
MyBase.TraceWriteLine($"未匹配到车型,输入字符为:{strCarType}");
|
||
}
|
||
PlcObject.InsertWriteQueue(PlcSignalDfn.WCarColor, strCarColor);
|
||
MyBase.TraceWriteLine("往PLC写入车型: " + strCarType + " ;车身颜色:" + strCarColor);
|
||
tmdal.InsertVIN(strCarID);
|
||
MyBase.TraceWriteLine(strCarID + " 插入到数据库表TTempSaveVIN中完成。");
|
||
|
||
#region 记录PLC过点信息
|
||
try
|
||
{
|
||
DateTime arriveTime = DateTime.Now;
|
||
if (tmdal.ExistsArriveLog(strCarID) == 0)
|
||
{
|
||
tmdal.InsertArriveLog(strCarID, arriveTime);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine($"车辆 {strCarID} 当天已存在抵达记录,未重复插入。");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("记录PLC过点信息异常,异常信息: " + ex.ToString());
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("报错:根据VIN从IOT上获取车型信息失败,不发送给PLC车型信息和颜色信息。 ");
|
||
}
|
||
}
|
||
}
|
||
|
||
if (iLastNoCarTypeFlag == 0 && PLCDfn.NoCarTypeFlag == 10)
|
||
{
|
||
string strCarID = PlcObject.GetS7StringData(PlcSignalDfn.PartID);
|
||
MyBase.TraceWriteLine("NoCarTypeFlag:0->10; PLC 反馈未收到软件发送的车类型码信息; VIN=" + strCarID);
|
||
}
|
||
|
||
if (iLastNSStartMeasure == 0 && PLCDfn.NSStartMeasure == 10) //启动测量信号
|
||
{
|
||
string strCarID = PlcObject.GetS7StringData(PlcSignalDfn.PartID);
|
||
if (strCarID.Length > 10)
|
||
{
|
||
// 记录日志,此时该车开始测量
|
||
MyBase.TraceWriteLine($"检测开始测量0->10: {strCarID} 机器人安全判断合格,启动NXS测量");
|
||
|
||
#region 记录PLC过点信息
|
||
// 记录启动测量时间
|
||
try
|
||
{
|
||
DateTime measureStartTime = DateTime.Now;
|
||
tmdal.UpdateStartMeasureTime(strCarID, measureStartTime);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("记录测量开始时间异常,异常信息: " + ex.ToString());
|
||
}
|
||
#endregion
|
||
}
|
||
else
|
||
{
|
||
//记录日志,获取到启动测量信号,但没有获取 车号
|
||
MyBase.TraceWriteLine("报错:获取到启动NXS测量信号,但没有获取 车号 ");
|
||
}
|
||
}
|
||
|
||
if (iLastCarPassFlag == 0 && PLCDfn.CarPassFlag == 10) //离开信号
|
||
{
|
||
string strCarID = PlcObject.GetS7StringData(PlcSignalDfn.PartID);
|
||
MyBase.TraceWriteLine("读取PLC CarPassFlag 完成信号:0->10;Read PLC VIN is: " + strCarID);
|
||
string strSecondPosCarID = tmdal.SelectMaintenanceStationVINbyStationNo(2);
|
||
if (strSecondPosCarID.Length == 21)
|
||
{
|
||
string strTempCarID = strSecondPosCarID.Substring(0, 17);
|
||
string strTempCarType = strSecondPosCarID.Substring(18, 3);
|
||
if (tmdal.CheckMRVINExistOrNotByVIN(strTempCarID) == 0)
|
||
{
|
||
string strTargetRate = Math.Round(ConfigDfn.dFPY2 * 100.00d, 2).ToString("F2") + "%";
|
||
|
||
MyBase.TraceWriteLine(strSecondPosCarID + " ;该VIN码只扫码没有测量,没有测量结果,上传IOT NG消息。");
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"requestData\":[{\"vin\":\"" + strTempCarID + "\",\"model\":\"" + strTempCarType + "\",\"equipmentNo\":\"" + ConfigDfn.strEquipNo + "\",\"equipmentName\":\"" + ConfigDfn.strEquipName + "\",\"calibrationResult\":\"NG\",\"detectionTime\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\",\"targetRate\":\"" + strTargetRate + "\",\"rate\":\"0.00%\",\"GapList\":[]}]}";
|
||
MyBase.TraceWriteLine("Update NG To IOT Data Content: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTAddress, strPostData, 10000);
|
||
MyBase.TraceWriteLine("NG数据上传IOT完成,结果返回为:" + strPostResult);
|
||
|
||
if (strPostResult.Contains("成功"))
|
||
{
|
||
MyBase.TraceWriteLine("NG数据上传IOT成功 ^_^");
|
||
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, true, "0.00");
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("NG数据上传IOT失败!");
|
||
|
||
tmdal.InsertIOTUploadLog(strCarID, strPostData, false, "0.00");
|
||
}
|
||
}
|
||
|
||
#region 记录PLC过点信息
|
||
|
||
try
|
||
{
|
||
DateTime leaveTime = DateTime.Now;
|
||
tmdal.UpdateLeaveTime(strTempCarID, leaveTime);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("记录PLC过点信息异常,异常信息: " + ex.ToString());
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
if (!string.IsNullOrEmpty(strCarID) && strCarID.Length > 10)
|
||
{
|
||
MyBase.TraceWriteLine("CarPassFlag 0->10 开始更新MaintenceInfo数据库位置7-2中的VIN码 ");
|
||
string strTempCarID = tmdal.SelectMaintenanceStationVINbyStationNo(6);
|
||
Thread.Sleep(10);
|
||
tmdal.updateMaintenceInfo(strTempCarID, 7);
|
||
MyBase.TraceWriteLine($"CarPassFlag 0->10 更新VIN={strTempCarID} 到MaintenceInfo数据库位置7完成。");
|
||
Thread.Sleep(15);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(5), 6);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(4), 5);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(3), 4);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(2), 3);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(1), 2);
|
||
Thread.Sleep(20);
|
||
string strCarColor = "";
|
||
string strCarType = GetCarTypeByIOTAPI(strCarID, out strCarColor);
|
||
if (!strCarType.ToUpper().Contains("ERR"))
|
||
{
|
||
if (strCarType.ToUpper().Contains("EH3"))
|
||
{
|
||
strCarID = strCarID + "_EH3";
|
||
}
|
||
else if (strCarType.ToUpper().Contains("EHY"))
|
||
{
|
||
strCarID = strCarID + "_EHY";
|
||
}
|
||
else if (strCarType.ToUpper().Contains("EHV"))
|
||
{
|
||
strCarID = strCarID + "_EHV";
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine($"未匹配到具体的车型,传入字符{strCarType}");
|
||
}
|
||
}
|
||
tmdal.updateMaintenceInfo(strCarID, 1);
|
||
MyBase.TraceWriteLine("CarPassFlag 0->10 更新到MaintenceInfo数据库位置1中的VIN为: " + strCarID);
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("CarPassFlag 0->10 strCarID Error = " + strCarID);
|
||
string strTempCarID = tmdal.SelectMaintenanceStationVINbyStationNo(6);
|
||
Thread.Sleep(10);
|
||
tmdal.updateMaintenceInfo(strTempCarID, 7);
|
||
MyBase.TraceWriteLine($"CarPassFlag 0->10 更新VIN={strTempCarID} 到MaintenceInfo数据库位置7完成。");
|
||
Thread.Sleep(15);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(5), 6);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(4), 5);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(3), 4);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(2), 3);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo(tmdal.SelectMaintenanceStationVINbyStationNo(1), 2);
|
||
Thread.Sleep(20);
|
||
tmdal.updateMaintenceInfo("empty", 1);
|
||
MyBase.TraceWriteLine("CarPassFlag 0->10 更新到MaintenceInfo数据库位置1中的VIN为:empty ");
|
||
}
|
||
}
|
||
|
||
//记录编码器速度等值
|
||
if (ConfigDfn.iRecordEncoderFlag == 1)
|
||
{
|
||
double dSpeed1 = PlcObject.GetS7Double(PlcSignalDfn.Speed1);
|
||
double dSpeed2 = PlcObject.GetS7Double(PlcSignalDfn.Speed2);
|
||
double dR01 = PlcObject.GetS7Double(PlcSignalDfn.R01_Pules);
|
||
double dR02 = PlcObject.GetS7Double(PlcSignalDfn.R02_Pules);
|
||
NLogger.Fatal(dSpeed1 + "," + dSpeed2 + "," + dR01 + "," + dR02);
|
||
}
|
||
}
|
||
iLastCarPassFlag = PLCDfn.CarPassFlag;
|
||
iLastReadVINFinishFlag = PLCDfn.ReadVINFinishFlag;
|
||
iLastNSStartMeasure = PLCDfn.NSStartMeasure;
|
||
iLastNoCarTypeFlag = PLCDfn.NoCarTypeFlag;
|
||
#endregion 循环读取PLC数据块中的信息
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MyBase.TraceWriteLine("tmrReadPLCData_Tick exception: " + ex.ToString());
|
||
}
|
||
}
|
||
|
||
private void tmrRefreshPLCStatus_Tick(object sender, EventArgs e)
|
||
{
|
||
if (labelTimeStatus_Tip.Text == "─") { labelTimeStatus_Tip.Text = "╲"; }
|
||
else if (labelTimeStatus_Tip.Text == "╲") { labelTimeStatus_Tip.Text = "│"; }
|
||
else if (labelTimeStatus_Tip.Text == "│") { labelTimeStatus_Tip.Text = "╱"; }
|
||
else if (labelTimeStatus_Tip.Text == "╱") { labelTimeStatus_Tip.Text = "─"; }
|
||
|
||
lampPLCHeart.State = PLCDfn.bPlcLiveTick ? LampColor.Green : LampColor.Silver;
|
||
rlePLCHeart.ForeColor = PLCDfn.bPlcLiveTick ? Color.Lime : Color.White;
|
||
}
|
||
|
||
private void tmrHeartBeatConnect_Tick(object sender, EventArgs e)
|
||
{
|
||
if (bPlcLiveTickLast != PLCDfn.bPlcLiveTick)
|
||
{
|
||
HeartBeatCount = 0;
|
||
}
|
||
else
|
||
{
|
||
HeartBeatCount++;
|
||
}
|
||
|
||
if (HeartBeatCount >= 600)
|
||
{
|
||
HeartBeatCount = 0;
|
||
if (!bStopPlcNormal)
|
||
{
|
||
MyBase.TraceWriteLine("PLC心跳检测10分钟内未变化,断开PLC,进行PLC重连!");
|
||
PlcObject.ClosePlc();
|
||
}
|
||
}
|
||
bPlcLiveTickLast = PLCDfn.bPlcLiveTick;
|
||
}
|
||
|
||
private void ReConnectPLC()
|
||
{
|
||
m_ThreadReconnectPLC = null;
|
||
m_ThreadReconnectPLC = new Thread(new ThreadStart(ReConnectPlcProcess));
|
||
if (!m_ThreadReconnectPLC.IsAlive)
|
||
{
|
||
m_ThreadReconnectPLC.Start();
|
||
}
|
||
}
|
||
|
||
private void ReConnectPlcProcess()
|
||
{
|
||
while (!PlcObject.IsPlcConnected())
|
||
{
|
||
bool bConnectResult = PlcObject.ConnectPlc();
|
||
if (!bConnectResult)
|
||
{
|
||
m_ReConnectNum++;
|
||
MyBase.TraceWriteLine("重连PLC,第" + m_ReConnectNum + "次!");
|
||
}
|
||
Thread.Sleep(1000);
|
||
}
|
||
MyBase.TraceWriteLine("重新连接PLC成功!");
|
||
lampConnectPLCStatus.State = LampColor.Green;
|
||
rlePLCStatus.ForeColor = Color.Lime;
|
||
this.BeginInvoke((EventHandler)delegate
|
||
{
|
||
tmrHeartBeatConnect.Start();
|
||
});
|
||
bStopPlcNormal = false;
|
||
m_ReConnectNum = 0;
|
||
this.Invoke((EventHandler)(delegate
|
||
{
|
||
//tmrReadPLCData.Start();
|
||
ttmrWritePLCLive.Start();//启动给PLC写入心跳 1s写一次 0 1
|
||
tmrRefreshPLCStatus.Start();//刷新PLC等的状态
|
||
}));
|
||
m_ThreadReconnectPLC.Abort();
|
||
}
|
||
|
||
#endregion PLC重连操作
|
||
|
||
private void ConnectThread()
|
||
{
|
||
MyBase.TraceWriteLine("连接PLC....");
|
||
|
||
bool bConnectResult = PlcObject.ConnectPlc();
|
||
this.Invoke((EventHandler)(delegate
|
||
{
|
||
if (bConnectResult)
|
||
{
|
||
lampConnectPLCStatus.State = LampColor.Green;
|
||
rlePLCStatus.ForeColor = Color.Lime;
|
||
MyBase.TraceWriteLine("连接PLC成功");
|
||
}
|
||
else
|
||
{
|
||
lampConnectPLCStatus.State = LampColor.Red;
|
||
rlePLCStatus.ForeColor = Color.Red;
|
||
ttmrReadPLCData.Stop();
|
||
MyBase.TraceWriteLine("连接PLC失败");
|
||
return;
|
||
}
|
||
|
||
//tmrReadPLCData.Start(); //读取PLC数据信息
|
||
ttmrReadPLCData.Start();
|
||
ttmrWritePLCLive.Start();//启动给PLC写入心跳 1s写一次 0 1
|
||
tmrRefreshPLCStatus.Start();//刷新PLC等的状态
|
||
if (ConfigPlc.bReConnect)
|
||
tmrHeartBeatConnect.Start(); //监测来自plc的心跳5分钟内没有变化,重新连接PLC
|
||
}));
|
||
}
|
||
|
||
private void btnConnectPlc_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
PlcObject.InitWritePlcThread();
|
||
bStopPlcNormal = false;
|
||
Thread m_Thread = new Thread(ConnectThread);
|
||
m_Thread.Start();
|
||
return;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
}
|
||
}
|
||
|
||
private void btnClosePlc_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
MyBase.TraceWriteLine("点击了断开PLC按钮,断开PLC!");
|
||
ttmrReadPLCData.Stop();
|
||
tmrHeartBeatConnect.Stop();
|
||
ttmrWritePLCLive.Stop();
|
||
tmrRefreshPLCStatus.Stop();
|
||
lampConnectPLCStatus.State = LampColor.White;
|
||
rlePLCStatus.ForeColor = Color.White;
|
||
rlePLCHeart.ForeColor = Color.White;
|
||
lampPLCHeart.State = LampColor.White;
|
||
bStopPlcNormal = true;
|
||
PlcObject.ClosePlc();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
}
|
||
}
|
||
|
||
#endregion PLC相关函数
|
||
|
||
private void lpcUploadIOTTest_Click(object sender, EventArgs e)
|
||
{
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"requestData\":[{\"vin\":\"test001\",\"model\":\"EHY\",\"equipmentNo\":\"" + ConfigDfn.strEquipNo + "\",\"equipmentName\":\"" + ConfigDfn.strEquipName + "\",\"calibrationResult\":\"OK\",\"detectionTime\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\",\"GapList\":[{\"vin\":\"test001\",\"gfNo\":\"F\",\"pointNumber\":\"L-01\",\"actualValue\":\"-0.30\",\"controlLine\":\"-1.00/1.00\",\"measurementResult\":\"OK\"}]}]}";
|
||
MyBase.TraceWriteLine("Test Post Data: " + strPostData);
|
||
|
||
//插入记录测试
|
||
tmdal.InsertIOTUploadLog("test001", strPostData, true, labResultPercent.Text);
|
||
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTAddress, strPostData, 10000);
|
||
MessageBox.Show("测试上传数据完成,获取到的返回值为: " + strPostResult, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
MyBase.TraceWriteLine("测试上传数据完成,获取到的返回值为: " + strPostResult);
|
||
}
|
||
|
||
private void lpcTestGetCarTye_Click(object sender, EventArgs e)
|
||
{
|
||
string strPostData = "{\"serno\":\"312314141\",\"vin\":\"LNNAJDDU9RDA00213\"}";
|
||
MyBase.TraceWriteLine("Test Post Data: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTCarTypeAddress, strPostData, 10000);
|
||
MessageBox.Show("测试从IOT获取车型信息完成,获取到的返回值为: " + strPostResult, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
MyBase.TraceWriteLine("测试从IOT获取车型信息完成,获取到的原返回值为: " + strPostResult);
|
||
string strNewResult = strPostResult.Substring(1, strPostResult.Length - 2).Replace("]", "");
|
||
MessageBox.Show("测试从IOT获取车型信息完成,处理后 获取到的返回值为: " + strNewResult, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
MyBase.TraceWriteLine("测试从IOT获取车型信息完成,处理后 获取到的返回值为: " + strNewResult);
|
||
CheryCarTypeInfo ccti = new CheryCarTypeInfo();
|
||
ccti = JsonConvert.DeserializeObject<CheryCarTypeInfo>(strNewResult);
|
||
MessageBox.Show("测试从IOT获取车型信息完成,获取到的返回值为: " + strNewResult + "; 解析出的车型:" + ccti.data.model + " ;解析出的物料号为" + ccti.data.material + " ;解析出颜色编号:" + ccti.data.material.Substring(7, 2), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
|
||
private string GetCarTypeByIOTAPI(string strVIN, out string strMaterialNo)
|
||
{
|
||
string strPostData = "{\"serno\":\"" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "\",\"vin\":\"" + strVIN + "\"}";
|
||
MyBase.TraceWriteLine(" Post VIN Data: " + strPostData);
|
||
string strPostResult = PostJsonToIOT(ConfigDfn.strIOTCarTypeAddress, strPostData, 5000);
|
||
MyBase.TraceWriteLine("GetCarTypeByIOTAPI IOT Return CarType Infomation : " + strPostResult);
|
||
string strNewResult = strPostResult.Substring(1, strPostResult.Length - 2).Replace("]", "");
|
||
//MyBase.TraceWriteLine("GetCarTypeByIOTAPI IOT Return New CarType Infomation : " + strNewResult);
|
||
CheryCarTypeInfo ccti = new CheryCarTypeInfo();
|
||
ccti = JsonConvert.DeserializeObject<CheryCarTypeInfo>(strNewResult);
|
||
if (ccti.message.Contains("成功"))
|
||
{
|
||
if (ccti.data.material != null && ccti.data.material.Length > 9)
|
||
{
|
||
strMaterialNo = ccti.data.material.Substring(7, 2);
|
||
MyBase.TraceWriteLine(" IOT Return CarType Infomation : " + strNewResult + "; 解析出的车型:" + ccti.data.model + "解析出车颜色编号:" + strMaterialNo);
|
||
}
|
||
else
|
||
{
|
||
strMaterialNo = "TE";
|
||
MyBase.TraceWriteLine(" IOT Return CarType Infomation : " + strNewResult + "; 解析出的车型:" + ccti.data.model + ";未解析出车颜色编号");
|
||
}
|
||
return ccti.data.model;
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine(" IOT Return CarType Infomation ERROR : " + strPostResult);
|
||
strMaterialNo = "ER";
|
||
return "ERR";
|
||
}
|
||
}
|
||
|
||
private void lpcShowCarData_Click(object sender, EventArgs e)
|
||
{
|
||
if (ConfigDfn.strShowCarLR == "L")
|
||
{
|
||
if (ConfigDfn.strCarModel.ToUpper().Contains("EH3"))
|
||
{
|
||
fLEH3.Show(); fLEHY.Hide(); fLEHV.Hide();
|
||
}
|
||
else if (ConfigDfn.strCarModel.ToUpper().Contains("EHV"))
|
||
{
|
||
fLEHV.Show(); fLEH3.Hide(); fLEHY.Hide();
|
||
}
|
||
else
|
||
{
|
||
fLEHY.Show(); fLEH3.Hide(); fLEHV.Hide();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (ConfigDfn.strCarModel.ToUpper().Contains("EH3"))
|
||
{
|
||
fREH3.Show(); fREHY.Hide(); fREHV.Hide();
|
||
}
|
||
else if (ConfigDfn.strCarModel.ToUpper().Contains("EHV"))
|
||
{
|
||
fREHV.Show(); fREH3.Hide(); fREHY.Hide();
|
||
}
|
||
else
|
||
{
|
||
fREHY.Show(); fREH3.Hide(); fREHV.Hide();
|
||
}
|
||
}
|
||
}
|
||
|
||
public void ShowCarMeasureDataByCarType(int iCarType)
|
||
{
|
||
Invoke((MethodInvoker)(() =>
|
||
{
|
||
if (ConfigDfn.strShowCarLR == "L")
|
||
{
|
||
if (iCarType == 1)
|
||
{
|
||
fLEH3.Show(); fLEHY.Hide(); fLEHV.Hide();
|
||
MyBase.TraceWriteLine("显示左侧EH3车身数据界面。");
|
||
}
|
||
else if (iCarType == 2)
|
||
{
|
||
fLEHY.Show(); fLEH3.Hide(); fLEHV.Hide();
|
||
MyBase.TraceWriteLine("显示左侧EHY车身数据界面。");
|
||
|
||
}
|
||
else if(iCarType == 3)
|
||
{
|
||
|
||
fLEHV.Show(); fLEH3.Hide(); fLEHY.Hide();
|
||
MyBase.TraceWriteLine("显示左侧EHV车身数据界面。");
|
||
}
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("未知车型,不显示");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (iCarType == 1)
|
||
{
|
||
fREH3.Show(); fREHY.Hide(); fREHV.Hide();
|
||
MyBase.TraceWriteLine("显示右侧EH3车身数据界面。");
|
||
}
|
||
else if (iCarType == 2)
|
||
{
|
||
fREHY.Show(); fREH3.Hide(); fREHV.Hide();
|
||
MyBase.TraceWriteLine("显示右侧EHY车身数据界面。");
|
||
}
|
||
else if (iCarType == 3)
|
||
{
|
||
fREHV.Show(); fREH3.Hide(); fREHY.Hide();
|
||
MyBase.TraceWriteLine("显示右侧EHV车身数据界面。");
|
||
}
|
||
|
||
else
|
||
{
|
||
MyBase.TraceWriteLine("未知车型,不显示");
|
||
}
|
||
}
|
||
|
||
}));
|
||
}
|
||
|
||
private void rbtnTestCOM_Click(object sender, EventArgs e)
|
||
{
|
||
if (rbtnTestCOM.Text == "打开串口")
|
||
{
|
||
serialTestPort = new SerialPort(rtbPort.Text.Trim(), 115200, Parity.None, 8, StopBits.One); // 设置串口参数
|
||
serialTestPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); // 注册数据接收事件处理方法
|
||
serialTestPort.Open(); // 打开串口
|
||
if (serialTestPort.IsOpen)
|
||
{
|
||
rbtnTestCOM.Text = "关闭串口";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
serialTestPort.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
|
||
serialTestPort.Close();
|
||
serialTestPort.Dispose();
|
||
rbtnTestCOM.Text = "打开串口";
|
||
}
|
||
}
|
||
|
||
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
|
||
{
|
||
SerialPort sp = (SerialPort)sender;
|
||
string indata = sp.ReadExisting();
|
||
MyBase.TraceWriteLine(indata);
|
||
rtbCOMContent.Text = indata;
|
||
}
|
||
|
||
private void CenterControl_Shown(object sender, EventArgs e)
|
||
{
|
||
rddlSizeName.SelectedIndex = 0;
|
||
DataTable dtMPName = tmdal.SelectAllMeasPointName();
|
||
if (dtMPName.Rows.Count > 0)
|
||
{
|
||
for (int i = 0; i < dtMPName.Rows.Count; i++)
|
||
{
|
||
rddlMeasurePoint.Items.Add(dtMPName.Rows[i][0].ToString());
|
||
}
|
||
rddlMeasurePoint.SelectedIndex = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
public class CheryIOTData
|
||
{
|
||
/// <summary>
|
||
/// VIN号
|
||
/// </summary>
|
||
public string vin { get; set; }
|
||
|
||
/// <summary>
|
||
/// FG
|
||
/// </summary>
|
||
public string gfNo { get; set; }
|
||
|
||
/// <summary>
|
||
/// 测点编号
|
||
/// </summary>
|
||
public string pointNumber { get; set; }
|
||
|
||
/// <summary>
|
||
/// 实测值
|
||
/// </summary>
|
||
public string actualValue { get; set; }
|
||
|
||
/// <summary>
|
||
/// 控制线
|
||
/// </summary>
|
||
public string controlLine { get; set; }
|
||
|
||
/// <summary>
|
||
/// 测量结果
|
||
/// </summary>
|
||
public string measurementResult { get; set; }
|
||
}
|
||
|
||
public class CarInfoData
|
||
{
|
||
public string material { get; set; }
|
||
public string model { get; set; }
|
||
}
|
||
|
||
public class CheryCarTypeInfo
|
||
{
|
||
/// <summary>
|
||
/// data
|
||
/// </summary>
|
||
public CarInfoData data { get; set; }
|
||
|
||
/// <summary>
|
||
/// message
|
||
/// </summary>
|
||
public string message { get; set; }
|
||
|
||
/// <summary>
|
||
/// serno
|
||
/// </summary>
|
||
public string serno { get; set; }
|
||
|
||
/// <summary>
|
||
/// success
|
||
/// </summary>
|
||
public string success { get; set; }
|
||
}
|
||
|
||
public static class JsonHelper
|
||
{
|
||
/// <summary>
|
||
/// 对象转成JSON 格式字符串
|
||
/// </summary>
|
||
/// <param name="obj">对象</param>
|
||
/// <returns>JSON格式的字符串</returns>
|
||
public static string ObjectToJson(object obj)
|
||
{
|
||
return JsonConvert.SerializeObject(obj);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析JSON字符串生成对象实体
|
||
/// </summary>
|
||
/// <typeparam name="T">对象类型</typeparam>
|
||
/// <param name="json">json字符串</param>
|
||
/// <returns>对象实体</returns>
|
||
public static T DeserializeJsonToObject<T>(string json) where T : class
|
||
{
|
||
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
|
||
StringReader sr = new StringReader(json);
|
||
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
|
||
T t = o as T;
|
||
return t;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析JSON数组生成对象实体集合
|
||
/// </summary>
|
||
/// <typeparam name="T">对象类型</typeparam>
|
||
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
|
||
/// <returns>对象实体集合</returns>
|
||
public static List<T> DeserializeJsonToList<T>(string json) where T : class
|
||
{
|
||
Newtonsoft.Json.JsonSerializer serializer = new JsonSerializer();
|
||
StringReader sr = new StringReader(json);
|
||
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
|
||
List<T> list = o as List<T>;
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 数据表转键值对集合 把DataTable转成 List集合, 存每一行 集合中放的是键值对字典,存每一列
|
||
/// </summary>
|
||
/// <param name="dt">数据表</param>
|
||
/// <returns>哈希表数组</returns>
|
||
public static List<Dictionary<string, object>> DataTableToList(DataTable dt)
|
||
{
|
||
List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
|
||
|
||
foreach (DataRow dr in dt.Rows)
|
||
{
|
||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||
foreach (DataColumn dc in dt.Columns)
|
||
{
|
||
dic.Add(dc.ColumnName, dr[dc.ColumnName]);
|
||
}
|
||
list.Add(dic);
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 数据集转键值对数组字典
|
||
/// </summary>
|
||
/// <returns>键值对数组字典</returns>
|
||
public static Dictionary<string, List<Dictionary<string, object>>> DataSetToDic(DataSet ds)
|
||
{
|
||
Dictionary<string, List<Dictionary<string, object>>> result = new Dictionary<string, List<Dictionary<string, object>>>();
|
||
|
||
foreach (DataTable dt in ds.Tables)
|
||
result.Add(dt.TableName, DataTableToList(dt));
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 数据表转JSON
|
||
/// </summary>
|
||
/// <param name="dt">数据表</param>
|
||
/// <returns>JSON字符串</returns>
|
||
public static string DataTableToJson(DataTable dt)
|
||
{
|
||
return ObjectToJson(DataTableToList(dt));
|
||
}
|
||
|
||
/// <summary>
|
||
/// JSON文本转对象,泛型方法 常用
|
||
/// </summary>
|
||
/// <typeparam name="T">类型</typeparam>
|
||
/// <param name="jsonText">JSON文本</param>
|
||
/// <returns>指定类型的对象</returns>
|
||
public static T JsonToObject<T>(string jsonText)
|
||
{
|
||
return JsonConvert.DeserializeObject<T>(jsonText);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将JSON文本转换为数据表数据
|
||
/// </summary>
|
||
/// <param name="jsonText">JSON文本</param>
|
||
/// <returns>数据表字典</returns>
|
||
public static Dictionary<string, List<Dictionary<string, object>>> TablesDataFromJson(string jsonText)
|
||
{
|
||
return JsonToObject<Dictionary<string, List<Dictionary<string, object>>>>(jsonText);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将JSON文本转换成数据行
|
||
/// </summary>
|
||
/// <param name="jsonText">JSON文本</param>
|
||
/// <returns>数据行的字典</returns>
|
||
public static Dictionary<string, object> DataRowFromJson(string jsonText)
|
||
{
|
||
return JsonToObject<Dictionary<string, object>>(jsonText);
|
||
}
|
||
}
|
||
} |