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.

401 lines
15 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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建立连接失败:{connect.Message}");
return false;
}
}
catch (Exception ex)
{
this.IsConnected = false;
PrintLogInfo("汇川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($"开始通过地址:{address},读取长度:{len}的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数据失败:{read.Message}");
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="address"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool writeValueByAddress(string address,int value)
{
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地址读取int16类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int readInt16ByAddress(string address)
{
PrintLogInfo(String.Format("开始通过PLC地址{0}读取int16类型数据", address));
try
{
OperateResult<short> read = inovanceTcp.ReadInt16(address);
if (read.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}读取int16类型数据成功{1}", address, read.Content));
return read.Content;
}
PrintLogInfo(String.Format("通过PLC地址{0}读取int16类型数据失败", address));
this.IsConnected = false;
return 0;
}
catch (Exception ex)
{
PrintLogInfo("通过PLC地址读取int16类型数据异常", ex);
this.IsConnected = false;
return 0;
}
}
/// <summary>
/// 通过PLC地址写入Short类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool writeShortByAddress(string address, int value)
{
PrintLogInfo(String.Format("开始通过PLC地址{0}写入Short类型数据{1}", address, value));
try
{
OperateResult write = inovanceTcp.Write(address, short.Parse(Convert.ToString(value)));
if (write.IsSuccess)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入Short类型数据{1}成功", address, value));
return true;
}
PrintLogInfo(String.Format("通过PLC地址{0}写入Short类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
PrintLogInfo(String.Format("通过PLC地址{0}写入Short类型数据异常", 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地址读取string类型数据异常", 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)
{
PrintLogInfo(String.Format("开始通过PLC地址{0}写入Double类型数据{1}", address, 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);
}
}
}
}