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);
 | 
						|
        //}
 | 
						|
    }
 | 
						|
}
 |