using JJServer; using log4net; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; using static JJServer.MyServer; using static JJMediSys.AlertForm; using JJMediSys.cs; namespace JJMediSys { public class TubeLabelTool { public static ILog logger = LogManager.GetLogger("WebLogger"); private static Mutex mutex = new Mutex(false, "Com"); public bool DevConnect; public ComTool comTool; public RecpCreate recpCreate; public byte[] RecvData; public DEVSTATUS stat = new DEVSTATUS(); bool SystemInYJmode = false; //是否应急模式 public string ShowComLog; public int PerSGMaxNum = 9; public bool IsDevFree = true; public string BleBarcodeStr = ""; public struct SgSetting { public int No { get; set; } public string[] NameList { get; set; } public bool InUse { get; set; } public string Model { get; set; } public string Recp { get; set; } public Color color { get; set; } public string Sgctrol { get; set; } public bool LJErr { get; set; } //逻辑故障 } public List listSgSetting = new List(); public List canDispenseTubles = new List(); public string EventMsgInfo = ""; [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern long GetLastError(); public void LoadSginfo() { ShowComLog = ConfigFileReader.GetValue("/configuration/appSettings/add[@key='ShowComLog']"); listSgSetting.Clear(); canDispenseTubles.Clear(); for (int i = 1; i <= 7; i++) { string[] Sginfo = ConfigFileReader.GetValue("/configuration/GROUP/SGINFO/add[@key='G" + i.ToString() + "']").Split('|'); if (Sginfo.Length == 6) { SgSetting temp = new SgSetting(); temp.InUse = false; temp.Recp = Sginfo[1]; temp.color = Color.FromName(Sginfo[2]); temp.No = i; temp.Model = Sginfo[3]; temp.NameList = Sginfo[4].Split(';').ToArray() ; if (Sginfo[0] == "1") { temp.InUse = true; foreach(string str in temp.NameList) { canDispenseTubles.Add(str); } } temp.Sgctrol = Sginfo[5]; temp.LJErr = false; listSgSetting.Add(temp); } } } public bool Open() { try { LoadSginfo(); recpCreate = new RecpCreate(); if(comTool!=null && comTool.isOpen()) { comTool.CloseCom(); } comTool = new ComTool(); string ComPort = ConfigFileReader.GetValue("/configuration/appSettings/add[@key='ComPort']"); int baudRate = int.Parse(ConfigFileReader.GetValue("/configuration/appSettings/add[@key='baudRate']")); int dataBit = int.Parse(ConfigFileReader.GetValue("/configuration/appSettings/add[@key='dataBit']")); float stopBits = float.Parse(ConfigFileReader.GetValue("/configuration/appSettings/add[@key='stopBits']")); int parity = int.Parse(ConfigFileReader.GetValue("/configuration/appSettings/add[@key='parity']")); bool DevConnect = comTool.OpenCom(ComPort, baudRate, dataBit, stopBits, parity); if (DevConnect) { logger.Info(string.Format("打开设备串口成功[{0}][{1}][{2}][{3}][{4}]", ComPort, baudRate, dataBit, stopBits, parity)); string[] Arr = SetSgCtrol().Split('|'); if (Arr[0] != "0") { logger.Info("设置试管参数失败"); MainForm.DevStat = -1; return false; } logger.Info("设置试管参数成功"); MainForm.DevStat = 0; } else { long aa = GetLastError(); logger.Error(string.Format("打开设备串口失败[{0}][{1}][{2}][{3}][{4}] Error[{5}]", ComPort, baudRate, dataBit, stopBits, parity, GetLastError())); } MainForm.DevStat = -1; return DevConnect; } catch (Exception e) { logger.Error(string.Format("打开设备串口异常[{0}]", e.Message)); MainForm.DevStat = -1; return false; } } public string SetSgCtrol() { if (!SystemSet.mTubeLabelTool.IsDevFree) { AlertForm.ShowAlert("设备正忙,请稍后", AlertType.Warning, 3); return "-1|设备正忙,请稍后再试"; } Byte[] SetInfo = new Byte[43]; SetInfo[0] = 0x71; int setp = 1; foreach (var t in listSgSetting) { string[] Detail = t.Sgctrol.Split(';'); if (Detail.Length != 3) return "-1|设置试管参数异常:" + t.Sgctrol; SetInfo[setp] = (byte)(int.Parse(Detail[0]) / 256); setp++; SetInfo[setp] = (byte)(int.Parse(Detail[0]) % 256); setp++; SetInfo[setp] = (byte)(int.Parse(Detail[1]) / 256); setp++; SetInfo[setp] = (byte)(int.Parse(Detail[1]) % 256); setp++; SetInfo[setp] = (byte)(int.Parse(Detail[2]) / 256); setp++; SetInfo[setp] = (byte)(int.Parse(Detail[2]) % 256); setp++; } if (!MechineCtrol("SetSysTemInfo", SetInfo, ref RecvData)) return "-1|设置试管参数失败"; return "0|"; } public string formatbcr(string Barcode) { for(int i=0;i<(12- Barcode.Length);i++) { Barcode = "0" + Barcode; } string Outr = Barcode.Substring(0, 2) + "-" + Barcode.Substring(2, 6) + "-" + Barcode.Substring(8, 4); return Outr; } public string formatBqstr(string itemname,string count) { int Namelen = 18; int countlen = 2; byte[] bytes = Encoding.Unicode.GetBytes(itemname); // 获取字节数组的长度 int length = bytes.Length; for (int i = length; i< Namelen;i++) { itemname = itemname + " "; } for (int i = count.Length; i < countlen; i++) { count = count + " "; } return itemname + count; } public bool CheckSystemStatus(ref string msg) { string status = GetDevStatus(); string[] Arr = status.Split('|'); if (Arr[0] != "0") { msg = "查询设备状态失败,请检查设备连接是否正常"; logger.Info(msg); return false; } if (stat.TubeState != 0x50 || stat.PrintState != 0x50 || stat.StickState != 0x50 || stat.BackPrintState != 0x50) { if (!MechineCtrol("DevReset", null, ref RecvData)) { msg = "设备状态异常,复位失败,请检查设备"; logger.Info(msg); return false; } GetDevStatus(); if ((stat.TubeState != 0x50 || stat.PrintState != 0x50 || stat.StickState != 0x50)) { if (stat.BackPrintState == 0x50) { msg = "设备状态异常,进入应急模式"; logger.Info(msg); SystemInYJmode = true; return true; } else { msg = "设备状态异常,请检查设备"; logger.Info(msg); return false; } } else if (stat.BackPrintState != 0x50) { msg = "回执打印机故障,请检查设备"; logger.Info(msg); return false; } else { SystemInYJmode = false; return true; } } else { SystemInYJmode = false; return true; } } public string GetSGName(string SGxx) { //06 紫帽-EDTA抗凝管 //01 蓝帽管,周1-5最迟15:00前送达 //2ml注射器-套洗涤真空管帽 string[] Arr = SGxx.Split(' '); if (Arr.Length == 1) return SGxx; string[] Arr2 = Arr[1].Split(','); return Arr2[0]; } public string SetResult(string Msg) { EventMsgInfo += $"\r\n发管失败:{Msg}"; Task.Run(() => PublicStatic.EventMgr.ExcuteCmd($"insert into EVENTINFOLIST(Msg,Details,Time) Values('{"发管过程失败"}','{EventMsgInfo}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')")); return "-1|" + Msg; } public string Dispense(PatientDatail labinfoList) { string msg = ""; EventMsgInfo = ""; if (!CheckSystemStatus(ref msg)) { return "-1|" + msg; } string LogStrSGAll = ""; string LogStrSGDisp = ""; string LogStrBQ = ""; RecvData = new byte[1024]; Byte[] DispenseData = new Byte[30]; List BarcodeLsit = new List(); // 条码信息 List SendImageListSG = new List(); //试管便签打印机 List SendImageListHZ = new List(); //副打印机 List SendImageListSGSave = new List(); //试管便签打印机 不带位置信息 int Count = 0; //DispenseData[0] = 0x70; string UndisSGInfo = ""; int[] JyOrderID = new int [30]; int OrderID = 0; bool DispenseFailed = false; //是否有出管失败的情况 如果有则不再重新出管,因为打印头有废标签 foreach (jyData labinfo in labinfoList.jyDatas) { logger.Info("dis1: " + labinfo.sgname); if (labinfo.bqtype == 1) //试管 { bool Candispense = false; logger.Info("dis: " + labinfo.sgname); LogStrSGAll += $"[{labinfo.sgname}] "; foreach (var t in listSgSetting) { if (t.NameList.Contains(labinfo.sgname) && t.InUse && stat.PreSaveTubeSensor[t.No - 1] != 0x00&&!t.LJErr) { LogStrSGDisp += $"[{labinfo.sgname}] "; DispenseData[Count] = (byte)((t.No) | 0xA0); JyOrderID[Count] = OrderID; //labinfo.Barcode = labinfo.Barcode + "11"; byte[] PerBarcode = new byte[labinfo.Barcode.Length + 1]; PerBarcode[0] = DispenseData[Count]; Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes(labinfo.Barcode), 0, PerBarcode, 1, labinfo.Barcode.Length); BarcodeLsit.Add(PerBarcode); byte[] ImageDataSG = new byte[SystemSet.RecpImageSize]; recpCreate.CreateImage(labinfo.sgxx, ref ImageDataSG); byte[] SendImageData = new byte[SystemSet.RecpImageSize + 2]; SendImageData[0] = (byte)((Count) | 0xB0); Buffer.BlockCopy(ImageDataSG, 0, SendImageData, 1, SystemSet.RecpImageSize); byte temp = 0x00; for (int i = 0; i < SystemSet.RecpImageSize; i++) { temp = (byte)(temp + ImageDataSG[i]); } SendImageData[SystemSet.RecpImageSize + 1] = temp; SendImageListSG.Add(SendImageData); SendImageListSGSave.Add(ImageDataSG); Count++; Candispense = true; break; } } if (!Candispense) { LogStrBQ += $"[{labinfo.sgname}] "; byte[] ImageDataSG = new byte[SystemSet.RecpImageSize]; recpCreate.CreateImage(labinfo.sgxx, ref ImageDataSG); SendImageListHZ.Add(ImageDataSG); UndisSGInfo = UndisSGInfo + labinfo.sgname + "@"; } } else { LogStrBQ += $"[{labinfo.sgname}] "; byte[] ImageDataSG = new byte[SystemSet.RecpImageSize]; recpCreate.CreateImage(labinfo.sgxx, ref ImageDataSG); SendImageListHZ.Add(ImageDataSG); } OrderID++; } logger.Info("UndisSGInfo: " + UndisSGInfo); EventMsgInfo += $"准备出管:\r\n所有试管信息:{LogStrSGAll}\r\n尝试出管列表:{LogStrSGDisp}\r\n标签打印列表:{LogStrBQ}"; if (SystemInYJmode) { foreach (byte[] image in SendImageListSGSave) { SendImageListHZ.Add(image); } } else { if (SendImageListHZ.Count > 0)//先打不能出管的标签及回执标签 { int TotalCout = SendImageListHZ.Count; //int PerSend = 0; int SendedCount = 0; foreach (byte[] ImageData in SendImageListHZ) { if (SendedCount % 10 == 0) { byte[] SendLen = { 0x00, 0x00 }; if (TotalCout - SendedCount > 10) { SendLen[0] = 0x0A; } else { SendLen[0] = (byte)(TotalCout - SendedCount); } if (!WaitMechinePrepare(ref msg)) { return SetResult(msg); } if (!MechineCtrol("GetPrint2Status", SendLen, ref RecvData)) // { return SetResult("发送副打印机标签数量失败"); } } byte[] SendImageData = new byte[SystemSet.RecpImageSize + 2]; SendImageData[0] = (byte)((SendedCount % 10) | 0xC0); Buffer.BlockCopy(ImageData, 0, SendImageData, 1, SystemSet.RecpImageSize); byte temp = 0x00; for (int i = 0; i < SystemSet.RecpImageSize; i++) { temp = (byte)(temp + ImageData[i]); } SendImageData[SystemSet.RecpImageSize + 1] = temp; if (SystemSet.CancelDispensing) { return SetResult("用户取消"); } if (!MechineCtrol("SendRecp", SendImageData, ref RecvData)|| RecvData[3]!=0xAA) //发送标签数据 { return SetResult("发送标签数据失败"); } SendedCount++; } } if (!WaitMechinePrepare(ref msg)) { return SetResult(msg); } SendImageListHZ.Clear(); if (SendImageListSG.Count > 0)//打印试管标签 { int DispensedCount = 0; bool NeedDispenseAgain = false; //是否再次出管 List ReSendImageListSG = new List(); //二次出管试管标签 如果不出管 直接发到回执 List ReSendOrderID = new List(); while (DispensedCount< Count) { if (SystemSet.CancelDispensing) { return SetResult("用户取消"); } Byte[] CmdData; Byte[] CmdBarcodeData; int StartPoint = DispensedCount; int CurDispenseCount = 0; if ((Count- DispensedCount)>= PerSGMaxNum) { CmdData = new byte[PerSGMaxNum+1]; CmdData[0] = 0x70; Buffer.BlockCopy(DispenseData, DispensedCount, CmdData, 1, PerSGMaxNum); CurDispenseCount = PerSGMaxNum; Byte[] TempData = new byte[1024]; int CurTempLen = 0; for (int i = DispensedCount; i < DispensedCount+CurDispenseCount; i++) { Buffer.BlockCopy(BarcodeLsit[i], 0, TempData, CurTempLen, BarcodeLsit[i].Length); CurTempLen += BarcodeLsit[i].Length; } CmdBarcodeData = new byte[CurTempLen + 1]; CmdBarcodeData[0] = 0x9B; Buffer.BlockCopy(TempData, 0, CmdBarcodeData, 1, CurTempLen); DispensedCount += PerSGMaxNum; } else { CmdData = new byte[Count - DispensedCount+1]; CmdData[0] = 0x70; Buffer.BlockCopy(DispenseData, DispensedCount, CmdData, 1, Count - DispensedCount); CurDispenseCount = Count - DispensedCount; Byte[] TempData = new byte[1024]; int CurTempLen = 0; for (int i = DispensedCount; i < DispensedCount+CurDispenseCount; i++) { Buffer.BlockCopy(BarcodeLsit[i], 0, TempData, CurTempLen, BarcodeLsit[i].Length); CurTempLen += BarcodeLsit[i].Length; } CmdBarcodeData = new byte[CurTempLen + 1]; CmdBarcodeData[0] = 0x9B; Buffer.BlockCopy(TempData, 0, CmdBarcodeData, 1, CurTempLen); DispensedCount = Count; } EventMsgInfo = $"{EventMsgInfo}\r\n发管参数:{BitConverter.ToString(CmdData).Replace("-", " ")}"; if (!MechineCtrol("DispenseMult", CmdData, ref RecvData)) //发试管列表 { return SetResult("发送发管列表失败,请重试"); } //if (!MechineCtrol("SendBarcodeInfo", CmdBarcodeData, ref RecvData)) //发送条码列表 //return "-1|发送条码列表失败,请重试"; for (int i =0; i< CurDispenseCount; i++) //发标签数据 { if (SystemSet.CancelDispensing) { return SetResult("用户取消"); } SendImageListSG[i + StartPoint][0]= (byte)((i) | 0xB0); if (!MechineCtrol("SendRecp", SendImageListSG[i+StartPoint], ref RecvData) || RecvData[3] != 0xAA) return SetResult("发送标签数据失败,请重试"); // Thread.Sleep(500); } if (!WaitMechineDispenseEnd(ref msg)) //等待发管完成 return SetResult(msg); if (MechineCtrol("GetLastDispenseStatus", null, ref RecvData)) //获取上次试管出管状态 { byte[] DisPenseStatus = new byte[RecvData.Length - 4]; Buffer.BlockCopy(RecvData, 3, DisPenseStatus, 0, RecvData.Length - 4); int i = 0; // DispenseFailed = DispenseFailed|(DisPenseStatus.Any(b => b == 0x02)); //如果有出管失败的记录 就不出管 因为有废标签 EventMsgInfo += $"\r\n出管状态:{BitConverter.ToString(DisPenseStatus).Replace("-", " ")}"; foreach (byte b in DisPenseStatus) { if (b != 0x00)//0x01 没管 0x02 出管失败 0x03未操作 { //if(DispenseFailed) //{ // if(ReSendImageListSG.Count>0) // { // foreach(byte[] ImageData in ReSendImageListSG) // { // SendImageListHZ.Add(ImageData); // } // ReSendImageListSG.Clear(); // } // SendImageListHZ.Add(SendImageListSGSave[i + StartPoint]); // NeedDispenseAgain = false; //} //else //{ if(b==0x02) //设置管仓状态为逻辑错误 { EventMsgInfo += $"\r\n管仓空管,调整管仓逻辑状态为逻辑空管"; setLJError(CmdData[i + 1]); MechineCtrol("CarReset", null, ref RecvData); //复位小车 等待小车复位完成 Thread.Sleep(500); MechineCtrol("LabelReset", null, ref RecvData); //复位小车 等待小车复位完成 if (!WaitMechinePrepare(ref msg)) return SetResult(msg); } ReSendOrderID.Add(JyOrderID[i + StartPoint]); ReSendImageListSG.Add(SendImageListSGSave[i + StartPoint]); NeedDispenseAgain = true; //} } /*if (b != 0x00)//0x01 没管 0x02 出管失败 0x03未操作 { SendImageListHZ.Add(SendImageListSGSave[i+ StartPoint]); }*/ i++; } } else { logger.Info("-1|获取试管发管状态失败"); EventMsgInfo += $"\r\n获取试管发管状态失败"; } } if(NeedDispenseAgain) { List SendImageListBD = new List(); string Result = DispenseAgain(labinfoList, ReSendOrderID,ref SendImageListBD); //补打标签 string[] Arr = Result.Split('|'); if(Arr[0]!="0") { return SetResult(Arr[1]); } foreach (byte[] imgedata in SendImageListBD) { SendImageListHZ.Add(imgedata); } } } } if (SendImageListHZ.Count > 0)//补打因为出管失败需要补打的标签 { EventMsgInfo += $"\r\n补打标签"; int TotalCout = SendImageListHZ.Count; //int PerSend = 0; int SendedCount = 0; foreach (byte[] ImageData in SendImageListHZ) { if (SendedCount % 10 == 0) { byte[] SendLen = { 0x00, 0x00 }; if (TotalCout - SendedCount > 10) { SendLen[0] = 0x0A; } else { SendLen[0] = (byte)(TotalCout - SendedCount); } if (!WaitMechinePrepare(ref msg)) return SetResult(msg); if (!MechineCtrol("GetPrint2Status", SendLen, ref RecvData)) // { return SetResult("发送副打印机标签数量失败"); } } byte[] SendImageData = new byte[SystemSet.RecpImageSize + 2]; SendImageData[0] = (byte)((SendedCount % 10) | 0xC0); Buffer.BlockCopy(ImageData, 0, SendImageData, 1, SystemSet.RecpImageSize); byte temp = 0x00; for (int i = 0; i < SystemSet.RecpImageSize; i++) { temp = (byte)(temp + ImageData[i]); } SendImageData[SystemSet.RecpImageSize + 1] = temp; if (SystemSet.CancelDispensing) { return SetResult("用户取消"); } if (!MechineCtrol("SendRecp", SendImageData, ref RecvData) || RecvData[3] != 0xAA) //发送标签数据 return SetResult("发送标签数据失败"); SendedCount++; } } //if(DispenseFailed) //{ // return "-1|出管异常,请清理主打印头标签" ; //} if (!WaitMechinePrepare(ref msg)) return SetResult(msg); else { EventMsgInfo += $"\r\n发管完成"; Task.Run(() => PublicStatic.EventMgr.ExcuteCmd($"insert into EVENTINFOLIST(Msg,Details,Time) Values('{"发管过程成功"}','{EventMsgInfo}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')")); return "0|"; } } public string DispenseAgain(PatientDatail labinfoList, List ReSendOrderID, ref List SendImageListHZ) { logger.Info("进入二次打印流程:"); EventMsgInfo += $"\r\n进入二次打印流程"; string msg1 = "" ; List BarcodeLsit = new List(); // 条码信息 List SendImageListBD = new List(); //副打印机 RecvData = new byte[1024]; Byte[] DispenseData = new Byte[30]; List SendImageListSG = new List(); //试管便签打印机 List SendImageListSGSave = new List(); //试管便签打印机 不带位置信息 int Count = 0; string UndisSGInfo = ""; int OrderID = 0; string LogStrSGAll = ""; string LogStrSGDisp = ""; string LogStrBQ = ""; foreach (jyData labinfo in labinfoList.jyDatas) { if(!ReSendOrderID.Contains(OrderID)) { OrderID++; continue; } LogStrSGAll += $"[{labinfo.sgname}] "; if (labinfo.bqtype == 1) //试管 { bool Candispense = false; logger.Info("dis: " + labinfo.sgname); foreach (var t in listSgSetting) { if (t.NameList.Contains(labinfo.sgname) && t.InUse && stat.PreSaveTubeSensor[t.No - 1] != 0x00&&!t.LJErr) { LogStrSGDisp += $"[{labinfo.sgname}] "; DispenseData[Count] = (byte)((t.No) | 0xA0); byte[] PerBarcode = new byte[labinfo.Barcode.Length + 1]; PerBarcode[0] = DispenseData[Count]; Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes(labinfo.Barcode), 0, PerBarcode, 1, labinfo.Barcode.Length); BarcodeLsit.Add(PerBarcode); byte[] ImageDataSG = new byte[SystemSet.RecpImageSize]; recpCreate.CreateImage(labinfo.sgxx, ref ImageDataSG); byte[] SendImageData = new byte[SystemSet.RecpImageSize + 2]; SendImageData[0] = (byte)((Count) | 0xB0); Buffer.BlockCopy(ImageDataSG, 0, SendImageData, 1, SystemSet.RecpImageSize); byte temp = 0x00; for (int i = 0; i < SystemSet.RecpImageSize; i++) { temp = (byte)(temp + ImageDataSG[i]); } SendImageData[SystemSet.RecpImageSize + 1] = temp; SendImageListSG.Add(SendImageData); SendImageListSGSave.Add(ImageDataSG); Count++; Candispense = true; break; } } if (!Candispense) { LogStrBQ += $"[{labinfo.sgname}] "; byte[] ImageDataSG = new byte[SystemSet.RecpImageSize]; recpCreate.CreateImage(labinfo.sgxx, ref ImageDataSG); SendImageListHZ.Add(ImageDataSG); UndisSGInfo = UndisSGInfo + labinfo.sgname + "@"; } } else { LogStrBQ += $"[{labinfo.sgname}] "; byte[] ImageDataSG = new byte[SystemSet.RecpImageSize]; recpCreate.CreateImage(labinfo.sgxx, ref ImageDataSG); SendImageListHZ.Add(ImageDataSG); } OrderID++; } logger.Info("UndisSGInfo: " + UndisSGInfo); EventMsgInfo += $"\r\n准备出管:\r\n所有试管信息:{LogStrSGAll}\r\n尝试出管列表:{LogStrSGDisp}\r\n标签打印列表:{LogStrBQ}"; if (SystemInYJmode) { foreach (byte[] image in SendImageListSGSave) { SendImageListHZ.Add(image); } } else { if (SendImageListSG.Count > 0)//打印试管标签 { int DispensedCount = 0; bool DispenseFailed = false; //是否有出管失败的情况 如果有则不再出第二批管,因为打印头有废标签 while (DispensedCount < Count) { Byte[] CmdData; Byte[] CmdBarcodeData; int StartPoint = DispensedCount; int CurDispenseCount = 0; if ((Count - DispensedCount) >= PerSGMaxNum) { CmdData = new byte[PerSGMaxNum + 1]; CmdData[0] = 0x70; Buffer.BlockCopy(DispenseData, DispensedCount, CmdData, 1, PerSGMaxNum); CurDispenseCount = PerSGMaxNum; Byte[] TempData = new byte[1024]; int CurTempLen = 0; for (int i = DispensedCount; i < CurDispenseCount; i++) { Buffer.BlockCopy(BarcodeLsit[i], 0, TempData, CurTempLen, BarcodeLsit[i].Length); CurTempLen += BarcodeLsit[i].Length; } CmdBarcodeData = new byte[CurTempLen + 1]; CmdBarcodeData[0] = 0x9B; Buffer.BlockCopy(TempData, 0, CmdBarcodeData, 1, CurTempLen); DispensedCount += PerSGMaxNum; } else { CmdData = new byte[Count - DispensedCount + 1]; CmdData[0] = 0x70; Buffer.BlockCopy(DispenseData, DispensedCount, CmdData, 1, Count - DispensedCount); CurDispenseCount = Count - DispensedCount; Byte[] TempData = new byte[1024]; int CurTempLen = 0; for (int i = DispensedCount; i < DispensedCount + CurDispenseCount; i++) { Buffer.BlockCopy(BarcodeLsit[i], 0, TempData, CurTempLen, BarcodeLsit[i].Length); CurTempLen += BarcodeLsit[i].Length; } CmdBarcodeData = new byte[CurTempLen + 1]; CmdBarcodeData[0] = 0x9B; Buffer.BlockCopy(TempData, 0, CmdBarcodeData, 1, CurTempLen); DispensedCount = Count; } //if (DispenseFailed) //如果前面已经报出管错误,则后面的管只打标签 因为出管失败可能有标签在打印头 会贴错管 //{ // for (int i = 0; i < CurDispenseCount; i++) // { // SendImageListHZ.Add(SendImageListSGSave[i + StartPoint]); // } // continue; //} EventMsgInfo += $"\r\n发管参数:{BitConverter.ToString(CmdData).Replace("-", " ")}"; if (!MechineCtrol("DispenseMult", CmdData, ref RecvData)) //发试管列表 return "-1|发送发管列表失败,请重试"; //if (!MechineCtrol("SendBarcodeInfo", CmdBarcodeData, ref RecvData)) //发送条码列表 // return "-1|发送条码列表失败,请重试"; for (int i = 0; i < CurDispenseCount; i++) //发标签数据 { if (SystemSet.CancelDispensing) { return "-1|用户取消"; } SendImageListSG[i + StartPoint][0] = (byte)((i) | 0xB0); if (!MechineCtrol("SendRecp", SendImageListSG[i + StartPoint], ref RecvData) || RecvData[3] != 0xAA) return "-1|发送标签数据失败,请重试"; // Thread.Sleep(500); } string msg = ""; Thread.Sleep(1000); if (!WaitMechineDispenseEnd(ref msg)) //等待发管完成 return "-1|" + msg; if (MechineCtrol("GetLastDispenseStatus", null, ref RecvData)) //获取上次试管出管状态 { byte[] DisPenseStatus = new byte[RecvData.Length - 4]; Buffer.BlockCopy(RecvData, 3, DisPenseStatus, 0, RecvData.Length - 4); EventMsgInfo += $"\r\n出管状态:{BitConverter.ToString(DisPenseStatus).Replace("-", " ")}"; DispenseFailed = DispenseFailed | (DisPenseStatus.Any(b => b == 0x02)); //如果有出管失败的记录 就不出管 因为有废标签 int i = 0; foreach (byte b in DisPenseStatus) { if (b != 0x00)//0x01 没管 0x02 出管失败 0x03未操作 { SendImageListHZ.Add(SendImageListSGSave[i+ StartPoint]); } i++; } } else { logger.Info("-1|获取试管发管状态失败"); } } } } return "0|"; } public bool WaitMechinePrepare(ref string Msg) { int Time = 60; bool Ready = false; Msg = "系统忙或组件状态异常"; while (Time > 0 && !Ready) { if(SystemSet.CancelDispensing) { Msg = "用户取消"; return false; } GetDevStatus(); if (stat.TubeState == 0x50 && stat.PrintState == 0x50 && stat.StickState == 0x50 && stat.BackPrintState == 0x50) { Ready = true; } else if (stat.TubeState == 0x53 || stat.PrintState == 0x53 || stat.StickState == 0x53) { if (stat.BackPrintState == 0x50) return true; else return false; } else { Time--; Thread.Sleep(500); } } return Ready; } public bool WaitMechineDispenseEnd(ref string Msg) { int Time = 120; bool Ready = false; Msg = "设备状态正忙"; while (Time > 0 && !Ready) { if (SystemSet.CancelDispensing) { Msg = "用户取消"; return false; } GetDevStatus(); if (stat.TubeState == 0x50 && stat.PrintState == 0x50 && stat.StickState == 0x50 && stat.BackPrintState == 0x50) { Ready = true; } else if (stat.TubeState == 0x53 || stat.PrintState == 0x53 || stat.StickState == 0x53) { if (stat.BackPrintState == 0x50) return true; else { Msg = "设备模块状态异常,请检查"; return false; } } else if ( stat.StickState == 0x52&&(stat.StickBugCode==0xE9|| stat.StickBugCode == 0xEA))//试管扫码异常 { Msg = "试管条码检测异常,请仔细核对试管上的条码"; return false; } else { Time--; Thread.Sleep(500); } } return Ready; } public bool MechineCtrol(string Cmd, Byte[] sendData, ref Byte[] RecvData) { if(!mutex.WaitOne()) { return false; } Byte[] toSend; IsDevFree = false; logger.Info($"CmdIn:{Cmd}"); switch (Cmd) { case "SendRecp": { toSend = new Byte[SystemSet.RecpImageSize + 3]; toSend[0] = 0xAA; // toSend[1] = 0xAA; Buffer.BlockCopy(sendData, 0, toSend, 1, sendData.Length); break; } case "RecpReset": { toSend = new Byte[4] { 0x02, 0x01, 0xCB, 0x03 }; break; } case "Recp2Reset": { toSend = new Byte[5] { 0x02, 0x02, 0xDC, 0x01, 0x03 }; break; } case "PrintTest": { toSend = new Byte[4] { 0x02, 0x01, 0xC0, 0x03 }; break; } case "LabelReset": { toSend = new Byte[4] { 0x02, 0x01, 0x52, 0x03 }; break; } case "CarReset": { toSend = new Byte[4] { 0x02, 0x01, 0xA0, 0x03 }; break; } case "DevReset": { toSend = new Byte[4] { 0x02, 0x01, 0xCA, 0x03 }; break; } case "Dispense": { toSend = new Byte[8] { 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }; Buffer.BlockCopy(sendData, 0, toSend, 2, sendData.Length); break; } case "DispenseMult": { toSend = new Byte[sendData.Length + 3]; toSend[0] = 0x02; toSend[1] = (byte)sendData.Length; toSend[sendData.Length + 2] = 0x03; Buffer.BlockCopy(sendData, 0, toSend, 2, sendData.Length); break; } case "SendBarcodeInfo": { toSend = new Byte[sendData.Length + 3]; toSend[0] = 0x02; toSend[1] = (byte)sendData.Length; toSend[sendData.Length + 2] = 0x03; Buffer.BlockCopy(sendData, 0, toSend, 2, sendData.Length); break; } case "GetStatus": { toSend = new Byte[4] { 0x02, 0x01, 0x57, 0x03 }; break; } case "SetSysTemInfo": { toSend = new Byte[sendData.Length + 3]; toSend[0] = 0x02; toSend[1] = (byte)sendData.Length; toSend[sendData.Length + 2] = 0x03; Buffer.BlockCopy(sendData, 0, toSend, 2, sendData.Length); break; } case "CutRecp": { toSend = new Byte[4] { 0x02, 0x01, 0xB0, 0x03 }; break; } case "GetPrint2Status": //副打印机状态 { toSend = new Byte[5] { 0x02, 0x02, 0x72, 0x00, 0x03 }; toSend[3] = sendData[0]; break; } case "GetVersion": { toSend = new Byte[4] { 0x02, 0x01, 0x79, 0x03 }; break; } case "ReplaceRecp": { toSend = new Byte[6] { 0x02, 0x03, 0x9F, 0x01, 0x0E, 0x03 }; break; } case "SendaLabel": { toSend = new Byte[4] { 0x02, 0x01, 0x75, 0x03 }; break; } case "GetLastDispenseStatus": { toSend = new Byte[4] { 0x02, 0x01, 0x97, 0x03 }; break; } case "InitSensor": { toSend = new Byte[4] { 0x02, 0x01, 0x90, 0x03 }; break; } case "SetTbPargs": { toSend = new Byte[7] { 0x02, 0x04, 0xC6, 0x00, 0x00, 0x00, 0x03 }; Buffer.BlockCopy(sendData, 0, toSend, 3, sendData.Length); break; } case "GetTbPargs": { toSend = new Byte[4] { 0x02, 0x01, 0x7b, 0x03 }; break; } case "SetQdPargs": { toSend = new Byte[7] { 0x02, 0x04, 0x76, 0x00, 0x00, 0x00, 0x03 }; Buffer.BlockCopy(sendData, 0, toSend, 3, sendData.Length); break; } case "GetQdPargs": { toSend = new Byte[4] { 0x02, 0x01, 0x77, 0x03 }; break; } case "SetSmPargs": { toSend = new Byte[7] { 0x02, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x03 }; Buffer.BlockCopy(sendData, 0, toSend, 3, sendData.Length); break; } case "GetSmPargs": { toSend = new Byte[4] { 0x02, 0x01, 0x5d, 0x03 }; break; } case "GetBoxBarcode": { toSend = new Byte[5] { 0x02, 0x02, 0xc7,0x03, 0x03 }; break; } default: { IsDevFree = true; return false; } } try { if (Cmd.Equals("DevReset")) RecvData = comTool.SendAndRecv(toSend, 10000); else if (Cmd.Equals("CarReset") || Cmd.Equals("LabelReset") || Cmd.Equals("SendaLabel") || Cmd.Equals("InitSensor") || Cmd.Equals("SetTbPargs") || Cmd.Equals("SetQdPargs") || Cmd.Equals("SetSmPargs") || Cmd.Equals("GetBoxBarcode")) RecvData = comTool.SendAndRecv(toSend, 500); else if (Cmd.Equals("GetStatus")) RecvData = comTool.SendAndRecv(toSend, 1500); else RecvData = comTool.SendAndRecv(toSend); if (ShowComLog != "0") { logger.Info(string.Format("\r\nOUT[{0}]\r\nIN[{1}]", BitConverter.ToString(toSend).Replace("-", " "), BitConverter.ToString(RecvData, 0, Math.Min(RecvData.Length, 300)).Replace("-", " "))); } MainForm.DevStat = 0; } catch (Exception e) { logger.Info(string.Format("\r\nOUT[{0}]\r\nIN[{1}]", BitConverter.ToString(toSend).Replace("-", " "), e.Message)); IsDevFree = true; mutex.ReleaseMutex(); MainForm.DevStat = -1; return false; } IsDevFree = true; mutex.ReleaseMutex(); return true; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct DEVSTATUS { public byte Command; //机器正在执行的指令 //public byte Rubish; //垃圾 public byte TubeState; //选管单元状态 public byte PrintState; //打印单元状态 public byte StickState; //贴标单元状态 public byte BackPrintState; //副打印单元状态 public byte TubeBugCode; //选管单元故障代码 public byte PrintBugCode; //打印单元故障代码 public byte StickBugCode; //贴标单元故障代码 public byte BackPrintBugCode; //副打印机单元故障代码 public byte CarCommand; //小车在执行的指令 public byte CarUnitState; //挖管单元状态 public byte CarMotorState; //小车电机状态 public byte CarOriginalSensor; //小车原点传感器 public byte CarPositionSensor; //小车位置传感器 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 7, ArraySubType = UnmanagedType.Struct)] public byte[] PreSaveTubeSensor; //管箱预存传感器 public byte CarLeftSensor; //小车落管左传感器 public byte CarMidSensor; //小车落管中传感器 public byte CarRightSensor; //小车落管右传感器 //public byte FrontMagState; //前电磁铁状态,第一管箱电磁铁 //public byte RearMagState; //后电磁铁状态,其他管箱 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte[] FrontMagSensor; //前电磁铁传感器 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte[] RearMagSensor; //后电磁铁传感器 public byte StickCommand; //贴标单元在执行的指令 public byte StickUnitState; //贴标单元状态 public byte RotateMotorState; //贴标旋转电机状态 public byte LeftWallMotorState; //左挡板电机状态 public byte RightWallMotorState; //右挡板电机状态 public byte LiftMotorState; //抬升电机状态 public byte LeftWallSensor; //左挡板传感器 public byte RightWallSensor; //右挡板传感器 // [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte LiftSensor; //抬升传感器 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte[] StickLeftTubeSensor; //贴标单元落管左传感器.采用ADC方式上传 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte[] StickRightTubeSensor; //贴标单元落管右传感器.采用ADC方式上传 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte[] StickUpTubeSensor; //贴标单元落管上传感器.采用ADC方式上传 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.Struct)] public byte[] StickDownTubeSensor; //贴标单元落管下传感器.采用ADC方式上传 public byte rush; //不要的数据 public byte PrintCommand; //打印单元正在执行指令 public byte PrintUnitState; //打印单元状态,打印头是否安装到位.1表示到位,0表示不到位。 20240103 public byte CarryMotorState; //走纸电机状态 public byte RollMotorState; //卷纸电机状态 public byte PaperGapSensor; //标签缝隙传感器 public byte PaperLessSensor; //纸张将近传感器。0表示足够,1表示将尽。20240103 public byte PrintTemperatureSensor; //打印温度传感器 public byte BackPrintCommand; //备用打印在执行指令 public byte BackPrintUnitState; //备用打印头安装状态,是否安装到位。1表示到位,0表示不到位。 public byte BackPaperGapSensor; //备用打印标签缝隙传感器 public byte BackPaperLessSensor; //备用打印纸将尽传感器。0表示足够,1表示将尽。20240103 public byte BackPrintTemperatureSensor; //打印温度传感器 public byte TubeTakeBoxSensorState; //取试管盒传感器 public byte TubeTakeBoxColorState; //取试管颜色传感器 //public byte SensorInit; //机器传感器是否初始化标志 0未初始化 // public byte Parameterset; //机器工作都败设置标志,如果为0, public byte Sensorlnit;//机器传感器初始化标志,如果为0表示没有初始化过,机器不能工作 public byte ParameterSet;//机器工作参数设置标志,如果为0,表示没有下发工作参数,机器不能工作 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.Struct)] public byte[] BackUp; //备用传感器 } public string GetDevStatus() { try { if (!MechineCtrol("GetStatus", null, ref RecvData)) { //AlertForm.ShowAlert("查询设备状态失败,请检查设备连接状态", AlertType.Error, 3); return "-1|查询设备状态失败,请检查设备连接状态"; } //数组转结构体,字节对齐 DEVSTATUS OldStatus = stat; IntPtr ptr = Marshal.AllocHGlobal(100);//分配非托管内存空间 Marshal.Copy(RecvData, 3, ptr, RecvData.Length - 4);//将数组数组拷贝到非托管内存指针 stat = (DEVSTATUS)Marshal.PtrToStructure(ptr, typeof(DEVSTATUS)); Marshal.FreeHGlobal(ptr);//释放内存 Task.Run(() => TaksCheckStatus(OldStatus, stat)); return "0|success"; } catch(Exception e) { return "-1|查询设备状态失败,请检查设备连接状态"; } } public void TaksCheckStatus(DEVSTATUS OldStatus, DEVSTATUS NewStatus) { //JLogger.logger.Info($"TaksCheckStatus OldStatus.BackUp[2]={OldStatus.BackUp[2]} NewStatus.BackUp[2]={NewStatus.BackUp[2]} OldStatus.BackUp[3]={OldStatus.BackUp[3]} NewStatus.BackUp[3]={NewStatus.BackUp[3]}"); if (OldStatus.BackUp[2] != NewStatus.BackUp[2]) { switch (NewStatus.BackUp[2]) { case 0x01: //试管仓打开 PublicStatic.EventMgr.ExcuteCmd($"insert into EVENTINFOLIST(Msg,Details,Time) Values('{"试管仓打开"}','{"试管仓被打开"}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')"); break; case 0x00: //试管仓关闭 PublicStatic.EventMgr.ExcuteCmd($"insert into EVENTINFOLIST(Msg,Details,Time) Values('{"试管仓关闭"}','{"试管仓被关闭"}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')"); break; } } if (OldStatus.BackUp[3] != NewStatus.BackUp[3]) { switch (NewStatus.BackUp[3]) { case 0x01: //标签仓打开 PublicStatic.EventMgr.ExcuteCmd($"insert into EVENTINFOLIST(Msg,Details,Time) Values('{"标签仓打开"}','{"标签仓被打开"}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')"); break; case 0x00: //标签仓关闭 PublicStatic.EventMgr.ExcuteCmd($"insert into EVENTINFOLIST(Msg,Details,Time) Values('{"标签仓关闭"}','{"标签仓被关闭"}','{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')"); break; } } } public string Reset() { if (!MechineCtrol("DevReset", null, ref RecvData)) { return "-1|系统复位失败"; } return "0|系统复位成功"; } public string RecpReset() { if (!MechineCtrol("RecpReset", null, ref RecvData)) { return "-1|标签复位失败"; } return "0|标签复位成功"; } public bool isOpened() { return comTool.isOpen(); } public bool WaitTubeTakeBox() { bool Ready = false; logger.Info("WaitTubeTakeBox"); GetDevStatus(); if (stat.TubeTakeBoxSensorState == 0x01) //盒子存在 { logger.Info("盒子在位"); //if(SystemSet.UseBle) // 如果使用蓝牙 //{ // logger.Info("获取条码"); // BleBarcodeStr = GetTubeBoxBleMacAddr(); //获取蓝牙地址条码 // logger.Info("匹配MAC地址:" + BleBarcodeStr); // if (BleBarcodeStr.Length <= 0) // return false; //} Ready = true; } return Ready; } public bool WaitTubeTakeBoxTaken() { bool Ready = false; logger.Info("WaitTubeTakeBoxTaken"); GetDevStatus(); if (stat.TubeTakeBoxSensorState == 0x00) { Ready = true; } return Ready; } //public string GetTubeBoxBleMacAddr() //{ // byte[] RecvData = new byte[600]; // MechineCtrol("GetBoxBarcode", null, ref RecvData); // if (RecvData[1] <= 0x02) // return ""; // int len = RecvData[1]-3; // byte[] bBarcode = new byte[len ] ; // Buffer.BlockCopy(RecvData, 3, bBarcode, 0, len); // string Bardocde = Encoding.ASCII.GetString(bBarcode); // logger.Info("获取到条码:"+ Bardocde); // MechineCtrol("GetBoxBarcode", null, ref RecvData); //再扫一遍 去除垃圾数据 扫码头可能回多条数据 // return SystemSet.sqlHelper.GetBLEAddr(Bardocde); //} public void setLJError(byte sgid) { switch(sgid) { case 0xA1: { SgSetting setting = listSgSetting[0]; setting.LJErr = true; listSgSetting[0] = setting; } break; case 0xA2: { SgSetting setting = listSgSetting[1]; setting.LJErr = true; listSgSetting[1] = setting; } break; case 0xA3: { SgSetting setting = listSgSetting[2]; setting.LJErr = true; listSgSetting[2] = setting; } break; case 0xA4: { SgSetting setting = listSgSetting[3]; setting.LJErr = true; listSgSetting[3] = setting; } break; case 0xA5: { SgSetting setting = listSgSetting[4]; setting.LJErr = true; listSgSetting[4] = setting; } break; case 0xA6: { SgSetting setting = listSgSetting[5]; setting.LJErr = true; listSgSetting[5] = setting; } break; case 0xA7: { SgSetting setting = listSgSetting[6]; setting.LJErr = true; listSgSetting[6] = setting; } break; default: break; } } } }