You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
8.5 KiB
C#

using HslCommunication;
using HslCommunication.Profinet.Delta;
using Sln.Iot.Serilog;
using System;
using System.Drawing;
namespace Sln.Iot.PLC
{
public class PLCConnect
{
private static readonly Lazy<PLCConnect> lazy = new Lazy<PLCConnect>(() => new PLCConnect());
public static PLCConnect Instance
{
get
{
return lazy.Value;
}
}
private readonly SerilogHelper _log = SerilogHelper.Instance;
/// <summary>
/// PLC1 192.168.1.20
/// </summary>
public DeltaSerialOverTcp DeltaInstance0;
/// <summary>
/// PLC1 192.168.1.21
/// </summary>
public DeltaSerialOverTcp DeltaInstance1;
/// <summary>
/// PLC2 192.168.1.22
/// </summary>
public DeltaSerialOverTcp DeltaInstance2;
/// <summary>
/// PLC3 192.168.1.23
/// </summary>
public DeltaSerialOverTcp DeltaInstance3;
/// <summary>
/// PLC4 192.168.1.24
/// </summary>
public DeltaSerialOverTcp DeltaInstance4;
/// <summary>
/// 锁对象1
/// </summary>
private static readonly object locker1 = new object();
public async void InitConnect()
{
List<Task<DeltaSerialOverTcp>> tasks = new List<Task<DeltaSerialOverTcp>>
{
CreateDeltaConnect("192.168.1.20", 502, 1),
CreateDeltaConnect("192.168.1.21", 502, 1),
CreateDeltaConnect("192.168.1.22", 502, 1),
CreateDeltaConnect("192.168.1.23", 502, 1),
CreateDeltaConnect("192.168.1.24", 502, 1)
};
await Task.WhenAll(tasks);
DeltaInstance0 = tasks[0].GetAwaiter().GetResult();
DeltaInstance1 = tasks[1].GetAwaiter().GetResult();
DeltaInstance2 = tasks[2].GetAwaiter().GetResult();
DeltaInstance3 = tasks[3].GetAwaiter().GetResult();
DeltaInstance4 = tasks[4].GetAwaiter().GetResult();
}
/// <summary>
/// 创建台达PLC连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <param name="stationNo"></param>
/// <returns></returns>
public async Task<DeltaSerialOverTcp> CreateDeltaConnect(string ip, int port, byte stationNo)
{
DeltaSerialOverTcp plc = new DeltaSerialOverTcp(ip, port, stationNo);
try
{
OperateResult res = new OperateResult();
res.IsSuccess = true;
int count = 0;
do
{
if (res.IsSuccess == false)
{
count++;
_log.Error($"PLC[{ip}]连接失败,正在进行第[{count}]次重连...");
}
res = await plc.ConnectServerAsync();
}
while (!res.IsSuccess);
}
catch (Exception ex)
{
_log.Error($"连接PLC[{ip}]失败", ex);
}
return plc;
}
/// <summary>
/// PLC写入数据
/// </summary>
/// <param name="address">地址</param>
/// <param name="value">值</param>
/// <param name="type">数据类型</param>
/// <returns></returns>
public OperateResult PlcWrite(DeltaSerialOverTcp connect, string address, object value, DataTypeEnum type)
{
if (connect == null) return new OperateResult() { IsSuccess = false };
var result = new OperateResult() { IsSuccess = false };
lock (locker1)
{
switch (type)
{
case DataTypeEnum.Bool:
result = connect.Write(address, Convert.ToBoolean(value));
break;
case DataTypeEnum.Byte:
result = connect.Write(address, Convert.ToByte(value));
break;
case DataTypeEnum.Int16:
result = connect.Write(address, Convert.ToInt16(value));
break;
case DataTypeEnum.UInt16:
result = connect.Write(address, Convert.ToUInt16(value));
break;
case DataTypeEnum.Int32:
result = connect.Write(address, Convert.ToInt32(value));
break;
case DataTypeEnum.UInt32:
result = connect.Write(address, Convert.ToUInt32(value));
break;
case DataTypeEnum.Int64:
result = connect.Write(address, Convert.ToInt64(value));
break;
case DataTypeEnum.UInt64:
result = connect.Write(address, Convert.ToUInt64(value));
break;
case DataTypeEnum.Float:
result = connect.Write(address, Convert.ToSingle(value));
break;
case DataTypeEnum.Double:
result = connect.Write(address, Convert.ToDouble(value));
break;
case DataTypeEnum.String:
result = connect.Write(address, Convert.ToString(value));
break;
default:
throw new ArgumentException($"Unsupported data type: {type}");
}
}
return result;
}
/// <summary>
/// 写入byte数组
/// </summary>
/// <param name="address"></param>
/// <param name="data"></param>
/// <returns></returns>
public OperateResult PlcWriteBytes(DeltaSerialOverTcp connect, string address, byte[] data)
{
if (connect == null) return new OperateResult() { IsSuccess = false };
lock (locker1)
{
var res = connect.Write(address, data);
return res;
}
}
/// <summary>
/// 读取int32
/// </summary>
/// <returns></returns>
public OperateResult<int> ReadInt32(DeltaSerialOverTcp connect, string address)
{
if (connect == null) return new OperateResult<int>() { IsSuccess = false };
lock (locker1)
{
var res = connect.ReadInt32(address);
return res;
}
}
/// <summary>
/// 读取int16
/// </summary>
/// <returns></returns>
public OperateResult<short> ReadInt16(DeltaSerialOverTcp connect, string address)
{
if (connect == null) return new OperateResult<short>() { IsSuccess = false };
lock (locker1)
{
var res = connect.ReadInt16(address);
return res;
}
}
/// <summary>
/// 读取float
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public OperateResult<float> ReadFloat(DeltaSerialOverTcp connect, string address)
{
if (connect == null) return new OperateResult<float>() { IsSuccess = false };
lock (locker1)
{
var res = connect.ReadFloat(address);
return res;
}
}
/// <summary>
/// 读取Bool
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public OperateResult<bool> ReadBool(DeltaSerialOverTcp connect, string address)
{
if (connect == null) return new OperateResult<bool>() { IsSuccess = false };
lock (locker1)
{
var res = connect.ReadBool(address);
return res;
}
}
/// <summary>
/// 读取字节数组
/// </summary>
/// <param name="address"></param>
/// <param name="length"></param>
/// <returns></returns>
public OperateResult<byte[]> ReadBytes(DeltaSerialOverTcp connect, string address, ushort length)
{
if (connect == null) return new OperateResult<byte[]>() { IsSuccess = false };
lock (locker1)
{
var res = connect.Read(address, length);
return res;
}
}
}
}