release:6.0.4.41
refactor: 支持blazor hybrid; feat(s7): 支持多写;
This commit is contained in:
@@ -24,14 +24,17 @@ public abstract class ProtocolBase : DisposableObject, IProtocol
|
||||
public ProtocolBase(IChannel channel)
|
||||
{
|
||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||
channel.Collects.Add(this);
|
||||
Channel = channel;
|
||||
Logger = channel.Logger;
|
||||
Channel.Starting += ChannelStarting;
|
||||
Channel.Stoped += ChannelStoped;
|
||||
Channel.Started += ChannelStarted;
|
||||
Channel.ChannelReceived += ChannelReceived;
|
||||
Channel.Config.ConfigurePlugins(ConfigurePlugins());
|
||||
lock (channel)
|
||||
{
|
||||
channel.Collects.Add(this);
|
||||
Channel = channel;
|
||||
Logger = channel.Logger;
|
||||
Channel.Starting += ChannelStarting;
|
||||
Channel.Stoped += ChannelStoped;
|
||||
Channel.Started += ChannelStarted;
|
||||
Channel.ChannelReceived += ChannelReceived;
|
||||
Channel.Config.ConfigurePlugins(ConfigurePlugins());
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>6.0.4.38</Version>
|
||||
<Version>6.0.4.41</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -8,6 +8,7 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Foundation.Json.Extension;
|
||||
using ThingsGateway.Foundation.SiemensS7;
|
||||
|
||||
using TouchSocket.Core;
|
||||
@@ -35,7 +36,8 @@ internal class S7MasterTest
|
||||
addresss[1].Length = addresss[0].Data.Length;
|
||||
addresss[2].Data = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
addresss[2].Length = addresss[0].Data.Length;
|
||||
var result = await siemensS7Master.S7RequestAsync(addresss, false, false);
|
||||
var result = await siemensS7Master.S7WriteAsync(addresss);
|
||||
Console.WriteLine(result.ToJsonNetString());
|
||||
|
||||
S7Variable s7Variable = new S7Variable(siemensS7Master, 200);
|
||||
|
||||
|
@@ -12,6 +12,4 @@
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
@@ -8,6 +8,8 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace ThingsGateway.Foundation.SiemensS7;
|
||||
@@ -46,6 +48,9 @@ public class S7Request
|
||||
/// </summary>
|
||||
public int Length { get; set; }
|
||||
|
||||
|
||||
public int BitLength { get; set; }
|
||||
public bool IsBit { get; set; }
|
||||
#endregion Request
|
||||
}
|
||||
|
||||
@@ -56,7 +61,6 @@ internal class S7Send : ISendMessage
|
||||
{
|
||||
internal bool Handshake;
|
||||
internal byte[] HandshakeBytes;
|
||||
internal bool IsBit;
|
||||
internal bool Read;
|
||||
internal SiemensAddress[] SiemensAddress;
|
||||
|
||||
@@ -66,11 +70,10 @@ internal class S7Send : ISendMessage
|
||||
Handshake = true;
|
||||
}
|
||||
|
||||
public S7Send(SiemensAddress[] siemensAddress, bool read, bool isBit)
|
||||
public S7Send(SiemensAddress[] siemensAddress, bool read)
|
||||
{
|
||||
SiemensAddress = siemensAddress;
|
||||
Read = read;
|
||||
IsBit = isBit;
|
||||
}
|
||||
|
||||
public int MaxLength => 2048;
|
||||
@@ -110,7 +113,7 @@ internal class S7Send : ISendMessage
|
||||
valueByteBlock.WriteByte(0x32);//协议id
|
||||
valueByteBlock.WriteByte(0x01);//请求
|
||||
valueByteBlock.WriteUInt16(0x00, EndianType.Big);//冗余识别
|
||||
valueByteBlock.WriteUInt16(0x01, EndianType.Big);//数据引用
|
||||
valueByteBlock.WriteUInt16((ushort)this.Sign, EndianType.Big);//数据ID标识
|
||||
valueByteBlock.WriteUInt16(parameterLen, EndianType.Big);//参数长度,item.len*12+2
|
||||
valueByteBlock.WriteUInt16(0x00, EndianType.Big);//数据长度,data.len+4 ,写入时填写,读取时为0
|
||||
//par
|
||||
@@ -157,7 +160,7 @@ internal class S7Send : ISendMessage
|
||||
valueByteBlock.WriteByte(0x32);//协议id
|
||||
valueByteBlock.WriteByte(0x01);//请求
|
||||
valueByteBlock.WriteUInt16(0x00, EndianType.Big);//冗余识别
|
||||
valueByteBlock.WriteUInt16(0x01, EndianType.Big);//数据引用
|
||||
valueByteBlock.WriteUInt16((ushort)this.Sign, EndianType.Big);//数据ID标识
|
||||
valueByteBlock.WriteUInt16(parameterLen, EndianType.Big);//参数长度,item.len*12+2
|
||||
valueByteBlock.WriteUInt16(0, EndianType.Big);//数据长度,data.len+4 ,写入时填写,读取时为0
|
||||
|
||||
@@ -172,7 +175,7 @@ internal class S7Send : ISendMessage
|
||||
{
|
||||
var data = address.Data;
|
||||
byte len = (byte)address.Length;
|
||||
bool isBit = (IsBit && len == 1);
|
||||
bool isBit = (address.IsBit && len == 1);
|
||||
valueByteBlock.WriteByte(0x12);//Var 规范
|
||||
valueByteBlock.WriteByte(0x0a);//剩余的字节长度
|
||||
valueByteBlock.WriteByte(0x10);//Syntax ID
|
||||
@@ -190,14 +193,15 @@ internal class S7Send : ISendMessage
|
||||
{
|
||||
var data = address.Data;
|
||||
byte len = (byte)address.Length;
|
||||
bool isBit = (IsBit && len == 1);
|
||||
bool isBit = (address.IsBit && len == 1);
|
||||
data = data.ArrayExpandToLengthEven();
|
||||
//后面跟的是写入的数据信息
|
||||
valueByteBlock.WriteByte(0);
|
||||
valueByteBlock.WriteByte((byte)(isBit ? 3 : 4));//Bit:3;Byte:4;Counter或者Timer:9
|
||||
valueByteBlock.WriteUInt16((ushort)(isBit ? len : len * 8), EndianType.Big);
|
||||
valueByteBlock.WriteByte((byte)(isBit ? address.DataCode == (byte)S7WordLength.Counter ? 9 : 3 : 4));//Bit:3;Byte:4;Counter或者Timer:9
|
||||
valueByteBlock.WriteUInt16((ushort)(isBit ? (byte)address.BitLength : len * 8), EndianType.Big);
|
||||
valueByteBlock.Write(data);
|
||||
|
||||
dataLen = (ushort)(dataLen +data.Length+4);
|
||||
dataLen = (ushort)(dataLen + data.Length + 4);
|
||||
}
|
||||
ushort telegramLen = (ushort)(itemLen * 12 + 19 + dataLen);
|
||||
valueByteBlock.Position = 2;
|
||||
|
@@ -31,6 +31,9 @@ public class SiemensAddress : S7Request
|
||||
this.DbBlock = siemensAddress.DbBlock;
|
||||
this.Data = siemensAddress.Data;
|
||||
this.Length = siemensAddress.Length;
|
||||
|
||||
BitLength=siemensAddress.BitLength;
|
||||
IsBit= siemensAddress.IsBit;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -9,6 +9,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Data;
|
||||
using System.Net;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
@@ -23,8 +24,18 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
/// <inheritdoc/>
|
||||
public SiemensS7Master(IChannel channel) : base(channel)
|
||||
{
|
||||
RegisterByteLength = 1;
|
||||
ThingsGatewayBitConverter = new S7BitConverter(EndianType.Big);
|
||||
lock (channel)
|
||||
{
|
||||
RegisterByteLength = 1;
|
||||
ThingsGatewayBitConverter = new S7BitConverter(EndianType.Big);
|
||||
|
||||
if (channel.Collects.Count(a => a.GetType() == typeof(SiemensS7Master)) > 1)
|
||||
{
|
||||
Channel.Starting -= ChannelStarting;
|
||||
Channel.Stoped -= ChannelStoped;
|
||||
Channel.Started -= ChannelStarted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -117,9 +128,8 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
/// <summary>
|
||||
/// 此方法并不会智能分组以最大化效率,减少传输次数,因为返回值是byte[],所以一切都按地址数组的顺序执行,最后合并数组
|
||||
/// </summary>
|
||||
public async ValueTask<OperResult<byte[]>> S7RequestAsync(SiemensAddress[] sAddresss, bool read, bool isBit, int bitLength = 0, CancellationToken cancellationToken = default)
|
||||
public async ValueTask<OperResult<byte[]>> S7ReadAsync(SiemensAddress[] sAddresss, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (read)
|
||||
{
|
||||
var byteBlock = new ValueByteBlock(2048);
|
||||
try
|
||||
@@ -135,7 +145,7 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
sAddress.Length = len;
|
||||
|
||||
var result = await this.SendThenReturnAsync(
|
||||
new S7Send([sAddress], read, isBit), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
new S7Send([sAddress], true), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
if (!result.IsSuccess) return result;
|
||||
|
||||
byteBlock.Write(result.Content);
|
||||
@@ -163,14 +173,27 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
byteBlock.SafeDispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
/// <summary>
|
||||
/// 此方法并不会智能分组以最大化效率,减少传输次数,因为返回值是byte[],所以一切都按地址数组的顺序执行,最后合并数组
|
||||
/// </summary>
|
||||
public async ValueTask<Dictionary<SiemensAddress, OperResult>> S7WriteAsync(SiemensAddress[] sAddresss, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
|
||||
var dictOperResult = new Dictionary<SiemensAddress, OperResult>();
|
||||
|
||||
void SetFailOperResult(OperResult operResult)
|
||||
{
|
||||
foreach (var item in sAddresss)
|
||||
{
|
||||
dictOperResult.TryAdd(item, operResult);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var sAddress = sAddresss[0];
|
||||
if (sAddresss.Length > 1 && isBit)
|
||||
{
|
||||
return new OperResult<byte[]>("Only supports single write");
|
||||
}
|
||||
else if (sAddresss.Length <= 1 && isBit)
|
||||
if (sAddresss.Length <= 1 && sAddress.IsBit)
|
||||
{
|
||||
//读取,再写入
|
||||
var byteBlock = new ValueByteBlock(2048);
|
||||
@@ -179,24 +202,36 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
var addressLen = sAddress.Length == 0 ? 1 : sAddress.Length;
|
||||
|
||||
if (addressLen > PduLength)
|
||||
return new OperResult<byte[]>("Write length exceeds limit");
|
||||
{
|
||||
SetFailOperResult(new OperResult("Write length exceeds limit"));
|
||||
return dictOperResult;
|
||||
}
|
||||
|
||||
var result = await this.SendThenReturnAsync(
|
||||
new S7Send([sAddress], true, isBit), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
new S7Send([sAddress], true), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!result.IsSuccess) return result;
|
||||
var vaue = sAddress.Data.ByteToBoolArray(bitLength);
|
||||
for (int i = sAddress.BitCode; i < vaue.Length + sAddress.BitCode; i++)
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
result.Content[i / 8] = result.Content[i / 8].SetBit((i % 8), vaue[i - sAddress.BitCode]);
|
||||
SetFailOperResult(result);
|
||||
return dictOperResult;
|
||||
}
|
||||
|
||||
var value = sAddress.Data.ByteToBoolArray(sAddress.BitLength);
|
||||
for (int i = sAddress.BitCode; i < value.Length + sAddress.BitCode; i++)
|
||||
{
|
||||
result.Content[i / 8] = result.Content[i / 8].SetBit((i % 8), value[i - sAddress.BitCode]);
|
||||
}
|
||||
sAddress.Data = result.Content;
|
||||
return await this.SendThenReturnAsync(
|
||||
new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
var wresult = await this.SendThenReturnAsync(
|
||||
new S7Send([sAddress], false), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
dictOperResult.TryAdd(sAddress, wresult);
|
||||
return dictOperResult;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
SetFailOperResult(new OperResult(ex));
|
||||
return dictOperResult;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -212,7 +247,7 @@ new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).Conf
|
||||
List<SiemensAddress> addresses = new();
|
||||
foreach (var item in sAddresss)
|
||||
{
|
||||
siemensAddresses.Add(addresses);
|
||||
siemensAddresses.Add(addresses);
|
||||
dataLen = (ushort)(dataLen + item.Data.Length + 4);
|
||||
ushort telegramLen = (ushort)(itemLen * 12 + 19 + dataLen);
|
||||
if (telegramLen < PduLength)
|
||||
@@ -234,7 +269,8 @@ new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).Conf
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>("Write length exceeds limit");
|
||||
SetFailOperResult(new OperResult("Write length exceeds limit"));
|
||||
return dictOperResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,24 +282,25 @@ new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).Conf
|
||||
try
|
||||
{
|
||||
var result = await this.SendThenReturnAsync(
|
||||
new S7Send(item.ToArray(), read, isBit), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
if(!result.IsSuccess)
|
||||
new S7Send(item.ToArray(), false), cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
foreach (var i1 in item)
|
||||
{
|
||||
return result;
|
||||
dictOperResult.TryAdd(i1, result);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
|
||||
SetFailOperResult(new OperResult(ex));
|
||||
return dictOperResult;
|
||||
}
|
||||
|
||||
}
|
||||
return new();
|
||||
return dictOperResult;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region 读写
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -272,7 +309,7 @@ new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).Conf
|
||||
try
|
||||
{
|
||||
var sAddress = SiemensAddress.ParseFrom(address, length);
|
||||
return S7RequestAsync([sAddress], true, false, 0, cancellationToken);
|
||||
return S7ReadAsync([sAddress], cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -288,7 +325,7 @@ new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).Conf
|
||||
var sAddress = SiemensAddress.ParseFrom(address);
|
||||
sAddress.Data = value;
|
||||
sAddress.Length = value.Length;
|
||||
return await S7RequestAsync([sAddress], false, false, 0, cancellationToken);
|
||||
return (await S7WriteAsync([sAddress], cancellationToken)).FirstOrDefault().Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -299,16 +336,14 @@ new S7Send([sAddress], false, isBit), cancellationToken: cancellationToken).Conf
|
||||
/// <inheritdoc/>
|
||||
public override async ValueTask<OperResult> WriteAsync(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//if (value.Length > 1)
|
||||
//{
|
||||
// return new OperResult(SiemensS7Resource.Localizer["MulWriteError"]);
|
||||
//}
|
||||
try
|
||||
{
|
||||
var sAddress = SiemensAddress.ParseFrom(address);
|
||||
sAddress.Data = value.BoolArrayToByte();
|
||||
sAddress.Length = sAddress.Data.Length;
|
||||
return await S7RequestAsync([sAddress], false, true, value.Length, cancellationToken);
|
||||
sAddress.BitLength = value.Length;
|
||||
sAddress.IsBit = true;
|
||||
return (await S7WriteAsync([sAddress], cancellationToken)).FirstOrDefault().Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@@ -8,6 +8,13 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
|
||||
using ThingsGateway.Foundation.SiemensS7;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
using TouchSocket.Core;
|
||||
@@ -54,6 +61,127 @@ public class SiemensS7Master : CollectBase
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取jtoken值代表的字节数组,不包含字符串
|
||||
/// </summary>
|
||||
/// <param name="dataType"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public byte[] GetBytes(DataTypeEnum dataType, JToken value)
|
||||
{
|
||||
//排除字符串
|
||||
if (value is JArray jArray)
|
||||
{
|
||||
return dataType switch
|
||||
{
|
||||
DataTypeEnum.Boolean => jArray.ToObject<Boolean[]>().BoolArrayToByte(),
|
||||
DataTypeEnum.Byte => jArray.ToObject<Byte[]>(),
|
||||
DataTypeEnum.Int16 => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<Int16[]>()),
|
||||
DataTypeEnum.UInt16 => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<UInt16[]>()),
|
||||
DataTypeEnum.Int32 => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<Int32[]>()),
|
||||
DataTypeEnum.UInt32 => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<UInt32[]>()),
|
||||
DataTypeEnum.Int64 => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<Int64[]>()),
|
||||
DataTypeEnum.UInt64 => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<UInt64[]>()),
|
||||
DataTypeEnum.Single => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<Single[]>()),
|
||||
DataTypeEnum.Double => _plc.ThingsGatewayBitConverter.GetBytes(jArray.ToObject<Double[]>()),
|
||||
_ => throw new(DefaultResource.Localizer["DataTypeNotSupported", dataType]),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return dataType switch
|
||||
{
|
||||
DataTypeEnum.Boolean => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<Boolean>()),
|
||||
DataTypeEnum.Byte => [value.ToObject<Byte>()],
|
||||
DataTypeEnum.Int16 => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<Int16>()),
|
||||
DataTypeEnum.UInt16 => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<UInt16>()),
|
||||
DataTypeEnum.Int32 => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<Int32>()),
|
||||
DataTypeEnum.UInt32 => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<UInt32>()),
|
||||
DataTypeEnum.Int64 => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<Int64>()),
|
||||
DataTypeEnum.UInt64 => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<UInt64>()),
|
||||
DataTypeEnum.Single => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<Single>()),
|
||||
DataTypeEnum.Double => _plc.ThingsGatewayBitConverter.GetBytes(value.ToObject<Double>()),
|
||||
_ => throw new(DefaultResource.Localizer["DataTypeNotSupported", dataType]),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override async ValueTask<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<VariableRunTime, JToken> writeInfoLists, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 如果是单线程模式,则等待写入锁
|
||||
if (IsSingleThread)
|
||||
await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// 检查协议是否为空,如果为空则抛出异常
|
||||
if (Protocol == null)
|
||||
throw new NotSupportedException();
|
||||
|
||||
// 创建用于存储操作结果的并发字典
|
||||
ConcurrentDictionary<string, OperResult> operResults = new();
|
||||
|
||||
//转换
|
||||
Dictionary<VariableRunTime, SiemensAddress> addresses = new();
|
||||
var w1 = writeInfoLists.Where(a => a.Key.DataType != DataTypeEnum.String);
|
||||
var w2 = writeInfoLists.Where(a => a.Key.DataType == DataTypeEnum.String);
|
||||
foreach (var item in w1)
|
||||
{
|
||||
SiemensAddress siemensAddress = SiemensAddress.ParseFrom(item.Key.RegisterAddress);
|
||||
siemensAddress.Data = GetBytes(item.Key.DataType, item.Value);
|
||||
siemensAddress.Length = siemensAddress.Data.Length;
|
||||
siemensAddress.BitLength = 1;
|
||||
siemensAddress.IsBit = item.Key.DataType == DataTypeEnum.Boolean;
|
||||
if (item.Key.DataType == DataTypeEnum.Boolean)
|
||||
{
|
||||
if (item.Value is JArray jArray)
|
||||
{
|
||||
siemensAddress.BitLength = jArray.ToObject<Boolean[]>().Length;
|
||||
}
|
||||
}
|
||||
addresses.Add(item.Key, siemensAddress);
|
||||
}
|
||||
|
||||
var result = await _plc.S7WriteAsync(addresses.Select(a => a.Value).ToArray(), cancellationToken).ConfigureAwait(false);
|
||||
foreach (var writeInfo in addresses)
|
||||
{
|
||||
if (result.TryGetValue(writeInfo.Value, out var r1))
|
||||
{
|
||||
operResults.TryAdd(writeInfo.Key.Name, r1);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用并发方式遍历写入信息列表,并进行异步写入操作
|
||||
await w2.ParallelForEachAsync(async (writeInfo, cancellationToken) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用协议的写入方法,将写入信息中的数据写入到对应的寄存器地址,并获取操作结果
|
||||
var result = await Protocol.WriteAsync(writeInfo.Key.RegisterAddress, writeInfo.Value, writeInfo.Key.DataType, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// 将操作结果添加到结果字典中,使用变量名称作为键
|
||||
operResults.TryAdd(writeInfo.Key.Name, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
operResults.TryAdd(writeInfo.Key.Name, new(ex));
|
||||
}
|
||||
}, CollectProperties.ConcurrentCount, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
||||
// 返回包含操作结果的字典
|
||||
return new Dictionary<string, OperResult>(operResults);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 如果是单线程模式,则释放写入锁
|
||||
if (IsSingleThread)
|
||||
WriteLock.Release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="SiemensS7PLC.ReadDateAsync(string,CancellationToken)"/>
|
||||
/// </summary>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageReference Include="MiniExcel" Version="1.34.0" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="8.7.4" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="8.7.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.7" />
|
||||
|
Reference in New Issue
Block a user