diff --git a/HighWayIot.Common/HighWayIot.Common.csproj b/HighWayIot.Common/HighWayIot.Common.csproj
new file mode 100644
index 0000000..d634007
--- /dev/null
+++ b/HighWayIot.Common/HighWayIot.Common.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {89A1EDD9-D79E-468D-B6D3-7D07B8843562}
+ Library
+ Properties
+ HighWayIot.Common
+ HighWayIot.Common
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {deabc30c-ec6f-472e-bd67-d65702fdaf74}
+ HighWayIot.Log4net
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Common/JsonChange.cs b/HighWayIot.Common/JsonChange.cs
new file mode 100644
index 0000000..cb8e067
--- /dev/null
+++ b/HighWayIot.Common/JsonChange.cs
@@ -0,0 +1,115 @@
+using HighWayIot.Log4net;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.Script.Serialization;
+using System.Xml.Linq;
+
+namespace HighWayIot.Common
+{
+ public class JsonChange
+ {
+
+ private static readonly Lazy lazy = new Lazy(() => new JsonChange());
+ public static JsonChange Instance
+ {
+ get
+ {
+ return lazy.Value;
+ }
+ }
+
+ private LogHelper log = LogHelper.Instance;
+
+ private JsonChange() { }
+
+ ///
+ /// Model 实体转json
+ ///
+ /// 可以是单个实体,也可是实体集(即:ToList())
+ ///
+ public string ModeToJson(object Model)
+ {
+ string str = "";
+ JavaScriptSerializer serializer = new JavaScriptSerializer();
+ try
+ {
+ str = serializer.Serialize(Model);
+ }
+ catch (Exception ex)
+ {
+ log.Error("Model转Json异常",ex);
+ }
+ return str;
+ }
+
+ ///
+ /// json实体转Model
+ ///
+ ///
+ ///
+ ///
+ public T JsonToMode(string jsonStr)
+ {
+ T info = default(T);
+ JavaScriptSerializer serializer = new JavaScriptSerializer();
+ try
+ {
+ info = serializer.Deserialize(jsonStr);
+ }
+ catch (Exception ex)
+ {
+ log.Error("Json转Model异常" ,ex);
+ }
+ return info;
+ }
+
+ ///
+ /// object转dictionary
+ ///
+ ///
+ ///
+ public Dictionary objectToDictionary(string jsonData)
+ {
+ Dictionary result = new Dictionary();
+
+ var inf = JsonConvert.DeserializeObject>(jsonData);
+
+ foreach (KeyValuePair item in inf)
+ {
+ if (item.Value != null)
+ {
+ var type = item.Value.GetType();
+ if (type == typeof(JObject))
+ {
+ var info = objectToDictionary(JsonConvert.SerializeObject(item.Value));
+ foreach (KeyValuePair ite in info)
+ {
+ result.Add(ite.Key, ite.Value);
+ }
+ continue;
+ }
+ else if (type == typeof(JArray))
+ {
+ JArray array = (JArray)item.Value;
+ var info = objectToDictionary(JsonConvert.SerializeObject(array[0]));
+ foreach (KeyValuePair ite in info)
+ {
+ result.Add(item.Key + ite.Key, ite.Value);
+ }
+ continue;
+ }
+ }
+
+ result.Add(item.Key, item.Value);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/HighWayIot.Common/MsgUtil.cs b/HighWayIot.Common/MsgUtil.cs
new file mode 100644
index 0000000..12a5e20
--- /dev/null
+++ b/HighWayIot.Common/MsgUtil.cs
@@ -0,0 +1,511 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Common
+{
+ ///
+ /// 工具类
+ ///
+ public sealed class MsgUtil
+ {
+
+ private static readonly Lazy lazy = new Lazy(() => new MsgUtil());
+
+ public static MsgUtil Instance
+ {
+ get
+ {
+ return lazy.Value;
+ }
+ }
+
+ private MsgUtil() { }
+
+ #region 数据解析公共方法
+ ///
+ /// 字节数组转换成结构体
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static object BytesToStruct(byte[] buf, int len, Type type)
+ {
+ object rtn;
+ IntPtr buffer = Marshal.AllocHGlobal(len);
+ Marshal.Copy(buf, 0, buffer, len);
+ try
+ {
+ rtn = Marshal.PtrToStructure(buffer, type);
+ Marshal.FreeHGlobal(buffer);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ return rtn;
+ }
+
+ public string StringToHexString(string s, Encoding encode)
+ {
+
+ byte[] b = encode.GetBytes(s); //按照指定编码将string编程字节数组
+ string result = string.Empty;
+ for (int i = 0; i < b.Length; i++) //逐字节变为16进制字符,以%隔开
+ {
+ result += "%" + Convert.ToString(b[i], 16);
+ }
+ return result;
+ }
+
+ ////
+ /// 结构体转byte数组
+ ///
+ /// 要转换的结构体
+ /// 转换后的byte数组
+ public static byte[] StructToBytes(object structObj)
+ {
+ //得到结构体的大小
+ int size = Marshal.SizeOf(structObj);
+ //创建byte数组
+ byte[] bytes = new byte[size];
+ //分配结构体大小的内存空间
+ IntPtr structPtr = Marshal.AllocHGlobal(size);
+ //将结构体拷到分配好的内存空间
+ Marshal.StructureToPtr(structObj, structPtr, false);
+ //从内存空间拷到byte数组
+ Marshal.Copy(structPtr, bytes, 0, size);
+ //释放内存空间
+ Marshal.FreeHGlobal(structPtr);
+ //返回byte数组
+ return bytes;
+ }
+
+
+ #endregion
+ #region 消息验证方法
+
+ ///
+ /// CS和校验
+ ///
+ ///
+ ///
+ public byte Check_CS(byte[] Abyte)
+ {
+ byte result = new byte();
+ try
+ {
+ int num = 0;
+ for (int i = 0; i < Abyte.Length; i++)
+ {
+ num = (num + Abyte[i]) % 256;
+ }
+ result = (byte)num;
+ }
+ catch
+ {
+ result = 0;
+ }
+ return result;
+ }
+
+ ///
+ /// BCC异或取反校验
+ ///
+ ///
+ ///
+ public string getBCC(byte[] data)
+ {
+ String ret = "";
+ byte[] BCC = new byte[1];
+ for (int i = 0; i < data.Length; i++)
+ {
+ BCC[0] = (byte)(BCC[0] ^ data[i]);
+ }
+ String hex = ((~BCC[0]) & 0xFF).ToString("X");//取反操作
+ if (hex.Length == 1)
+ {
+ hex = '0' + hex;
+ }
+ ret += hex.ToUpper();
+ return ret;
+ }
+
+ static int BytesToInt(byte[] b, int length)
+ {
+ int temp = 0;
+ for (int i = 0; i <= length - 1 && i < 4; i++)
+ {
+ temp += (int)(b[i] << (i * 8));
+ }
+ return temp;
+ }
+
+ public static byte[] CalculateVerify(byte[] pMessage, int iLength)
+ {
+ UInt16 i;
+ int iVerify = 0;
+
+ iVerify = pMessage[0];
+ for (i = 0; i < iLength - 1; i++)
+ {
+ iVerify = iVerify + pMessage[i + 1];
+ }
+ return BitConverter.GetBytes(Convert.ToUInt16(iVerify));
+ }
+ #endregion
+ public byte[] HexStrTorbytes(string strHex)//e.g. " 01 01" ---> { 0x01, 0x01}
+ {
+ strHex = strHex.Replace(" ", "");
+ if ((strHex.Length % 2) != 0)
+ strHex += " ";
+ byte[] returnBytes = new byte[strHex.Length / 2];
+ for (int i = 0; i < returnBytes.Length; i++)
+ returnBytes[i] = Convert.ToByte(strHex.Substring(i * 2, 2), 16);
+ return returnBytes;
+ }
+
+ ///
+ /// 将字符串强制转换成int,转换失败则返回0
+ ///
+ ///
+ ///
+ public int ParseToInt(string str)
+ {
+ int returnInt = 0;
+
+ if (str == null || str.Trim().Length < 1)
+ {
+ return returnInt;
+ }
+
+ if (int.TryParse(str, out returnInt))
+ {
+ return returnInt;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ public byte[] HexToString(string Str)
+ {
+ byte[] str = new byte[Str.Length / 2];
+ for (int i = 0; i < str.Length; i++)
+ {
+ int temp = Convert.ToInt32(Str.Substring(i * 2, 2), 16);
+ str[i] = (byte)temp;
+ }
+ return str;
+ }
+ public string ConverToString(byte[] data)
+ {
+ string str;
+ StringBuilder stb = new StringBuilder();
+ for (int i = 0; i < data.Length; i++)
+ {
+ if ((int)data[i] > 15)
+ {
+ stb.Append(Convert.ToString(data[i], 16).ToUpper()); //添加字符串
+ }
+ else //如果是小于0F需要加个零
+ {
+ stb.Append("0" + Convert.ToString(data[i], 16).ToUpper());
+ }
+ }
+ str = stb.ToString();
+ return str;
+ }
+
+ public string bytesToHexStr(byte[] bytes, int iLen)
+ {
+ StringBuilder sb = new StringBuilder();
+ if (bytes != null)
+ {
+ for (int i = 0; i < iLen; i++)
+ {
+ sb.Append(bytes[i].ToString("X2"));
+ }
+ }
+ return sb.ToString();
+ }
+
+ ///
+ /// 从十进制转换到十六进制
+ ///
+ ///
+ ///
+ public string Ten2Hex(string ten)
+ {
+ ulong tenValue = Convert.ToUInt64(ten);
+ ulong divValue, resValue;
+ string hex = "";
+ do
+ {
+ //divValue = (ulong)Math.Floor(tenValue / 16);
+
+ divValue = (ulong)Math.Floor((decimal)(tenValue / 16));
+
+ resValue = tenValue % 16;
+ hex = tenValue2Char(resValue) + hex;
+ tenValue = divValue;
+ }
+ while (tenValue >= 16);
+ if (tenValue != 0)
+ hex = tenValue2Char(tenValue) + hex;
+ return hex;
+ }
+
+ public static string tenValue2Char(ulong ten)
+ {
+ switch (ten)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ return ten.ToString();
+ case 10:
+ return "A";
+ case 11:
+ return "B";
+ case 12:
+ return "C";
+ case 13:
+ return "D";
+ case 14:
+ return "E";
+ case 15:
+ return "F";
+ default:
+ return "";
+ }
+ }
+ }
+
+ #region 消息公用的头尾
+
+ ///
+ /// 能源通讯协议结构体
+ ///
+
+ public enum CallbackSendData
+ {
+ _LoginIn = 0XA1,
+ _SetTime = 0X08,
+ _HeartBeat = 0XA4,
+ _ERealFlag = 0XB3,
+ _SRealFlag = 0XB4,
+ _TRealFlag = 0XB5,
+ _IRealFlag = 0XB6,
+
+ _EFlag = 0XC3,
+ _SFlag = 0XC4,
+ _TFlag = 0XC5,
+ _IFlag = 0XC6,
+ }
+ public struct struFrame
+ {
+ //帧开始
+ public byte BeginChar_State;
+ //采集器类型
+ public byte Collection_Type;
+ //采集器地址
+ public byte[] Collection_Addr;
+ //命令序列号
+ public byte[] Command_Id;
+ //起始符
+ public byte StartChar_State;
+ //控制码
+ public byte Ctrl_State;
+ //数据长度
+ public byte[] DataLen_State;
+ //数据域
+ public byte[] Data_State;
+ //校验码
+ public byte CSChar_State;
+ //结束符
+ public byte EndChar_State;
+ //终端类型
+ public byte flagDTN;
+ //逻辑编号
+ public byte[] addrDNL;
+ //主站地址
+ public byte flagMSTA;
+ //帧内序号
+ public byte flagISEQ;
+ //帧序号
+ public byte flagFSEQ;
+ //控制码
+ public byte flagCtrl;
+ //传送方向
+ public byte flagCtrlD;
+ //异常标志
+ public byte flagCtrlE;
+ //功能标志
+ public byte flagCtrlF;
+ //数据长度
+ public int lenData;
+ //数据字符串
+ public byte[] strData;
+
+ public object userData;
+ public string tName;
+
+ public object userData2;
+ //public bool isCtrl;
+ //public bool isData;
+
+ public bool isTimeCorrectting;
+
+ };
+
+
+
+ ///
+ /// 头文件
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+ public struct Head
+ {
+ public byte start; //起始
+ public short addr; //软件地址
+ public byte mstaseq; //主站地址与命令序号
+ public byte control; //控制码
+ public short length; //数据长度
+ }
+ ///
+ /// 结尾
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+ public struct Tail
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public byte[] verifica; //校验码
+ public byte end; //结束码
+ }
+ #endregion
+ #region 与MES通讯协议
+ //识别一条EPC数据 125+3
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+ public struct ReadEPC
+ {
+ public Head head;
+ public int num;//合并编号
+ public Tail tail;
+ }
+
+ ///
+ /// 写入反馈 125+5
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+ public struct RecWrite
+ {
+ public Head head;
+ public int num;//合并编号
+ public byte state;//1成功,0失败,2写失败,读成功
+ public Tail tail;
+ }
+ //
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+
+ public struct RecDataCell
+ {
+ public byte len;//Data长度
+ public byte[] data;//len 长度个字节数据
+ }
+ ///
+ /// 自报数据 125+6
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+
+ public struct RecAutoData
+ {
+ public Head head;
+ public int num;//合并编号
+ public RecDataCell recDatas;//自报数据
+ public Tail tail;
+ }
+
+ ///
+ ///心跳 101
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+
+ public struct Heart
+ {
+ public Head head;
+ public Tail tail;
+ }
+ #endregion
+ #region 与上层应用层 消息指令
+ ///
+ /// 收到的消息指令
+ ///
+ enum RecAppMsgType
+ {
+ _ReadEpc = 125 + 3,
+ _ReadData = 125 + 4,
+ _WirteData = 125 + 5,
+ _AutoSendData,
+
+ _HeartBeat = 101,
+ _ReadEquipState = 125 + 102,
+ _SendGetSoftState = 125 + 103,
+
+ }
+
+ ///
+ /// 发送的消息指令
+ ///
+ enum RetAppMsgType
+ {
+ _RetEpc = 125 + 3,
+ _RetData = 125 + 4,
+ _RetDataBack = 125 + 5,
+ _RetAutoSendData,
+
+ _RetEquipState = 125 + 102,
+ _RetGetSoftState = 125 + 103,
+ }
+ #endregion
+
+
+ #region 与设备层 适配层消息指令
+ //收到设备层消息
+ enum RecEquipMsgType
+ {
+ _GetEquipInfo = 0X01, //收到适配软件所需设备信息
+ _GetSensor = 0x02, //收到适配软件传感器信息
+ _EPCinfo = 0x03, //收到设备返回数据 将数据发送MES 并保存数据库
+ _SendData = 0x04, //收到读取到的数据 收到数据后,上传给MES,并保存数据库
+ _RecGetData = 0x05, //收到写入的数据是否成功反馈
+ _RecAutoData = 0x06, //收到设备自报数据
+
+ _HeartBeat = 101, //心跳
+ _EquipState, //设备状态
+ }
+ //发送给设备层消息
+ enum RetEquipMsgType
+ {
+ _RetEquipInfo = 0X01, //获取适配软件所需设备信息
+ _RetSensor = 0x02, //获取适配软件传感器信息
+ _GetEPCinfo = 0x03, //向设备发送命令,识别EPC数据
+ _GetData = 0x04, //向设备发送命令,读取数据
+ _WirteData = 0x05, //向设备发送命令,写入数据
+ _RetAutoData = 0x06, //收到设备自爆数据反馈
+
+ }
+ #endregion
+}
diff --git a/HighWayIot.Common/Properties/AssemblyInfo.cs b/HighWayIot.Common/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f4774ed
--- /dev/null
+++ b/HighWayIot.Common/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.Common")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.Common")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("89a1edd9-d79e-468d-b6d3-7d07b8843562")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.Common/StringChange.cs b/HighWayIot.Common/StringChange.cs
new file mode 100644
index 0000000..81839d3
--- /dev/null
+++ b/HighWayIot.Common/StringChange.cs
@@ -0,0 +1,216 @@
+using HighWayIot.Log4net;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Common
+{
+ public class StringChange
+ {
+ private static readonly Lazy lazy = new Lazy(() => new StringChange());
+ public static StringChange Instance
+ {
+ get
+ {
+ return lazy.Value;
+ }
+ }
+
+ private StringChange() { }
+
+ ///
+ /// 将字符串强制转换成int,转换失败则返回0
+ ///
+ ///
+ ///
+ public int ParseToInt(string str)
+ {
+ int returnInt = 0;
+ if (str == null || str.Trim().Length < 1)
+ {
+ return returnInt;
+ }
+ if (int.TryParse(str, out returnInt))
+ {
+ return returnInt;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ ///
+ /// char数组转Array
+ ///
+ ///
+ ///
+ ///
+ public string CharArrayToString(char[] cha, int len)
+ {
+ string str = "";
+ for (int i = 0; i < len; i++)
+ {
+ str += string.Format("{0}", cha[i]);
+ }
+
+ return str;
+ }
+
+ public string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01"
+ {
+ string returnStr = "";
+ if (bytes != null)
+ {
+ for (int i = 0; i < iLen; i++)
+ {
+ returnStr += bytes[i].ToString("X2");
+ }
+ }
+ return returnStr;
+ }
+
+ public byte[] HexStrTorbytes(string strHex)//e.g. " 01 01" ---> { 0x01, 0x01}
+ {
+ strHex = strHex.Replace(" ", "");
+ if ((strHex.Length % 2) != 0)
+ strHex += " ";
+ byte[] returnBytes = new byte[strHex.Length / 2];
+ for (int i = 0; i < returnBytes.Length; i++)
+ returnBytes[i] = Convert.ToByte(strHex.Substring(i * 2, 2), 16);
+ return returnBytes;
+ }
+
+ public string StringToHexString(string s, Encoding encode)
+ {
+ byte[] b = encode.GetBytes(s); //按照指定编码将string编程字节数组
+ string result = string.Empty;
+ for (int i = 0; i < b.Length; i++) //逐字节变为16进制字符,以%隔开
+ {
+ result += "%" + Convert.ToString(b[i], 16);
+ }
+ return result;
+ }
+
+ public string HexStringToString(string hs, Encoding encode)
+ {
+ //以%分割字符串,并去掉空字符
+ string[] chars = hs.Split(new char[] { '%' }, StringSplitOptions.RemoveEmptyEntries);
+ byte[] b = new byte[chars.Length];
+ //逐个字符变为16进制字节数据
+ for (int i = 0; i < chars.Length; i++)
+ {
+ b[i] = Convert.ToByte(chars[i], 16);
+ }
+ //按照指定编码将字节数组变为字符串
+ return encode.GetString(b);
+ }
+
+ public byte[] Swap16Bytes(byte[] OldU16)
+ {
+ byte[] ReturnBytes = new byte[2];
+ ReturnBytes[1] = OldU16[0];
+ ReturnBytes[0] = OldU16[1];
+ return ReturnBytes;
+ }
+
+
+ /// 64Base码
+ /// 保存路径
+ /// 文件名称
+ ///
+ public bool Base64ToImage(string strbase64, string path, string filename)
+ {
+ bool Flag = false;
+ try
+ {
+ //base64编码的文本 转为 图片
+ //图片名称
+ byte[] arr = Convert.FromBase64String(strbase64);//将指定的字符串(它将二进制数据编码为 Base64 数字)转换为等效的 8 位无符号整数数组。
+ using (MemoryStream ms = new MemoryStream(arr))
+ {
+ Bitmap bmp = new Bitmap(ms);//加载图像
+ if (!Directory.Exists(path))//判断保存目录是否存在
+ {
+ Directory.CreateDirectory(path);
+ }
+ bmp.Save((path + "\\" + filename + ".png"),System.Drawing.Imaging.ImageFormat.Png);//将图片以JPEG格式保存在指定目录(可以选择其他图片格式)
+ ms.Close();//关闭流并释放
+ if (File.Exists(path + "\\" + filename + ".png"))//判断是否存在
+ {
+ Flag = true;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("图片保存失败:" + ex.Message);
+ }
+ return Flag;
+ }
+
+ ///
+ /// 获取时间戳
+ ///
+ ///
+ public long GetTimeStamp()
+ {
+ TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+ return Convert.ToInt64(ts.TotalSeconds);
+ }
+
+ public byte[] ConvertFloatToINt(byte[] floatBytes)
+ {
+ byte[] intBytes = new byte[floatBytes.Length / 2];
+ for (int i = 0; i < intBytes.Length; i++)
+ {
+ intBytes[i] = floatBytes[i * 2 + 1];
+ }
+ return intBytes;
+ }
+
+ //CRC异或校验
+ public byte CalculateVerify(byte[] pMessage, int iLength)
+ {
+ UInt16 i;
+ byte iVerify = 0;
+
+ iVerify = pMessage[0];
+ for (i = 1; i < iLength; i++)
+ {
+ iVerify = (byte)(iVerify ^ pMessage[i]);
+ }
+ return iVerify;
+ }
+
+ public int HexStringToNegative(string strNumber)
+ {
+
+ int iNegate = 0;
+ int iNumber = Convert.ToInt32(strNumber, 16);
+ if (iNumber > 127)
+ {
+ int iComplement = iNumber - 1;
+ string strNegate = string.Empty;
+ char[] binchar = Convert.ToString(iComplement, 2).PadLeft(8, '0').ToArray();
+ foreach (char ch in binchar)
+ {
+ if (Convert.ToInt32(ch) == 48)
+ {
+ strNegate += "1";
+ }
+ else
+ {
+ strNegate += "0";
+ }
+ }
+ iNegate = -Convert.ToInt32(strNegate, 2);
+ }
+ return iNegate;
+ }
+ }
+}
\ No newline at end of file
diff --git a/HighWayIot.Common/packages.config b/HighWayIot.Common/packages.config
new file mode 100644
index 0000000..46471ce
--- /dev/null
+++ b/HighWayIot.Common/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Library/GRreader.dll b/HighWayIot.Library/GRreader.dll
new file mode 100644
index 0000000..70ee539
Binary files /dev/null and b/HighWayIot.Library/GRreader.dll differ
diff --git a/HighWayIot.Library/HslCommunication.dll b/HighWayIot.Library/HslCommunication.dll
new file mode 100644
index 0000000..7082ca2
Binary files /dev/null and b/HighWayIot.Library/HslCommunication.dll differ
diff --git a/HighWayIot.Library/MQTTnet.dll b/HighWayIot.Library/MQTTnet.dll
new file mode 100644
index 0000000..86ee0dd
Binary files /dev/null and b/HighWayIot.Library/MQTTnet.dll differ
diff --git a/HighWayIot.Library/MySql.Data.dll b/HighWayIot.Library/MySql.Data.dll
new file mode 100644
index 0000000..888c220
Binary files /dev/null and b/HighWayIot.Library/MySql.Data.dll differ
diff --git a/HighWayIot.Library/Oracle.ManagedDataAccess.dll b/HighWayIot.Library/Oracle.ManagedDataAccess.dll
new file mode 100644
index 0000000..c408c77
Binary files /dev/null and b/HighWayIot.Library/Oracle.ManagedDataAccess.dll differ
diff --git a/HighWayIot.Library/SqlSugar.dll b/HighWayIot.Library/SqlSugar.dll
new file mode 100644
index 0000000..fcb0e21
Binary files /dev/null and b/HighWayIot.Library/SqlSugar.dll differ
diff --git a/HighWayIot.Library/System.Data.SQLite.dll b/HighWayIot.Library/System.Data.SQLite.dll
new file mode 100644
index 0000000..f68bb53
Binary files /dev/null and b/HighWayIot.Library/System.Data.SQLite.dll differ
diff --git a/HighWayIot.Library/TouchSocket.dll b/HighWayIot.Library/TouchSocket.dll
new file mode 100644
index 0000000..d28fbdd
Binary files /dev/null and b/HighWayIot.Library/TouchSocket.dll differ
diff --git a/HighWayIot.Library/log4net.dll b/HighWayIot.Library/log4net.dll
new file mode 100644
index 0000000..8646b6f
Binary files /dev/null and b/HighWayIot.Library/log4net.dll differ
diff --git a/HighWayIot.Log4net/HighWayIot.Log4net.csproj b/HighWayIot.Log4net/HighWayIot.Log4net.csproj
new file mode 100644
index 0000000..9a4f9a5
--- /dev/null
+++ b/HighWayIot.Log4net/HighWayIot.Log4net.csproj
@@ -0,0 +1,55 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {DEABC30C-EC6F-472E-BD67-D65702FDAF74}
+ Library
+ Properties
+ HighWayIot.Log4net
+ HighWayIot.Log4net
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\HighWayIot.Library\log4net.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Log4net/LogHelper.cs b/HighWayIot.Log4net/LogHelper.cs
new file mode 100644
index 0000000..971f5f2
--- /dev/null
+++ b/HighWayIot.Log4net/LogHelper.cs
@@ -0,0 +1,147 @@
+using log4net.Config;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Log4net
+{
+ public class LogHelper
+ {
+ private static readonly Lazy lazy = new Lazy(() => new LogHelper());
+ public static LogHelper Instance
+ {
+ get
+ {
+ return lazy.Value;
+ }
+ }
+
+ private readonly log4net.ILog loginfo = log4net.LogManager.GetLogger("loginfo");
+ private readonly log4net.ILog logerror = log4net.LogManager.GetLogger("logerror");
+ private readonly log4net.ILog logView = log4net.LogManager.GetLogger("viewlog");
+ private readonly log4net.ILog sqllog = log4net.LogManager.GetLogger("sqllog");
+ private readonly log4net.ILog semaphorelog = log4net.LogManager.GetLogger("semaphorelog");
+ private readonly log4net.ILog logPlc = log4net.LogManager.GetLogger("plclog");
+ private readonly log4net.ILog logRfid = log4net.LogManager.GetLogger("rfidlog");
+
+ /**
+ * 配置文件路径
+ *
+ */
+ //private readonly string fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
+ private readonly string fileName = "Z:\\Desktop\\日常代码\\HighWayIot\\HighWayIot.Log4net\\config\\log4net.config";
+
+ private LogHelper()
+ {
+ if (File.Exists(fileName))
+ {
+ XmlConfigurator.Configure(new FileInfo(fileName));
+ }
+ }
+
+ ///
+ /// 记录Info日志
+ ///
+ ///
+ ///
+ public void Info(string msg)
+ {
+ if (loginfo.IsInfoEnabled)
+ {
+ loginfo.Info(msg);
+ }
+ }
+
+ ///
+ /// 记录PLC日志
+ ///
+ ///
+ public void PlcLog(string msg)
+ {
+ if (logPlc.IsInfoEnabled)
+ {
+ logPlc.Info(msg);
+ }
+ }
+
+ ///
+ /// 记录Rfid日志
+ ///
+ ///
+ public void RfidLog(string msg)
+ {
+ if (logRfid.IsInfoEnabled)
+ {
+ logRfid.Info(msg);
+ }
+ }
+
+ ///
+ /// 界面日志
+ ///
+ ///
+ public void ViewLog(string msg)
+ {
+ if (logView.IsInfoEnabled)
+ {
+ logView.Info(msg);
+ }
+ }
+
+ public void SqlLog(string msg)
+ {
+ if (sqllog.IsInfoEnabled)
+ {
+ sqllog.Info(msg);
+ }
+ }
+
+ public void SemaphoreLog(string msg)
+ {
+ if (semaphorelog.IsInfoEnabled)
+ {
+ semaphorelog.Info(msg);
+ }
+ }
+
+ ///
+ /// 记录Error日志
+ ///
+ ///
+ ///
+ public void Error(string info, Exception ex = null)
+ {
+ if (!string.IsNullOrEmpty(info) && ex == null)
+ {
+ logerror.ErrorFormat("【附加信息】 : {0}
", new object[] { info });
+ }
+ else if (!string.IsNullOrEmpty(info) && ex != null)
+ {
+ string errorMsg = BeautyErrorMsg(ex);
+ logerror.ErrorFormat("【附加信息】 : {0}
{1}", new object[] { info, errorMsg });
+ }
+ else if (string.IsNullOrEmpty(info) && ex != null)
+ {
+ string errorMsg = BeautyErrorMsg(ex);
+ logerror.Error(errorMsg);
+ }
+ }
+
+ ///
+ /// 美化错误信息
+ ///
+ /// 异常
+ /// 错误信息
+ private string BeautyErrorMsg(Exception ex)
+ {
+ string errorMsg = string.Format("【异常类型】:{0}
【异常信息】:{1}
【堆栈调用】:{2}", new object[] { ex.GetType().Name, ex.Message, ex.StackTrace });
+ errorMsg = errorMsg.Replace("\r\n", "
");
+ errorMsg = errorMsg.Replace("位置", "位置");
+ return errorMsg;
+ }
+
+ }
+}
diff --git a/HighWayIot.Log4net/Properties/AssemblyInfo.cs b/HighWayIot.Log4net/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1f83578
--- /dev/null
+++ b/HighWayIot.Log4net/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.Log4net")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.Log4net")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("deabc30c-ec6f-472e-bd67-d65702fdaf74")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.Log4net/config/log4net.config b/HighWayIot.Log4net/config/log4net.config
new file mode 100644
index 0000000..a9d7efb
--- /dev/null
+++ b/HighWayIot.Log4net/config/log4net.config
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Mqtt/HighWayIot.Mqtt.csproj b/HighWayIot.Mqtt/HighWayIot.Mqtt.csproj
new file mode 100644
index 0000000..2521b2d
--- /dev/null
+++ b/HighWayIot.Mqtt/HighWayIot.Mqtt.csproj
@@ -0,0 +1,55 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {CD9B8712-0E09-42D2-849B-B8EAB02C7AB8}
+ Library
+ Properties
+ HighWayIot.Mqtt
+ HighWayIot.Mqtt
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\HighWayIot.Library\log4net.dll
+
+
+ ..\HighWayIot.Library\MQTTnet.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Mqtt/MqttClient.cs b/HighWayIot.Mqtt/MqttClient.cs
new file mode 100644
index 0000000..8d87baf
--- /dev/null
+++ b/HighWayIot.Mqtt/MqttClient.cs
@@ -0,0 +1,153 @@
+using MQTTnet.Client;
+using MQTTnet;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Security.Authentication;
+
+namespace HighWayIot.Mqtt
+{
+ public sealed class MqttClient
+ {
+
+ public delegate void PrintMessageReceived(string message);
+ public event PrintMessageReceived PrintMessageReceivedEvent;
+
+ private IMqttClient client;
+
+ private static readonly Lazy lazy = new Lazy(() => new MqttClient());
+
+ public static MqttClient Instance
+ {
+ get
+ {
+ return lazy.Value;
+ }
+ }
+
+ private MqttClient() { }
+
+ ///
+ /// 链接服务器
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async void Connect(string ip, int port, string clientId, string username, string password)
+ {
+ try
+ {
+ MqttClientOptions options = new MqttClientOptionsBuilder()
+ .WithTcpServer(ip, port)
+ .WithClientId(clientId)
+ .WithCredentials(username, password)
+ .WithTls(o => //开启ssl
+ {
+ o.CertificateValidationHandler = _ => true;
+
+ o.SslProtocol = SslProtocols.Tls12;
+ }).Build();
+ client = new MqttFactory().CreateMqttClient();
+
+ client.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceived;
+
+ MqttClientConnectResult result = await client.ConnectAsync(options);
+
+ if (result != null)
+ {
+ if (result.ResultCode == MQTTnet.Client.MqttClientConnectResultCode.Success)
+ {
+ PrintMessageReceivedEvent?.Invoke($"连接服务器成功{ip}:{port}");
+ }
+ else
+ {
+ PrintMessageReceivedEvent?.Invoke($"连接服务器失败");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ PrintMessageReceivedEvent?.Invoke($"连接服务器异常:{ex.Message}");
+ }
+ }
+
+ ///
+ /// 断开链接
+ ///
+ public void DisConnect()
+ {
+ client.DisconnectAsync();
+ PrintMessageReceivedEvent?.Invoke($"断开连接");
+ }
+
+ ///
+ /// 订阅主题
+ ///
+ ///
+ public async void SubscriptionAsync(string topic)
+ {
+ try
+ {
+ var mqttFactory = new MqttFactory();
+ var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
+ .WithTopicFilter(
+ f =>
+ {
+ f.WithTopic(topic);
+ })
+ .Build();
+
+ MqttClientSubscribeResult result = await client.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
+
+ PrintMessageReceivedEvent?.Invoke($"订阅主题:{topic}");
+ }
+ catch (Exception ex)
+ {
+ PrintMessageReceivedEvent?.Invoke($"订阅主题异常:{ex.Message}");
+ }
+ }
+
+ ///
+ /// 取消订阅
+ ///
+ ///
+ public void Unsubscribe(string topic)
+ {
+ client.UnsubscribeAsync(topic);
+ PrintMessageReceivedEvent?.Invoke($"取消订阅,主题:{topic}");
+ }
+
+ ///
+ /// 推送消息
+ ///
+ ///
+ ///
+ public void Publish(string topic, string message)
+ {
+ try
+ {
+ var msg = new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(message)
+ .Build();
+ client.PublishAsync(msg, CancellationToken.None);
+ PrintMessageReceivedEvent?.Invoke($"向服务端推送成功,主题:{topic};内容:{message}");
+ }
+ catch (Exception ex)
+ {
+ PrintMessageReceivedEvent?.Invoke($"向服务端推送消息异常:{ex.Message}");
+ }
+ }
+
+ private async Task MqttClient_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs eventArgs)
+ {
+ var info = $"接收到主题:{eventArgs.ApplicationMessage.Topic}的消息,内容:{Encoding.UTF8.GetString(eventArgs.ApplicationMessage.Payload)}";
+ PrintMessageReceivedEvent?.Invoke(info);
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/HighWayIot.Mqtt/Properties/AssemblyInfo.cs b/HighWayIot.Mqtt/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4bf53a9
--- /dev/null
+++ b/HighWayIot.Mqtt/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.Mqtt")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.Mqtt")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("cd9b8712-0e09-42d2-849b-b8eab02c7ab8")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.Plc/HighWayIot.Plc.csproj b/HighWayIot.Plc/HighWayIot.Plc.csproj
new file mode 100644
index 0000000..61c1108
--- /dev/null
+++ b/HighWayIot.Plc/HighWayIot.Plc.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {4EE4C3E2-AC45-4275-8017-E99D70FC1F52}
+ Library
+ Properties
+ HighWayIot.Plc
+ HighWayIot.Plc
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\HighWayIot.Library\HslCommunication.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {89a1edd9-d79e-468d-b6d3-7d07b8843562}
+ HighWayIot.Common
+
+
+ {deabc30c-ec6f-472e-bd67-d65702fdaf74}
+ HighWayIot.Log4net
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Plc/IPlc.cs b/HighWayIot.Plc/IPlc.cs
new file mode 100644
index 0000000..d3259ee
--- /dev/null
+++ b/HighWayIot.Plc/IPlc.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Plc
+{
+ public interface IPlc
+ {
+ bool IsConnected { get; set; }
+
+ ///
+ /// 建立连接
+ ///
+ ///
+ ///
+ ///
+ bool Connect(string IP, int port);
+
+ ///
+ /// 断开连接
+ ///
+ ///
+ bool DisConnect();
+
+ ///
+ /// 通过地址和长度读取PLC数据
+ ///
+ ///
+ ///
+ ///
+ byte[] readValueByAddress(int len, string address);
+
+ ///
+ /// 通过PLC地址写入int类型数据
+ ///
+ ///
+ ///
+ ///
+ bool writeValueByAddress(int value, string address);
+
+ ///
+ /// 通过PLC地址清零数据
+ ///
+ ///
+ ///
+ ///
+ bool resetByAddress(string address, int len);
+
+ ///
+ /// 通过PLC地址读取EA值
+ ///
+ ///
+ ///
+ string readEaByAddress(string address);
+
+ ///
+ /// 通过PLC地址读取交互信号
+ ///
+ ///
+ ///
+ int readInteractiveSignal(string address);
+
+ ///
+ /// 通过PLC地址读取int32类型数据
+ ///
+ ///
+ ///
+ int readInt32ByAddress(string address);
+
+ ///
+ /// 通过PLC地址写入int32类型数据
+ ///
+ ///
+ ///
+ ///
+ bool writeInt32ByAddress(string address, int value);
+
+ ///
+ /// 通过PLC地址读取string类型数据
+ ///
+ ///
+ ///
+ string readStringByAddress(string address, ushort length);
+
+ ///
+ /// 通过PLC地址写入String类型数据
+ ///
+ ///
+ ///
+ ///
+ bool writeStringByAddress(string address, string value);
+
+ ///
+ /// 通过PLC地址读取Bool类型数据
+ ///
+ ///
+ ///
+ bool readBoolByAddress(string address);
+
+ ///
+ /// 通过PLC地址写入Bool类型数据
+ ///
+ ///
+ ///
+ bool writeBoolByAddress(string address, bool value);
+
+ ///
+ /// 通过PLC地址写入Double类型数据
+ ///
+ ///
+ ///
+ ///
+ bool writeDoubleByAddress(string address, int value);
+ }
+}
diff --git a/HighWayIot.Plc/Impl/InovancePlc.cs b/HighWayIot.Plc/Impl/InovancePlc.cs
new file mode 100644
index 0000000..5feae10
--- /dev/null
+++ b/HighWayIot.Plc/Impl/InovancePlc.cs
@@ -0,0 +1,487 @@
+using HslCommunication;
+using HslCommunication.Profinet.Inovance;
+using HighWayIot.Common;
+using System;
+using HighWayIot.Log4net;
+
+namespace HighWayIot.Plc.Impl
+{
+ ///
+ /// 汇川PLC
+ ///
+ public class InovancePlc : IPlc
+ {
+ private LogHelper log = LogHelper.Instance;
+
+ private StringChange stringChange = StringChange.Instance;
+
+ private InovanceTcpNet inovanceTcp = null;
+
+ public InovancePlc()
+ {
+ if (!HslCommunication.Authorization.SetAuthorizationCode("ed1415f8-e06a-43ad-95f7-c04f7ae93b41"))
+ {
+ log.Info("HslCommunication激活失败");
+ return;
+ }
+ log.Info("HslCommunication 11.0.6.0激活成功");
+ this.inovanceTcp = new InovanceTcpNet();
+ this.inovanceTcp.ConnectTimeOut = 2000;
+ }
+
+ public bool IsConnected { get; set; }
+
+ ///
+ /// 建立连接
+ ///
+ ///
+ ///
+ ///
+ public bool Connect(string IP, int port)
+ {
+ inovanceTcp?.ConnectClose();
+
+ log.PlcLog("汇川PLC连接开始");
+ inovanceTcp.IpAddress = IP;
+ inovanceTcp.Port = 502;
+ inovanceTcp.DataFormat = HslCommunication.Core.DataFormat.CDAB;
+ try
+ {
+ OperateResult connect = inovanceTcp.ConnectServer();
+ if (connect.IsSuccess)
+ {
+ this.IsConnected = true;
+ log.PlcLog("汇川PLC建立连接成功!!!");
+ return true;
+ }
+ else
+ {
+ this.IsConnected = false;
+ log.PlcLog("汇川PLC建立连接失败!!!");
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.IsConnected = false;
+ log.Error("欧姆龙NJ系列PLC建立连接异常", ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 断开连接
+ ///
+ ///
+ public bool DisConnect()
+ {
+ return inovanceTcp.ConnectClose().IsSuccess;
+ }
+
+ ///
+ /// 通过地址和长度读取PLC数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public byte[] readValueByAddress(int len, string address)
+ {
+ //log.PlcLog("开始通过PLC地址和长度读取PLC数据");
+ try
+ {
+ OperateResult read = inovanceTcp.Read(address, (ushort)(len));
+ if (read.IsSuccess)
+ {
+ byte[] result = stringChange.ConvertFloatToINt(read.Content);
+ log.PlcLog(String.Format("通过地址和长度读取PLC数据成功:{0}",stringChange.bytesToHexStr(result, result.Length)));
+ return result;
+ }
+ else
+ {
+ log.PlcLog("通过地址和长度读取PLC数据失败!!!");
+ this.IsConnected = false;
+ return new byte[0];
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过地址和长度读取PLC数据异常", ex);
+ this.IsConnected = false;
+ return new byte[0];
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入int类型数据,模切汇川PLC复位逻辑
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeValueByAddress(int value, string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}", address, value));
+ OperateResult operateResult = new OperateResult();
+ try
+ {
+ int s = 0;
+ string[] strArry = address.Split('.');
+
+ //先读取整个块的内容
+ var info = inovanceTcp.ReadInt16(strArry[0]);
+ if (info.Content == 0)
+ {
+ int length = stringChange.ParseToInt(strArry[1]) + 1;
+ string[] array = new string[length];
+ for(int i=0;i< length;i++)
+ {
+ if(i == stringChange.ParseToInt(strArry[1]))
+ {
+ array[i] = value.ToString();
+ }
+ else
+ {
+ array[i] = "0";
+ }
+ }
+ //反转
+ Array.Reverse(array);
+ byte[] buffer = new byte[array.Length];
+ string result = "";
+ for(int i = 0; i < array.Length; i++)
+ {
+ result += (byte)Convert.ToInt32(array[i], 16);
+ }
+ s = Convert.ToInt32(result.Trim(), 2);
+ operateResult = inovanceTcp.Write(strArry[0], (ushort)s);
+ }
+ else
+ {
+ var inf2 = Convert.ToString(info.Content, 2);
+ string[] infoArray = new string[inf2.Length];
+ for (int i = 0; i < inf2.Length; i++)
+ {
+ infoArray[i] = inf2.Substring(i, 1);
+ }
+ Array.Reverse(infoArray);
+ infoArray[stringChange.ParseToInt(strArry[1])] = value.ToString();
+ string result = "";
+ foreach (var item in infoArray)
+ {
+ result = result + item;
+ }
+ s = Convert.ToInt32(result.Trim(), 10);
+ operateResult = inovanceTcp.Write(strArry[0], s);
+ }
+ if (operateResult.IsSuccess)
+ {
+ log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址写入int类型数据", ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址清零数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool resetByAddress(string address, int len)
+ {
+ // log.PlcLog(String.Format("开发通过PLC地址{0}清零数据", address));
+ try
+ {
+ byte[] write = new byte[len * 2];
+ for (int i = 0; i < len * 2; i++)
+ {
+ write[i] = 0;
+ }
+ OperateResult operateResult = inovanceTcp.Write(address, write);
+
+ if (operateResult.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}清零数据成功", address));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}清零数据失败!!!", address));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}清零数据异常", address), ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取EA值
+ ///
+ ///
+ ///
+ ///
+ public string readEaByAddress(string address)
+ {
+ //log.PlcLog(String.Format("通过PLC地址{0}读取EA值", address));
+ try
+ {
+ OperateResult read = inovanceTcp.Read(address, (ushort)(8));
+
+ if (read.IsSuccess && read.Content != null)
+ {
+ string result = Convert.ToString(read.Content);
+ log.PlcLog(String.Format("通过PLC地址{0}读取EA值成功:{1}", address, result));
+ return result;
+ }
+ else
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取EA值失败!!!", address));
+ this.IsConnected = false;
+ return "";
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取EA值异常", ex);
+ this.IsConnected = false;
+ return "";
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取交互信号
+ ///
+ ///
+ ///
+ public int readInteractiveSignal(string address)
+ {
+ // log.PlcLog(String.Format("开始通过PLC地址{0}读取交互信号", address));
+ try
+ {
+ OperateResult read = inovanceTcp.ReadInt16(address);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取交互信号失败!!!", address));
+ this.IsConnected = false;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取交互信号异常", ex);
+ this.IsConnected = false;
+ return 0;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取int32类型数据
+ ///
+ ///
+ ///
+ public int readInt32ByAddress(string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取int32类型数据", address));
+ try
+ {
+ OperateResult read = inovanceTcp.ReadInt16(address);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address));
+ this.IsConnected = false;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取int32类型数据异常", ex);
+ this.IsConnected = false;
+ return 0;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入int32类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeInt32ByAddress(string address, int value)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value));
+ try
+ {
+ OperateResult write = inovanceTcp.Write(address, short.Parse(Convert.ToString(value)));
+ if (write.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入String类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeStringByAddress(string address, string value)
+ {
+ //log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}", address, value));
+ try
+ {
+ OperateResult operateResult = inovanceTcp.Write(address, value);
+ if (operateResult.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取string类型数据
+ ///
+ ///
+ ///
+ ///
+ public string readStringByAddress(string address, ushort length)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取string类型数据", address));
+ try
+ {
+ OperateResult read = inovanceTcp.ReadString(address, length);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address));
+ return "";
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取int32类型数据异常", ex);
+ return "";
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取Bool类型数据
+ ///
+ ///
+ ///
+ ///
+ public bool readBoolByAddress(string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取bool类型数据", address));
+ try
+ {
+ OperateResult read = inovanceTcp.ReadBool(address);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据成功{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取bool类型数据异常", ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入Bool类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeBoolByAddress(string address, bool value)
+ {
+ // log.PlcLog(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value));
+ try
+ {
+
+ OperateResult write = inovanceTcp.Write(address, value);
+
+ if (write.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 写入Double类型
+ ///
+ ///
+ ///
+ ///
+ public bool writeDoubleByAddress(string address, int value)
+ {
+ try
+ {
+ OperateResult write = inovanceTcp.Write(address, Convert.ToDouble(value));
+
+ if (write.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex);
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/HighWayIot.Plc/Impl/OMRONNJPLC.CS b/HighWayIot.Plc/Impl/OMRONNJPLC.CS
new file mode 100644
index 0000000..3a29c8d
--- /dev/null
+++ b/HighWayIot.Plc/Impl/OMRONNJPLC.CS
@@ -0,0 +1,444 @@
+using HighWayIot.Common;
+using HighWayIot.Log4net;
+using HslCommunication;
+using HslCommunication.Profinet.Omron;
+using System;
+
+namespace HighWayIot.Plc.Impl
+{
+ ///
+ /// 欧姆龙NJ系列PLC
+ ///
+ public class OmronNJPlc : IPlc
+ {
+
+ private LogHelper log = LogHelper.Instance;
+
+ private StringChange stringChange = StringChange.Instance;
+
+ private OmronFinsNet omronFinsNet = null;
+
+ public OmronNJPlc()
+ {
+ if (!HslCommunication.Authorization.SetAuthorizationCode("ed1415f8-e06a-43ad-95f7-c04f7ae93b41"))
+ {
+ log.Info("HslCommunication 11.0.6.0激活失败");
+ return;
+ }
+ log.Info("HslCommunication 11.0.6.0激活成功");
+ this.omronFinsNet = new OmronFinsNet();
+ this.omronFinsNet.ConnectTimeOut = 2000;
+ }
+
+ public bool IsConnected { get; set; }
+
+ ///
+ /// 建立连接
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool Connect(string IP, int port)
+ {
+ log.PlcLog("欧姆龙NJ系列PLC连接开始");
+ omronFinsNet.IpAddress = IP;
+ omronFinsNet.Port = 9600;
+ omronFinsNet.SA1 = (byte)192;
+ omronFinsNet.DA1 = (byte)239;
+ omronFinsNet.DA2 = (byte)0;
+ try
+ {
+ OperateResult connect = omronFinsNet.ConnectServer();
+ if (connect.IsSuccess)
+ {
+ this.IsConnected = true;
+ log.PlcLog("欧姆龙NJ系列PLC建立连接成功!!!");
+ return true;
+ }
+ else
+ {
+ this.IsConnected = false;
+ log.PlcLog("欧姆龙NJ系列PLC建立连接失败!!!");
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.IsConnected = false;
+ log.Error("欧姆龙NJ系列PLC建立连接异常", ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 断开连接
+ ///
+ ///
+ public bool DisConnect()
+ {
+ return omronFinsNet.ConnectClose().IsSuccess;
+ }
+
+ ///
+ /// 通过地址和长度读取PLC数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public byte[] readValueByAddress(int len, string address)
+ {
+ //log.PlcLog("开始通过PLC地址和长度读取PLC数据");
+ try
+ {
+ OperateResult read = omronFinsNet.Read(address, (ushort)(len));
+ if (read.IsSuccess)
+ {
+ byte[] result = stringChange.ConvertFloatToINt(read.Content);
+ log.PlcLog(String.Format("通过地址和长度读取PLC数据成功:{0}", stringChange.bytesToHexStr(result, result.Length)));
+ return result;
+ }
+ else
+ {
+ log.PlcLog("通过地址和长度读取PLC数据失败!!!");
+ this.IsConnected = false;
+ return new byte[0];
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过地址和长度读取PLC数据异常", ex);
+ this.IsConnected = false;
+ return new byte[0];
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入int类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeValueByAddress(int value, string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}",address,value));
+ try
+ {
+ OperateResult operateResult = omronFinsNet.Write(address, Convert.ToInt32(value));
+ if (operateResult.IsSuccess)
+ {
+ log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址写入int类型数据", ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址清零数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool resetByAddress(string address, int len)
+ {
+ //log.PlcLog(String.Format("开发通过PLC地址{0}清零数据", address));
+ try
+ {
+ byte[] write = new byte[len * 2];
+ for (int i = 0; i < len * 2; i++)
+ {
+ write[i] = 0;
+ }
+ OperateResult operateResult = omronFinsNet.Write(address, write);
+
+ if (operateResult.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}清零数据成功", address));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}清零数据失败!!!", address));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}清零数据异常",address), ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取EA值
+ ///
+ ///
+ ///
+ ///
+ public string readEaByAddress(string address)
+ {
+ //log.PlcLog(String.Format("通过PLC地址{0}读取EA值", address));
+ try
+ {
+ OperateResult read = omronFinsNet.Read(address, (ushort)(8));
+
+ if (read.IsSuccess && read.Content != null)
+ {
+ string result = Convert.ToString(read.Content);
+ log.PlcLog(String.Format("通过PLC地址{0}读取EA值成功:{1}", address,result));
+ return result;
+ }
+ else
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取EA值失败!!!", address));
+ this.IsConnected = false;
+ return "";
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取EA值异常", ex);
+ this.IsConnected = false;
+ return "";
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取交互信号
+ ///
+ ///
+ ///
+ public int readInteractiveSignal(string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取交互信号", address));
+ try
+ {
+ OperateResult read = omronFinsNet.ReadInt16(address);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取交互信号失败!!!", address));
+ this.IsConnected = false;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取交互信号异常", ex);
+ this.IsConnected = false;
+ return 0;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取int32类型数据
+ ///
+ ///
+ ///
+ public int readInt32ByAddress(string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取int32类型数据",address));
+ try
+ {
+ OperateResult read = omronFinsNet.ReadInt16(address);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address));
+ this.IsConnected = false;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取int32类型数据异常", ex);
+ this.IsConnected = false;
+ return 0;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入int32类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeInt32ByAddress(string address, int value)
+ {
+ log.PlcLog(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address,value));
+ try
+ {
+ OperateResult write = omronFinsNet.Write(address, short.Parse(Convert.ToString(value)));
+ if (write.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address,value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address,value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入int32类型数据异常", address),ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入String类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeStringByAddress(string address, string value)
+ {
+ //log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}",address,value));
+ try
+ {
+ OperateResult operateResult = omronFinsNet.Write(address, value);
+ if (operateResult.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value));
+ //this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入String类型数据异常", address),ex);
+ //this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取string类型数据
+ ///
+ ///
+ ///
+ ///
+ public string readStringByAddress(string address,ushort length)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取string类型数据", address));
+ try
+ {
+ OperateResult read = omronFinsNet.ReadString(address, length);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address));
+ this.IsConnected = false;
+ return "";
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取int32类型数据异常", ex);
+ return "";
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取Bool类型数据
+ ///
+ ///
+ ///
+ ///
+ public bool readBoolByAddress(string address)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}读取bool类型数据", address));
+ try
+ {
+ OperateResult read = omronFinsNet.ReadBool(address);
+ if (read.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error("通过PLC地址读取int32类型数据异常", ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入Bool类型数据
+ ///
+ ///
+ ///
+ ///
+ public bool writeBoolByAddress(string address, bool value)
+ {
+ //log.PlcLog(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value));
+ try
+ {
+ OperateResult write = omronFinsNet.Write(address, short.Parse(stringChange.ParseToInt(value ? "1" : "0").ToString()));
+ if (write.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 写入Double类型
+ ///
+ ///
+ ///
+ ///
+ public bool writeDoubleByAddress(string address, int value)
+ {
+ try
+ {
+ OperateResult write = omronFinsNet.Write(address, Convert.ToDouble(value));
+
+ if (write.IsSuccess)
+ {
+ log.PlcLog(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value));
+ return true;
+ }
+ log.PlcLog(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ log.Error(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex);
+ return false;
+ }
+ }
+ }
+}
diff --git a/HighWayIot.Plc/Impl/SiemensPlc.cs b/HighWayIot.Plc/Impl/SiemensPlc.cs
new file mode 100644
index 0000000..e9b6b26
--- /dev/null
+++ b/HighWayIot.Plc/Impl/SiemensPlc.cs
@@ -0,0 +1,405 @@
+using HighWayIot.Common;
+using HighWayIot.Log4net;
+using HslCommunication;
+using HslCommunication.Profinet.Siemens;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Plc.Impl
+{
+ public class SiemensPlc
+ {
+
+ private LogHelper logHelper = LogHelper.Instance;
+
+ private StringChange stringChange = StringChange.Instance;
+
+ private const SiemensPLCS type = SiemensPLCS.S200Smart;
+
+ private SiemensS7Net s7 = new SiemensS7Net(type);
+
+ public SiemensPlc()
+ {
+ if (!HslCommunication.Authorization.SetAuthorizationCode("30c15272-3960-4853-9fab-3087392ee5cd"))
+ {
+ logHelper.Info("HslCommunication激活失败");
+ return;
+ }
+ }
+
+ public bool IsConnected { get; set; }
+
+ ///
+ /// 建立连接
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool Connect(string IP, int port)
+ {
+ logHelper.PlcLog("西门子S7系列PLC连接开始");
+ s7.IpAddress = IP;
+ s7.Port = 102;
+ try
+ {
+ OperateResult connect = s7.ConnectServer();
+ if (connect.IsSuccess)
+ {
+ this.IsConnected = true;
+ logHelper.PlcLog("西门子S7系列PLC建立连接成功!!!");
+ return true;
+ }
+ else
+ {
+ this.IsConnected = false;
+ logHelper.PlcLog("西门子S7系列PLC建立连接失败!!!");
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.IsConnected = false;
+ logHelper.Error("西门子S7系列PLC建立连接异常", ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 通过地址和长度读取PLC数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public byte[] readValueByAddress(int len, string address)
+ {
+ //logHelper.PlcLog("开始通过PLC地址和长度读取PLC数据");
+ try
+ {
+ OperateResult read = s7.Read(address, (ushort)(len));
+ if (read.IsSuccess)
+ {
+ byte[] result = stringChange.ConvertFloatToINt(read.Content);
+ logHelper.PlcLog(String.Format("通过地址和长度读取PLC数据成功:{0}", stringChange.bytesToHexStr(result, result.Length)));
+ return result;
+ }
+ else
+ {
+ logHelper.PlcLog("通过地址和长度读取PLC数据失败!!!");
+ this.IsConnected = false;
+ return new byte[0];
+ }
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过地址和长度读取PLC数据异常", ex);
+ this.IsConnected = false;
+ return new byte[0];
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入int类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeValueByAddress(int value, string address)
+ {
+ //logHelper.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}",address,value));
+ try
+ {
+ OperateResult operateResult = s7.Write(address, Convert.ToInt32(value));
+ if (operateResult.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value));
+ return true;
+ }
+ logHelper.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过PLC地址写入int类型数据", ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址清零数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool resetByAddress(string address, int len)
+ {
+ //logHelper.PlcLog(String.Format("开发通过PLC地址{0}清零数据", address));
+ try
+ {
+ byte[] write = new byte[len * 2];
+ for (int i = 0; i < len * 2; i++)
+ {
+ write[i] = 0;
+ }
+ OperateResult operateResult = s7.Write(address, write);
+
+ if (operateResult.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}清零数据成功", address));
+ return true;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}清零数据失败!!!", address));
+ return false;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error(String.Format("通过PLC地址{0}清零数据异常", address), ex);
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取EA值
+ ///
+ ///
+ ///
+ ///
+ public string readEaByAddress(string address)
+ {
+ //logHelper.PlcLog(String.Format("通过PLC地址{0}读取EA值", address));
+ try
+ {
+ OperateResult read = s7.Read(address, (ushort)(8));
+
+ if (read.IsSuccess && read.Content != null)
+ {
+ string result = Convert.ToString(read.Content);
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取EA值成功:{1}", address, result));
+ return result;
+ }
+ else
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取EA值失败!!!", address));
+ this.IsConnected = false;
+ return "";
+ }
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过PLC地址读取EA值异常", ex);
+ this.IsConnected = false;
+ return "";
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取交互信号
+ ///
+ ///
+ ///
+ public int readInteractiveSignal(string address)
+ {
+ //logHelper.PlcLog(String.Format("开始通过PLC地址{0}读取交互信号", address));
+ try
+ {
+ OperateResult read = s7.ReadInt16(address);
+ if (read.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取交互信号失败!!!", address));
+ this.IsConnected = false;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过PLC地址读取交互信号异常", ex);
+ this.IsConnected = false;
+ return 0;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取int32类型数据
+ ///
+ ///
+ ///
+ public int readInt32ByAddress(string address)
+ {
+ //logHelper.PlcLog(String.Format("开始通过PLC地址{0}读取int32类型数据",address));
+ try
+ {
+ OperateResult read = s7.ReadInt16(address);
+ if (read.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address));
+ this.IsConnected = false;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过PLC地址读取int32类型数据异常", ex);
+ this.IsConnected = false;
+ return 0;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入int32类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeInt32ByAddress(string address, int value)
+ {
+ logHelper.PlcLog(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value));
+ try
+ {
+ OperateResult write = s7.Write(address, short.Parse(Convert.ToString(value)));
+ if (write.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value));
+ return true;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入String类型数据
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool writeStringByAddress(string address, string value)
+ {
+ //logHelper.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}",address,value));
+ try
+ {
+ OperateResult operateResult = s7.Write(address, value);
+ if (operateResult.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value));
+ return true;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value));
+ //this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex);
+ //this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取string类型数据
+ ///
+ ///
+ ///
+ ///
+ public string readStringByAddress(string address, ushort length)
+ {
+ //logHelper.PlcLog(String.Format("开始通过PLC地址{0}读取string类型数据", address));
+ try
+ {
+ OperateResult read = s7.ReadString(address, length);
+ if (read.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address));
+ this.IsConnected = false;
+ return "";
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过PLC地址读取int32类型数据异常", ex);
+ return "";
+ }
+ }
+
+ ///
+ /// 通过PLC地址读取Bool类型数据
+ ///
+ ///
+ ///
+ ///
+ public bool readBoolByAddress(string address)
+ {
+ //logHelper.PlcLog(String.Format("开始通过PLC地址{0}读取bool类型数据", address));
+ try
+ {
+ OperateResult read = s7.ReadBool(address);
+ if (read.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据成功:{1}", address, read.Content));
+ return read.Content;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error("通过PLC地址读取int32类型数据异常", ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+
+ ///
+ /// 通过PLC地址写入Bool类型数据
+ ///
+ ///
+ ///
+ ///
+ public bool writeBoolByAddress(string address, bool value)
+ {
+ //logHelper.PlcLog(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value));
+ try
+ {
+ OperateResult write = s7.Write(address, short.Parse(stringChange.ParseToInt(value ? "1" : "0").ToString()));
+ if (write.IsSuccess)
+ {
+ logHelper.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value));
+ return true;
+ }
+ logHelper.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value));
+ this.IsConnected = false;
+ return false;
+ }
+ catch (Exception ex)
+ {
+ logHelper.Error(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex);
+ this.IsConnected = false;
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/HighWayIot.Plc/Properties/AssemblyInfo.cs b/HighWayIot.Plc/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2e5f081
--- /dev/null
+++ b/HighWayIot.Plc/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.Plc")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.Plc")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("4ee4c3e2-ac45-4275-8017-e99d70fc1f52")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.Repository/HighWayIot.Repository.csproj b/HighWayIot.Repository/HighWayIot.Repository.csproj
new file mode 100644
index 0000000..8943229
--- /dev/null
+++ b/HighWayIot.Repository/HighWayIot.Repository.csproj
@@ -0,0 +1,89 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {D0DC3CFB-6748-4D5E-B56A-76FDC72AB4B3}
+ Library
+ Properties
+ HighWayIot.Repository
+ HighWayIot.Repository
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ False
+ Z:\Desktop\日常代码\HighWayIot\HighWayIot.Library\MySql.Data.dll
+
+
+ ..\HighWayIot.Library\Oracle.ManagedDataAccess.dll
+
+
+ Z:\Desktop\日常代码\HighWayIot\HighWayIot.Library\SqlSugar.dll
+
+
+
+
+
+ Z:\Desktop\日常代码\HighWayIot\HighWayIot.Library\System.Data.SQLite.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {89a1edd9-d79e-468d-b6d3-7d07b8843562}
+ HighWayIot.Common
+
+
+ {deabc30c-ec6f-472e-bd67-d65702fdaf74}
+ HighWayIot.Log4net
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Repository/Properties/AssemblyInfo.cs b/HighWayIot.Repository/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9798fc0
--- /dev/null
+++ b/HighWayIot.Repository/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.Repository")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.Repository")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("d0dc3cfb-6748-4d5e-b56a-76fdc72ab4b3")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.Repository/Repository.cs b/HighWayIot.Repository/Repository.cs
new file mode 100644
index 0000000..89bc460
--- /dev/null
+++ b/HighWayIot.Repository/Repository.cs
@@ -0,0 +1,40 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository
+{
+ public class Repository : SimpleClient where T : class, new()
+
+ {
+ public Repository(dynamic configId)
+ {
+ /**
+ * 根据configId动态获取数据源
+ */
+ base.Context = SqlSugarHelper.Db.GetConnectionScope(configId);
+
+ //.NET自带IOC: base.Context = 你存储的Services.GetService();
+ //Furion: base.Context=App.GetService();
+ //Furion脚手架: base.Context=DbContext.Instance
+ //SqlSugar.Ioc: base.Context=DbScoped.SugarScope;
+ //手动去赋值: base.Context=DbHelper.GetDbInstance()
+
+ //动态添加
+ //if (!SqlSugarHelper.Db.IsAnyConnection("用户读出来的数据库ConfigId"))
+ //{
+ // SqlSugarHelper.Db.AddConnection(new ConnectionConfig() { 数据库读出来信息 });
+ //}
+ //base.Context = SqlSugarHelper.Db.GetConnectionScope("用户读出来的数据库ConfigId");
+ }
+
+ public SqlSugarScope _db()
+ {
+ return base.Context as SqlSugarScope;
+ }
+ }
+}
+
diff --git a/HighWayIot.Repository/SqlSugarHelper.cs b/HighWayIot.Repository/SqlSugarHelper.cs
new file mode 100644
index 0000000..9bdadd9
--- /dev/null
+++ b/HighWayIot.Repository/SqlSugarHelper.cs
@@ -0,0 +1,79 @@
+using HighWayIot.Common;
+using HighWayIot.Log4net;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository
+{
+ internal class SqlSugarHelper //不能是泛型类
+ {
+ private static LogHelper logHelper = LogHelper.Instance;
+
+ private static JsonChange jsonChange = JsonChange.Instance;
+
+ #region 连接字符串
+ /**
+ * Sqlite:获取debug路径下的数据库文件,不建议直接写死路径
+ * private static string sqliteConnStr = $"Data Source={Path.GetFullPath("data\\data.db")};Version=3";
+ */
+ //private static string sqliteConnStr = "Data Source=Z:\\Desktop\\日常代码\\HighWayIot\\HighWayIot\\bin\\Debug\\data\\data.db;Version=3";
+
+ /**
+ * Mysql
+ */
+ private static string mysqlConnStr = "Data Source=127.0.0.1;Port=6000;Initial Catalog=ry-cloud;uid=root;pwd=123456;Charset=utf8mb4;SslMode=none";
+
+ //private static string oracleConnStr = "Data Source=175.27.215.92/helowin;User ID=aucma_mes;Password=aucma";
+ #endregion
+
+ //如果是固定多库可以传 new SqlSugarScope(List,db=>{}) 文档:多租户
+ //如果是不固定多库 可以看文档Saas分库
+
+ //用单例模式
+ public static SqlSugarScope Db = new SqlSugarScope(
+ // new List()
+ //{
+ //new ConnectionConfig()
+ //{
+ // ConfigId = "sqlite",
+ // ConnectionString = sqliteConnStr,
+ // DbType = DbType.Sqlite,
+ // InitKeyType = InitKeyType.Attribute,
+ // IsAutoCloseConnection = true
+ //},
+ new ConnectionConfig()
+ {
+ ConfigId = "mysql",
+ ConnectionString = mysqlConnStr,
+ DbType = DbType.MySql,
+ InitKeyType = InitKeyType.Attribute,
+ IsAutoCloseConnection = true
+ },
+ //},
+ //new ConnectionConfig()
+ //{
+ // ConfigId = "aucma_mes",
+ // ConnectionString = oracleConnStr,
+ // DbType = DbType.Oracle,
+ // InitKeyType = InitKeyType.Attribute,
+ // IsAutoCloseConnection = true
+ //}
+ //},
+ db =>
+ {
+ //(A)全局生效配置点
+ //调试SQL事件,可以删掉
+ db.Aop.OnLogExecuting = (sql, pars) =>
+ {
+ logHelper.SqlLog($"{sql};参数:{jsonChange.ModeToJson(pars)}");
+ };
+ });
+
+ }
+}
+
diff --git a/HighWayIot.Repository/app.config b/HighWayIot.Repository/app.config
new file mode 100644
index 0000000..c00df4d
--- /dev/null
+++ b/HighWayIot.Repository/app.config
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Repository/domain/BaseBomInfo.cs b/HighWayIot.Repository/domain/BaseBomInfo.cs
new file mode 100644
index 0000000..da881fb
--- /dev/null
+++ b/HighWayIot.Repository/domain/BaseBomInfo.cs
@@ -0,0 +1,22 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.domain
+{
+ [SugarTable("BASE_BOMINFO")]
+ public class BaseBomInfo
+ {
+ ///
+ /// 主键标识
+ ///
+ [SugarColumn(ColumnName = "OBJID", IsPrimaryKey = true, IsIdentity = true)]
+ public int ObjId { get; set; }
+
+ [SugarColumn(ColumnName = "BOM_CODE")]
+ public string bomCode { get; set; }
+ }
+}
diff --git a/HighWayIot.Repository/domain/BaseDeviceinfo.cs b/HighWayIot.Repository/domain/BaseDeviceinfo.cs
new file mode 100644
index 0000000..168d352
--- /dev/null
+++ b/HighWayIot.Repository/domain/BaseDeviceinfo.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using SqlSugar;
+namespace HighWayIot.Repository.domain
+{
+ ///
+ /// 设备信息
+ ///
+ [SugarTable("base_deviceInfo")]
+ public class BaseDeviceinfo
+ {
+ ///
+ /// 主键标识
+ ///
+ [SugarColumn(ColumnName="objId" ,IsPrimaryKey = true ,IsIdentity = true )]
+ public int ObjId { get; set; }
+ ///
+ /// 机台编号
+ ///
+ [SugarColumn(ColumnName="process_Id" )]
+ public int? ProcessId { get; set; }
+ ///
+ /// 位置编号
+ ///
+ [SugarColumn(ColumnName="position_Id" )]
+ public int? PositionId { get; set; }
+ ///
+ /// 设备编号
+ ///
+ [SugarColumn(ColumnName="device_Id" )]
+ public int? DeviceId { get; set; }
+ ///
+ /// 设备名称
+ ///
+ [SugarColumn(ColumnName="device_Name" )]
+ public string DeviceName { get; set; }
+ ///
+ /// 设备 IP
+ ///
+ [SugarColumn(ColumnName="device_Ip" )]
+ public string DeviceIp { get; set; }
+ ///
+ /// 设备端口
+ ///
+ [SugarColumn(ColumnName="device_Port" )]
+ public int? DevicePort { get; set; }
+ ///
+ /// 设备天线
+ ///
+ [SugarColumn(ColumnName="device_Ant" )]
+ public int? DeviceAnt { get; set; }
+ ///
+ /// 设备类型
+ ///
+ [SugarColumn(ColumnName="device_Type" )]
+ public string DeviceType { get; set; }
+ }
+}
diff --git a/HighWayIot.Repository/domain/SysUserInfo.cs b/HighWayIot.Repository/domain/SysUserInfo.cs
new file mode 100644
index 0000000..9421e5d
--- /dev/null
+++ b/HighWayIot.Repository/domain/SysUserInfo.cs
@@ -0,0 +1,37 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Principal;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.domain
+{
+ ///
+ /// 用户信息
+ ///
+ [SugarTable("sys_user")]
+ public class SysUserInfo
+ {
+ ///
+ /// 用户Id,自增主键
+ ///
+ [SugarColumn(ColumnName = "user_id", IsPrimaryKey = true, IsIdentity = true)]
+ public int userId { get; set; }
+
+ ///
+ /// 用户名称
+ ///
+ [SugarColumn(ColumnName = "user_name")]
+ public string userName { get; set; }
+
+ ///
+ /// 用户密码
+ ///
+ [SugarColumn(ColumnName = "password")]
+ public string password { get; set; }
+
+ }
+}
+
diff --git a/HighWayIot.Repository/service/IBaseBomInfoService.cs b/HighWayIot.Repository/service/IBaseBomInfoService.cs
new file mode 100644
index 0000000..bb83271
--- /dev/null
+++ b/HighWayIot.Repository/service/IBaseBomInfoService.cs
@@ -0,0 +1,14 @@
+using HighWayIot.Repository.domain;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.service
+{
+ public interface IBaseBomInfoService
+ {
+ List GetBomInfos();
+ }
+}
diff --git a/HighWayIot.Repository/service/IBaseDeviceinfoService.cs b/HighWayIot.Repository/service/IBaseDeviceinfoService.cs
new file mode 100644
index 0000000..5d410e9
--- /dev/null
+++ b/HighWayIot.Repository/service/IBaseDeviceinfoService.cs
@@ -0,0 +1,20 @@
+using HighWayIot.Repository.domain;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.service
+{
+ public interface IBaseDeviceinfoService
+ {
+ ///
+ /// 根据工序编号获取设备集合
+ ///
+ ///
+ ///
+ List GetDeviceInfoListByProcessId(int ProcessId);
+
+ }
+}
diff --git a/HighWayIot.Repository/service/ISysUserInfoService.cs b/HighWayIot.Repository/service/ISysUserInfoService.cs
new file mode 100644
index 0000000..0540e05
--- /dev/null
+++ b/HighWayIot.Repository/service/ISysUserInfoService.cs
@@ -0,0 +1,19 @@
+using HighWayIot.Repository.domain;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.service
+{
+ public interface ISysUserInfoService
+ {
+
+ ///
+ /// 获取用户列表
+ ///
+ ///
+ List GetUserInfos( );
+ }
+}
diff --git a/HighWayIot.Repository/service/Impl/BaseBomInfoServiceImpl.cs b/HighWayIot.Repository/service/Impl/BaseBomInfoServiceImpl.cs
new file mode 100644
index 0000000..8764b80
--- /dev/null
+++ b/HighWayIot.Repository/service/Impl/BaseBomInfoServiceImpl.cs
@@ -0,0 +1,30 @@
+using HighWayIot.Log4net;
+using HighWayIot.Repository.domain;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.service.Impl
+{
+ public class BaseBomInfoServiceImpl:IBaseBomInfoService
+ {
+ Repository _bomInfoRepository => new Repository("aucma_mes");
+
+ private LogHelper logHelper = LogHelper.Instance;
+
+ public List GetBomInfos()
+ {
+ try
+ {
+ var info = _bomInfoRepository.GetList();
+ return info;
+ }catch(Exception ex)
+ {
+ logHelper.Error("获取BOM集合异常", ex);
+ return null;
+ }
+ }
+ }
+}
diff --git a/HighWayIot.Repository/service/Impl/BaseDeviceinfoServiceImpl.cs b/HighWayIot.Repository/service/Impl/BaseDeviceinfoServiceImpl.cs
new file mode 100644
index 0000000..6b76af9
--- /dev/null
+++ b/HighWayIot.Repository/service/Impl/BaseDeviceinfoServiceImpl.cs
@@ -0,0 +1,23 @@
+using HighWayIot.Repository.domain;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.service.Impl
+{
+ public class BaseDeviceinfoServiceImpl : IBaseDeviceinfoService
+ {
+ Repository _deviceInfoRepository => new Repository("mysql");
+
+
+ public List GetDeviceInfoListByProcessId(int ProcessId)
+ {
+ Expression> exp = s1 => s1.ProcessId == ProcessId;
+ List deviceinfos = _deviceInfoRepository.GetList(exp);
+ return deviceinfos;
+ }
+ }
+}
diff --git a/HighWayIot.Repository/service/Impl/BaseSysUserInfoServiceImpl.cs b/HighWayIot.Repository/service/Impl/BaseSysUserInfoServiceImpl.cs
new file mode 100644
index 0000000..f0c84d5
--- /dev/null
+++ b/HighWayIot.Repository/service/Impl/BaseSysUserInfoServiceImpl.cs
@@ -0,0 +1,30 @@
+using HighWayIot.Log4net;
+using HighWayIot.Repository.domain;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Repository.service.Impl
+{
+ public class BaseSysUserInfoServiceImpl : ISysUserInfoService
+ {
+ private LogHelper log = LogHelper.Instance;
+ Repository _repository => new Repository("mysql");
+
+ public List GetUserInfos()
+ {
+ try
+ {
+ List deviceInfo = _repository.GetList();
+ return deviceInfo;
+ }catch (Exception ex)
+ {
+ log.Error("用户信息获取异常", ex);
+ return null;
+ }
+ }
+ }
+}
diff --git a/HighWayIot.Rfid/Dto/MessagePack.cs b/HighWayIot.Rfid/Dto/MessagePack.cs
new file mode 100644
index 0000000..def98b6
--- /dev/null
+++ b/HighWayIot.Rfid/Dto/MessagePack.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Rfid.Dto
+{
+ public class MessagePack
+ {
+ //public byte m_beginChar1 = 0xBB; //开始包
+ public byte[] m_pData = null; //发送数据
+ //public byte m_EndChar1 = 0x0D; //结束包
+ }
+}
diff --git a/HighWayIot.Rfid/HighWayIot.Rfid.csproj b/HighWayIot.Rfid/HighWayIot.Rfid.csproj
new file mode 100644
index 0000000..efeb9f3
--- /dev/null
+++ b/HighWayIot.Rfid/HighWayIot.Rfid.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {29813574-49C0-4979-A5A6-47EB7C4288A0}
+ Library
+ Properties
+ HighWayIot.Rfid
+ HighWayIot.Rfid
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\HighWayIot.Library\GRreader.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {89a1edd9-d79e-468d-b6d3-7d07b8843562}
+ HighWayIot.Common
+
+
+ {deabc30c-ec6f-472e-bd67-d65702fdaf74}
+ HighWayIot.Log4net
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.Rfid/ICommunicateService.cs b/HighWayIot.Rfid/ICommunicateService.cs
new file mode 100644
index 0000000..0c9c915
--- /dev/null
+++ b/HighWayIot.Rfid/ICommunicateService.cs
@@ -0,0 +1,18 @@
+using HighWayIot.Rfid.Dto;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Rfid
+{
+ public interface ICommunicateService
+ {
+ void Init(string strIp, int iPort, object objetcter);
+ bool SendMessage(MessagePack pMessagePack);
+ bool Connect();
+ bool GetState();
+ bool DisConnect();
+ }
+}
diff --git a/HighWayIot.Rfid/IDeviceAdapter.cs b/HighWayIot.Rfid/IDeviceAdapter.cs
new file mode 100644
index 0000000..3e9945d
--- /dev/null
+++ b/HighWayIot.Rfid/IDeviceAdapter.cs
@@ -0,0 +1,216 @@
+using GRreader;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot.Rfid
+{
+ public delegate void RecvIdentifyData(ushort iLen, byte[] pData, byte Antenna, UInt16 iDeviceId, string strId);
+
+ public enum G2MemBank
+ {
+ RESERVED = 0, //保留区
+ EPC = 1,
+ TID = 2,
+ USER = 3,
+ };
+
+ public enum CommType
+ {
+ RJ45 = 1, //网口
+ RS232 = 2, //com口
+ RS485 = 3, //485接口
+ };
+ public enum DeviceType
+ {
+ Mesnac_PKRK = 1, //软控物联网读写器一体机_GRUI160
+ Alien_9650 = 2, //Alien9650
+ ThingMagic_Vega = 3, //ThingMagic车载读写器
+ Mesnac_LD = 4, //软控磊德
+ Mesnac_GRUV100 = 5, //软控物联网车载读写器_GRUV100
+ Mesnac_GRUR445 = 6, //软控物联网四端口读写器
+ GzgDevice = 7, //干燥柜
+
+ ZlanIO_101 = 101, //卓岚IO
+ Moxa_E1212 = 102, //摩砂E1212
+ HwIo8 = 103, //海威
+ RFU620 = 620, //SICK 读写器
+ RFly_I160 = 160,//金瑞铭RFly-I160读写器
+ HWKC_81600 = 81600,//海威IO设备
+ Fuchs = 104
+ };
+
+ public enum WriteOrRead
+ {
+ Write = 1, //写
+ Read = 2, //读
+ };
+
+ ///
+ /// 设备适配层接口
+ ///
+ public interface IDeviceAdapter
+ {
+ event RecvIdentifyData RecvIdentifyDataEvent;
+
+ ///
+ /// 设备初始化
+ ///
+ /// true成功,false失败
+ /// 通讯类型 1,RJ45 2,串口。
+ /// 连接字符串 当iCommType为1时,pUrl格式“192.168.1.100:23”,为2时,pUrl格式为:“Com1:9600“
+ /// 详见DeviceType
+ bool Device_Init(CommType iCommType, string pUrl, DeviceType iDeviceType);
+
+ ///
+ /// 设备初始化
+ ///
+ /// true成功,false失败
+ /// 通讯类型 1,RJ45 2,串口。
+ /// 连接字符串 当iCommType为1时,pUrl格式“192.168.1.100:23”,为2时,pUrl格式为:“Com1:9600“
+ /// 详见DeviceType
+ bool Device_Init_Id(CommType iCommType, string pUrl, UInt16 iDeviceId);
+
+ ///
+ /// 连接设备
+ ///
+ /// true成功,false失败
+ bool Device_Connect();
+
+ ///
+ /// 重新连接设备
+ ///
+ /// true成功,false失败
+ bool Device_ReConnect();
+
+ ///
+ /// 设备销毁
+ ///
+ void Device_Destroy();
+
+ ///
+ /// 设备状态
+ ///
+ /// true正常,false异常
+ bool Device_GetState();
+
+ ///
+ /// 根据天线号读取单个标签数据,只返回一条
+ /// //只有在天线号为0的时候可以读写其他区的数据
+ ///
+ /// 实际读取到的长度,0为读取失败
+ /// 过滤数据区域 1,保留区 2,TID区 3,EPC区 4,USER区
+ /// 过滤写入起始偏移地址,单位byte
+ /// 过滤长度,单位byte
+ /// 过滤数据
+ /// 数据区哉 1,保留区 2,TID区 3,EPC区 4,USER区
+ /// 读取起始偏移地址,单位byte,必须为偶数。
+ /// 读取长度,单位byte,必须为偶数。
+ /// 读取数据存放区。
+ /// 天线号,0为本机,255为所有天线
+ UInt16 Device_Read(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData, G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, ref Byte[] pReadData, byte Antenna);
+
+ ///
+ /// 根据天线号写单个标签数据
+ /// //只有在天线号为0的时候可以写其他区的数据
+ ///
+ /// 0,写失败 1,写入成功 2,写入和读取的不一致
+ /// 过滤数据区哉 1,保留区 2,TID区 3,EPC区 4,USER区
+ /// 过滤写入起始偏移地址,单位byte
+ /// 过滤写入长度,单位byte
+ /// 过滤数据
+ /// 数据区哉 1,保留区 2,TID区 3,EPC区 4,USER区
+ /// 写入起始偏移地址,单位byte,必须为偶数。
+ /// 写入长度,单位byte,必须为偶数。
+ /// 待写入的数据
+ /// 天线号,0为本机,255为所有天线
+ UInt16 Device_Write(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
+ G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, Byte[] pWriteData, byte Antenna);
+
+ ///
+ /// 根据天线号识别单个标签EPC数据,只返回一条
+ ///
+ /// 识别的标签EPC长度,0为识别失败
+ /// 识别到的数据缓存区
+ /// 天线号,0为本机,255为所有天线
+ /// 超时时间,单位毫秒,识别到立即返回,未识别到等待超时返回
+ Byte Device_GetOneIdentifyData(ref Byte[] pReadData, Byte Antenna, UInt16 Timedout);
+
+ ///
+ /// 根据天线号识别单个标签EPC数据,只返回一条
+ ///
+ /// 识别的标签EPC长度,0为识别失败
+ /// 识别到的数据缓存区
+ /// 天线号,0为本机,255为所有天线
+ /// 超时时间,单位毫秒,统计时间内读到的次数,返回次数最多的一条
+ Byte Device_GetOneIdentifyData_Finish(ref Byte[] pReadData, Byte Antenna, UInt16 Timedout);
+
+ ///
+ /// 根据天线号识别单个标签EPC数据,只返回一条
+ ///
+ /// EPC数据,例"4A474730303130323332",为""时失败
+ /// 天线号,0为本机,255为所有天线
+ /// 超时时间,单位毫秒,识别到立即返回,未识别到等待超时返回
+ string Device_GetOneIdentifyData(Byte Antenna, UInt16 Timedout);
+
+ ///
+ /// 根据天线号识别单个标签EPC数据,只返回一条
+ ///
+ /// EPC数据,例"4A474730303130323332",为""时失败
+ /// 天线号,0为本机,255为所有天线
+ /// 超时时间,单位毫秒,统计时间内读到的次数,返回次数最多的一条
+ string Device_GetOneIdentifyData_Finish(Byte Antenna, UInt16 Timedout);
+
+ ///
+ /// 开始工作,读写器为开始识别,其他设备待定义
+ ///
+ /// true正常,false异常
+ /// 是否自动上报,1自动,0不自动,默认0
+ /// 过滤规则,默认为0无规则, 后续待定
+ bool Device_BeginIdentify();
+
+ ///
+ /// 停止识别,读写器为停止识别,其他设备待定义
+ ///
+ /// true正常,false异常
+ bool Device_StopIdentify();
+
+ ///
+ /// 获取工作期间的所有数据
+ ///
+ /// 实际读取到数据的总长度包括每组数据所占的字节,0为读取失败
+ /// 数据存放区,多组数据时格式为:1字节长度+天线号+每组数据...
+ /// 天线号,0为本机,255为读取所有天线
+ UInt16 Device_GetIdentifyData(ref Byte[] pReadData, Byte Antenna);
+
+ ///
+ /// 设置天线收发功率
+ ///
+ /// true为设置成功,false为设置失败
+ /// 识别到的数据缓存区
+ /// 天线号,0为本机,255为所有天线
+ /// Write为写,Read为读
+ bool Device_SetRf(int iDbi, Byte Antenna, WriteOrRead RorW);
+
+ ///
+ /// 发送心跳报文
+ ///
+ /// 1成功,2为通讯成功,设备未返回,3为发送失败
+ byte Device_SendHeartPack();
+
+ ///
+ /// 获取自报数据
+ ///
+ /// 总长度,0为失败
+ /// 获得的自报数据,格式为长度,数据,。。。。。。长度,数据,其中长度占一个字节
+ UInt16 Device_GetReportData(ref byte[] pReadData, Byte Antenna, UInt32 Timedout);
+ ///
+ /// 四通道读写器按时间段读取数据
+ ///
+ ///
+ ///
+ List Device_GetTagInfoList(DeviceType DeviceType,int time);
+ }
+}
\ No newline at end of file
diff --git a/HighWayIot.Rfid/Impl/BgTcpClient.cs b/HighWayIot.Rfid/Impl/BgTcpClient.cs
new file mode 100644
index 0000000..10beee7
--- /dev/null
+++ b/HighWayIot.Rfid/Impl/BgTcpClient.cs
@@ -0,0 +1,817 @@
+using HighWayIot.Common;
+using HighWayIot.Log4net;
+using HighWayIot.Rfid.Dto;
+using HighWayIot.Rfid.Impl;
+using MaterialTraceability.Rfid.Impl;
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace HighWayIot.Rfid.Impl
+{
+ 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
+ };
+
+ class BgTcpClient : ICommunicateService
+ {
+
+ private LogHelper log = LogHelper.Instance;
+
+ private StringChange stringChange = StringChange.Instance;
+
+ RecvState enumRecvState = RecvState.WaitingBeginChar1_State;
+ int m_iPosition = 0;
+ UInt16 m_iFullMessageLength = 0;
+ byte m_iVerify = 0;
+ byte[] m_szFullMessage = new byte[1024]; //此数组用于状态机
+ int iBarcodeGroupCount = 0; //读取的组数
+ int iBarcodeLength = 0;//条码长度
+ int iBarcodeGroupCountFlag = 0;//组数标记
+ RFly_I160Adapter m_RFly_I160Adapter = null;
+
+ private BackgroundWorker m_bgwReceive = new BackgroundWorker();
+ private BackgroundWorker m_bgwDeal = new BackgroundWorker();
+ private string m_FsIP = "";
+ private Int32 m_FnPort = 0;
+
+ private Socket m_ClientSock = null;
+
+ private ArrayList m_FrecvData = new ArrayList();
+ private Semaphore m_Fsem = new Semaphore(0, 100000);
+ private ManualResetEvent Exitevent = new ManualResetEvent(false);
+
+ //接收线程
+ private void bgwReceive_DoWork(object sender, DoWorkEventArgs e)
+ {
+ //LogService.Instance.Debug("RFly-I160 进入 bgwReceive_DoWork 线程函数:");
+ int nPackLen = 1024;
+ byte[] buff = new byte[nPackLen];
+ while (true)
+ {
+ try
+ {
+ if (m_ClientSock != null && m_ClientSock.Connected)
+ {
+ int nCount = m_ClientSock.Receive(buff, nPackLen, 0);
+ if (nCount > 0)
+ {
+ log.RfidLog(m_FsIP + ":" + m_FnPort + " RFly-I160接收原始报文:" + bytesToHexStr(buff, nCount));
+
+ PareReceiveBufferData(buff, nCount); //调用状态机函数
+ continue;
+ }
+ else //接收错误
+ {
+ if (m_ClientSock != null)
+ {
+ m_ClientSock.Close();
+ m_ClientSock = null;
+ }
+ e.Cancel = true;
+ m_Fsem.Release();
+ }
+ }
+ else
+ {
+ e.Cancel = true;
+ if (m_ClientSock != null)
+ {
+ m_ClientSock.Close();
+ m_ClientSock = null;
+ }
+ m_Fsem.Release();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ e.Cancel = true;
+ if (m_ClientSock != null)
+ {
+ m_ClientSock.Close();
+ m_ClientSock = null;
+ }
+ log.Error("Socket接收数据线程退出",ex);
+ m_Fsem.Release();
+ return;
+ }
+ if (this.m_bgwReceive.CancellationPending)
+ {
+ e.Cancel = true;
+ if (m_ClientSock != null)
+ {
+ m_ClientSock.Close();
+ m_ClientSock = null;
+ }
+ m_Fsem.Release();
+ return;
+ }
+ }
+ }
+
+ //发送线程(包括接收后的处理)
+ private void bgwDeal_DoWork(object sender, DoWorkEventArgs e)
+ {
+ log.RfidLog("RFly-I160 进入 bgwDeal_DoWork 线程:");
+ while (true)
+ {
+ try
+ {
+ m_Fsem.WaitOne();
+
+ lock (m_FrecvData)
+ {
+ if (m_FrecvData.Count > 0)
+ {
+ byte[] buff = (byte[])m_FrecvData[0];
+ if (m_RFly_I160Adapter != null)
+ {
+ m_RFly_I160Adapter.Device_DealValidPack(buff); //处理函数
+ }
+ m_FrecvData.RemoveAt(0);
+ }
+ }
+ if (Exitevent.WaitOne(0, false))
+ {
+ e.Cancel = true;
+ log.RfidLog("Socket处理数据线程正常退出");
+ Exitevent.Reset();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ e.Cancel = true;
+ log.Error("Socket处理数据异常",ex);
+ return;
+ }
+ if (this.m_bgwDeal.CancellationPending)
+ {
+ log.RfidLog("Socket处理数据线程异常退出");
+ e.Cancel = true;
+ return;
+ }
+ }
+ }
+
+ //发送函数
+ public bool SendMessage(MessagePack pMessagePack)
+ {
+ UInt16 iPos = 0;
+ byte[] u16byte = new byte[2];
+ try
+ {
+ byte[] SendBuffer = new byte[pMessagePack.m_pData.Length]; //起始字符1
+ Array.Copy(pMessagePack.m_pData, 0, SendBuffer, iPos, pMessagePack.m_pData.Length); //数据域
+
+ log.RfidLog(m_FsIP + ":" + m_FnPort + " RFly-I160发送原始报文:" + bytesToHexStr(SendBuffer, pMessagePack.m_pData.Length));
+
+ int nCount = m_ClientSock.Send(SendBuffer, pMessagePack.m_pData.Length, SocketFlags.None);
+ if (nCount > 0) //发送成功
+ {
+ //LogInfo.Fatal("m_ClientSock.Send函数发送成功");
+ return true;
+ }
+ else
+ {
+ log.RfidLog("连接已断开,数据发送失败");
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("发送报文异常", ex);
+ return false;
+ }
+ }
+
+ #region 初始化一套函数
+ public bool Connect()
+ {
+ //连接
+ try
+ {
+ Exitevent.Reset();
+ if (m_FsIP == "" || m_FnPort == 0)
+ {
+ log.RfidLog("IP和端口号不能为空,连接失败");
+ return false;
+ }
+ if (m_ClientSock != null && GetState())
+ {
+ log.RfidLog("已经连接了");
+ return true;
+ }
+ m_ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ IPEndPoint iep = new IPEndPoint(IPAddress.Parse(m_FsIP), m_FnPort);
+ m_ClientSock.Connect(iep);
+ if (m_ClientSock.Connected)
+ {
+ try
+ {
+ if (!m_bgwReceive.IsBusy)
+ {
+ //启动接收线程
+ m_bgwReceive.DoWork += new DoWorkEventHandler(bgwReceive_DoWork);
+ m_bgwReceive.RunWorkerAsync();
+ }
+ else
+ {
+ log.RfidLog("接收线程正在运行");
+ }
+ //启动处理线程
+ if (!m_bgwDeal.IsBusy)
+ {
+ m_bgwDeal.DoWork += new DoWorkEventHandler(bgwDeal_DoWork);
+ m_bgwDeal.RunWorkerAsync();
+ }
+ else
+ {
+ log.RfidLog("处理线程正在运行");
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ log.Error("创建后台线程异常 ",ex);
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Socket连接异常 ",ex);
+ return false;
+ }
+ }
+
+ public bool DisConnect()
+ {
+ try
+ {
+ Exitevent.Set();
+ Thread.Sleep(100);
+ m_Fsem.Release();
+ if (m_ClientSock != null)
+ {
+ log.Info("关闭Socket连接 ");
+ m_ClientSock.Disconnect(false);
+ m_ClientSock.Close();
+ m_ClientSock = null;
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ log.Error("Socket连接异常 ",ex);
+ return false;
+ }
+ }
+
+ public bool GetState()
+ {
+ bool bResult = false;
+ bool blockingState = false;
+ try
+ {
+ if (m_ClientSock != null)
+ {
+ blockingState = m_ClientSock.Blocking;
+ byte[] tmp = new byte[1];
+
+ m_ClientSock.Blocking = false;
+ m_ClientSock.Send(tmp, 0, 0);
+ bResult = true;
+ Console.WriteLine("Connected!");
+ }
+ else
+ {
+ bResult = false;
+ }
+ }
+ catch (SocketException e)
+ {
+ // 10035 == WSAEWOULDBLOCK
+ if (e.NativeErrorCode.Equals(10035))
+ {
+ bResult = true;
+ Console.WriteLine("Still Connected, but the Send would block");
+ }
+ else
+ {
+ bResult = false;
+ Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
+ }
+ }
+ finally
+ {
+ if (m_ClientSock != null)
+ {
+ m_ClientSock.Blocking = blockingState;
+ }
+ }
+
+ return bResult;
+ }
+
+ public void Init(string strIp, int iPort, object objetcter)
+ {
+ Exitevent.Reset();
+ m_FsIP = strIp;
+ m_FnPort = iPort;
+ m_RFly_I160Adapter = objetcter as RFly_I160Adapter;
+ }
+ #endregion
+
+ ///
+ /// 状态机函数
+ ///
+ ///
+ ///
+ public void PareReceiveData(byte[] buffer, int iLen)
+ {
+ //LogService.Instance.Debug("RFly-I160进入状态机:");
+ m_szFullMessage = new byte[iLen];
+ for (int i = 0; i < iLen; i++)
+ {
+ switch (enumRecvState)
+ {
+ case RecvState.WaitingBeginChar1_State: //开始接受数据帧1 0xBB
+ //LogService.Instance.Debug("RFly-I160等待接收帧同步字符WaitingBeginChar1_State:0XBB");
+ Array.Clear(m_szFullMessage, 0, iLen);//清空为0
+ if (buffer[i] == 0xBB)
+ {
+ //LogService.Instance.Debug("Buffer数据为: " + StringChange.bytesToHexStr(buffer, buffer.Length));
+ 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
+ {
+ //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:温度");
+ 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
+ {
+ //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:心跳");
+ 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_Fsem.Release();
+ 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);
+ //LogService.Instance.Debug("解析的数据为: " + StringChange.bytesToHexStr(tempData, iBarcodeLength));
+
+ //m_szFullMessage[m_iPosition] = buffer[i]; //单组标签:01;两组标签:02
+ 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 == 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数据显示
+ {
+ //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:Noread");
+ m_szFullMessage[0] = 0xBB;
+ m_szFullMessage[1] = 0xDD;
+ m_szFullMessage[2] = 0x00;
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ m_iPosition = 0;
+ i = iLen;
+ enumRecvState = RecvState.WaitingBeginChar1_State;
+ }
+ //else if (buffer[i] == 0x00) //获取温度
+ //{
+ // m_szFullMessage[3] = 0x00;
+ // m_iPosition++;
+ // lock (m_FrecvData)
+ // {
+ // m_FrecvData.Add(m_szFullMessage);
+ // }
+ // m_Fsem.Release();
+ //}
+ else if (buffer[i] == 0x00) //获取温度
+ {
+ //m_szFullMessage[3] = 0x90;
+ //m_iPosition++;
+ Array.Copy(buffer, 0, m_szFullMessage, 0, 8);
+ i = 8;
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ //add by wenjy 2022-09-03
+ //m_iPosition = 0;
+ //i = iLen;
+ //enumRecvState = RecvState.WaitingBeginChar1_State;
+
+ }
+ else if (buffer[i] == 0x11)
+ {
+ //m_szFullMessage[3] = 0x00;
+ Array.Copy(buffer, 0, m_szFullMessage, 0, 7);
+ i = 7;
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ }
+ else if (buffer[i] == 0x01)
+ {
+ //m_szFullMessage[3] = 0x00;
+ Array.Copy(buffer, 0, m_szFullMessage, 0, 8);
+ i = 8;
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ }
+ else if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x04 && buffer[3] == 0xBF)
+ {
+ m_szFullMessage[3] = 0xBF;
+ m_iPosition++;
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ }
+ else
+ {
+ m_szFullMessage[m_iPosition] = buffer[i];
+ m_iPosition++;
+ if (buffer[i] == 0x0D)
+ {
+ //LogService.Instance.Debug("RFly-I160准备发送");
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ }
+ }
+ m_iPosition = 0;
+ enumRecvState = RecvState.WaitingBeginChar1_State;
+
+ //LogService.Instance.Debug("RFly-I160状态机结束。");
+ break;
+ }
+ }
+ }
+
+ ///
+ /// 状态机函数 Add By WenJy 2022-09-26
+ ///
+ ///
+ ///
+ public void PareReceiveBufferData(byte[] buffer, int iLen)
+ {
+ var bufferStr = stringChange.bytesToHexStr(buffer, iLen);
+ log.RfidLog(String.Format("进入状态机函数:{0}", bufferStr));
+ 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
+ {
+ //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:温度");
+ 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
+ {
+ //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:心跳");
+ 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_Fsem.Release();
+ 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 == 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_Fsem.Release();
+ 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);
+ }
+ m_Fsem.Release();
+ 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);
+ }
+ m_Fsem.Release();
+ 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);
+ }
+ m_Fsem.Release();
+ }
+ else if (buffer[i] == 0x01)
+ {
+ Array.Copy(buffer, 0, m_szFullMessage, 0, 8);
+ i = 8;
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ }
+ else
+ {
+ m_szFullMessage[m_iPosition] = buffer[i];
+ m_iPosition++;
+ if (buffer[i] == 0x0D)
+ {
+ lock (m_FrecvData)
+ {
+ m_FrecvData.Add(m_szFullMessage);
+ }
+ m_Fsem.Release();
+ }
+ }
+ m_iPosition = 0;
+ enumRecvState = RecvState.WaitingBeginChar1_State;
+ break;
+ }
+ }
+ }
+ //CRC异或校验
+ public byte CalculateVerify(byte[] pMessage, int iLength)
+ {
+ UInt16 i;
+ byte iVerify = 0;
+
+ iVerify = pMessage[0];
+ for (i = 1; i < iLength; i++)
+ {
+ iVerify = (byte)(iVerify ^ pMessage[i]);
+ }
+ return iVerify;
+ }
+ private byte[] Swap16Bytes(byte[] OldU16)
+ {
+ byte[] ReturnBytes = new byte[2];
+ ReturnBytes[1] = OldU16[0];
+ ReturnBytes[0] = OldU16[1];
+ return ReturnBytes;
+ }
+
+ private string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01"
+ {
+ string returnStr = "";
+ if (bytes != null)
+ {
+ for (int i = 0; i < iLen; i++)
+ {
+ returnStr += bytes[i].ToString("X2");
+ }
+ }
+ return returnStr;
+ }
+ }
+}
+
diff --git a/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS b/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS
new file mode 100644
index 0000000..72ad2ce
--- /dev/null
+++ b/HighWayIot.Rfid/Impl/RFLY_I160ADAPTER.CS
@@ -0,0 +1,1486 @@
+using GRreader;
+using HighWayIot.Common;
+using HighWayIot.Log4net;
+using HighWayIot.Rfid;
+using HighWayIot.Rfid.Dto;
+using HighWayIot.Rfid.Impl;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+namespace MaterialTraceability.Rfid.Impl
+{
+ [ClassInterface(ClassInterfaceType.None)]
+ public class RFly_I160Adapter : IDeviceAdapter
+ {
+ private LogHelper log = LogHelper.Instance;
+ private StringChange stringChange = StringChange.Instance;
+ private JsonChange jsonChange = JsonChange.Instance;
+
+ #region 全局变量声明
+ List m_TagInfoList = new List();
+ CommType gConnetType = new CommType();
+ private DeviceType m_iDeviceType = DeviceType.RFly_I160;
+ private DeviceType DeviceType;
+ ICommunicateService m_ICommunicateService = null;
+ public UHFreader MyReader = new UHFreader();
+ public event RecvIdentifyData RecvIdentifyDataEvent = null;
+ public UInt16 m_iDeviceId = 0;
+ private string m_strIp; //读写器IP或串口号
+ private int m_iPort; //读写器端口号或波特率
+ private readonly string m_ReadDbm = "10";
+ private readonly string m_WriteDbm = "10";
+ private readonly string m_AnalysisFlag = "1"; //1:按照次数最多返回条码;2:按照平均功率最大返回条码
+ 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 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 bool m_OneEpcSemSuccessful = false;
+ private Semaphore m_OneEpcSem = new Semaphore(0, 100000);
+
+ private bool m_ReadDataSuccessful = false;
+ private bool m_Device_ReadSuccessful = false;
+ private byte m_ReadDataLen = 0;
+ private byte[] m_ReadData = null;
+ private Semaphore m_ReadSem = new Semaphore(0, 100000);
+ private Semaphore m_WriteSem = 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_OneEpcAntenna = 254;
+ private byte[] m_OneEpcData = null;
+ private bool m_GetReadNoDataSuccessful;
+ private bool writeResult = false;
+ #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);
+ log.RfidLog("设备初始化成功,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);
+ log.RfidLog("设备初始化成功,串口号:" + m_strIp + "波特率:" + m_iPort);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("连接读写器异常:",ex);
+ 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())
+ {
+ log.RfidLog("Device_Connect:连接成功");
+ return true;
+ }
+ else
+ {
+ log.RfidLog("Device_Connect:连接失败");
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Device_Connect异常:",ex);
+ return false;
+ }
+ }
+
+ public void Device_Destroy()
+ {
+ m_ICommunicateService.DisConnect();
+ }
+
+ public bool Device_GetState()
+ {
+ return m_ICommunicateService.GetState();
+ }
+
+ public bool Device_ReConnect()
+ {
+ log.RfidLog("Device_Connect 调用重连函数!");
+ return Device_Connect();
+ }
+ #endregion
+ public bool Device_DealValidPack(byte[] ValidData)
+ {
+ byte bAntana = 0; //读写器天线号 默认0x04
+ UInt16 iReadCount = 0; //标签读取次数
+ UInt16 iRSSI = 0; //标签信号强度
+ byte[] bResultEPC_Data = new byte[14];
+ byte[] bNoData = new byte[12];
+ try
+ {
+ byte info = ValidData[3];
+ switch (info) //心跳
+ {
+ case 0X90:
+ m_GetHeartSuccessful = true;
+ Console.WriteLine("Device_DealValidPack处理函数:" + stringChange.bytesToHexStr(ValidData, ValidData.Length));
+ try
+ {
+ log.SemaphoreLog("信号量m_GetHeartSem释放");
+ m_GetHeartSem.Release();
+ }
+ catch (Exception ex)
+ {
+ log.Error("心跳信号量处理异常", ex);
+ log.SemaphoreLog("信号量m_GetHeartSem释放异常:" + ex.Message);
+ }
+ break;
+ case 0x02:
+ if (ValidData[2] == 0x00 || ValidData[2] == 0x01)
+ {
+ log.RfidLog("----函数调用:Device_DealValidPack:NoRead!");
+ m_BarcodeGroupCount = 0;
+ m_GetReadNoDataSuccessful = true;
+ m_OneEpcDataLen = 0;
+ }
+ else
+ {
+
+ log.RfidLog("----函数调用:Device_DealValidPack 有数据!");
+
+ m_BarcodeGroupCount = Convert.ToInt32(ValidData[5].ToString()); //标签组数TagCount
+ m_MulAllData = new byte[ValidData.Length];
+ Array.Clear(m_MulAllData, 0, ValidData.Length);
+ Array.Copy(ValidData, 0, m_MulAllData, 0, ValidData.Length);
+
+ Array.Copy(m_MulAllData, 11, bResultEPC_Data, 0, 14);
+ m_ReadDataLen = 14;
+ m_OneEpcDataLen = 14;
+ m_OneEpcData = new byte[m_OneEpcDataLen];
+
+
+ bAntana = ValidData[8];
+ m_OneEpcAntenna = ValidData[8];
+ iReadCount = ValidData[6];
+ iRSSI = ValidData[7];
+
+ //DeviceType 改为 m_iDeviceType,原代码为DeviceType,因测试一体机没有赋值改为m_iDeviceType
+
+ //四通道读写器业务逻辑
+ if (DeviceType == DeviceType.Mesnac_GRUR445)
+ {
+ m_TagInfoList = Device_DealTagInfoList2(m_MulAllData);
+
+ }
+ else
+ {
+ m_TagInfoList = Device_AutoDealContent(m_MulAllData);
+ }
+ //m_OneEpcSem.Release();
+ //m_ReadSem.Release();
+ //log.RfidLog("----有数据,释放信号量!");
+ }
+ try
+ {
+ log.SemaphoreLog("信号量m_OneEpcSem,释放");
+ m_OneEpcSem.Release();
+ //log.SemaphoreLog("信号量m_GlobalSem,释放");
+ //m_GlobalSem.Release();
+ }
+ catch(Exception e)
+ {
+ log.Error("释放信号量错误!"+e.ToString());
+ log.SemaphoreLog("释放信号量错误:"+e.Message);
+ }
+ break;
+ default:
+ log.RfidLog("Device_DealValidPack处理函数:" + stringChange.bytesToHexStr(ValidData, ValidData.Length));
+ Console.WriteLine("Device_DealValidPack处理函数:" + stringChange.bytesToHexStr(ValidData, ValidData.Length));
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("空间名:" + ex.Source + ";" + '\n' +
+ "方法名:" + ex.TargetSite + '\n' +
+ "故障点:" + ex.StackTrace.Substring(ex.StackTrace.LastIndexOf("\\") + 1, ex.StackTrace.Length - ex.StackTrace.LastIndexOf("\\") - 1) + '\n' +
+ "错误提示:",ex);
+ return false;
+ }
+ return true;
+ }
+
+ public byte Device_SendHeartPack()
+ {
+ byte iResult = 0;
+ try
+ {
+ log.RfidLog("函数调用:Device_SendHeartPack");
+ //m_GlobalSem.WaitOne(-1, false);
+ MessagePack pMessagePack = new MessagePack();
+ pMessagePack.m_pData = new byte[9];
+ Array.Clear(pMessagePack.m_pData, 0, 1);//清空为0
+ //获取温度
+ pMessagePack.m_pData[0] = 0xAA;
+ pMessagePack.m_pData[1] = 0x55;
+ pMessagePack.m_pData[2] = 0x00;
+ pMessagePack.m_pData[3] = 0x90;
+ pMessagePack.m_pData[4] = 0x90;
+ pMessagePack.m_pData[5] = 0x0D;
+ m_GetHeartSem.WaitOne(1, false);
+ log.SemaphoreLog("信号量m_GetHeartSem,WaitOne(1, false)");
+ if (m_ICommunicateService != null)
+ {
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ log.SemaphoreLog("信号量m_GetHeartSem,WaitOne(9000, false)");
+ if (m_GetHeartSem.WaitOne(5000, false)) //等待结果,并取结果返回。
+ {
+ if (m_GetHeartSuccessful)
+ {
+ //log.RfidLog("发送心跳正常。");
+ iResult = 1; //通讯连接和读写器都正常
+ }
+ }
+ else //超时
+ {
+ log.SemaphoreLog("信号量m_GetHeartSem,发送心跳超时");
+ log.RfidLog("发送心跳超时。");
+ iResult = 2; //通讯连接器正常,读写器故障
+ };
+ }
+ else
+ {
+ //通讯连接器失败或网络故障
+ log.RfidLog("发送心跳报文失败,通讯故障。");
+ iResult = 3;
+ }
+ }
+ else
+ {
+ //m_GetHeartSem.Release();
+ return 3;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.RfidLog("Device_SendHeartPack:"+ex.Message);
+ iResult = 3;
+ }
+ finally
+ {
+ //m_GlobalSem.Release();
+ //m_GetHeartSem.Release();
+ }
+ return iResult;
+ }
+ public ushort Device_GetReportData(ref byte[] pReadData, Byte Antenna, UInt32 Timedout)
+ {
+ byte[] pTemp = null;
+ byte iReadLen = 0;
+ if ((iReadLen = Device_GetOneIdentifyData(ref pTemp, Antenna, (UInt16)Timedout)) > 0)
+ {
+ // log.RfidLog("Device_GetReportData获取自报数据" + "数据长度" + iReadLen);
+ pReadData = new byte[iReadLen + 1];
+ pReadData[0] = iReadLen;
+ Array.Copy(pTemp, 0, pReadData, 1, iReadLen);
+ return (ushort)(iReadLen + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ ///
+ /// 根据天线号识别单个标签EPC数据,只返回读到的第一条数据
+ ///
+ /// 识别的标签EPC长度,0为识别失败
+ /// 识别到的数据缓存区
+ /// 天线号,0为本机,255为所有天线
+ /// 超时时间,单位毫秒,识别到立即返回,未识别到等待超时返回
+ public Byte Device_GetOneIdentifyData(ref Byte[] pReadData, Byte Antenna, UInt16 Timedout)
+ {
+ byte[] u16byte = new byte[2];
+ byte iResult = 0;
+ byte[] bCRC = new byte[4];
+ try
+ {
+ m_GlobalSem.WaitOne(1, false);
+ //log.RfidLog("函数调用:Device_GetOneIdentifyData");
+ if (Antenna == 0) //此版本4为主机
+ {
+ Antenna = (byte)(Antenna + 1);
+ }
+
+ MessagePack pMessagePack = new MessagePack();
+
+ //A5 5A 00 0A 80 00 64 EE 0D 0A //100毫秒的示例
+ 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;
+ //pMessagePack.m_pData[4] = 0x03;
+ //pMessagePack.m_pData[5] = 0xE8;
+ u16byte = BitConverter.GetBytes(Timedout); //超时时间
+ u16byte = stringChange.Swap16Bytes(u16byte); //协议里为大端在前
+ //log.RfidLog("u16byte:" + 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;
+ //log.RfidLog("pMessagePack.m_pData:" + pMessagePack.m_pData);
+ //int i = m_OneEpcSem.Release(1);
+ m_OneEpcSem.WaitOne(1, false);
+ m_OneEpcDataLen = 0;
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ m_ReadDataSuccessful = true;
+ if (m_OneEpcSem.WaitOne(Timedout + 1000, false)) //等待结果,并取结果返回。
+ {
+ if ((m_OneEpcDataLen > 0 && m_OneEpcAntenna == Antenna)) //有数据,正常
+ {
+ pReadData = new byte[14];
+ Array.Copy(m_AutoReadEPC, 0, pReadData, 0, 14);
+ log.RfidLog("Device_GetOneIdentifyData:" + stringChange.bytesToHexStr(pReadData, pReadData.Length));
+
+ iResult = m_OneEpcDataLen;
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ m_ReadDataSuccessful = false;
+ }
+ else
+ {
+ log.RfidLog("Device_GetOneIdentifyData长度或者天线号不正确");
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ iResult = 0;
+ m_ReadDataSuccessful = false;
+ }
+ }
+ else //超时
+ {
+ iResult = 0;
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ m_ReadDataSuccessful = false;
+ log.RfidLog("Device_GetOneIdentifyData超时");
+ }
+ }
+ else
+ {
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ log.RfidLog("Device_GetOneIdentifyData发送识别单条EPC命令失败:");
+ iResult = 0;
+ m_ReadDataSuccessful = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Device_GetOneIdentifyData识别单条EPC数据异常:",ex);
+ iResult = 0;
+ m_ReadDataSuccessful = false;
+ }
+ finally
+ {
+ //m_GlobalSem.Release();
+ }
+ return iResult;
+ }
+
+ public UInt16 Device_Read(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
+ G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, ref Byte[] pReadData, byte Antenna)
+ {
+ byte[] u16byte = new byte[2];
+ byte iResult = 0;
+ try
+ {
+ m_GlobalSem.WaitOne(1, false);
+ log.RfidLog("函数调用:Device_Read");
+
+ MessagePack pMessagePack = new MessagePack();
+ pMessagePack.m_pData = new byte[8];
+ Array.Clear(pMessagePack.m_pData, 0, pMessagePack.m_pData.Length);//清空为0
+
+ pMessagePack.m_pData[0] = 0xAA;
+ pMessagePack.m_pData[1] = 0x55;
+ pMessagePack.m_pData[2] = 0x02;
+ pMessagePack.m_pData[3] = 0x02;
+ pMessagePack.m_pData[4] = 0x03;
+ pMessagePack.m_pData[5] = 0xE8;
+ pMessagePack.m_pData[6] = 0xEB;
+ pMessagePack.m_pData[7] = 0x0D;
+ //m_ReadSem.Release(1);
+ m_ReadSem.WaitOne(1, false);
+ m_ReadDataLen = 0;
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ m_ReadDataSuccessful = true;
+ if (m_ReadSem.WaitOne(2000, false)) //等待结果,并取结果返回。
+ {
+ if (m_ReadDataLen > 0) //有数据,正常
+ {
+ pReadData = new byte[m_ReadDataLen];
+ Array.Copy(m_OneEpcData, 0, pReadData, 0, m_ReadDataLen);
+ iResult = m_ReadDataLen;
+ log.RfidLog("Device_Read:" + stringChange.bytesToHexStr(pReadData, pReadData.Length));
+
+ m_ReadDataLen = 0;
+ }
+ else
+ {
+ m_ReadDataLen = 0;
+ log.RfidLog("Device_Read失败,返回长度为0");
+ iResult = 0;
+ }
+ }
+ else //超时
+ {
+ log.RfidLog("Device_Read失败,超时未返回");
+ iResult = 0;
+ }
+ }
+ else
+ {
+ log.RfidLog("发送读取命令失败");
+ iResult = 0;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("读取数据异常:",ex);
+ iResult = 0;
+ }
+ finally
+ {
+ //m_GlobalSem.Release();
+ }
+ return iResult;
+
+ }
+ public UInt16 Device_Write(G2MemBank filterMembank, UInt16 filterWordPtr, UInt16 filterWordCnt, Byte[] filterData,
+ G2MemBank Membank, UInt16 WordPtr, UInt16 WordCnt, Byte[] pWriteData, byte Antenna)
+ {
+ byte[] u16byte = new byte[2];
+ byte iResult = 0;
+ try
+ {
+ m_GlobalSem.WaitOne(1, false);
+ log.RfidLog("函数调用:Device_Write");
+ //int datalen = 36+ pWriteData.Length;
+ int datalen = 48;
+ MessagePack pMessagePack = new MessagePack();
+ pMessagePack.m_pData = new byte[datalen];
+ Array.Clear(pMessagePack.m_pData, 0, pMessagePack.m_pData.Length);//清空为0
+
+ pMessagePack.m_pData[0] = 0xAA;
+
+ pMessagePack.m_pData[1] = 0x55;
+
+ pMessagePack.m_pData[2] = (byte)(datalen - 6);//先占位
+
+ pMessagePack.m_pData[3] = 0x03;
+
+ pMessagePack.m_pData[4] = 0x00;
+
+ pMessagePack.m_pData[5] = 0x64;
+
+ pMessagePack.m_pData[6] = 0x00;
+
+ pMessagePack.m_pData[7] = 0x00;
+
+ pMessagePack.m_pData[8] = 0x00;
+
+ pMessagePack.m_pData[9] = 0x00;
+
+ pMessagePack.m_pData[10] = 0x01;
+
+ pMessagePack.m_pData[11] = 0x00;
+
+ pMessagePack.m_pData[12] = 0x00;
+
+ pMessagePack.m_pData[13] = 0x00;
+
+ pMessagePack.m_pData[14] = 0x20;
+
+ pMessagePack.m_pData[15] = 0x60;
+
+ Array.Copy(filterData, 0, pMessagePack.m_pData, 16, filterData.Length);
+
+ pMessagePack.m_pData[28] = 0x03;
+
+ pMessagePack.m_pData[29] = 0x00;
+
+ pMessagePack.m_pData[30] = 0x00;
+
+ pMessagePack.m_pData[31] = 0x00;
+
+ pMessagePack.m_pData[32] = 0x00;
+
+ pMessagePack.m_pData[33] = (byte)WordCnt;
+
+ Array.Copy(pWriteData, 0, pMessagePack.m_pData, 34, pWriteData.Length);
+
+
+ byte[] bCRC = new byte[datalen - 4];
+
+ //Array.Copy(u16byte, 0, pMessagePack.m_pData, 4, 2);
+
+ Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, bCRC.Length);
+
+ pMessagePack.m_pData[datalen - 2] = stringChange.CalculateVerify(bCRC, bCRC.Length);
+
+ pMessagePack.m_pData[datalen - 1] = 0x0D;
+
+ m_WriteSem.WaitOne(1, false);
+ m_ReadDataLen = 0;
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ m_ReadDataSuccessful = true;
+ if (m_WriteSem.WaitOne(2000, false)) //等待结果,并取结果返回。
+ {
+ //log.RfidLog("Device_Write成功");
+ if (writeResult)
+ {
+ iResult = 1;
+ }
+ }
+ else //超时
+ {
+ log.RfidLog("Device_Write失败,超时未返回");
+ iResult = 0;
+ }
+ }
+ else
+ {
+ log.RfidLog("发送写入命令失败");
+ iResult = 0;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("写入数据异常:",ex);
+ iResult = 0;
+ }
+ finally
+ {
+ //m_GlobalSem.Release();
+ }
+ return iResult;
+ }
+ ///
+ /// 返回读写器获取的条码中最好的一条 1:按照读取次数最多返回条码;2:按照功率最大返回条码
+ ///
+ /// 要处理的数据
+ /// 1:按照读取次数最多返回条码;2:按照平均功率最大返回条码
+ /// 1:打印log;0:不打印Log
+ ///
+ public byte[] CommandAnalysisBarcode(List cBarcodeObjList, int iFlag, int iPrintLogFlag)
+ {
+ byte[] tempBarcode = null;
+ if (iFlag == 1) //按次数最多获取
+ {
+ if (iPrintLogFlag == 1)
+ {
+ // log.RfidLog("----调用通用函数:CommandAnalysisBarcode Flag=1 按照最大次数选择条码,如果次数相同 ,按照平均功率最大的选择条码:");
+ }
+ #region 按照最大次数选择条码,如果次数相同 ,按照平均功率最大的选择条码
+ #region 求出最大次数
+ int iOrderMaxCount = cBarcodeObjList[0].Count;
+ for (int i = 0; i < cBarcodeObjList.Count; i++)
+ {
+ if (iPrintLogFlag == 1)
+ {
+ #region 打印所有条码 次数和平均功率
+ log.RfidLog("条码:[ " + stringChange.bytesToHexStr(cBarcodeObjList[i].EPC, cBarcodeObjList[i].EPC.Length) + " ] 次数:[ " + cBarcodeObjList[i].Count.ToString() + " ] 平均最大功率: [" + cBarcodeObjList[i].RSSI.ToString() + " ]");
+ #endregion
+ }
+
+ if (cBarcodeObjList[i].Count > iOrderMaxCount)
+ {
+ iOrderMaxCount = cBarcodeObjList[i].Count;
+ }
+ }
+ if (iPrintLogFlag == 1)
+ {
+ //LogService.Instance.Debug("按照次数优先,最大次数为:" + iOrderMaxCount.ToString());
+ }
+ #endregion
+ #region 求出等于最大次数的所有条码对象
+ List cBarcodeObjListCount = new List();
+ foreach (TagInfo itemMax in cBarcodeObjList)
+ {
+ if (itemMax.Count == iOrderMaxCount)
+ {
+ cBarcodeObjListCount.Add(itemMax);
+ //LogService.Instance.Debug("按照次数优先,等于最大次数条码为:" + stringChange.bytesToHexStr(itemMax.EPC, itemMax.EPC.Length));
+ }
+ }
+ if (iPrintLogFlag == 1)
+ {
+ //LogService.Instance.Debug("按照次数优先,等于最大次数条码数量为:" + cBarcodeObjListCount.Count.ToString());
+ }
+ #endregion
+ #region 求出最优条码
+
+ if (cBarcodeObjListCount.Count == 1) //如果只有一条
+ {
+
+ foreach (TagInfo itemCount in cBarcodeObjListCount)
+ {
+ if (itemCount.Count == iOrderMaxCount)
+ {
+ if (iPrintLogFlag == 1)
+ {
+ //log.RfidLog("---- 取出的最优条码是: " + stringChange.bytesToHexStr(itemCount.EPC, itemCount.EPC.Length));
+ }
+ tempBarcode = new byte[itemCount.EPC.Length];
+ Array.Copy(itemCount.EPC, 0, tempBarcode, 0, itemCount.EPC.Length);
+ }
+ }
+ //Add By baogq 2019年5月24日 15:29:20
+ //tempBarcode = new byte[cBarcodeObjListCount[0].EPC.Length];
+ //tempBarcode = cBarcodeObjListCount[0].EPC;
+ //Array.Copy(cBarcodeObjListCount[0].EPC, 0, tempBarcode, 0, cBarcodeObjListCount[0].EPC.Length);
+ cBarcodeObjListCount.Clear();
+ return tempBarcode;
+ }
+ else //如果有多条
+ {
+ #region 求出最大次数相同下条码的强度最强的条码
+ #region 求出最大次数相同的条码中,强度的最大值
+ float iOrderAvgMaxPower = cBarcodeObjListCount[0].RSSI;
+ for (int i = 0; i < cBarcodeObjListCount.Count; i++)
+ {
+ if (cBarcodeObjListCount[i].RSSI > iOrderAvgMaxPower)
+ {
+ iOrderAvgMaxPower = cBarcodeObjListCount[i].RSSI;
+ }
+ }
+ if (iPrintLogFlag == 1)
+ {
+ //LogService.Instance.Debug("按照次数优先,等于最大次数条码中平均功率最大值为:" + iOrderAvgMaxPower.ToString());
+ }
+
+ #endregion
+
+ foreach (TagInfo itemAvg in cBarcodeObjListCount)
+ {
+ if (itemAvg.RSSI == iOrderAvgMaxPower)
+ {
+ if (iPrintLogFlag == 1)
+ {
+ //log.RfidLog("---- 取出的最优条码是: " + stringChange.bytesToHexStr(itemAvg.EPC, itemAvg.EPC.Length));
+ }
+
+ tempBarcode = new byte[itemAvg.EPC.Length];
+ Array.Copy(itemAvg.EPC, 0, tempBarcode, 0, itemAvg.EPC.Length);
+ }
+ }
+ #endregion
+ }
+ #endregion
+ #endregion
+ return tempBarcode;
+ }
+ else if (iFlag == 2)//按照功率最大获取
+ {
+ if (iPrintLogFlag == 1)
+ {
+ //log.RfidLog("----调用通用函数:CommandAnalysisBarcode Flag=2 按照最大平均功率取出条码,如果最大平均功率相同,则按照次数最大取值最优条码:");
+ }
+ #region 按照最大平均功率取出条码,如果最大功率相同,则按照次数最大取值最优条码
+ #region 求出最大功率
+ int iMaxAvgPow = cBarcodeObjList[0].RSSI;
+ for (int i = 0; i < cBarcodeObjList.Count; i++)
+ {
+ if (iPrintLogFlag == 1)
+ {
+ #region 打印所有条码 次数和平均功率
+ log.RfidLog("条码:[ " + stringChange.bytesToHexStr(cBarcodeObjList[i].EPC, cBarcodeObjList[i].EPC.Length) + " ] 平均最大功率: [" + cBarcodeObjList[i].RSSI.ToString() + " ] 次数:[ " + cBarcodeObjList[i].Count.ToString() + " ] ");
+ #endregion
+ }
+
+ if (cBarcodeObjList[i].RSSI > iMaxAvgPow)
+ {
+ iMaxAvgPow = cBarcodeObjList[i].RSSI;
+ }
+ }
+ if (iPrintLogFlag == 1)
+ {
+ //LogService.Instance.Debug("按照平均功率最大,最大平均功率为:" + iMaxAvgPow.ToString());
+ }
+ #endregion
+ #region 求出等于最大功率的所有条码对象
+ List cBarcodeObjListCount = new List();
+ foreach (TagInfo itemMax in cBarcodeObjList)
+ {
+ if (itemMax.RSSI == iMaxAvgPow)
+ {
+ cBarcodeObjListCount.Add(itemMax);
+ }
+ }
+ if (iPrintLogFlag == 1)
+ {
+ //LogService.Instance.Debug("按照平均功率最大,最大平均功率相同的条码数量为:" + cBarcodeObjListCount.Count.ToString());
+ }
+ #endregion
+ #region 求出最优条码
+ //如果只有一条
+ if (cBarcodeObjListCount.Count == 1)
+ {
+ if (iPrintLogFlag == 1)
+ {
+ // log.RfidLog("---- 取出的最优条码是: " + stringChange.bytesToHexStr(cBarcodeObjList[0].EPC, cBarcodeObjList[0].EPC.Length));
+ }
+
+ tempBarcode = new byte[cBarcodeObjListCount[0].EPC.Length];
+ Array.Copy(cBarcodeObjListCount[0].EPC, 0, tempBarcode, 0, cBarcodeObjListCount[0].EPC.Length);
+ }
+ else //如果有多条
+ {
+ #region 求出平均功率最大相同时,条码读到次数最多的一个条码
+ #region 求出平均功率最大相同条码中,最大的次数
+ int iReadMaxCount = cBarcodeObjListCount[0].Count;
+ for (int i = 0; i < cBarcodeObjListCount.Count; i++)
+ {
+ if (cBarcodeObjListCount[i].Count > iReadMaxCount)
+ {
+ iReadMaxCount = cBarcodeObjListCount[i].Count;
+ }
+ }
+ if (iPrintLogFlag == 1)
+ {
+ //LogService.Instance.Debug("在最大平均功率相同的条码中,读取次数最多为:" + iReadMaxCount.ToString());
+ }
+ #endregion
+ foreach (TagInfo itemReadCount in cBarcodeObjListCount)
+ {
+ if (itemReadCount.Count == iReadMaxCount)
+ {
+ if (iPrintLogFlag == 1)
+ {
+ // log.RfidLog("---- 取出的最优条码是: " + stringChange.bytesToHexStr(itemReadCount.EPC, itemReadCount.EPC.Length));
+ }
+
+ tempBarcode = new byte[itemReadCount.EPC.Length];
+ Array.Copy(itemReadCount.EPC, 0, tempBarcode, 0, itemReadCount.EPC.Length);
+ }
+ }
+ #endregion
+ }
+ #endregion
+ #endregion
+ return tempBarcode;
+ }
+ else
+ {
+ return tempBarcode;
+ }
+
+ }
+
+
+ #region 处理自动上传的函数
+ private Mutex mutauto = new Mutex();
+
+ ///
+ /// 四通道读写器标签逻辑处理
+ ///
+ ///
+ ///
+ public List Device_DealTagInfoList(byte[] AutoDealReportData)
+ {
+ List tagInfoList = new List();
+
+ byte[] bResultEPC_Data = new byte[14];
+ m_AutoReadEPC = null;
+ m_readEPCDataLen = 0;
+ //LogService.Instance.Debug("----函数调用:Device_AutoDealContent 开始!");
+ 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[] tempDataByte = new byte[iBarcodeLength];
+ 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 = tempRSSIByte[0];
+ tempDataRSSI = stringChange.HexStringToNegative(stringChange.bytesToHexStr(tempRSSIByte, 1));
+
+ byte[] tempPCByte = new byte[2]; //取出PC
+ Array.Clear(tempPCByte, 0, 2);
+ Array.Copy(AutoDealReportData, iFirstPC, tempPCByte, 0, 2);
+ //tempPCByte = tempPCByte[0];
+
+ #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;
+ tag.EPCstring = System.Text.Encoding.ASCII.GetString(tempDataByte);
+ //tag.EPCstring = stringChange.bytesToHexStr(tempDataByte, tempDataByte.Length);
+ tag.PC = tempPCByte;
+ tag.Antana = tempDataANT;
+ tagInfoList.Add(tag);
+ int iBarcodeListLen = tagInfoList.Count; //特别注意,必须这样,要不然会多一条数据
+
+ //int iFirstCountPos = 6; //第一次读取标签次数位置
+ //int iFirstRSSIPos = 7; //第一次读取标签强度位置
+ //int iFirstAnt = 8; //第一次读取标签天线位置
+ //int iFirstLeftBarcketPos = 11;//EPC数据起始位置
+
+ iFirstCountPos = iFirstCountPos + 21; //次数
+ iFirstRSSIPos = iFirstCountPos + 1; //强度
+ iFirstAnt = iFirstRSSIPos + 1; //天线
+ iFirstPC = iFirstAnt + 1;
+ iFirstLeftBarcketPos = iFirstLeftBarcketPos + 21;
+
+ log.RfidLog("----函数调用:Device_AutoDealContent 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + tag.EPCstring + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]");
+ iCommonSecondFlag++;
+ if (iCommonSecondFlag == iBarcodeGroupCount)
+ {
+ mutauto.ReleaseMutex();
+ log.RfidLog("《《《返回标签数据!");
+ return tagInfoList;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ log.RfidLog("----函数调用:Device_AutoDealContent 自动处理函数异常:" + ex.ToString());
+ mutauto.ReleaseMutex();
+ }
+ return tagInfoList;
+ }
+
+ public List Device_DealTagInfoList2(byte[] AutoDealReportData)
+ {
+ List tagInfoList = new List();
+ byte[] bResultEPC_Data = new byte[14];
+ m_AutoReadEPC = null;
+ 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 = System.Text.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;
+
+ log.RfidLog("----函数调用:Device_DealTagInfoList2 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + tag.EPCstring + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]");
+ iCommonSecondFlag++;
+ if (iCommonSecondFlag == iBarcodeGroupCount)
+ {
+ mutauto.ReleaseMutex();
+ log.RfidLog("《《《返回标签数据!");
+ return tagInfoList;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ log.RfidLog("----函数调用:Device_AutoDealContent 自动处理函数异常:" + ex.ToString());
+ mutauto.ReleaseMutex();
+ }
+ return tagInfoList;
+ }
+
+ 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;
+ }
+
+ ///
+ /// 一体机读写器标签逻辑处理
+ ///
+ ///
+ ///
+ public List Device_AutoDealContent(byte[] AutoDealReportData)
+ {
+ List tagInfoList = new List();
+
+ byte[] bResultEPC_Data = new byte[12];
+ m_AutoReadEPC = null;
+ m_readEPCDataLen = 0;
+ try
+ {
+ mutauto.WaitOne();
+ int iFirstCountPos = 6; //第一次读取标签次数位置
+ int iFirstRSSIPos = 7; //第一次读取标签强度位置
+ int iFirstAnt = 8; //第一次读取标签天线位置
+ int iFirstLeftBarcketPos = 11;//EPC数据起始位置
+ UInt16 tempDataCount = 0;
+ UInt16 tempDataRSSI = 0;
+ UInt16 tempDataANT = 0;
+ int iBarcodeGroupCount = Convert.ToInt32(AutoDealReportData[5].ToString()); //标签组数
+ int iBarcodeLength = 16; //标签长度
+ for (int j = 0; j < iBarcodeGroupCount; j++)
+ {
+ TagInfo tag = new TagInfo();
+
+ byte[] tempDataByte = new byte[iBarcodeLength];
+ 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 = tempRSSIByte[0];
+
+ byte[] tempAntByte = new byte[1]; //取出天线号
+ Array.Clear(tempAntByte, 0, 1);
+ Array.Copy(AutoDealReportData, iFirstAnt, tempAntByte, 0, 1);
+ tempDataANT = tempAntByte[0];
+
+ tag.Count = tempDataCount;
+ tag.RSSI = tempDataRSSI;
+ tag.EPC = tempDataByte;
+ tag.EPCstring = System.Text.Encoding.ASCII.GetString(tempDataByte);;
+ tag.Antana = tempDataANT;
+ tagInfoList.Add(tag);
+ int iBarcodeListLen = tagInfoList.Count; //特别注意,必须这样,要不然会多一条数据
+
+ iFirstCountPos = iFirstCountPos + 21;
+ iFirstRSSIPos = iFirstCountPos + 1;
+ iFirstAnt = iFirstRSSIPos + 1;
+ iFirstLeftBarcketPos = iFirstLeftBarcketPos + 21;
+
+ }
+
+ }
+ catch (Exception ex)
+ {
+ log.RfidLog("----函数调用:Device_AutoDealContent 自动处理函数异常:" + ex.ToString());
+ mutauto.ReleaseMutex();
+ }
+ return tagInfoList;
+ }
+ #endregion
+
+
+ #region 该函数不实现了
+ public bool Device_SetRf(int iDbi, byte Antenna, WriteOrRead RorW)
+ {
+ bool bResult = false;
+ try
+ {
+ bool Set_OK;
+ if (RorW == WriteOrRead.Read)
+ {
+ Set_OK = MyReader.SetPower(iDbi, Convert.ToSingle(m_WriteDbm));
+ if (Set_OK) //设置功率工程
+ {
+ log.RfidLog("设置天线读功率成功!");
+ bResult = true;
+ }
+ else
+ {
+ log.Error("设置天线读功率失败;");
+ bResult = false;
+ }
+ }
+ else
+ {
+ Set_OK = MyReader.SetPower(Convert.ToSingle(m_ReadDbm), iDbi);
+ if (Set_OK) //设置功率工程
+ {
+ log.RfidLog("设置天线写功率成功!");
+ bResult = true;
+ }
+ else
+ {
+ log.Error("设置天线写功率失败;");
+ bResult = false;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Device_SetRf异常:",ex);
+ bResult = false;
+ }
+ return bResult;
+ }
+
+ public string Device_GetOneIdentifyData(Byte Antenna, UInt16 Timedout)
+ {
+ byte[] u16byte = new byte[2];
+ byte[] bCRC = new byte[4];
+ string strResult = "";
+ try
+ {
+ m_GlobalSem.WaitOne(1, false);
+ //log.RfidLog("函数调用:Device_GetOneIdentifyData");
+ if (Antenna == 0) //此版本1为主机
+ {
+ Antenna = (byte)(Antenna + 1);
+ }
+
+ 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;//change by yinzf
+ pMessagePack.m_pData[3] = 0x02;
+ //pMessagePack.m_pData[4] = 0x00;
+ //pMessagePack.m_pData[5] = 0x64;
+ //pMessagePack.m_pData[6] = 0x67;
+ u16byte = BitConverter.GetBytes(Timedout); //超时时间
+ u16byte = stringChange.Swap16Bytes(u16byte); //协议里为大端在前
+ //log.RfidLog("u16byte:" + 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;
+
+ //m_OneEpcSem.Release(1);
+ m_OneEpcSem.WaitOne(1, false);
+ m_OneEpcDataLen = 0;
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ if (m_OneEpcSem.WaitOne(Timedout + 500, false)) //等待结果,并取结果返回。
+ {
+ if (m_OneEpcDataLen >= 1) //有数据,正常
+ {
+ strResult = Encoding.ASCII.GetString(m_OneEpcData);
+ //Encoding.ASCII.GetBytes(strResult);
+ //pReadData = new byte[m_OneEpcDataLen];
+ //Array.Copy(m_OneEpcData, 0, pReadData, 0, m_OneEpcDataLen);
+ log.RfidLog("Device_GetOneIdentifyData:" + stringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen));
+
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ }
+ else
+ {
+ strResult = stringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen);
+ log.RfidLog("Device_GetOneIdentifyData:" + stringChange.bytesToHexStr(m_OneEpcData, m_OneEpcDataLen));
+
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ strResult = "";
+ }
+ }
+ else //超时
+ {
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ log.RfidLog("Device_GetOneIdentifyData超时未返回");
+ strResult = "";
+ }
+ }
+ else
+ {
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ log.RfidLog("Device_GetOneIdentifyData发送识别单条EPC命令超时");
+ strResult = "";
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("Device_GetOneIdentifyData识别单条EPC数据异常:",ex);
+ strResult = "";
+ }
+ finally
+ {
+ //m_GlobalSem.Release();
+ }
+ return strResult;
+ }
+
+ public string Device_GetOneIdentifyData_Finish(byte Antenna, ushort Timedout)
+ {
+ return "";
+ }
+ public Byte Device_GetOneIdentifyData_Finish(ref byte[] pReadData, byte Antenna, ushort Timedout)
+ {
+ return 0;
+ }
+ public bool Device_BeginIdentify()
+ {
+ byte[] u16byte = new byte[2];
+ bool bResult = false;
+ try
+ {
+ log.RfidLog("函数调用:Device_BeginIdentify");
+ MessagePack pMessagePack = new MessagePack();
+
+ pMessagePack.m_pData = new byte[1];
+
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ if (BeginEvent.WaitOne(200, false)) //等待结果,并取结果返回。
+ {
+ bResult = true;
+ }
+ else //超时
+ {
+ bResult = false;
+ }
+ }
+ else
+ {
+ log.RfidLog("发送开始连续识别命令失败:");
+ bResult = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("发送开始连续识别命令异常", ex);
+ bResult = false;
+ }
+ return bResult;
+ }
+
+ public bool Device_StopIdentify()
+ {
+ bool bResult = false;
+ try
+ {
+ log.RfidLog("函数调用:Device_StopIdentify");
+ MessagePack pMessagePack = new MessagePack();
+
+ pMessagePack.m_pData = new byte[1];
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ if (m_StopSem.WaitOne(200, false)) //等待结果,并取结果返回。
+ {
+ bResult = true;
+ }
+ else //超时
+ {
+ bResult = false;
+ }
+ }
+ else
+ {
+ log.RfidLog("发送停止连续识别命令失败:");
+ bResult = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("发送停止连续识别命令异常:",ex);
+ bResult = false;
+ }
+ return bResult;
+ }
+
+ public ushort Device_GetIdentifyData(ref byte[] pReadData, byte Antenna)
+ {
+ return 0;
+ }
+
+ public List Device_GetTagInfoList(DeviceType devicetype,int waitTime)
+ {
+ log.Info("进入Device_GetTagInfoList函数,参数deviceType:" + jsonChange.ModeToJson(devicetype) + ";waitTime:" + waitTime);
+ byte[] u16byte = new byte[2];
+ byte iResult = 0;
+ byte[] bCRC = new byte[4];
+ try
+ {
+ //log.SemaphoreLog("信号量m_GlobalSem,WaitOne(1, false)");
+ //m_GlobalSem.WaitOne(1, false);
+ MessagePack pMessagePack = new MessagePack();
+
+ //A5 5A 00 0A 80 00 64 EE 0D 0A //100毫秒的示例
+ 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;
+ //pMessagePack.m_pData[4] = 0x03;
+ //pMessagePack.m_pData[5] = 0xE8;
+ if (waitTime == 0)
+ {
+ waitTime = 1000;
+ }
+ u16byte = BitConverter.GetBytes(waitTime); //超时时间
+ u16byte = stringChange.Swap16Bytes(u16byte); //协议里为大端在前
+ //log.RfidLog("u16byte:" + 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;
+
+ //m_OneEpcSem.WaitOne(1, false);
+ GetAllRelese(m_OneEpcSem);
+
+ log.SemaphoreLog("信号量m_OneEpcSem,WaitOne(1, false)");
+ m_OneEpcDataLen = 0;
+ DeviceType = devicetype;
+ if (m_ICommunicateService.SendMessage(pMessagePack)) //发送报文成功
+ {
+ m_ReadDataSuccessful = true;
+ log.SemaphoreLog("信号量m_OneEpcSem,WaitOne("+ waitTime + ", false)");
+ if (m_OneEpcSem.WaitOne(waitTime+2000, false)) //等待结果,并取结果返回。
+ {
+ if (m_OneEpcDataLen > 0) //有数据,正常
+ {
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ m_ReadDataSuccessful = false;
+ log.Info("成功返回数据!");
+ return m_TagInfoList;
+ }
+ else
+ {
+ log.Info("Device_GetTagInfoLista长度或者天线号不正确");
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ iResult = 0;
+ m_TagInfoList.Clear();
+ m_ReadDataSuccessful = false;
+ }
+ }
+ else //超时
+ {
+ iResult = 0;
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ m_ReadDataSuccessful = false;
+ m_TagInfoList.Clear();
+ log.Info("Device_GetTagInfoList超时");
+ log.SemaphoreLog("信号量m_OneEpcSem返回,Device_GetTagInfoList超时");
+
+ }
+ }
+ else
+ {
+ m_OneEpcDataLen = 0;
+ m_OneEpcAntenna = 254;
+ log.Info("Device_GetTagInfoList发送识别单条EPC命令失败:");
+ iResult = 0;
+ m_TagInfoList.Clear();
+ m_ReadDataSuccessful = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Info("Device_GetTagInfoList识别单条EPC数据异常:" + ex.Message);
+ log.Error("Device_GetTagInfoList识别单条EPC数据异常:", ex);
+ iResult = 0;
+ m_TagInfoList.Clear();
+ m_ReadDataSuccessful = false;
+ }
+ finally
+ {
+ // m_GlobalSem.Release();
+ }
+ return m_TagInfoList;
+ }
+ #endregion
+
+ private void GetAllRelese(Semaphore sph)
+ {
+ bool res = sph.WaitOne(1, false);
+ if (res)
+ {
+ log.RfidLog("信号量手动释放");
+ GetAllRelese(sph);
+ }
+ }
+ }
+}
+
diff --git a/HighWayIot.Rfid/Properties/AssemblyInfo.cs b/HighWayIot.Rfid/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b2d54f1
--- /dev/null
+++ b/HighWayIot.Rfid/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.Rfid")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.Rfid")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("29813574-49c0-4979-a5a6-47eb7c4288a0")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.TouchSocket/HighWayIot.TouchSocket.csproj b/HighWayIot.TouchSocket/HighWayIot.TouchSocket.csproj
new file mode 100644
index 0000000..c9b3f8a
--- /dev/null
+++ b/HighWayIot.TouchSocket/HighWayIot.TouchSocket.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}
+ Library
+ Properties
+ HighWayIot.TouchSocket
+ HighWayIot.TouchSocket
+ v4.8
+ 512
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+ ..\packages\TouchSocket.2.0.0-beta.253\lib\net45\TouchSocket.dll
+
+
+ ..\packages\TouchSocket.Core.2.0.0-beta.253\lib\net45\TouchSocket.Core.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.TouchSocket/Properties/AssemblyInfo.cs b/HighWayIot.TouchSocket/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b32fba1
--- /dev/null
+++ b/HighWayIot.TouchSocket/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot.TouchSocket")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot.TouchSocket")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("dd18a634-1f9c-409a-8c32-c3c81b1b55b5")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/HighWayIot.TouchSocket/SocketConnect.cs b/HighWayIot.TouchSocket/SocketConnect.cs
new file mode 100644
index 0000000..cf6cf3a
--- /dev/null
+++ b/HighWayIot.TouchSocket/SocketConnect.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+
+namespace HighWayIot.TouchSocket
+{
+ public class SocketConnect
+ {
+
+ public void SocketMonitor()
+ {
+ var service = new TcpService();
+ service.Connecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在连接
+ service.Connected = (client, e) => { return EasyTask.CompletedTask; };//有客户端成功连接
+ service.Disconnecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在断开连接,只有当主动断开时才有效。
+ service.Disconnected = (client, e) => { return EasyTask.CompletedTask; };//有客户端断开连接
+ service.Received = (client, e) =>
+ {
+ //从客户端收到信息
+ var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意:数据长度是byteBlock.Len
+ client.Logger.Info($"已从{client.Id}接收到信息:{mes}");
+
+ return EasyTask.CompletedTask;
+ };
+
+ service.Setup(new TouchSocketConfig()//载入配置
+ .SetListenIPHosts("192.168.11.211:6501", "192.168.11.212:6502", "192.168.11.213:6503", "192.168.11.214:6504")//同时监听两个地址
+ .ConfigureContainer(a =>//容器的配置顺序应该在最前面
+ {
+ a.AddConsoleLogger();//添加一个控制台日志注入(注意:在maui中控制台日志不可用)
+ })
+ .ConfigurePlugins(a =>
+ {
+ //a.Add();//此处可以添加插件
+ }));
+
+ service.Start();//启动
+ }
+ }
+}
diff --git a/HighWayIot.TouchSocket/app.config b/HighWayIot.TouchSocket/app.config
new file mode 100644
index 0000000..a0cefc2
--- /dev/null
+++ b/HighWayIot.TouchSocket/app.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.TouchSocket/packages.config b/HighWayIot.TouchSocket/packages.config
new file mode 100644
index 0000000..de7e94c
--- /dev/null
+++ b/HighWayIot.TouchSocket/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot.sln b/HighWayIot.sln
new file mode 100644
index 0000000..51b17d3
--- /dev/null
+++ b/HighWayIot.sln
@@ -0,0 +1,73 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.6.33723.286
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot", "HighWayIot\HighWayIot.csproj", "{DFFFA7B9-62AF-4E3F-B802-A68B135490CA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Log4net", "HighWayIot.Log4net\HighWayIot.Log4net.csproj", "{DEABC30C-EC6F-472E-BD67-D65702FDAF74}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Common", "HighWayIot.Common\HighWayIot.Common.csproj", "{89A1EDD9-D79E-468D-B6D3-7D07B8843562}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Repository", "HighWayIot.Repository\HighWayIot.Repository.csproj", "{D0DC3CFB-6748-4D5E-B56A-76FDC72AB4B3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Plc", "HighWayIot.Plc\HighWayIot.Plc.csproj", "{4EE4C3E2-AC45-4275-8017-E99D70FC1F52}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Rfid", "HighWayIot.Rfid\HighWayIot.Rfid.csproj", "{29813574-49C0-4979-A5A6-47EB7C4288A0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.TouchSocket", "HighWayIot.TouchSocket\HighWayIot.TouchSocket.csproj", "{DD18A634-1F9C-409A-8C32-C3C81B1B55B5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighWayIot.Mqtt", "HighWayIot.Mqtt\HighWayIot.Mqtt.csproj", "{CD9B8712-0E09-42D2-849B-B8EAB02C7AB8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RFIDSocket", "RFIDSocket\RFIDSocket.csproj", "{B632CAA9-47D5-47DC-A49F-2106166096BA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DFFFA7B9-62AF-4E3F-B802-A68B135490CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DFFFA7B9-62AF-4E3F-B802-A68B135490CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DFFFA7B9-62AF-4E3F-B802-A68B135490CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DFFFA7B9-62AF-4E3F-B802-A68B135490CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DEABC30C-EC6F-472E-BD67-D65702FDAF74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DEABC30C-EC6F-472E-BD67-D65702FDAF74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DEABC30C-EC6F-472E-BD67-D65702FDAF74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DEABC30C-EC6F-472E-BD67-D65702FDAF74}.Release|Any CPU.Build.0 = Release|Any CPU
+ {89A1EDD9-D79E-468D-B6D3-7D07B8843562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {89A1EDD9-D79E-468D-B6D3-7D07B8843562}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {89A1EDD9-D79E-468D-B6D3-7D07B8843562}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {89A1EDD9-D79E-468D-B6D3-7D07B8843562}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0DC3CFB-6748-4D5E-B56A-76FDC72AB4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0DC3CFB-6748-4D5E-B56A-76FDC72AB4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0DC3CFB-6748-4D5E-B56A-76FDC72AB4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0DC3CFB-6748-4D5E-B56A-76FDC72AB4B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4EE4C3E2-AC45-4275-8017-E99D70FC1F52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4EE4C3E2-AC45-4275-8017-E99D70FC1F52}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4EE4C3E2-AC45-4275-8017-E99D70FC1F52}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4EE4C3E2-AC45-4275-8017-E99D70FC1F52}.Release|Any CPU.Build.0 = Release|Any CPU
+ {29813574-49C0-4979-A5A6-47EB7C4288A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {29813574-49C0-4979-A5A6-47EB7C4288A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29813574-49C0-4979-A5A6-47EB7C4288A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {29813574-49C0-4979-A5A6-47EB7C4288A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DD18A634-1F9C-409A-8C32-C3C81B1B55B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD9B8712-0E09-42D2-849B-B8EAB02C7AB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD9B8712-0E09-42D2-849B-B8EAB02C7AB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD9B8712-0E09-42D2-849B-B8EAB02C7AB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD9B8712-0E09-42D2-849B-B8EAB02C7AB8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B632CAA9-47D5-47DC-A49F-2106166096BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B632CAA9-47D5-47DC-A49F-2106166096BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B632CAA9-47D5-47DC-A49F-2106166096BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B632CAA9-47D5-47DC-A49F-2106166096BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7AD8B4D0-04C9-45D5-A242-7AD45121F5DF}
+ EndGlobalSection
+EndGlobal
diff --git a/HighWayIot/App.config b/HighWayIot/App.config
new file mode 100644
index 0000000..d91651e
--- /dev/null
+++ b/HighWayIot/App.config
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HighWayIot/HighWayIot.csproj b/HighWayIot/HighWayIot.csproj
new file mode 100644
index 0000000..7701d8a
--- /dev/null
+++ b/HighWayIot/HighWayIot.csproj
@@ -0,0 +1,76 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {DFFFA7B9-62AF-4E3F-B802-A68B135490CA}
+ Exe
+ HighWayIot
+ HighWayIot
+ v4.8
+ 512
+ true
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ False
+ Z:\Desktop\日常代码\HighWayIot\HighWayIot.Library\MySql.Data.dll
+
+
+ ..\HighWayIot.Library\Oracle.ManagedDataAccess.dll
+
+
+
+
+ Z:\Desktop\日常代码\HighWayIot\HighWayIot.Library\System.Data.SQLite.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {DEABC30C-EC6F-472E-BD67-D65702FDAF74}
+ HighWayIot.Log4net
+
+
+ {d0dc3cfb-6748-4d5e-b56a-76fdc72ab4b3}
+ HighWayIot.Repository
+
+
+
+
\ No newline at end of file
diff --git a/HighWayIot/Program.cs b/HighWayIot/Program.cs
new file mode 100644
index 0000000..7eb57ca
--- /dev/null
+++ b/HighWayIot/Program.cs
@@ -0,0 +1,34 @@
+using HighWayIot.Log4net;
+using HighWayIot.Repository.service;
+using HighWayIot.Repository.service.Impl;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HighWayIot
+{
+ internal class Program
+ {
+ private static LogHelper logger = LogHelper.Instance;
+
+ //private static IBaseDeviceinfoService sqliteTest = new BaseDeviceinfoServiceImpl();
+
+ //private static ISysUserInfoService mysqlTest = new BaseSysUserInfoServiceImpl();
+
+ //private static IBaseBomInfoService oracleTest = new BaseBomInfoServiceImpl();
+
+ static void Main(string[] args)
+ {
+ logger.Info("初始化启动");
+
+
+ //var info = sqliteTest.GetDeviceInfoListByProcessId(3);
+
+ //var info2 = mysqlTest.GetUserInfos();
+
+ //var info3 = oracleTest.GetBomInfos();
+ }
+ }
+}
diff --git a/HighWayIot/Properties/AssemblyInfo.cs b/HighWayIot/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..de7562d
--- /dev/null
+++ b/HighWayIot/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("HighWayIot")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HighWayIot")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("dfffa7b9-62af-4e3f-b802-a68b135490ca")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/RFIDSocket/App.config b/RFIDSocket/App.config
new file mode 100644
index 0000000..193aecc
--- /dev/null
+++ b/RFIDSocket/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RFIDSocket/Program.cs b/RFIDSocket/Program.cs
new file mode 100644
index 0000000..270dad3
--- /dev/null
+++ b/RFIDSocket/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace RFIDSocket
+{
+ internal static class Program
+ {
+ ///
+ /// 应用程序的主入口点。
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new RFIDSocket());
+ }
+ }
+}
diff --git a/RFIDSocket/Properties/AssemblyInfo.cs b/RFIDSocket/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5f8e8e7
--- /dev/null
+++ b/RFIDSocket/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("RFIDSocket")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RFIDSocket")]
+[assembly: AssemblyCopyright("Copyright © 2024")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("b632caa9-47d5-47dc-a49f-2106166096ba")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/RFIDSocket/Properties/Resources.Designer.cs b/RFIDSocket/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..10c3172
--- /dev/null
+++ b/RFIDSocket/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本: 4.0.30319.42000
+//
+// 对此文件的更改可能导致不正确的行为,如果
+// 重新生成代码,则所做更改将丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace RFIDSocket.Properties
+{
+
+
+ ///
+ /// 强类型资源类,用于查找本地化字符串等。
+ ///
+ // 此类是由 StronglyTypedResourceBuilder
+ // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+ // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+ // (以 /str 作为命令选项),或重新生成 VS 项目。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// 返回此类使用的缓存 ResourceManager 实例。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RFIDSocket.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 重写当前线程的 CurrentUICulture 属性,对
+ /// 使用此强类型资源类的所有资源查找执行重写。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/RFIDSocket/Properties/Resources.resx b/RFIDSocket/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/RFIDSocket/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/RFIDSocket/Properties/Settings.Designer.cs b/RFIDSocket/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..b4da644
--- /dev/null
+++ b/RFIDSocket/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace RFIDSocket.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/RFIDSocket/Properties/Settings.settings b/RFIDSocket/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/RFIDSocket/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/RFIDSocket/RFIDSocket.Designer.cs b/RFIDSocket/RFIDSocket.Designer.cs
new file mode 100644
index 0000000..0b1c6d4
--- /dev/null
+++ b/RFIDSocket/RFIDSocket.Designer.cs
@@ -0,0 +1,47 @@
+namespace RFIDSocket
+{
+ partial class RFIDSocket
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows 窗体设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // RFIDSocket
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(1643, 1064);
+ this.Name = "RFIDSocket";
+ this.Text = "小件日志";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
+
diff --git a/RFIDSocket/RFIDSocket.cs b/RFIDSocket/RFIDSocket.cs
new file mode 100644
index 0000000..1f42266
--- /dev/null
+++ b/RFIDSocket/RFIDSocket.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace RFIDSocket
+{
+ public partial class RFIDSocket : Form
+ {
+ public RFIDSocket()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/RFIDSocket/RFIDSocket.csproj b/RFIDSocket/RFIDSocket.csproj
new file mode 100644
index 0000000..9403162
--- /dev/null
+++ b/RFIDSocket/RFIDSocket.csproj
@@ -0,0 +1,83 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B632CAA9-47D5-47DC-A49F-2106166096BA}
+ WinExe
+ RFIDSocket
+ RFIDSocket
+ v4.8
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ RFIDSocket.cs
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ RFIDSocket.cs
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RFIDSocket/RFIDSocket.resx b/RFIDSocket/RFIDSocket.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/RFIDSocket/RFIDSocket.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file