XiangTan_JiaoJie/DM_Weight/Port/ModbusHelper.cs

150 lines
6.2 KiB
C#
Raw Normal View History

2024-12-03 13:28:29 +08:00
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.Text;
using System.Threading.Tasks;
namespace DM_Weight.Port
{
public class ModbusHelper
{
private ModbusIpMaster master;
private Socket socket;
private TcpClient client;
private static ModbusHelper instance;
private static readonly object objLock = new object();
private readonly ILog logger = LogManager.GetLogger(typeof(CheckOrderNewWindowViewModel));
public ModbusHelper()
{
if (ConfigurationManager.AppSettings["test"] == null || !(ConfigurationManager.AppSettings["test"].ToString().Equals("Y")))
{
socket = MakeKeepALiveSocket();
client = new TcpClient();
client.Client = socket;
master = ModbusIpMaster.CreateIp(client);
}
}
public static ModbusHelper GetInstance()
{
if (instance == null)
{
lock (objLock)
{
if (instance == null)
instance = new ModbusHelper();
}
}
return instance;
}
private void SetModusIpMaster()
{
Debug.WriteLine("SetModusIpMaster");
socket = MakeKeepALiveSocket();
client = new TcpClient();
client.Client = socket;
master = ModbusIpMaster.CreateIp(client);
}
public bool[] GetAllBoxState()
{
if (ConfigurationManager.AppSettings["test"] != null && ConfigurationManager.AppSettings["test"].ToString().Equals("Y"))
{
return new bool[] { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false };
}
bool[] bools = Policy.Handle<Exception>()
.Retry(3, (exception, retryCount) =>
{
this.Dispose();
//Debug.WriteLine($"获取所有箱子门状态出错,第{retryCount}次重试", exception);
logger.Info($"获取所有箱子门状态出错,第{retryCount}次重试, 异常信息{exception}");
this.SetModusIpMaster();
// return TimeSpan.FromSeconds (1);
}).Execute<bool[]>(() =>
{
bool[] flags = new bool[18];
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();
Debug.WriteLine("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)
{
if (ConfigurationManager.AppSettings["test"] != null && ConfigurationManager.AppSettings["test"].ToString().Equals("Y"))
{
return true;
}
bool bFlag = false;
Policy.Handle<Exception>().Retry(3, ((exception, retryCount) =>
{
this.Dispose();
//Debug.WriteLine($"打开箱子出错,第{retryCount}次重试", exception);
logger.Info($"打开箱子出错,第{retryCount}次重试,异常信息{exception}");
this.SetModusIpMaster();
//return TimeSpan.FromSeconds (1);
})).Execute(() =>
{
logger.Info($"正在打开{boxNum}号药箱");
master.WriteSingleRegister(1, (ushort)boxNum, 14);
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;
}
}
}