change - PLC 逻辑实现

master
WenJY 2 days ago
parent d7d1c90670
commit 17a06226c4

@ -0,0 +1,187 @@
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.0.30319.42000
* Mr.Wen's MacBook Pro
* Sln.Wcs.Common
* E5D05299-9C0E-4F5C-82ED-85A02684D06C
*
* WenJY
*
* 2026-05-06 16:53:46
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using System.Text;
namespace Sln.Wcs.Common;
public class StringChange
{
/// <summary>
/// 将字符串强制转换成int转换失败则返回0
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public int ParseToInt(string str)
{
int returnInt = 0;
if (str == null || str.Trim().Length < 1)
{
return returnInt;
}
if (int.TryParse(str, out returnInt))
{
return returnInt;
}
else
{
return 0;
}
}
/// <summary>
/// char数组转Array
/// </summary>
/// <param name="cha"></param>
/// <param name="len"></param>
/// <returns></returns>
public string CharArrayToString(char[] cha, int len)
{
string str = "";
for (int i = 0; i < len; i++)
{
str += string.Format("{0}", cha[i]);
}
return str;
}
public string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01"
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < iLen; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
public byte[] HexStrTorbytes(string strHex)//e.g. " 01 01" ---> { 0x01, 0x01}
{
strHex = strHex.Replace(" ", "");
if ((strHex.Length % 2) != 0)
strHex += " ";
byte[] returnBytes = new byte[strHex.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(strHex.Substring(i * 2, 2), 16);
return returnBytes;
}
public string StringToHexString(string s, Encoding encode)
{
byte[] b = encode.GetBytes(s); //按照指定编码将string编程字节数组
string result = string.Empty;
for (int i = 0; i < b.Length; i++) //逐字节变为16进制字符以%隔开
{
result += "%" + Convert.ToString(b[i], 16);
}
return result;
}
public string HexStringToString(string hs, Encoding encode)
{
//以%分割字符串,并去掉空字符
string[] chars = hs.Split(new char[] { '%' }, StringSplitOptions.RemoveEmptyEntries);
byte[] b = new byte[chars.Length];
//逐个字符变为16进制字节数据
for (int i = 0; i < chars.Length; i++)
{
b[i] = Convert.ToByte(chars[i], 16);
}
//按照指定编码将字节数组变为字符串
return encode.GetString(b);
}
public byte[] Swap16Bytes(byte[] OldU16)
{
byte[] ReturnBytes = new byte[2];
ReturnBytes[1] = OldU16[0];
ReturnBytes[0] = OldU16[1];
return ReturnBytes;
}
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
public long GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds);
}
public byte[] ConvertFloatToINt(byte[] floatBytes)
{
byte[] intBytes = new byte[floatBytes.Length / 2];
for (int i = 0; i < intBytes.Length; i++)
{
intBytes[i] = floatBytes[i * 2];
}
return intBytes;
}
//CRC异或校验
public byte CalculateVerify(byte[] pMessage, int iLength)
{
UInt16 i;
byte iVerify = 0;
iVerify = pMessage[0];
for (i = 1; i < iLength; i++)
{
iVerify = (byte)(iVerify ^ pMessage[i]);
}
return iVerify;
}
public int HexStringToNegative(string strNumber)
{
int iNegate = 0;
int iNumber = Convert.ToInt32(strNumber, 16);
if (iNumber > 127)
{
int iComplement = iNumber - 1;
string strNegate = string.Empty;
char[] binchar = Convert.ToString(iComplement, 2).PadLeft(8, '0').ToArray();
foreach (char ch in binchar)
{
if (Convert.ToInt32(ch) == 48)
{
strNegate += "1";
}
else
{
strNegate += "0";
}
}
iNegate = -Convert.ToInt32(strNegate, 2);
}
return iNegate;
}
}

@ -56,6 +56,14 @@ public class BaseDeviceHost
[SugarColumn(ColumnName = "host_name")]
public string hostName { get; set; }
/// <summary>
/// Desc:主机类型0-西门子 PLC1-汇川 PLC
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(ColumnName = "host_type")]
public int hostType { get; set; }
/// <summary>
/// Desc:主机IP
/// Default:

