Files
tj-tzhg/JJMediSys/cs/TubeLabelTool.cs
2025-11-26 17:21:18 +08:00

1365 lines
61 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}
}