feat: 添加保存值功能

This commit is contained in:
Diego
2024-09-10 10:59:58 +08:00
parent 3ca5768974
commit 59a25854ef
11 changed files with 177 additions and 6 deletions

View File

@@ -122,6 +122,14 @@ public class Variable : PrimaryIdEntity
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
public virtual bool RpcWriteEnable { get; set; } = true;
/// <summary>
/// 保存值
/// </summary>
[SugarColumn(ColumnDescription = "保存值", IsNullable = true)]
[AutoGenerateColumn(Visible = true, Filterable = true, Sortable = true)]
public virtual bool SaveValue { get; set; } = false;
/// <summary>
/// 变量额外属性Json
/// </summary>

View File

@@ -11,6 +11,8 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ThingsGateway.Gateway.Application.Extensions;
using TouchSocket.Core;
@@ -194,8 +196,48 @@ public class CollectDeviceHostedService : DeviceHostedService
{
// 如果设备已更改,则执行启动前的操作
if (isChanged)
{
try
{
//添加保存数据变量读取操作
var saveVariable = dev.VariableRunTimes.Where(a => a.Value.SaveValue).ToDictionary(a => a.Value.Id, a => a.Value);
if (saveVariable.Any())
{
var cacheDb = CacheDBUtil.GetCache(typeof(CacheDBItem<JToken>), nameof(VariableRunTime), nameof(VariableRunTime.SaveValue));
var varList = await cacheDb.DBProvider.Queryable<CacheDBItem<JToken>>().ToListAsync().ConfigureAwait(false);
for (int i = 0; i < varList.Count; i++)
{
var varValue = varList[i];
if (saveVariable.TryGetValue(varValue.Id, out var variable))
{
if (varValue.Value is JValue jValue)
{
variable.Value = jValue.Value;
}
else
{
variable.Value = varValue.Value;
}
}
}
cacheDb.SafeDispose();
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "SaveValue");
}
await OnCollectDeviceStarting().ConfigureAwait(false);
}
try
{
// 启动新的通道线程
@@ -271,6 +313,8 @@ public class CollectDeviceHostedService : DeviceHostedService
await CreatAllChannelThreadsAsync().ConfigureAwait(false);
await OnCollectDeviceStarting().ConfigureAwait(false);
}
await ReadValue().ConfigureAwait(false);
await StartAllChannelThreadsAsync().ConfigureAwait(false);
await OnCollectDeviceStarted().ConfigureAwait(false);
_ = Task.Run(() =>
@@ -290,6 +334,52 @@ public class CollectDeviceHostedService : DeviceHostedService
}
}
private async Task ReadValue()
{
try
{
//添加保存数据变量读取操作
var saveVariable = GlobalData.ReadOnlyVariables.Where(a => a.Value.SaveValue).ToDictionary(a => a.Value.Id, a => a.Value);
var cacheDb = CacheDBUtil.GetCache(typeof(CacheDBItem<JToken>), nameof(VariableRunTime), nameof(VariableRunTime.SaveValue));
cacheDb.InitDb();
{
var varList = await cacheDb.DBProvider.Queryable<CacheDBItem<JToken>>().ToListAsync().ConfigureAwait(false);
List<long> ids = new List<long>();
for (int i = 0; i < varList.Count; i++)
{
var varValue = varList[i];
var has = saveVariable.Any();
if (has && saveVariable.TryGetValue(varValue.Id, out var variable))
{
if (varValue.Value is JValue jValue)
{
variable.Value = jValue.Value;
}
else
{
variable.Value = varValue.Value;
}
}
else
{
ids.Add(varValue.Id);
}
}
if (ids.Any())
{
await cacheDb.DBProvider.Deleteable<CacheDBItem<JToken>>(ids).ExecuteCommandAsync().ConfigureAwait(false);
}
cacheDb.SafeDispose();
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "SaveValue");
}
}
/// <summary>
/// 停止
/// </summary>
@@ -305,6 +395,9 @@ public class CollectDeviceHostedService : DeviceHostedService
await BeforeRemoveAllChannelThreadAsync().ConfigureAwait(false);
//取消其他后台服务
await OnCollectDeviceStoping().ConfigureAwait(false);
await SaveValue().ConfigureAwait(false);
//停止全部采集线程
await RemoveAllChannelThreadAsync(removeDevice).ConfigureAwait(false);
//停止其他后台服务
@@ -331,6 +424,35 @@ public class CollectDeviceHostedService : DeviceHostedService
}
}
private async Task SaveValue()
{
try
{
//添加保存数据变量读取操作
var saveVariable = DriverBases.SelectMany(a => a.CurrentDevice.VariableRunTimes).Where(a => a.Value.SaveValue).Select(a =>
{
return new CacheDBItem<JToken>()
{
Id = a.Value.Id,
Value = JToken.FromObject(a.Value.Value)
};
}).ToList();
if (saveVariable.Any())
{
var cacheDb = CacheDBUtil.GetCache(typeof(CacheDBItem<JToken>), nameof(VariableRunTime), nameof(VariableRunTime.SaveValue));
await cacheDb.DBProvider.Fastest<CacheDBItem<JToken>>().PageSize(100000).BulkMergeAsync(saveVariable).ConfigureAwait(false);
cacheDb.SafeDispose();
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "SaveValue");
}
}
/// <summary>
/// 读取数据库,创建全部设备
/// </summary>