@ -0,0 +1,122 @@
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.0.30319.42000
* Mr.Wen's MacBook Pro
* Sln.Wcs.Plc
* C46CF1F4-254E-4BA5-B32D-A7175A197EB1
*
* WenJY
*
* 2026-05-06 16:58:24
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using System;
using System.Collections.Generic;
using HslCommunication;
using Microsoft.Extensions.DependencyInjection;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Plc.Service;
using Sln.Wcs.Plc.Service.Impl;
using Sln.Wcs.Repository.service;
using Sln.Wcs.Serilog;
using SqlSugar;
namespace Sln.Wcs.Plc;
public static class PlcSetUp
{
public static void AddPlcSetup(this IServiceCollection services)
{
//获取 PLC 主机信息=>初始化链接=>将链接信息存入容器中
services.AddSingleton<List<IPlc>>(x =>
{
var _log = x.GetService<SerilogHelper>();
var _hostService = x.GetService<IBaseDeviceHostService>();
List<IPlc> plcs = new List<IPlc>();
try
{
do
{
if (!Authorization.SetAuthorizationCode("3daa5a3b-defd-474d-b2d9-c4d2265dfe20"))
{
_log.Info("HslCommunication激活失败可用时长为24小时");
break;
}
else
{
_log.Info("HslCommunication激活成功");
}
//获取主机信息
List<BaseDeviceHost> deviceHosts = _hostService.Query(x => x.isFlag == 1);
foreach (var item in deviceHosts)
{
IPlc _plc = InitPlc(x, item.hostType);
var conRes = _plc.Connect(item.hostIP, item.hostPort);
if (conRes)
{
_log.Info($"PLC{item.hostIP}:{item.hostPort};连接成功,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
_plc.ConfigKey = item.hostCode;
}
else
{
_log.Info($"PLC{item.hostIP}:{item.hostPort};连接失败,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
}
}
} while (false);
}
catch (Exception e)
{
_log.Error($"PLC初始化连接异常{e.Message}");
}
return plcs;
});
}
private static IPlc InitPlc(IServiceProvider serviceProvider, int plcType)
{
IPlc _plc = null;
var _inovance = serviceProvider.GetRequiredService<InovanceImpl>();
var _siemens = serviceProvider.GetRequiredService<SiemensImpl>();
switch (plcType)
{
case 0:
_plc = _siemens;
break;
case 1:
_plc = _inovance;
break;
// case "MelsecBinaryPlc":
// _plc = _melsecBinary;
// break;
// case "OmronNJPlc":
// _plc = _omronNj;
// break;
default:
break;
}
return _plc;
}
}

@ -1,15 +1,15 @@
#region << 版 本 注 释 >>
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* (c) 2026 WenJY
* CLR4.0.30319.42000
* LAPTOP-E0N2L34V
* SlnMesnac.Plc
* 496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
* Mr.Wen's MacBook Pro
* Sln.Wcs.Plc.Service
* 4196498E-9837-4A60-955F-D33464BFC338
*
* WenJY
* wenjy@mesnac.com
* 2024-03-27 21:58:35
*
* 2026-05-06 16:48:45
* V1.0.0
*
*
@ -25,16 +25,16 @@
using System.Threading.Tasks;
namespace Sln.Wcs.Plc
namespace Sln.Wcs.Plc.Service;
public interface IPlc
{
public abstract class PlcAbsractFactory
{
public string ConfigKey { get; set; }
string ConfigKey { get; set; }
/// <summary>
/// 是否连接
/// </summary>
public abstract bool IsConnected { get; set; }
bool IsConnected { get; set; }
/// <summary>
/// 建立连接
@ -42,21 +42,13 @@ namespace Sln.Wcs.Plc
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public abstract bool Connect(string ip, int port);
/// <summary>
/// 异步建立连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public abstract Task<bool> ConnectAsync(string ip, int port);
bool Connect(string ip, int port);
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
public abstract bool DisConnect();
bool DisConnect();
/// <summary>
/// 根据地址读取指定长度数据
@ -64,14 +56,14 @@ namespace Sln.Wcs.Plc
/// <param name="address"></param>
/// <param name="len"></param>
/// <returns></returns>
public abstract byte[] readValueByAddress(string address, int len);
byte[] readValueByAddress(string address, int len);
/// <summary>
/// 通过PLC地址读取int16类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public abstract int readInt16ByAddress(string address);
int readInt16ByAddress(string address);
/// <summary>
/// 通过PLC地址写入int16类型数据
@ -79,14 +71,14 @@ namespace Sln.Wcs.Plc
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
public abstract bool writeInt16ByAddress(string address, int value);
bool writeInt16ByAddress(string address, int value);
/// <summary>
/// 通过PLC地址读取string类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public abstract string readStringByAddress(string address, ushort length);
string readStringByAddress(string address, ushort length);
/// <summary>
/// 弃用--通过PLC地址写入String类型数据
@ -94,7 +86,7 @@ namespace Sln.Wcs.Plc
/// <param name="address"></param>
/// <param name="SFC"></param>
/// <returns></returns>
public abstract bool writeStringByAddress(string address, string value);
bool writeStringByAddress(string address, string value);
/// <summary>
/// 使用--通过PLC地址写入String类型数据
@ -102,28 +94,21 @@ namespace Sln.Wcs.Plc
/// <param name="address"></param>
/// <param name="SFC"></param>
/// <returns></returns>
public abstract bool writeStringByAddress(string address, string value, int length);
//bool writeStringByAddress(string address, string value, int length);
/// <summary>
/// 通过PLC地址读取Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public abstract bool readBoolByAddress(string address);
/// <summary>
/// 通过PLC地址读取心跳结果
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public abstract bool readHeartByAddress(string address);
bool readBoolByAddress(string address);
/// <summary>
/// 通过PLC地址写入Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public abstract bool writeBoolByAddress(string address, bool value);
bool writeBoolByAddress(string address, bool value);
/// <summary>
/// 通过PLC地址写入Double类型数据
@ -131,6 +116,5 @@ namespace Sln.Wcs.Plc
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
public abstract bool writeDoubleByAddress(string address, int value);
}
bool writeDoubleByAddress(string address, int value);
}

@ -0,0 +1,349 @@
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.0.30319.42000
* Mr.Wen's MacBook Pro
* Sln.Wcs.Plc.Service.Impl
* 0882A816-67FC-4851-83E2-EDCB081572D9
*
* WenJY
*
* 2026-05-06 16:50:15
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using System;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.Profinet.Inovance;
using Sln.Wcs.Common;
namespace Sln.Wcs.Plc.Service.Impl;
public class InovanceImpl:IPlc
{
public string ConfigKey { get; set; }
public bool IsConnected { get; set; }
private InovanceTcpNet inovanceTcp = null;
private readonly StringChange _stringChange;
public InovanceImpl(StringChange stringChange)
{
_stringChange = stringChange;
this.inovanceTcp = new InovanceTcpNet();
this.inovanceTcp.ConnectTimeOut = 2000;
}
/// <summary>
/// 建立连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public bool Connect(string ip, int port)
{
try
{
inovanceTcp?.ConnectClose();
if (inovanceTcp != null)
{
inovanceTcp.IpAddress = ip;
inovanceTcp.Port = port;
inovanceTcp.DataFormat = HslCommunication.Core.DataFormat.CDAB;
OperateResult connect = inovanceTcp.ConnectServer();
this.IsConnected = connect.IsSuccess;
if (!connect.IsSuccess)
{
throw new InvalidOperationException($"汇川PLC连接失败:{connect.Message}");
}
return connect.IsSuccess;
}
else
{
throw new ArgumentException($"汇川PLC实例inovanceTcp为null");
}
}
catch (Exception ex)
{
throw new InvalidOperationException($"汇川PLC连接异常{ex.Message}");
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public bool DisConnect()
{
try
{
OperateResult disConnect = inovanceTcp.ConnectClose();
this.IsConnected = false;
if (!disConnect.IsSuccess)
{
throw new InvalidOperationException($"汇川PLC断开连接失败:{disConnect.Message}");
}
return disConnect.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"汇川PLC断开连接异常{ex.Message}");
}
}
/// <summary>
/// 根据地址读取指定长度数据
/// </summary>
/// <param name="address"></param>
/// <param name="len"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public byte[] readValueByAddress(string address, int len)
{
try
{
OperateResult<byte[]> read = inovanceTcp.Read(address, (ushort)(len));
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据失败:{read.Message}");
}
return _stringChange.ConvertFloatToINt(read.Content);
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据异常:{ex.Message}");
}
}
/// <summary>
/// 根据地址读取int16数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public int readInt16ByAddress(string address)
{
try
{
OperateResult<short> read = inovanceTcp.ReadInt16(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取int16数据失败{read.Content}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取int16数据异常{ex.Message}");
}
}
/// <summary>
/// 根据地址写入int16数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeInt16ByAddress(string address, int value)
{
try
{
OperateResult operateResult = new OperateResult();
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)
{
throw new InvalidOperationException($"根据地址:{address};写入int16数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入int16数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址读取string类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="length"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public string readStringByAddress(string address, ushort length)
{
try
{
OperateResult<String> read = inovanceTcp.ReadString(address, length);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取string数据失败{read.Content}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取string数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址写入String类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeStringByAddress(string address, string value)
{
try
{
OperateResult operateResult = inovanceTcp.Write(address, value);
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入string数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入string数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址读取Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool readBoolByAddress(string address)
{
try
{
OperateResult<bool> read = inovanceTcp.ReadBool(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取bool数据失败{read.Content}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取bool数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址写入Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeBoolByAddress(string address, bool value)
{
try
{
OperateResult operateResult = inovanceTcp.Write(address, short.Parse(_stringChange.ParseToInt(value ? "1" : "0").ToString()));
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入bool数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入bool数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址写入Double类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeDoubleByAddress(string address, int value)
{
try
{
OperateResult operateResult = inovanceTcp.Write(address, Convert.ToDouble(value));
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入double数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入double数据异常{ex.Message}");
}
}
}

@ -0,0 +1,290 @@
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.0.30319.42000
* Mr.Wen's MacBook Pro
* Sln.Wcs.Plc.Service.Impl
* EA9A83A7-5C7B-462B-8429-5A6542CD7043
*
* WenJY
*
* 2026-05-06 17:15:12
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using System;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using Sln.Wcs.Common;
namespace Sln.Wcs.Plc.Service.Impl;
public class SiemensImpl:IPlc
{
public string ConfigKey { get; set; }
public bool IsConnected { get; set; }
private StringChange _stringChange;
private const SiemensPLCS type = SiemensPLCS.S200Smart;
private SiemensS7Net s7 = new SiemensS7Net(type);
public SiemensImpl(StringChange stringChange)
{
_stringChange = stringChange;
}
/// <summary>
/// 建立连接
/// </summary>
/// <param name="iP"></param>
/// <param name="port"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool Connect(string iP, int port)
{
try
{
s7.IpAddress = iP;
s7.Port = 102;
OperateResult connect = s7.ConnectServer();
this.IsConnected = connect.IsSuccess;
if (!connect.IsSuccess)
{
throw new InvalidOperationException($"西门子S系列PLC连接失败:{connect.Message}");
}
return connect.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"西门子S系列PLC连接异常{ex.Message}");
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool DisConnect()
{
try
{
OperateResult disConnect = s7.ConnectClose();
this.IsConnected = false;
if (!disConnect.IsSuccess)
{
throw new InvalidOperationException($"西门子S系列PLC断开连接失败:{disConnect.Message}");
}
return disConnect.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"西门子S系列PLC断开连接异常{ex.Message}");
}
}
/// <summary>
/// 根据地址读取指定长度数据
/// </summary>
/// <param name="address"></param>
/// <param name="len"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public byte[] readValueByAddress(string address, int len)
{
try
{
OperateResult<byte[]> read = s7.Read(address, (ushort)(len));
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据失败:{read.Message}");
}
return _stringChange.ConvertFloatToINt(read.Content);
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据异常:{ex.Message}");
}
}
/// <summary>
/// 根据地址读取int16数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public int readInt16ByAddress(string address)
{
try
{
OperateResult<short> read = s7.ReadInt16(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取int16数据失败{read.Content}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取int16数据异常{ex.Message}");
}
}
/// <summary>
/// 根据地址写入int16数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeInt16ByAddress(string address, int value)
{
try
{
OperateResult operateResult = s7.Write(address, Convert.ToInt16(value));
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入int16数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入int16数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址读取string类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="length"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public string readStringByAddress(string address, ushort length)
{
try
{
OperateResult<String> read = s7.ReadString(address, length);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取string数据失败{read.Content}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取string数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址写入String类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeStringByAddress(string address, string value)
{
try
{
OperateResult operateResult = s7.Write(address, value);
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入string数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入string数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址读取Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool readBoolByAddress(string address)
{
try
{
OperateResult<bool> read = s7.ReadBool(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取bool数据失败{read.Content}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取bool数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址写入Bool类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeBoolByAddress(string address, bool value)
{
try
{
OperateResult operateResult = s7.Write(address, short.Parse(_stringChange.ParseToInt(value ? "1" : "0").ToString()));
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入bool数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入bool数据异常{ex.Message}");
}
}
/// <summary>
/// 通过PLC地址写入Double类型数据
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public bool writeDoubleByAddress(string address, int value)
{
try
{
OperateResult operateResult = s7.Write(address, Convert.ToDouble(value));
if (!operateResult.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};写入double数据失败{operateResult.Message}");
}
return operateResult.IsSuccess;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};写入double数据异常{ex.Message}");
}
}
}

@ -6,17 +6,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HslCommunication" Version="12.6.3" />
<PackageReference Include="HslCommunication" Version="11.6.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.9" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Sln.Wcs.Common\Sln.Wcs.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Factory\" />
<ProjectReference Include="..\Sln.Wcs.Model\Sln.Wcs.Model.csproj" />
<ProjectReference Include="..\Sln.Wcs.Repository\Sln.Wcs.Repository.csproj" />
<ProjectReference Include="..\Sln.Wcs.Serilog\Sln.Wcs.Serilog.csproj" />
</ItemGroup>
</Project>

@ -9,6 +9,8 @@ using Sln.Wcs.Model.Configs;
using Sln.Wcs.Repository;
using Sln.Wcs.Repository.service;
using Sln.Wcs.Serilog;
using Sln.Wcs.Plc;
using Sln.Wcs.Plc.Service;
using ZiggyCreatures.Caching.Fusion;
using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson;
@ -30,6 +32,7 @@ namespace Sln.Wcs
var log = serviceProvider.GetService<SerilogHelper>();
log.Info($"系统启动成功,日志存放位置:{config["logPath"]}");
}
private static void ConfigureServices(IServiceCollection services)
@ -46,6 +49,7 @@ namespace Sln.Wcs
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HikRoBotSdk.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistApi.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistSdk.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Plc.dll")),
};
services.Scan(scan => scan.FromAssemblies(assemblies)
@ -58,6 +62,8 @@ namespace Sln.Wcs
services.AddSqlSugarSetup();
services.AddPlcSetup();
services.AddFusionCache()
.WithSerializer(
new FusionCacheNewtonsoftJsonSerializer()

@ -31,6 +31,7 @@
<ProjectReference Include="..\Sln.Wcs.HikRoBotSdk\Sln.Wcs.HikRoBotSdk.csproj" />
<ProjectReference Include="..\Sln.Wcs.HoistApi\Sln.Wcs.HoistApi.csproj" />
<ProjectReference Include="..\Sln.Wcs.HoistSdk\Sln.Wcs.HoistSdk.csproj" />
<ProjectReference Include="..\Sln.Wcs.Plc\Sln.Wcs.Plc.csproj" />
<ProjectReference Include="..\Sln.Wcs.Repository\Sln.Wcs.Repository.csproj" />
<ProjectReference Include="..\Sln.Wcs.Serilog\Sln.Wcs.Serilog.csproj" />
</ItemGroup>

Loading…
Cancel
Save