mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 10:50:48 +08:00
10.9.34
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using ThingsGateway.NewLife.Collections;
|
||||
|
||||
namespace ThingsGateway.NewLife.DictionaryExtensions;
|
||||
|
||||
/// <summary>并发字典扩展</summary>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.9.33</PluginVersion>
|
||||
<ProPluginVersion>10.9.33</ProPluginVersion>
|
||||
<DefaultVersion>10.9.33</DefaultVersion>
|
||||
<PluginVersion>10.9.34</PluginVersion>
|
||||
<ProPluginVersion>10.9.34</ProPluginVersion>
|
||||
<DefaultVersion>10.9.34</DefaultVersion>
|
||||
<AuthenticationVersion>2.9.16</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.9.15</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.17</NET8Version>
|
||||
|
@@ -39,7 +39,8 @@ public interface IThingsGatewayBitConverter
|
||||
|
||||
[JsonProperty(ItemConverterType = typeof(NewtonsoftEncodingConverter))]
|
||||
#endif
|
||||
Encoding Encoding { get; set; }
|
||||
public Encoding? Encoding { get; set; }
|
||||
public Encoding EncodingValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前的Bcd编码类型
|
||||
|
@@ -29,13 +29,16 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(EncodingConverter))]
|
||||
[JsonConverter(typeof(NewtonsoftEncodingConverter))]
|
||||
public Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
public Encoding? Encoding { get; set; }
|
||||
#else
|
||||
|
||||
[JsonConverter(typeof(NewtonsoftEncodingConverter))]
|
||||
public Encoding Encoding { get; set; } = Encoding.UTF8;
|
||||
public Encoding? Encoding { get; set; }
|
||||
|
||||
#endif
|
||||
|
||||
public Encoding EncodingValue => Encoding ?? Encoding.UTF8;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataFormatEnum DataFormat { get; set; }
|
||||
|
||||
@@ -239,7 +242,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] bytes = Encoding.GetBytes(value);
|
||||
byte[] bytes = EncodingValue.GetBytes(value);
|
||||
return IsStringReverseByteWord ? bytes.BytesReverseByWord().ArrayExpandToLength(StringLength.Value) : bytes.ArrayExpandToLength(StringLength.Value);
|
||||
}
|
||||
}
|
||||
@@ -252,7 +255,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] bytes = Encoding.GetBytes(value);
|
||||
byte[] bytes = EncodingValue.GetBytes(value);
|
||||
return IsStringReverseByteWord ? bytes.BytesReverseByWord() : bytes;
|
||||
}
|
||||
}
|
||||
@@ -366,8 +369,8 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
else
|
||||
{
|
||||
return IsStringReverseByteWord ?
|
||||
Encoding.GetString(new ReadOnlySpan<byte>(buffer, offset, len).ToArray().BytesReverseByWord()).TrimEnd().Replace($"\0", "") :
|
||||
Encoding.GetString(buffer, offset, len).TrimEnd().Replace($"\0", "");
|
||||
EncodingValue.GetString(new ReadOnlySpan<byte>(buffer, offset, len).ToArray().BytesReverseByWord()).TrimEnd().Replace($"\0", "") :
|
||||
EncodingValue.GetString(buffer, offset, len).TrimEnd().Replace($"\0", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace ThingsGateway.Foundation.SiemensS7;
|
||||
|
||||
internal static class PackHelper
|
||||
@@ -88,7 +86,7 @@ internal static class PackHelper
|
||||
|
||||
if (s7Address.WStringEnable)
|
||||
{
|
||||
it.ThingsGatewayBitConverter.Encoding = Encoding.Unicode;
|
||||
//it.ThingsGatewayBitConverter.Encoding = Encoding.Unicode;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -98,7 +96,7 @@ internal static class PackHelper
|
||||
// 字符串在S7中,前四个字节不属于实际内容
|
||||
it.Index += 4;
|
||||
lastLen = it.ThingsGatewayBitConverter.StringLength.Value + 4;
|
||||
it.ThingsGatewayBitConverter.Encoding = Encoding.BigEndianUnicode;
|
||||
//it.ThingsGatewayBitConverter.Encoding = Encoding.BigEndianUnicode;
|
||||
|
||||
}
|
||||
else if (it.ThingsGatewayBitConverter.IsVariableStringLength)
|
||||
|
@@ -128,12 +128,12 @@ internal sealed partial class SiemensHelper
|
||||
|
||||
|
||||
|
||||
internal static async ValueTask<OperResult<string>> ReadWStringAsync(SiemensS7Master plc, string address, CancellationToken cancellationToken)
|
||||
internal static async ValueTask<OperResult<string>> ReadWStringAsync(SiemensS7Master plc, string address, Encoding encoding, CancellationToken cancellationToken)
|
||||
{
|
||||
//先读取一次获取长度,再读取实际值
|
||||
if (plc.SiemensS7Type != SiemensTypeEnum.S200Smart)
|
||||
{
|
||||
var encoding = Encoding.BigEndianUnicode;
|
||||
encoding ??= Encoding.BigEndianUnicode;
|
||||
var result1 = await plc.ReadAsync(address, 4, cancellationToken).ConfigureAwait(false);
|
||||
if (!result1.IsSuccess)
|
||||
{
|
||||
@@ -155,7 +155,7 @@ internal sealed partial class SiemensHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
var encoding = Encoding.Unicode;
|
||||
encoding ??= Encoding.Unicode;
|
||||
var result1 = await plc.ReadAsync(address, 1, cancellationToken).ConfigureAwait(false);
|
||||
if (!result1.IsSuccess)
|
||||
return new OperResult<string>(result1);
|
||||
@@ -171,12 +171,12 @@ internal sealed partial class SiemensHelper
|
||||
}
|
||||
}
|
||||
|
||||
internal static async ValueTask<OperResult> WriteWStringAsync(SiemensS7Master plc, string address, string value, CancellationToken cancellationToken = default)
|
||||
internal static async ValueTask<OperResult> WriteWStringAsync(SiemensS7Master plc, string address, string value, Encoding encoding, CancellationToken cancellationToken = default)
|
||||
{
|
||||
value ??= string.Empty;
|
||||
if (plc.SiemensS7Type != SiemensTypeEnum.S200Smart)
|
||||
{
|
||||
byte[] inBytes1 = Encoding.BigEndianUnicode.GetBytes(value);
|
||||
byte[] inBytes1 = (encoding ?? Encoding.BigEndianUnicode).GetBytes(value);
|
||||
var result = await plc.ReadAsync(address, 4, cancellationToken).ConfigureAwait(false);
|
||||
if (!result.IsSuccess) return result;
|
||||
var num = plc.ThingsGatewayBitConverter.ToUInt16(result.Content, 0);
|
||||
@@ -189,7 +189,7 @@ internal sealed partial class SiemensHelper
|
||||
inBytes1
|
||||
), DataTypeEnum.String, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
byte[] inBytes2 = Encoding.Unicode.GetBytes(value);
|
||||
byte[] inBytes2 = (encoding ?? Encoding.Unicode).GetBytes(value);
|
||||
return await plc.WriteAsync(address, DataTransUtil.SpliceArray([(byte)value.Length], inBytes2), DataTypeEnum.String, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -569,7 +569,7 @@ public partial class SiemensS7Master : DeviceBase
|
||||
{
|
||||
return new OperResult<string[]>(AppResource.StringLengthReadError);
|
||||
}
|
||||
var result = await SiemensHelper.ReadWStringAsync(this, address, cancellationToken).ConfigureAwait(false);
|
||||
var result = await SiemensHelper.ReadWStringAsync(this, address, bitConverter.Encoding, cancellationToken).ConfigureAwait(false);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult(new string[] { result.Content });
|
||||
@@ -585,7 +585,7 @@ public partial class SiemensS7Master : DeviceBase
|
||||
{
|
||||
return new OperResult<string[]>(AppResource.StringLengthReadError);
|
||||
}
|
||||
var result = await SiemensHelper.ReadStringAsync(this, address, bitConverter.Encoding, cancellationToken).ConfigureAwait(false);
|
||||
var result = await SiemensHelper.ReadStringAsync(this, address, bitConverter.EncodingValue, cancellationToken).ConfigureAwait(false);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
return OperResult.CreateSuccessResult(new string[] { result.Content });
|
||||
@@ -608,11 +608,11 @@ public partial class SiemensS7Master : DeviceBase
|
||||
|
||||
if (((S7BitConverter)bitConverter)?.WStringEnable == true)
|
||||
{
|
||||
return SiemensHelper.WriteWStringAsync(this, address, value, cancellationToken);
|
||||
return SiemensHelper.WriteWStringAsync(this, address, value, bitConverter.Encoding, cancellationToken);
|
||||
}
|
||||
if (bitConverter.IsVariableStringLength)
|
||||
{
|
||||
return SiemensHelper.WriteStringAsync(this, address, value, bitConverter.Encoding, cancellationToken);
|
||||
return SiemensHelper.WriteStringAsync(this, address, value, bitConverter.EncodingValue, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -8,6 +8,8 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using Opc.Ua;
|
||||
@@ -314,6 +316,14 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
jToken.CalculateActualValueRank(),
|
||||
jToken
|
||||
);
|
||||
if (dataValue == null)
|
||||
{
|
||||
_businessBase.LogMessage?.LogWarning($"{tag.NodeId} value is null , jToken: {jToken}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_businessBase.LogMessage?.LogTrace($"{tag.NodeId} value {dataValue} , jToken: {jToken}");
|
||||
}
|
||||
newValue = dataValue;
|
||||
success = true;
|
||||
}
|
||||
@@ -337,7 +347,6 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
else
|
||||
tag.ValueRank = ValueRanks.Scalar;
|
||||
|
||||
|
||||
var tp = elementType ?? value?.GetType() ?? typeof(string);
|
||||
|
||||
tag.DataType = DataNodeType(tp);
|
||||
@@ -493,8 +502,18 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
UserWriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description,
|
||||
ValueRank = ValueRanks.Scalar,
|
||||
Id = variableRuntime.Id,
|
||||
DataType = DataNodeType(variableRuntime),
|
||||
};
|
||||
var type = DataNodeType(variableRuntime);
|
||||
if (type != null)
|
||||
{
|
||||
variable.DataType = type;
|
||||
variable.IsDataTypeInit = true;
|
||||
var elementType = variableRuntime.Value?.GetType()?.GetElementTypeEx();
|
||||
if (elementType != null)
|
||||
variable.ValueRank = ValueRanks.OneOrMoreDimensions;
|
||||
else
|
||||
variable.ValueRank = ValueRanks.Scalar;
|
||||
}
|
||||
var service = dbDrivers.FirstOrDefault(a => GlobalData.ContainsVariable(a.DeviceId, variableRuntime));
|
||||
var level = ThingsGatewayNodeManager.ProtectTypeTrans(variableRuntime, service != null);
|
||||
variable.AccessLevel = level;
|
||||
@@ -940,20 +959,24 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
/// </summary>
|
||||
/// <param name="variableRuntime"></param>
|
||||
/// <returns></returns>
|
||||
private NodeId DataNodeType(VariableRuntime variableRuntime)
|
||||
private NodeId? DataNodeType(VariableRuntime variableRuntime)
|
||||
{
|
||||
var str = variableRuntime.GetPropertyValue(_businessBase.DeviceId, nameof(OpcUaServerVariableProperty.DataType)) ?? "";
|
||||
Type tp;
|
||||
if (Enum.TryParse(str, out DataTypeEnum result))
|
||||
{
|
||||
tp = result.GetSystemType();
|
||||
return DataNodeType(tp);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp = variableRuntime.Value?.GetType() ?? variableRuntime.DataType.GetSystemType(); ;
|
||||
tp = variableRuntime.Value?.GetType();
|
||||
if (tp != null)
|
||||
{
|
||||
return DataNodeType(tp);
|
||||
}
|
||||
}
|
||||
|
||||
return DataNodeType(tp);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -156,7 +156,12 @@ public partial class OpcUaServer : BusinessBase
|
||||
{
|
||||
// 启动服务器。
|
||||
await m_application.CheckApplicationInstanceCertificates(true, 1200, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await m_application.Start(m_server).ConfigureAwait(false);
|
||||
IdVariableRuntimes.ForEach(a =>
|
||||
{
|
||||
VariableValueChange(a.Value, a.Value.AdaptVariableBasicData());
|
||||
});
|
||||
await base.ProtectedStartAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user