迁移导入变量功能到驱动调试内

This commit is contained in:
2248356998 qq.com
2023-06-08 15:11:58 +08:00
parent 17daad8f89
commit e8d8b0d41d
22 changed files with 245 additions and 179 deletions

View File

@@ -124,12 +124,12 @@ public class OPCDAClient : DisposableObject
}
public OperResult<List<BrowseElement>> GetBrowse(string itemId = null)
{
return this.m_server.Browse(itemId);
return this.m_server?.Browse(itemId);
}
public OperResult<ServerStatus> GetStatus()
{
return this.m_server.GetServerStatus();
return this.m_server?.GetServerStatus();
}
public void Init(OPCNode node = null)

View File

@@ -13,7 +13,7 @@
namespace ThingsGateway.Foundation.Adapter.OPCUA;
public class OPCNode
{
public string OPCUrl { get; set; } = "opc.tcp://127.0.0.1:49320";
public string OPCURL { get; set; } = "opc.tcp://127.0.0.1:49320";
public int UpdateRate { get; set; } = 1000;
public int GroupSize { get; set; } = 500;
public float DeadBand { get; set; } = 0;
@@ -22,6 +22,6 @@ public class OPCNode
public override string ToString()
{
return OPCUrl;
return OPCURL;
}
}

View File

@@ -107,27 +107,27 @@ public class OPCUAClient : DisposableObject
TrustedIssuerCertificates = new CertificateTrustList
{
StoreType = CertificateStoreType.Directory,
StorePath = AppContext.BaseDirectory+ @"OPCUAClientCertificate\pki\trustedIssuer",
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\trustedIssuer",
},
TrustedPeerCertificates = new CertificateTrustList
{
StoreType = CertificateStoreType.Directory,
StorePath = AppContext.BaseDirectory+ @"OPCUAClientCertificate\pki\trustedPeer",
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\trustedPeer",
},
RejectedCertificateStore = new CertificateStoreIdentifier
{
StoreType = CertificateStoreType.Directory,
StorePath = AppContext.BaseDirectory+ @"OPCUAClientCertificate\pki\rejected",
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\rejected",
},
UserIssuerCertificates = new CertificateTrustList
{
StoreType = CertificateStoreType.Directory,
StorePath = AppContext.BaseDirectory+ @"OPCUAClientCertificate\pki\issuerUser",
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\issuerUser",
},
TrustedUserCertificates = new CertificateTrustList
{
StoreType = CertificateStoreType.Directory,
StorePath = AppContext.BaseDirectory+ @"OPCUAClientCertificate\pki\trustedUser",
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\trustedUser",
}
@@ -389,7 +389,7 @@ public class OPCUAClient : DisposableObject
/// </summary>
public async Task ConnectAsync()
{
m_session = await ConnectAsync(OPCNode.OPCUrl);
m_session = await ConnectAsync(OPCNode.OPCURL);
}
/// <summary>

View File

@@ -40,7 +40,7 @@ namespace ThingsGateway.Foundation.Tests
_opc = new OPCUAClient();
_opc.UserIdentity = new UserIdentity("Administrator", "111111");
//_opc.UserIdentity = new UserIdentity(new AnonymousIdentityToken());
_opc.OPCNode = new() { OPCUrl = "opc.tcp://127.0.0.1:49320" };
_opc.OPCNode = new() { OPCURL = "opc.tcp://127.0.0.1:49320" };
var MonitorNodeTags = new string[] { address };
_opc.AddTagsAndSave(MonitorNodeTags.ToList());

View File

