mirror of
				https://gitee.com/ThingsGateway/ThingsGateway.git
				synced 2025-11-04 01:23:58 +08:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			10.11.26.0
			...
			10.11.27.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8404e20c5e | 
@@ -24,13 +24,13 @@
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="SqlSugarCore.Dm" Version="8.8.2" />
 | 
			
		||||
		<PackageReference Include="SqlSugarCore.Kdbndp" Version="9.3.7.821" />
 | 
			
		||||
		<PackageReference Include="SqlSugarCore.Kdbndp" Version="9.3.7.905" />
 | 
			
		||||
		<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.20" />
 | 
			
		||||
		<!--<PackageReference Include="Microsoft.Data.Sqlite" Version="$(NET9Version)" />-->
 | 
			
		||||
		<PackageReference Include="MySqlConnector" Version="2.4.0" />
 | 
			
		||||
		<PackageReference Include="Npgsql" Version="9.0.3" />
 | 
			
		||||
		<PackageReference Include="CsvHelper" Version="33.1.0" />
 | 
			
		||||
		<PackageReference Include="TDengine.Connector" Version="3.1.8" />
 | 
			
		||||
		<PackageReference Include="TDengine.Connector" Version="3.1.9" />
 | 
			
		||||
		<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.9.1" />
 | 
			
		||||
		<PackageReference Include="Oscar.Data.SqlClient" Version="4.2.23" />
 | 
			
		||||
		<PackageReference Include="System.Data.Common" Version="4.3.0" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<Project>
 | 
			
		||||
 | 
			
		||||
	<PropertyGroup>
 | 
			
		||||
		<PluginVersion>10.11.26</PluginVersion>
 | 
			
		||||
		<ProPluginVersion>10.11.26</ProPluginVersion>
 | 
			
		||||
		<DefaultVersion>10.11.26</DefaultVersion>
 | 
			
		||||
		<PluginVersion>10.11.27</PluginVersion>
 | 
			
		||||
		<ProPluginVersion>10.11.27</ProPluginVersion>
 | 
			
		||||
		<DefaultVersion>10.11.27</DefaultVersion>
 | 
			
		||||
		<AuthenticationVersion>10.11.3</AuthenticationVersion>
 | 
			
		||||
		<SourceGeneratorVersion>10.11.3</SourceGeneratorVersion>
 | 
			
		||||
		<NET8Version>8.0.19</NET8Version>
 | 
			
		||||
 
 | 
			
		||||
@@ -49,12 +49,11 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
 | 
			
		||||
        this.ThrowIfDisposed();
 | 
			
		||||
        this.ThrowIfClientNotConnected();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (!await this.OnTcpSending(memory).ConfigureAwait(false)) return;
 | 
			
		||||
 | 
			
		||||
        var transport = this.Transport;
 | 
			
		||||
        var adapter = this.DataHandlingAdapter;
 | 
			
		||||
        var locker = transport.SemaphoreSlimForWriter;
 | 
			
		||||
        var locker = transport.WriteLocker;
 | 
			
		||||
 | 
			
		||||
        await locker.WaitAsync(token).ConfigureAwait(false);
 | 
			
		||||
        try
 | 
			
		||||
