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.

499 lines
18 KiB
C#

using HslCommunication.Profinet.Inovance;
using HslCommunication;
using System;
using System.Collections.Generic;
using System.Text;
using SlnMesnac.Common;
using Microsoft.Extensions.Logging;
namespace SlnMesnac.Plc.Impl
{
/// <summary>
/// 汇川PLC
/// </summary>
public class InovancePlc : IPlc
{
private ILogger<InovancePlc> _logger;
private StringChange _stringChange;
private InovanceTcpNet inovanceTcp = null;
public InovancePlc(ILogger<InovancePlc> logger, StringChange stringChange)
{
this._logger = logger;
_stringChange = stringChange;
this.inovanceTcp = new InovanceTcpNet();
this.inovanceTcp.ConnectTimeOut = 2000;
}
public bool IsConnected { get; set; }
/// <summary>
/// 建立连接
/// </summary>
/// <param name="IP"></param>
/// <param name="port"></param>
/// <returns></returns>
public bool Connect(string IP, int port)
{
inovanceTcp?.ConnectClose();
PrintLogInfo("汇川PLC连接开始");
inovanceTcp.IpAddress = IP;
inovanceTcp.Port = 502;
inovanceTcp.DataFormat = HslCommunication.Core.DataFormat.CDAB;
try
{
OperateResult connect = inovanceTcp.ConnectServer();
if (connect.IsSuccess)
{
this.IsConnected = true;
PrintLogInfo("汇川PLC建立连接成功");
return true;
}
else
{
this.IsConnected = false;
PrintLogInfo("汇川PLC建立连接失败");
return false;
}
}
catch (Exception ex)
{
this.IsConnected = false;
PrintLogInfo("欧姆龙NJ系列PLC建立连接异常", ex);
return false;
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
public bool DisConnect()
{
return inovanceTcp.ConnectClose().IsSuccess;
}
/// <summary>
/// 通过地址和长度读取PLC数据
/// </summary>
/// <param name="len"></param>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public byte[] readValueByAddress(int len, string address)
{
//PrintLogInfo("开始通过PLC地址和长度读取PLC数据");
try
{
OperateResult<byte[]> read = inovanceTcp.Read(address, (ushort)(len));
if (read.IsSuccess)
{
byte[] result = _stringChange.ConvertFloatToINt(read.Content);
PrintLogInfo(String.Format("通过地址和长度读取PLC数据成功{0}", _stringChange.bytesToHexStr(result, result.Length)));
return result;
}
else
{
PrintLogInfo("通过地址和长度读取PLC数据失败");
this.IsConnected = false;
return new byte[0];
}
}
catch (Exception ex)
{
PrintLogInfo("通过地址和长度读取PLC数据异常", ex);
this.IsConnected = false;
return new byte[0];
}
}
/// <summary>
/// 通过PLC地址写入int类型数据,模切汇川PLC复位逻辑
/// </summary>
/// <param name="value"></param>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool writeValueByAddress(int value, string address)
{
//PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}", address, value));
OperateResult operateResult = new OperateResult();
try
{
int s = 0;
string[] strArry = address.Split('.');
//先读取整个块的内容
var info = inovanceTcp.ReadInt16(strArry[0]);
if (info.Content == 0)
{
int length = _stringChange.ParseToInt(strArry[1]) + 1;
string[] array = new string[length];
for (int i = 0; i < length; i++)
{
if (i == _stringChange.ParseToInt(strArry[1]))
{
array[i] = value.ToString();
}
else
{
array[i] = "0";
}
}
//反转
Array.Reverse(array);
byte[] buffer = new byte[array.Length];
string result = "";
for (int i = 0; i < array.Length; i++)
{
result += (byte)Convert.ToInt32(array[i], 16);
}
s = Convert.ToInt32(result.Trim(), 2);
operateResult = inovanceTcp.Write(strArry[0], (ushort)s);
}
else
{
var inf2 = Convert.ToString(info.Content, 2);
string[] infoArray = new string[inf2.Length];
for (int i = 0; i < inf2.Length; i++)
{
infoArray[i] = inf2.Substring(i, 1);
}
Array.Reverse(infoArray);
infoArray[_stringChange.ParseToInt(strArry[1])] = value.ToString();
string result = "";
foreach (var item in infoArray)
{
result = result + item;
}
s = Convert.ToInt32(result.Trim(), 10);
operateResult = inovanceTcp.Write(strArry[0], s);
}
if (operateResult.IsSuccess)
{
PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value));
return true;
}
PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value));
this.IsConnected = false;
return false;
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址写入int类型数据", ex);
this.IsConnected = false;
return false;
}
}
/// <summary>
/// 通过PLC地址清零数据
/// </summary>
/// <param name="address"></param>
/// <param name="len"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool resetByAddress(string address, int len)
{
// PrintLogInfo(String.Format("开发通过PLC地址{0}清零数据", address));
try
{
byte[] write = new byte[len * 2];
for (int i = 0; i < len * 2; i++)
{
write[i] = 0;
}
OperateResult operateResult = inovanceTcp.Write(address, write);
if (operateResult.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}清零数据成功", address));
return true;
}
PrintLogInfo(String.Format("通过PLC地址{0}清零数据失败!!!", address));
this.IsConnected = false;
return false;
}
catch (Exception ex)
{
PrintLogInfo(String.Format("通过PLC地址{0}清零数据异常", address), ex);
this.IsConnected = false;
return false;
}
}
/// <summary>
/// 通过PLC地址读取EA值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public string readEaByAddress(string address)
{
//PrintLogInfo(String.Format("通过PLC地址{0}读取EA值", address));
try
{
OperateResult<Byte[]> read = inovanceTcp.Read(address, (ushort)(8));
if (read.IsSuccess && read.Content != null)
{
string result = Convert.ToString(read.Content);
PrintLogInfo(String.Format("通过PLC地址{0}读取EA值成功{1}", address, result));
return result;
}
else
{
PrintLogInfo(String.Format("通过PLC地址{0}读取EA值失败", address));
this.IsConnected = false;
return "";
}
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址读取EA值异常", ex);
this.IsConnected = false;
return "";
}
}
/// <summary>
/// 通过PLC地址读取交互信号
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int readInteractiveSignal(string address)
{
// PrintLogInfo(String.Format("开始通过PLC地址{0}读取交互信号", address));
try
{
OperateResult<short> read = inovanceTcp.ReadInt16(address);
if (read.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content));
return read.Content;
}
PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号失败!!!", address));
this.IsConnected = false;
return 0;
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址读取交互信号异常", ex);
this.IsConnected = false;
return 0;
}
}
/// <summary>
/// 通过PLC地址读取int32类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int readInt32ByAddress(string address)
{
//PrintLogInfo(String.Format("开始通过PLC地址{0}读取int32类型数据", address));
try
{
OperateResult<short> read = inovanceTcp.ReadInt16(address);
if (read.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据成功{1}", address, read.Content));
return read.Content;
}
PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据失败", address));
this.IsConnected = false;
return 0;
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址读取int32类型数据异常", ex);
this.IsConnected = false;
return 0;
}
}
/// <summary>
/// 通过PLC地址写入int32类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool writeInt32ByAddress(string address, int value)
{
//PrintLogInfo(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value));
try
{
OperateResult write = inovanceTcp.Write(address, short.Parse(Convert.ToString(value)));
if (write.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value));
return true;
}
PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex);
return false;
}
}
/// <summary>
/// 通过PLC地址写入String类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool writeStringByAddress(string address, string value)
{
//PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}", address, value));
try
{
OperateResult operateResult = inovanceTcp.Write(address, value);
if (operateResult.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value));
return true;
}
PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex);
return false;
}
}
/// <summary>
/// 通过PLC地址读取string类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public string readStringByAddress(string address, ushort length)
{
//PrintLogInfo(String.Format("开始通过PLC地址{0}读取string类型数据", address));
try
{
OperateResult<String> read = inovanceTcp.ReadString(address, length);
if (read.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据成功{1}", address, read.Content));
return read.Content;
}
PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据失败", address));
return "";
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址读取int32类型数据异常", ex);
return "";
}
}
/// <summary>
/// 通过PLC地址读取Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool readBoolByAddress(string address)
{
//PrintLogInfo(String.Format("开始通过PLC地址{0}读取bool类型数据", address));
try
{
OperateResult<bool> read = inovanceTcp.ReadBool(address);
if (read.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据成功{1}", address, read.Content));
return read.Content;
}
PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据失败", address));
return false;
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址读取bool类型数据异常", ex);
return false;
}
}
/// <summary>
/// 通过PLC地址写入Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool writeBoolByAddress(string address, bool value)
{
// PrintLogInfo(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value));
try
{
OperateResult write = inovanceTcp.Write(address, value);
if (write.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value));
return true;
}
PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex);
return false;
}
}
/// <summary>
/// 写入Double类型
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool writeDoubleByAddress(string address, int value)
{
try
{
OperateResult write = inovanceTcp.Write(address, Convert.ToDouble(value));
if (write.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value));
return true;
}
PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex);
return false;
}
}
private void PrintLogInfo(string message, Exception ex = null)
{
if (ex != null)
{
_logger.LogError($"{message}{ex.Message}");
}
else
{
_logger.LogInformation(message);
}
}
}
}