mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 10:50:48 +08:00
docs: 更新采集插件开发文档
This commit is contained in:
@@ -62,7 +62,7 @@ public class HardwareJob : IJob, IHardwareJob
|
||||
if (historyHardwareInfos == null)
|
||||
{
|
||||
using var db = DbContext.GetDB<HistoryHardwareInfo>(); ;
|
||||
historyHardwareInfos = await db.Queryable<HistoryHardwareInfo>().Where(a => a.Date > DateTime.Now.AddDays(-3)).ToListAsync().ConfigureAwait(false);
|
||||
historyHardwareInfos = await db.Queryable<HistoryHardwareInfo>().Where(a => a.Date > DateTime.Now.AddDays(-3)).Take(1000).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
MemoryCache.Set(CacheKey, historyHardwareInfos);
|
||||
}
|
||||
|
@@ -238,7 +238,7 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
||||
return variableTasks;
|
||||
}
|
||||
|
||||
private void SetDeviceStatus(object? state, CancellationToken cancellationToken)
|
||||
protected virtual void SetDeviceStatus(object? state, CancellationToken cancellationToken)
|
||||
{
|
||||
if (IsConnected())
|
||||
{
|
||||
|
@@ -441,6 +441,9 @@ internal sealed class AlarmHostedService : BackgroundService, IAlarmHostedServic
|
||||
//stopwatch.Stop();
|
||||
//_logger.LogInformation("报警分析耗时:" + stopwatch.ElapsedMilliseconds + "ms");
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Alarm analysis fail");
|
||||
|
@@ -1091,14 +1091,13 @@ public class OpcUaMaster : IDisposable
|
||||
{
|
||||
|
||||
VariableNode variableNode = new VariableNode();
|
||||
DataValue value;
|
||||
DataValue value = values[1 + 2 * i];
|
||||
|
||||
if (!DataValue.IsGood(values[1 + 2 * i]))
|
||||
{
|
||||
//throw ServiceResultException.Create(values[1+2 * i].StatusCode, 1+2 * i, diagnosticInfos, responseHeader.StringTable);
|
||||
}
|
||||
//if (!DataValue.IsGood(value))
|
||||
//{
|
||||
// //throw ServiceResultException.Create(values[1+2 * i].StatusCode, 1+2 * i, diagnosticInfos, responseHeader.StringTable);
|
||||
//}
|
||||
// DataType Attribute
|
||||
value = values[1 + 2 * i];
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
@@ -1109,13 +1108,13 @@ public class OpcUaMaster : IDisposable
|
||||
{
|
||||
variableNode.DataType = (NodeId)value.GetValue(typeof(NodeId));
|
||||
}
|
||||
value = values[0 + 2 * i];
|
||||
|
||||
// NodeId Attribute
|
||||
if (!DataValue.IsGood(values[0 + 2 * i]))
|
||||
if (!DataValue.IsGood(value))
|
||||
{
|
||||
throw ServiceResultException.Create(values[0 + 2 * i].StatusCode, 0 + 2 * i, diagnosticInfos, responseHeader.StringTable);
|
||||
throw ServiceResultException.Create(value.StatusCode, 0 + 2 * i, diagnosticInfos, responseHeader.StringTable);
|
||||
}
|
||||
value = values[0 + 2 * i];
|
||||
if (value == null)
|
||||
{
|
||||
throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not support the NodeId attribute.");
|
||||
|
@@ -146,6 +146,8 @@ public class OpcUaMaster : CollectBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private volatile bool checkLog;
|
||||
private async Task CheckAsync(object? state, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_plc.Session != null)
|
||||
@@ -177,10 +179,13 @@ public class OpcUaMaster : CollectBase
|
||||
}
|
||||
}
|
||||
LogMessage?.LogInformation("AddSubscriptions done");
|
||||
checkLog = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage?.LogWarning(ex, "AddSubscriptions");
|
||||
if (!checkLog)
|
||||
LogMessage?.LogWarning(ex, "AddSubscriptions");
|
||||
checkLog = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"HardwareInfo": {
|
||||
"HistoryInterval": 60000, //历史更新间隔ms
|
||||
"HistoryInterval": 300000, //历史更新间隔ms
|
||||
"DaysAgo": 1, //保留1天数据
|
||||
"Enable": true //启用硬件信息获取
|
||||
}
|
||||
|
@@ -1,3 +1,5 @@
|
||||
docker pull mcr.microsoft.com/dotnet/aspnet:8.0-noble
|
||||
|
||||
docker build -t registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway:latest .
|
||||
|
||||
docker push registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway
|
||||
|
@@ -1,3 +1,5 @@
|
||||
docker pull mcr.microsoft.com/dotnet/aspnet:8.0-noble-arm64v8
|
||||
|
||||
docker build -f Dockerfile_arm64 -t registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway_arm64:latest .
|
||||
|
||||
docker push registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway_arm64
|
||||
|
@@ -1,46 +1,52 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://thingsgateway.cn/
|
||||
// QQ群:605534569
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//using Newtonsoft.Json.Linq;
|
||||
|
||||
//using ThingsGateway.Foundation;
|
||||
//using ThingsGateway.Gateway.Application;
|
||||
|
||||
//using ThingsGateway.Razor;
|
||||
//namespace ThingsGateway.Server;
|
||||
|
||||
///// <summary>
|
||||
///// 插件类
|
||||
///// 插件类,默认实现了<see cref="IDevice"/>接口,继承<see cref="CollectFoundationBase"/> 实现采集插件
|
||||
///// </summary>
|
||||
//public class TestCollectPlugin : CollectFoundationBase
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 调试UI Type,如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverDebugUIType => base.DriverDebugUIType;
|
||||
// /// <summary>
|
||||
// /// 插件属性UI Type,继承<see cref="IPropertyUIBase"/>如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverPropertyUIType => base.DriverPropertyUIType;
|
||||
// /// <summary>
|
||||
// /// 插件UI Type,继承<see cref="IDriverUIBase"/>如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverUIType => base.DriverUIType;
|
||||
// /// <summary>
|
||||
// /// 插件变量寄存器UI Type,继承<see cref="IAddressUIBase"/>如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverVariableAddressUIType => base.DriverVariableAddressUIType;
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 插件配置项,继承<see cref="CollectPropertyBase"/> 返回类实例
|
||||
// /// </summary>
|
||||
// public override CollectPropertyBase CollectProperties => _property;
|
||||
// private TestCollectProperty? _property = new();
|
||||
|
||||
// /// <summary>
|
||||
// /// 插件默认的PLC通讯类,如未实现,返回null
|
||||
// /// </summary>
|
||||
// public override IProtocol? Protocol => null;
|
||||
|
||||
// /// <summary>
|
||||
// /// 在插件初始化时调用,只会执行一次,参数为插件默认的链路通道类,如未实现可忽略l
|
||||
// /// </summary>
|
||||
// protected override Task InitChannelAsync(IChannel? channel ,CancellationToken cancellationToken)
|
||||
// protected override Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
|
||||
// {
|
||||
// //做一些初始化操作
|
||||
|
||||
// return Task.CompletedTask;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 变量打包操作,会在Init方法后执行,参数为设备变量列表,返回源读取变量列表
|
||||
// /// 变量打包操作,会在默认的AfterVariablesChangedAsync方法里执行,参数为设备变量列表,返回源读取变量列表
|
||||
// /// </summary>
|
||||
// protected override Task<List<VariableSourceRead>> ProtectedLoadSourceReadAsync(List<VariableRuntime> deviceVariables)
|
||||
// {
|
||||
@@ -50,33 +56,175 @@
|
||||
// //一般可操作 VariableRuntime 类中的 index, thingsgatewaybitconvter 等属性
|
||||
// //一般可操作 VariableSourceRead 类中的 address, length 等属性
|
||||
|
||||
// return new List<VariableSourceRead>();
|
||||
// return Task.FromResult(new List<VariableSourceRead>());
|
||||
// }
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 实现<see cref="IDevice"/>
|
||||
// /// </summary>
|
||||
// public override IDevice? FoundationDevice => base.FoundationDevice;
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 特殊方法,添加<see cref="DynamicMethodAttribute"/> 特性 ,返回IOperResult
|
||||
// /// 支持<see cref="CancellationToken"/> 参数,需放到最后
|
||||
// /// 默认解析方式为英文分号
|
||||
// /// 比如rpc参数为 test1;test2,解析query1="test1",query2="test2"
|
||||
// /// 也可以在变量地址中填入test1,rpc参数传入test2,解析query1="test1",query2="test2"
|
||||
// /// </summary>
|
||||
// [DynamicMethod("测试特殊方法")]
|
||||
// public IOperResult<string> TestMethod(string query1, string query2, CancellationToken cancellationToken)
|
||||
// {
|
||||
// return new OperResult<string>() { Content = "测试特殊方法" };
|
||||
// }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 插件类配置
|
||||
///// </summary>
|
||||
//public class TestCollectProperty : CollectFoundationPackPropertyBase
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 添加<see cref="DynamicPropertyAttribute"/> 特性,如需多语言配置,可添加json资源,参考其他插件
|
||||
// /// </summary>
|
||||
// [DynamicProperty(Description = null, Remark = null)]
|
||||
// public string TestString { get; set; }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 插件类,完全自定义
|
||||
///// </summary>
|
||||
//public class TestCollectPlugin1 : CollectBase
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 调试UI Type,如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverDebugUIType => base.DriverDebugUIType;
|
||||
// /// <summary>
|
||||
// /// 插件属性UI Type,继承<see cref="IPropertyUIBase"/>如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverPropertyUIType => base.DriverPropertyUIType;
|
||||
// /// <summary>
|
||||
// /// 插件UI Type,继承<see cref="IDriverUIBase"/>如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverUIType => base.DriverUIType;
|
||||
// /// <summary>
|
||||
// /// 插件变量寄存器UI Type,继承<see cref="IAddressUIBase"/>如果不存在无需重写
|
||||
// /// </summary>
|
||||
// public override Type DriverVariableAddressUIType => base.DriverVariableAddressUIType;
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 插件配置项,继承<see cref="CollectPropertyBase"/> 返回类实例
|
||||
// /// </summary>
|
||||
// public override CollectPropertyBase CollectProperties => _property;
|
||||
// private TestCollectProperty1? _property = new();
|
||||
|
||||
// /// <summary>
|
||||
// /// 在插件初始化时调用,只会执行一次,参数为插件默认的链路通道类,如未实现可忽略l
|
||||
// /// </summary>
|
||||
// protected override Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
|
||||
// {
|
||||
// //做一些初始化操作
|
||||
|
||||
// return Task.CompletedTask;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 变量打包操作,会在默认的AfterVariablesChangedAsync方法里执行,参数为设备变量列表,返回源读取变量列表
|
||||
// /// </summary>
|
||||
// protected override Task<List<VariableSourceRead>> ProtectedLoadSourceReadAsync(List<VariableRuntime> deviceVariables)
|
||||
// {
|
||||
// //实现将设备变量打包成源读取变量
|
||||
// //比如如果需要实现MC中的字多读功能,需将多个变量地址打包成一个源读取地址和读取长度,根据一系列规则,添加解析标识,然后在返回的整个字节数组中解析出原来的变量地址代表的数据字节
|
||||
|
||||
// //一般可操作 VariableRuntime 类中的 index, thingsgatewaybitconvter 等属性
|
||||
// //一般可操作 VariableSourceRead 类中的 address, length 等属性
|
||||
|
||||
// return Task.FromResult(new List<VariableSourceRead>());
|
||||
// }
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 如果不实现ReadSourceAsync方法,可以返回flase
|
||||
// /// </summary>
|
||||
// protected override bool VariableSourceReadsEnable => base.VariableSourceReadsEnable;
|
||||
|
||||
// /// <summary>
|
||||
// /// 获取任务列表,默认会实现 TestOnline任务,SetDeviceStatus任务以及 VariableSourceRead等任务,VariableSourceRead任务启用条件为<see cref="VariableSourceReadsEnable"/> 为true。任务即是timer实现,可通过<see cref="ScheduledTaskHelper.GetTask(string, Func{object?, CancellationToken, Task}, object?, TouchSocket.Core.ILog, CancellationToken)"/> 方法实现定时任务
|
||||
// /// </summary>
|
||||
// /// <param name="cancellationToken"></param>
|
||||
// /// <returns></returns>
|
||||
// protected override List<IScheduledTask> ProtectedGetTasks(CancellationToken cancellationToken)
|
||||
// {
|
||||
// return base.ProtectedGetTasks(cancellationToken);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 实现离线重连任务
|
||||
// /// </summary>
|
||||
// /// <param name="state"></param>
|
||||
// /// <param name="cancellationToken"></param>
|
||||
// /// <returns></returns>
|
||||
// protected override Task TestOnline(object? state, CancellationToken cancellationToken)
|
||||
// {
|
||||
// return base.TestOnline(state, cancellationToken);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 返回是否成功连接设备
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public override bool IsConnected()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 在变量发生组态变化后执行,默认会执行<see cref="ProtectedLoadSourceReadAsync"/> 方法,重新获取源读取变量列表,并且重新启动VariableSourceRead等任务
|
||||
// /// </summary>
|
||||
// /// <param name="cancellationToken"></param>
|
||||
// /// <returns></returns>
|
||||
// public override Task AfterVariablesChangedAsync(CancellationToken cancellationToken)
|
||||
// {
|
||||
// return base.AfterVariablesChangedAsync(cancellationToken);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 变量寄存器的字符串描述
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public override string GetAddressDescription()
|
||||
// {
|
||||
// return base.GetAddressDescription();
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 设备暂停时执行,默认会暂停所有任务
|
||||
// /// </summary>
|
||||
// /// <param name="pause"></param>
|
||||
// public override void PauseThread(bool pause)
|
||||
// {
|
||||
// base.PauseThread(pause);
|
||||
// }
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 开始前执行
|
||||
// /// </summary>
|
||||
// protected override Task ProtectedBeforeStartAsync(CancellationToken cancellationToken)
|
||||
// protected override Task ProtectedStartAsync(CancellationToken cancellationToken)
|
||||
// {
|
||||
// //一般实现PLC长连接
|
||||
// return base.ProtectedBeforeStartAsync(cancellationToken);
|
||||
// return base.ProtectedStartAsync(cancellationToken);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 循环执行方法,父类会自动调用<see cref="ReadSourceAsync(VariableSourceRead, CancellationToken)"/>
|
||||
// /// <br></br>
|
||||
// /// 一般需要更新设备变量值,调用<see cref="VariableRuntime.SetValue(object?, DateTime, bool)"/>
|
||||
// /// <br></br>
|
||||
// /// 通讯失败时,更新设备状态,调用<see cref="DeviceRuntime.SetDeviceStatus(DateTime?, int?, string)"/>
|
||||
// /// <br></br>
|
||||
// /// </summary>
|
||||
// protected override Task ProtectedExecuteAsync(CancellationToken cancellationToken)
|
||||
// {
|
||||
// return base.ProtectedExecuteAsync(cancellationToken);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 写入变量,实现设备写入操作
|
||||
// /// 写入变量,实现设备写入操作,注意执行写锁,using var writeLock = ReadWriteLock.WriterLock();
|
||||
// /// </summary>
|
||||
// protected override ValueTask<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<VariableRuntime, JToken> writeInfoLists, CancellationToken cancellationToken)
|
||||
// {
|
||||
@@ -84,7 +232,7 @@
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 读取源变量,如重写了<see cref="ProtectedExecuteAsync"/> ,此方法可能不会执行
|
||||
// /// 读取源变量,在<see cref="VariableSourceReadsEnable"/> 为true时,添加源读取任务,任务启动时会执行
|
||||
// /// 一般需要更新设备变量值,调用<see cref="VariableRuntime.SetValue(object?, DateTime, bool)"/>
|
||||
// /// </summary>
|
||||
// protected override ValueTask<OperResult<byte[]>> ReadSourceAsync(VariableSourceRead variableSourceRead, CancellationToken cancellationToken)
|
||||
@@ -103,7 +251,7 @@
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 特殊方法,添加<see cref="DynamicMethodAttribute"/> 特性
|
||||
// /// 特殊方法,添加<see cref="DynamicMethodAttribute"/> 特性 ,返回IOperResult
|
||||
// /// 支持<see cref="CancellationToken"/> 参数,需放到最后
|
||||
// /// 默认解析方式为英文分号
|
||||
// /// 比如rpc参数为 test1;test2,解析query1="test1",query2="test2"
|
||||
@@ -119,7 +267,7 @@
|
||||
///// <summary>
|
||||
///// 插件类配置
|
||||
///// </summary>
|
||||
//public class TestCollectProperty : CollectPropertyBase
|
||||
//public class TestCollectProperty1 : CollectPropertyBase
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 添加<see cref="DynamicPropertyAttribute"/> 特性,如需多语言配置,可添加json资源,参考其他插件
|
||||
|
Reference in New Issue
Block a user