@@ -62,7 +61,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
 | 
			
		||||
            // 如果数据处理适配器未设置,则使用默认发送方式。
 | 
			
		||||
            if (adapter == null)
 | 
			
		||||
            {
 | 
			
		||||
                await transport.Output.WriteAsync(memory, token).ConfigureAwait(false);
 | 
			
		||||
                await transport.Writer.WriteAsync(memory, token).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
@@ -70,7 +69,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
 | 
			
		||||
                var ddpSend = new DDPSend(memory, Id, true);
 | 
			
		||||
                ddpSend.Build(ref byteBlock);
 | 
			
		||||
                var newMemory = byteBlock.Memory;
 | 
			
		||||
                var writer = new PipeBytesWriter(transport.Output);
 | 
			
		||||
                var writer = new PipeBytesWriter(transport.Writer);
 | 
			
		||||
                adapter.SendInput(ref writer, in newMemory);
 | 
			
		||||
                await writer.FlushAsync(token).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
@@ -100,7 +99,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
 | 
			
		||||
 | 
			
		||||
        var transport = this.Transport;
 | 
			
		||||
        var adapter = this.DataHandlingAdapter;
 | 
			
		||||
        var locker = transport.SemaphoreSlimForWriter;
 | 
			
		||||
        var locker = transport.WriteLocker;
 | 
			
		||||
 | 
			
		||||
        await locker.WaitAsync(token).ConfigureAwait(false);
 | 
			
		||||
        try
 | 
			
		||||
@@ -113,7 +112,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
 | 
			
		||||
            requestInfoBuilder.Build(ref byteBlock);
 | 
			
		||||
            var ddpSend = new DDPSend(byteBlock.Memory, Id, true);
 | 
			
		||||
 | 
			
		||||
            var writer = new PipeBytesWriter(transport.Output);
 | 
			
		||||
            var writer = new PipeBytesWriter(transport.Writer);
 | 
			
		||||
            adapter.SendInput(ref writer, ddpSend);
 | 
			
		||||
            await writer.FlushAsync(token).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,26 @@ public static class PluginUtil
 | 
			
		||||
 | 
			
		||||
            if (channelOptions.ChannelType == ChannelTypeEnum.TcpClient)
 | 
			
		||||
            {
 | 
			
		||||
                action += a => a.UseReconnection<IClientChannel>();
 | 
			
		||||
                action += a => a.UseReconnection<IClientChannel>().SetActionForCheck((channel, failCount) =>
 | 
			
		||||
                {
 | 
			
		||||
                    if (channel.Online)
 | 
			
		||||
                    {
 | 
			
		||||
                        return Task.FromResult(ConnectionCheckResult.Alive);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        if (failCount > 3)
 | 
			
		||||
                        {
 | 
			
		||||
                            return Task.FromResult(ConnectionCheckResult.Dead);
 | 
			
		||||
                        }
 | 
			
		||||
                        return Task.FromResult(ConnectionCheckResult.Skip);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                })
 | 
			
		||||
                .SetPollingTick(TimeSpan.FromSeconds(5)
 | 
			
		||||
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            return action;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,8 @@
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="$(NET9Version)" />
 | 
			
		||||
		<PackageReference Include="TouchSocket" Version="4.0.0-beta.13" />
 | 
			
		||||
		<PackageReference Include="TouchSocket.SerialPorts" Version="4.0.0-beta.13" />
 | 
			
		||||
		<PackageReference Include="TouchSocket" Version="4.0.0-beta.20" />
 | 
			
		||||
		<PackageReference Include="TouchSocket.SerialPorts" Version="4.0.0-beta.20" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
 
 | 
			
		||||
@@ -214,6 +214,17 @@ public class ControlController : ControllerBase, IRpcServer
 | 
			
		||||
        return GlobalData.VariableRuntimeService.InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 增加测试Dtu数据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpPost("insertTestDtuData")]
 | 
			
		||||
    [DisplayName("增加测试Dtu数据")]
 | 
			
		||||
    [TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
 | 
			
		||||
    public Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart = true)
 | 
			
		||||
    {
 | 
			
		||||
        return GlobalData.VariableRuntimeService.InsertTestDtuDataAsync(testDeviceCount, slaveUrl, restart);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 确认实时报警
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -338,6 +338,14 @@ public partial class ManagementController : ControllerBase, IRpcServer
 | 
			
		||||
    public Task InsertTestDataAsync([FromBody] InsertTestDataInput input) =>
 | 
			
		||||
        App.GetService<IVariablePageService>().InsertTestDataAsync(input.TestVariableCount, input.TestDeviceCount, input.SlaveUrl, input.BusinessEnable, input.Restart);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [HttpPost]
 | 
			
		||||
    [TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
 | 
			
		||||
    public Task InsertTestDtuDataAsync([FromBody] InsertTestDtuDataInput input) =>
 | 
			
		||||
        App.GetService<IVariablePageService>().InsertTestDtuDataAsync(input.TestDeviceCount, input.SlaveUrl, input.Restart);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [HttpPost]
 | 
			
		||||
    [TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
 | 
			
		||||
    public Task<bool> IsRedundantDeviceAsync(long id) =>
 | 
			
		||||
@@ -628,7 +636,12 @@ public class InsertTestDataInput
 | 
			
		||||
    public bool BusinessEnable { get; set; }
 | 
			
		||||
    public bool Restart { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class InsertTestDtuDataInput
 | 
			
		||||
{
 | 
			
		||||
    public int TestDeviceCount { get; set; }
 | 
			
		||||
    public string SlaveUrl { get; set; }
 | 
			
		||||
    public bool Restart { get; set; }
 | 
			
		||||
}
 | 
			
		||||
public class LastLogDataInput
 | 
			
		||||
{
 | 
			
		||||
    public string File { get; set; }
 | 
			
		||||
 
 | 
			
		||||
@@ -221,7 +221,8 @@ public interface IManagementRpcServer : IRpcServer
 | 
			
		||||
 | 
			
		||||
    [DmtpRpc]
 | 
			
		||||
    Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart);
 | 
			
		||||
 | 
			
		||||
    [DmtpRpc]
 | 
			
		||||
    Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart);
 | 
			
		||||
    [DmtpRpc]
 | 
			
		||||
    Task<bool> IsRedundantDeviceAsync(long id);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -179,6 +179,10 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
 | 
			
		||||
    public Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart) =>
 | 
			
		||||
        App.GetService<IVariablePageService>().InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart);
 | 
			
		||||
 | 
			
		||||
    public Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart) =>
 | 
			
		||||
        App.GetService<IVariablePageService>().InsertTestDtuDataAsync(testDeviceCount, slaveUrl, restart);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public Task<bool> IsRedundantDeviceAsync(long id) =>
 | 
			
		||||
        App.GetService<IDevicePageService>().IsRedundantDeviceAsync(id);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,7 @@ public partial class ManagementTask : AsyncDisposableObject
 | 
			
		||||
                   .SetTick(TimeSpan.FromMilliseconds(_managementOptions.HeartbeatInterval))
 | 
			
		||||
                   .SetMaxFailCount(3);
 | 
			
		||||
 | 
			
		||||
                   a.AddDmtpHandshakedPlugin(async () =>
 | 
			
		||||
                   a.AddDmtpCreatedChannelPlugin(async () =>
 | 
			
		||||
                   {
 | 
			
		||||
                       try
 | 
			
		||||
                       {
 | 
			
		||||
 
 | 
			
		||||
@@ -35,5 +35,6 @@ namespace ThingsGateway.Gateway.Application
 | 
			
		||||
        Task<OperResult<object>> OnWriteVariableAsync(long id, string writeData);
 | 
			
		||||
        Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableAsync(IBrowserFile a, bool restart);
 | 
			
		||||
        Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableFileAsync(string filePath, bool restart);
 | 
			
		||||
        Task InsertTestDtuDataAsync(int deviceCount, string slaveUrl, bool restart);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -111,4 +111,5 @@ internal interface IVariableService
 | 
			
		||||
    Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string filePath);
 | 
			
		||||
    Task<HashSet<long>> ImportVariableAsync(List<Variable> upData, List<Variable> insertData);
 | 
			
		||||
    Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile);
 | 
			
		||||
    Task<(List<Channel>, List<Device>, List<Variable>)> InsertTestDtuDataAsync(int deviceCount, string slaveUrl = "127.0.0.1:502");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -423,6 +423,45 @@ public class VariableRuntimeService : IVariableRuntimeService
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async Task InsertTestDtuDataAsync(int deviceCount, string slaveUrl, bool restart)
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // await WaitLock.WaitAsync().ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            var datas = await GlobalData.VariableService.InsertTestDtuDataAsync(deviceCount, slaveUrl).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
                var newChannelRuntimes = datas.Item1.AdaptListChannelRuntime();
 | 
			
		||||
 | 
			
		||||
                //批量修改之后,需要重新加载通道
 | 
			
		||||
                RuntimeServiceHelper.Init(newChannelRuntimes);
 | 
			
		||||
 | 
			
		||||
                {
 | 
			
		||||
                    var newDeviceRuntimes = datas.Item2.AdaptListDeviceRuntime();
 | 
			
		||||
 | 
			
		||||
                    RuntimeServiceHelper.Init(newDeviceRuntimes);
 | 
			
		||||
                }
 | 
			
		||||
                {
 | 
			
		||||
                    var newVariableRuntimes = datas.Item3.AdaptListVariableRuntime();
 | 
			
		||||
                    RuntimeServiceHelper.Init(newVariableRuntimes);
 | 
			
		||||
                }
 | 
			
		||||
                //根据条件重启通道线程
 | 
			
		||||
 | 
			
		||||
                if (restart)
 | 
			
		||||
                {
 | 
			
		||||
                    await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                    await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            //WaitLock.Release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
 | 
			
		||||
    {
 | 
			
		||||
        return GlobalData.VariableService.PreviewAsync(browserFile);
 | 
			
		||||
 
 | 
			
		||||
@@ -235,6 +235,144 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
 | 
			
		||||
        return (newChannels, newDevices, newVariables);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public async Task<(List<Channel>, List<Device>, List<Variable>)> InsertTestDtuDataAsync(int deviceCount, string slaveUrl = "127.0.0.1:502")
 | 
			
		||||
    {
 | 
			
		||||
        if (slaveUrl.IsNullOrWhiteSpace()) slaveUrl = "127.0.0.1:502";
 | 
			
		||||
        List<Channel> newChannels = new();
 | 
			
		||||
        List<Device> newDevices = new();
 | 
			
		||||
        List<Variable> newVariables = new();
 | 
			
		||||
 | 
			
		||||
        ManageHelper.CheckChannelCount(deviceCount);
 | 
			
		||||
        ManageHelper.CheckDeviceCount(deviceCount);
 | 
			
		||||
        ManageHelper.CheckVariableCount(deviceCount);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //DTU
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < deviceCount; i++)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            Channel serviceChannel = new Channel();
 | 
			
		||||
            Device serviceDevice = new Device();
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
                var id = CommonUtils.GetSingleId();
 | 
			
		||||
                var name = $"modbusSlaveChannel{id}";
 | 
			
		||||
                serviceChannel.ChannelType = ChannelTypeEnum.TcpClient;
 | 
			
		||||
                serviceChannel.Name = name;
 | 
			
		||||
                serviceChannel.Enable = true;
 | 
			
		||||
                serviceChannel.Id = id;
 | 
			
		||||
                serviceChannel.CreateUserId = UserManager.UserId;
 | 
			
		||||
                serviceChannel.CreateOrgId = UserManager.OrgId;
 | 
			
		||||
                serviceChannel.RemoteUrl = "127.0.0.1:502";
 | 
			
		||||
                serviceChannel.DtuId = name;
 | 
			
		||||
                serviceChannel.Heartbeat = "ThingsGateway.Plugin.Modbus";
 | 
			
		||||
                serviceChannel.PluginName = "ThingsGateway.Plugin.Modbus.ModbusSlave";
 | 
			
		||||
                newChannels.Add(serviceChannel);
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
                var id = CommonUtils.GetSingleId();
 | 
			
		||||
                var name = $"modbusSlaveDevice{id}";
 | 
			
		||||
                serviceDevice.Name = name;
 | 
			
		||||
                serviceDevice.Id = id;
 | 
			
		||||
                serviceDevice.CreateUserId = UserManager.UserId;
 | 
			
		||||
                serviceDevice.CreateOrgId = UserManager.OrgId;
 | 
			
		||||
                serviceDevice.ChannelId = serviceChannel.Id;
 | 
			
		||||
                serviceDevice.IntervalTime = "1000";
 | 
			
		||||
                newDevices.Add(serviceDevice);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //SERVICE
 | 
			
		||||
        var dtuids = newChannels.Select(a => a.Name).ToList();
 | 
			
		||||
        Channel channel = new Channel();
 | 
			
		||||
        {
 | 
			
		||||
            var id = CommonUtils.GetSingleId();
 | 
			
		||||
            var name = $"modbusChannel{id}";
 | 
			
		||||
            channel.ChannelType = ChannelTypeEnum.TcpService;
 | 
			
		||||
            channel.Name = name;
 | 
			
		||||
            channel.Id = id;
 | 
			
		||||
            channel.CreateUserId = UserManager.UserId;
 | 
			
		||||
            channel.CreateOrgId = UserManager.OrgId;
 | 
			
		||||
            channel.BindUrl = slaveUrl;
 | 
			
		||||
            channel.Heartbeat = "ThingsGateway.Plugin.Modbus";
 | 
			
		||||
            channel.PluginName = "ThingsGateway.Plugin.Modbus.ModbusMaster";
 | 
			
		||||
            //动态插件属性默认
 | 
			
		||||
            newChannels.Add(channel);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach (var item in dtuids)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            Device device = new Device();
 | 
			
		||||
            {
 | 
			
		||||
                var id = CommonUtils.GetSingleId();
 | 
			
		||||
                var name = $"modbusDevice{id}";
 | 
			
		||||
                device.Name = name;
 | 
			
		||||
                device.Id = id;
 | 
			
		||||
                device.ChannelId = channel.Id;
 | 
			
		||||
                device.CreateUserId = UserManager.UserId;
 | 
			
		||||
                device.CreateOrgId = UserManager.OrgId;
 | 
			
		||||
                device.IntervalTime = "1000";
 | 
			
		||||
                device.DevicePropertys = new Dictionary<string, string>()
 | 
			
		||||
                {
 | 
			
		||||
                    {
 | 
			
		||||
                        nameof(CollectFoundationDtuPackPropertyBase.DtuId),item
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                //动态插件属性默认
 | 
			
		||||
                newDevices.Add(device);
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
                var address = $"400001";
 | 
			
		||||
                var id = CommonUtils.GetSingleId();
 | 
			
		||||
                var name = $"modbus{address}";
 | 
			
		||||
                Variable variable = new Variable();
 | 
			
		||||
                variable.DataType = DataTypeEnum.Int16;
 | 
			
		||||
                variable.Name = name;
 | 
			
		||||
                variable.Id = id;
 | 
			
		||||
                variable.CreateOrgId = UserManager.OrgId;
 | 
			
		||||
                variable.CreateUserId = UserManager.UserId;
 | 
			
		||||
                variable.DeviceId = device.Id;
 | 
			
		||||
                variable.RegisterAddress = address;
 | 
			
		||||
                newVariables.Add(variable);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        using var db = GetDB();
 | 
			
		||||
 | 
			
		||||
        var result = await db.UseTranAsync(async () =>
 | 
			
		||||
        {
 | 
			
		||||
            if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory < 2 * 1024 * 1024 || WebEnableVariable.WebEnable == false)
 | 
			
		||||
            {
 | 
			
		||||
                await db.BulkCopyAsync(newChannels, 10000).ConfigureAwait(false);
 | 
			
		||||
                await db.BulkCopyAsync(newDevices, 10000).ConfigureAwait(false);
 | 
			
		||||
                await db.BulkCopyAsync(newVariables, 10000).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await db.BulkCopyAsync(newChannels, 200000).ConfigureAwait(false);
 | 
			
		||||
                await db.BulkCopyAsync(newDevices, 200000).ConfigureAwait(false);
 | 
			
		||||
                await db.BulkCopyAsync(newVariables, 200000).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }).ConfigureAwait(false);
 | 
			
		||||
        if (result.IsSuccess)//如果成功了
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw new(result.ErrorMessage, result.ErrorException);
 | 
			
		||||
        }
 | 
			
		||||
        return (newChannels, newDevices, newVariables);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    #endregion 测试
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,9 @@
 | 
			
		||||
		<PackageReference Include="Riok.Mapperly" Version="4.2.1" ExcludeAssets="runtime" PrivateAssets="all" />
 | 
			
		||||
		<PackageReference Include="Rougamo.Fody" Version="5.0.1" />
 | 
			
		||||
		<PackageReference Include="System.Linq.Async" Version="6.0.3" />
 | 
			
		||||
		<PackageReference Include="TouchSocket.Dmtp" Version="4.0.0-beta.13" />
 | 
			
		||||
		<!--<PackageReference Include="TouchSocket.WebApi.Swagger" Version="4.0.0-beta.13" />-->
 | 
			
		||||
		<PackageReference Include="TouchSocket.WebApi" Version="4.0.0-beta.13" />
 | 
			
		||||
		<PackageReference Include="TouchSocket.Dmtp" Version="4.0.0-beta.20" />
 | 
			
		||||
		<!--<PackageReference Include="TouchSocket.WebApi.Swagger" Version="4.0.0-beta.20" />-->
 | 
			
		||||
		<PackageReference Include="TouchSocket.WebApi" Version="4.0.0-beta.20" />
 | 
			
		||||
		<PackageReference Include="ThingsGateway.Authentication" Version="$(AuthenticationVersion)" />
 | 
			
		||||
		<!--<ProjectReference Include="..\..\PluginPro\ThingsGateway.Authentication\ThingsGateway.Authentication.csproj" />-->
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -243,6 +243,7 @@
 | 
			
		||||
    "BusinessEnable": "BusinessEnable",
 | 
			
		||||
    "SlaveUrl": "SlaveUrl",
 | 
			
		||||
    "Test": "Addition of test variables",
 | 
			
		||||
    "TestDtu": "Addition of test dtu variables",
 | 
			
		||||
    "TestDeviceCount": "TestDeviceCount",
 | 
			
		||||
    "TestVariableCount": "TestVariableCount",
 | 
			
		||||
    "WriteValue": "WriteValue",
 | 
			
		||||
 
 | 
			
		||||
@@ -243,6 +243,7 @@
 | 
			
		||||
    "BusinessEnable": "添加业务设备",
 | 
			
		||||
    "SlaveUrl": "服务端Url",
 | 
			
		||||
    "Test": "一键添加测试变量",
 | 
			
		||||
    "TestDtu": "一键添加Dtu测试变量",
 | 
			
		||||
    "TestDeviceCount": "采集设备数量",
 | 
			
		||||
    "TestVariableCount": "变量数量",
 | 
			
		||||
    "WriteValue": "写入值",
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,7 @@
 | 
			
		||||
        @if (WebsiteOption.Value.Demo || App.HostEnvironment.IsDevelopment())
 | 
			
		||||
        {
 | 
			
		||||
            <PopConfirmButton Color=Color.Warning Text="@Localizer["Test"]" IsKeepDisabled=@(!AuthorizeButton(AdminOperConst.Add))
 | 
			
		||||
                              IsAsync OnConfirm=@(InsertTestDataAsync)>
 | 
			
		||||
                              IsAsync OnConfirm=@(InsertTestDataAsync) class="me-1">
 | 
			
		||||
 | 
			
		||||
                <BodyTemplate>
 | 
			
		||||
                    <BootstrapInput @bind-Value=TestVariableCount ShowLabel="true" ShowLabelTooltip="true" />
 | 
			
		||||
@@ -136,6 +136,16 @@
 | 
			
		||||
                </BodyTemplate>
 | 
			
		||||
 | 
			
		||||
            </PopConfirmButton>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <PopConfirmButton Color=Color.Warning Text="@Localizer["TestDtu"]" IsKeepDisabled=@(!AuthorizeButton(AdminOperConst.Add))
 | 
			
		||||
                              IsAsync OnConfirm=@(InsertTestDtuDataAsync)>
 | 
			
		||||
 | 
			
		||||
                <BodyTemplate>
 | 
			
		||||
                    <BootstrapInput @bind-Value=TestDeviceCount ShowLabel="true" ShowLabelTooltip="true" />
 | 
			
		||||
                </BodyTemplate>
 | 
			
		||||
 | 
			
		||||
            </PopConfirmButton>
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </TableToolbarTemplate>
 | 
			
		||||
 
 | 
			
		||||
@@ -481,6 +481,32 @@ finally
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private async Task InsertTestDtuDataAsync()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                await Task.Run(() => VariablePageService.InsertTestDtuDataAsync(TestDeviceCount, SlaveUrl, AutoRestartThread));
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                await InvokeAsync(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await ToastService.Default();
 | 
			
		||||
                    await table.QueryAsync();
 | 
			
		||||
                    StateHasChanged();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            await InvokeAsync(async () => await ToastService.Warn(ex));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [Parameter]
 | 
			
		||||
    public bool AutoRestartThread { get; set; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
 | 
			
		||||
using System.Buffers;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
using TouchSocket.Sockets;
 | 
			
		||||
 | 
			
		||||
@@ -184,10 +185,28 @@ public class ModbusSlave : DeviceBase, IModbusAddress
 | 
			
		||||
    /// <inheritdoc/>
 | 
			
		||||
    private void Init(ModbusRequest mAddress)
 | 
			
		||||
    {
 | 
			
		||||
        //自动扩容
 | 
			
		||||
        ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a =>
 | 
			
		||||
        {
 | 
			
		||||
            var bytes = new ByteBlock(ushort.MaxValue * 2);
 | 
			
		||||
            bytes.SetLength(ushort.MaxValue * 2);
 | 
			
		||||
            var bytes = new ByteBlock(256,
 | 
			
		||||
            (c) =>
 | 
			
		||||
            {
 | 
			
		||||
                var data= ArrayPool<byte>.Shared.Rent(c);
 | 
			
		||||
                for (int i = 0; i < data.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    data[i] = 0;
 | 
			
		||||
                }
 | 
			
		||||
                return data;
 | 
			
		||||
            },
 | 
			
		||||
            (m) =>
 | 
			
		||||
            {
 | 
			
		||||
                if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
 | 
			
		||||
                {
 | 
			
		||||
                    ArrayPool<byte>.Shared.Return(result.Array);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            );
 | 
			
		||||
            bytes.SetLength(256);
 | 
			
		||||
            for (int i = 0; i < bytes.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                bytes.WriteByte(0);
 | 
			
		||||
@@ -197,8 +216,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
 | 
			
		||||
        });
 | 
			
		||||
        ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a =>
 | 
			
		||||
        {
 | 
			
		||||
            var bytes = new ByteBlock(ushort.MaxValue * 2);
 | 
			
		||||
            bytes.SetLength(ushort.MaxValue * 2);
 | 
			
		||||
            var bytes = new ByteBlock(256,
 | 
			
		||||
            (c) =>
 | 
			
		||||
            {
 | 
			
		||||
                var data = ArrayPool<byte>.Shared.Rent(c);
 | 
			
		||||
                for (int i = 0; i < data.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    data[i] = 0;
 | 
			
		||||
                }
 | 
			
		||||
                return data;
 | 
			
		||||
            },
 | 
			
		||||
            (m) =>
 | 
			
		||||
            {
 | 
			
		||||
                if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
 | 
			
		||||
                {
 | 
			
		||||
                    ArrayPool<byte>.Shared.Return(result.Array);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            );
 | 
			
		||||
            bytes.SetLength(256);
 | 
			
		||||
            for (int i = 0; i < bytes.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                bytes.WriteByte(0);
 | 
			
		||||
@@ -208,8 +244,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
 | 
			
		||||
        });
 | 
			
		||||
        ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a =>
 | 
			
		||||
        {
 | 
			
		||||
            var bytes = new ByteBlock(ushort.MaxValue * 2);
 | 
			
		||||
            bytes.SetLength(ushort.MaxValue * 2);
 | 
			
		||||
            var bytes = new ByteBlock(256,
 | 
			
		||||
            (c) =>
 | 
			
		||||
            {
 | 
			
		||||
                var data = ArrayPool<byte>.Shared.Rent(c);
 | 
			
		||||
                for (int i = 0; i < data.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    data[i] = 0;
 | 
			
		||||
                }
 | 
			
		||||
                return data;
 | 
			
		||||
            },
 | 
			
		||||
            (m) =>
 | 
			
		||||
            {
 | 
			
		||||
                if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
 | 
			
		||||
                {
 | 
			
		||||
                    ArrayPool<byte>.Shared.Return(result.Array);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            );
 | 
			
		||||
            bytes.SetLength(256);
 | 
			
		||||
            for (int i = 0; i < bytes.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                bytes.WriteByte(0);
 | 
			
		||||
@@ -219,8 +272,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
 | 
			
		||||
        });
 | 
			
		||||
        ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a =>
 | 
			
		||||
        {
 | 
			
		||||
            var bytes = new ByteBlock(ushort.MaxValue * 2);
 | 
			
		||||
            bytes.SetLength(ushort.MaxValue * 2);
 | 
			
		||||
            var bytes = new ByteBlock(256,
 | 
			
		||||
            (c) =>
 | 
			
		||||
            {
 | 
			
		||||
                var data = ArrayPool<byte>.Shared.Rent(c);
 | 
			
		||||
                for (int i = 0; i < data.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    data[i] = 0;
 | 
			
		||||
                }
 | 
			
		||||
                return data;
 | 
			
		||||
            },
 | 
			
		||||
            (m) =>
 | 
			
		||||
            {
 | 
			
		||||
                if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
 | 
			
		||||
                {
 | 
			
		||||
                    ArrayPool<byte>.Shared.Return(result.Array);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            );
 | 
			
		||||
            bytes.SetLength(256);
 | 
			
		||||
            for (int i = 0; i < bytes.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                bytes.WriteByte(0);
 | 
			
		||||
@@ -278,16 +348,20 @@ public class ModbusSlave : DeviceBase, IModbusAddress
 | 
			
		||||
                    switch (f)
 | 
			
		||||
                    {
 | 
			
		||||
                        case 1:
 | 
			
		||||
                            return OperResult.CreateSuccessResult(ModbusServer01ByteBlock.Memory.Slice(mAddress.StartAddress, len));
 | 
			
		||||
                            ModbusServer01ByteBlock.Position = mAddress.StartAddress;
 | 
			
		||||
                            return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer01ByteBlock.GetMemory(len).Slice(0, len));
 | 
			
		||||
 | 
			
		||||
                        case 2:
 | 
			
		||||
                            return OperResult.CreateSuccessResult(ModbusServer02ByteBlock.Memory.Slice(mAddress.StartAddress, len));
 | 
			
		||||
                            ModbusServer02ByteBlock.Position = mAddress.StartAddress;
 | 
			
		||||
                            return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer02ByteBlock.GetMemory(len).Slice(0, len));
 | 
			
		||||
 | 
			
		||||
                        case 3:
 | 
			
		||||
                            return OperResult.CreateSuccessResult(ModbusServer03ByteBlock.Memory.Slice(mAddress.StartAddress * RegisterByteLength, len));
 | 
			
		||||
                            ModbusServer03ByteBlock.Position = mAddress.StartAddress * RegisterByteLength;
 | 
			
		||||
                            return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer03ByteBlock.GetMemory(len).Slice(0, len));
 | 
			
		||||
 | 
			
		||||
                        case 4:
 | 
			
		||||
                            return OperResult.CreateSuccessResult(ModbusServer04ByteBlock.Memory.Slice(mAddress.StartAddress * RegisterByteLength, len));
 | 
			
		||||
                            ModbusServer04ByteBlock.Position = mAddress.StartAddress * RegisterByteLength;
 | 
			
		||||
                            return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer04ByteBlock.GetMemory(len).Slice(0, len));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user