mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-26 05:20:16 +08:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e06f19bbc | ||
|
|
0b66c1f0d6 | ||
|
|
ff2742ffd8 | ||
|
|
70c2992a5f | ||
|
|
4ac4ee6874 | ||
|
|
865164a404 | ||
|
|
f9c8069ab2 | ||
|
|
2fbf5140e5 | ||
|
|
0126f8144a | ||
|
|
71383d7482 | ||
|
|
4d3bfc5f42 | ||
|
|
c173d217de | ||
|
|
d2da9a039f | ||
|
|
c915edd458 | ||
|
|
504948452e | ||
|
|
3daa6c7a54 | ||
|
|
10cd1580a5 | ||
|
|
5b0876e106 | ||
|
|
cfcdeaff01 | ||
|
|
7c34f233fd | ||
|
|
686146a7d9 | ||
|
|
44732d5977 | ||
|
|
05c3794cf7 |
8
doc/build/404.html
vendored
8
doc/build/404.html
vendored
File diff suppressed because one or more lines are too long
1
doc/build/assets/js/9cabb813.83d75387.js
vendored
Normal file
1
doc/build/assets/js/9cabb813.83d75387.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
doc/build/assets/js/9cabb813.8aa3c0c0.js
vendored
1
doc/build/assets/js/9cabb813.8aa3c0c0.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
doc/build/docs/1/index.html
vendored
8
doc/build/docs/1/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/100/index.html
vendored
8
doc/build/docs/100/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/1000/index.html
vendored
8
doc/build/docs/1000/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/10001/index.html
vendored
8
doc/build/docs/10001/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/1001/index.html
vendored
8
doc/build/docs/1001/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/1002/index.html
vendored
8
doc/build/docs/1002/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/101/index.html
vendored
8
doc/build/docs/101/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/102/index.html
vendored
8
doc/build/docs/102/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/103/index.html
vendored
8
doc/build/docs/103/index.html
vendored
File diff suppressed because one or more lines are too long
10
doc/build/docs/104/index.html
vendored
10
doc/build/docs/104/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/105/index.html
vendored
8
doc/build/docs/105/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/106/index.html
vendored
8
doc/build/docs/106/index.html
vendored
File diff suppressed because one or more lines are too long
10
doc/build/docs/2/index.html
vendored
10
doc/build/docs/2/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/200/index.html
vendored
8
doc/build/docs/200/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/20001/index.html
vendored
8
doc/build/docs/20001/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/20002/index.html
vendored
8
doc/build/docs/20002/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/20003/index.html
vendored
8
doc/build/docs/20003/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/20004/index.html
vendored
8
doc/build/docs/20004/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/20005/index.html
vendored
8
doc/build/docs/20005/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/201/index.html
vendored
8
doc/build/docs/201/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/202/index.html
vendored
8
doc/build/docs/202/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/203/index.html
vendored
8
doc/build/docs/203/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/204/index.html
vendored
8
doc/build/docs/204/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/205/index.html
vendored
8
doc/build/docs/205/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/206/index.html
vendored
8
doc/build/docs/206/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/301/index.html
vendored
8
doc/build/docs/301/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/302/index.html
vendored
8
doc/build/docs/302/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/303/index.html
vendored
8
doc/build/docs/303/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/304/index.html
vendored
8
doc/build/docs/304/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/305/index.html
vendored
8
doc/build/docs/305/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/306/index.html
vendored
8
doc/build/docs/306/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/307/index.html
vendored
8
doc/build/docs/307/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/308/index.html
vendored
8
doc/build/docs/308/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/309/index.html
vendored
8
doc/build/docs/309/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/400/index.html
vendored
8
doc/build/docs/400/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/401/index.html
vendored
8
doc/build/docs/401/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/402/index.html
vendored
8
doc/build/docs/402/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/403/index.html
vendored
8
doc/build/docs/403/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/404/index.html
vendored
8
doc/build/docs/404/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/501/index.html
vendored
8
doc/build/docs/501/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/502/index.html
vendored
8
doc/build/docs/502/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/601/index.html
vendored
8
doc/build/docs/601/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/602/index.html
vendored
8
doc/build/docs/602/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/index.html
vendored
8
doc/build/docs/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/docs/upgrade/index.html
vendored
8
doc/build/docs/upgrade/index.html
vendored
File diff suppressed because one or more lines are too long
8
doc/build/index.html
vendored
8
doc/build/index.html
vendored
File diff suppressed because one or more lines are too long
2
doc/build/search-index.json
vendored
2
doc/build/search-index.json
vendored
File diff suppressed because one or more lines are too long
8
doc/build/search/index.html
vendored
8
doc/build/search/index.html
vendored
File diff suppressed because one or more lines are too long
@@ -115,6 +115,16 @@ arraylen=2;
|
||||
|报警文本| 对应显示的报警文本 ||
|
||||
|报警约束| 动态解析的表达式 ,原始值的代码为raw,计算值为true时才能产生报警 ||
|
||||
|
||||
:::tip `例子`
|
||||
|
||||
数值高高报警
|
||||
|
||||
变量值大于报警限值,并且报警约束为true或者报警约束不存在时,产生报警
|
||||
|
||||
比如设置高高限值为1,其他默认,当变量值大于1时,产生报警
|
||||
|
||||
:::
|
||||
|
||||
|
||||
### 业务属性配置项
|
||||
<img src={require("@site/static/img/docs/添加变量2.png").default} />
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<LangVersion>11.0</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>5.0.0.2</Version>
|
||||
<Version>5.0.0.5</Version>
|
||||
<Authors>Diego</Authors>
|
||||
<Company>Diego</Company>
|
||||
<Product>Diego</Product>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// SignalR消息
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 会话信息
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// SqlSugar系统常量
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 主键id基类
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 实体种子数据接口
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Linq分页泛型集合
|
||||
|
||||
@@ -115,7 +115,7 @@ public static class ObjectExtension
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="generic">泛型类型</param>
|
||||
/// <returns>bool</returns>
|
||||
internal static bool HasImplementedRawGeneric(this Type type, Type generic)
|
||||
public static bool HasImplementedRawGeneric(this Type type, Type generic)
|
||||
{
|
||||
// 检查接口类型
|
||||
var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Sqlsugar分页拓展类
|
||||
|
||||
@@ -24,6 +24,4 @@ global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Threading.Tasks;
|
||||
|
||||
global using ThingsGateway.Admin.Application;
|
||||
global using ThingsGateway.Admin.Core;
|
||||
global using ThingsGateway.Core;
|
||||
@@ -20,7 +20,7 @@ using ThingsGateway.Core.Extension;
|
||||
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库上下文对象
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 仓储模式对象
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
using Furion.ConfigurableOptions;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化表配置
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.1" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.136" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.137" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// CodeFirst功能类
|
||||
@@ -109,32 +109,6 @@ public static class CodeFirstUtils
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断类型是否实现某个泛型
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="generic">泛型类型</param>
|
||||
/// <returns>bool</returns>
|
||||
public static bool HasImplementedRawGeneric(this Type type, Type generic)
|
||||
{
|
||||
// 检查接口类型
|
||||
var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
|
||||
if (isTheRawGenericType) return true;
|
||||
|
||||
// 检查类型
|
||||
while (type != null && type != typeof(object))
|
||||
{
|
||||
isTheRawGenericType = IsTheRawGenericType(type);
|
||||
if (isTheRawGenericType) return true;
|
||||
type = type.BaseType ?? default;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
// 判断逻辑
|
||||
bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 排除SqlSugar忽略的列
|
||||
/// </summary>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
using NewLife.Serialization;
|
||||
|
||||
namespace ThingsGateway.Admin.Application;
|
||||
namespace ThingsGateway.Admin.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 种子数据工具类
|
||||
|
||||
@@ -23,6 +23,13 @@ namespace ThingsGateway.Cache;
|
||||
/// </summary>
|
||||
public class LiteDBDefalutCacheItem<T> : IPrimaryIdEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// LiteDBDefalutCacheItem
|
||||
/// </summary>
|
||||
public LiteDBDefalutCacheItem()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LiteDBDefalutCacheItem
|
||||
/// </summary>
|
||||
|
||||
@@ -157,14 +157,19 @@ public partial class AdapterDebugPage : AdapterDebugBase
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = TextFileReader.LastLog(files.FirstOrDefault().FullName, 0);
|
||||
if (result.IsSuccess)
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Messages = result.Content.Select(a => ((int)a.LogLevel, $"{a.LogTime} - {a.Message} {Environment.NewLine} {a.ExceptionString}")).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
var result = TextFileReader.LastLog(files.FirstOrDefault().FullName, 0);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Messages = result.Content.Select(a => ((int)a.LogLevel, $"{a.LogTime} - {a.Message}")).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages = new List<(int, string)>();
|
||||
}
|
||||
});
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Components;
|
||||
using ThingsGateway.Foundation;
|
||||
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
namespace ThingsGateway.Demo
|
||||
{
|
||||
@@ -34,6 +35,7 @@ namespace ThingsGateway.Demo
|
||||
{
|
||||
if (ChannelData != item.Item)
|
||||
{
|
||||
ChannelData?.Channel?.Close();
|
||||
ChannelData = item.Item;
|
||||
await OnEditClick.InvokeAsync(ChannelData);
|
||||
}
|
||||
@@ -48,6 +50,7 @@ namespace ThingsGateway.Demo
|
||||
{
|
||||
if (ChannelData != channelData)
|
||||
{
|
||||
ChannelData?.Channel?.Close();
|
||||
ChannelData = channelData;
|
||||
ChannelConfigs.Default.Save(true, out _);
|
||||
await OnEditClick.InvokeAsync(ChannelData);
|
||||
@@ -59,6 +62,7 @@ namespace ThingsGateway.Demo
|
||||
{
|
||||
try
|
||||
{
|
||||
ChannelData?.Channel?.Close();
|
||||
ChannelConfigs.Default.ChannelDatas.Remove(ChannelData);
|
||||
ChannelData = null;
|
||||
ChannelName = null;
|
||||
@@ -95,6 +99,7 @@ namespace ThingsGateway.Demo
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
ChannelData?.Channel?.Close();
|
||||
ChannelConfigs.Default.ChannelDatas.Remove(ChannelData);
|
||||
ChannelData = (ChannelData)data;
|
||||
ChannelData.CreateChannel(ChannelData);
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:150px" Dense HideDetails="@("auto")"
|
||||
Label=@(AppService.I18n.T(_plc.Description(x => x.Password))) @bind-Value=@_plc.Password></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:150px" Dense HideDetails="@("auto")"
|
||||
Label=@(AppService.I18n.T(_plc.Description(x => x.HeartbeatHexString))) @bind-Value=@_plc.HeartbeatHexString></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px"
|
||||
@bind-Value="_plc.DataFormat" Label="@(AppService.I18n.T(_plc.Description(x => x.DataFormat)))"
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:150px" Dense HideDetails="@("auto")"
|
||||
Label=@(AppService.I18n.T(_plc.Description(x => x.Station))) @bind-Value=@_plc.Station></MTextField>
|
||||
<MTextField Class="ma-1" Outlined Style="max-width:150px" Dense HideDetails="@("auto")"
|
||||
Label=@(AppService.I18n.T(_plc.Description(x => x.HeartbeatHexString))) @bind-Value=@_plc.HeartbeatHexString></MTextField>
|
||||
|
||||
<MSelect Class="ma-1" Outlined Style="max-width:200px"
|
||||
@bind-Value="_plc.DataFormat" Label="@(AppService.I18n.T(_plc.Description(x => x.DataFormat)))"
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<ProjectReference Include="..\foundation\ThingsGateway.Foundation.OpcDa\src\ThingsGateway.Foundation.OpcDa.csproj" />
|
||||
<ProjectReference Include="..\foundation\ThingsGateway.Foundation.OpcUa\src\ThingsGateway.Foundation.OpcUa.csproj" />
|
||||
<ProjectReference Include="..\foundation\ThingsGateway.Foundation.SiemensS7\src\ThingsGateway.Foundation.SiemensS7.csproj" />
|
||||
<ProjectReference Include="..\foundation\ThingsGateway.Foundation\src\ThingsGateway.Foundation.csproj" />
|
||||
<ProjectReference Include="..\ThingsGateway.Components\ThingsGateway.Components.csproj" />
|
||||
<ProjectReference Include="..\ThingsGateway.Core\ThingsGateway.Core.csproj" />
|
||||
</ItemGroup>
|
||||
@@ -47,9 +46,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Service\" />
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,5 +2,8 @@
|
||||
"HardwareInfo": {
|
||||
"Enable": true, //启用硬件信息获取
|
||||
"TimeInterval": 10000 //更新间隔ms
|
||||
},
|
||||
"ChannelThread": {
|
||||
"CycleInterval": 20 //最小循环间隔
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,8 @@
|
||||
"HardwareInfo": {
|
||||
"Enable": true, //启用硬件信息获取
|
||||
"TimeInterval": 10000 //更新间隔ms
|
||||
},
|
||||
"ChannelThread": {
|
||||
"CycleInterval": 20 //最小循环间隔
|
||||
}
|
||||
}
|
||||
@@ -173,6 +173,7 @@ public class VariableRunTime : Variable, IVariable
|
||||
{
|
||||
IsOnline = false;
|
||||
Set(null);
|
||||
VariableSource.LastErrorMessage = $"{Name} 转换表达式失败:{ex.Message}";
|
||||
return new($"{Name} 转换表达式失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,13 @@ public class ChannelThread
|
||||
/// <summary>
|
||||
/// 线程最小等待间隔时间
|
||||
/// </summary>
|
||||
public const int CycleInterval = 10;
|
||||
public static volatile int CycleInterval = 10;
|
||||
|
||||
static ChannelThread()
|
||||
{
|
||||
var cycleInterval = App.GetConfig<int?>("ChannelThread:CycleInterval") ?? 10;
|
||||
CycleInterval = cycleInterval < 10 ? 10 : cycleInterval;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="TouchSocket.Core.TouchSocketConfig"/>
|
||||
|
||||
@@ -449,7 +449,7 @@ public class PluginService : IPluginService
|
||||
foreach (var item in plugin.OtherFiles ?? new())
|
||||
{
|
||||
using var otherStream = item.OpenReadStream(maxFileSize);
|
||||
using MemoryStream memoryStream1 = new MemoryStream();
|
||||
MemoryStream memoryStream1 = new MemoryStream();
|
||||
await otherStream.CopyToAsync(memoryStream1);
|
||||
memoryStream1.Seek(0, SeekOrigin.Begin);
|
||||
otherFilesStreams.Add((item.Name, memoryStream1));
|
||||
@@ -491,6 +491,7 @@ public class PluginService : IPluginService
|
||||
item.Item2.Seek(0, SeekOrigin.Begin);
|
||||
using FileStream fs1 = new(fullDir.CombinePathOS(item.Item1), FileMode.Create);
|
||||
await item.Item2.CopyToAsync(fs1);
|
||||
await item.Item2.DisposeAsync();
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SqlSugar.TDengineCore" Version="4.1.6">
|
||||
<Private>false</Private>
|
||||
<IncludeAssets> native;build;runtime </IncludeAssets>
|
||||
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -117,7 +117,6 @@ public class AlarmWorker : BackgroundService
|
||||
device.VariableRunTimes?.ForEach(v => { v.VariableCollectChange -= DeviceVariableChange; });
|
||||
}
|
||||
|
||||
|
||||
StoppingTokens.ParallelForEach(cancellationToken =>
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
|
||||
@@ -78,6 +78,8 @@ public class CollectDeviceWorker : DeviceWorker
|
||||
var businessDeviceHostService = WorkerUtil.GetWoker<BusinessDeviceWorker>();
|
||||
await businessDeviceHostService.StartAsync();
|
||||
await alarmHostService.StartAsync();
|
||||
if (Start != null)
|
||||
await Start.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -89,6 +91,8 @@ public class CollectDeviceWorker : DeviceWorker
|
||||
var businessDeviceHostService = WorkerUtil.GetWoker<BusinessDeviceWorker>();
|
||||
await alarmHostService.StopAsync();
|
||||
await businessDeviceHostService.StopAsync();
|
||||
if (Stop != null)
|
||||
await Stop.Invoke();
|
||||
}
|
||||
|
||||
#endregion public 设备创建更新结束
|
||||
@@ -161,4 +165,9 @@ public class CollectDeviceWorker : DeviceWorker
|
||||
}
|
||||
|
||||
#endregion worker服务
|
||||
}
|
||||
|
||||
public event RestartEventHandler Stop;
|
||||
public event RestartEventHandler Start;
|
||||
}
|
||||
|
||||
public delegate Task RestartEventHandler();
|
||||
@@ -30,7 +30,7 @@ public partial class DeviceStatus
|
||||
try
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
Execute();
|
||||
await Execute();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -76,12 +76,12 @@ public partial class DeviceStatus
|
||||
private RenderFragment _driverRender;
|
||||
private object _importRef;
|
||||
|
||||
private void DeviceInfoOnClick(DriverBase item)
|
||||
private async void DeviceInfoOnClick(DriverBase item)
|
||||
{
|
||||
if (_driverBaseItem != item)
|
||||
{
|
||||
_driverBaseItem = item;
|
||||
Execute();
|
||||
await Execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ public partial class DeviceStatus
|
||||
|
||||
private List<(int, string)> Messages { get; set; } = new List<(int, string)>();
|
||||
|
||||
protected void Execute()
|
||||
protected async Task Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -180,6 +180,7 @@ public partial class DeviceStatus
|
||||
{
|
||||
Messages = new List<(int, string)>();
|
||||
}
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"ConfigurationScanDirectories": [ "Config" ],
|
||||
|
||||
"Urls": "http://0.0.0.0:7200" //监听地址
|
||||
"Urls": "http://0.0.0.0:7200", //监听地址
|
||||
"DetailedErrors": true
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"ConfigurationScanDirectories": [ "Config" ],
|
||||
|
||||
"Urls": "http://0.0.0.0:7200" //监听地址
|
||||
"Urls": "http://0.0.0.0:7200", //监听地址
|
||||
}
|
||||
@@ -35,14 +35,4 @@ public class DltConst
|
||||
00010000 (当前)正向有功总电能
|
||||
"""
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Dtu-{0}-已连接
|
||||
/// </summary>
|
||||
public const string DtuConnected = "Dtu-{0}-Connected.";
|
||||
|
||||
/// <summary>
|
||||
/// 客户端未连接,或寄存器设置错误,必须设置ID={DTU注册包}
|
||||
/// </summary>
|
||||
public const string DtuNoConnectedWaining = "The client is not connected or the register is set incorrectly. id={Dtu registration package} must be set.";
|
||||
}
|
||||
@@ -85,20 +85,6 @@ public class Dlt645_2007BitConverter : ThingsGatewayBitConverter
|
||||
return Convert.ToDouble(this.ToString(buffer, offset, buffer.Length));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IThingsGatewayBitConverter CopyNew()
|
||||
{
|
||||
return new Dlt645_2007BitConverter(EndianType)
|
||||
{
|
||||
DataFormat = DataFormat,
|
||||
BcdFormat = BcdFormat,
|
||||
Encoding = Encoding,
|
||||
IsStringReverseByteWord = IsStringReverseByteWord,
|
||||
StringLength = StringLength,
|
||||
ArrayLength = ArrayLength,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString(byte[] buffer)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,14 @@ internal class Dlt645_2007Message : MessageBase, IMessage
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
if (SendBytes?.Length > 0)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;//不是主动请求的,可能是心跳DTU包,直接放弃
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,12 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
[Description("自动断开连接")]
|
||||
public bool CheckClear { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 心跳检测(大写16进制字符串)
|
||||
/// </summary>
|
||||
[Description("心跳检测")]
|
||||
public string HeartbeatHexString { get; set; } = "FFFF8080";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
@@ -77,7 +83,7 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
switch (Channel.ChannelType)
|
||||
{
|
||||
case ChannelTypeEnum.TcpService:
|
||||
Action<IPluginManager> action = null;
|
||||
Action<IPluginManager> action = a => { };
|
||||
if (CheckClear)
|
||||
{
|
||||
action = a => a.UseCheckClear()
|
||||
@@ -89,16 +95,11 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
c.SafeClose("超时清理");
|
||||
});
|
||||
}
|
||||
if (action == null)
|
||||
action = a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
else
|
||||
action += a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
|
||||
action += a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
return action;
|
||||
}
|
||||
return base.ConfigurePlugins();
|
||||
@@ -164,7 +165,7 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
return new();
|
||||
}
|
||||
else
|
||||
return new OperResult<byte[]>(DltConst.DtuNoConnectedWaining);
|
||||
return new OperResult<byte[]>(FoundationConst.DtuNoConnectedWaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -181,7 +182,7 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
if (((TcpServiceBase)Channel).SocketClients.TryGetSocketClient($"ID={mAddress.SocketId}", out TgSocketClient? client))
|
||||
return SendThenReturn(new SendMessage(commandResult), cancellationToken, client);
|
||||
else
|
||||
return new OperResult<byte[]>(DltConst.DtuNoConnectedWaining);
|
||||
return new OperResult<byte[]>(FoundationConst.DtuNoConnectedWaining);
|
||||
}
|
||||
else
|
||||
return SendThenReturn(new SendMessage(commandResult), cancellationToken);
|
||||
@@ -225,7 +226,7 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
if (((TcpServiceBase)Channel).SocketClients.TryGetSocketClient($"ID={mAddress.SocketId}", out TgSocketClient? client))
|
||||
return SendThenReturnAsync(new SendMessage(commandResult), cancellationToken, client);
|
||||
else
|
||||
return Task.FromResult(new OperResult<byte[]>(DltConst.DtuNoConnectedWaining));
|
||||
return Task.FromResult(new OperResult<byte[]>(FoundationConst.DtuNoConnectedWaining));
|
||||
}
|
||||
else
|
||||
return SendThenReturnAsync(new SendMessage(commandResult), cancellationToken);
|
||||
@@ -475,17 +476,30 @@ public class Dlt645_2007Master : ProtocolBase
|
||||
[PluginOption(Singleton = true)]
|
||||
internal class DtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
{
|
||||
private Dlt645_2007Master _dlt645_2007Master;
|
||||
|
||||
public DtuPlugin(Dlt645_2007Master dlt645_2007Master)
|
||||
{
|
||||
_dlt645_2007Master = dlt645_2007Master;
|
||||
}
|
||||
|
||||
public async Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e)
|
||||
{
|
||||
if (client is ISocketClient socket)
|
||||
{
|
||||
var bytes = e.ByteBlock.ToArray();
|
||||
if (!socket.Id.StartsWith("ID="))
|
||||
{
|
||||
ByteBlock byteBlock = e.ByteBlock;
|
||||
var id = $"ID={Encoding.UTF8.GetString(byteBlock.ToArray())}";
|
||||
client.Logger.Info(string.Format(DltConst.DtuConnected, id));
|
||||
var id = $"ID={Encoding.UTF8.GetString(bytes)}";
|
||||
client.Logger.Info(string.Format(FoundationConst.DtuConnected, id));
|
||||
socket.ResetId(id);
|
||||
}
|
||||
if (_dlt645_2007Master.HeartbeatHexString == bytes.ToHexString())
|
||||
{
|
||||
//回应心跳包
|
||||
socket.DefaultSend(bytes);
|
||||
socket.Logger?.Trace($"{socket.ToString()}- {FoundationConst.Send}:{bytes.ToHexString(' ')}");
|
||||
}
|
||||
}
|
||||
await e.InvokeNext();//如果本插件无法处理当前数据,请将数据转至下一个插件。
|
||||
}
|
||||
|
||||
@@ -35,16 +35,6 @@ public class ModbusConst
|
||||
"""
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Dtu-{0}-已连接
|
||||
/// </summary>
|
||||
public const string DtuConnected = "Dtu-{0}-Connected.";
|
||||
|
||||
/// <summary>
|
||||
/// 客户端未连接,或寄存器设置错误,必须设置ID={DTU注册包}
|
||||
/// </summary>
|
||||
public const string DtuNoConnectedWaining = "The client is not connected or the register is set incorrectly. id={Dtu registration package} must be set.";
|
||||
|
||||
/// <summary>
|
||||
/// 功能码错误
|
||||
/// </summary>
|
||||
|
||||
@@ -25,7 +25,14 @@ internal class ModbusRtuMessage : MessageBase, IMessage
|
||||
/// <inheritdoc/>
|
||||
public override bool CheckHeadBytes(byte[] heads)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
if (SendBytes?.Length > 0)
|
||||
{
|
||||
BodyLength = -1;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;//不是主动请求的,可能是心跳DTU包,直接放弃
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,7 @@ internal class ModbusTcpMessage : MessageBase, IMessage
|
||||
BodyLength = num;
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,12 @@ public class ModbusMaster : ProtocolBase
|
||||
[Description("自动断开连接")]
|
||||
public bool CheckClear { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 心跳检测(大写16进制字符串)
|
||||
/// </summary>
|
||||
[Description("心跳检测")]
|
||||
public string HeartbeatHexString { get; set; } = "FFFF8080";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetAddressDescription()
|
||||
{
|
||||
@@ -88,7 +94,7 @@ public class ModbusMaster : ProtocolBase
|
||||
switch (Channel.ChannelType)
|
||||
{
|
||||
case ChannelTypeEnum.TcpService:
|
||||
Action<IPluginManager> action = null;
|
||||
Action<IPluginManager> action = a => { };
|
||||
if (CheckClear)
|
||||
{
|
||||
action = a => a.UseCheckClear()
|
||||
@@ -100,16 +106,12 @@ public class ModbusMaster : ProtocolBase
|
||||
c.SafeClose("超时清理");
|
||||
});
|
||||
}
|
||||
if (action == null)
|
||||
action = a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
else
|
||||
action += a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
|
||||
action += a =>
|
||||
{
|
||||
DtuPlugin dtuPlugin = new(this);
|
||||
a.Add(dtuPlugin);
|
||||
};
|
||||
return action;
|
||||
}
|
||||
return base.ConfigurePlugins();
|
||||
@@ -191,7 +193,7 @@ public class ModbusMaster : ProtocolBase
|
||||
if (((TcpServiceBase)Channel).SocketClients.TryGetSocketClient($"ID={mAddress.SocketId}", out TgSocketClient? client))
|
||||
return SendThenReturn(new SendMessage(commandResult), cancellationToken, client);
|
||||
else
|
||||
return new OperResult<byte[]>(ModbusConst.DtuNoConnectedWaining);
|
||||
return new OperResult<byte[]>(FoundationConst.DtuNoConnectedWaining);
|
||||
}
|
||||
else
|
||||
return SendThenReturn(new SendMessage(commandResult), cancellationToken);
|
||||
@@ -219,7 +221,7 @@ public class ModbusMaster : ProtocolBase
|
||||
if (((TcpServiceBase)Channel).SocketClients.TryGetSocketClient($"ID={mAddress.SocketId}", out TgSocketClient? client))
|
||||
return SendThenReturnAsync(new SendMessage(commandResult), cancellationToken, client);
|
||||
else
|
||||
return Task.FromResult(new OperResult<byte[]>(ModbusConst.DtuNoConnectedWaining));
|
||||
return Task.FromResult(new OperResult<byte[]>(FoundationConst.DtuNoConnectedWaining));
|
||||
}
|
||||
else
|
||||
return SendThenReturnAsync(new SendMessage(commandResult), cancellationToken);
|
||||
@@ -344,17 +346,30 @@ public class ModbusMaster : ProtocolBase
|
||||
[PluginOption(Singleton = true)]
|
||||
internal class DtuPlugin : PluginBase, ITcpReceivingPlugin
|
||||
{
|
||||
private ModbusMaster _modbusMaster;
|
||||
|
||||
public DtuPlugin(ModbusMaster modbusMaster)
|
||||
{
|
||||
this._modbusMaster = modbusMaster;
|
||||
}
|
||||
|
||||
public async Task OnTcpReceiving(ITcpClientBase client, ByteBlockEventArgs e)
|
||||
{
|
||||
if (client is ISocketClient socket)
|
||||
{
|
||||
var bytes = e.ByteBlock.ToArray();
|
||||
if (!socket.Id.StartsWith("ID="))
|
||||
{
|
||||
ByteBlock byteBlock = e.ByteBlock;
|
||||
var id = $"ID={Encoding.UTF8.GetString(byteBlock.ToArray())}";
|
||||
client.Logger.Info(string.Format(ModbusConst.DtuConnected, id));
|
||||
var id = $"ID={Encoding.UTF8.GetString(bytes)}";
|
||||
client.Logger.Info(string.Format(FoundationConst.DtuConnected, id));
|
||||
socket.ResetId(id);
|
||||
}
|
||||
if (_modbusMaster.HeartbeatHexString == bytes.ToHexString())
|
||||
{
|
||||
//回应心跳包
|
||||
socket.DefaultSend(bytes);
|
||||
socket.Logger?.Trace($"{socket.ToString()}- {FoundationConst.Send}:{bytes.ToHexString(' ')}");
|
||||
}
|
||||
}
|
||||
await e.InvokeNext();//如果本插件无法处理当前数据,请将数据转至下一个插件。
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public class ModbusSlave : ProtocolBase
|
||||
switch (Channel.ChannelType)
|
||||
{
|
||||
case ChannelTypeEnum.TcpService:
|
||||
Action<IPluginManager> action = null;
|
||||
Action<IPluginManager> action = a => { };
|
||||
if (CheckClear)
|
||||
{
|
||||
action = a => a.UseCheckClear()
|
||||
@@ -132,16 +132,7 @@ public class ModbusSlave : ProtocolBase
|
||||
c.SafeClose("超时清理");
|
||||
});
|
||||
}
|
||||
if (action == null)
|
||||
action = a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
else
|
||||
action += a =>
|
||||
{
|
||||
a.Add<DtuPlugin>();
|
||||
};
|
||||
|
||||
return action;
|
||||
}
|
||||
return base.ConfigurePlugins();
|
||||
|
||||
@@ -356,6 +356,7 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
if (!result2.IsSuccess)
|
||||
{
|
||||
Logger?.LogWarning($"{channel.ToString()}:PDU初始化失败-{result2.ErrorMessage},请检查机架号/槽号是否正确");
|
||||
channel.Close();
|
||||
return;
|
||||
}
|
||||
PduLength = ThingsGatewayBitConverter.ToUInt16(result2.Content.SelectLast(2), 0);
|
||||
@@ -364,11 +365,13 @@ public partial class SiemensS7Master : ProtocolBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.LogWarning($"{channel.ToString()}:PDU初始化失败-{ex.Message},请检查机架号/槽号是否正确");
|
||||
channel.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
channel.Close();
|
||||
Logger.Exception(ex);
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace ThingsGateway.Foundation
|
||||
{
|
||||
base.Stop();
|
||||
if (Monitor == null)
|
||||
Logger.Info($"{Monitor.IPHost}{FoundationConst.ServiceStoped}");
|
||||
Logger.Info($"{Monitor?.IPHost}{FoundationConst.ServiceStoped}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user