Files
tj-tzhg/JJMediSys/cs/TubeLabelTool.cs

1365 lines
61 KiB
C#
Raw Normal View History

2025-11-26 17:20:53 +08:00
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<SgSetting> listSgSetting = new List<SgSetting>();
public List<string> canDispenseTubles = new List<string>();
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<byte[]> BarcodeLsit = new List<byte[]>(); // 条码信息
List<byte[]> SendImageListSG = new List<byte[]>(); //试管便签打印机
List<byte[]> SendImageListHZ = new List<byte[]>(); //副打印机
List<byte[]> SendImageListSGSave = new List<byte[]>(); //试管便签打印机 不带位置信息
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<byte[]> ReSendImageListSG = new List<byte[]>(); //二次出管试管标签 如果不出管 直接发到回执
List<int> ReSendOrderID = new List<int>();
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<byte[]> SendImageListBD = new List<byte[]>();
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<int> ReSendOrderID, ref List<byte[]> SendImageListHZ)
{
logger.Info("进入二次打印流程:");
EventMsgInfo += $"\r\n进入二次打印流程";
string msg1 = "" ;
List<byte[]> BarcodeLsit = new List<byte[]>(); // 条码信息
List<byte[]> SendImageListBD = new List<byte[]>(); //副打印机
RecvData = new byte[1024];
Byte[] DispenseData = new Byte[30];
List<byte[]> SendImageListSG = new List<byte[]>(); //试管便签打印机
List<byte[]> SendImageListSGSave = new List<byte[]>(); //试管便签打印机 不带位置信息
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;
}
}
}
}