using B20UVLog.Models; using B20UVLog.Pages; using NetTaste; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using TFT_MelsecMcNet; namespace B20UVLog { public class LogPcTask_Biz { #region 单例模式 /// /// 单例模式对象 /// private static LogPcTask_Biz _instance = null; private static readonly object lockObj = new object(); /// /// 单例模式方法 /// public static LogPcTask_Biz Instance { get { if (_instance == null) { lock (lockObj) { if (_instance == null) { _instance = new LogPcTask_Biz(); } } } return _instance; } } #endregion #region 全局变量 public MelsecMcNet melsec_net = null; /// /// 日志头部 /// private readonly string LogHeadText = "日志采集系统LogPc主业务类 ==>> "; private readonly List taskList = new(); private readonly int TaskDelayTime = 500; private readonly int ReadDelayTime = 5000; private readonly CancellationTokenSource tokenSource = new(); private PlcItemTypeModel AxisDataPLC; private PlcItemTypeModel AxisData2PLC; private PlcItemTypeModel AxisData3PLC; private PlcItemTypeModel AxisData4PLC; private PlcItemTypeModel AxisData5PLC; private PlcItemTypeModel ServoAxisStautsPLC; private PlcItemTypeModel GlassInformationPLC; private PlcItemTypeModel LampUseTimePLC; private PlcItemTypeModel RecipeBodyPLC; private PlcItemTypeModel SYSParaPLC; private PlcItemTypeModel RobotInterfaceInPLC; private PlcItemTypeModel RobotInterfaceOutPLC; private PlcItemTypeModel YMeasureDataPLC; private PlcItemTypeModel EQPStatusPLC; private PlcItemTypeModel RecipeCountPLC; private PlcItemTypeModel LampDataPLC; private PlcItemTypeModel AnalogDataPLC; private PlcItemTypeModel AlarmPLC; private PlcItemTypeModel WarnPLC; private PlcItemTypeModel IOPLC; //字典字段 private List axleAlarm=new List(); private List axleWarn = new List(); private List deviceAlarm = new List(); private List deviceWarn = new List(); #endregion /// /// Log采集业务类 初始化数据 /// /// public void Init() { AxisDataPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "AxisData"); AxisData2PLC= DbHelper.Db.Queryable().First(x => x.PlcItemType == "AxisData2"); AxisData3PLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "AxisData3"); AxisData4PLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "AxisData4"); AxisData5PLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "AxisData5"); ServoAxisStautsPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "ServoAxisStatus"); GlassInformationPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "GlassInformation"); LampUseTimePLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "LampUseTime"); RecipeBodyPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "RecipeBody"); SYSParaPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "SysPara"); RobotInterfaceInPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "RobotInterfaceIn"); RobotInterfaceOutPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "RobotInterfaceOut"); YMeasureDataPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "YMeasureData"); EQPStatusPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "EQPStatus"); RecipeCountPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "RecipeCount"); AnalogDataPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "AnalogData"); LampDataPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "LampData"); AlarmPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "Alarm"); WarnPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "Warn"); IOPLC = DbHelper.Db.Queryable().First(x => x.PlcItemType == "IO"); //获取字典中的所有字段 axleAlarm = DbHelper.Db.Queryable().ToList().FindAll(x=>x.Type=="Alarm"&&x.Code=="Axle"); axleWarn = DbHelper.Db.Queryable().ToList().FindAll(x => x.Type == "Warn" && x.Code == "Axle"); deviceAlarm = DbHelper.Db.Queryable().ToList().FindAll(x => x.Type == "Alarm" && x.Code == "Device"); deviceWarn = DbHelper.Db.Queryable().ToList().FindAll(x => x.Type == "Warn" && x.Code == "Warn"); } /// /// 连接PLC /// /// public bool ConnectPlc() { try { melsec_net = new MelsecMcNet(ConfigurationManager.AppSettings["PLCAddr"], Convert.ToInt32(ConfigurationManager.AppSettings["PLCPort"])); OperateResult connect = melsec_net.ConnectServer(); if (connect.IsSuccess) { ; return true; } else { return false; } } catch (Exception ex) { return false; } } /// /// 断开PLC连接 /// public void DisConnectPlc() { // 暂停所有PLC采集线程。 if (taskList.Count > 0) { tokenSource?.Cancel(); foreach (Task item in taskList) { while (!item.IsCompleted) { } item.Dispose(); } taskList.Clear(); tokenSource?.Dispose(); } OperateResult result = melsec_net?.ConnectClose(); if (result.IsSuccess) { } else { } melsec_net = null; } #region PLC数据采集主业务线程 public void StartPlcLogMonitor() { AxisDataLogTask(); AxisData2LogTask(); AxisData3LogTask(); AxisData4LogTask(); AxisData5LogTask(); ServoAxisStatusLogTask(); GlassInformationLogTask(); LampUserTimeLogTask(); RecipeBodyLogTask(); SYSParaLogTask(); RobotInPLCLogTask(); RobotOutPLCLogTask(); YMeasureDataLogTask(); EQPStatusLogTask(); RecipeBodyLogTask(); AnalogDataLogTask(); LampDataLogTask(); AlarmLogTask(); WarnLogTask(); IOLogTask(); } private void AxisDataLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AxisDataPLC is null) { continue; } OperateResult isAxisData = melsec_net.ReadBool(AxisDataPLC.ReportFlagAddress); if (isAxisData.IsSuccess && isAxisData.Content) { OperateResult axisDataRet = melsec_net.ReadInt16(AxisDataPLC.PlcItemAddressType + AxisDataPLC.PlcItemStartAddress, (ushort)AxisDataPLC.PlcItemAddressLength); List axisDataPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AxisDataPLC.PlcItemType).ToList(); if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in axisDataPlcItemLst) { ParsePlcItemData(plcItem, axisDataRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 AxisDataModel axisData = MapPlcItemToObjectProperty(axisDataPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(AxisDataPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(AxisDataPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(AxisDataPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void AxisData2LogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AxisData2PLC is null) { continue; } OperateResult isAxisData = melsec_net.ReadBool(AxisData2PLC.ReportFlagAddress); if (isAxisData.IsSuccess && isAxisData.Content) { OperateResult axisDatatRet = melsec_net.ReadInt16(AxisData2PLC.PlcItemAddressType + AxisData2PLC.PlcItemStartAddress, (ushort)AxisData2PLC.PlcItemAddressLength); List axisDataPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AxisData2PLC.PlcItemType).ToList(); if (!axisDatatRet.IsSuccess || axisDatatRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in axisDataPlcItemLst) { ParsePlcItemData(plcItem, axisDatatRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 AxisData2 axisData = MapPlcItemToObjectProperty(axisDataPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(AxisData2PLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(AxisData2PLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(AxisData2PLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void AxisData3LogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AxisData3PLC is null) { continue; } OperateResult isAxisData = melsec_net.ReadBool(AxisData3PLC.ReportFlagAddress); if (isAxisData.IsSuccess && isAxisData.Content) { OperateResult axisDataRet = melsec_net.ReadInt16(AxisData3PLC.PlcItemAddressType + AxisData3PLC.PlcItemStartAddress, (ushort)AxisData3PLC.PlcItemAddressLength); List axisDataPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AxisData3PLC.PlcItemType).ToList(); if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in axisDataPlcItemLst) { ParsePlcItemData(plcItem, axisDataRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 AxisData3 axisData = MapPlcItemToObjectProperty(axisDataPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(AxisData3PLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(AxisData3PLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(AxisData3PLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void AxisData4LogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AxisData4PLC is null) { continue; } OperateResult isAxisData = melsec_net.ReadBool(AxisData4PLC.ReportFlagAddress); if (isAxisData.IsSuccess && isAxisData.Content) { OperateResult axisDataRet = melsec_net.ReadInt16(AxisData4PLC.PlcItemAddressType + AxisData4PLC.PlcItemStartAddress, (ushort)AxisData4PLC.PlcItemAddressLength); List axisDataPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AxisData4PLC.PlcItemType).ToList(); if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in axisDataPlcItemLst) { ParsePlcItemData(plcItem, axisDataRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 AxisData4 axisData = MapPlcItemToObjectProperty(axisDataPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(AxisData4PLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(AxisData4PLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(AxisData4PLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void AxisData5LogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AxisData5PLC is null) { continue; } OperateResult isAxisData = melsec_net.ReadBool(AxisData5PLC.ReportFlagAddress); if (isAxisData.IsSuccess && isAxisData.Content) { OperateResult axisDataRet = melsec_net.ReadInt16(AxisData5PLC.PlcItemAddressType + AxisData5PLC.PlcItemStartAddress, (ushort)AxisData5PLC.PlcItemAddressLength); List axisDataPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AxisData5PLC.PlcItemType).ToList(); if (!axisDataRet.IsSuccess || axisDataRet.Content.Length <= 0 || axisDataPlcItemLst is null || axisDataPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in axisDataPlcItemLst) { ParsePlcItemData(plcItem, axisDataRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 AxisData5 axisData = MapPlcItemToObjectProperty(axisDataPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(AxisData5PLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(AxisData5PLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(AxisData5PLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } /// /// servoAxis /// private void ServoAxisStatusLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (ServoAxisStautsPLC is null) { continue; } OperateResult isServoAxis = melsec_net.ReadBool(ServoAxisStautsPLC.ReportFlagAddress); if (isServoAxis.IsSuccess && isServoAxis.Content) { OperateResult servoAxisRet = melsec_net.ReadInt16(ServoAxisStautsPLC.PlcItemAddressType + ServoAxisStautsPLC.PlcItemStartAddress, (ushort)ServoAxisStautsPLC.PlcItemAddressLength); List servoAxisPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == ServoAxisStautsPLC.PlcItemType).ToList(); if (!servoAxisRet.IsSuccess || servoAxisRet.Content.Length <= 0 || servoAxisPlcItemLst is null || servoAxisPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in servoAxisPlcItemLst) { ParsePlcItemData(plcItem, servoAxisRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 ServoAxisStautsOriginal servoOrignal = MapPlcItemToObjectProperty(servoAxisPlcItemLst); //ServoAxisStautsOriginal 将不为0的字段转为ServoAxisStautsModel var nonZeroProperties = GetNonZeroProperties(servoOrignal); foreach (var property in nonZeroProperties) { string name = property.Key; int value = property.Value; ServoAxisStatusModel servoAxisStatusModel = new ServoAxisStatusModel(); if(name.Contains("Warn")) { servoAxisStatusModel.AxisName = name.Substring(0, 4); servoAxisStatusModel.WarningCode = value; servoAxisStatusModel.WarningDescribe =axleWarn?.FirstOrDefault(x=>x.Key==value.ToString().Trim())?.Value; } else { if (name.Contains("Alarm")) { servoAxisStatusModel.AxisName = name.Substring(0, 4); servoAxisStatusModel.AlarmCode = value; servoAxisStatusModel.AlarmDescribe = axleAlarm?.FirstOrDefault(x => x.Key == value.ToString().Trim())?.Value; } } servoAxisStatusModel.RecordTime = DateTime.Now; DbHelper.Db.Insertable(servoAxisStatusModel).ExecuteCommand(); melsec_net.Write(ServoAxisStautsPLC.ReplyFlagAddress, true); } } else { OperateResult isJobEventReply = melsec_net.ReadBool(ServoAxisStautsPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(ServoAxisStautsPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void GlassInformationLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (GlassInformationPLC is null) { continue; } OperateResult isServoAxis = melsec_net.ReadBool(GlassInformationPLC.ReportFlagAddress); if (isServoAxis.IsSuccess && isServoAxis.Content) { OperateResult glassInfoRet = melsec_net.ReadInt16(GlassInformationPLC.PlcItemAddressType + GlassInformationPLC.PlcItemStartAddress, (ushort)GlassInformationPLC.PlcItemAddressLength); List servoAxisPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == GlassInformationPLC.PlcItemType).ToList(); if (!glassInfoRet.IsSuccess || glassInfoRet.Content.Length <= 0 || servoAxisPlcItemLst is null || servoAxisPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in servoAxisPlcItemLst) { ParsePlcItemData(plcItem, glassInfoRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 GlassInformationModel glassInfoData = MapPlcItemToObjectProperty(servoAxisPlcItemLst); //读取时间 OperateResult glassInfoRetTime = melsec_net.ReadInt16("D16100", 6); if (!glassInfoRetTime.IsSuccess || glassInfoRetTime.Content.Length <= 0) { continue; } Convert16BitBCDToTwoInts(glassInfoRetTime.Content[0], out int yy1, out int mm1); Convert16BitBCDToTwoInts(glassInfoRetTime.Content[1], out int dd1, out int hh1); Convert16BitBCDToTwoInts(glassInfoRetTime.Content[2], out int ff1, out int ss1); Convert16BitBCDToTwoInts(glassInfoRetTime.Content[3], out int yy2, out int mm2); Convert16BitBCDToTwoInts(glassInfoRetTime.Content[4], out int dd2, out int hh2); Convert16BitBCDToTwoInts(glassInfoRetTime.Content[5], out int ff2, out int ss2); glassInfoData.LordingTime = new DateTime(yy1, mm1, dd1, hh1, ff1, ss1); glassInfoData.UnlordingTime = new DateTime(yy2, mm2, dd2, hh2, ff2, ss2); glassInfoData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(glassInfoData).ExecuteCommand(); melsec_net.Write(GlassInformationPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(GlassInformationPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(GlassInformationPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void LampUserTimeLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (LampUseTimePLC is null) { continue; } OperateResult isLampUse = melsec_net.ReadBool(LampUseTimePLC.ReportFlagAddress); if (isLampUse.IsSuccess && isLampUse.Content) { OperateResult glassInfoRet = melsec_net.ReadInt16(LampUseTimePLC.PlcItemAddressType + LampUseTimePLC.PlcItemStartAddress, (ushort)LampUseTimePLC.PlcItemAddressLength); List glassInfoPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == LampUseTimePLC.PlcItemType).ToList(); if (!glassInfoRet.IsSuccess || glassInfoRet.Content.Length <= 0 || glassInfoPlcItemLst is null || glassInfoPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in glassInfoPlcItemLst) { ParsePlcItemData(plcItem, glassInfoRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 LampUseTimeModel axisData = MapPlcItemToObjectProperty(glassInfoPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(LampUseTimePLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(LampUseTimePLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(LampUseTimePLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void RecipeBodyLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (RecipeBodyPLC is null) { continue; } OperateResult isLampUse = melsec_net.ReadBool(RecipeBodyPLC.ReportFlagAddress); if (isLampUse.IsSuccess && isLampUse.Content) { OperateResult recipeBodyRet = melsec_net.ReadInt16(RecipeBodyPLC.PlcItemAddressType + RecipeBodyPLC.PlcItemStartAddress, (ushort)RecipeBodyPLC.PlcItemAddressLength); List reciprBodyPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == RecipeBodyPLC.PlcItemType).ToList(); if (!recipeBodyRet.IsSuccess || recipeBodyRet.Content.Length <= 0 || reciprBodyPlcItemLst is null || reciprBodyPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in reciprBodyPlcItemLst) { ParsePlcItemData(plcItem, recipeBodyRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 RecipeBodyModel axisData = MapPlcItemToObjectProperty(reciprBodyPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(RecipeBodyPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(RecipeBodyPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(RecipeBodyPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void SYSParaLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (SYSParaPLC is null) { continue; } OperateResult isSysPara = melsec_net.ReadBool(SYSParaPLC.ReportFlagAddress); if (isSysPara.IsSuccess && isSysPara.Content) { OperateResult sysParaRet = melsec_net.ReadInt16(SYSParaPLC.PlcItemAddressType + SYSParaPLC.PlcItemStartAddress, (ushort)SYSParaPLC.PlcItemAddressLength); List sysparaItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == SYSParaPLC.PlcItemType).ToList(); if (!sysParaRet.IsSuccess || sysParaRet.Content.Length <= 0 || sysparaItemLst is null || sysparaItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in sysparaItemLst) { ParsePlcItemData(plcItem, sysParaRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 SysParaModel axisData = MapPlcItemToObjectProperty(sysparaItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(SYSParaPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(SYSParaPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(SYSParaPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void RobotInPLCLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (RobotInterfaceInPLC is null) { continue; } OperateResult isRobotIn = melsec_net.ReadBool(RobotInterfaceInPLC.ReportFlagAddress); if (isRobotIn.IsSuccess && isRobotIn.Content) { OperateResult robotInRet = melsec_net.ReadInt16(RobotInterfaceInPLC.PlcItemAddressType + RobotInterfaceInPLC.PlcItemStartAddress, (ushort)RobotInterfaceInPLC.PlcItemAddressLength); List robotInPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == RobotInterfaceInPLC.PlcItemType).ToList(); if (!robotInRet.IsSuccess || robotInRet.Content.Length <= 0 || robotInPlcItemLst is null || robotInPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in robotInPlcItemLst) { ParsePlcItemData(plcItem, robotInRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 RobotInterfaceInModel axisData = MapPlcItemToObjectProperty(robotInPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(RobotInterfaceInPLC.ReplyFlagAddress, true); } else { OperateResult isRobotInReply = melsec_net.ReadBool(RobotInterfaceInPLC.ReplyFlagAddress); if (isRobotInReply.IsSuccess && isRobotInReply.Content) { melsec_net.Write(RobotInterfaceInPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void RobotOutPLCLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (RobotInterfaceOutPLC is null) { continue; } OperateResult isRobotOut = melsec_net.ReadBool(RobotInterfaceOutPLC.ReportFlagAddress); if (isRobotOut.IsSuccess && isRobotOut.Content) { OperateResult robotInRet = melsec_net.ReadInt16(RobotInterfaceOutPLC.PlcItemAddressType + RobotInterfaceOutPLC.PlcItemStartAddress, (ushort)RobotInterfaceOutPLC.PlcItemAddressLength); List robotInPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == RobotInterfaceOutPLC.PlcItemType).ToList(); if (!robotInRet.IsSuccess || robotInRet.Content.Length <= 0 || robotInPlcItemLst is null || robotInPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in robotInPlcItemLst) { ParsePlcItemData(plcItem, robotInRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 RobotInterfaceOutModel axisData = MapPlcItemToObjectProperty(robotInPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(RobotInterfaceOutPLC.ReplyFlagAddress, true); } else { OperateResult isRobotInReply = melsec_net.ReadBool(RobotInterfaceOutPLC.ReplyFlagAddress); if (isRobotInReply.IsSuccess && isRobotInReply.Content) { melsec_net.Write(RobotInterfaceOutPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void YMeasureDataLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (YMeasureDataPLC is null) { continue; } OperateResult isYMeasure = melsec_net.ReadBool(YMeasureDataPLC.ReportFlagAddress); if (isYMeasure.IsSuccess && isYMeasure.Content) { OperateResult yMeasureRet = melsec_net.ReadInt16(YMeasureDataPLC.PlcItemAddressType + YMeasureDataPLC.PlcItemStartAddress, (ushort)YMeasureDataPLC.PlcItemAddressLength); List glassInfoPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == YMeasureDataPLC.PlcItemType).ToList(); if (!yMeasureRet.IsSuccess || yMeasureRet.Content.Length <= 0 || glassInfoPlcItemLst is null || glassInfoPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in glassInfoPlcItemLst) { ParsePlcItemData(plcItem, yMeasureRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 YMeasureDataModel axisData = MapPlcItemToObjectProperty(glassInfoPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(YMeasureDataPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(YMeasureDataPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(YMeasureDataPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void EQPStatusLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (EQPStatusPLC is null) { continue; } OperateResult isEQPStatus = melsec_net.ReadBool(EQPStatusPLC.ReportFlagAddress); if (isEQPStatus.IsSuccess && isEQPStatus.Content) { OperateResult eqpStatusRet = melsec_net.ReadInt16(EQPStatusPLC.PlcItemAddressType + EQPStatusPLC.PlcItemStartAddress, (ushort)EQPStatusPLC.PlcItemAddressLength); List eqpPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == EQPStatusPLC.PlcItemType).ToList(); if (!eqpStatusRet.IsSuccess || eqpStatusRet.Content.Length <= 0 || eqpPlcItemLst is null || eqpPlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in eqpPlcItemLst) { ParsePlcItemData(plcItem, eqpStatusRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 EQPStatusModel axisData = MapPlcItemToObjectProperty(eqpPlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(EQPStatusPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(EQPStatusPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(EQPStatusPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void RecipeCountLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (RecipeCountPLC is null) { continue; } OperateResult isRecipeCount = melsec_net.ReadBool(RecipeCountPLC.ReportFlagAddress); if (isRecipeCount.IsSuccess && isRecipeCount.Content) { OperateResult recipeRet = melsec_net.ReadInt16(RecipeCountPLC.PlcItemAddressType + RecipeCountPLC.PlcItemStartAddress, (ushort)RecipeCountPLC.PlcItemAddressLength); List recipePlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == RecipeCountPLC.PlcItemType).ToList(); if (!recipeRet.IsSuccess || recipeRet.Content.Length <= 0 || recipePlcItemLst is null || recipePlcItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in recipePlcItemLst) { ParsePlcItemData(plcItem, recipeRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 RecipeCountModel axisData = MapPlcItemToObjectProperty(recipePlcItemLst); axisData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(axisData).ExecuteCommand(); melsec_net.Write(RecipeCountPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(RecipeCountPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(RecipeCountPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void AnalogDataLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AnalogDataPLC is null) { continue; } { List analogPlcItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AnalogDataPLC.PlcItemType).ToList(); foreach(var item in analogPlcItemLst) { item.Value= melsec_net.ReadInt16(item.PlcAddr).Content; } //foreach (PlcItemModel plcItem in analogPlcItemLst) //{ // ParsePlcItemData(plcItem, analogDataRet.Content, 0); //} //ToDo:把PLC数据插入到数据库中 AnalogDataModel analogData = MapPlcItemToObjectProperty(analogPlcItemLst); //几个字段特殊读取 //OperateResult stageMain = melsec_net.ReadInt16("D16640"); //analogData.StageMainCDA= stageMain.Content; //OperateResult irradiator = melsec_net.ReadInt16("D16642"); //analogData.IrradiatorMainCDA = irradiator.Content; //OperateResult z1Current = melsec_net.ReadInt16("D16650"); //analogData.Z1Current = z1Current.Content; //OperateResult z2Current = melsec_net.ReadInt16("D16652"); //analogData.Z2Current = z2Current.Content; //OperateResult z3Current = melsec_net.ReadInt16("D16654"); //analogData.Z3Current = z3Current.Content; //OperateResult z4Current = melsec_net.ReadInt16("D16656"); //analogData.Z4Current = z4Current.Content; analogData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(analogData).ExecuteCommand(); } Task.Delay(ReadDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void LampDataLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (LampDataPLC is null) { continue; } { //OperateResult lampDataRet = melsec_net.ReadInt16(LampDataPLC.PlcItemAddressType + LampDataPLC.PlcItemStartAddress, (ushort)AnalogDataPLC.PlcItemAddressLength); List lampDataItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == LampDataPLC.PlcItemType).ToList(); foreach (var item in lampDataItemLst) { item.Value = melsec_net.ReadInt16(item.PlcAddr).Content; } //ToDo:把PLC数据插入到数据库中 LampDataModel lampData = MapPlcItemToObjectProperty(lampDataItemLst); //几个字段特殊读取 lampData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(lampData).ExecuteCommand(); } Task.Delay(ReadDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void AlarmLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (AlarmPLC is null) { continue; } OperateResult isAlarm = melsec_net.ReadBool(AlarmPLC.ReportFlagAddress); if (isAlarm.IsSuccess && isAlarm.Content) { OperateResult alarmRet = melsec_net.ReadInt16(AlarmPLC.PlcItemAddressType + AlarmPLC.PlcItemStartAddress, (ushort)AlarmPLC.PlcItemAddressLength); List alarmItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == AlarmPLC.PlcItemType).ToList(); if (!alarmRet.IsSuccess || alarmRet.Content.Length <= 0 || alarmItemLst is null || alarmItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in alarmItemLst) { ParsePlcItemData(plcItem, alarmRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 AlarmModel alarmData = MapPlcItemToObjectProperty(alarmItemLst); alarmData.AlarmDescribe = deviceAlarm?.FirstOrDefault(x=>x.Key.Trim()==alarmData.AlarmCode.ToString())?.Value; alarmData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(alarmData).ExecuteCommand(); melsec_net.Write(AlarmPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(AlarmPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(AlarmPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void WarnLogTask() { taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (WarnPLC is null) { continue; } OperateResult isLampUse = melsec_net.ReadBool(WarnPLC.ReportFlagAddress); if (isLampUse.IsSuccess && isLampUse.Content) { OperateResult warnRet = melsec_net.ReadInt16(WarnPLC.PlcItemAddressType + WarnPLC.PlcItemStartAddress, (ushort)WarnPLC.PlcItemAddressLength); List warnItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == WarnPLC.PlcItemType).ToList(); if (!warnRet.IsSuccess || warnRet.Content.Length <= 0 || warnItemLst is null || warnItemLst.Count <= 0) { continue; } foreach (PlcItemModel plcItem in warnItemLst) { ParsePlcItemData(plcItem, warnRet.Content, 0); } //ToDo:把PLC数据插入到数据库中 WarnModel warnData = MapPlcItemToObjectProperty(warnItemLst); warnData.WarnDescribe = deviceWarn?.FirstOrDefault(x => x.Key.Trim() == warnData.WarnCode.ToString())?.Value; warnData.RecordTime = DateTime.Now; DbHelper.Db.Insertable(warnData).ExecuteCommand(); melsec_net.Write(WarnPLC.ReplyFlagAddress, true); } else { OperateResult isJobEventReply = melsec_net.ReadBool(WarnPLC.ReplyFlagAddress); if (isJobEventReply.IsSuccess && isJobEventReply.Content) { melsec_net.Write(WarnPLC.ReplyFlagAddress, false); } } Task.Delay(TaskDelayTime).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void IOLogTask() { List ioNewModelList = new List(); DateTime recordTime; taskList.Add(Task.Factory.StartNew(() => { while (true) { if (tokenSource.IsCancellationRequested) { break; } if (IOPLC is null) { continue; } { OperateResult ioRet = melsec_net.ReadInt16(IOPLC.PlcItemAddressType + IOPLC.PlcItemStartAddress, (ushort)IOPLC.PlcItemAddressLength); List ioItemLst = DbHelper.Db.Queryable().Where(x => x.PlcItemType == IOPLC.PlcItemType).ToList(); if (!ioRet.IsSuccess || ioRet.Content.Length <= 0 || ioItemLst is null || ioItemLst.Count <= 0) { continue; } recordTime = DateTime.Now; ioNewModelList.Clear(); foreach (PlcItemModel plcItem in ioItemLst) { ParsePlcItemData(plcItem, ioRet.Content, 0); //转化为 IONewModel ioNewModel = new IONewModel(); ioNewModel.IOName = plcItem.PlcItemCode; if (plcItem.PlcItemCode.Contains("Stage")) { ioNewModel.IOType = "Stage"; } else { if (plcItem.PlcItemCode.Contains("IrradiatorInput")) { ioNewModel.IOType = "IrradiatorInput"; } else { if (plcItem.PlcItemCode.Contains("IrradiatorOutput")) { ioNewModel.IOType = "IrradiatorOutput"; } } } ioNewModel.IOValue = Convert.ToInt32(plcItem.Value); ioNewModel.RecordTime = recordTime; ioNewModelList.Add(ioNewModel); } //ToDo:把PLC数据插入到数据库中 DbHelper.Db.Insertable(ioNewModelList).ExecuteCommand(); } Task.Delay(500).Wait(); } }, tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)); } private void ParsePlcItemData(PlcItemModel plcItem, short[] retLst, int startIndex) { if (plcItem.PlcItemFormat == 0) // 解析为int类型 { if (plcItem.IsFullWord == 1) // 全字解析,不进行二进制拆分 { short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray(); if (plcItem.WordSize == 1) { plcItem.Value = tmpVal[0]; } else if (plcItem.WordSize == 2) { plcItem.Value = (tmpVal[0] << 16) + tmpVal[1]; } } else // 非全字解析,需要对数据进行二进制拆分,根据具体的二进制位数,进行数据转换。 { short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray(); string binStr = string.Empty; for (int j = 0; j < tmpVal.Length; j++) { binStr += string.Concat(Convert.ToString(tmpVal[j], 2).PadLeft(16, '0').Reverse()); } string retStr = string.Concat(binStr.Skip(plcItem.BinSubOffset).Take(plcItem.BinSize).ToArray().Reverse()); plcItem.Value = Convert.ToInt32(retStr, 2); } } else if (plcItem.PlcItemFormat == 1) // 解析为ASCII码字符串, 数据直接转换为对应的ASCII码字符串数据进行存储 { short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray(); List bytes = new(); for (int j = 0; j < plcItem.WordSize; j++) { //bytes.AddRange(BitConverter.GetBytes(tmpVal[j])); bytes.Add((byte)tmpVal[j]); } ASCIIEncoding asciiMd = new(); //Console.WriteLine(BitConverter.ToString(bytes.ToArray())); char[] ascii = asciiMd.GetChars(bytes.ToArray()); string retStr = string.Empty; for (int j = 0; j < bytes.Count; j++) { retStr += ascii[j]; } plcItem.Value = retStr; } else if (plcItem.PlcItemFormat == 2) // 解析为二进制数据,按照二进制具体位置和位数,重新组装数据 { if (plcItem.IsFullWord == 1) // 全字解析 , 直接存储数据的二进制字符串 { short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray(); string binStr = string.Empty; for (int j = 0; j < tmpVal.Length; j++) { binStr += string.Concat(Convert.ToString(tmpVal[j], 2).PadLeft(16, '0').Reverse()); } plcItem.Value = binStr; } else // 非全字解析 按照二进制具体位置和位数,存储相应的二进制字符串 { short[] tmpVal = retLst.Skip(startIndex + plcItem.WordSubOffset).Take(plcItem.WordSize).ToArray(); string binStr = string.Empty; for (int j = 0; j < tmpVal.Length; j++) { binStr += string.Concat(Convert.ToString(tmpVal[j], 2).PadLeft(16, '0').Reverse()); } string retStr = string.Concat(binStr.Skip(plcItem.BinSubOffset).Take(plcItem.BinSize).ToArray().Reverse()); plcItem.Value = retStr; } } } /// /// 根据解析出来的PLC点位数据,创建对应的数据库实体对象。 /// /// 对应的数据库实体对象 /// 解析出来的PLC点位数据 /// private static T MapPlcItemToObjectProperty(List plcItemLst) where T : class, new() { T tmp = new(); PropertyInfo[] propertys = tmp.GetType().GetProperties(); foreach (PropertyInfo property in propertys) { foreach (PlcItemModel item in plcItemLst) { if (property.Name == item.PlcItemCode) { if (property.PropertyType.FullName == typeof(DateTime).FullName) { property.SetValue(tmp, item.Value is null ? new DateTime() : Convert.ToDateTime(item.Value), null); } else if (property.PropertyType.FullName == typeof(int).FullName) { property.SetValue(tmp, item.Value is null ? 0 : Convert.ToInt32(item.Value), null); } else if (property.PropertyType.FullName == typeof(decimal).FullName) { property.SetValue(tmp, item.Value is null ? 0 : Convert.ToDecimal(item.Value), null); } else if (property.PropertyType.FullName == typeof(string).FullName) { property.SetValue(tmp, item.Value is null ? null : item.Value.ToString(), null); } else if (property.PropertyType.FullName == typeof(bool).FullName || property.PropertyType.FullName == typeof(bool).FullName) { //property.SetValue(tmp, item.Value is null ? false : Convert.ToBoolean(item.Value), null); //VS编辑器建议的简化写法。 非常巧妙!!!!!! property.SetValue(tmp, item.Value is not null && Convert.ToBoolean(item.Value), null); } else if (property.PropertyType.BaseType.FullName == typeof(byte[]).FullName) { property.SetValue(tmp, item.Value is null ? null : item.Value, null); } else if (property.PropertyType.BaseType.FullName == typeof(Enum).FullName) { property.SetValue(tmp, Enum.Parse(property.PropertyType, (item.Value ?? 0).ToString()), null); } else { property.SetValue(tmp, item.Value, null); } break; } } } return tmp; } private Dictionary GetNonZeroProperties(object obj) { Dictionary nonZeroProperties = new Dictionary(); PropertyInfo[] properties = obj.GetType().GetProperties(); foreach (PropertyInfo property in properties) { if (property.PropertyType == typeof(int)) { int value = (int)property.GetValue(obj); if (value != 0) { nonZeroProperties.Add(property.Name, value); } } } return nonZeroProperties; } // 将8位BCD码转化为整数 private int BCDToInt(byte bcdValue) { int result = 0; int multiplier = 1; while (bcdValue > 0) { int digit = bcdValue & 0xF; result += digit * multiplier; bcdValue >>= 4; multiplier *= 10; } return result; } // 将16位BCD码转化为两个整数 private void Convert16BitBCDToTwoInts(short bcdValue, out int int1, out int int2) { // 高8位BCD码 byte highByte = (byte)((bcdValue >> 8) & 0xFF); // 低8位BCD码 byte lowByte = (byte)(bcdValue & 0xFF); // 分别转换高8位和低8位 int1 = BCDToInt(highByte); int2 = BCDToInt(lowByte); } #endregion } }