@@ -12,15 +12,16 @@
@using BlazorComponent;
@using Microsoft.AspNetCore.Components.Web;
@using System.Reflection;
@using ThingsGateway.Foundation.Adapter.OPCDA;
@using ThingsGateway.Foundation;
@using ThingsGateway.Foundation.Adapter.OPCDA.Rcw;
@using ThingsGateway.Web.Foundation;
@using Masa.Blazor
@inherits DriverImportUIBase
@using Yitter.IdGenerator;
<MCard Class="ma-0">
<MCardTitle Class="indigo white--text text-h6">
@OPCDAClient.PLC?.OPCNode?.ToString()
@PLC?.OPCNode?.ToString()
</MCardTitle>
<MRow Class="pa-4"
Justify="JustifyTypes.SpaceBetween">
@@ -119,16 +120,15 @@
protected override void OnInitialized()
{
Task.Run(async () =>
{
Nodes = PopulateBranch("");
overlay = false;
await InvokeAsync(StateHasChanged);
});
{
Nodes = PopulateBranch("");
overlay = false;
await InvokeAsync(StateHasChanged);
});
}
private bool overlay = true;
[Parameter]
public override object DriverObj { get; set; }
private OPCDAClient OPCDAClient => (OPCDAClient)DriverObj;
public ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient PLC { get; set; }
private List<OPCDATagModel> Nodes = new();
private List<BrowseElement> _selected { get; set; } = new();
private List<BrowseElement> actived = new();
@@ -147,7 +147,8 @@
}
}
[Inject]
IDriverPluginService DriverPluginService { get; set; }
private Task PopulateBranchAsync(OPCDATagModel model)
{
return Task.Run(() =>
@@ -157,9 +158,32 @@
});
}
public override List<CollectDeviceVariable> GetImportVariableList()
public CollectDevice GetImportDevice()
{
var data =
new CollectDevice()
{
Name = PLC.OPCNode.OPCName + YitIdHelper.NextId().ToString(),
Id = YitIdHelper.NextId(),
Enable = true,
IsLogOut = true,
DevicePropertys = new(),
PluginId = DriverPluginService.GetIdByName("ThingsGateway.OPCDA.OPCDAClient").ToLong(),
};
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCName), Value = PLC.OPCNode.OPCName, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCName)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCIP), Value = PLC.OPCNode.OPCIP, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCIP)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.ActiveSubscribe), Value = PLC.OPCNode.ActiveSubscribe.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.ActiveSubscribe)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.CheckRate), Value = PLC.OPCNode.CheckRate.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.CheckRate)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.DeadBand), Value = PLC.OPCNode.DeadBand.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.DeadBand)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.GroupSize), Value = PLC.OPCNode.GroupSize.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.GroupSize)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.UpdateRate), Value = PLC.OPCNode.UpdateRate.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.UpdateRate)).GetCustomAttribute<DevicePropertyAttribute>().Name });
return data;
}
public (CollectDevice, List<CollectDeviceVariable>) GetImportVariableList()
{
var device = GetImportDevice();
var data = _selected.Select(a =>
{
ProtectTypeEnum level = ProtectTypeEnum.ReadOnly;
@@ -175,16 +199,16 @@
}
return new CollectDeviceVariable()
{
Name = OPCDAClient.Device.Name + "_" + a.Name,
Name = device.Name + "_" + a.Name,
VariableAddress = a.ItemName,
DeviceId = OPCDAClient.Device.Id,
DeviceId = device.Id,
Id = Yitter.IdGenerator.YitIdHelper.NextId(),
ProtectTypeEnum = level,
IntervalTime = 1000,
};
}).Where(a => a != null).ToList();
return data;
return (device, data);
}
private List<OPCDATagModel> PopulateBranch(string sourceId)
@@ -192,8 +216,11 @@
List<OPCDATagModel> nodes = new List<OPCDATagModel>();
nodes.Add(new OPCDATagModel() { Name = "Browsering..." });
var result = OPCDAClient.PLC.GetBrowse(sourceId);
if (!result.IsSuccess) return new();
var result = PLC.GetBrowse(sourceId);
if (!result.IsSuccess)
{
return new() { new() { Name = "未完成连接", Tag = new(),Nodes=null } };
}
var references = result.Content;
List<OPCDATagModel> list = new List<OPCDATagModel>();
if (references != null)

View File

@@ -41,8 +41,6 @@ public class OPCDAClient : CollectBase
public override System.Type DriverDebugUIType => typeof(OPCDAClientDebugDriverPage);
public override System.Type DriverImportUIType => typeof(ImportVariable);
public override CollectDriverPropertyBase DriverPropertys => driverPropertys;
public override ThingsGatewayBitConverter ThingsGatewayBitConverter { get; } = new(EndianType.Little);

View File

