using DM_Weight.Finger; using DM_Weight.ViewModels; using log4net; using log4net.Repository.Hierarchy; using Modbus.Device; using Polly; using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Speech.Synthesis; using System.Text; using System.Threading; using System.Threading.Tasks; namespace DM_Weight.Port { public class ModbusHelper { private static ModbusHelper instance; private ModbusIpMaster master; private Socket socket; private TcpClient client; private readonly ILog logger = LogManager.GetLogger(typeof(CheckOrderNewWindowViewModel)); private static object _lock = new object(); public static bool BoxOperate { get; set; } public ModbusHelper() { socket = MakeKeepALiveSocket(); client = new TcpClient(); client.Client = socket; master = ModbusIpMaster.CreateIp(client); } public static ModbusHelper GetInstance() { lock (_lock) { if (instance == null) { //lock (objLock) //{ // if (instance == null) instance = new ModbusHelper(); //} } return instance; } } private void SetModusIpMaster() { logger.Info("SetModusIpMaster"); socket = MakeKeepALiveSocket(); client = new TcpClient(); client.Client = socket; master = ModbusIpMaster.CreateIp(client); } public bool[] GetAllBoxState() { lock (_lock) { bool[] bools = Policy.Handle() .Retry(3, (exception, retryCount) => { this.Dispose(); //Debug.WriteLine($"获取所有箱子门状态出错,第{retryCount}次重试", exception); logger.Info($"获取所有箱子门状态出错,第{retryCount}次重试, 异常信息{exception}"); Thread.Sleep(50); BoxOperate = false; this.SetModusIpMaster(); // return TimeSpan.FromSeconds (1); Task.Factory.StartNew(() => { //FingerprintUtil.FingerDisconnect(); }); }).Execute(() => { bool[] flags = new bool[18]; if (master == null) { this.SetModusIpMaster(); } var result = master.ReadInputRegisters(1, 0x0033, 2); var r1 = Convert.ToString(((int)result[0] >> 14) | ((int)result[1] << 2), 2).PadLeft(18, '0'); var r2 = r1.ToCharArray(); logger.Info("r2=>" + string.Join(", ", r2)); for (int i = 0; i < 18; i++) { flags[i] = r2[17 - i] == '1' ? true : false; } logger.Info($"获取所有箱子门状态返回:{string.Join(',', flags)}"); return flags; }); return bools; } } public bool OpenBoxDoor(int boxNum) { lock (_lock) { BoxOperate = true; bool bFlag = false; Thread.Sleep(50); Policy.Handle().Retry(3, ((exception, retryCount) => { this.Dispose(); //Debug.WriteLine($"打开箱子出错,第{retryCount}次重试", exception); logger.Info($"打开箱子出错,第{retryCount}次重试,异常信息{exception}"); Thread.Sleep(50); this.SetModusIpMaster(); Task.Factory.StartNew(() => { //FingerprintUtil.FingerDisconnect(); }); //return TimeSpan.FromSeconds (1); })).Execute(() => { logger.Info($"正在打开{boxNum}号药箱"); master.WriteSingleRegister(1, (ushort)boxNum, 20); logger.Info($"开门指令已发送{(ushort)boxNum}"); //Console.WriteLine($"开门指令已发送{(ushort)boxNum}"); bFlag = true; }); return bFlag; } } private void Dispose() { socket.Shutdown(SocketShutdown.Both); socket.Close(); client.Close(); master.Dispose(); } public static Socket MakeKeepALiveSocket() { uint dummy = 0; byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);//启用Keep-Alive BitConverter.GetBytes((uint)10000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));//在这个时间间隔内没有数据交互,则发送探测包 BitConverter.GetBytes((uint)10000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);//发探测包时间间隔 //IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.13"), 502); string modbusIp = ConfigurationManager.AppSettings["modbusIp"].ToString(); int modbusPort = Convert.ToInt32(ConfigurationManager.AppSettings["modbusPort"]); IPEndPoint iep = new IPEndPoint(IPAddress.Parse(modbusIp), modbusPort); Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket = Policy.Handle() .Retry(3, (exception, retryCount) => { Console.WriteLine($"建立Socket,第{retryCount}次重试", exception); // return TimeSpan.FromSeconds (1); }) .Execute(() => { _socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); _socket.Connect(iep); return _socket; }); return _socket; } //private static SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(); //public static void SpeakAsync(string textinfo) //{ // speechSynthesizer.Rate = 2; // speechSynthesizer.SpeakAsync(textinfo); //} } }