feat: 添加保存值功能
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -355,6 +355,7 @@ public abstract class DeviceHostedService : BackgroundService
|
||||
// 检查是否已请求停止,如果没有则开始每个通道线程
|
||||
if (!_stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
|
||||
foreach (var item in ChannelThreads)
|
||||
{
|
||||
if (!_stoppingToken.IsCancellationRequested)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
"ReadExpressions": "读取表达式",
|
||||
"WriteExpressions": "写入表达式",
|
||||
"RpcWriteEnable": "远程写入",
|
||||
"SaveValue": "保存值",
|
||||
|
||||
"AlarmDelay": "报警延时",
|
||||
"BoolOpenAlarmEnable": "布尔开报警使能",
|
||||
@@ -398,6 +399,7 @@
|
||||
"ReadExpressions": "读取表达式",
|
||||
"WriteExpressions": "写入表达式",
|
||||
"RpcWriteEnable": "远程写入",
|
||||
"SaveValue": "保存值",
|
||||
|
||||
"AlarmDelay": "报警延时",
|
||||
"BoolOpenAlarmEnable": "布尔开报警使能",
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
"ReadExpressions": "讀取表達式",
|
||||
"WriteExpressions": "寫入表達式",
|
||||
"RpcWriteEnable": "遠端寫入",
|
||||
"SaveValue": "保存值",
|
||||
"AlarmDelay": "警報延遲",
|
||||
"BoolOpenAlarmEnable": "布林開警報啟用",
|
||||
"BoolOpenRestrainExpressions": "布林開警報約束",
|
||||
@@ -368,6 +369,7 @@
|
||||
"ReadExpressions": "讀取表達式",
|
||||
"WriteExpressions": "寫入表達式",
|
||||
"RpcWriteEnable": "遠端寫入",
|
||||
"SaveValue": "保存值",
|
||||
"AlarmDelay": "警報延遲",
|
||||
"BoolOpenAlarmEnable": "布林開警報啟用",
|
||||
"BoolOpenRestrainExpressions": "布林開警報約束",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -155,6 +155,7 @@ public abstract class CollectBase : DriverBase
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
|
||||
this.RemoveCollectDeviceRuntime();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
@@ -246,6 +246,7 @@ public abstract class DriverBase : DisposableObject
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// 如果已经取消了操作,则直接返回
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
|
||||
@@ -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)//如果成功了
|
||||
{
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user