@@ -12,6 +12,7 @@
@using BlazorComponent;
@using Microsoft.AspNetCore.Components.Web;
@using Masa.Blazor.Presets;
@using Microsoft.JSInterop;
@using ThingsGateway.Core;
@using ThingsGateway.Foundation;
@@ -40,8 +41,6 @@
</MButton>
</MRow>
<MButton Class="mx-1 my-1" Color="primary" OnClick="Read">
组读取
</MButton>
@@ -50,8 +49,19 @@
写入
</MButton>
<MRow NoGutters>
<MButton Class="mx-1 my-3" Color="primary" OnClick="()=>IsShowImportVariableList=!IsShowImportVariableList">
<span>导入变量</span>
</MButton>
</MRow>
</MCol>
</MCard>
</MCol>
<MCol Md="8">
@@ -99,12 +109,40 @@
</MCard>
<PModal @bind-Value="IsShowImportVariableList" OnCancel="() => IsShowImportVariableList = false"
Title=导入变量 Height=@("700") Persistent
MaxWidth="1500" OnSave="DownDeviceExport">
<ChildContent>
@if (IsShowImportVariableList)
{
<ImportVariable @ref=importVariable PLC="_plc"></ImportVariable>
}
</ChildContent>
<SaveContent Context="save">
<MButton Text Color="primary" OnClick="save.Click" Disabled="isDownExport" Loading="isDownExport">
<MLabel>导出Excel</MLabel>
</MButton>
</SaveContent>
</PModal>
@code{
bool IsShowImportVariableList;
private ImportVariable importVariable { get; set; }
}
@code
{
private OPCDAClientPage tcpClientPage;
private ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient _plc;
private async Task DownDeviceExport()
{
var data = importVariable?.GetImportVariableList();
if(data!=null)
{
await DownDeviceExport(data?.Item1);
await DownDeviceExport(data?.Item2);
}
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)

View File

@@ -14,14 +14,15 @@
@using Microsoft.AspNetCore.Components.Web;
@namespace ThingsGateway.OPCUA
@using Opc.Ua;
@using System.Reflection;
@using ThingsGateway.Foundation.Adapter.OPCUA;
@using ThingsGateway.Foundation;
@using ThingsGateway.Web.Foundation;
@using Masa.Blazor
@inherits DriverImportUIBase
@using Yitter.IdGenerator;
<MCard Class="ma-0">
<MCardTitle Class="indigo white--text text-h6">
@OPCUAClient.PLC?.OPCNode?.OPCUrl
@PLC?.OPCNode?.OPCURL
</MCardTitle>
<MRow Class="pa-4"
Justify="JustifyTypes.SpaceBetween">
@@ -40,7 +41,7 @@
</MCol>
<MCol Cols="12" Md="6">
<MCardText Style="height:500px;overflow-y:auto;">
@if (_actived?.Count == 0)
@if (_actived?.Count == 0 || _actived?.FirstOrDefault()?.NodeId==null)
{
<div key="title"
class="text-h6 font-weight-light grey--text pa-4 text-center">
@@ -110,6 +111,32 @@
</MOverlay>
@code
{
[Inject]
IDriverPluginService DriverPluginService { get; set; }
public CollectDevice GetImportDevice()
{
var data =
new CollectDevice()
{
Name = PLC.OPCNode.OPCURL,
Id = YitIdHelper.NextId(),
Enable = true,
IsLogOut = true,
DevicePropertys = new(),
PluginId = DriverPluginService.GetIdByName("ThingsGateway.OPCUA.OPCUAClient").ToLong(),
};
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.OPCURL), Value = PLC.OPCNode.OPCURL, Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.OPCURL)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.UserName), Value = PLC.UserIdentity.DisplayName, Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.UserName)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.Password), Value = "", Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.Password)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.IsUseSecurity), Value = PLC.OPCNode.IsUseSecurity.ToString(), Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.IsUseSecurity)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.ActiveSubscribe), Value = true.ToString(), Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.ActiveSubscribe)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.DeadBand), Value = PLC.OPCNode.DeadBand.ToString(), Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.DeadBand)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.GroupSize), Value = PLC.OPCNode.GroupSize.ToString(), Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.GroupSize)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.UpdateRate), Value = PLC.OPCNode.UpdateRate.ToString(), Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.UpdateRate)).GetCustomAttribute<DevicePropertyAttribute>().Name });
data.DevicePropertys.Add(new() { PropertyName = nameof(OPCUAClientProperty.ReconnectPeriod), Value = PLC.OPCNode.ReconnectPeriod.ToString(), Description = typeof(OPCUAClientProperty).GetProperty(nameof(OPCUAClientProperty.ReconnectPeriod)).GetCustomAttribute<DevicePropertyAttribute>().Name });
return data;
}
protected override void OnInitialized()
{
@@ -122,8 +149,7 @@
}
private bool overlay = true;
[Parameter]
public override object DriverObj { get; set; }
private OPCUAClient OPCUAClient => (OPCUAClient)DriverObj;
public ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient PLC { get; set; }
private List<OPCUATagModel> Nodes = new();
private List<ReferenceDescription> _selected { get; set; } = new();
private List<ReferenceDescription> actived = new();
@@ -136,7 +162,8 @@
if (actived?.FirstOrDefault() != value?.FirstOrDefault() && value?.Count > 0)
{
actived = value;
nodeAttributes = OPCUAClient.PLC.ReadNoteAttributes(actived.FirstOrDefault().NodeId.ToString());
if (actived.FirstOrDefault().NodeId != null)
nodeAttributes = PLC.ReadNoteAttributes(actived.FirstOrDefault().NodeId.ToString());
}
}
@@ -150,20 +177,20 @@
var sourceId = (NodeId)model.Tag.NodeId;
model.Nodes = PopulateBranch(sourceId);
});
}
public override List<CollectDeviceVariable> GetImportVariableList()
public (CollectDevice, List<CollectDeviceVariable>) GetImportVariableList()
{
var device = GetImportDevice();
var data = _selected.Select(a =>
{
var nodeClass = (OPCUAClient.PLC.ReadNoteAttribute(a.NodeId.ToString(), Attributes.NodeClass).FirstOrDefault().Value).ToString();
var nodeClass = (PLC.ReadNoteAttribute(a.NodeId.ToString(), Attributes.NodeClass).FirstOrDefault().Value).ToString();
if (nodeClass == nameof(NodeClass.Variable))
{
ProtectTypeEnum level = ProtectTypeEnum.ReadOnly;
try
{
var userAccessLevel = (AccessLevelType)(OPCUAClient.PLC.ReadNoteAttribute(a.NodeId.ToString(), Attributes.UserAccessLevel).FirstOrDefault().Value);
var userAccessLevel = (AccessLevelType)(PLC.ReadNoteAttribute(a.NodeId.ToString(), Attributes.UserAccessLevel).FirstOrDefault().Value);
level = (userAccessLevel.HasFlag(AccessLevelType.CurrentRead)) ?
userAccessLevel.HasFlag(AccessLevelType.CurrentWrite) ?
ProtectTypeEnum.ReadWrite : ProtectTypeEnum.ReadOnly : ProtectTypeEnum.WriteOnly;
@@ -172,7 +199,7 @@
{
}
var dataTypeId = (Opc.Ua.NodeId)(OPCUAClient.PLC.ReadNoteAttribute(a.NodeId.ToString(), Attributes.DataType).FirstOrDefault().Value);
var dataTypeId = (Opc.Ua.NodeId)(PLC.ReadNoteAttribute(a.NodeId.ToString(), Attributes.DataType).FirstOrDefault().Value);
var dataType = Opc.Ua.DataTypes.GetSystemType(dataTypeId, null);
var result = Enum.TryParse(typeof(DataTypeEnum), dataType.Name, out object dataTypeEnum);
if (!result)
@@ -181,9 +208,9 @@
}
return new CollectDeviceVariable()
{
Name = OPCUAClient.Device.Name + "_" + a.DisplayName.Text,
Name = device.Name + "_" + a.DisplayName.Text,
VariableAddress = a.NodeId.ToString(),
DeviceId = OPCUAClient.Device.Id,
DeviceId = device.Id,
DataTypeEnum = (DataTypeEnum)dataTypeEnum,
Id = Yitter.IdGenerator.YitIdHelper.NextId(),
ProtectTypeEnum = level,
@@ -195,11 +222,15 @@
return null;
}
}).Where(a => a != null).ToList();
return data;
return (device, data);
}
private List<OPCUATagModel> PopulateBranch(NodeId sourceId)
{
if (!PLC.Connected)
{
return new() { new() { Name = "未完成连接", Tag = new(), Nodes = null } };
}
List<OPCUATagModel> nodes = new List<OPCUATagModel>();
nodes.Add(new OPCUATagModel() { Name = "Browsering..." });
@@ -259,7 +290,7 @@
nodesToBrowse.Add(nodeToBrowse1);
nodesToBrowse.Add(nodeToBrowse2);
ReferenceDescriptionCollection references = FormUtils.Browse(OPCUAClient.PLC.Session, nodesToBrowse, false);
ReferenceDescriptionCollection references = FormUtils.Browse(PLC.Session, nodesToBrowse, false);
return references;
}

View File

@@ -43,9 +43,6 @@ public class OPCUAClient : CollectBase
{
}
/// <inheritdoc/>
public override Type DriverImportUIType => typeof(ImportVariable);
/// <inheritdoc/>
public override Type DriverDebugUIType => typeof(OPCUAClientDebugDriverPage);
@@ -148,7 +145,7 @@ public class OPCUAClient : CollectBase
{
Device = device;
OPCNode oPCNode = new();
oPCNode.OPCUrl = driverPropertys.OPCURL;
oPCNode.OPCURL = driverPropertys.OPCURL;
oPCNode.UpdateRate = driverPropertys.UpdateRate;
oPCNode.DeadBand = driverPropertys.DeadBand;
oPCNode.GroupSize = driverPropertys.GroupSize;

View File

@@ -11,6 +11,7 @@
*@
@namespace ThingsGateway.OPCUA
@using Masa.Blazor.Presets;
@using BlazorComponent;
@using Microsoft.AspNetCore.Components.Web;
@using Microsoft.JSInterop;
@@ -64,6 +65,13 @@
写入
</MButton>
<MRow NoGutters>
<MButton Class="mx-1 my-3" Color="primary" OnClick="()=>IsShowImportVariableList=!IsShowImportVariableList">
<span>导入变量</span>
</MButton>
</MRow>
</MCol>
</MCard>
</MCol>
@@ -113,12 +121,43 @@
</MCard>
<PModal @bind-Value="IsShowImportVariableList" OnCancel="() => IsShowImportVariableList = false"
Title=导入变量 Height=@("700") Persistent
MaxWidth="1500" OnSave="DownDeviceExport">
<ChildContent>
@if (IsShowImportVariableList)
{
<ImportVariable @ref=importVariable PLC="_plc"></ImportVariable>
}
</ChildContent>
<SaveContent Context="save">
<MButton Text Color="primary" OnClick="save.Click" Disabled="isDownExport" Loading="isDownExport">
<MLabel>导出Excel</MLabel>
</MButton>
</SaveContent>
</PModal>
@code {
bool IsShowImportVariableList;
private ImportVariable importVariable { get; set; }
}
@code
{
private OPCUAClientPage tcpClientPage;
private ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient _plc;
private async Task DownDeviceExport()
{
var data = importVariable?.GetImportVariableList();
if (data != null)
{
await DownDeviceExport(data?.Item1);
await DownDeviceExport(data?.Item2);
}
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)

View File

@@ -35,7 +35,7 @@
</MRow>
<MRow Justify="JustifyTypes.SpaceBetween" Align="AlignTypes.Center">
<MCheckbox Class="mx-1 my-1" Label=@node.Description(a=>a.IsUseSecurity) Dense HideDetails="@("auto")" @bind-Value=@node.IsUseSecurity />
<MTextField Class="mx-1 my-1" Label=@node.Description(a=>a.OPCUrl) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.OPCUrl />
<MTextField Class="mx-1 my-1" Label=@node.Description(a=>a.OPCURL) Dense Outlined HideDetails="@("auto")" @bind-Value=@node.OPCURL />
<MTextField Class="mx-1 my-1" Label="用户名" Dense Outlined HideDetails="@("auto")" @bind-Value=@username />
<MTextField Class="mx-1 my-1" Label="密码" Dense Outlined HideDetails="@("auto")" @bind-Value=@password />
<MButton Class="mx-1 my-1" OnClick=@(Reconnect) Color="primary">

View File

@@ -32,5 +32,5 @@ public class OPCUAServerProperty : UpDriverPropertyBase
/// </summary>
[DeviceProperty("接受不受信任的证书", "")]
public bool AutoAcceptUntrustedCertificates { get; set; } = true;
}

View File

@@ -68,7 +68,7 @@ namespace ThingsGateway.Core
db.Aop.OnLogExecuting = (sql, pars) =>
{
//如果不是开发环境就打印sql
if (App.HostEnvironment.IsDevelopment()&& !sql.Contains("tg_log_runtime"))
if (App.HostEnvironment.IsDevelopment() && !sql.Contains("tg_log_runtime"))
{
if (sql.StartsWith("SELECT"))
{

View File

@@ -34,10 +34,6 @@ public abstract class CollectBase : DriverBase
{
}
/// <summary>
/// 导入变量UI Type继承实现<see cref="DriverImportUIBase"/>后返回继承类的Type如果不存在返回null
/// </summary>
public virtual Type DriverImportUIType { get; }
/// <summary>
/// 共享通道类型

View File

@@ -149,7 +149,51 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
isDownExport = false;
}
}
[Inject]
IVariableService VariableService { get; set; }
[Inject]
ICollectDeviceService CollectDeviceService { get; set; }
/// <summary>
/// 导入变量导出到excel
/// </summary>
/// <returns></returns>
protected async Task DownDeviceExport(CollectDevice data)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await CollectDeviceService.ExportFileAsync(new() { data });
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
await JS.InvokeVoidAsync("downloadFileFromStream", $"设备导出{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
/// <summary>
/// 导入变量导出到excel
/// </summary>
/// <returns></returns>
protected async Task DownDeviceExport(List<CollectDeviceVariable> data)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await VariableService.ExportFileAsync(data);
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
await JS.InvokeVoidAsync("downloadFileFromStream", $"变量导出{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
/// <inheritdoc/>
protected void LogOut(string str)
{

View File

@@ -1,33 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Microsoft.AspNetCore.Components;
namespace ThingsGateway.Web.Foundation;
/// <summary>
/// 导入变量UI
/// </summary>
public abstract class DriverImportUIBase : ComponentBase
{
/// <summary>
/// 设备通讯类
/// </summary>
[Parameter]
public virtual object DriverObj { get; set; }
/// <summary>
/// 获取导入变量列表
/// </summary>
/// <returns></returns>
public abstract List<CollectDeviceVariable> GetImportVariableList();
}

View File

@@ -275,10 +275,12 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
public const string CollectDeviceSheetName = "采集设备";
/// <inheritdoc/>
[OperDesc("导出采集设备表", IsRecordPar = false)]
public async Task<MemoryStream> ExportFileAsync()
public async Task<MemoryStream> ExportFileAsync(List<CollectDevice> devDatas = null)
{
var devDatas = GetCacheList();
if (devDatas == null)
{
devDatas = GetCacheList();
}
//总数据
Dictionary<string, object> sheets = new Dictionary<string, object>();

View File

@@ -57,7 +57,7 @@ public interface ICollectDeviceService : ITransient
/// 导出Excel
/// </summary>
/// <returns></returns>
Task<MemoryStream> ExportFileAsync();
Task<MemoryStream> ExportFileAsync(List<CollectDevice> devDatas = null);
/// <summary>
/// 获取缓存
/// </summary>
@@ -110,8 +110,6 @@ public interface ICollectDeviceService : ITransient
/// <param name="file"></param>
/// <returns></returns>
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile file);
}
/// <summary>
/// 设备组/名称树

View File

@@ -679,9 +679,9 @@ public class CollectDeviceCore : DisposableObject
base.Dispose(disposing);
StopThread();
_driver = null;
Methods=null;
Methods = null;
Propertys = null;
if (Device!=null)
if (Device != null)
{
_pluginService.DeleteDriver(DeviceId, Device.PluginId);
}

View File

@@ -172,7 +172,7 @@ public class PluginSingletonService : ISingleton
{
var devId = YitIdHelper.NextId();
var assemblyLoadContext = new AssemblyLoadContext(devId.ToString(), true);
var weakALC = new WeakReference(assemblyLoadContext, true);
var weakALC = new WeakReference(assemblyLoadContext, true);
try
{

View File

@@ -334,7 +334,7 @@ public class UploadDeviceWorker : BackgroundService
for (int i = 0; i < num; i++)
{
UploadDeviceCore devcore = UploadDeviceCores[i];
if(devcore.Device!=null)
if (devcore.Device != null)
{
if (
(devcore.Device.ActiveTime != DateTime.MinValue && devcore.Device.ActiveTime.AddMinutes(3) <= DateTime.UtcNow)

View File

@@ -158,7 +158,7 @@
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("tgdevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small OnClick=@(()=>Config(item.DeviceId,!item.Device?.KeepOn))>
<MIcon>@(item.Device?.KeepOn==true ? "mdi-pause" : "mdi-play")</MIcon>
<MIcon>@(item.Device?.KeepOn == true ? "mdi-pause" : "mdi-play")</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
@@ -176,16 +176,6 @@
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("tgdevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=>ImportVaiable(item.DeviceId))>
<MIcon>mdi-import</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<span>@T("导入变量")</span>
</ChildContent>
</MTooltip>
</MCardActions>
<MSubheader>
@@ -400,7 +390,7 @@
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("tgdevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small OnClick=@(()=>UpConfig(item.DeviceId,!item.Device?.KeepOn))>
<MIcon>@(item.Device?.KeepOn==true ? "mdi-pause" : "mdi-play")</MIcon>
<MIcon>@(item.Device?.KeepOn == true ? "mdi-pause" : "mdi-play")</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
@@ -538,7 +528,7 @@
<MSpeedDial @bind-Value="fab" Direction="top" Class="position-button"
<MSpeedDial @bind-Value="fab" Direction="bottom" Class="position-button"
Transition="slide-y-reverse-transition">
<ActivatorContent>
<MButton Color="blue darken" Dark Small Fab @attributes="@context.Attrs">
@@ -573,7 +563,7 @@
<style>
.position-button {
position: fixed !important;
top: 40%;
top: 10%;
right: 0;
box-shadow: 1px 1px 8px var(--mud-palette-primary);
background-color: var(--mud-palette-primary);
@@ -582,23 +572,6 @@
</style>
<PModal @bind-Value="IsShowImportVariableList" OnCancel="() => IsShowImportVariableList = false"
Title=@T("导入变量") Height=@("700") Persistent
MaxWidth="1500" OnSave="DownDeviceExport">
<ChildContent>
@if (IsShowImportVariableList)
{
@_importRender
}
</ChildContent>
<SaveContent Context="save">
<MButton Text Color="primary" OnClick="save.Click" Disabled="isDownExport" Loading="isDownExport">
<MLabel>@T("导出Excel")</MLabel>
</MButton>
</SaveContent>
</PModal>
@@ -678,29 +651,11 @@
IJSRuntime JS { get; set; }
[Inject]
IVariableService VariableService { get; set; }
async Task DownDeviceExport()
{
try
{
var data = _importRef.GetImportVariableList();
isDownExport = true;
StateHasChanged();
using var memoryStream = await VariableService.ExportFileAsync(data);
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
await JS.InvokeVoidAsync("downloadFileFromStream", $"变量导出{DateTime.UtcNow.Add(JsInitVariables.TimezoneOffset).ToString("yyyy-MM-dd HH:mm:ss fff")}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
StringNumber tab;
private System.Timers.Timer DelayTimer;
private bool fab;
bool isAllRestart;
bool isRestart;
bool IsShowImportVariableList;
CollectDeviceWorker CollectDeviceHostService { get; set; }
UploadDeviceWorker UploadDeviceHostService { get; set; }
AlarmWorker AlarmHostService { get; set; }
@@ -718,34 +673,11 @@
return base.OnInitializedAsync();
}
private BootstrapDynamicComponent _importComponent;
private RenderFragment _importRender;
private DriverImportUIBase _importRef;
async Task ImportVaiable(long devId)
{
var driver = ServiceExtension.GetBackgroundService<CollectDeviceWorker>().GetImportUI(devId);
if (driver?.DriverImportUIType == null)
{
await PopupService.EnqueueSnackbarAsync("插件未实现导入变量", AlertTypes.Warning);
return;
}
_importComponent = new BootstrapDynamicComponent(driver.DriverImportUIType, new Dictionary<string, object>()
{
[nameof(DriverImportUIBase.DriverObj)] = driver
}
);
_importRender = _importComponent.Render(a => _importRef = (DriverImportUIBase)a);
IsShowImportVariableList = true;
}
async Task Restart(long devId)
{
try
{
_importComponent = null;
_importRef = null;
_importRender = null;
var confirm = await PopupService.OpenConfirmDialogAsync(T("重启"), T("确定重启?"));
if (confirm)
{
@@ -768,9 +700,6 @@
{
try
{
_importComponent = null;
_importRef = null;
_importRender = null;
var confirm = await PopupService.OpenConfirmDialogAsync(T("重启"), T("确定重启?"));
if (confirm)
{
@@ -791,11 +720,11 @@
}
async Task Config(long devId, bool? isStart)
{
var str = isStart==true ? T("启动") : T("暂停");
var str = isStart == true ? T("启动") : T("暂停");
var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?");
if (confirm)
{
await CollectDeviceHostService.ConfigDeviceThreadAsync(devId, isStart==true);
await CollectDeviceHostService.ConfigDeviceThreadAsync(devId, isStart == true);
}
}
async Task UpConfig(long devId, bool? isStart)