KOMAX的Alpha 550数据采集之二

上次文章是采集数据,这篇是处理数据
完整代码放在文章最后,大家感兴趣可以看看!

处理流程

数据分析
设计软件页面
整理采集思路
编辑代码
调试运行

数据处理效果预览

KOMAX数据采集
导线单压被判断为异常,后续已更新判断逻辑
效率计算逻辑已更改,图片效率为单个订单效率,后面更改为平均效率
补充更改后的效果
KOMAX设备数据监控

KOMAX的Alpha 550数据分析

在这里插入图片描述

界面设计

在这里插入图片描述
这是设计的界面,有点麻烦,我就没做,不好意思!设计思路也是,改了又改,有点乱了,我又没整理就不发了!

数据结构定义

 public class HmiData : INotifyPropertyChanged{private string machinNumber;// 机台号public string MachinNumber{get { return machinNumber; }set{if (value != machinNumber){machinNumber = value;OnPropertyChanged(nameof(MachinNumber));}}}private string orderName;// 订单名称public string OrderName{get { return orderName; }set{if (value != orderName){orderName = value;OnPropertyChanged(nameof(OrderName));}}}private string orderStartTime;// 订单开始时间public string OrderStartTime{get { return orderStartTime; }set{if (value != orderStartTime){orderStartTime = value;OnPropertyChanged(nameof(OrderStartTime));}}}private string orderEndTime;// 订单结束时间public string OrderEndTime{get { return orderEndTime; }set{if (value != orderEndTime){orderEndTime = value;OnPropertyChanged(nameof(OrderEndTime));}}}private string wireNumber;// 导线号public string WireNumber{get { return wireNumber; }set{if (value != wireNumber){wireNumber = value;OnPropertyChanged(nameof(WireNumber));}}}private string wireFIFO;// 导线FIFOpublic string WireFIFO{get { return wireFIFO; }set{if (value != wireFIFO){wireFIFO = value;OnPropertyChanged(nameof(WireFIFO));}}}private string terminalNumber1;// 端子号1public string TerminalNumber1{get { return terminalNumber1; }set{if (value != terminalNumber1){terminalNumber1 = value;OnPropertyChanged(nameof(TerminalNumber1));}}}private string terminalFIFO1;// 端子1FIFOpublic string TerminalFIFO1{get { return terminalFIFO1; }set{if (value != terminalFIFO1){terminalFIFO1 = value;OnPropertyChanged(nameof(TerminalFIFO1));}}}private string toolNumber1;// 模具号1public string ToolNumber1{get { return toolNumber1; }set{if (value != toolNumber1){toolNumber1 = value;OnPropertyChanged(nameof(ToolNumber1));}}}private string terminalNumber2;// 端子号2public string TerminalNumber2{get { return terminalNumber2; }set{if (value != terminalNumber2){terminalNumber2 = value;OnPropertyChanged(nameof(TerminalNumber2));}}}private string terminalFIFO2;// 端子2FIFOpublic string TerminalFIFO2{get { return terminalFIFO2; }set{if (value != terminalFIFO2){terminalFIFO2 = value;OnPropertyChanged(nameof(TerminalFIFO2));}}}private string toolNumber2;// 模具号2public string ToolNumber2{get { return toolNumber2; }set{if (value != toolNumber2){toolNumber2 = value;OnPropertyChanged(nameof(ToolNumber2));}}}private string orderQuantity;// 订单数量public string OrderQuantity{get { return orderQuantity; }set{if (value != orderQuantity){orderQuantity = value;OnPropertyChanged(nameof(OrderQuantity));}}}private string orderCompletedQuantity;// 订单已完成数量public string OrderCompletedQuantity{get { return orderCompletedQuantity; }set{if (value != orderCompletedQuantity){orderCompletedQuantity = value;OnPropertyChanged(nameof(OrderCompletedQuantity));}}}private string batchQuantity;// 批次数量public string BatchQuantity{get { return batchQuantity; }set{if (value != batchQuantity){batchQuantity = value;OnPropertyChanged(nameof(BatchQuantity));}}}private string orderStatus;// 订单状态public string OrderStatus{get { return orderStatus; }set{if (value != orderStatus){orderStatus = value;OnPropertyChanged(nameof(OrderStatus));}}}private string productionEfficiency;// 生产效率public string ProductionEfficiency{get { return productionEfficiency; }set{if (value != productionEfficiency){productionEfficiency = value;OnPropertyChanged(nameof(ProductionEfficiency));}}}private string jobNotes;// 生产效率public string JobNotes{get { return jobNotes; }set{if (value != jobNotes){productionEfficiency = value;OnPropertyChanged(nameof(JobNotes));}}}//数据改变事件public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}

数据绑定

 //初始化DataTableprivate void IintDataTable(){// Create a new DataTabledataTable = new DataTable();// Add columns to the DataTabledataTable.Columns.Add("机台号", typeof(string));dataTable.Columns.Add("订单号", typeof(string));dataTable.Columns.Add("开始时间", typeof(string));dataTable.Columns.Add("结束时间", typeof(string));dataTable.Columns.Add("导线号", typeof(string));dataTable.Columns.Add("导线FIFO", typeof(string));dataTable.Columns.Add("端子1", typeof(string));dataTable.Columns.Add("端子1FIFO", typeof(string));dataTable.Columns.Add("模具1", typeof(string));dataTable.Columns.Add("端子2", typeof(string));dataTable.Columns.Add("端子2FIFO", typeof(string));dataTable.Columns.Add("模具2", typeof(string));dataTable.Columns.Add("订单数量", typeof(string));dataTable.Columns.Add("完成数量", typeof(string));dataTable.Columns.Add("批次数量", typeof(string));dataTable.Columns.Add("订单状态", typeof(string));dataTable.Columns.Add("效率(PCS/H)", typeof(string));dataTable.Columns.Add("备注", typeof(string));AddnewRow();// Bind the HmiDataCollection to the DataGridMyDataGrid.ItemsSource = dataTable.DefaultView;}private void AddnewRow(){// Create a new instance of the HmiData classHmiData newData = new HmiData{MachinNumber = strmachinenumber,OrderName = "",OrderStartTime = "",OrderEndTime = "",WireNumber = "",WireFIFO = "",TerminalNumber1 = "",TerminalFIFO1 = "",ToolNumber1 = "",TerminalNumber2 = "",TerminalFIFO2 = "",ToolNumber2 = "",OrderQuantity = "",OrderCompletedQuantity = "",BatchQuantity = "",OrderStatus = "",ProductionEfficiency = "",JobNotes = ""};// Add a new row to the DataTableDataRow newRow = dataTable.NewRow(); Set the values of the columns in the new rownewRow.ItemArray = new object[] {newData.OrderName,newData.OrderStartTime,newData.OrderEndTime,newData.WireNumber,newData.WireFIFO,newData.TerminalNumber1,newData.TerminalFIFO1,newData.ToolNumber1,newData.TerminalNumber2,newData.TerminalFIFO2,newData.ToolNumber2,newData.OrderQuantity,newData.OrderCompletedQuantity,newData.BatchQuantity,newData.OrderStatus,newData.ProductionEfficiency,newData.JobNotes};// Add the new row to the DataTabledataTable.Rows.Add(newRow);//更新列表行数datarows = dataTable.Rows.Count - 1;rownow = dataTable.Rows[datarows];rownow["机台号"] = strmachinenumber;}

采集主线程

  private void Work(){try{while (true){System.Threading.Thread.Sleep(1000); //毫秒                   //对比数据,如果相等就跳出本次循环if (tempstr != myMqtt.hmidatat){tempstr = myMqtt.hmidatat;}else{System.Threading.Thread.Sleep(1000); //毫秒continue;}//更新列表行数datarows = dataTable.Rows.Count - 1;rownow = dataTable.Rows[datarows];//rownow = dataTable.Rows[0];string topic = myMqtt.hmitopic;if (topic.Contains("/application/production/job/state")){MyJobStateData = myMqtt.hmidatat;var tt2 = new Task(() => JobState());tt2.Start();//MyJobStateData = myMqtt.hmidatat;//JobState();topic = "";logger.LogInfo("/job/state");continue;}else{//判断订阅的话题,然后赋值if (topic.Contains("/application/production/job/update/progress")){MyJobProgressData = myMqtt.hmidatat;var tt1 = new Task(() => JobProgress());tt1.Start();topic = "";continue;}if (topic.Contains("/status/scan/material")){var tt3 = new Task(() => MaterialScanGood());tt3.Start();MyMaterialScanGoodData = myMqtt.hmidatat;topic = "";logger.LogInfo("/status/scan/material");continue;}if (topic.Contains("/application/production/job/report/counter")){var tt3 = new Task(() => MaterialScan());tt3.Start();MyMaterialScanData = myMqtt.hmidatat;topic = "";logger.LogInfo("/job/report/counter");continue;}System.Threading.Thread.Sleep(1000); //毫秒}}}catch (Exception ex){// write the error message and stack trace to the log filelogger.LogError(ex.Message);logger.LogError(ex.StackTrace);}}

订单状态监控

 //当前行DataRow rownow;//string StartTime = "";//string CompleteTime = "";//string OrderName = "";//订单状态变化private void JobState(){try{string xm1 = MyJobStateData;// 解析XML字符串XDocument Doc1 = XDocument.Parse(xm1);// 提取订单状态string OrderState = Doc1.Root.Element("State").Value;// 提取订单号string href = Doc1.Root.Element("Job").Attribute("href").Value;//string strorder = href.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last();string strorder = GetValueFromHref(href);logger.LogInfo(strorder);// 提取时间string OrderdateTime = Doc1.Root.Attribute("dateTime").Value;//UTC时间转换成本地时间DateTime date = DateTime.Parse(OrderdateTime).ToLocalTime();//判断订单结束if(OrderState == "Done"){//比较订单号if (rownow["订单号"].ToString() == strorder){rownow["结束时间"] = date.ToString();logger.LogInfo("Done");//增加一个空行AddOrder();return;}}//判断订单开始if (OrderState == "InWork"){//比较订单号if (rownow["订单号"].ToString() == ""){logger.LogInfo("InWork");rownow["开始时间"] = date.ToString();rownow["订单号"] = strorder;//增加一个空行//AddOrder();return;}}}catch (Exception ex){// write the error message and stack trace to the log filelogger.LogError(ex.Message);logger.LogError(ex.StackTrace);}}

产量监控

//订单数量变化private void JobProgress(){try{string xm2 = MyJobProgressData;XDocument doc2 = XDocument.Parse(xm2);//取出订单号string href = doc2.Root.Element("Job").Attribute("href").Value;//string strorder = href.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last();string strorder = GetValueFromHref(href);//判断订单号是否为空if (rownow["订单号"].ToString() == ""){rownow["订单号"] = strorder;}else{//否则订单号不一致,判断为订单改变if (strorder != rownow["订单号"].ToString()){//增加订单AddOrder();logger.LogInfo("JobProgress 订单不一致");rownow["订单号"] = strorder;}}//Mydata.OrderStatus = doc.Root.Element("JobType").Value;rownow["订单状态"] = doc2.Root.Element("JobType").Value;rownow["完成数量"] = doc2.Root.Element("CompletedHarnesses").Value;//string completedAdditionals = doc.Root.Element("CompletedAdditionals").Value;rownow["订单数量"] = doc2.Root.Element("TargetHarnesses").Value;//string targetAdditionals = doc.Root.Element("TargetAdditionals").Value;rownow["批次数量"] = doc2.Root.Element("TargetBatchSize").Value;}catch (Exception ex){// write the error message and stack trace to the log filelogger.LogError(ex.Message);logger.LogError(ex.StackTrace);}}

物料监控

//物料状态变化private void MaterialScanGood(){try{string xm3 = MyMaterialScanGoodData;XmlDocument doc3 = new XmlDocument();doc3.LoadXml(xm3);XmlNode root3 = doc3.DocumentElement;XmlNode wireLineNode = root3.SelectSingleNode("ProcessModule/WireLine");bool isGood = bool.Parse(root3.SelectSingleNode("IsGood").InnerText);//判断扫描的是导线if (wireLineNode != null && isGood){rownow["导线号"] = root3.SelectSingleNode("MaterialKey").InnerText;rownow["导线FIFO"] = root3.SelectSingleNode("MaterialHandlingUnit").InnerText;return;}XmlNode crimpModuleNode = root3.SelectSingleNode("ProcessModule/CrimpModule");//判断工作站1if (crimpModuleNode != null && crimpModuleNode.Attributes["href"].Value.Contains("%255DC1MCI721-0011") && isGood){rownow["模具1"] = root3.SelectSingleNode("ToolKey").InnerText;rownow["端子1"] = root3.SelectSingleNode("MaterialKey").InnerText;rownow["端子1FIFO"] = root3.SelectSingleNode("MaterialHandlingUnit").InnerText;return;}//判断工作站2if (crimpModuleNode != null && crimpModuleNode.Attributes["href"].Value.Contains("%255DC1MCI721-0012") && isGood){rownow["模具2"] = root3.SelectSingleNode("ToolKey").InnerText;rownow["端子2"] = root3.SelectSingleNode("MaterialKey").InnerText;rownow["端子2FIFO"] = root3.SelectSingleNode("MaterialHandlingUnit").InnerText;return;}}catch (Exception ex){// write the error message and stack trace to the log filelogger.LogError(ex.Message);logger.LogError(ex.StackTrace);}//App.Current.Dispatcher.Invoke(() =>//{//    mytext.Text = "/status/scan/material";//    MyLabel.Content = myMqtt.hmidatat;//});}//物料状态变化private void MaterialScan(){try{string xm4 = MyMaterialScanData;XmlDocument doc4 = new XmlDocument();doc4.LoadXml(xm4);XmlNode root4 = doc4.DocumentElement;XmlNode wireLineNode = root4.SelectSingleNode("//Wire");//判断是导线if (wireLineNode != null){string wireHref = GetValueFromHref(wireLineNode.Attributes["href"].Value);rownow["导线号"] = wireHref;XmlNode handlingUnitNode = doc4.SelectSingleNode("//SlotConsumption/HandlingUnit");if (handlingUnitNode != null  && handlingUnitNode.Attributes["material"] != null){rownow["导线FIFO"] = handlingUnitNode.Attributes["material"].Value;}}//取端子信息XmlNodeList terminalNodes = doc4.SelectNodes("//Terminal");XmlNodeList crimpModuleNodes = doc4.SelectNodes("//CrimpModule");XmlNodeList HandlingUnitNodes = doc4.SelectNodes("//CrimpModuleConsumption/HandlingUnit");for (int i = 0; i < terminalNodes.Count; i++){string crimpModuleHref = crimpModuleNodes[i].Attributes["href"].Value;if (crimpModuleHref.Contains("%255DC1MCI721-0011")){string terminalHref = terminalNodes[i].Attributes["href"].Value;rownow["端子1"] = GetValueFromHref(terminalHref);if (HandlingUnitNodes[i].Attributes["material"] != null){rownow["端子1FIFO"] = HandlingUnitNodes[i].Attributes["material"].Value;}if (HandlingUnitNodes[i].Attributes["tool"] != null){rownow["模具1"] = HandlingUnitNodes[i].Attributes["tool"].Value;}continue;}if (crimpModuleHref.Contains("%255DC1MCI721-0012")){string terminalHref = terminalNodes[i].Attributes["href"].Value;rownow["端子2"] = GetValueFromHref(terminalHref);if (HandlingUnitNodes[i].Attributes["material"] != null){rownow["端子2FIFO"] = HandlingUnitNodes[i].Attributes["material"].Value;}if (HandlingUnitNodes[i].Attributes["tool"] != null){rownow["模具2"] = HandlingUnitNodes[i].Attributes["tool"].Value;}continue;}}}catch (Exception ex){// write the error message and stack trace to the log filelogger.LogError(ex.Message);logger.LogError(ex.StackTrace);}}static string GetValueFromHref(string href){href = href.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last();return href;}

日志模块

 public interface ILogger{void LogError(string message);void LogWarning(string message);void LogInfo(string message);}//错误日志public class FileLogger : ILogger{private readonly Mutex _mutex;private readonly string _logFilePath;public FileLogger(string logFilePath){_logFilePath = logFilePath;_mutex = new Mutex();}public void LogError(string message){_mutex.WaitOne();try{WriteLog("ERROR", message);}finally{_mutex.ReleaseMutex();}}public void LogWarning(string message){_mutex.WaitOne();try{WriteLog("WARNING", message);}finally{_mutex.ReleaseMutex();}}public void LogInfo(string message){_mutex.WaitOne();try{WriteLog("INFO", message);}finally{_mutex.ReleaseMutex();}}private void WriteLog(string level, string message){string logMessage = string.Format("[{0}] {1}: {2}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), level, message);File.AppendAllText(_logFilePath, logMessage + Environment.NewLine);}}

效率计算和备注信息模块

  private void AddOrder(){try{//计算效率if (rownow["开始时间"].ToString() != "" && rownow["结束时间"].ToString() != "" && rownow["完成数量"].ToString() != ""){efficiencynumber = efficiencynumber + 1;// calculate efficiency using completed quantity, start time, and end timedouble completedQuantity = Convert.ToDouble(rownow["完成数量"]);DateTime startTime = Convert.ToDateTime(rownow["开始时间"]);DateTime endTime = Convert.ToDateTime(rownow["结束时间"]);efficiency = (efficiency + completedQuantity / (endTime - startTime).TotalHours)/ efficiencynumber;// update the efficiency column in the current rowif(efficiency.ToString().Length > 6){rownow["效率(PCS/H)"] = efficiency.ToString().Substring(0, 6);}else{rownow["效率(PCS/H)"] = efficiency.ToString();}}//添加备注if (rownow["订单数量"].ToString() == ""){rownow["备注"] = "订单数量异常;";}if (rownow["开始时间"].ToString() == ""){rownow["备注"] = rownow["备注"] + "订单状态异常;";}if (rownow["导线号"].ToString() == "" ||( rownow["端子1"].ToString() == "" && rownow["端子2"].ToString() == "")){rownow["备注"] = rownow["备注"] + "物料状态异常;";}//更新订单状态rownow["订单状态"] = "Finish";//此处一定要有委托,否则报错// Add the new row to the DataTableApp.Current.Dispatcher.Invoke(() =>{//设备备注的字体颜色DataGridColumn column = MyDataGrid.Columns[17]; // 获取第2列DataGridTextColumn textColumn = column as DataGridTextColumn;if (textColumn != null){Style cellStyle = new Style(typeof(DataGridCell));cellStyle.Setters.Add(new Setter(Control.ForegroundProperty, Brushes.Red));textColumn.CellStyle = cellStyle;}//添加一行空数据AddnewRow();});}catch(Exception ex){// write the error message and stack trace to the log filelogger.LogError(ex.Message);logger.LogError(ex.StackTrace);}}

运行日志

在这里插入图片描述
分享使人快乐!我为人人,人人为我!努力学习,努力工作!
完整代码包下载链接
链接:https://pan.baidu.com/s/1tyDBPAZmoecOs_bGrRC_jw
提取码:eton


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部