From 99b7c84e8fe2c43a717fb55a6ba215bb10efa05c Mon Sep 17 00:00:00 2001 From: wenjy Date: Wed, 31 Jan 2024 17:04:59 +0800 Subject: [PATCH] =?UTF-8?q?add=20-=20=E6=B7=BB=E5=8A=A0RFID=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SlnMesnac.Config/AppConfig.cs | 15 +- SlnMesnac.Config/RfidConfig.cs | 30 ++ SlnMesnac.Model/dto/TagInfo.cs | 17 + SlnMesnac.Plc/PlcPool.cs | 1 - SlnMesnac.Rfid/Dto/MessagePack.cs | 9 + SlnMesnac.Rfid/Enum/RecvState.cs | 21 + SlnMesnac.Rfid/Factory/RflyFactory.cs | 461 ++++++++++++++++++ SlnMesnac.Rfid/RfidAbsractFactory.cs | 27 + SlnMesnac.Rfid/RfidPool.cs | 90 ++++ SlnMesnac.Rfid/RfidSetup.cs | 23 + SlnMesnac.Rfid/SlnMesnac.Rfid.csproj | 14 + .../SlnMesnac.TouchSocket.csproj | 2 +- SlnMesnac.TouchSocket/TcpServer.cs | 17 +- SlnMesnac.WPF/SlnMesnac.WPF.csproj | 1 + SlnMesnac.WPF/Startup.cs | 7 + .../ViewModel/MainWindowViewModel.cs | 6 +- SlnMesnac.WPF/appsettings.json | 16 + SlnMesnac.sln | 6 + 18 files changed, 745 insertions(+), 18 deletions(-) create mode 100644 SlnMesnac.Config/RfidConfig.cs create mode 100644 SlnMesnac.Model/dto/TagInfo.cs create mode 100644 SlnMesnac.Rfid/Dto/MessagePack.cs create mode 100644 SlnMesnac.Rfid/Enum/RecvState.cs create mode 100644 SlnMesnac.Rfid/Factory/RflyFactory.cs create mode 100644 SlnMesnac.Rfid/RfidAbsractFactory.cs create mode 100644 SlnMesnac.Rfid/RfidPool.cs create mode 100644 SlnMesnac.Rfid/RfidSetup.cs create mode 100644 SlnMesnac.Rfid/SlnMesnac.Rfid.csproj diff --git a/SlnMesnac.Config/AppConfig.cs b/SlnMesnac.Config/AppConfig.cs index 47e949a..fac4e8b 100644 --- a/SlnMesnac.Config/AppConfig.cs +++ b/SlnMesnac.Config/AppConfig.cs @@ -14,16 +14,6 @@ namespace SlnMesnac.Config /// public string logPath { get; set; } - /// - /// MCS 开仓地址 - /// - public string mcsOpenAddr { get; set; } - - /// - /// CWSS 开仓地址 - /// - public string cwssOpenAddr { get; set; } - /// /// Sql连接配置 /// @@ -34,6 +24,11 @@ namespace SlnMesnac.Config /// public List plcConfig { get; set; } + /// + /// RFID连接配置 + /// + public List rfidConfig { get; set; } + public AppConfig Value => this; } } diff --git a/SlnMesnac.Config/RfidConfig.cs b/SlnMesnac.Config/RfidConfig.cs new file mode 100644 index 0000000..1e1b98c --- /dev/null +++ b/SlnMesnac.Config/RfidConfig.cs @@ -0,0 +1,30 @@ +namespace SlnMesnac.Config +{ + public class RfidConfig + { + /// + /// 配置ID + /// + public int configId { get; set; } + + /// + /// 设备 IP + /// + public string equipIp { get; set; } + + /// + /// 设备 Port + /// + public int equipPort { get; set; } + + /// + /// 设备 Key + /// + public string equipKey { get; set; } + + /// + /// 是否启用 + /// + public bool isFlage { get; set; } + } +} \ No newline at end of file diff --git a/SlnMesnac.Model/dto/TagInfo.cs b/SlnMesnac.Model/dto/TagInfo.cs new file mode 100644 index 0000000..dbe04de --- /dev/null +++ b/SlnMesnac.Model/dto/TagInfo.cs @@ -0,0 +1,17 @@ +using System; + +namespace SlnMesnac.Model.dto +{ + public class TagInfo + { + public byte[] PC = new byte[2]; + public int Count { get; set; } + public int RSSI{ get; set; } + public int Antana{ get; set; } + public byte[] EPC{ get; set; } + public byte[] Data{ get; set; } + public string PCstring = (string) null; + public string EPCstring = (string) null; + public DateTime Time{ get; set; } + } +} \ No newline at end of file diff --git a/SlnMesnac.Plc/PlcPool.cs b/SlnMesnac.Plc/PlcPool.cs index 55bb2c4..6a89ff8 100644 --- a/SlnMesnac.Plc/PlcPool.cs +++ b/SlnMesnac.Plc/PlcPool.cs @@ -88,7 +88,6 @@ namespace SlnMesnac.Plc if (connectResult) { _logger.LogInformation($"PLC:{ip}:{port};连接成功,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); - keyValuePairs.Add(key, _plc); if (!keyValuePairs.ContainsKey(key)) { keyValuePairs.Add(key, _plc); diff --git a/SlnMesnac.Rfid/Dto/MessagePack.cs b/SlnMesnac.Rfid/Dto/MessagePack.cs new file mode 100644 index 0000000..8ef347a --- /dev/null +++ b/SlnMesnac.Rfid/Dto/MessagePack.cs @@ -0,0 +1,9 @@ +namespace SlnMesnac.Rfid.Dto +{ + public class MessagePack + { + //public byte m_beginChar1 = 0xBB; //开始包 + public byte[] m_pData = null; //发送数据 + //public byte m_EndChar1 = 0x0D; //结束包 + } +} \ No newline at end of file diff --git a/SlnMesnac.Rfid/Enum/RecvState.cs b/SlnMesnac.Rfid/Enum/RecvState.cs new file mode 100644 index 0000000..68c253c --- /dev/null +++ b/SlnMesnac.Rfid/Enum/RecvState.cs @@ -0,0 +1,21 @@ +namespace SlnMesnac.Rfid.Enum +{ + public enum RecvState + { + //RFly-I160 返回数据 BB DD 00 01 40 41 0D + WaitingBeginChar1_State = 1, //等待接收帧同步字符1 0xBB + WaitingBeginChar2_State = 2, //等待接收帧同步字符2 0xDD + WaitingForBarcodeLength_State = 3, //等待条码长度不固定 + WaitingForCode_State = 4, //等待指令编号Code 0x02 + WaitingForStus_State = 5, //等待接受状态码 0x00 + WaitingForTagCount_State = 6, //等待接受标签组数不固定 + WaitingForCount_State = 7, //等待接收第一组标签读取次数 0x01 + WaitingForRSSI_State = 8, //等待接收读取信号强度 0xCB + WaitingForAnt_State = 9, //等待接收天线端口 0x01 + WaitingForPC1_State = 10, //等待接收EPC区域 0x00 + WaitingForPC2_State = 11, //等待接收EPC区域 0x00 + WaitingForData_State = 12, //等待接收数据字符 + WaitingForXor_State = 13, //等待比对校验位 + WaitingForEndChar_State = 14, //等待接收尾字符 0x0D + } +} \ No newline at end of file diff --git a/SlnMesnac.Rfid/Factory/RflyFactory.cs b/SlnMesnac.Rfid/Factory/RflyFactory.cs new file mode 100644 index 0000000..b193e00 --- /dev/null +++ b/SlnMesnac.Rfid/Factory/RflyFactory.cs @@ -0,0 +1,461 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using SlnMesnac.Common; +using SlnMesnac.Model.dto; +using SlnMesnac.Rfid.Dto; +using SlnMesnac.Rfid.Enum; +using TouchSocket.Core; +using TouchSocket.Sockets; + +namespace SlnMesnac.Rfid.Factory +{ + public class RflyFactory:RfidAbsractFactory + { + private ILogger _logger; + private readonly TcpClient _tcpClient = new TcpClient(); + private readonly StringChange _stringChange; + + public RflyFactory(ILogger logger,StringChange stringChange) + { + _logger = logger; + _stringChange = stringChange; + } + + /// + /// 建立连接 + /// + /// + /// + /// + /// + public override bool Connect(string ip, int port) + { + try + { + _tcpClient.Setup(new TouchSocketConfig().SetRemoteIPHost($"{ip}:{port}")); + _tcpClient.Connect(); + return true; + } + catch (Exception e) + { + throw new InvalidOperationException($"设备连接异常:{e.Message}"); + } + } + + /// + /// 按时间段盘点 + /// + /// + /// + /// + public override List TimePeriodRead(int timeout = 5000) + { + byte[] u16byte = new byte[2]; + byte[] bCRC = new byte[4]; + try + { + #region 指令封装 + MessagePack pMessagePack = new MessagePack(); + pMessagePack.m_pData = new byte[8]; + pMessagePack.m_pData[0] = 0xAA; + pMessagePack.m_pData[1] = 0x55; + pMessagePack.m_pData[2] = 0x02; + pMessagePack.m_pData[3] = 0x02; + u16byte = BitConverter.GetBytes(timeout); //超时时间 + u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前 + Array.Copy(u16byte, 0, pMessagePack.m_pData, 4, 2); + Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 4); + pMessagePack.m_pData[6] = _stringChange.CalculateVerify(bCRC, bCRC.Length); + pMessagePack.m_pData[7] = 0x0D; + #endregion + + var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions() + { + FilterFunc = response => + { + return true; + } + }); + + byte[] reciveBuffer = waitClient.SendThenReturn(pMessagePack.m_pData, timeout); + + _logger.LogInformation($"接收原始报文:{_stringChange.bytesToHexStr(reciveBuffer,reciveBuffer.Length)}"); + + byte[] resultBuffer = PareReceiveBufferData(reciveBuffer,reciveBuffer.Length); + + List tagInfoList = Device_DealTagInfoList(resultBuffer); + + return tagInfoList; + } + catch (Exception e) + { + throw new InvalidOperationException($"按时间段盘点异常:{e.Message}"); + } + } + + #region 标签解析 + + /// + /// 状态机函数 + /// + /// + /// + /// + /// + private byte[] PareReceiveBufferData(byte[] buffer, int iLen) + { + RecvState enumRecvState = RecvState.WaitingBeginChar1_State; + int m_iPosition = 0; + UInt16 m_iFullMessageLength = 0; + int iBarcodeLength = 0;//条码长度 + ArrayList m_FrecvData = new ArrayList(); + byte m_iVerify = 0; + try + { + var bufferStr = _stringChange.bytesToHexStr(buffer, iLen); + byte[] m_szFullMessage = new byte[iLen]; + for (int i = 0; i < iLen; i++) + { + switch (enumRecvState) + { + case RecvState.WaitingBeginChar1_State: //开始接受数据帧1 0xBB + Array.Clear(m_szFullMessage, 0, iLen);//清空为0 + if (buffer[i] == 0xBB) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingBeginChar2_State; + } + else + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingBeginChar2_State: //开始接受数据帧1 0xDD + if (buffer[i] == 0xDD) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForBarcodeLength_State; + } + else + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingForBarcodeLength_State: //开始接受数据长度(TagCount - EPC) + m_szFullMessage[m_iPosition] = buffer[i]; + iBarcodeLength = buffer[i]; //单组标签:18;两组标签:35 + m_iPosition++; + enumRecvState = RecvState.WaitingForCode_State; + break; + + case RecvState.WaitingForCode_State: //开始接受指令编号 + if (buffer[i] == 0x02) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForStus_State; + } + else if (buffer[i] == 0x90) // 如果是心跳BB DD 01 90 00 1F 8E 0D + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForEndChar_State; + } + else if (buffer[i] == 0xBF) // 如果是心跳BB DD 04 BF 00 00 00 F9 0B 49 0D + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForEndChar_State; + } + else + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingForStus_State: //开始接受状态码 + if (buffer[i] == 0x00) + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + enumRecvState = RecvState.WaitingForTagCount_State; + } + else if (buffer[i] == 0x40) + { + m_szFullMessage[m_iPosition] = buffer[i]; + //LogService.Instance.Debug("RFU620等待接受WaitingForEndChar_State:Noread"); + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + m_iPosition = 0; + i = iLen; + enumRecvState = RecvState.WaitingBeginChar1_State; + //LogService.Instance.Debug("RFly-I160状态机结束。"); + } + break; + case RecvState.WaitingForTagCount_State: //开始接受标签组数 + Array.Copy(buffer, i, m_szFullMessage, m_iPosition, iBarcodeLength);//m_iPosition = 5 + byte[] tempData = new byte[iBarcodeLength]; + Array.Clear(tempData, 0, iBarcodeLength); + Array.Copy(buffer, i, tempData, 0, iBarcodeLength); + m_iPosition = m_iPosition + iBarcodeLength; //m_iPosition = 39 + i = i + iBarcodeLength - 1; //i = 39 + enumRecvState = RecvState.WaitingForXor_State; + break; + case RecvState.WaitingForXor_State: //开始比对校验位 Rfly160 + byte[] m_CRCVerify = new byte[1024]; //此数组用于校验位计算 + Array.Clear(m_CRCVerify, 0, m_CRCVerify.Length); + Array.Copy(m_szFullMessage, 2, m_CRCVerify, 0, iBarcodeLength + 3); //校验位计算是从Length - EPC 结束 + m_szFullMessage[m_iPosition] = buffer[i]; + m_iVerify = m_szFullMessage[m_iPosition]; + if (m_iVerify == _stringChange.CalculateVerify(m_CRCVerify, m_CRCVerify.Length)) + { + m_iPosition++; + enumRecvState = RecvState.WaitingForEndChar_State; + } + else //如果校验不成功 + { + m_iFullMessageLength = 0; + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + break; + case RecvState.WaitingForEndChar_State: + if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x00 && buffer[3] != 0x90) //此处为Noread数据显示 + { + m_szFullMessage[0] = 0xBB; + m_szFullMessage[1] = 0xDD; + m_szFullMessage[2] = 0x00; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + m_iPosition = 0; + i = iLen; + enumRecvState = RecvState.WaitingBeginChar1_State; + } + else if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x04 && buffer[3] == 0xBF) + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 11); + i = 11; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + i = iLen; + } + else if (buffer[i] == 0x00) //获取温度 + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 8); + i = 8; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + i = iLen; + } + else if (buffer[i] == 0x11) + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 7); + i = 7; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + } + else if (buffer[i] == 0x01) + { + Array.Copy(buffer, 0, m_szFullMessage, 0, 8); + i = 8; + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + } + else + { + m_szFullMessage[m_iPosition] = buffer[i]; + m_iPosition++; + if (buffer[i] == 0x0D) + { + lock (m_FrecvData) + { + m_FrecvData.Add(m_szFullMessage); + } + } + } + m_iPosition = 0; + enumRecvState = RecvState.WaitingBeginChar1_State; + break; + } + } + + return m_szFullMessage; + } + catch (Exception e) + { + throw new InvalidOperationException($"状态机逻辑处理异常:{e.Message}"); + } + } + + private Mutex mutauto = new Mutex(); + /// + /// 解析函数 + /// + /// + /// + /// + public List Device_DealTagInfoList(byte[] AutoDealReportData) + { + List tagInfoList = new List(); + byte[] bResultEPC_Data = new byte[14]; + byte[] m_AutoReadEPC = null; + int m_readEPCDataLen = 0; + try + { + mutauto.WaitOne(); + int iFirstCountPos = 6; //第一次读取标签次数位置 + int iFirstRSSIPos = 7; //第一次读取标签强度位置 + int iFirstAnt = 8; + int iFirstPC = 9; //第一次读取标签天线位置 + int iFirstLeftBarcketPos = 11;//EPC数据起始位置 + UInt16 tempDataCount = 0; + int tempDataRSSI = 0; + UInt16 tempDataANT = 0; + int iBarcodeGroupCount = Convert.ToInt32(AutoDealReportData[5].ToString()); //标签组数 + int iBarcodeLength = 16; //标签长度 + int iCommonSecondFlag = 0; + for (int j = 0; j < iBarcodeGroupCount; j++) + { + TagInfo tag = new TagInfo(); + byte[] tempPCByte = new byte[2]; //取出PC + Array.Clear(tempPCByte, 0, 2); + Array.Copy(AutoDealReportData, iFirstPC, tempPCByte, 0, 2); + + int pc = Convert.ToInt32(tempPCByte[0].ToString("X")); + int epcLength = EPCLengthByPC(pc); + iBarcodeLength = epcLength; + + byte[] tempDataByte = new byte[epcLength]; + Array.Clear(tempDataByte, 0, iBarcodeLength); + Array.Copy(AutoDealReportData, iFirstLeftBarcketPos, tempDataByte, 0, iBarcodeLength); + + byte[] tempCountByte = new byte[1]; //取出标签次数 + Array.Clear(tempCountByte, 0, 1); + Array.Copy(AutoDealReportData, iFirstCountPos, tempCountByte, 0, 1); + tempDataCount = tempCountByte[0]; + + byte[] tempRSSIByte = new byte[1]; //取出标签强度 + Array.Clear(tempRSSIByte, 0, 1); + Array.Copy(AutoDealReportData, iFirstRSSIPos, tempRSSIByte, 0, 1); + + tempDataRSSI = _stringChange.HexStringToNegative(_stringChange.bytesToHexStr(tempRSSIByte, 1)); + + #region add by wenjy 20220829 取出天线号 + byte[] tempAntByte = new byte[1]; //取出天线号 + Array.Clear(tempAntByte, 0, 1); + Array.Copy(AutoDealReportData, iFirstAnt, tempAntByte, 0, 1); + tempDataANT = tempAntByte[0]; + #endregion + + tag.Count = tempDataCount; + tag.RSSI = tempDataRSSI; + tag.EPC = tempDataByte; + + if (pc == 24) + { + tag.EPCstring = _stringChange.bytesToHexStr(tempDataByte, tempDataByte.Length).Substring(0, 7); + } + else + { + tag.EPCstring = Encoding.ASCII.GetString(tempDataByte); + } + + tag.PC = tempPCByte; + tag.Antana = tempDataANT; + tagInfoList.Add(tag); + int iBarcodeListLen = tagInfoList.Count; //特别注意,必须这样,要不然会多一条数据 + + iFirstCountPos = iFirstCountPos + iBarcodeLength + 5; //次数 + iFirstRSSIPos = iFirstCountPos + 1; //强度 + iFirstAnt = iFirstRSSIPos + 1; //天线 + iFirstPC = iFirstAnt + 1; + iFirstLeftBarcketPos = iFirstLeftBarcketPos + iBarcodeLength + 5; + + _logger.LogInformation("----函数调用:Device_DealTagInfoList 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + tag.EPCstring + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]"); + iCommonSecondFlag++; + if (iCommonSecondFlag == iBarcodeGroupCount) + { + mutauto.ReleaseMutex(); + _logger.LogInformation("《《《返回标签数据!"); + return tagInfoList; + } + } + return tagInfoList; + } + catch (Exception ex) + { + mutauto.ReleaseMutex(); + throw new InvalidOperationException($"Device_AutoDealContent 自动处理函数异常:{ex.Message}"); + } + } + + /// + /// 根据PC获取EPC长度 + /// + /// + /// + private int EPCLengthByPC(int pcValue) + { + int epcLength = 0; + if (pcValue >= 10 && pcValue < 20) + { + epcLength = 4; + } + else if (pcValue >= 20 && pcValue < 30) + { + epcLength = 8; + } + else if (pcValue >= 30 && pcValue < 40) + { + epcLength = 12; + } + else if (pcValue >= 40 && pcValue < 50) + { + epcLength = 16; + } + else if (pcValue >= 50 && pcValue < 60) + { + epcLength = 20; + } + else if (pcValue >= 60 && pcValue < 70) + { + epcLength = 24; + } + else if (pcValue >= 70 && pcValue < 80) + { + epcLength = 28; + } + else if (pcValue >= 80 && pcValue < 90) + { + epcLength = 30; + } + return epcLength; + } + + #endregion + } +} \ No newline at end of file diff --git a/SlnMesnac.Rfid/RfidAbsractFactory.cs b/SlnMesnac.Rfid/RfidAbsractFactory.cs new file mode 100644 index 0000000..287a922 --- /dev/null +++ b/SlnMesnac.Rfid/RfidAbsractFactory.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using SlnMesnac.Model.dto; + +namespace SlnMesnac.Rfid +{ + /// + /// RFID抽象工厂 + /// + public abstract class RfidAbsractFactory + { + /// + /// 建立连接 + /// + /// + /// + /// + public abstract bool Connect(string ip, int port); + + /// + /// 按时间段盘点 + /// + /// + /// + public abstract List TimePeriodRead(int timeout = 5000); + } +} \ No newline at end of file diff --git a/SlnMesnac.Rfid/RfidPool.cs b/SlnMesnac.Rfid/RfidPool.cs new file mode 100644 index 0000000..c0ff660 --- /dev/null +++ b/SlnMesnac.Rfid/RfidPool.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; +using SlnMesnac.Config; +using SlnMesnac.Rfid.Factory; + +namespace SlnMesnac.Rfid +{ + public class RfidPool + { + private readonly ILogger _logger; + private readonly RflyFactory _rflyFactory; + private readonly AppConfig _appConfig; + + private Dictionary keyValuePairs = new Dictionary(); + + public RfidPool(RflyFactory rflyFactory,ILogger logger,AppConfig appConfig) + { + _rflyFactory = rflyFactory; + _logger = logger; + _appConfig = appConfig; + } + + /// + /// 初始化 + /// + public void Init() + { + + if (_appConfig.rfidConfig != null) + { + foreach (var item in _appConfig.rfidConfig) + { + if (item.isFlage) + { + try + { + RfidAbsractFactory absractFactory = _rflyFactory; + absractFactory.Connect(item.equipIp, item.equipPort); + _logger.LogInformation($"RFID:{item.equipIp}:{item.equipPort};连接成功,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); + var key = item.equipKey; + if (!keyValuePairs.ContainsKey(key)) + { + keyValuePairs.Add(key, absractFactory); + } + else + { + keyValuePairs[key] = absractFactory; + } + } + catch (Exception e) + { + _logger.LogError($"RFID设备:{item.equipKey}初始化异常:{e.Message}"); + } + } + } + } + else + { + _logger.LogInformation("PLC配置信息为空"); + } + } + + /// + /// 获取RFID设备 + /// + /// + /// + public RfidAbsractFactory GetRfidByKey(string key) + { + try + { + return keyValuePairs[key]; + } + catch (Exception e) + { + throw new ArgumentException($"根据RFID Key获取连接信息异常:{e.Message}"); ; + } + } + + /// + /// 获取所有PLC信息 + /// + /// + public Dictionary GetAll() + { + return keyValuePairs; + } + } +} \ No newline at end of file diff --git a/SlnMesnac.Rfid/RfidSetup.cs b/SlnMesnac.Rfid/RfidSetup.cs new file mode 100644 index 0000000..1d24dea --- /dev/null +++ b/SlnMesnac.Rfid/RfidSetup.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using SlnMesnac.Rfid.Factory; + +namespace SlnMesnac.Rfid +{ + public static class RfidSetup + { + public static void AddRfidSetup(this IServiceCollection services) + { + services.AddSingleton(); + + services.AddSingleton(); + } + + public static IApplicationBuilder UseRfidExtensions(this IApplicationBuilder app) + { + var pool = app.ApplicationServices.GetService(); + pool.Init(); + return app; + } + } +} \ No newline at end of file diff --git a/SlnMesnac.Rfid/SlnMesnac.Rfid.csproj b/SlnMesnac.Rfid/SlnMesnac.Rfid.csproj new file mode 100644 index 0000000..ac2b62d --- /dev/null +++ b/SlnMesnac.Rfid/SlnMesnac.Rfid.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.1 + enable + + + + + + + + + diff --git a/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj b/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj index 6943480..790191c 100644 --- a/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj +++ b/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj @@ -6,7 +6,7 @@ - + diff --git a/SlnMesnac.TouchSocket/TcpServer.cs b/SlnMesnac.TouchSocket/TcpServer.cs index 46c6239..af5774e 100644 --- a/SlnMesnac.TouchSocket/TcpServer.cs +++ b/SlnMesnac.TouchSocket/TcpServer.cs @@ -23,19 +23,26 @@ namespace SlnMesnac.TouchSocket { _service.Connecting = (client, e) => { _logger.LogInformation($"客户端{client.IP}正在接入服务"); + return EasyTask.CompletedTask; }; _service.Connected = (client, e) => { - _logger.LogInformation($"客户端{client.IP}接入服务成功,Id:{client.ID}"); + _logger.LogInformation($"客户端{client.IP}接入服务成功"); + return EasyTask.CompletedTask; }; _service.Disconnected = (client, e) => { - _logger.LogInformation($"客户端{client.IP}断开连接,Id:{client.ID}"); + _logger.LogInformation($"客户端{client.IP}断开连接"); + return EasyTask.CompletedTask; }; - _service.Received = (client, byteBlock, requestInfo) => + _service.Received = (client, e) => { //if (requestInfo is MyFixedHeaderRequestInfo myRequestInfo) //{ // string body = Encoding.UTF8.GetString(myRequestInfo.Body, 0, myRequestInfo.Body.Length); //} + //从客户端收到信息 + var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意:数据长度是byteBlock.Len + + return EasyTask.CompletedTask; }; _service.Setup(new TouchSocketConfig()//载入配置 @@ -47,8 +54,8 @@ namespace SlnMesnac.TouchSocket .ConfigurePlugins(a => { //自定义插件 - })) - .Start(); + })); + _service.Start(); _logger.LogInformation($"TcpServer启动成功,监听端口:{serverPort}"); } catch (Exception ex) diff --git a/SlnMesnac.WPF/SlnMesnac.WPF.csproj b/SlnMesnac.WPF/SlnMesnac.WPF.csproj index 79a3beb..38a951d 100644 --- a/SlnMesnac.WPF/SlnMesnac.WPF.csproj +++ b/SlnMesnac.WPF/SlnMesnac.WPF.csproj @@ -26,6 +26,7 @@ + diff --git a/SlnMesnac.WPF/Startup.cs b/SlnMesnac.WPF/Startup.cs index bbbf884..29c207e 100644 --- a/SlnMesnac.WPF/Startup.cs +++ b/SlnMesnac.WPF/Startup.cs @@ -15,6 +15,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using SlnMesnac.Mqtt; +using SlnMesnac.Rfid; using SlnMesnac.TouchSocket; namespace SlnMesnac.WPF @@ -61,6 +62,9 @@ namespace SlnMesnac.WPF //注册TouchSocket services.AddTouchSocketSetup(); + + //注册RFID + services.AddRfidSetup(); } /// @@ -80,6 +84,9 @@ namespace SlnMesnac.WPF //初始化PLC中间件 app.UsePlcExtensions(); + + //初始化RFID中间件 + app.UseRfidExtensions(); app.UseRouting(); diff --git a/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs b/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs index 57a6d3c..a15ed91 100644 --- a/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs +++ b/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs @@ -14,13 +14,14 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; +using SlnMesnac.Rfid; namespace SlnMesnac.WPF.ViewModel { public class MainWindowViewModel: ViewModelBase { private readonly ILogger _logger; - + private readonly RfidPool _rfidPool; #region 参数定义 /// /// PLC设备状态 @@ -86,6 +87,7 @@ namespace SlnMesnac.WPF.ViewModel { _logger = App.ServiceProvider.GetService>(); + _rfidPool = App.ServiceProvider.GetService(); ControlOnClickCommand = new RelayCommand(obj => ControlOnClick(obj)); FormControlCommand = new RelayCommand(x => FormControl(x)); @@ -125,6 +127,8 @@ namespace SlnMesnac.WPF.ViewModel // 最小化当前窗口 case "Minimized": + var info = _rfidPool.GetRfidByKey("test2"); + info.TimePeriodRead(); Application.Current.MainWindow.WindowState = WindowState.Minimized; break; default: diff --git a/SlnMesnac.WPF/appsettings.json b/SlnMesnac.WPF/appsettings.json index 7c20653..a1f2ad9 100644 --- a/SlnMesnac.WPF/appsettings.json +++ b/SlnMesnac.WPF/appsettings.json @@ -38,6 +38,22 @@ "plcKey": "cwss", "isFlage": false } + ], + "RfidConfig": [ + { + "configId": 1, + "equipIp": "127.0.0.1", + "equipPort": 6000, + "equipKey": "test1", + "isFlage": false + }, + { + "configId": 2, + "equipIp": "127.0.0.1", + "equipPort": 6009, + "equipKey": "test2", + "isFlage": true + } ] } } diff --git a/SlnMesnac.sln b/SlnMesnac.sln index 76dbfd5..1a63097 100644 --- a/SlnMesnac.sln +++ b/SlnMesnac.sln @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.TouchSocket", "Sl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Mqtt", "SlnMesnac.Mqtt\SlnMesnac.Mqtt.csproj", "{7D908FF5-88AE-42AB-A193-F2896EF44AB1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Rfid", "SlnMesnac.Rfid\SlnMesnac.Rfid.csproj", "{40D23A4B-8372-4145-936C-08AE63C6D1F9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -81,6 +83,10 @@ Global {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Release|Any CPU.Build.0 = Release|Any CPU + {40D23A4B-8372-4145-936C-08AE63C6D1F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40D23A4B-8372-4145-936C-08AE63C6D1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40D23A4B-8372-4145-936C-08AE63C6D1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40D23A4B-8372-4145-936C-08AE63C6D1F9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE