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