156 lines
4.8 KiB
C#
156 lines
4.8 KiB
C#
using JinYuan.DataConvertLib;
|
|||
|
|
using PLCCommunication.PLCType.Omron;
|
||
|
|
using System;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
|
||
|
|
namespace WindowsService1
|
||
|
|
{
|
||
|
|
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 定义每个数据读取请求的参数。
|
||
|
|
/// </summary>
|
||
|
|
public class PLCDataReadRequest
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// PLC起始地址
|
||
|
|
/// </summary>
|
||
|
|
public string StartAddress { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 读取长度
|
||
|
|
/// </summary>
|
||
|
|
public ushort Length { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 读取区域名称
|
||
|
|
/// </summary>
|
||
|
|
public string StorageName { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 读取数据类型
|
||
|
|
/// </summary>
|
||
|
|
public PLCDataType DataType { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 存储每次读取操作的结果。
|
||
|
|
/// </summary>
|
||
|
|
public class PLCDataResult
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// 读取区域名称
|
||
|
|
/// </summary>
|
||
|
|
public string StorageName { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 读取数据类型
|
||
|
|
/// </summary>
|
||
|
|
public PLCDataType DataType { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 数据
|
||
|
|
/// </summary>
|
||
|
|
public byte[] Data { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 是否读取成功
|
||
|
|
/// </summary>
|
||
|
|
public bool IsSuccess { get; set; }
|
||
|
|
/// <summary>
|
||
|
|
/// 读取失败的错误信息
|
||
|
|
/// </summary>
|
||
|
|
public string ErrorMessage { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
public class PLCDataReader
|
||
|
|
{
|
||
|
|
private readonly OmronFinsNet _plc;
|
||
|
|
|
||
|
|
|
||
|
|
public PLCDataReader(OmronFinsNet plc)
|
||
|
|
{
|
||
|
|
_plc = plc ?? throw new ArgumentNullException(nameof(plc));
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<PLCDataResult> ReadDataAsync(PLCDataReadRequest request)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var data = await _plc.ReadAsync(request.StartAddress, request.Length);
|
||
|
|
if (data.IsSuccess && data.Content.Length > 0)
|
||
|
|
{
|
||
|
|
Logger.WriteInfo($"成功读取PLC数据,起始地址:{request.StartAddress},长度:{request.Length},类型:{request.DataType}");
|
||
|
|
return new PLCDataResult
|
||
|
|
{
|
||
|
|
StorageName = request.StorageName,
|
||
|
|
DataType = request.DataType,
|
||
|
|
Data = data.Content,
|
||
|
|
IsSuccess = true
|
||
|
|
};
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Logger.WriteInfo($"读取PLC数据失败,起始地址:{request.StartAddress},长度:{request.Length},类型:{request.DataType}");
|
||
|
|
return new PLCDataResult
|
||
|
|
{
|
||
|
|
StorageName = request.StorageName,
|
||
|
|
DataType = request.DataType,
|
||
|
|
IsSuccess = false,
|
||
|
|
ErrorMessage = "读取PLC数据失败"
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Logger.WriteError($"读取PLC数据时发生错误:{ex.Message}");
|
||
|
|
return new PLCDataResult
|
||
|
|
{
|
||
|
|
StorageName = request.StorageName,
|
||
|
|
DataType = request.DataType,
|
||
|
|
IsSuccess = false,
|
||
|
|
ErrorMessage = ex.Message
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private object[] ParseData(byte[] content, PLCDataType dataType)
|
||
|
|
{
|
||
|
|
switch (dataType)
|
||
|
|
{
|
||
|
|
case PLCDataType.Short:
|
||
|
|
return ParseShortData(content);
|
||
|
|
case PLCDataType.Float:
|
||
|
|
return ParseFloatData(content);
|
||
|
|
default:
|
||
|
|
throw new ArgumentException($"不支持的数据类型:{dataType}");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private object[] ParseShortData(byte[] content)
|
||
|
|
{
|
||
|
|
int count = content.Length / 2;
|
||
|
|
return Enumerable.Range(0, count)
|
||
|
|
.Select(i => (object)ShortLib.GetShortFromByteArray(content, i * 2))
|
||
|
|
.ToArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private object[] ParseFloatData(byte[] content)
|
||
|
|
{
|
||
|
|
int count = content.Length / 4;
|
||
|
|
return Enumerable.Range(0, count)
|
||
|
|
.Select(i => (object)FloatLib.GetFloatFromByteArray(content, i * 4))
|
||
|
|
.ToArray();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class ConvertHelper
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// 字节数组高低位转换
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="Arrbyte"></param>
|
||
|
|
/// <returns></returns>
|
||
|
|
public static byte[] ByteReverse(this byte[] Arrbyte)
|
||
|
|
{
|
||
|
|
byte[] ArrByte = Arrbyte.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
|
||
|
|
return ArrByte;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|