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.
Aucma.Scada/HighWayIot.Plc/Impl/InovancePlc.cs

493 lines
19 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 HighWayIot.Common;
using HighWayIot.Log4net;
using HslCommunication;
using HslCommunication.Profinet.Inovance;
using System;
using System.Threading.Tasks;
namespace HighWayIot.Plc.Impl
{
/// <summary>
/// 汇川PLC
/// </summary>
public class InovancePlc : IPlc
{
private LogHelper log = LogHelper.Instance;
private StringChange stringChange = StringChange.Instance;
private InovanceTcpNet inovanceTcp = null;
public InovancePlc()
{
if (!HslCommunication.Authorization.SetAuthorizationCode("ed1415f8-e06a-43ad-95f7-c04f7ae93b41"))
{
log.Info("HslCommunication激活失败");
return;
}
log.Info("HslCommunication 11.0.6.0激活成功");
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();
log.PlcLog("汇川PLC连接开始");
inovanceTcp.IpAddress = IP;
inovanceTcp.Port = 502;
inovanceTcp.DataFormat = HslCommunication.Core.DataFormat.CDAB;
try
{
OperateResult connect = inovanceTcp.ConnectServer();
if (connect.IsSuccess)
{
this.IsConnected = true;
log.PlcLog("汇川PLC建立连接成功");
return true;
}
else
{
this.IsConnected = false;
log.PlcLog("汇川PLC建立连接失败");
return false;
}
}
catch (Exception ex)
{
this.IsConnected = false;
log.Error("欧姆龙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)
{
//log.PlcLog("开始通过PLC地址和长度读取PLC数据");
try
{
OperateResult<byte[]> read = inovanceTcp.Read(address, (ushort)(len));
if (read.IsSuccess)
{
byte[] result = stringChange.ConvertFloatToINt(read.Content);
log.PlcLog(String.Format("通过地址和长度读取PLC数据成功{0}", stringChange.bytesToHexStr(result, result.Length)));
return result;
}
else
{
log.PlcLog("通过地址和长度读取PLC数据失败");
this.IsConnected = false;
return new byte[0];
}
}
catch (Exception ex)
{
log.Error("通过地址和长度读取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)
{
//log.PlcLog(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)
{
log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value));
return true;
}
log.PlcLog(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value));
this.IsConnected = false;
return false;
}
catch (Exception ex)
{
log.Error("通过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)
{
// log.PlcLog(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)
{
log.PlcLog(String.Format("通过PLC地址{0}清零数据成功", address));
return true;
}
log.PlcLog(String.Format("通过PLC地址{0}清零数据失败!!!", address));
this.IsConnected = false;
return false;
}
catch (Exception ex)
{
log.Error(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)
{
//log.PlcLog(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);
log.PlcLog(String.Format("通过PLC地址{0}读取EA值成功{1}", address, result));
return result;
}
else
{
log.PlcLog(String.Format("通过PLC地址{0}读取EA值失败", address));
this.IsConnected = false;
return "";
}
}
catch (Exception ex)
{
log.Error("通过PLC地址读取EA值异常", ex);
this.IsConnected = false;
return "";
}
}
/// <summary>
/// 通过PLC地址读取交互信号
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int readInteractiveSignal(string address)
{
// log.PlcLog(String.Format("开始通过PLC地址{0}读取交互信号", address));
try
{
OperateResult<short> read = inovanceTcp.ReadInt16(address);
if (read.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content));
return read.Content;
}
log.PlcLog(String.Format("通过PLC地址{0}读取交互信号失败!!!", address));
this.IsConnected = false;
return 0;
}
catch (Exception ex)
{
log.Error("通过PLC地址读取交互信号异常", ex);
this.IsConnected = false;
return 0;
}
}
/// <summary>
/// 通过PLC地址读取int32类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int readInt32ByAddress(string address)
{
//log.PlcLog(String.Format("开始通过PLC地址{0}读取int32类型数据", address));
try
{
OperateResult<short> read = inovanceTcp.ReadInt16(address);
if (read.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据成功{1}", address, read.Content));
return read.Content;
}
log.PlcLog(String.Format("通过PLC地址{0}读取int32类型数据失败", address));
this.IsConnected = false;
return 0;
}
catch (Exception ex)
{
log.Error("通过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)
{
//log.PlcLog(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value));
try
{
OperateResult write = inovanceTcp.Write(address, short.Parse(Convert.ToString(value)));
if (write.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value));
return true;
}
log.PlcLog(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
log.Error(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)
{
//log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}", address, value));
try
{
OperateResult operateResult = inovanceTcp.Write(address, value);
if (operateResult.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value));
return true;
}
log.PlcLog(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
log.Error(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)
{
//log.PlcLog(String.Format("开始通过PLC地址{0}读取string类型数据", address));
try
{
OperateResult<String> read = inovanceTcp.ReadString(address, length);
if (read.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}读取string类型数据成功{1}", address, read.Content));
return read.Content;
}
log.PlcLog(String.Format("通过PLC地址{0}读取string类型数据失败", address));
return "";
}
catch (Exception ex)
{
log.Error("通过PLC地址读取int32类型数据异常", ex);
return "";
}
}
/// <summary>
/// 通过PLC地址读取Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool readBoolByAddress(string address)
{
//log.PlcLog(String.Format("开始通过PLC地址{0}读取bool类型数据", address));
try
{
OperateResult<bool> read = inovanceTcp.ReadBool(address);
if (read.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据成功{1}", address, read.Content));
return read.Content;
}
log.PlcLog(String.Format("通过PLC地址{0}读取bool类型数据失败", address));
return false;
}
catch (Exception ex)
{
log.Error("通过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)
{
// log.PlcLog(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value));
try
{
OperateResult write = inovanceTcp.Write(address, value);
if (write.IsSuccess)
{
log.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value));
return true;
}
log.PlcLog(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
log.Error(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)
{
log.PlcLog(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value));
return true;
}
log.PlcLog(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value));
return false;
}
catch (Exception ex)
{
log.Error(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex);
return false;
}
}
public Task<bool> ReadHeart(string address)
{
throw new NotImplementedException();
}
}
}