You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

790 lines
32 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Configuration;
//using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Threading;
namespace Mesnac.DeviceAdapter.HWKC_81600
{
[ClassInterface(ClassInterfaceType.None)]
public class HWKC_81600Adapter : IDeviceAdapter
{
public log4net.ILog LogInfo = log4net.LogManager.GetLogger("RollingLogFileAppender"); //Logging 名字要在 App.config 中能找到
#region 全局变量声明
private List<IOInfo> IO_Infolist = new List<IOInfo>();
private List<IOInfo> IO_OUTfolist = new List<IOInfo>();
private class IOInfo
{
public int id;
public byte[] state;
public DateTime time;
}
CommType gConnetType = new CommType();
private DeviceType m_iDeviceType = DeviceType.HWKC_81600;
ICommunicateService m_ICommunicateService = null;
public event RecvIdentifyData RecvIdentifyDataEvent = null;
public event RecvIdentifyData RecvIdentifyData_ToMES_Event;
public UInt16 m_iDeviceId = 0;
private string m_strIp; //读写器IP或串口号
private int m_iPort; //读写器端口号或波特率
private readonly string m_ReadDbm = ConfigurationManager.AppSettings["ReadDbm"];
private readonly string m_WriteDbm = ConfigurationManager.AppSettings["WriteDbm"];
private readonly string m_AnalysisFlag = ConfigurationManager.AppSettings["AnalysisFlag"]; //1按照次数最多返回条码2按照平均功率最大返回条码
private readonly string m_IsIOSendData = ConfigurationManager.AppSettings["IsIOSendData"];
private int m_ConnectFlag = 0;
private Mutex mut = new Mutex();
private ManualResetEvent BeginEvent = new ManualResetEvent(true);
public bool TagInventory_Lable = true;//连续盘点标签标志
private Semaphore m_GlobalSem = new Semaphore(1, 1);
private byte m_ReadHeartDataLen = 0;
private byte[] m_ReadHeartData = null;
private bool m_GetHeartSuccessful = false;
private Semaphore m_GetHeartSem = new Semaphore(0, 100000);
private Semaphore m_MulEpcSem = new Semaphore(0, 100000);
private Semaphore m_StopSem = new Semaphore(0, 100000);
private Semaphore m_OneEpcSem = new Semaphore(0, 100000);
private byte m_ReadDataLen = 0;
private byte[] m_ReadData = null;
private Semaphore m_ReadSem = new Semaphore(0, 100000);
private bool m_bWriteSuccedTag = false;
private byte m_WriteDataLen = 0;
private byte[] m_WriteData = null;
private Semaphore m_WriteSem = new Semaphore(0, 100000);
private bool m_ReadTimeoutSuccessful = false; //延时读取
private Semaphore m_ReadTimeoutSem = new Semaphore(0, 100000);
private int m_BarcodeGroupCount = 0;
private byte[] m_MulAllData = null;
private byte[] m_AutoReadEPC = null;
private int m_readEPCDataLen = 0;
private byte m_OneEpcDataLen = 0;
private byte m_ReadAntenna = 254;
private byte[] m_OneEpcData = null;
#endregion
public int AutoReport
{
get { return AutoReport; }
set { AutoReport = value; }
}
public int Filter
{
get { return Filter; }
set { Filter = value; }
}
#region 设备连接部分
public bool Device_Init(CommType iCommType, string pUrl, DeviceType iDeviceType)
{
try
{
m_iDeviceType = iDeviceType;
//LogService.Instance.Debug("函数调用:Device_Init Start: ");
//if (iDeviceType == DeviceType.Mesnac_GRUV100)
{
if (iCommType == CommType.RJ45) //网口
{
if (m_ICommunicateService == null)
{
m_ICommunicateService = new BgTcpClient();
}
string[] split = pUrl.Split(new Char[] { ':' });
m_strIp = split[0];
string strTemp = split[1];
m_iPort = Convert.ToInt32(strTemp);
m_ICommunicateService.Init(m_strIp, m_iPort, this);
LogInfo.Info("设备初始化成功IP" + m_strIp + "端口号:" + m_iPort);
}
else //串口,代用串口号和波特率
{
if (m_ICommunicateService == null)
{
return false;
}
string[] split = pUrl.Split(new Char[] { ':' });
m_strIp = split[0];
string strTemp = split[1];
m_iPort = Convert.ToInt32(strTemp);
m_ICommunicateService.Init(m_strIp, m_iPort, this);
LogInfo.Info("设备初始化成功,串口号:" + m_strIp + "波特率:" + m_iPort);
}
}
}
catch (Exception ex)
{
LogInfo.Info("连接读写器异常:" + ex.Message);
return false;
}
return true;
}
public bool Device_Init_Id(CommType iCommType, string pUrl, ushort iDeviceId)
{
m_iDeviceId = iDeviceId;
Device_Init(iCommType, pUrl, (DeviceType)1);
return true;
}
public bool Device_Connect()
{
try
{
if (m_ICommunicateService != null)
{
if (m_ICommunicateService.Connect())
{
//LogService.Instance.Info("Device_Connect:连接成功");
return true;
}
else
{
LogInfo.Info("Device_Connect:连接失败");
return false;
}
}
else
{
return false;
}
}
catch (Exception ex)
{
LogInfo.Info("Device_Connect异常" + ex.Message);
return false;
}
}
public void Device_Destroy()
{
m_ICommunicateService.DisConnect();
}
public bool Device_GetState()
{
return m_ICommunicateService.GetState();
}
public bool Device_ReConnect()
{
return Device_Connect();
}
#endregion
#region 处理函数
public bool Device_DealValidPack(byte[] ValidData)
{
//LogService.Instance.Debug("----函数调用:Device_DealValidPack 开始!");
try
{
switch (ValidData[1]) //处理数据
{
case 0X04: //心跳
//if (ValidData[1] == 0X04 && ValidData[2] == 0X02)
//{
// //m_ReadHeartDataLen = 1;
// m_GetHeartSuccessful = true;
//}
//else
//{
// //m_ReadHeartDataLen = 0;
// m_GetHeartSuccessful = false;
//}
m_GetHeartSuccessful = true;
m_GetHeartSem.Release();
break;
case 0X03: //Read DI自报
if (ValidData[1] == 0X03 && ValidData[2] == 0X02) //成功
{
//m_ReadDataLen = 1;
m_ReadData = new byte[1];
m_ReadAntenna = ValidData[3];
m_ReadData[0] = ValidData[4];
//光电过滤
//if (StringChange.MethodFilterData.EliminatingJitter(m_iDeviceId, m_ReadData))
//{
// return true;
//}
//else
//{
// if (RecvIdentifyDataEvent != null)
// {
// RecvIdentifyDataEvent(1, m_ReadData, m_ReadAntenna, m_iDeviceId, m_strIp);
// }
//}
if (RecvIdentifyDataEvent != null)
{
RecvIdentifyDataEvent?.Invoke(1, null, m_ReadAntenna, m_iDeviceId, m_strIp, "2");
if (m_ReadData[0] == 0xFF)
{
if (m_IsIOSendData == "1")
{
bool iflag = SendAutoSignalCallBack();//向终端发送自报数据回执
if (!iflag)
{
SendAutoSignalCallBack();
LogInfo.Info("方法SendAutoSignalCallBackHWKC_81600设备" + m_strIp + ":" + m_iPort + "再次发送自报数据回执:" + iflag);
}
}
}
}
}
break;
case 0X02: //Read DI
if (ValidData[1] == 0X02 && ValidData[2] == 0X02)
{
m_ReadDataLen = 1;
//m_ReadHeartDataLen = 1;
m_ReadHeartData = new byte[1];
m_ReadHeartData[0] = ValidData[4];
m_ReadData = new byte[1];
m_ReadData[0] = ValidData[4];
}
else
{
m_ReadDataLen = 0;
}
m_ReadSem.Release();
break;
case 0X05: //Write DO
Deal_WriteDoTime(ValidData);
//if (ValidData[0] == 0X01 && ValidData[1] == 0X05) //成功
//{
// m_WriteDataLen = 1;
// m_WriteData = new byte[1];
// m_WriteData[0] = ValidData[4];
//}
//else
//{
// m_WriteDataLen = 0;
//}
////LogService.Instance.Debug("写入DO" + ValidData[4]);
//m_WriteSem.Release();
break;
case 0X07: //Write DO 带时间
Deal_WriteDoTime(ValidData);
//if (ValidData[0] == 0X01 && ValidData[1] == 0X07) //成功
//{
// m_WriteDataLen = 1;
// m_WriteData = new byte[1];
// m_WriteData[0] = ValidData[4];
//}
//else
//{
// m_WriteDataLen = 0;
//}
////LogService.Instance.Debug("带时间写入DO" + ValidData[4]);
//m_WriteSem.Release();
break;
case 0X09: //Write DO 带翻转时间
Deal_WriteDoTime(ValidData);
break;
}
}
catch (Exception ex)
{
LogInfo.Info("空间名:" + ex.Source + "" + '\n' +
"方法名:" + ex.TargetSite + '\n' +
"故障点:" + ex.StackTrace.Substring(ex.StackTrace.LastIndexOf("\\") + 1, ex.StackTrace.Length - ex.StackTrace.LastIndexOf("\\") - 1) + '\n' +
"错误提示:" + ex.Message);
return false;
}
return true;
}
private bool SendAutoSignalCallBack()
{
bool iFlag = false;
try
{
//收到自报信号发送回执报文
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_Data1 = new byte[1];
pMessagePack.m_BeginChar = 0X01;
pMessagePack.m_FunctionCode = 0x83;
pMessagePack.m_Channel1 = 0x02;
pMessagePack.m_Channel2 = 0x00;
pMessagePack.m_Data1[0] = 0x01;
if (m_ICommunicateService != null)
{
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
{
iFlag = true;
}
else
{
//重新发送
//SendAutoSignalCallBack();
iFlag = false;
}
}
else
{
LogInfo.Info("方法SendAutoSignalCallBackHWKC_81600设备" + m_strIp + ":" + m_iPort + "发送自报数据回执失败,设备通讯故障。");
iFlag = false;
}
return iFlag;
////await Task.Delay(1000);
}
catch (Exception ex)
{
LogInfo.Info("空间名:" + ex.Source + "" + '\n' +
"方法名:" + ex.TargetSite + '\n' +
"故障点:" + ex.StackTrace.Substring(ex.StackTrace.LastIndexOf("\\") + 1, ex.StackTrace.Length - ex.StackTrace.LastIndexOf("\\") - 1) + '\n' +
"错误提示:" + ex.Message);
return iFlag;
}
}
#region 写入返回处理数据
private void Deal_WriteDoTime(byte[] ValidData)
{
if (ValidData[0] == 0X01 && ValidData[1] == 0X09) //Write DO 带翻转时间 成功
{
m_WriteDataLen = 1;
m_WriteData = new byte[1];
m_WriteData[0] = ValidData[4];
}
else if (ValidData[0] == 0X01 && ValidData[1] == 0X07) //Write DO 带时间成功
{
m_WriteDataLen = 1;
m_WriteData = new byte[1];
m_WriteData[0] = ValidData[4];
}
else if (ValidData[0] == 0X01 && ValidData[1] == 0X05) //Write DO 成功
{
m_WriteDataLen = 1;
m_WriteData = new byte[1];
m_WriteData[0] = ValidData[4];
}
else
{
m_WriteDataLen = 0;
}
//LogService.Instance.Debug("带翻转时间写入DO" + ValidData[4]);
m_WriteSem.Release();
}
#endregion
#endregion
#region 心跳函数
public byte Device_SendHeartPack()
{
byte iResult = 0;
try
{
//LogService.Instance.Debug("函数调用:Device_SendHeartPack");
//m_GlobalSem.WaitOne(-1, false);
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_Data1 = new byte[1];
pMessagePack.m_Data2 = new byte[1];
//获取当前输入通道状态
//pMessagePack.m_FunctionCode = 0x02;
pMessagePack.m_FunctionCode = 0x04;
pMessagePack.m_Channel2 = 0x05;
pMessagePack.m_Data1[0] = 0x00;
pMessagePack.m_Data2[0] = 0x01;
//m_GetHeartSem.WaitOne(1, false);
if (m_ICommunicateService != null)
{
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
{
if (m_GetHeartSem.WaitOne(1000, false)) //等待结果,并取结果返回。
{
if (m_GetHeartSuccessful)
{
iResult = 1; //通讯连接和读写器都正常
}
else
{
iResult = 2; //通讯连接和读写器都正常
}
//if (m_GetHeartSuccessful) //有数据,正常
//{
// //LogService.Instance.Info("Device_SendHeartPack Channel is: " + StringChange.bytesToHexStr(m_ReadHeartData, m_ReadHeartData.Length));
// //LogService.Instance.Info("发送心跳包正常。");
// //m_ReadHeartDataLen = 0;
// iResult = 1; //通讯连接和读写器都正常
//}
//else
//{
// //m_ReadHeartDataLen = 0;
// LogService.Instance.Error("Device_SendHeartPack 失败,返回的通道不是08");
// iResult = 2;
//}
}
else //超时
{
iResult = 2;
//Device_Destroy();
//if (m_GetHeartSuccessful) //有数据,正常
//{
// iResult = 1; //通讯连接和读写器都正常
//}
//else
//{
// //LogService.Instance.Info("发送心跳报文超时。");
// iResult = 2; //通讯连接器正常,读写器故障
//}
};
}
else
{
//通讯连接器失败或网络故障
LogInfo.Info("发送心跳报文失败,设备通讯故障。");
//Device_Destroy();
iResult = 3;
}
}
else
{
iResult = 3;
}
}
catch (Exception ex)
{
LogInfo.Info("Device_SendHeartPack" + ex.Message);
iResult = 3;
}
//finally
//{
// m_GlobalSem.Release();
//}
m_GetHeartSuccessful = false;
return iResult;
}
#endregion
#region 读取函数
public UInt16 Device_Read(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, ref Byte[] pReadData, byte Antenna, int ReadTimes)
{
UInt16 iResult = 0;
try
{
//m_GlobalSem.WaitOne(-1, false);
//LogService.Instance.Info("函数调用:Device_Read 开始:");
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_Data1 = new byte[1];
pMessagePack.m_Data2 = new byte[1];
pMessagePack.m_FunctionCode = 0x02;
pMessagePack.m_Data1[0] = 0x00;
pMessagePack.m_Data2[0] = 0x01;
//m_ReadSem.Release(1);
m_ReadSem.WaitOne(1, false);
m_ReadDataLen = 0;
Thread.Sleep(2000);
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
{
if (m_ReadSem.WaitOne(2000, false)) //等待结果,并取结果返回。
{
if (m_ReadDataLen > 0) //有数据,正常
{
if (Antenna <= 4)
{
string str = Convert.ToString(Convert.ToInt32(m_ReadData[0]), 2).PadLeft(8, '0');
string str2 = StringChange.ArrayReverse(str);
string[] items = new string[8];
for (int i = 0; i < items.Length; i++)
{
items[i] = str2[i].ToString();
}
if (items[Antenna - 1] == "0")
{
m_ReadData[0] = 0X00;
}
else if (items[Antenna - 1] == "1")
{
m_ReadData[0] = 0XFF;
}
}
else if (Antenna > 4)
{
string str = Convert.ToString(Convert.ToInt32(m_ReadData[0]), 2).PadLeft(8, '0');
string str2 = StringChange.ArrayReverse(str);
//string str3 = str.Substring(0,4);
string[] items = new string[8];
for (int i = 0; i < items.Length; i++)
{
items[i] = str2[i].ToString();
}
if (items[Antenna - 1] == "0")
{
m_ReadData[0] = 0X00;
}
else if (items[Antenna - 1] == "1")
{
m_ReadData[0] = 0XFF;
}
}
//if ((m_ReadData[0] == 01 && Antenna ==1) || (m_ReadData[0] == 02 && Antenna == 2)|| (m_ReadData[0] == 04 && Antenna == 3)|| (m_ReadData[0] == 08 && Antenna == 4))
//{
// m_ReadData[0] = 0xFF;
//}
//else if (m_ReadData[0] == 00)
//{
// m_ReadData[0] = 0x00;
//}
pReadData = new byte[m_ReadDataLen];
Array.Copy(m_ReadData, 0, pReadData, 0, m_ReadDataLen);
iResult = m_ReadDataLen;
LogInfo.Info("Device_Read Data is: " + StringChange.bytesToHexStr(pReadData, pReadData.Length));
m_ReadDataLen = 0;
}
else
{
m_ReadDataLen = 0;
LogInfo.Info("Device_Read失败,返回长度为0");
iResult = 0;
}
}
else //超时
{
LogInfo.Info("Device_Read失败,超时未返回");
iResult = 0;
}
}
else
{
LogInfo.Info("发送读取命令失败");
iResult = 0;
}
}
catch (Exception ex)
{
LogInfo.Info("读取数据异常:" + ex.Message);
iResult = 0;
}
//finally
//{
// m_GlobalSem.Release();
//}
return iResult;
}
#endregion
#region 根据天线号写单个标签数据
public UInt16 Device_Write(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, Byte[] pWriteData, byte Antenna)
{
UInt16 iResult = 0;
try
{
//m_GlobalSem.WaitOne(-1, false);
//LogService.Instance.Info("函数调用:Device_Write 开始: ");
MessagePack pMessagePack = new MessagePack();
if (Membank == G2MemBank.TID)//控制 单个输出 打开 时间
{
pMessagePack.m_Data1 = new byte[2];
pMessagePack.m_Data2 = new byte[2];
//pMessagePack.m_BeginChar = 0x01;
pMessagePack.m_FunctionCode = 0x07;
//pMessagePack.m_Channel1 = 0x00;
pMessagePack.m_Channel2 = (byte)(Antenna + 4);
pMessagePack.m_Data1[0] = 0xFF;
pMessagePack.m_Data1[1] = 0x00;
//Array.Copy(pWriteData,0, pMessagePack.m_Data2,0, pWriteData.Length);
//Array.Copy(pWriteData, 1, pMessagePack.m_Data2, 1, pWriteData.Length);
pMessagePack.m_Data2[0] = pWriteData[0];
pMessagePack.m_Data2[1] = pWriteData[1]; //设置时间,单位秒
}
else if (Membank == G2MemBank.USER)//控制 单个 输出 翻转 时间 优先级高于单个 打开 功能 0x05 码
{
pMessagePack.m_Data1 = new byte[2];
pMessagePack.m_Data2 = new byte[2];
//pMessagePack.m_BeginChar = 0x01;
pMessagePack.m_FunctionCode = 0x09;
//pMessagePack.m_Channel1 = 0x00;
pMessagePack.m_Channel2 = (byte)(Antenna + 4);
pMessagePack.m_Data1[0] = pWriteData[0];
pMessagePack.m_Data1[1] = pWriteData[1];
//Array.Copy(pWriteData,0, pMessagePack.m_Data2,0, pWriteData.Length);
//Array.Copy(pWriteData, 1, pMessagePack.m_Data2, 1, pWriteData.Length);
pMessagePack.m_Data2[0] = pWriteData[2];
pMessagePack.m_Data2[1] = pWriteData[3]; //设置时间,单位秒
}
else
{
pMessagePack.m_Data1 = new byte[1];
pMessagePack.m_Data2 = new byte[1];
pMessagePack.m_FunctionCode = 0x05;
pMessagePack.m_Channel2 = (byte)(Antenna + 4); //通道号地址高 0005H 表示第1 路输 出 DO1
if (Antenna == 0)
{
pMessagePack.m_Channel2 = (byte)(Antenna + 5); //如果天线号默认是0则从第一路开始
}
//pMessagePack.m_PackType = Convert.ToByte((int)Membank);
pMessagePack.m_Data1[0] = pWriteData[0];
pMessagePack.m_Data2[0] = 0x00;
}
m_WriteSem.WaitOne(1, false);
m_WriteDataLen = 0;
Thread.Sleep(100);
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
{
iResult = 1;
if (m_WriteSem.WaitOne(500, false)) //等待结果,并取结果返回。
{
if (m_WriteDataLen > 0) //有数据,正常
{
pWriteData = new byte[m_WriteDataLen];
Array.Copy(m_WriteData, 0, pWriteData, 0, m_WriteDataLen);
iResult = m_WriteDataLen;
LogInfo.Info("Device_Write Data is: " + StringChange.bytesToHexStr(pWriteData, pWriteData.Length) + " ;写入成功。");
}
else
{
LogInfo.Info("Device_Write,返回长度为0");
iResult = 0;
}
}
else //超时
{
LogInfo.Info("Device_Write失败,超时未返回");
iResult = 0;
}
}
else
{
LogInfo.Info("发送写入命令失败");
iResult = 0;
}
}
catch (Exception ex)
{
LogInfo.Info("写入数据异常:" + ex.Message);
iResult = 0;
}
//finally
//{
// m_GlobalSem.Release();
//}
m_WriteDataLen = 0;
return iResult;
}
#endregion
#region 未实现的函数
public bool Device_BeginIdentify(byte Antenna, int timeout, bool autoRead, int num)
{
return true;
}
public bool Device_StopIdentify(byte Antenna)
{
bool bResult = false;
try
{
LogInfo.Info("函数调用:Device_StopIdentify");
MessagePack pMessagePack = new MessagePack();
if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
{
if (m_StopSem.WaitOne(200, false)) //等待结果,并取结果返回。
{
bResult = true;
}
else //超时
{
bResult = false;
}
}
else
{
LogInfo.Info("发送停止连续识别命令失败:");
bResult = false;
}
}
catch (Exception ex)
{
LogInfo.Info("发送停止连续识别命令异常:" + ex.Message);
bResult = false;
}
return bResult;
}
public string Device_GetOneIdentifyData(Byte Antenna, UInt16 Timedout)
{
return "";
}
public string Device_GetOneIdentifyData_Finish(byte Antenna, ushort Timedout)
{
return "";
}
public Byte Device_GetOneIdentifyData(ref Byte[] pReadData, Byte Antenna, UInt16 Timedout, int ReadCounts)
{
return 0;
}
public Byte Device_GetOneIdentifyData_Finish(ref byte[] pReadData, byte Antenna, ushort Timedout)
{
return 0;
}
private Mutex mut2 = new Mutex();
public ushort Device_GetReportData(ref byte[] pReadData, Byte Antenna, UInt32 Timedout)
{
mut2.WaitOne();
byte[] pTemp = null;
byte iReadLen = 0;
if ((iReadLen = Device_GetOneIdentifyData(ref pTemp, Antenna, (UInt16)Timedout, 5)) > 0)
{
LogInfo.Info("Device_GetReportData获取自报数据" + "数据长度" + iReadLen);
pReadData = new byte[iReadLen + 1];
pReadData[0] = iReadLen;
Array.Copy(pTemp, 0, pReadData, 1, iReadLen);
mut2.ReleaseMutex();
return (ushort)(iReadLen + 1);
}
else
{
mut2.ReleaseMutex();
return 0;
}
}
private Mutex mut3 = new Mutex();
public bool Device_SetRf(int iDbi, byte Antenna, WriteOrRead RorW)
{
return true;
}
//该函数不实现了
public ushort Device_GetIdentifyData(ref byte[] pReadData, byte Antenna)
{
return 0;
}
public bool Device_WriteAlarmLight(int port, UInt16 Timedout)
{
throw new NotImplementedException();
}
public List<TagInfo> Device_GetAllIdentifyData(byte Antenna, ushort Timedout, int ReadCounts)
{
throw new NotImplementedException();
}
#endregion
}
}