#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using Microsoft.JSInterop;
using System.IO;
using System.Threading;
using ThingsGateway.Admin.Blazor.Core;
using ThingsGateway.Admin.Core;
using ThingsGateway.Application.Extensions;
using ThingsGateway.Foundation;
namespace ThingsGateway.Application;
///
/// 调试UI
///
public abstract class DriverDebugUIBase : ComponentBase, IDisposable
{
///
/// 导出提示
///
public bool isDownExport;
///
/// 日志缓存
///
public ConcurrentLinkedList<(LogLevel level, string message)> Messages = new();
IJSObjectReference _helper;
readonly PeriodicTimer _periodicTimer = new(TimeSpan.FromSeconds(1));
///
/// 默认读写设备
///
public virtual IReadWriteDevice Plc { get; set; }
///
/// 变量地址
///
public virtual string Address { get; set; } = "40001";
///
/// 数据类型
///
protected virtual DataTypeEnum DataTypeEnum { get; set; } = DataTypeEnum.Int16;
///
[Inject]
protected IJSRuntime JS { get; set; }
///
/// 写入值
///
public virtual string WriteValue { get; set; }
[Inject]
private ICollectDeviceService CollectDeviceService { get; set; }
[Inject]
private IVariableService VariableService { get; set; }
[Inject]
private InitTimezone InitTimezone { get; set; }
///
public virtual void Dispose()
{
_periodicTimer?.Dispose();
}
///
public virtual async Task ReadAsync()
{
try
{
var data = await Plc.ReadAsync(Address, DataTypeEnum.GetSystemType());
if (data.IsSuccess)
{
Messages.Add((LogLevel.Information, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - 对应类型值:" + data.Content));
}
else
{
Messages.Add((LogLevel.Error, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + data.Message));
}
}
catch (Exception ex)
{
Messages.Add((LogLevel.Warning, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + "错误:" + ex.Message));
}
}
///
public virtual async Task WriteAsync()
{
try
{
var data = await Plc.WriteAsync(Address, DataTypeEnum.GetSystemType(), WriteValue);
if (data.IsSuccess)
{
Messages.Add((LogLevel.Information, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + data.Message));
}
else
{
Messages.Add((LogLevel.Warning, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + data.Message));
}
}
catch (Exception ex)
{
Messages.Add((LogLevel.Error, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + "写入前失败:" + ex.Message));
}
}
///
/// 导入设备
///
///
public async Task DeviceImportAsync(CollectDevice data)
{
try
{
isDownExport = true;
StateHasChanged();
await CollectDeviceService.AddAsync(data);
}
finally
{
isDownExport = false;
}
}
///
/// 导入变量
///
///
public async Task DeviceVariableImportAsync(List data)
{
try
{
isDownExport = true;
StateHasChanged();
await VariableService.AddBatchAsync(data);
}
finally
{
isDownExport = false;
}
}
///
/// 导出
///
///
///
public async Task DownDeviceMessageExportAsync(IEnumerable values)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = new MemoryStream();
StreamWriter writer = new(memoryStream);
foreach (var item in values)
{
writer.WriteLine(item);
}
writer.Flush();
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
await _helper.InvokeVoidAsync("downloadFileFromStream", $"报文导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef);
}
finally
{
isDownExport = false;
}
}
///
/// 导出到excel
///
///
public async Task DownDeviceExportAsync(CollectDevice data)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await CollectDeviceService.ExportFileAsync(new List() { data });
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
await _helper.InvokeVoidAsync("downloadFileFromStream", $"设备导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
///
/// 导出到excel
///
///
public async Task DownDeviceVariableExportAsync(List data, string devName)
{
try
{
isDownExport = true;
StateHasChanged();
using var memoryStream = await VariableService.ExportFileAsync(data, devName);
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamRef = new DotNetStreamReference(stream: memoryStream);
_helper ??= await JS.InvokeAsync("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js");
await _helper.InvokeVoidAsync("downloadFileFromStream", $"变量导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.xlsx", streamRef);
}
finally
{
isDownExport = false;
}
}
///
public void LogOut(TouchSocket.Core.LogLevel logLevel, object source, string message, Exception exception)
{
Messages.Add(((LogLevel)logLevel, SysDateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + message + (exception != null ? exception.Message : "")));
if (Messages.Count > 2500)
{
Messages.Clear();
}
}
///
protected override void OnInitialized()
{
_ = RunTimerAsync();
base.OnInitialized();
}
private async Task RunTimerAsync()
{
while (await _periodicTimer.WaitForNextTickAsync())
{
await InvokeAsync(StateHasChanged);
}
}
}