View File

@@ -355,6 +355,7 @@ public abstract class DeviceHostedService : BackgroundService
// 检查是否已请求停止,如果没有则开始每个通道线程
if (!_stoppingToken.IsCancellationRequested)
{
foreach (var item in ChannelThreads)
{
if (!_stoppingToken.IsCancellationRequested)

View File

@@ -92,6 +92,7 @@
"ReadExpressions": "ReadExpressions",
"WriteExpressions": "WriteExpressions",
"RpcWriteEnable": "RpcWriteEnable",
"SaveValue": "SaveValue",
"AlarmDelay": "AlarmDelay",
"BoolOpenAlarmEnable": "BoolOpenAlarmEnable",
@@ -337,6 +338,7 @@
"ReadExpressions": "ReadExpressions",
"WriteExpressions": "WriteExpressions",
"RpcWriteEnable": "RpcWriteEnable",
"SaveValue": "SaveValue",
"AlarmDelay": "AlarmDelay",
"BoolOpenAlarmEnable": "BoolOpenAlarmEnable",
"BoolOpenRestrainExpressions": "BoolOpenRestrainExpressions",

View File

@@ -120,6 +120,7 @@
"ReadExpressions": "读取表达式",
"WriteExpressions": "写入表达式",
"RpcWriteEnable": "远程写入",
"SaveValue": "保存值",
"AlarmDelay": "报警延时",
"BoolOpenAlarmEnable": "布尔开报警使能",
@@ -398,6 +399,7 @@
"ReadExpressions": "读取表达式",
"WriteExpressions": "写入表达式",
"RpcWriteEnable": "远程写入",
"SaveValue": "保存值",
"AlarmDelay": "报警延时",
"BoolOpenAlarmEnable": "布尔开报警使能",

View File

@@ -107,6 +107,7 @@
"ReadExpressions": "讀取表達式",
"WriteExpressions": "寫入表達式",
"RpcWriteEnable": "遠端寫入",
"SaveValue": "保存值",
"AlarmDelay": "警報延遲",
"BoolOpenAlarmEnable": "布林開警報啟用",
"BoolOpenRestrainExpressions": "布林開警報約束",
@@ -368,6 +369,7 @@
"ReadExpressions": "讀取表達式",
"WriteExpressions": "寫入表達式",
"RpcWriteEnable": "遠端寫入",
"SaveValue": "保存值",
"AlarmDelay": "警報延遲",
"BoolOpenAlarmEnable": "布林開警報啟用",
"BoolOpenRestrainExpressions": "布林開警報約束",

View File

@@ -13,6 +13,8 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System.Collections.Concurrent;
using ThingsGateway.NewLife.X;
@@ -356,9 +358,35 @@ public class ChannelThread
driverBase.AfterStop();
// 如果需要移除的是采集设备
if (IsCollectChannel)
{
try
{
//添加保存数据变量读取操作
var saveVariable = driverBase.CurrentDevice.VariableRunTimes.Where(a => a.Value.SaveValue).Select(a =>
{
return new CacheDBItem<JToken>()
{
Id = a.Value.Id,
Value = JToken.FromObject(a.Value.Value)
};
}).ToList();
if (saveVariable.Any())
{
var cacheDb = CacheDBUtil.GetCache(typeof(CacheDBItem<JToken>), nameof(VariableRunTime), nameof(VariableRunTime.SaveValue));
var varList = await cacheDb.DBProvider.Storageable(saveVariable).ExecuteCommandAsync().ConfigureAwait(false);
cacheDb.SafeDispose();
}
}
catch (Exception ex)
{
LogMessage.LogWarning(ex, "SaveValue");
}
driverBase.RemoveCollectDeviceRuntime();
}
else
@@ -501,6 +529,8 @@ public class ChannelThread
// 如果需要移除的是采集设备
if (IsCollectChannel)
{
DriverBases.RemoveCollectDeviceRuntime();
}
else

View File

@@ -155,6 +155,7 @@ public abstract class CollectBase : DriverBase
protected override void Dispose(bool disposing)
{
this.RemoveCollectDeviceRuntime();
base.Dispose(disposing);
}

View File

@@ -246,6 +246,7 @@ public abstract class DriverBase : DisposableObject
try
{
// 如果已经取消了操作,则直接返回
if (cancellationToken.IsCancellationRequested)
{

View File

@@ -62,7 +62,7 @@ public class VariableService : BaseService<Variable>, IVariableService
List<Device> newDevices = new();
List<Variable> newVariables = new();
var addressNum = 1;
var variableCount = 1000;
var variableCount = 10000;
var channelCount = Math.Max(count / variableCount, 1);
for (int i = 0; i < channelCount; i++)
{
@@ -90,8 +90,8 @@ public class VariableService : BaseService<Variable>, IVariableService
//动态插件属性默认
newDevices.Add(device);
}
if (channelCount == i + 1 && (count % 1000) != 0)
variableCount = Math.Min(count % 1000, 1000);
if (channelCount == i + 1 && (count % 10000) != 0)
variableCount = Math.Min(count % 10000, 10000);
for (int i1 = 0; i1 < variableCount; i1++)
{
addressNum++;
@@ -138,9 +138,9 @@ public class VariableService : BaseService<Variable>, IVariableService
var result = await db.UseTranAsync(async () =>
{
await db.Fastest<Channel>().PageSize(50000).BulkCopyAsync(newChannels).ConfigureAwait(false);
await db.Fastest<Device>().PageSize(50000).BulkCopyAsync(newDevices).ConfigureAwait(false);
await db.Fastest<Variable>().PageSize(50000).BulkCopyAsync(newVariables).ConfigureAwait(false);
await db.Fastest<Channel>().PageSize(100000).BulkCopyAsync(newChannels).ConfigureAwait(false);
await db.Fastest<Device>().PageSize(100000).BulkCopyAsync(newDevices).ConfigureAwait(false);
await db.Fastest<Variable>().PageSize(100000).BulkCopyAsync(newVariables).ConfigureAwait(false);
}).ConfigureAwait(false);
if (result.IsSuccess)//如果成功了
{

View File

@@ -26,6 +26,7 @@
<EditorItem @bind-Field="@context.ProtectType" />
<EditorItem @bind-Field="@context.Enable" />
<EditorItem @bind-Field="@context.RpcWriteEnable" />
<EditorItem @bind-Field="@context.SaveValue" />
<EditorItem @bind-Field="@context.Description">
<EditTemplate Context="value">
@@ -141,6 +142,7 @@ else
<EditorItem @bind-Field="@context.ProtectType" />
<EditorItem @bind-Field="@context.Enable" />
<EditorItem @bind-Field="@context.RpcWriteEnable" />
<EditorItem @bind-Field="@context.SaveValue" />
<EditorItem @bind-Field="@context.Description">
<EditTemplate Context="value">