176 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			176 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C#
		
	
	
	
| 
								 | 
							
								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<Exception>()
							 | 
						|||
| 
								 | 
							
								                .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[]>(() =>
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    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<Exception>().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<Exception>()
							 | 
						|||
| 
								 | 
							
								              .Retry(3, (exception, retryCount) =>
							 | 
						|||
| 
								 | 
							
								              {
							 | 
						|||
| 
								 | 
							
								                  Console.WriteLine($"建立Socket,第{retryCount}次重试", exception);
							 | 
						|||
| 
								 | 
							
								                  // return TimeSpan.FromSeconds (1);
							 | 
						|||
| 
								 | 
							
								              })
							 | 
						|||
| 
								 | 
							
								              .Execute<Socket>(() =>
							 | 
						|||
| 
								 | 
							
								              {
							 | 
						|||
| 
								 | 
							
								                  _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);
							 | 
						|||
| 
								 | 
							
								        //}
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |