refactor: 字节解析顺序回退5.x版本策略

This commit is contained in:
Diego
2024-06-09 12:23:55 +08:00
parent fd5ed78442
commit 0f3f4b0f5b
34 changed files with 578 additions and 105 deletions

View File

@@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation;
/// <summary>
/// 应用于多字节数据的解析或是生成格式<br />
/// </summary>
public enum DataFormatEnum
{
/// <summary>Big-Endian</summary>
ABCD,
/// <summary>Big-Endian Byte Swap</summary>
BADC,
/// <summary>Little-Endian Byte Swap</summary>
CDAB,
/// <summary>Little-Endian</summary>
DCBA,
}

View File

@@ -29,11 +29,6 @@ public interface IProtocol : IDisposable
/// </summary>
IChannel Channel { get; }
/// <summary>
/// 数据解析规则
/// </summary>
EndianType EndianType { get; set; }
/// <summary>
/// 数据解析规则
/// </summary>
@@ -72,6 +67,11 @@ public interface IProtocol : IDisposable
/// </summary>
ushort ConnectTimeout { get; set; }
/// <summary>
/// 数据解析规则
/// </summary>
DataFormatEnum DataFormat { get; set; }
#endregion
#region

View File

@@ -46,13 +46,6 @@ public abstract class ProtocolBase : DisposableObject, IProtocol
/// <inheritdoc/>
public virtual int CacheTimeout { get; set; } = 1000;
/// <inheritdoc/>
public virtual EndianType EndianType
{
get => ThingsGatewayBitConverter.EndianType;
set => ThingsGatewayBitConverter.EndianType = value;
}
/// <inheritdoc/>
public virtual int SendDelayTime { get; set; }
@@ -77,6 +70,13 @@ public abstract class ProtocolBase : DisposableObject, IProtocol
}
}
/// <inheritdoc/>
public virtual DataFormatEnum DataFormat
{
get => ThingsGatewayBitConverter.DataFormat;
set => ThingsGatewayBitConverter.DataFormat = value;
}
/// <inheritdoc/>
public virtual IChannel Channel { get; }

View File

@@ -27,7 +27,7 @@ public interface IThingsGatewayBitConverter
/// <summary>
/// 指定大小端。
/// </summary>
EndianType EndianType { get; set; }
EndianType EndianType { get; }
/// <summary>
/// 当前的字符串编码类型
@@ -61,6 +61,8 @@ public interface IThingsGatewayBitConverter
/// </summary>
bool IsStringReverseByteWord { get; set; }
DataFormatEnum DataFormat { get; set; }
#region GetBytes
/// <summary>

View File

@@ -10,6 +10,8 @@
using Newtonsoft.Json;
using System;
using System.Runtime.CompilerServices;
using System.Text;
using ThingsGateway.Foundation.Extension.Generic;
@@ -61,7 +63,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
}
/// <inheritdoc/>
public virtual EndianType EndianType { get; set; }
public virtual EndianType EndianType { get; }
/// <inheritdoc/>
public virtual bool IsStringReverseByteWord { get; set; }
@@ -111,7 +113,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 2);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -123,7 +125,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 2);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -135,7 +137,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 4);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -147,7 +149,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 4);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -159,7 +161,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 4);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -171,7 +173,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 4);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -183,7 +185,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 4);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -195,7 +197,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
using ValueByteBlock byteBlock = new ValueByteBlock(value.Length * 4);
for (int index = 0; index < value.Length; ++index)
{
byte[] bytes = TouchSocketBitConverter.GetBytes(value[index]);
byte[] bytes = GetBytes(value[index]);
byteBlock.Write(bytes);
}
return byteBlock.ToArray();
@@ -244,13 +246,55 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
/// <inheritdoc/>
public virtual int ToInt32(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToInt32(buffer, offset);
if (buffer.Length - offset < 4)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<int>(p);
}
else
{
this.ByteTransDataFormat4_Net6(ref buffer[offset]);
var v = Unsafe.Read<int>(p);
this.ByteTransDataFormat4_Net6(ref buffer[offset]);
return v;
}
}
}
}
/// <inheritdoc/>
public virtual long ToInt64(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToInt64(buffer, offset);
if (buffer.Length - offset < 8)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<long>(p);
}
else
{
this.ByteTransDataFormat8_Net6(ref buffer[offset]);
var v = Unsafe.Read<long>(p);
this.ByteTransDataFormat8_Net6(ref buffer[offset]);
return v;
}
}
}
}
/// <inheritdoc/>
@@ -262,24 +306,108 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
/// <inheritdoc/>
public virtual uint ToUInt32(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToUInt32(buffer, offset);
if (buffer.Length - offset < 4)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<uint>(p);
}
else
{
this.ByteTransDataFormat4_Net6(ref buffer[offset]);
var v = Unsafe.Read<uint>(p);
this.ByteTransDataFormat4_Net6(ref buffer[offset]);
return v;
}
}
}
}
/// <inheritdoc/>
public virtual ulong ToUInt64(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToUInt64(buffer, offset);
if (buffer.Length - offset < 8)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<ulong>(p);
}
else
{
this.ByteTransDataFormat8_Net6(ref buffer[offset]);
var v = Unsafe.Read<ulong>(p);
this.ByteTransDataFormat8_Net6(ref buffer[offset]);
return v;
}
}
}
}
/// <inheritdoc/>
public virtual float ToSingle(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToSingle(buffer, offset);
if (buffer.Length - offset < 4)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<float>(p);
}
else
{
this.ByteTransDataFormat4_Net6(ref buffer[offset]);
var v = Unsafe.Read<float>(p);
this.ByteTransDataFormat4_Net6(ref buffer[offset]);
return v;
}
}
}
}
public virtual double ToDouble(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToDouble(buffer, offset);
if (buffer.Length - offset < 8)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<double>(p);
}
else
{
this.ByteTransDataFormat8_Net6(ref buffer[offset]);
var v = Unsafe.Read<double>(p);
this.ByteTransDataFormat8_Net6(ref buffer[offset]);
return v;
}
}
}
}
/// <inheritdoc/>
@@ -402,7 +530,13 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
public virtual byte[] GetBytes(decimal value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = new byte[16];
Unsafe.As<byte, decimal>(ref bytes[0]) = value;
if (DataFormat != DataFormatEnum.DCBA)
{
this.ByteTransDataFormat16_Net6(ref bytes[0]);
}
return bytes;
}
public virtual byte[] GetBytes(char value)
@@ -432,41 +566,325 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
public virtual byte[] GetBytes(int value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = BitConverter.GetBytes(value);
if (DataFormat != DataFormatEnum.DCBA)
bytes = this.ByteTransDataFormat4(bytes, 0);
return bytes;
}
public virtual byte[] GetBytes(uint value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = BitConverter.GetBytes(value);
if (DataFormat != DataFormatEnum.DCBA)
bytes = this.ByteTransDataFormat4(bytes, 0);
return bytes;
}
public virtual byte[] GetBytes(long value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = BitConverter.GetBytes(value);
if (DataFormat != DataFormatEnum.DCBA)
bytes = this.ByteTransDataFormat8(bytes, 0);
return bytes;
}
public virtual byte[] GetBytes(ulong value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = BitConverter.GetBytes(value);
if (DataFormat != DataFormatEnum.DCBA)
bytes = this.ByteTransDataFormat8(bytes, 0);
return bytes;
}
public virtual byte[] GetBytes(float value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = BitConverter.GetBytes(value);
if (DataFormat != DataFormatEnum.DCBA)
bytes = this.ByteTransDataFormat4(bytes, 0);
return bytes;
}
public virtual byte[] GetBytes(double value)
{
return TouchSocketBitConverter.GetBytes(value);
var bytes = BitConverter.GetBytes(value);
if (DataFormat != DataFormatEnum.DCBA)
bytes = this.ByteTransDataFormat8(bytes, 0);
return bytes;
}
public virtual decimal ToDecimal(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToDecimal(buffer, offset);
if (buffer.Length - offset < 16)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
unsafe
{
fixed (byte* p = &buffer[offset])
{
if (DataFormat == DataFormatEnum.DCBA)
{
return Unsafe.Read<decimal>(p);
}
else
{
this.ByteTransDataFormat16_Net6(ref buffer[offset]);
var v = Unsafe.Read<decimal>(p);
this.ByteTransDataFormat16_Net6(ref buffer[offset]);
return v;
}
}
}
}
public virtual char ToChar(byte[] buffer, int offset)
{
return TouchSocketBitConverter.ToChar(buffer, offset);
}
public DataFormatEnum DataFormat { get; set; }
#region Tool
/// <summary>反转多字节的数据信息</summary>
/// <param name="value">数据字节</param>
/// <param name="offset">起始索引默认值为0</param>
/// <returns>实际字节信息</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte[] ByteTransDataFormat4(byte[] value, int offset)
{
var numArray = new byte[4];
switch (this.DataFormat)
{
case DataFormatEnum.ABCD:
numArray[0] = value[offset + 3];
numArray[1] = value[offset + 2];
numArray[2] = value[offset + 1];
numArray[3] = value[offset];
break;
case DataFormatEnum.BADC:
numArray[0] = value[offset + 2];
numArray[1] = value[offset + 3];
numArray[2] = value[offset];
numArray[3] = value[offset + 1];
break;
case DataFormatEnum.CDAB:
numArray[0] = value[offset + 1];
numArray[1] = value[offset];
numArray[2] = value[offset + 3];
numArray[3] = value[offset + 2];
break;
case DataFormatEnum.DCBA:
numArray[0] = value[offset];
numArray[1] = value[offset + 1];
numArray[2] = value[offset + 2];
numArray[3] = value[offset + 3];
break;
}
return numArray;
}
/// <summary>反转多字节的数据信息</summary>
/// <param name="value">数据字节</param>
/// <param name="offset">起始索引默认值为0</param>
/// <returns>实际字节信息</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte[] ByteTransDataFormat8(byte[] value, int offset)
{
var numArray = new byte[8];
switch (this.DataFormat)
{
case DataFormatEnum.ABCD:
numArray[0] = value[offset + 7];
numArray[1] = value[offset + 6];
numArray[2] = value[offset + 5];
numArray[3] = value[offset + 4];
numArray[4] = value[offset + 3];
numArray[5] = value[offset + 2];
numArray[6] = value[offset + 1];
numArray[7] = value[offset];
break;
case DataFormatEnum.BADC:
numArray[0] = value[offset + 6];
numArray[1] = value[offset + 7];
numArray[2] = value[offset + 4];
numArray[3] = value[offset + 5];
numArray[4] = value[offset + 2];
numArray[5] = value[offset + 3];
numArray[6] = value[offset];
numArray[7] = value[offset + 1];
break;
case DataFormatEnum.CDAB:
numArray[0] = value[offset + 1];
numArray[1] = value[offset];
numArray[2] = value[offset + 3];
numArray[3] = value[offset + 2];
numArray[4] = value[offset + 5];
numArray[5] = value[offset + 4];
numArray[6] = value[offset + 7];
numArray[7] = value[offset + 6];
break;
case DataFormatEnum.DCBA:
numArray[0] = value[offset];
numArray[1] = value[offset + 1];
numArray[2] = value[offset + 2];
numArray[3] = value[offset + 3];
numArray[4] = value[offset + 4];
numArray[5] = value[offset + 5];
numArray[6] = value[offset + 6];
numArray[7] = value[offset + 7];
break;
}
return numArray;
}
#endregion Tool
#region Tool
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ByteTransDataFormat4_Net6(ref byte value)
{
unsafe
{
fixed (byte* p = &value)
{
var a = Unsafe.ReadUnaligned<byte>(p);
var b = Unsafe.ReadUnaligned<byte>(p + 1);
var c = Unsafe.ReadUnaligned<byte>(p + 2);
var d = Unsafe.ReadUnaligned<byte>(p + 3);
switch (this.DataFormat)
{
case DataFormatEnum.ABCD:
Unsafe.WriteUnaligned(p, d);
Unsafe.WriteUnaligned(p + 1, c);
Unsafe.WriteUnaligned(p + 2, b);
Unsafe.WriteUnaligned(p + 3, a);
break;
case DataFormatEnum.BADC:
Unsafe.WriteUnaligned(p, c);
Unsafe.WriteUnaligned(p + 1, d);
Unsafe.WriteUnaligned(p + 2, a);
Unsafe.WriteUnaligned(p + 3, b);
break;
case DataFormatEnum.CDAB:
Unsafe.WriteUnaligned(p, b);
Unsafe.WriteUnaligned(p + 1, a);
Unsafe.WriteUnaligned(p + 2, d);
Unsafe.WriteUnaligned(p + 3, c);
break;
case DataFormatEnum.DCBA:
return;
}
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ByteTransDataFormat8_Net6(ref byte value)
{
unsafe
{
fixed (byte* p = &value)
{
var a = Unsafe.ReadUnaligned<byte>(p);
var b = Unsafe.ReadUnaligned<byte>(p + 1);
var c = Unsafe.ReadUnaligned<byte>(p + 2);
var d = Unsafe.ReadUnaligned<byte>(p + 3);
var e = Unsafe.ReadUnaligned<byte>(p + 4);
var f = Unsafe.ReadUnaligned<byte>(p + 5);
var g = Unsafe.ReadUnaligned<byte>(p + 6);
var h = Unsafe.ReadUnaligned<byte>(p + 7);
switch (this.DataFormat)
{
case DataFormatEnum.ABCD:
Unsafe.WriteUnaligned(p, h);
Unsafe.WriteUnaligned(p + 1, g);
Unsafe.WriteUnaligned(p + 2, f);
Unsafe.WriteUnaligned(p + 3, e);
Unsafe.WriteUnaligned(p + 4, d);
Unsafe.WriteUnaligned(p + 5, c);
Unsafe.WriteUnaligned(p + 6, b);
Unsafe.WriteUnaligned(p + 7, a);
break;
case DataFormatEnum.BADC:
Unsafe.WriteUnaligned(p, g);
Unsafe.WriteUnaligned(p + 1, h);
Unsafe.WriteUnaligned(p + 2, e);
Unsafe.WriteUnaligned(p + 3, f);
Unsafe.WriteUnaligned(p + 4, c);
Unsafe.WriteUnaligned(p + 5, d);
Unsafe.WriteUnaligned(p + 6, a);
Unsafe.WriteUnaligned(p + 7, b);
break;
case DataFormatEnum.CDAB:
Unsafe.WriteUnaligned(p, b);
Unsafe.WriteUnaligned(p + 1, a);
Unsafe.WriteUnaligned(p + 2, d);
Unsafe.WriteUnaligned(p + 3, c);
Unsafe.WriteUnaligned(p + 4, f);
Unsafe.WriteUnaligned(p + 5, e);
Unsafe.WriteUnaligned(p + 6, h);
Unsafe.WriteUnaligned(p + 7, g);
break;
case DataFormatEnum.DCBA:
break;
}
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ByteTransDataFormat16_Net6(ref byte value)
{
unsafe
{
fixed (byte* p = &value)
{
switch (this.DataFormat)
{
case DataFormatEnum.ABCD:
var span = new Span<byte>(p, 16);
span.Reverse();
break;
case DataFormatEnum.DCBA:
return;
default:
throw new NotSupportedException();
}
}
}
}
#endregion Tool
}

View File

@@ -24,7 +24,7 @@ namespace ThingsGateway.Foundation;
public static class ThingsGatewayBitConverterExtension
{
/// <summary>
/// 从设备地址中解析附加信息,包括 endianType=XX;4字节数据解析规则、encoding=XX;字符串解析规则、len=XX;读写长度、bcdFormat=XX; bcd解析规则等。
/// 从设备地址中解析附加信息,包括 dataFormat=XX;4字节数据解析规则、encoding=XX;字符串解析规则、len=XX;读写长度、bcdFormat=XX; bcd解析规则等。
/// 这个方法获取<see cref="IThingsGatewayBitConverter"/>,并去掉地址中的所有额外信息。
/// 解析步骤将被缓存。
/// </summary>
@@ -49,7 +49,7 @@ public static class ThingsGatewayBitConverterExtension
// 根据分号拆分附加信息
var strs = registerAddress.SplitStringBySemicolon();
EndianType? endianType = null;
DataFormatEnum? dataFormat = null;
Encoding? encoding = null;
int? length = null;
int? stringlength = null;
@@ -57,11 +57,11 @@ public static class ThingsGatewayBitConverterExtension
StringBuilder sb = new();
foreach (var str in strs)
{
// 解析 endianType
// 解析 dataFormat
if (str.ToLower().StartsWith("data="))
{
var endianTypeName = str.Substring(5);
try { if (Enum.TryParse<EndianType>(endianTypeName, true, out var endianType1)) endianType = endianType1; } catch { }
var dataFormatName = str.Substring(5);
try { if (Enum.TryParse<DataFormatEnum>(dataFormatName, true, out var dataFormat1)) dataFormat = dataFormat1; } catch { }
}
// 解析 encoding
else if (str.ToLower().StartsWith("encoding="))
@@ -101,7 +101,7 @@ public static class ThingsGatewayBitConverterExtension
registerAddress = sb.ToString();
// 如果没有解析出任何附加信息,则直接返回默认的数据转换器
if (bcdFormat == null && length == null && stringlength == null && encoding == null && endianType == null)
if (bcdFormat == null && length == null && stringlength == null && encoding == null && dataFormat == null)
{
return defaultBitConverter;
}
@@ -126,9 +126,9 @@ public static class ThingsGatewayBitConverterExtension
{
converter.StringLength = stringlength.Value;
}
if (endianType != null)
if (dataFormat != null)
{
converter.EndianType = endianType.Value;
converter.DataFormat = dataFormat.Value;
}
// 将解析结果添加到缓存中缓存有效期为3600秒

View File

@@ -67,7 +67,7 @@ public class Variable : PrimaryIdEntity
public virtual int? IntervalTime { get; set; }
/// <summary>
/// 变量地址,可能带有额外的信息,比如<see cref="EndianType"/> ,以;分割
/// 变量地址,可能带有额外的信息,比如<see cref="DataFormatEnum"/> ,以;分割
/// </summary>
[SugarColumn(ColumnDescription = "变量地址", Length = 200, IsNullable = true)]
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]

View File

@@ -1,6 +1,7 @@
@namespace ThingsGateway.Gateway.Razor
@using ThingsGateway.Admin.Application
@using ThingsGateway.Admin.Razor
@using ThingsGateway.Foundation
@using ThingsGateway.Gateway.Application
@inherits ComponentDefault
@@ -20,7 +21,15 @@
</EditTemplate>
</EditorItem>
<EditorItem @bind-Field="@context.Name" Readonly=BatchEditEnable />
<EditorItem @bind-Field="@context.ChannelType" />
<EditorItem @bind-Field="@context.ChannelType">
<EditTemplate Context="value">
<div class="col-12 col-sm-6">
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>InvokeAsync(StateHasChanged)) />
</div>
</EditTemplate>
</EditorItem>
<EditorItem @bind-Field="@context.Enable" />
<EditorItem @bind-Field="@context.LogEnable" />
@@ -32,15 +41,16 @@
</EditTemplate>
</EditorItem>
<EditorItem @bind-Field="@context.RemoteUrl" />
<EditorItem @bind-Field="@context.BindUrl" />
<EditorItem @bind-Field="@context.PortName" />
<EditorItem @bind-Field="@context.BaudRate" />
<EditorItem @bind-Field="@context.DataBits" />
<EditorItem @bind-Field="@context.Parity" />
<EditorItem @bind-Field="@context.StopBits" />
<EditorItem @bind-Field="@context.DtrEnable" />
<EditorItem @bind-Field="@context.RtsEnable" />
<EditorItem @bind-Field="@context.RemoteUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
<EditorItem @bind-Field="@context.BindUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession&&context.ChannelType!=ChannelTypeEnum.TcpService) />
<EditorItem @bind-Field="@context.PortName" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.BaudRate" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.DataBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.Parity" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
</FieldItems>
<Buttons>
@@ -67,7 +77,15 @@ else
</EditTemplate>
</EditorItem>
<EditorItem @bind-Field="@context.Name" />
<EditorItem @bind-Field="@context.ChannelType" />
<EditorItem @bind-Field="@context.ChannelType">
<EditTemplate Context="value">
<div class="col-12 col-sm-6">
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>InvokeAsync(StateHasChanged)) />
</div>
</EditTemplate>
</EditorItem>
<EditorItem @bind-Field="@context.Enable" />
<EditorItem @bind-Field="@context.LogEnable" />
@@ -79,16 +97,17 @@ else
</EditTemplate>
</EditorItem>
<EditorItem @bind-Field="@context.RemoteUrl" />
<EditorItem @bind-Field="@context.BindUrl" />
<EditorItem @bind-Field="@context.PortName" />
<EditorItem @bind-Field="@context.BaudRate" />
<EditorItem @bind-Field="@context.DataBits" />
<EditorItem @bind-Field="@context.Parity" />
<EditorItem @bind-Field="@context.StopBits" />
<EditorItem @bind-Field="@context.DtrEnable" />
<EditorItem @bind-Field="@context.RtsEnable" />
<EditorItem @bind-Field="@context.RemoteUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession) />
<EditorItem @bind-Field="@context.BindUrl" Ignore=@(context.ChannelType!=ChannelTypeEnum.TcpClient&&context.ChannelType!=ChannelTypeEnum.UdpSession&&context.ChannelType!=ChannelTypeEnum.TcpService) />
<EditorItem @bind-Field="@context.PortName" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.BaudRate" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.DataBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.Parity" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
</FieldItems>
</EditorForm>

View File

@@ -12,6 +12,8 @@ using System.Text;
using ThingsGateway.Foundation.Extension.Generic;
using TouchSocket.Core;
namespace ThingsGateway.Foundation.Dlt645;
/// <summary>
@@ -19,6 +21,10 @@ namespace ThingsGateway.Foundation.Dlt645;
/// </summary>
public class Dlt645_2007BitConverter : ThingsGatewayBitConverter
{
public Dlt645_2007BitConverter(EndianType endianType) : base(endianType)
{
}
/// <inheritdoc/>
public override short ToInt16(byte[] buffer, int offset)
{

View File

@@ -22,8 +22,7 @@ public class Dlt645_2007Master : ProtocolBase, IDtu
/// <inheritdoc/>
public Dlt645_2007Master(IChannel channel) : base(channel)
{
ThingsGatewayBitConverter = new Dlt645_2007BitConverter();
ThingsGatewayBitConverter.EndianType = EndianType.Big;
ThingsGatewayBitConverter = new Dlt645_2007BitConverter(EndianType.Big);
RegisterByteLength = 2;
if (channel is IClientChannel client)
client.WaitHandlePool.MaxSign = ushort.MaxValue;

View File

@@ -10,7 +10,7 @@
"CacheTimeout": "CacheTimeout",
"SendDelayTime": "SendDelayTime",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"Timeout": "Timeout",
"ConnectTimeout": "ConnectTimeout",
"IsStringReverseByteWord": "IsStringReverseByteWord"

View File

@@ -10,7 +10,7 @@
"CacheTimeout": "组包缓存时间",
"SendDelayTime": "发送延时",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"Timeout": "读写超时",
"ConnectTimeout": "连接超时",
"IsStringReverseByteWord": "字符串反转"

View File

@@ -8,7 +8,7 @@
"CacheTimeout": "CacheTimeout",
"SendDelayTime": "SendDelayTime",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"Timeout": "Timeout",
"ConnectTimeout": "ConnectTimeout",
"IsStringReverseByteWord": "IsStringReverseByteWord"
@@ -27,7 +27,7 @@
"CacheTimeout": "CacheTimeout",
"SendDelayTime": "SendDelayTime",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"Timeout": "Timeout",
"ConnectTimeout": "ConnectTimeout",
"IsStringReverseByteWord": "IsStringReverseByteWord"

View File

@@ -8,7 +8,7 @@
"CacheTimeout": "组包缓存时间",
"SendDelayTime": "发送延时",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"Timeout": "读写超时",
"ConnectTimeout": "连接超时",
"IsStringReverseByteWord": "字符串反转"
@@ -27,7 +27,7 @@
"CacheTimeout": "组包缓存时间",
"SendDelayTime": "发送延时",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"Timeout": "读写超时",
"ConnectTimeout": "连接超时",
"IsStringReverseByteWord": "字符串反转"

View File

@@ -1,16 +1,16 @@
{
"ThingsGateway.Foundation.SiemensS7.SiemensS7Master": {
"SiemensS7Type": "S7 Type",
"LocalTSAP": "Local TSAP",
"Rack": "Rack Number",
"Slot": "Slot Number",
"SiemensS7Type": "SiemensS7Type",
"LocalTSAP": "LocalTSAP",
"Rack": "Rack",
"Slot": "Slot",
"CacheTimeout": "Packet Assembly Cache Time",
"SendDelayTime": "Send Delay Time",
"EndianType": "Parsing Rules",
"Timeout": "Read/Write Timeout",
"ConnectTimeout": "Connection Timeout",
"IsStringReverseByteWord": "String Byte/Word Reversal"
"CacheTimeout": "CacheTimeout",
"SendDelayTime": "SendDelayTime",
"DataFormat": "DataFormat",
"Timeout": "Timeout",
"ConnectTimeout": "ConnectTimeout",
"IsStringReverseByteWord": "IsStringReverseByteWord"
},
"ThingsGateway.Foundation.SiemensS7.SiemensS7Resource": {
@@ -41,4 +41,4 @@
"AddressError": "Register address format error {0}"
}
}
}

View File

@@ -7,7 +7,7 @@
"CacheTimeout": "组包缓存时间",
"SendDelayTime": "发送延时",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"Timeout": "读写超时",
"ConnectTimeout": "连接超时",
"IsStringReverseByteWord": "字符串反转"

View File

@@ -39,7 +39,7 @@ public class Dlt645_2007Master : CollectBase
//载入配置
_plc = new(channel)
{
EndianType = _driverPropertys.EndianType,
DataFormat = _driverPropertys.DataFormat,
DtuId = _driverPropertys.DtuId,
SendDelayTime = _driverPropertys.SendDelayTime,
CacheTimeout = _driverPropertys.CacheTimeout,

View File

@@ -59,7 +59,7 @@ public class Dlt645_2007MasterProperty : CollectPropertyBase
/// 默认解析顺序
/// </summary>
[DynamicProperty]
public EndianType EndianType { get; set; } = EndianType.Big;
public DataFormatEnum DataFormat { get; set; }
/// <summary>
/// 默认地址

View File

@@ -7,7 +7,7 @@
"DtuId": "DefaultDtuId",
"HeartbeatHexString": "HeartbeatHexString",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"IsStringReverseByteWord": "StringReverseByteWord",
"CheckClearTime": "CheckClearTime",
"Timeout": "Timeout",

View File

@@ -7,7 +7,7 @@
"DtuId": "默认DtuId",
"HeartbeatHexString": "心跳验证(HexString)",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"IsStringReverseByteWord": "字符串反转",
"CheckClearTime": "客户端连接滑动过期时间",
"Timeout": "读写超时时间",

View File

@@ -27,7 +27,7 @@
<EditorItem @bind-Field=context.CheckClearTime />
<EditorItem @bind-Field=context.HeartbeatHexString />
<EditorItem @bind-Field=context.CacheTimeout />
<EditorItem @bind-Field=context.EndianType />
<EditorItem @bind-Field=context.DataFormat />
<EditorItem @bind-Field=context.SendDelayTime />
<EditorItem @bind-Field=context.Timeout />
<EditorItem @bind-Field=context.IsStringReverseByteWord />

View File

@@ -4,7 +4,7 @@
"HeartbeatHexString": "HeartbeatHexString",
"Station": "DefaultStation",
"DtuId": "DefaultDtuId",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"IsStringReverseByteWord": "StringReverseByteWord",
"CheckClearTime": "CheckClearTime",
"Timeout": "Timeout",
@@ -24,7 +24,7 @@
"ThingsGateway.Plugin.Modbus.ModbusSlaveProperty": {
"ModbusType": "ModbusType",
"Station": "DefaultStation",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"IsStringReverseByteWord": "IsStringReverseByteWord",
"CheckClearTime": "CheckClearTime",
"DeviceRpcEnable": "DeviceRpcEnable",

View File

@@ -4,7 +4,7 @@
"HeartbeatHexString": "心跳验证(HexString)",
"Station": "默认站号",
"DtuId": "默认DtuId",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"IsStringReverseByteWord": "字符串反转",
"CheckClearTime": "客户端连接滑动过期时间",
"Timeout": "读写超时时间",
@@ -25,7 +25,7 @@
"ThingsGateway.Plugin.Modbus.ModbusSlaveProperty": {
"ModbusType": "协议类型",
"Station": "默认站号",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"IsStringReverseByteWord": "字符串反转",
"CheckClearTime": "客户端连接滑动过期时间",
"DeviceRpcEnable": "允许写入",

View File

@@ -49,7 +49,7 @@ public class ModbusMaster : CollectBase
//载入配置
_plc = new(channel)
{
EndianType = _driverPropertys.EndianType,
DataFormat = _driverPropertys.DataFormat,
DtuId = _driverPropertys.DtuId,
IsStringReverseByteWord = _driverPropertys.IsStringReverseByteWord,
SendDelayTime = _driverPropertys.SendDelayTime,

View File

@@ -45,7 +45,7 @@ public class ModbusMasterProperty : CollectPropertyBase
/// 默认解析顺序
/// </summary>
[DynamicProperty]
public EndianType EndianType { get; set; } = EndianType.Big;
public DataFormatEnum DataFormat { get; set; }
/// <summary>
/// 读写超时时间

View File

@@ -78,7 +78,7 @@ public class ModbusSlave : BusinessBase
//载入配置
_plc = new(channel)
{
EndianType = _driverPropertys.EndianType,
DataFormat = _driverPropertys.DataFormat,
IsStringReverseByteWord = _driverPropertys.IsStringReverseByteWord,
CacheTimeout = _driverPropertys.CacheTimeout,
Station = _driverPropertys.Station,

View File

@@ -33,7 +33,7 @@ public class ModbusSlaveProperty : BusinessPropertyBase
/// 默认解析顺序
/// </summary>
[DynamicProperty]
public EndianType EndianType { get; set; } = EndianType.Big;
public DataFormatEnum DataFormat { get; set; }
[DynamicProperty]
public bool IsStringReverseByteWord { get; set; }

View File

@@ -25,7 +25,7 @@
<EditorItem @bind-Field=context.CheckClearTime />
<EditorItem @bind-Field=context.HeartbeatHexString />
<EditorItem @bind-Field=context.CacheTimeout />
<EditorItem @bind-Field=context.EndianType />
<EditorItem @bind-Field=context.DataFormat />
<EditorItem @bind-Field=context.SendDelayTime />
<EditorItem @bind-Field=context.Timeout />
<EditorItem @bind-Field=context.IsStringReverseByteWord />

View File

@@ -29,7 +29,7 @@
<EditorItem @bind-Field=context.MaxClientCount />
<EditorItem @bind-Field=context.IsWriteMemory />
<EditorItem @bind-Field=context.CacheTimeout />
<EditorItem @bind-Field=context.EndianType />
<EditorItem @bind-Field=context.DataFormat />
<EditorItem @bind-Field=context.SendDelayTime />
<EditorItem @bind-Field=context.Timeout />
<EditorItem @bind-Field=context.IsStringReverseByteWord />

View File

@@ -5,7 +5,7 @@
"LocalTSAP": "LocalTSAP",
"Slot": "Slot",
"EndianType": "EndianType",
"DataFormat": "DataFormat",
"IsStringReverseByteWord": "StringReverseByteWord",
"CheckClearTime": "CheckClearTime",
"Timeout": "Timeout",

View File

@@ -5,7 +5,7 @@
"LocalTSAP": "本地TSAP",
"Slot": "槽号",
"EndianType": "解析规则",
"DataFormat": "解析规则",
"IsStringReverseByteWord": "字符串反转",
"CheckClearTime": "客户端连接滑动过期时间",
"Timeout": "读写超时时间",

View File

@@ -24,7 +24,7 @@
<EditorItem @bind-Field=context.Rack />
<EditorItem @bind-Field=context.Slot />
<EditorItem @bind-Field=context.CacheTimeout />
<EditorItem @bind-Field=context.EndianType />
<EditorItem @bind-Field=context.DataFormat />
<EditorItem @bind-Field=context.SendDelayTime />
<EditorItem @bind-Field=context.Timeout />
<EditorItem @bind-Field=context.IsStringReverseByteWord />

View File

@@ -42,7 +42,7 @@ public class SiemensS7Master : CollectBase
//载入配置
_plc = new(channel)
{
EndianType = _driverPropertys.EndianType,
DataFormat = _driverPropertys.DataFormat,
SendDelayTime = _driverPropertys.SendDelayTime,
CacheTimeout = _driverPropertys.CacheTimeout,
ConnectTimeout = _driverPropertys.ConnectTimeout,

View File

@@ -75,7 +75,7 @@ public class SiemensS7MasterProperty : CollectPropertyBase
/// 默认解析顺序
/// </summary>
[DynamicProperty]
public EndianType EndianType { get; set; } = EndianType.Big;
public DataFormatEnum DataFormat { get; set; }
public override int ConcurrentCount { get; set; } = 1;
}