Compare commits
37 Commits
master
...
zhy_feat_d
| Author | SHA1 | Date | |
|---|---|---|---|
| 179b9a2e91 | |||
| 87bf7feff2 | |||
| 8b33ec5400 | |||
| 2d2245fa85 | |||
|
|
4a609b6cf8 | ||
|
|
72c50311b6 | ||
| 7dd833257a | |||
| c999b0a0a9 | |||
| 679086b174 | |||
| db8b0e0b23 | |||
| dbb31d1c60 | |||
| f4b7afae48 | |||
|
|
6393db4dc6 | ||
| 86da556e98 | |||
| 95712c4c0e | |||
|
|
54c1643015 | ||
| f746d84225 | |||
|
|
71a5f7b89b | ||
|
|
91602a95c6 | ||
| 2d2bb0dcc0 | |||
| 2ead6e8242 | |||
| 6adbfe7883 | |||
| 76019141f1 | |||
|
|
27b7452cd1 | ||
|
|
6bc3b31f81 | ||
| ee1f3e3ca9 | |||
| 5d7e7bd7ed | |||
|
|
7a7a68b326 | ||
|
|
4ce1741f7e | ||
| 469ea285f2 | |||
| 3d83cf0ccb | |||
| 6ff97c1c0f | |||
| 77eabfec5d | |||
|
|
e806a127bf | ||
|
|
a78b819233 | ||
| d9491b9b33 | |||
| ead03c6361 |
12
Dockerfile
12
Dockerfile
@ -1,7 +1,7 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 8080
|
||||||
EXPOSE 443
|
EXPOSE 10500
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
ENV ASPNETCORE_ENVIRONMENT=Production
|
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
|
||||||
@ -38,15 +38,7 @@ RUN mkdir -p /app/Plugins
|
|||||||
# 复制发布内容
|
# 复制发布内容
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
|
|
||||||
# 健康检查
|
|
||||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
|
||||||
CMD curl -f http://localhost:80/health || exit 1
|
|
||||||
|
|
||||||
# 设置入口点
|
# 设置入口点
|
||||||
ENTRYPOINT ["dotnet", "JiShe.CollectBus.Host.dll"]
|
ENTRYPOINT ["dotnet", "JiShe.CollectBus.Host.dll"]
|
||||||
|
|
||||||
# 启动命令
|
|
||||||
# 可选:添加命令行参数
|
|
||||||
# CMD ["--urls", "http://+:80"]
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -385,6 +385,20 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
return Activator.CreateInstance(accessorType)!;
|
return Activator.CreateInstance(accessorType)!;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object GetAccessor(Type type)
|
||||||
|
{
|
||||||
|
MethodInfo getAccessorMethod = typeof(SourceEntityAccessorFactory)
|
||||||
|
.GetMethod(
|
||||||
|
name: nameof(GetAccessor),
|
||||||
|
bindingAttr: BindingFlags.Public | BindingFlags.Static,
|
||||||
|
|
||||||
|
types: Type.EmptyTypes
|
||||||
|
);
|
||||||
|
|
||||||
|
MethodInfo genericMethod = getAccessorMethod.MakeGenericMethod(type);
|
||||||
|
return genericMethod.Invoke(null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
namespace JiShe.CollectBus.IoTDB.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 需要忽略表模型初始化,有此特性无需初始化
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public class IgnoreInitTableAttribute : System.Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
public IgnoreInitTableAttribute()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,12 +10,11 @@ namespace JiShe.CollectBus.IoTDB.Interface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IIoTDbProvider
|
public interface IIoTDbProvider
|
||||||
{
|
{
|
||||||
///// <summary>
|
/// <summary>
|
||||||
///// 切换 SessionPool
|
/// 切换 SessionPool
|
||||||
///// </summary>
|
/// </summary>
|
||||||
///// <param name="useTableSession">是否使用表模型</param>
|
/// <param name="sessionpolType">是否使用表模型</param>
|
||||||
//void SwitchSessionPool(bool useTableSession);
|
/// <returns></returns>
|
||||||
|
|
||||||
IIoTDbProvider GetSessionPool(bool sessionpolType);
|
IIoTDbProvider GetSessionPool(bool sessionpolType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -66,5 +65,11 @@ namespace JiShe.CollectBus.IoTDB.Interface
|
|||||||
/// <param name="options"></param>
|
/// <param name="options"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<BusPagedResult<T>> QueryAsync<T>(IoTDBQueryOptions options) where T : IoTEntity, new();
|
Task<BusPagedResult<T>> QueryAsync<T>(IoTDBQueryOptions options) where T : IoTEntity, new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化表模型
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task InitTableSessionModelAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,5 +32,12 @@ namespace JiShe.CollectBus.IoTDB.Interface
|
|||||||
/// <param name="sql"></param>
|
/// <param name="sql"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<SessionDataSet> ExecuteQueryStatementAsync(string sql);
|
Task<SessionDataSet> ExecuteQueryStatementAsync(string sql);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行无返回结果SQL
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sql"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> ExecuteNonQueryStatementAsync(string sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ namespace JiShe.CollectBus.IoTDB.Model
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private string _devicePath;
|
private string _devicePath;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备路径
|
/// 设备路径,树模型使用,表模型会在数据插入的时候直接获取继承类的名称作为表明
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string DevicePath
|
public virtual string DevicePath
|
||||||
{
|
{
|
||||||
|
|||||||
@ -7,6 +7,7 @@ namespace JiShe.CollectBus.IoTDB.Model
|
|||||||
/// Table模型单项数据实体
|
/// Table模型单项数据实体
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SourceAnalyzers(EntityTypeEnum.TableModel)]
|
[SourceAnalyzers(EntityTypeEnum.TableModel)]
|
||||||
|
[IgnoreInitTable]
|
||||||
public class TableModelSingleMeasuringEntity<T> : IoTEntity
|
public class TableModelSingleMeasuringEntity<T> : IoTEntity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -26,6 +26,8 @@ using System.Diagnostics.Metrics;
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace JiShe.CollectBus.IoTDB.Provider
|
namespace JiShe.CollectBus.IoTDB.Provider
|
||||||
{
|
{
|
||||||
@ -86,7 +88,7 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
_logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 tablet 为null");
|
_logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 tablet 为null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 路径为 {tablet.First().InsertTargetName}");
|
_logger.LogWarning($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 路径为 {tablet.First().InsertTargetName}");
|
||||||
|
|
||||||
await CurrentSession.InsertAsync(tablet.First());
|
await CurrentSession.InsertAsync(tablet.First());
|
||||||
}
|
}
|
||||||
@ -127,7 +129,7 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
|
|
||||||
foreach (var item in tablet)
|
foreach (var item in tablet)
|
||||||
{
|
{
|
||||||
_logger.LogError($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 路径为 {item.InsertTargetName}");
|
_logger.LogWarning($"{nameof(InsertAsync)} IoTDB插入{typeof(T).Name}的数据时 路径为 {item.InsertTargetName}");
|
||||||
|
|
||||||
await CurrentSession.InsertAsync(item);
|
await CurrentSession.InsertAsync(item);
|
||||||
}
|
}
|
||||||
@ -366,6 +368,10 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
{
|
{
|
||||||
tableNameOrTreePath = metadata.TableNameOrTreePath;
|
tableNameOrTreePath = metadata.TableNameOrTreePath;
|
||||||
}
|
}
|
||||||
|
else if(metadata.IsSingleMeasuring && string.IsNullOrWhiteSpace(metadata.TableNameOrTreePath) == true)//单侧点时,且路径没有指定,取默认实体名称和第一个列名组合。
|
||||||
|
{
|
||||||
|
tableNameOrTreePath = $"{metadata.EntityName}_{metadata.ColumnNames.First()}";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tableNameOrTreePath = DevicePathBuilder.GetTableName<T>();
|
tableNameOrTreePath = DevicePathBuilder.GetTableName<T>();
|
||||||
@ -631,9 +637,6 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
// 过滤元组子项
|
// 过滤元组子项
|
||||||
if (member.NameOrPath.Contains(".Item")) continue;
|
if (member.NameOrPath.Contains(".Item")) continue;
|
||||||
|
|
||||||
// 类型名称处理
|
|
||||||
string declaredTypeName = member.DeclaredTypeName;
|
|
||||||
|
|
||||||
// 特性查询优化
|
// 特性查询优化
|
||||||
var attributes = member.CustomAttributes ?? Enumerable.Empty<Attribute>();
|
var attributes = member.CustomAttributes ?? Enumerable.Empty<Attribute>();
|
||||||
var tagAttr = attributes.OfType<TAGColumnAttribute>().FirstOrDefault();
|
var tagAttr = attributes.OfType<TAGColumnAttribute>().FirstOrDefault();
|
||||||
@ -842,6 +845,25 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理不同列类型的逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupedColumns"></param>
|
||||||
|
/// <param name="category"></param>
|
||||||
|
private string ProcessCategory(IReadOnlyDictionary<ColumnCategory, List<ColumnInfo>> groupedColumns, ColumnCategory category)
|
||||||
|
{
|
||||||
|
if (groupedColumns.TryGetValue(category, out var cols))
|
||||||
|
{
|
||||||
|
List<string> tempColumnInfos = new List<string>();
|
||||||
|
foreach (var item in cols)
|
||||||
|
{
|
||||||
|
tempColumnInfos.Add($" {item.Name} {item.DataType} {item.Category}");
|
||||||
|
}
|
||||||
|
return string.Join(",", tempColumnInfos);
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据列结构
|
/// 数据列结构
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -976,6 +998,136 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Regex _asciiAlphanumericRegex = new Regex(@"^[a-zA-Z0-9]*$", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化表模型
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task InitTableSessionModelAsync()
|
||||||
|
{
|
||||||
|
//获取JiShe.CollectBus.IoTDB程序集和JiShe.CollectBus.Domain程序集中的所有 [SourceAnalyzers(EntityTypeEnum.TableModel)] 的实体
|
||||||
|
var assemblyNames = new[] { "JiShe.CollectBus.IoTDB", "JiShe.CollectBus.Domain" };
|
||||||
|
var assemblies = CommonHelper.LoadAssemblies(assemblyNames);
|
||||||
|
|
||||||
|
var targetTypes = CollectTargetTypes(assemblies);
|
||||||
|
if (targetTypes == null || targetTypes.Count <= 0)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{nameof(InitTableSessionModelAsync)} 初始化表模型时没有找到对应的实体类信息。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @"CREATE TABLE table1(
|
||||||
|
// time TIMESTAMP TIME,
|
||||||
|
// region STRING TAG,
|
||||||
|
// plant_id STRING TAG,
|
||||||
|
// device_id STRING TAG,
|
||||||
|
// model_id STRING ATTRIBUTE,
|
||||||
|
// maintenance STRING ATTRIBUTE,
|
||||||
|
// temperature FLOAT FIELD,
|
||||||
|
// humidity FLOAT FIELD,
|
||||||
|
// status Boolean FIELD,
|
||||||
|
// arrival_time TIMESTAMP FIELD
|
||||||
|
//) COMMENT 'table1' WITH(TTL = 31536000000);";
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var item in targetTypes)
|
||||||
|
{
|
||||||
|
var accessor = SourceEntityAccessorFactory.GetAccessor(item);
|
||||||
|
//通过 dynamic 简化操作
|
||||||
|
dynamic dynamicAccessor = accessor;
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.Append("CREATE TABLE IF NOT EXISTS ");
|
||||||
|
stringBuilder.Append(dynamicAccessor.EntityName);
|
||||||
|
stringBuilder.Append("( time TIMESTAMP TIME, ");
|
||||||
|
var columns = new List<ColumnInfo>();
|
||||||
|
foreach (var member in dynamicAccessor.MemberList)
|
||||||
|
{
|
||||||
|
// 过滤元组子项
|
||||||
|
if (member.NameOrPath.Contains(".Item")) continue;
|
||||||
|
|
||||||
|
// 特性查询优化
|
||||||
|
var attributes = (IEnumerable<Attribute>)(member.CustomAttributes ?? Enumerable.Empty<Attribute>());
|
||||||
|
var tagAttr = attributes.OfType<TAGColumnAttribute>().FirstOrDefault();
|
||||||
|
var attrColumn = attributes.OfType<ATTRIBUTEColumnAttribute>().FirstOrDefault();
|
||||||
|
var fieldColumn = attributes.OfType<FIELDColumnAttribute>().FirstOrDefault();
|
||||||
|
|
||||||
|
// 构建ColumnInfo
|
||||||
|
ColumnInfo? column = null;
|
||||||
|
if (tagAttr != null)
|
||||||
|
{
|
||||||
|
column = new ColumnInfo(member.NameOrPath, ColumnCategory.TAG, GetDataTypeFromTypeName(member.DeclaredTypeName), false, member.DeclaredTypeName);
|
||||||
|
}
|
||||||
|
else if (attrColumn != null)
|
||||||
|
{
|
||||||
|
column = new ColumnInfo(member.NameOrPath, ColumnCategory.ATTRIBUTE, GetDataTypeFromTypeName(member.DeclaredTypeName), false, member.DeclaredTypeName);
|
||||||
|
}
|
||||||
|
else if (fieldColumn != null)
|
||||||
|
{
|
||||||
|
column = new ColumnInfo(member.NameOrPath, ColumnCategory.FIELD, GetDataTypeFromTypeName(member.DeclaredTypeName), false, member.DeclaredTypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!column.HasValue)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{nameof(InitTableSessionModelAsync)} 初始化表模型时实体类{dynamicAccessor.EntityName}的{member.NameOrPath}列的ColumnInfo构建失败。");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
columns.Add(column.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//按业务逻辑顺序处理(TAG -> ATTRIBUTE -> FIELD)
|
||||||
|
var groupedColumns = columns
|
||||||
|
.GroupBy(c => c.Category)
|
||||||
|
.ToDictionary(g => g.Key, g => g.ToList());
|
||||||
|
List<string> tempColumInfos = new List<string>();
|
||||||
|
|
||||||
|
tempColumInfos.Add( ProcessCategory(groupedColumns, ColumnCategory.TAG));
|
||||||
|
tempColumInfos.Add(ProcessCategory(groupedColumns, ColumnCategory.ATTRIBUTE));
|
||||||
|
tempColumInfos.Add(ProcessCategory(groupedColumns, ColumnCategory.FIELD));
|
||||||
|
stringBuilder.Append(string.Join(",", tempColumInfos.Where(d => !string.IsNullOrWhiteSpace(d))));
|
||||||
|
stringBuilder.Append($" ) COMMENT '{item.Name}' ");
|
||||||
|
|
||||||
|
_logger.LogWarning($"{dynamicAccessor.EntityName} 初始化语句:{stringBuilder.ToString()}");
|
||||||
|
|
||||||
|
await CurrentSession.ExecuteNonQueryStatementAsync($"{stringBuilder.ToString()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取程序集中的所有 [SourceAnalyzers(EntityTypeEnum.TableModel)] 的实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assemblies"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private List<Type> CollectTargetTypes(List<Assembly> assemblies)
|
||||||
|
{
|
||||||
|
var targetTypes = new List<Type>();
|
||||||
|
foreach (var assembly in assemblies)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var type in assembly.GetExportedTypes())
|
||||||
|
{
|
||||||
|
//获取表模型特性的类
|
||||||
|
var sourceAnalyzersAttribute = type.GetCustomAttribute<SourceAnalyzersAttribute>();
|
||||||
|
|
||||||
|
//需要忽略表模型初始化,有此特性无需初始化
|
||||||
|
var ignoreInitTableAttribute = type.GetCustomAttribute<IgnoreInitTableAttribute>();
|
||||||
|
|
||||||
|
if (sourceAnalyzersAttribute?.EntityType == EntityTypeEnum.TableModel && ignoreInitTableAttribute == null)
|
||||||
|
{
|
||||||
|
if (type.GetConstructor(Type.EmptyTypes) != null)
|
||||||
|
targetTypes.Add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ReflectionTypeLoadException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"加载 {assembly} 失败: {string.Join(", ", ex.LoaderExceptions.Select(e => e.Message))}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,6 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
{
|
{
|
||||||
throw new Exception($"{nameof(SessionPoolAdapter)} Tree模型数据入库没有成功,返回结果为:{result},请检查IoTEntity继承子类属性索引是否有变动。");
|
throw new Exception($"{nameof(SessionPoolAdapter)} Tree模型数据入库没有成功,返回结果为:{result},请检查IoTEntity继承子类属性索引是否有变动。");
|
||||||
}
|
}
|
||||||
//await CloseAsync();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +83,17 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
|
public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
|
||||||
{
|
{
|
||||||
var result = await _sessionPool.ExecuteQueryStatementAsync(sql, _options.Timeout);
|
var result = await _sessionPool.ExecuteQueryStatementAsync(sql, _options.Timeout);
|
||||||
//await result.Close();
|
return result;
|
||||||
//await CloseAsync();
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行无返回结果SQL
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sql"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<int> ExecuteNonQueryStatementAsync(string sql)
|
||||||
|
{
|
||||||
|
var result = await _sessionPool.ExecuteNonQueryStatementAsync(sql);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,6 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
throw new Exception($"{nameof(TableSessionPoolAdapter)} table模型数据入库没有成功,返回结果为:{result},请检查IoTEntity继承子类属性索引是否有变动。");
|
throw new Exception($"{nameof(TableSessionPoolAdapter)} table模型数据入库没有成功,返回结果为:{result},请检查IoTEntity继承子类属性索引是否有变动。");
|
||||||
}
|
}
|
||||||
|
|
||||||
//await CloseAsync();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +82,17 @@ namespace JiShe.CollectBus.IoTDB.Provider
|
|||||||
public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
|
public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
|
||||||
{
|
{
|
||||||
var result = await _sessionPool.ExecuteQueryStatementAsync(sql,_options.Timeout);
|
var result = await _sessionPool.ExecuteQueryStatementAsync(sql,_options.Timeout);
|
||||||
//await result.Close();
|
return result;
|
||||||
//await CloseAsync();
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行无返回结果SQL
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sql"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<int> ExecuteNonQueryStatementAsync(string sql)
|
||||||
|
{
|
||||||
|
var result = await _sessionPool.ExecuteNonQueryStatementAsync(sql);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,10 +8,11 @@ using Volo.Abp.DependencyInjection;
|
|||||||
|
|
||||||
namespace JiShe.CollectBus.Kafka.AdminClient;
|
namespace JiShe.CollectBus.Kafka.AdminClient;
|
||||||
|
|
||||||
public class AdminClientService : IAdminClientService, IDisposable, ISingletonDependency
|
public class AdminClientService : IAdminClientService, ISingletonDependency
|
||||||
{
|
{
|
||||||
private readonly ILogger<AdminClientService> _logger;
|
private readonly ILogger<AdminClientService> _logger;
|
||||||
private readonly KafkaOptionConfig _kafkaOptionConfig;
|
private readonly KafkaOptionConfig _kafkaOptionConfig;
|
||||||
|
private readonly Lazy<IAdminClient> _lazyAdminClient;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AdminClientService" /> class.
|
/// Initializes a new instance of the <see cref="AdminClientService" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -21,7 +22,8 @@ public class AdminClientService : IAdminClientService, IDisposable, ISingletonDe
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_kafkaOptionConfig = kafkaOptionConfig.Value;
|
_kafkaOptionConfig = kafkaOptionConfig.Value;
|
||||||
Instance = GetInstance();
|
//Instance = GetInstance();
|
||||||
|
_lazyAdminClient = new Lazy<IAdminClient>(() => GetInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -30,7 +32,7 @@ public class AdminClientService : IAdminClientService, IDisposable, ISingletonDe
|
|||||||
/// <value>
|
/// <value>
|
||||||
/// The instance.
|
/// The instance.
|
||||||
/// </value>
|
/// </value>
|
||||||
public IAdminClient Instance { get; set; }
|
public IAdminClient Instance => _lazyAdminClient.Value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建Kafka主题
|
/// 创建Kafka主题
|
||||||
@ -79,7 +81,7 @@ public class AdminClientService : IAdminClientService, IDisposable, ISingletonDe
|
|||||||
public async Task<List<string>> ListTopicsAsync()
|
public async Task<List<string>> ListTopicsAsync()
|
||||||
{
|
{
|
||||||
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(10));
|
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(10));
|
||||||
return new List<string>(metadata.Topics.Select(t => t.Topic));
|
return await Task.FromResult(new List<string>(metadata.Topics.Select(t => t.Topic)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -90,7 +92,7 @@ public class AdminClientService : IAdminClientService, IDisposable, ISingletonDe
|
|||||||
public async Task<bool> TopicExistsAsync(string topic)
|
public async Task<bool> TopicExistsAsync(string topic)
|
||||||
{
|
{
|
||||||
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(10));
|
var metadata = Instance.GetMetadata(TimeSpan.FromSeconds(10));
|
||||||
return metadata.Topics.Any(t => t.Topic == topic);
|
return await Task.FromResult(metadata.Topics.Any(t => t.Topic == topic));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -137,11 +139,6 @@ public class AdminClientService : IAdminClientService, IDisposable, ISingletonDe
|
|||||||
return metadata.Topics[0].Partitions.Count;
|
return metadata.Topics[0].Partitions.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Instance?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the instance.
|
/// Gets the instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
using Confluent.Kafka;
|
using Confluent.Kafka;
|
||||||
using JiShe.CollectBus.Common.Consts;
|
using JiShe.CollectBus.Common.Consts;
|
||||||
|
using JiShe.CollectBus.Common.Extensions;
|
||||||
using JiShe.CollectBus.Kafka.Consumer;
|
using JiShe.CollectBus.Kafka.Consumer;
|
||||||
using JiShe.CollectBus.Kafka.Internal;
|
using JiShe.CollectBus.Kafka.Internal;
|
||||||
using JiShe.CollectBus.Kafka.Producer;
|
using JiShe.CollectBus.Kafka.Producer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
@ -20,22 +22,14 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
{
|
{
|
||||||
var configuration = context.Services.GetConfiguration();
|
var configuration = context.Services.GetConfiguration();
|
||||||
//var kafkaSection = configuration.GetSection(CommonConst.Kafka);
|
//var kafkaSection = configuration.GetSection(CommonConst.Kafka);
|
||||||
//KafkaOptionConfig kafkaOptionConfig = new KafkaOptionConfig ();
|
//KafkaOptionConfig kafkaOptionConfig = new KafkaOptionConfig();
|
||||||
//kafkaSection.Bind(kafkaOptionConfig);
|
//kafkaSection.Bind(kafkaOptionConfig);
|
||||||
//if (configuration[CommonConst.ServerTagName] != null)
|
//Configure<KafkaOptionConfig>(kafkaSection);
|
||||||
//{
|
|
||||||
// kafkaOptionConfig.ServerTagName = configuration[CommonConst.ServerTagName]!;
|
|
||||||
//}
|
|
||||||
//context.Services.AddSingleton(kafkaOptionConfig);
|
|
||||||
|
|
||||||
//context.Services.Configure<KafkaOptionConfig>(context.Services.GetConfiguration().GetSection(CommonConst.Kafka));
|
|
||||||
|
|
||||||
Configure<KafkaOptionConfig>(options =>
|
Configure<KafkaOptionConfig>(options =>
|
||||||
{
|
{
|
||||||
configuration.GetSection(CommonConst.Kafka).Bind(options);
|
configuration.GetSection(CommonConst.Kafka).Bind(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// 注册Producer
|
// 注册Producer
|
||||||
context.Services.AddSingleton<IProducerService, ProducerService>();
|
context.Services.AddSingleton<IProducerService, ProducerService>();
|
||||||
// 注册Consumer
|
// 注册Consumer
|
||||||
@ -44,6 +38,12 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
// 注册Polly
|
// 注册Polly
|
||||||
context.Services.AddSingleton<KafkaPollyPipeline>();
|
context.Services.AddSingleton<KafkaPollyPipeline>();
|
||||||
|
|
||||||
|
var topics = ProtocolConstExtensions.GetAllTopicNamesByIssued();
|
||||||
|
topics.AddRange(ProtocolConstExtensions.GetAllTopicNamesByReceived());
|
||||||
|
|
||||||
|
// 注册任务调度
|
||||||
|
context.Services.AddSingleton<KafkaTaskScheduler>();
|
||||||
|
|
||||||
//context.Services.AddHostedService<HostedService>();
|
//context.Services.AddHostedService<HostedService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ using System.Collections.Concurrent;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using YamlDotNet.Core.Tokens;
|
||||||
|
|
||||||
namespace JiShe.CollectBus.Kafka.Consumer
|
namespace JiShe.CollectBus.Kafka.Consumer
|
||||||
{
|
{
|
||||||
@ -36,17 +37,21 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
|
|
||||||
private readonly KafkaPollyPipeline _kafkaPollyPipeline;
|
private readonly KafkaPollyPipeline _kafkaPollyPipeline;
|
||||||
|
|
||||||
|
|
||||||
|
private readonly KafkaTaskScheduler _kafkaTaskScheduler;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ConsumerService
|
/// ConsumerService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
/// <param name="kafkaOptionConfig"></param>
|
/// <param name="kafkaOptionConfig"></param>
|
||||||
public ConsumerService(ILogger<ConsumerService> logger, IOptions<KafkaOptionConfig> kafkaOptionConfig, KafkaPollyPipeline kafkaPollyPipeline, IOptions<ServerApplicationOptions> applicationOptions)
|
public ConsumerService(ILogger<ConsumerService> logger, IOptions<KafkaOptionConfig> kafkaOptionConfig, KafkaPollyPipeline kafkaPollyPipeline, IOptions<ServerApplicationOptions> applicationOptions, KafkaTaskScheduler kafkaTaskScheduler)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_kafkaOptionConfig = kafkaOptionConfig.Value;
|
_kafkaOptionConfig = kafkaOptionConfig.Value;
|
||||||
_applicationOptions = applicationOptions.Value;
|
_applicationOptions = applicationOptions.Value;
|
||||||
_kafkaPollyPipeline = kafkaPollyPipeline;
|
_kafkaPollyPipeline = kafkaPollyPipeline;
|
||||||
|
_kafkaTaskScheduler = kafkaTaskScheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region private 私有方法
|
#region private 私有方法
|
||||||
@ -130,21 +135,26 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 扩展独立线程,避免阻塞
|
||||||
|
_kafkaTaskScheduler.WorkerThreadExpansion();
|
||||||
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
||||||
{
|
{
|
||||||
|
|
||||||
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}";
|
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}";
|
||||||
var cts = new CancellationTokenSource();
|
var consumerStore = _consumerStore.GetOrAdd(consumerKey, _ =>
|
||||||
|
|
||||||
var consumer = _consumerStore.GetOrAdd(consumerKey, _ =>
|
|
||||||
(
|
(
|
||||||
CreateConsumer<TKey, TValue>(groupId),
|
CreateConsumer<TKey, TValue>(groupId),
|
||||||
cts
|
new CancellationTokenSource()
|
||||||
)).Consumer as IConsumer<TKey, TValue>;
|
));
|
||||||
|
if (consumerStore.Consumer == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"{string.Join("、", topics)}创建消息消费失败或消费组已被释放");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var consumer = consumerStore.Consumer as IConsumer<TKey, TValue>;
|
||||||
|
var cts = consumerStore.CTS;
|
||||||
|
|
||||||
consumer!.Subscribe(topics);
|
consumer!.Subscribe(topics);
|
||||||
|
_= Task.Factory.StartNew(async () =>
|
||||||
_ = Task.Run(async () =>
|
|
||||||
{
|
{
|
||||||
while (!cts.IsCancellationRequested)
|
while (!cts.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
@ -195,12 +205,17 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{string.Join("、", topics)}消费者被释放");
|
||||||
|
break;
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "处理消息时发生未知错误");
|
_logger.LogError(ex, "处理消息时发生未知错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, cts.Token);
|
}, cts.Token, TaskCreationOptions.None, _kafkaTaskScheduler);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -226,19 +241,28 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 扩展独立线程,避免阻塞
|
||||||
|
_kafkaTaskScheduler.WorkerThreadExpansion();
|
||||||
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
||||||
{
|
{
|
||||||
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}";
|
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}";
|
||||||
var cts = new CancellationTokenSource();
|
|
||||||
var consumer = _consumerStore.GetOrAdd(consumerKey, _ =>
|
var consumerStore = _consumerStore.GetOrAdd(consumerKey, _ =>
|
||||||
(
|
(
|
||||||
CreateConsumer<Ignore, TValue>(groupId),
|
CreateConsumer<Ignore, TValue>(groupId),
|
||||||
cts
|
new CancellationTokenSource()
|
||||||
)).Consumer as IConsumer<Ignore, TValue>;
|
));
|
||||||
|
if (consumerStore.Consumer == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"{string.Join("、", topics)}创建消息消费失败或消费组已被释放");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var consumer = consumerStore.Consumer as IConsumer<Ignore, TValue>;
|
||||||
|
var cts = consumerStore.CTS;
|
||||||
|
|
||||||
consumer!.Subscribe(topics);
|
consumer!.Subscribe(topics);
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Factory.StartNew(async () =>
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (!cts.IsCancellationRequested)
|
while (!cts.IsCancellationRequested)
|
||||||
@ -288,12 +312,17 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{string.Join("、", topics)}消费者被释放");
|
||||||
|
break;
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "处理消息时发生未知错误");
|
_logger.LogError(ex, "处理消息时发生未知错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, cts.Token);
|
}, cts.Token, TaskCreationOptions.None, _kafkaTaskScheduler);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -342,22 +371,31 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 扩展独立线程,避免阻塞
|
||||||
|
_kafkaTaskScheduler.WorkerThreadExpansion();
|
||||||
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
||||||
{
|
{
|
||||||
|
|
||||||
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}";
|
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}";
|
||||||
var cts = new CancellationTokenSource();
|
|
||||||
|
|
||||||
var consumer = _consumerStore.GetOrAdd(consumerKey, _ =>
|
var consumerStore = _consumerStore.GetOrAdd(consumerKey, _ =>
|
||||||
(
|
(
|
||||||
CreateConsumer<TKey, TValue>(groupId),
|
CreateConsumer<TKey, TValue>(groupId),
|
||||||
cts
|
new CancellationTokenSource()
|
||||||
)).Consumer as IConsumer<TKey, TValue>;
|
));
|
||||||
|
if (consumerStore.Consumer == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"{string.Join("、", topics)}创建消息消费失败或消费组已被释放");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var consumer = consumerStore.Consumer as IConsumer<TKey, TValue>;
|
||||||
|
var cts = consumerStore.CTS;
|
||||||
|
|
||||||
consumer!.Subscribe(topics);
|
consumer!.Subscribe(topics);
|
||||||
|
|
||||||
var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒
|
var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Factory.StartNew(async () =>
|
||||||
{
|
{
|
||||||
var messages = new List<(TValue Value, TopicPartitionOffset Offset)>();
|
var messages = new List<(TValue Value, TopicPartitionOffset Offset)>();
|
||||||
var startTime = DateTime.UtcNow;
|
var startTime = DateTime.UtcNow;
|
||||||
@ -444,12 +482,17 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{string.Join("、", topics)}消费者被释放");
|
||||||
|
break;
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "处理批量消息时发生未知错误");
|
_logger.LogError(ex, "处理批量消息时发生未知错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, cts.Token);
|
}, cts.Token, TaskCreationOptions.None, _kafkaTaskScheduler);
|
||||||
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
@ -501,23 +544,30 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 扩展独立线程,避免阻塞
|
||||||
|
_kafkaTaskScheduler.WorkerThreadExpansion();
|
||||||
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
await _kafkaPollyPipeline.KafkaPipeline.ExecuteAsync(async token =>
|
||||||
{
|
{
|
||||||
|
|
||||||
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}";
|
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(Ignore).Name}_{typeof(TValue).Name}";
|
||||||
var cts = new CancellationTokenSource();
|
var consumerStore = _consumerStore.GetOrAdd(consumerKey, _ =>
|
||||||
|
|
||||||
var consumer = _consumerStore.GetOrAdd(consumerKey, _ =>
|
|
||||||
(
|
(
|
||||||
CreateConsumer<Ignore, TValue>(groupId),
|
CreateConsumer<Ignore, TValue>(groupId),
|
||||||
cts
|
new CancellationTokenSource()
|
||||||
)).Consumer as IConsumer<Ignore, TValue>;
|
));
|
||||||
|
if (consumerStore.Consumer == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"{string.Join("、", topics)}创建消息消费失败或消费组已被释放");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var consumer = consumerStore.Consumer as IConsumer<Ignore, TValue>;
|
||||||
|
var cts = consumerStore.CTS;
|
||||||
|
|
||||||
consumer!.Subscribe(topics);
|
consumer!.Subscribe(topics);
|
||||||
|
|
||||||
var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒
|
var timeout = batchTimeout ?? TimeSpan.FromSeconds(5); // 默认超时时间调整为5秒
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Factory.StartNew(async () =>
|
||||||
{
|
{
|
||||||
var messages = new List<(TValue Value, TopicPartitionOffset Offset)>();
|
var messages = new List<(TValue Value, TopicPartitionOffset Offset)>();
|
||||||
var startTime = DateTime.UtcNow;
|
var startTime = DateTime.UtcNow;
|
||||||
@ -602,12 +652,17 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{string.Join("、", topics)}消费者被释放");
|
||||||
|
break;
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "处理批量消息时发生未知错误");
|
_logger.LogError(ex, "处理批量消息时发生未知错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, cts.Token);
|
}, cts.Token, TaskCreationOptions.None, _kafkaTaskScheduler);
|
||||||
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
@ -630,11 +685,13 @@ namespace JiShe.CollectBus.Kafka.Consumer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}";
|
var consumerKey = $"{groupId}_{string.Join("_", topics)}_{typeof(TKey).Name}_{typeof(TValue).Name}";
|
||||||
if (_consumerStore.TryRemove(consumerKey, out var entry))
|
if (_consumerStore.TryGetValue(consumerKey, out var entry))
|
||||||
{
|
{
|
||||||
entry.CTS.Cancel();
|
entry.CTS.Cancel();
|
||||||
(entry.Consumer as IDisposable)?.Dispose();
|
(entry.Consumer as IDisposable)?.Dispose();
|
||||||
entry.CTS.Dispose();
|
entry.CTS.Dispose();
|
||||||
|
// 从字典中移除
|
||||||
|
_consumerStore.TryRemove(consumerKey, out entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@ -49,4 +49,11 @@ public class KafkaOptionConfig
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string? SaslPassword { get; set; }
|
public string? SaslPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 订阅任务线程数量
|
||||||
|
/// 当主题未指定时,订阅任务线程数量默认为:-1
|
||||||
|
/// 优先级低于订阅任务特性TaskCount值
|
||||||
|
/// </summary>
|
||||||
|
public int TaskThreadCount { get; set; } = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
169
modules/JiShe.CollectBus.Kafka/Internal/KafkaTaskScheduler.cs
Normal file
169
modules/JiShe.CollectBus.Kafka/Internal/KafkaTaskScheduler.cs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace JiShe.CollectBus.Kafka.Internal
|
||||||
|
{
|
||||||
|
public class KafkaTaskScheduler : TaskScheduler, IDisposable
|
||||||
|
{
|
||||||
|
private readonly BlockingCollection<Task> _tasksCollection=new BlockingCollection<Task> ();
|
||||||
|
private readonly List<Thread> _workerThreads;
|
||||||
|
private readonly object _disposeLock = new object();
|
||||||
|
private bool _isDisposed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前队列中的任务数
|
||||||
|
/// </summary>
|
||||||
|
public int QueuedTasks => _tasksCollection.Count;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前工作线程数
|
||||||
|
/// </summary>
|
||||||
|
public int WorkerThreads => _workerThreads.Count;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化任务调度器
|
||||||
|
/// </summary>
|
||||||
|
public KafkaTaskScheduler()
|
||||||
|
{
|
||||||
|
// 默认最大并发线程数为CPU核心数
|
||||||
|
int MaxConcurrencyLevel = Environment.ProcessorCount;
|
||||||
|
_workerThreads = new List<Thread>(MaxConcurrencyLevel);
|
||||||
|
for (int i = 0; i < MaxConcurrencyLevel; i++)
|
||||||
|
{
|
||||||
|
var thread = new Thread(ExecuteScheduledTasks)
|
||||||
|
{
|
||||||
|
IsBackground = true,
|
||||||
|
Name = $"KafkaWorkerTask-{i + 1}"
|
||||||
|
};
|
||||||
|
thread.Start();
|
||||||
|
_workerThreads.Add(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 扩容工作线程调度
|
||||||
|
/// 可以启动多个工作线程来处理任务
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="taskNum">扩展独立线程数(默认为1)</param>
|
||||||
|
public void WorkerThreadExpansion(int taskNum = 1)
|
||||||
|
{
|
||||||
|
int currCount = WorkerThreads+1;
|
||||||
|
Parallel.For(0, taskNum, (index) =>
|
||||||
|
{
|
||||||
|
var thread = new Thread(ExecuteScheduledTasks)
|
||||||
|
{
|
||||||
|
IsBackground = true,
|
||||||
|
Name = $"KafkaWorkerTask-{index+ currCount}"
|
||||||
|
};
|
||||||
|
thread.Start();
|
||||||
|
_workerThreads.Add(thread);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工作线程执行循环
|
||||||
|
/// </summary>
|
||||||
|
private void ExecuteScheduledTasks()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var task in _tasksCollection.GetConsumingEnumerable())
|
||||||
|
{
|
||||||
|
TryExecuteTaskSafely(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) { }
|
||||||
|
catch (ObjectDisposedException) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 安全执行任务并处理异常
|
||||||
|
/// </summary>
|
||||||
|
private void TryExecuteTaskSafely(Task task)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TryExecuteTask(task);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException){}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnExceptionOccurred(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region TaskScheduler 重写方法
|
||||||
|
protected override IEnumerable<Task> GetScheduledTasks()
|
||||||
|
{
|
||||||
|
ThrowIfDisposed();
|
||||||
|
return _tasksCollection.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void QueueTask(Task task)
|
||||||
|
{
|
||||||
|
ThrowIfDisposed();
|
||||||
|
_tasksCollection.Add(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
||||||
|
{
|
||||||
|
// 禁止内联执行以强制所有任务在专用线程执行
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 释放资源
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
lock (_disposeLock)
|
||||||
|
{
|
||||||
|
if (_isDisposed) return;
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
// 停止接收新任务
|
||||||
|
_tasksCollection.CompleteAdding();
|
||||||
|
|
||||||
|
// 等待所有工作线程退出
|
||||||
|
foreach (var thread in _workerThreads)
|
||||||
|
{
|
||||||
|
if (thread.IsAlive)
|
||||||
|
{
|
||||||
|
thread.Join(TimeSpan.FromSeconds(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 释放资源
|
||||||
|
_tasksCollection.Dispose();
|
||||||
|
}
|
||||||
|
_isDisposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowIfDisposed()
|
||||||
|
{
|
||||||
|
if (_isDisposed)
|
||||||
|
{
|
||||||
|
throw new ObjectDisposedException(GetType().Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 异常事件处理
|
||||||
|
/// <summary>
|
||||||
|
/// 任务执行异常时触发
|
||||||
|
/// </summary>
|
||||||
|
public event Action<Exception>? ExceptionEvent;
|
||||||
|
|
||||||
|
private void OnExceptionOccurred(Exception ex)
|
||||||
|
{
|
||||||
|
ExceptionEvent?.Invoke(ex);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -33,11 +33,11 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
|
|
||||||
var topics = ProtocolConstExtensions.GetAllTopicNamesByIssued();
|
var topics = ProtocolConstExtensions.GetAllTopicNamesByIssued();
|
||||||
topics.AddRange(ProtocolConstExtensions.GetAllTopicNamesByReceived());
|
topics.AddRange(ProtocolConstExtensions.GetAllTopicNamesByReceived());
|
||||||
|
|
||||||
foreach (var item in topics)
|
foreach (var item in topics)
|
||||||
{
|
{
|
||||||
kafkaAdminClient.CreateTopicAsync(item, kafkaOptions.Value.NumPartitions, kafkaOptions.Value.KafkaReplicationFactor).ConfigureAwait(false).GetAwaiter().GetResult();
|
kafkaAdminClient.CreateTopicAsync(item, kafkaOptions.Value.NumPartitions, kafkaOptions.Value.KafkaReplicationFactor).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -77,7 +77,7 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
Parallel.ForEach(subscribeTypes, subscribeType =>
|
Parallel.ForEach(subscribeTypes, subscribeType =>
|
||||||
{
|
{
|
||||||
var subscribes = provider.GetServices(subscribeType).ToList();
|
var subscribes = provider.GetServices(subscribeType).ToList();
|
||||||
Parallel.ForEach(subscribes,subscribe =>
|
Parallel.ForEach(subscribes, subscribe =>
|
||||||
{
|
{
|
||||||
if (subscribe != null)
|
if (subscribe != null)
|
||||||
{
|
{
|
||||||
@ -102,7 +102,26 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
logger.LogWarning($"kafka订阅主题:{_topicSubscribeCount}数,共启动:{_threadCount}线程");
|
logger.LogWarning($"kafka订阅主题:{_topicSubscribeCount}数,共启动:{_threadCount}线程");
|
||||||
|
|
||||||
|
var kafkaTaskScheduler = provider.GetRequiredService<KafkaTaskScheduler>();
|
||||||
|
kafkaTaskScheduler.ExceptionEvent += (ex) =>
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Kafka任务调度异常");
|
||||||
|
};
|
||||||
|
//logger.LogWarning($"kafka订阅工作线程数:{kafkaTaskScheduler.WorkerThreads},队列任务:{kafkaTaskScheduler.QueuedTasks}数");
|
||||||
|
//
|
||||||
|
// 订阅调度监控测试可打开
|
||||||
|
//_ = Task.Factory.StartNew(async () =>
|
||||||
|
// {
|
||||||
|
// while (true)
|
||||||
|
// {
|
||||||
|
// logger.LogWarning($"kafka订阅工作线程数:{kafkaTaskScheduler.WorkerThreads},队列任务:{kafkaTaskScheduler.QueuedTasks}数");
|
||||||
|
// await Task.Delay(TimeSpan.FromSeconds(5));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -123,20 +142,35 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (subscribeTypes.Count == 0) return;
|
if (subscribeTypes.Count == 0) return;
|
||||||
foreach (var subscribeType in subscribeTypes)
|
|
||||||
|
Parallel.ForEach(subscribeTypes, subscribeType =>
|
||||||
{
|
{
|
||||||
var subscribes = provider.GetServices(subscribeType).ToList();
|
var subscribes = provider.GetServices(subscribeType).ToList();
|
||||||
subscribes.ForEach(subscribe =>
|
Parallel.ForEach(subscribes, subscribe =>
|
||||||
{
|
{
|
||||||
|
|
||||||
if (subscribe != null)
|
if (subscribe != null)
|
||||||
{
|
{
|
||||||
Tuple<int, int> tuple = BuildKafkaSubscribe(subscribe, provider, logger, kafkaOptions.Value);
|
Tuple<int, int> tuple = BuildKafkaSubscribe(subscribe, provider, logger, kafkaOptions.Value);
|
||||||
threadCount += tuple.Item1;
|
//threadCount += tuple.Item1;
|
||||||
topicCount += tuple.Item2;
|
//topicCount += tuple.Item2;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
|
//foreach (var subscribeType in subscribeTypes)
|
||||||
|
//{
|
||||||
|
// var subscribes = provider.GetServices(subscribeType).ToList();
|
||||||
|
// subscribes.ForEach(subscribe =>
|
||||||
|
// {
|
||||||
|
|
||||||
|
// if (subscribe != null)
|
||||||
|
// {
|
||||||
|
// Tuple<int, int> tuple = BuildKafkaSubscribe(subscribe, provider, logger, kafkaOptions.Value);
|
||||||
|
// threadCount += tuple.Item1;
|
||||||
|
// topicCount += tuple.Item2;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//}
|
||||||
logger.LogInformation($"kafka订阅主题:{topicCount}数,共启动:{threadCount}线程");
|
logger.LogInformation($"kafka订阅主题:{topicCount}数,共启动:{threadCount}线程");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -156,13 +190,10 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
Parallel.ForEach(subscribedMethods, sub =>
|
Parallel.ForEach(subscribedMethods, sub =>
|
||||||
{
|
{
|
||||||
Interlocked.Increment(ref _topicSubscribeCount);
|
Interlocked.Increment(ref _topicSubscribeCount);
|
||||||
int partitionCount = sub.Attribute!.TaskCount == -1 ? 3 : sub.Attribute!.TaskCount;// kafkaOptionConfig.NumPartitions;
|
|
||||||
var adminClientService = provider.GetRequiredService<IAdminClientService>();
|
var adminClientService = provider.GetRequiredService<IAdminClientService>();
|
||||||
|
|
||||||
int topicCount = adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic);
|
int topicCount = adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic);
|
||||||
|
// 可以根据配置文件TaskThreadCount来配置线程数
|
||||||
//int partitionCount = sub.Attribute!.TaskCount == -1 ? topicCount : sub.Attribute!.TaskCount;// kafkaOptionConfig.NumPartitions;
|
int partitionCount = sub.Attribute!.TaskCount == -1 ? (kafkaOptionConfig.TaskThreadCount==-1? topicCount: kafkaOptionConfig.TaskThreadCount) : sub.Attribute!.TaskCount;// kafkaOptionConfig.NumPartitions;
|
||||||
|
|
||||||
partitionCount = partitionCount > topicCount ? topicCount : partitionCount;
|
partitionCount = partitionCount > topicCount ? topicCount : partitionCount;
|
||||||
//partitionCount = sub.Attribute!.TaskCount == -1 ? adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic) : sub.Attribute!.TaskCount;
|
//partitionCount = sub.Attribute!.TaskCount == -1 ? adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic) : sub.Attribute!.TaskCount;
|
||||||
if (partitionCount <= 0)
|
if (partitionCount <= 0)
|
||||||
@ -179,7 +210,7 @@ namespace JiShe.CollectBus.Kafka
|
|||||||
|
|
||||||
//foreach (var sub in subscribedMethods)
|
//foreach (var sub in subscribedMethods)
|
||||||
//{
|
//{
|
||||||
// //int partitionCount = sub.Attribute!.TaskCount==-1?3: sub.Attribute!.TaskCount;// kafkaOptionConfig.NumPartitions;
|
//// //int partitionCount = sub.Attribute!.TaskCount==-1?3: sub.Attribute!.TaskCount;// kafkaOptionConfig.NumPartitions;
|
||||||
// var adminClientService = provider.GetRequiredService<IAdminClientService>();
|
// var adminClientService = provider.GetRequiredService<IAdminClientService>();
|
||||||
|
|
||||||
// int topicCount = adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic);
|
// int topicCount = adminClientService.GetTopicPartitionsNum(sub.Attribute!.Topic);
|
||||||
|
|||||||
@ -38,16 +38,19 @@ namespace JiShe.CollectBus.Protocol.T1882018.SendData
|
|||||||
#region 读数据
|
#region 读数据
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取计量数据
|
/// 读取计量数据,CTR0_控制码(01H/09H)_DI1_DI0_SER
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Telemetry1882018PacketResponse CTR_01_Send(Telemetry1882018PacketRequest request)
|
public static Telemetry1882018PacketResponse CTR0_01_Send(Telemetry1882018PacketRequest request)
|
||||||
{
|
{
|
||||||
var itemCodeArr = request.ItemCode.Split('_');
|
var itemCodeArr = request.ItemCode.Split('_');
|
||||||
var c_data = itemCodeArr[0];//01
|
var ctr = itemCodeArr[0];//CTR0
|
||||||
var d_data = itemCodeArr[2];//91 或者 90
|
var c_data = itemCodeArr[1];//01
|
||||||
var dataUnit = new List<string>() { "1F", d_data, "00" };
|
var DI1 = itemCodeArr[2];//91 或者 90
|
||||||
|
var DI0 = itemCodeArr[3];//1F
|
||||||
|
var SER = itemCodeArr[4];//00
|
||||||
|
var dataUnit = new List<string>() { DI1, DI0, SER };
|
||||||
var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit);
|
var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit);
|
||||||
|
|
||||||
return new Telemetry1882018PacketResponse() { Data = dataList };
|
return new Telemetry1882018PacketResponse() { Data = dataList };
|
||||||
@ -56,16 +59,19 @@ namespace JiShe.CollectBus.Protocol.T1882018.SendData
|
|||||||
|
|
||||||
#region 写数据
|
#region 写数据
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 阀控
|
/// 写数据,CTR3_控制码(04H/0CH)_DI1_DI0_SER
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Telemetry1882018PacketResponse CTR_04_Send(Telemetry1882018PacketRequest request)
|
public static Telemetry1882018PacketResponse CTR3_04_Send(Telemetry1882018PacketRequest request)
|
||||||
{
|
{
|
||||||
var itemCodeArr = request.ItemCode.Split('_');
|
var itemCodeArr = request.ItemCode.Split('_');
|
||||||
var c_data = itemCodeArr[0];//01
|
var ctr = itemCodeArr[0];//CTR3
|
||||||
var d_data = itemCodeArr[2];//55 或者 99
|
var c_data = itemCodeArr[1];//04
|
||||||
var dataUnit = new List<string>() { "A0", "17", "00", d_data };
|
var DI1 = itemCodeArr[2];//A0
|
||||||
|
var DI0 = itemCodeArr[3];//17
|
||||||
|
var SER = itemCodeArr[4];//55 或者 99
|
||||||
|
var dataUnit = new List<string>() { DI1, DI0, SER };
|
||||||
var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit);
|
var dataList = Build188SendData.Build188SendCommand(request.MeterAddress, c_data, dataUnit);
|
||||||
|
|
||||||
return new Telemetry1882018PacketResponse() { Data = dataList };
|
return new Telemetry1882018PacketResponse() { Data = dataList };
|
||||||
|
|||||||
@ -31,7 +31,7 @@ namespace JiShe.CollectBus.Protocol.T1882018
|
|||||||
T188ControlHandlers = Telemetry1882018PacketBuilder.T1882018ControlHandlers;
|
T188ControlHandlers = Telemetry1882018PacketBuilder.T1882018ControlHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed override ProtocolInfo Info => new(nameof(T1882018ProtocolPlugin), "376.1/188-2018", "TCP", "376.1/188-2018协议", "HJ-LXS-15 DN15");
|
public sealed override ProtocolInfo Info => new(nameof(T1882018ProtocolPlugin), "376.1/188-2018", "TCP", "376.1/188-2018协议", "云集");
|
||||||
|
|
||||||
public override async Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? sendAction = null)
|
public override async Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? sendAction = null)
|
||||||
{
|
{
|
||||||
@ -93,9 +93,9 @@ namespace JiShe.CollectBus.Protocol.T1882018
|
|||||||
//数据转发场景 10H_F1
|
//数据转发场景 10H_F1
|
||||||
if (request.ItemCode == T37612012PacketItemCodeConst.AFN10HFN01H && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false)
|
if (request.ItemCode == T37612012PacketItemCodeConst.AFN10HFN01H && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false)
|
||||||
{
|
{
|
||||||
//var subItemCodeArr = request.SubProtocolRequest.ItemCode.Split("_");
|
var subItemCodeArr = request.SubProtocolRequest.ItemCode.Split("_");
|
||||||
|
|
||||||
var t188PacketHandlerName = $"{T1882018PacketItemCodeConst.BasicT1882018}_{request.SubProtocolRequest.ItemCode}_Send";
|
var t188PacketHandlerName = $"{subItemCodeArr[0]}_{subItemCodeArr[1]}_Send";
|
||||||
Telemetry1882018PacketResponse t645PacketResponse = null;
|
Telemetry1882018PacketResponse t645PacketResponse = null;
|
||||||
|
|
||||||
if (T188ControlHandlers != null && T188ControlHandlers.TryGetValue(t188PacketHandlerName
|
if (T188ControlHandlers != null && T188ControlHandlers.TryGetValue(t188PacketHandlerName
|
||||||
@ -124,6 +124,7 @@ namespace JiShe.CollectBus.Protocol.T1882018
|
|||||||
FocusAddress = request.FocusAddress,
|
FocusAddress = request.FocusAddress,
|
||||||
Fn = fn,
|
Fn = fn,
|
||||||
Pn = request.Pn,
|
Pn = request.Pn,
|
||||||
|
SubRequest = request.SubProtocolRequest,
|
||||||
DataUnit = dataUnit,
|
DataUnit = dataUnit,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,7 +101,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData.AFN_10H
|
|||||||
meter.DataValue = value;
|
meter.DataValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
meter.ItemType = "10_97";
|
meter.ItemType = T37612012PacketItemCodeConst.AFN10HFN97H;
|
||||||
meter.ValidData = data[2].Equals("91") || data[2].Equals("B1");
|
meter.ValidData = data[2].Equals("91") || data[2].Equals("B1");
|
||||||
meter.FiledDesc = "电网频率";//"电网频率";
|
meter.FiledDesc = "电网频率";//"电网频率";
|
||||||
meter.FiledName = meter.ItemType.GetDataFieldByGatherDataType() ?? string.Empty;
|
meter.FiledName = meter.ItemType.GetDataFieldByGatherDataType() ?? string.Empty;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using FreeRedis;
|
using Confluent.Kafka;
|
||||||
|
using FreeRedis;
|
||||||
using JiShe.CollectBus.Common;
|
using JiShe.CollectBus.Common;
|
||||||
using JiShe.CollectBus.Common.Consts;
|
using JiShe.CollectBus.Common.Consts;
|
||||||
using JiShe.CollectBus.Common.Encrypt;
|
using JiShe.CollectBus.Common.Encrypt;
|
||||||
@ -29,6 +30,7 @@ using Volo.Abp.DependencyInjection;
|
|||||||
using Volo.Abp.Guids;
|
using Volo.Abp.Guids;
|
||||||
using YamlDotNet.Core.Tokens;
|
using YamlDotNet.Core.Tokens;
|
||||||
using static FreeSql.Internal.GlobalFilter;
|
using static FreeSql.Internal.GlobalFilter;
|
||||||
|
using static IClientRPCService;
|
||||||
using static JiShe.CollectBus.Common.Consts.T37612012PacketItemCodeConst;
|
using static JiShe.CollectBus.Common.Consts.T37612012PacketItemCodeConst;
|
||||||
|
|
||||||
namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
||||||
@ -172,6 +174,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
{
|
{
|
||||||
// 新建
|
// 新建
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = DateTime.Now;
|
||||||
|
//特殊编码映射
|
||||||
|
var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(data.ItemType);
|
||||||
taskData = new MeterReadingTelemetryPacketInfo()
|
taskData = new MeterReadingTelemetryPacketInfo()
|
||||||
{
|
{
|
||||||
SystemName = _applicationOptions.SystemType,
|
SystemName = _applicationOptions.SystemType,
|
||||||
@ -190,7 +194,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
Fn = analysisBaseDto.Fn,
|
Fn = analysisBaseDto.Fn,
|
||||||
Seq = analysisBaseDto.PSEQ,
|
Seq = analysisBaseDto.PSEQ,
|
||||||
MSA = analysisBaseDto.MSA,
|
MSA = analysisBaseDto.MSA,
|
||||||
ItemCode = data.ItemType,
|
ItemCode = itemCodeInfo.Item1,
|
||||||
|
SubItemCode = itemCodeInfo.Item2,
|
||||||
TaskMark = taskMark,
|
TaskMark = taskMark,
|
||||||
IsSend = false,
|
IsSend = false,
|
||||||
ManualOrNot = false,
|
ManualOrNot = false,
|
||||||
@ -208,6 +213,31 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
if (!string.IsNullOrWhiteSpace(data.FiledName))
|
if (!string.IsNullOrWhiteSpace(data.FiledName))
|
||||||
{
|
{
|
||||||
await _dbProvider.GetSessionPool(false).InsertAsync(meter);
|
await _dbProvider.GetSessionPool(false).InsertAsync(meter);
|
||||||
|
// 增加标识字段
|
||||||
|
var meterIsSync = new TreeModelSingleMeasuringEntity<bool>()
|
||||||
|
{
|
||||||
|
SystemName = _applicationOptions.SystemType,
|
||||||
|
DeviceId = $"{data.DeviceId}",
|
||||||
|
DeviceType = $"{data.DeviceType}",
|
||||||
|
ProjectId = $"{data.ProjectId}",
|
||||||
|
DataType = analysisBaseDto.DataType,
|
||||||
|
Timestamps = meter.Timestamps,
|
||||||
|
SingleMeasuring = (IotDbFieldConst.IsSync, false)
|
||||||
|
};
|
||||||
|
await _dbProvider.GetSessionPool(false).InsertAsync(meterIsSync);
|
||||||
|
|
||||||
|
// 数据库业务ID
|
||||||
|
var meterIsDatabaseBusiID = new TreeModelSingleMeasuringEntity<int>()
|
||||||
|
{
|
||||||
|
SystemName = _applicationOptions.SystemType,
|
||||||
|
DeviceId = $"{data.DeviceId}",
|
||||||
|
DeviceType = $"{data.DeviceType}",
|
||||||
|
ProjectId = $"{data.ProjectId}",
|
||||||
|
DataType = analysisBaseDto.DataType,
|
||||||
|
Timestamps = meter.Timestamps,
|
||||||
|
SingleMeasuring = (IotDbFieldConst.DatabaseBusiID, data.DatabaseBusiID)
|
||||||
|
};
|
||||||
|
await _dbProvider.GetSessionPool(false).InsertAsync(meterIsDatabaseBusiID);
|
||||||
}
|
}
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
@ -225,6 +255,9 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
var data = analysisBaseDto.Data!;
|
var data = analysisBaseDto.Data!;
|
||||||
List<MeterReadingTelemetryPacketInfo> meterReadingTelemetryPacketInfos = new List<MeterReadingTelemetryPacketInfo>();
|
List<MeterReadingTelemetryPacketInfo> meterReadingTelemetryPacketInfos = new List<MeterReadingTelemetryPacketInfo>();
|
||||||
List<TreeModelSingleMeasuringEntity<T>> treeModelSingleMeasuringEntities = new List<TreeModelSingleMeasuringEntity<T>>();
|
List<TreeModelSingleMeasuringEntity<T>> treeModelSingleMeasuringEntities = new List<TreeModelSingleMeasuringEntity<T>>();
|
||||||
|
List<TreeModelSingleMeasuringEntity<bool>> meterIsSyncs = new List<TreeModelSingleMeasuringEntity<bool>>();
|
||||||
|
List<TreeModelSingleMeasuringEntity<int>> meterDataBaseIDs = new List<TreeModelSingleMeasuringEntity<int>>();
|
||||||
|
|
||||||
foreach (var item in data)
|
foreach (var item in data)
|
||||||
{
|
{
|
||||||
if(!item.TimeSpan.HasValue)
|
if(!item.TimeSpan.HasValue)
|
||||||
@ -278,6 +311,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
{
|
{
|
||||||
// 新建
|
// 新建
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = DateTime.Now;
|
||||||
|
//特殊编码映射
|
||||||
|
var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(item.ItemType);
|
||||||
taskData = new MeterReadingTelemetryPacketInfo()
|
taskData = new MeterReadingTelemetryPacketInfo()
|
||||||
{
|
{
|
||||||
SystemName = _applicationOptions.SystemType,
|
SystemName = _applicationOptions.SystemType,
|
||||||
@ -296,7 +331,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
Fn = analysisBaseDto.Fn,
|
Fn = analysisBaseDto.Fn,
|
||||||
Seq = analysisBaseDto.PSEQ,
|
Seq = analysisBaseDto.PSEQ,
|
||||||
MSA = analysisBaseDto.MSA,
|
MSA = analysisBaseDto.MSA,
|
||||||
ItemCode = item.ItemType,
|
ItemCode = itemCodeInfo.Item1,
|
||||||
|
SubItemCode = itemCodeInfo.Item2,
|
||||||
TaskMark = taskMark,
|
TaskMark = taskMark,
|
||||||
IsSend = false,
|
IsSend = false,
|
||||||
ManualOrNot = false,
|
ManualOrNot = false,
|
||||||
@ -314,6 +350,35 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
if (!string.IsNullOrWhiteSpace(item.FiledName) && item.ProjectId>0)
|
if (!string.IsNullOrWhiteSpace(item.FiledName) && item.ProjectId>0)
|
||||||
{
|
{
|
||||||
treeModelSingleMeasuringEntities.Add(meter);
|
treeModelSingleMeasuringEntities.Add(meter);
|
||||||
|
|
||||||
|
// 增加标识字段
|
||||||
|
var meterIsSync = new TreeModelSingleMeasuringEntity<bool>()
|
||||||
|
{
|
||||||
|
SystemName = _applicationOptions.SystemType,
|
||||||
|
DeviceId = $"{item.DeviceId}",
|
||||||
|
DeviceType = $"{item.DeviceType}",
|
||||||
|
ProjectId = $"{item.ProjectId}",
|
||||||
|
DataType = analysisBaseDto.DataType,
|
||||||
|
Timestamps = meter.Timestamps,
|
||||||
|
SingleMeasuring = (IotDbFieldConst.IsSync, false)
|
||||||
|
};
|
||||||
|
if(!meterIsSyncs.Any(a=> a.DataType == meterIsSync.DataType && a.ProjectId == meterIsSync.ProjectId && a.SystemName== meterIsSync.SystemName && a.DeviceId== meterIsSync.DeviceId && a.Timestamps== meterIsSync.Timestamps))
|
||||||
|
meterIsSyncs.Add(meterIsSync);
|
||||||
|
|
||||||
|
// 数据库业务ID
|
||||||
|
var meterIsDatabaseBusiID = new TreeModelSingleMeasuringEntity<int>()
|
||||||
|
{
|
||||||
|
SystemName = _applicationOptions.SystemType,
|
||||||
|
DeviceId = $"{item.DeviceId}",
|
||||||
|
DeviceType = $"{item.DeviceType}",
|
||||||
|
ProjectId = $"{item.ProjectId}",
|
||||||
|
DataType = analysisBaseDto.DataType,
|
||||||
|
Timestamps = meter.Timestamps,
|
||||||
|
SingleMeasuring = (IotDbFieldConst.DatabaseBusiID, item.DatabaseBusiID)
|
||||||
|
};
|
||||||
|
if (!meterDataBaseIDs.Any(a => a.DataType == meterIsSync.DataType && a.ProjectId == meterIsSync.ProjectId && a.SystemName == meterIsSync.SystemName && a.DeviceId == meterIsSync.DeviceId && a.Timestamps == meterIsSync.Timestamps))
|
||||||
|
meterDataBaseIDs.Add(meterIsDatabaseBusiID);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 批量保存数据
|
// 批量保存数据
|
||||||
@ -321,6 +386,11 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
if (treeModelSingleMeasuringEntities.Count > 0)
|
if (treeModelSingleMeasuringEntities.Count > 0)
|
||||||
{
|
{
|
||||||
await _dbProvider.GetSessionPool(false).BatchInsertAsync(treeModelSingleMeasuringEntities);
|
await _dbProvider.GetSessionPool(false).BatchInsertAsync(treeModelSingleMeasuringEntities);
|
||||||
|
|
||||||
|
// 报存标识字段
|
||||||
|
await _dbProvider.GetSessionPool(false).BatchInsertAsync(meterIsSyncs);
|
||||||
|
await _dbProvider.GetSessionPool(false).BatchInsertAsync(meterDataBaseIDs);
|
||||||
|
|
||||||
}
|
}
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
@ -365,7 +435,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
ProjectId = $"{data.ProjectId}",
|
ProjectId = $"{data.ProjectId}",
|
||||||
DataType = IOTDBDataTypeConst.Status,
|
DataType = IOTDBDataTypeConst.Status,
|
||||||
Timestamps = timestamps,
|
Timestamps = timestamps,
|
||||||
SingleMeasuring = (ConcentratorStatusFieldConst.FrameData, analysisBaseDto.ReceivedHexMessage ?? string.Empty)
|
SingleMeasuring = (IotDbFieldConst.FrameData, analysisBaseDto.ReceivedHexMessage ?? string.Empty)
|
||||||
};
|
};
|
||||||
await _dbProvider.GetSessionPool(false).InsertAsync(treeFrameData);
|
await _dbProvider.GetSessionPool(false).InsertAsync(treeFrameData);
|
||||||
|
|
||||||
@ -378,7 +448,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
ProjectId = $"{data.ProjectId}",
|
ProjectId = $"{data.ProjectId}",
|
||||||
Timestamps = timestamps,
|
Timestamps = timestamps,
|
||||||
DataType = IOTDBDataTypeConst.Status,
|
DataType = IOTDBDataTypeConst.Status,
|
||||||
SingleMeasuring = (ConcentratorStatusFieldConst.RecordingTime, data.TimeSpan.HasValue ? data.TimeSpan.Value : DateTime.Now)
|
SingleMeasuring = (IotDbFieldConst.RecordingTime, data.TimeSpan.HasValue ? data.TimeSpan.Value : DateTime.Now)
|
||||||
};
|
};
|
||||||
await _dbProvider.GetSessionPool(false).InsertAsync(treeRecordingTimeData);
|
await _dbProvider.GetSessionPool(false).InsertAsync(treeRecordingTimeData);
|
||||||
}
|
}
|
||||||
@ -386,6 +456,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
// 新建
|
// 新建
|
||||||
string taskMark = CommonHelper.GetTaskMark(analysisBaseDto.AFN, analysisBaseDto.Fn, analysisBaseDto.Pn, analysisBaseDto.MSA, analysisBaseDto.PSEQ);
|
string taskMark = CommonHelper.GetTaskMark(analysisBaseDto.AFN, analysisBaseDto.Fn, analysisBaseDto.Pn, analysisBaseDto.MSA, analysisBaseDto.PSEQ);
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = DateTime.Now;
|
||||||
|
//特殊编码映射
|
||||||
|
var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(data.ItemType);
|
||||||
var taskData = new MeterReadingTelemetryPacketInfo()
|
var taskData = new MeterReadingTelemetryPacketInfo()
|
||||||
{
|
{
|
||||||
SystemName = _applicationOptions.SystemType,
|
SystemName = _applicationOptions.SystemType,
|
||||||
@ -404,7 +476,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
Fn = analysisBaseDto.Fn,
|
Fn = analysisBaseDto.Fn,
|
||||||
Seq = analysisBaseDto.PSEQ,
|
Seq = analysisBaseDto.PSEQ,
|
||||||
MSA = analysisBaseDto.MSA,
|
MSA = analysisBaseDto.MSA,
|
||||||
ItemCode = data.ItemType,
|
ItemCode = itemCodeInfo.Item1,
|
||||||
|
SubItemCode = itemCodeInfo.Item2,
|
||||||
TaskMark = taskMark,
|
TaskMark = taskMark,
|
||||||
IsSend = false,
|
IsSend = false,
|
||||||
ManualOrNot = false,
|
ManualOrNot = false,
|
||||||
@ -463,7 +536,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
ProjectId = $"{item.ProjectId}",
|
ProjectId = $"{item.ProjectId}",
|
||||||
DataType = IOTDBDataTypeConst.Status,
|
DataType = IOTDBDataTypeConst.Status,
|
||||||
Timestamps = timestamps,
|
Timestamps = timestamps,
|
||||||
SingleMeasuring = (ConcentratorStatusFieldConst.FrameData, analysisBaseDto.ReceivedHexMessage ?? string.Empty)
|
SingleMeasuring = (IotDbFieldConst.FrameData, analysisBaseDto.ReceivedHexMessage ?? string.Empty)
|
||||||
};
|
};
|
||||||
|
|
||||||
await _dbProvider.GetSessionPool(false).InsertAsync(treeFrameData);
|
await _dbProvider.GetSessionPool(false).InsertAsync(treeFrameData);
|
||||||
@ -476,7 +549,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
ProjectId = $"{item.ProjectId}",
|
ProjectId = $"{item.ProjectId}",
|
||||||
DataType = IOTDBDataTypeConst.Status,
|
DataType = IOTDBDataTypeConst.Status,
|
||||||
Timestamps = timestamps,
|
Timestamps = timestamps,
|
||||||
SingleMeasuring = (ConcentratorStatusFieldConst.RecordingTime, item.TimeSpan.HasValue ? item.TimeSpan.Value : DateTime.Now)
|
SingleMeasuring = (IotDbFieldConst.RecordingTime, item.TimeSpan.HasValue ? item.TimeSpan.Value : DateTime.Now)
|
||||||
};
|
};
|
||||||
await _dbProvider.GetSessionPool(false).InsertAsync(treeRecordingTimeData);
|
await _dbProvider.GetSessionPool(false).InsertAsync(treeRecordingTimeData);
|
||||||
|
|
||||||
@ -485,6 +558,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
// 新建
|
// 新建
|
||||||
string taskMark = CommonHelper.GetTaskMark(analysisBaseDto.AFN, analysisBaseDto.Fn, analysisBaseDto.Pn, analysisBaseDto.MSA, analysisBaseDto.PSEQ);
|
string taskMark = CommonHelper.GetTaskMark(analysisBaseDto.AFN, analysisBaseDto.Fn, analysisBaseDto.Pn, analysisBaseDto.MSA, analysisBaseDto.PSEQ);
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = DateTime.Now;
|
||||||
|
//特殊编码映射
|
||||||
|
var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(item.ItemType);
|
||||||
var taskData = new MeterReadingTelemetryPacketInfo()
|
var taskData = new MeterReadingTelemetryPacketInfo()
|
||||||
{
|
{
|
||||||
SystemName = _applicationOptions.SystemType,
|
SystemName = _applicationOptions.SystemType,
|
||||||
@ -503,7 +578,8 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
|
|||||||
Fn = analysisBaseDto.Fn,
|
Fn = analysisBaseDto.Fn,
|
||||||
Seq = analysisBaseDto.PSEQ,
|
Seq = analysisBaseDto.PSEQ,
|
||||||
MSA = analysisBaseDto.MSA,
|
MSA = analysisBaseDto.MSA,
|
||||||
ItemCode = item.ItemType,
|
ItemCode = itemCodeInfo.Item1,
|
||||||
|
SubItemCode = itemCodeInfo.Item2,
|
||||||
TaskMark = taskMark,
|
TaskMark = taskMark,
|
||||||
IsSend = false,
|
IsSend = false,
|
||||||
ManualOrNot = false,
|
ManualOrNot = false,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Reflection;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using JiShe.CollectBus.Common.BuildSendDatas;
|
using JiShe.CollectBus.Common.BuildSendDatas;
|
||||||
using JiShe.CollectBus.Common.Extensions;
|
using JiShe.CollectBus.Common.Extensions;
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ namespace JiShe.CollectBus.Protocol.T6452007.SendData
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 读数据
|
#region 读数据 命名规则:C控制码_DI3
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 变量数据标识编码处理
|
/// 变量数据标识编码处理
|
||||||
@ -109,7 +110,7 @@ namespace JiShe.CollectBus.Protocol.T6452007.SendData
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Telemetry6452007PacketResponse C11_02_Send(Telemetry6452007PacketRequest request)
|
public static Telemetry6452007PacketResponse C11_02_Send(Telemetry6452007PacketRequest request)
|
||||||
{
|
{
|
||||||
var itemCodeArr = request.ItemCode.Split('_');//11_02_80_00_02
|
var itemCodeArr = request.ItemCode.Split('_');//11_02_80_00_02,控制码_DI3_DI2_DI1_DI0
|
||||||
var c_data = itemCodeArr[0];
|
var c_data = itemCodeArr[0];
|
||||||
var DI3 = itemCodeArr[1];
|
var DI3 = itemCodeArr[1];
|
||||||
var DI2 = itemCodeArr[2];
|
var DI2 = itemCodeArr[2];
|
||||||
@ -118,6 +119,8 @@ namespace JiShe.CollectBus.Protocol.T6452007.SendData
|
|||||||
|
|
||||||
var dataUnit = new List<string>() { DI3, DI2, DI1, DI0 };
|
var dataUnit = new List<string>() { DI3, DI2, DI1, DI0 };
|
||||||
|
|
||||||
|
dataUnit.Reverse();
|
||||||
|
|
||||||
var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit);
|
var dataList = Build645SendData.Build645SendCommand(request.MeterAddress, c_data, dataUnit);
|
||||||
return new Telemetry6452007PacketResponse() { Data = dataList };
|
return new Telemetry6452007PacketResponse() { Data = dataList };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,38 +36,6 @@ namespace JiShe.CollectBus.Protocol.T6452007
|
|||||||
|
|
||||||
public override async Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? sendAction = null)
|
public override async Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? sendAction = null)
|
||||||
{
|
{
|
||||||
//TODO:645解析报文
|
|
||||||
//TB3761? tB3761 = Analysis3761(messageReceived);
|
|
||||||
//if (tB3761 != null)
|
|
||||||
//{
|
|
||||||
// if (tB3761.AFN_FC?.AFN == (int)AFN.链路接口检测)
|
|
||||||
// {
|
|
||||||
// if (tB3761.A == null || tB3761.A.Code.IsNullOrWhiteSpace() || tB3761.A.A3?.D1_D7 == null || tB3761.SEQ?.PSEQ == null)
|
|
||||||
// {
|
|
||||||
// _logger.LogError($"解析AFN.链路接口检测报文失败,报文:{messageReceived},TB3761:{tB3761.Serialize()}");
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// if (tB3761.DT?.Fn == (int)FN.登录)
|
|
||||||
// {
|
|
||||||
// // 登录回复
|
|
||||||
// if (tB3761.SEQ.CON == (int)CON.需要对该帧进行确认)
|
|
||||||
// await LoginAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ);
|
|
||||||
// }
|
|
||||||
// else if (tB3761.DT?.Fn == (int)FN.心跳)
|
|
||||||
// {
|
|
||||||
// // 心跳回复
|
|
||||||
// //心跳帧有两种情况:
|
|
||||||
// //1. 集中器先有登录帧,再有心跳帧
|
|
||||||
// //2. 集中器没有登录帧,只有心跳帧
|
|
||||||
// await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// await OnTcpNormalReceived(client, tB3761);
|
|
||||||
//}
|
|
||||||
//return (tB3761 as T)!;
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,15 +17,13 @@ namespace JiShe.CollectBus.Application.Contracts
|
|||||||
/// 单个添加数据
|
/// 单个添加数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="redisHashCacheKey">主数据存储Hash缓存Key</param>
|
|
||||||
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
||||||
/// <param name="redisZSetScoresIndexCacheKey">ZSET索引缓存Key</param>
|
/// <param name="redisDeviceInfoHashCacheKey">hash缓存Key</param>
|
||||||
/// <param name="data">待缓存数据</param>
|
/// <param name="data">待缓存数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task InsertDataAsync<T>(
|
Task InsertDataAsync<T>(
|
||||||
string redisHashCacheKey,
|
|
||||||
string redisSetIndexCacheKey,
|
string redisSetIndexCacheKey,
|
||||||
string redisZSetScoresIndexCacheKey,
|
string redisDeviceInfoHashCacheKey,
|
||||||
T data) where T : DeviceCacheBasicModel;
|
T data) where T : DeviceCacheBasicModel;
|
||||||
|
|
||||||
|
|
||||||
@ -47,15 +45,13 @@ namespace JiShe.CollectBus.Application.Contracts
|
|||||||
/// 删除缓存信息
|
/// 删除缓存信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="redisHashCacheKey">主数据存储Hash缓存Key</param>
|
|
||||||
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
||||||
/// <param name="redisZSetScoresIndexCacheKey">ZSET索引缓存Key</param>
|
/// <param name="redisDeviceInfoHashCacheKey">hash缓存Key</param>
|
||||||
/// <param name="data">已缓存数据</param>
|
/// <param name="data">已缓存数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task RemoveCacheDataAsync<T>(
|
Task RemoveCacheDataAsync<T>(
|
||||||
string redisHashCacheKey,
|
|
||||||
string redisSetIndexCacheKey,
|
string redisSetIndexCacheKey,
|
||||||
string redisZSetScoresIndexCacheKey,
|
string redisDeviceInfoHashCacheKey,
|
||||||
T data) where T : DeviceCacheBasicModel;
|
T data) where T : DeviceCacheBasicModel;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -94,6 +94,7 @@ public class CollectBusApplicationModule : AbpModule
|
|||||||
|
|
||||||
//默认初始化表计信息
|
//默认初始化表计信息
|
||||||
var dbContext = context.ServiceProvider.GetRequiredService<EnergySystemScheduledMeterReadingService>();
|
var dbContext = context.ServiceProvider.GetRequiredService<EnergySystemScheduledMeterReadingService>();
|
||||||
await dbContext.InitAmmeterCacheData();
|
await dbContext.InitAmmeterCacheData("V4-Gather-8890");
|
||||||
|
await dbContext.InitWatermeterCacheData("V4-Gather-8890");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,6 +17,7 @@ using static FreeSql.Internal.GlobalFilter;
|
|||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
using static Volo.Abp.UI.Navigation.DefaultMenuNames.Application;
|
using static Volo.Abp.UI.Navigation.DefaultMenuNames.Application;
|
||||||
using JiShe.CollectBus.IotSystems.Ammeters;
|
using JiShe.CollectBus.IotSystems.Ammeters;
|
||||||
|
using System.IO.Pipelines;
|
||||||
|
|
||||||
namespace JiShe.CollectBus.RedisDataCache
|
namespace JiShe.CollectBus.RedisDataCache
|
||||||
{
|
{
|
||||||
@ -47,21 +48,18 @@ namespace JiShe.CollectBus.RedisDataCache
|
|||||||
/// 单个添加数据
|
/// 单个添加数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="redisHashCacheKey">主数据存储Hash缓存Key</param>
|
|
||||||
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
||||||
/// <param name="redisZSetScoresIndexCacheKey">ZSET索引缓存Key</param>
|
/// <param name="redisDeviceInfoHashCacheKey">hash缓存Key</param>
|
||||||
/// <param name="data">待缓存数据</param>
|
/// <param name="data">待缓存数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task InsertDataAsync<T>(
|
public async Task InsertDataAsync<T>(
|
||||||
string redisHashCacheKey,
|
|
||||||
string redisSetIndexCacheKey,
|
string redisSetIndexCacheKey,
|
||||||
string redisZSetScoresIndexCacheKey,
|
string redisDeviceInfoHashCacheKey,
|
||||||
T data) where T : DeviceCacheBasicModel
|
T data) where T : DeviceCacheBasicModel
|
||||||
{
|
{
|
||||||
// 参数校验增强
|
// 参数校验增强
|
||||||
if (data == null || string.IsNullOrWhiteSpace(redisHashCacheKey)
|
if (data == null || string.IsNullOrWhiteSpace(redisSetIndexCacheKey)
|
||||||
|| string.IsNullOrWhiteSpace(redisSetIndexCacheKey)
|
|| string.IsNullOrWhiteSpace(redisDeviceInfoHashCacheKey))
|
||||||
|| string.IsNullOrWhiteSpace(redisZSetScoresIndexCacheKey))
|
|
||||||
{
|
{
|
||||||
_logger.LogError($"{nameof(InsertDataAsync)} 参数异常,-101");
|
_logger.LogError($"{nameof(InsertDataAsync)} 参数异常,-101");
|
||||||
return;
|
return;
|
||||||
@ -70,14 +68,27 @@ namespace JiShe.CollectBus.RedisDataCache
|
|||||||
// 使用事务保证原子性
|
// 使用事务保证原子性
|
||||||
using (var trans = Instance.Multi())
|
using (var trans = Instance.Multi())
|
||||||
{
|
{
|
||||||
// 主数据存储Hash
|
// Set索引缓存
|
||||||
trans.HSet(redisHashCacheKey, data.MemberId, data.Serialize());
|
trans.SAdd(redisSetIndexCacheKey, $"{data.TimeDensity.ToString().PadLeft(2, '0')}:{data.FocusAddress}");
|
||||||
|
|
||||||
// 集中器号分组索引Set缓存
|
//检查HSet是否存在对应的信息,如果存在,需要进一步检查value是否已经存在,如果存在则更新,不存在则添加
|
||||||
trans.SAdd(redisSetIndexCacheKey, data.MemberId);
|
var oldValue = Instance.HGet<List<T>>(redisDeviceInfoHashCacheKey, data.FocusAddress);
|
||||||
|
if (oldValue == null || oldValue.Count <= 0)//直接添加
|
||||||
|
{
|
||||||
|
//设备信息缓存
|
||||||
|
trans.HSet(redisDeviceInfoHashCacheKey, data.FocusAddress, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 移除缓存中同类型旧数据
|
||||||
|
oldValue.RemoveAll(device => device.MeterType == data.MeterType);
|
||||||
|
|
||||||
// 集中器与表计信息排序索引ZSET缓存Key
|
//添加新数据
|
||||||
trans.ZAdd(redisZSetScoresIndexCacheKey, data.ScoreValue, data.MemberId);
|
oldValue.Add(data);
|
||||||
|
|
||||||
|
//设备信息缓存
|
||||||
|
trans.HSet(redisDeviceInfoHashCacheKey, data.FocusAddress, oldValue);
|
||||||
|
}
|
||||||
|
|
||||||
var results = trans.Exec();
|
var results = trans.Exec();
|
||||||
|
|
||||||
@ -129,9 +140,24 @@ namespace JiShe.CollectBus.RedisDataCache
|
|||||||
// Set索引缓存
|
// Set索引缓存
|
||||||
pipe.SAdd(redisSetIndexCacheKey, $"{item.Value.First().TimeDensity.ToString().PadLeft(2, '0')}:{item.Value.First().FocusAddress}");
|
pipe.SAdd(redisSetIndexCacheKey, $"{item.Value.First().TimeDensity.ToString().PadLeft(2, '0')}:{item.Value.First().FocusAddress}");
|
||||||
|
|
||||||
|
//检查HSet是否存在对应的信息,如果存在,需要进一步检查value是否已经存在,如果存在则更新,不存在则添加
|
||||||
|
var oldValue = Instance.HGet<List<T>>(redisDeviceInfoHashCacheKey, item.Key);
|
||||||
|
if (oldValue == null || oldValue.Count <= 0)//直接添加
|
||||||
|
{
|
||||||
//设备信息缓存
|
//设备信息缓存
|
||||||
pipe.HSet(redisDeviceInfoHashCacheKey, item.Key, item.Value.Serialize());
|
pipe.HSet(redisDeviceInfoHashCacheKey, item.Key, item.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 移除缓存中同类型旧数据
|
||||||
|
oldValue.RemoveAll(device => device.MeterType == item.Value[0].MeterType);
|
||||||
|
|
||||||
|
//添加新数据
|
||||||
|
oldValue.AddRange(item.Value);
|
||||||
|
|
||||||
|
//设备信息缓存
|
||||||
|
pipe.HSet(redisDeviceInfoHashCacheKey, item.Key, oldValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pipe.EndPipe();
|
pipe.EndPipe();
|
||||||
}
|
}
|
||||||
@ -146,21 +172,18 @@ namespace JiShe.CollectBus.RedisDataCache
|
|||||||
/// 删除缓存信息
|
/// 删除缓存信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="redisHashCacheKey">主数据存储Hash缓存Key</param>
|
|
||||||
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
/// <param name="redisSetIndexCacheKey">Set索引缓存Key</param>
|
||||||
/// <param name="redisZSetScoresIndexCacheKey">ZSET索引缓存Key</param>
|
/// <param name="redisDeviceInfoHashCacheKey">hash缓存Key</param>
|
||||||
/// <param name="data">已缓存数据</param>
|
/// <param name="data">已缓存数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task RemoveCacheDataAsync<T>(
|
public async Task RemoveCacheDataAsync<T>(
|
||||||
string redisHashCacheKey,
|
|
||||||
string redisSetIndexCacheKey,
|
string redisSetIndexCacheKey,
|
||||||
string redisZSetScoresIndexCacheKey,
|
string redisDeviceInfoHashCacheKey,
|
||||||
T data) where T : DeviceCacheBasicModel
|
T data) where T : DeviceCacheBasicModel
|
||||||
{
|
{
|
||||||
if (data == null
|
if (data == null
|
||||||
|| string.IsNullOrWhiteSpace(redisHashCacheKey)
|
|| string.IsNullOrWhiteSpace(redisDeviceInfoHashCacheKey)
|
||||||
|| string.IsNullOrWhiteSpace(redisSetIndexCacheKey)
|
|| string.IsNullOrWhiteSpace(redisSetIndexCacheKey) )
|
||||||
|| string.IsNullOrWhiteSpace(redisZSetScoresIndexCacheKey))
|
|
||||||
{
|
{
|
||||||
_logger.LogError($"{nameof(RemoveCacheDataAsync)} 参数异常,-101");
|
_logger.LogError($"{nameof(RemoveCacheDataAsync)} 参数异常,-101");
|
||||||
return;
|
return;
|
||||||
@ -169,31 +192,29 @@ namespace JiShe.CollectBus.RedisDataCache
|
|||||||
const string luaScript = @"
|
const string luaScript = @"
|
||||||
local hashCacheKey = KEYS[1]
|
local hashCacheKey = KEYS[1]
|
||||||
local setIndexCacheKey = KEYS[2]
|
local setIndexCacheKey = KEYS[2]
|
||||||
local zsetScoresIndexCacheKey = KEYS[3]
|
local focusAddress = ARGV[1]
|
||||||
local member = ARGV[1]
|
local scoreValue = ARGV[2]
|
||||||
|
|
||||||
local deleted = 0
|
local deleted = 0
|
||||||
if redis.call('HDEL', hashCacheKey, member) > 0 then
|
if redis.call('HDEL', hashCacheKey, focusAddress) > 0 then
|
||||||
deleted = 1
|
deleted = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
redis.call('SREM', setIndexCacheKey, member)
|
redis.call('SREM', setIndexCacheKey, scoreValue)
|
||||||
redis.call('ZREM', zsetScoresIndexCacheKey, member)
|
|
||||||
return deleted
|
return deleted
|
||||||
";
|
";
|
||||||
|
|
||||||
var keys = new[]
|
var keys = new[]
|
||||||
{
|
{
|
||||||
redisHashCacheKey,
|
redisDeviceInfoHashCacheKey,
|
||||||
redisSetIndexCacheKey,
|
redisSetIndexCacheKey
|
||||||
redisZSetScoresIndexCacheKey
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await Instance.EvalAsync(luaScript, keys, new[] { data.MemberId });
|
var result = await Instance.EvalAsync(luaScript, keys, new object[] { data.FocusAddress , data.ScoreValue});
|
||||||
|
|
||||||
if ((int)result == 0)
|
if ((int)result == 0)
|
||||||
{
|
{
|
||||||
_logger.LogError($"{nameof(RemoveCacheDataAsync)} 删除指定Key{redisHashCacheKey}的{data.MemberId}数据失败,-102");
|
_logger.LogError($"{nameof(RemoveCacheDataAsync)} 删除指定Key{redisDeviceInfoHashCacheKey}的{data.MemberId}数据失败,-102");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,7 @@ using Microsoft.Extensions.Options;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.Metrics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TouchSocket.Core;
|
using TouchSocket.Core;
|
||||||
using TouchSocket.Sockets;
|
using TouchSocket.Sockets;
|
||||||
@ -585,5 +586,35 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
|
|||||||
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IoTDB空表查询情况
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task TestIoTDBEmptyTableQuery()
|
||||||
|
{
|
||||||
|
var meter = new MeterReadingTelemetryPacketInfo() { DevicePath = "MeterReadingTelemetryPacketInfo", DeviceId = "1111" };
|
||||||
|
QueryCondition conditions = new QueryCondition()
|
||||||
|
{
|
||||||
|
Field = "DeviceId",
|
||||||
|
Operator = "=",
|
||||||
|
Value = meter.DeviceId
|
||||||
|
};
|
||||||
|
var query = new IoTDBQueryOptions()
|
||||||
|
{
|
||||||
|
TableNameOrTreePath = meter.DevicePath,
|
||||||
|
PageIndex = 1,
|
||||||
|
PageSize = 1,
|
||||||
|
Conditions = new List<QueryCondition>() { conditions },
|
||||||
|
};
|
||||||
|
|
||||||
|
await _iotDBProvider.GetSessionPool(true).InitTableSessionModelAsync();
|
||||||
|
|
||||||
|
var pageResult = await _iotDBProvider.GetSessionPool(true).QueryAsync<MeterReadingTelemetryPacketInfo>(query);
|
||||||
|
|
||||||
|
await Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ using JiShe.CollectBus.Common.Extensions;
|
|||||||
using JiShe.CollectBus.Common.Helpers;
|
using JiShe.CollectBus.Common.Helpers;
|
||||||
using JiShe.CollectBus.Common.Models;
|
using JiShe.CollectBus.Common.Models;
|
||||||
using JiShe.CollectBus.DataChannels;
|
using JiShe.CollectBus.DataChannels;
|
||||||
|
using JiShe.CollectBus.EnergySystems.Entities;
|
||||||
using JiShe.CollectBus.GatherItem;
|
using JiShe.CollectBus.GatherItem;
|
||||||
using JiShe.CollectBus.IoTDB.Interface;
|
using JiShe.CollectBus.IoTDB.Interface;
|
||||||
using JiShe.CollectBus.IoTDB.Model;
|
using JiShe.CollectBus.IoTDB.Model;
|
||||||
@ -28,6 +29,9 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Volo.Abp.Guids;
|
using Volo.Abp.Guids;
|
||||||
|
using static FreeSql.Internal.GlobalFilter;
|
||||||
|
using static Microsoft.AspNetCore.Razor.Language.TagHelperMetadata;
|
||||||
|
using static Thrift.Protocol.Utilities.TJSONProtocolConstants;
|
||||||
|
|
||||||
namespace JiShe.CollectBus.ScheduledMeterReading
|
namespace JiShe.CollectBus.ScheduledMeterReading
|
||||||
{
|
{
|
||||||
@ -129,125 +133,32 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
var tempArryay = item.Split(":");
|
var tempArryay = item.Split(":");
|
||||||
string meteryType = tempArryay[4];//表计类别
|
string meteryType = tempArryay[4];//表计类别
|
||||||
int timeDensity = Convert.ToInt32(tempArryay[5]);//采集频率
|
int timeDensity = Convert.ToInt32(tempArryay[5]);//采集频率
|
||||||
if (timeDensity > 15)
|
|
||||||
{
|
|
||||||
timeDensity = 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//电表定时广播校时,一天一次。
|
//电表定时广播校时,一天一次。
|
||||||
string currentTimeStr = $"{currentTime:HH:mm:00}";
|
string currentTimeStr = $"{currentTime:HH:mm:00}";
|
||||||
//if (string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))//自动校时
|
if (string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))//自动校时
|
||||||
//{
|
{
|
||||||
// //_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
|
//_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
|
||||||
// //return;
|
//return;
|
||||||
|
|
||||||
// _ = CreateMeterPublishTask<DeviceInfo>(
|
_ = CreateMeterPublishTask<DeviceInfo>(
|
||||||
// timeDensity: timeDensity,
|
timeDensity: timeDensity,
|
||||||
// nextTaskTime: currentTime,
|
nextTaskTime: currentTime,
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
meterType: MeterTypeEnum.Ammeter,
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
||||||
// {
|
{
|
||||||
// var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps);
|
var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps);
|
||||||
|
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))//集中器版本号读取
|
|
||||||
//{
|
|
||||||
// _ = CreateMeterPublishTask<DeviceInfo>(
|
|
||||||
// timeDensity: timeDensity,
|
|
||||||
// nextTaskTime: currentTime,
|
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
|
||||||
// {
|
|
||||||
// var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps);
|
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//SIM卡读取
|
|
||||||
//{
|
|
||||||
// _ = CreateMeterPublishTask<DeviceInfo>(
|
|
||||||
// timeDensity: timeDensity,
|
|
||||||
// nextTaskTime: currentTime,
|
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
|
||||||
// {
|
|
||||||
// var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps);
|
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//月冻结
|
|
||||||
//{
|
|
||||||
// _ = CreateMeterPublishTask<DeviceInfo>(
|
|
||||||
// timeDensity: timeDensity,
|
|
||||||
// nextTaskTime: currentTime,
|
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
|
||||||
// {
|
|
||||||
// var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps);
|
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))//日冻结
|
|
||||||
//{
|
|
||||||
// _ = CreateMeterPublishTask<DeviceInfo>(
|
|
||||||
// timeDensity: timeDensity,
|
|
||||||
// nextTaskTime: currentTime,
|
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
|
||||||
// {
|
|
||||||
// var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps);
|
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// _logger.LogInformation($"{nameof(CreateToBeIssueTasks)} 不是自动校时、采集终端信息等时间,继续处理其他");
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//_ = CreateMeterPublishTask<DeviceInfo>(
|
|
||||||
// timeDensity: timeDensity,
|
|
||||||
// nextTaskTime: currentTime,
|
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
|
||||||
// {
|
|
||||||
// var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps);
|
|
||||||
|
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
if (tempTask == null || tempTask.Count <= 0)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))//集中器版本号读取
|
||||||
|
{
|
||||||
_ = CreateMeterPublishTask<DeviceInfo>(
|
_ = CreateMeterPublishTask<DeviceInfo>(
|
||||||
timeDensity: timeDensity,
|
timeDensity: timeDensity,
|
||||||
nextTaskTime: currentTime,
|
nextTaskTime: currentTime,
|
||||||
@ -257,58 +168,67 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps);
|
var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps);
|
||||||
if (tempTask == null || tempTask.Count <= 0)
|
if (tempTask == null || tempTask.Count <= 0)
|
||||||
{
|
{
|
||||||
_logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
_logger.LogWarning($"集中器终端版本信息 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
//_ = CreateMeterPublishTask<DeviceInfo>(
|
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//SIM卡读取
|
||||||
// timeDensity: timeDensity,
|
{
|
||||||
// nextTaskTime: currentTime,
|
_ = CreateMeterPublishTask<DeviceInfo>(
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
timeDensity: timeDensity,
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
nextTaskTime: currentTime,
|
||||||
// {
|
meterType: MeterTypeEnum.Ammeter,
|
||||||
// var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps);
|
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
{
|
||||||
// {
|
var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps);
|
||||||
// _logger.LogWarning($"集中器 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
if (tempTask == null || tempTask.Count <= 0)
|
||||||
// return;
|
{
|
||||||
// }
|
_logger.LogWarning($"集中器SIM卡读取 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
return;
|
||||||
// });
|
}
|
||||||
|
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
||||||
//_ = CreateMeterPublishTask<DeviceInfo>(
|
});
|
||||||
// timeDensity: timeDensity,
|
}
|
||||||
// nextTaskTime: currentTime,
|
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticMonthFreezeTime, StringComparison.CurrentCultureIgnoreCase))//月冻结
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
{
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
_ = CreateMeterPublishTask<DeviceInfo>(
|
||||||
// {
|
timeDensity: timeDensity,
|
||||||
// var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps);
|
nextTaskTime: currentTime,
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
meterType: MeterTypeEnum.Ammeter,
|
||||||
// {
|
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
||||||
// _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
{
|
||||||
// return;
|
var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps);
|
||||||
// }
|
if (tempTask == null || tempTask.Count <= 0)
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
{
|
||||||
// });
|
_logger.LogWarning($"电表月冻结 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
||||||
//_ = CreateMeterPublishTask<DeviceInfo>(
|
});
|
||||||
// timeDensity: timeDensity,
|
}
|
||||||
// nextTaskTime: currentTime,
|
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))//日冻结
|
||||||
// meterType: MeterTypeEnum.Ammeter,
|
{
|
||||||
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
_ = CreateMeterPublishTask<DeviceInfo>(
|
||||||
// {
|
timeDensity: timeDensity,
|
||||||
// var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps);
|
nextTaskTime: currentTime,
|
||||||
// if (tempTask == null || tempTask.Count <= 0)
|
meterType: MeterTypeEnum.Ammeter,
|
||||||
// {
|
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
|
||||||
// _logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
{
|
||||||
// return;
|
var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps);
|
||||||
// }
|
if (tempTask == null || tempTask.Count <= 0)
|
||||||
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
{
|
||||||
// });
|
_logger.LogWarning($"电表日冻结 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"{nameof(CreateToBeIssueTasks)} 不是自动校时、采集终端信息等时间,继续处理其他");
|
||||||
|
}
|
||||||
|
|
||||||
//检查任务时间节点,由于定时任务10秒钟运行一次,需要判定当前时间是否在任务时间节点内,不在则跳过
|
//检查任务时间节点,由于定时任务10秒钟运行一次,需要判定当前时间是否在任务时间节点内,不在则跳过
|
||||||
var currentTaskTime = tasksToBeIssueModel.LastTaskTime.CalculateNextCollectionTime(timeDensity);//程序启动缓存电表的时候,NextTaskTime需要格式化到下一个采集点时间。
|
var currentTaskTime = tasksToBeIssueModel.LastTaskTime.CalculateNextCollectionTime(timeDensity);//程序启动缓存电表的时候,NextTaskTime需要格式化到下一个采集点时间。
|
||||||
@ -320,10 +240,14 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
var meterTypes = EnumExtensions.ToEnumDictionary<MeterTypeEnum>();
|
var meterTypes = EnumExtensions.ToEnumDictionary<MeterTypeEnum>();
|
||||||
|
|
||||||
//tasksToBeIssueModel.NextTaskTime;
|
|
||||||
|
|
||||||
if (meteryType == MeterTypeEnum.Ammeter.ToString())
|
if (meteryType == MeterTypeEnum.Ammeter.ToString())
|
||||||
{
|
{
|
||||||
|
//电表最大采集频率为15分钟
|
||||||
|
if (timeDensity > 15)
|
||||||
|
{
|
||||||
|
timeDensity = 15;
|
||||||
|
}
|
||||||
|
|
||||||
_ = CreateMeterPublishTask<DeviceInfo>(
|
_ = CreateMeterPublishTask<DeviceInfo>(
|
||||||
timeDensity: timeDensity,
|
timeDensity: timeDensity,
|
||||||
nextTaskTime: currentTaskTime,
|
nextTaskTime: currentTaskTime,
|
||||||
@ -333,7 +257,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
var tempTask = await AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
|
var tempTask = await AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
|
||||||
if (tempTask == null || tempTask.Count <= 0)
|
if (tempTask == null || tempTask.Count <= 0)
|
||||||
{
|
{
|
||||||
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempTask));
|
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempTask));
|
||||||
@ -410,6 +334,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
// 创建取消令牌源
|
// 创建取消令牌源
|
||||||
//var cts = new CancellationTokenSource();
|
//var cts = new CancellationTokenSource();
|
||||||
|
|
||||||
|
await _dbProvider.GetSessionPool(true).InitTableSessionModelAsync();
|
||||||
|
|
||||||
_ = _dataChannelManage.ScheduledMeterTaskReadingAsync(DataChannelManage.TaskDataChannel.Reader);
|
_ = _dataChannelManage.ScheduledMeterTaskReadingAsync(DataChannelManage.TaskDataChannel.Reader);
|
||||||
|
|
||||||
// //此处代码不要删除
|
// //此处代码不要删除
|
||||||
@ -497,8 +423,10 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
deviceIds.Add(ammeter.MeterId.ToString());
|
deviceIds.Add(ammeter.MeterId.ToString());
|
||||||
|
|
||||||
//处理ItemCode
|
//处理ItemCode
|
||||||
if (string.IsNullOrWhiteSpace(ammeter.ItemCodes) && !string.IsNullOrWhiteSpace(ammeter.DataTypes))
|
if (ammeter.ItemCodes == null && !string.IsNullOrWhiteSpace(ammeter.DataTypes))
|
||||||
{
|
{
|
||||||
|
ammeter.ItemCodes = new List<string>();
|
||||||
|
|
||||||
var itemArr = ammeter.DataTypes.Split(',').ToList();
|
var itemArr = ammeter.DataTypes.Split(',').ToList();
|
||||||
|
|
||||||
#region 拼接采集项
|
#region 拼接采集项
|
||||||
@ -511,7 +439,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
{
|
{
|
||||||
if (!excludeItemCode.Contains(gatherItem.ItemCode))
|
if (!excludeItemCode.Contains(gatherItem.ItemCode))
|
||||||
{
|
{
|
||||||
itemCodeList.Add(gatherItem.ItemCode);
|
itemCodeList.Add(gatherItem.ItemCode.Replace("WAVE_109", "10_109"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,15 +458,11 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ammeter.ItemCodes = itemCodeList.Serialize();//转换成JSON字符串
|
ammeter.ItemCodes = itemCodeList;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(ammeter.ItemCodes))
|
|
||||||
{
|
|
||||||
ammeter.ItemCodes = ammeter.ItemCodes.Replace("WAVE_109", "10_109");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ammeter.ItemCodes = "10_97";
|
//var tempItemCodeList = new List<string>() { "10_97" };
|
||||||
|
//ammeter.ItemCodes = tempItemCodeList.Serialize();
|
||||||
|
|
||||||
if (!keyValuePairs.ContainsKey(ammeter.FocusAddress))
|
if (!keyValuePairs.ContainsKey(ammeter.FocusAddress))
|
||||||
{
|
{
|
||||||
@ -706,7 +630,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(ammeterInfo.ItemCodes))
|
if (ammeterInfo.ItemCodes == null || ammeterInfo.ItemCodes.Count <=0)
|
||||||
{
|
{
|
||||||
//_logger.LogError($"{nameof(AmmerterCreatePublishTaskAction)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}数据采集指令生成失败,采集项为空,-101");
|
//_logger.LogError($"{nameof(AmmerterCreatePublishTaskAction)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}数据采集指令生成失败,采集项为空,-101");
|
||||||
return null;
|
return null;
|
||||||
@ -753,7 +677,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> tempCodes = ammeterInfo.ItemCodes.Deserialize<List<string>>()!;
|
List<string> tempCodes = ammeterInfo.ItemCodes!;
|
||||||
|
|
||||||
//TODO:自动上报数据只主动采集1类数据。
|
//TODO:自动上报数据只主动采集1类数据。
|
||||||
if (ammeterInfo.AutomaticReport.Equals(1))
|
if (ammeterInfo.AutomaticReport.Equals(1))
|
||||||
@ -805,13 +729,14 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
//var aFN = (AFN)aFNStr.HexToDec();
|
//var aFN = (AFN)aFNStr.HexToDec();
|
||||||
//var fn = int.Parse(itemCodeArr[1]);
|
//var fn = int.Parse(itemCodeArr[1]);
|
||||||
|
|
||||||
|
//特殊编码映射
|
||||||
var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(tempItem);
|
var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo645SubCodeRelationship(tempItem);
|
||||||
|
|
||||||
//TODO:特殊表
|
//TODO:特殊表
|
||||||
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
||||||
{
|
{
|
||||||
FocusAddress = ammeterInfo.FocusAddress,
|
FocusAddress = ammeterInfo.FocusAddress,
|
||||||
Pn = ammeterInfo.MeteringCode,
|
Pn = itemCodeInfo.Item1 == T37612012PacketItemCodeConst.AFN10HFN01H ? 0 : ammeterInfo.MeteringCode,
|
||||||
ItemCode = itemCodeInfo.Item1,
|
ItemCode = itemCodeInfo.Item1,
|
||||||
DataTimeMark = new Protocol.DataTimeMark()
|
DataTimeMark = new Protocol.DataTimeMark()
|
||||||
{
|
{
|
||||||
@ -838,8 +763,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
ammeterInfo: ammeterInfo,
|
ammeterInfo: ammeterInfo,
|
||||||
timestamps: DateTimeOffset.Now.ToUnixTimeNanoseconds(),
|
timestamps: DateTimeOffset.Now.ToUnixTimeNanoseconds(),
|
||||||
builderResponse: builderResponse,
|
builderResponse: builderResponse,
|
||||||
itemCode: tempItem,
|
itemCode: itemCodeInfo.Item1,
|
||||||
subItemCode: null,
|
subItemCode: itemCodeInfo.Item2,
|
||||||
pendingCopyReadTime: timestamps,
|
pendingCopyReadTime: timestamps,
|
||||||
creationTime: currentTime,
|
creationTime: currentTime,
|
||||||
packetType: (TelemetryPacketTypeEnum)timeDensity,
|
packetType: (TelemetryPacketTypeEnum)timeDensity,
|
||||||
@ -884,12 +809,16 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#else
|
||||||
//判断是否是自动校时时间
|
//判断是否是自动校时时间
|
||||||
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))
|
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
|
_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
||||||
|
|
||||||
@ -961,12 +890,16 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//判断是否是自动校时时间
|
|
||||||
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))
|
#if DEBUG
|
||||||
|
#else
|
||||||
|
//判断是否是日冻结抄读时间
|
||||||
|
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
|
_logger.LogInformation($"{nameof(AmmeterScheduledGetAutomaticDayFreezeData)} 非电表日冻结抄读时间,暂不处理");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
||||||
|
|
||||||
@ -974,7 +907,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType);
|
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType);
|
||||||
if (protocolPlugin == null)
|
if (protocolPlugin == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105");
|
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 电表日冻结抄读运行时间{currentTime}没有找到对应的协议组件,-105");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,7 +917,13 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
{
|
{
|
||||||
FocusAddress = ammeterInfo.FocusAddress,
|
FocusAddress = ammeterInfo.FocusAddress,
|
||||||
Pn = ammeterInfo.MeteringCode,
|
Pn = ammeterInfo.MeteringCode,
|
||||||
ItemCode = item
|
ItemCode = item,
|
||||||
|
DataTimeMark = new Protocol.DataTimeMark()
|
||||||
|
{
|
||||||
|
Density = ammeterInfo.TimeDensity.GetFocusDensity(),//转换成协议的值
|
||||||
|
Point = 1,
|
||||||
|
DataTime = currentTime.AddDays(-1),//日冻结抄读时间为昨天
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var meterReadingRecords = CreateAmmeterPacketInfo(
|
var meterReadingRecords = CreateAmmeterPacketInfo(
|
||||||
@ -1032,12 +971,26 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//判断是否是自动校时时间
|
#if DEBUG
|
||||||
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))
|
#else
|
||||||
|
//需要检查是不是每月1号抄读上个月的数据
|
||||||
|
if (currentTime.Date != currentTime.FirstDayOfMonth().Date)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
|
_logger.LogInformation($"{nameof(AmmeterScheduledGetAutomaticMonthFreezeData)} 非月冻结数据抄读时间,暂不处理");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timestamps = currentTime.LastDayOfPrdviousMonth();
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断是否是月冻结数据抄读
|
||||||
|
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticMonthFreezeTime, StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 非电表月冻结抄读时间,暂不处理");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
||||||
|
|
||||||
@ -1045,17 +998,27 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType);
|
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(ammeterInfo.BrandType);
|
||||||
if (protocolPlugin == null)
|
if (protocolPlugin == null)
|
||||||
{
|
{
|
||||||
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105");
|
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 电表月冻结抄读时间{currentTime}没有找到对应的协议组件,-105");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var item in DayFreezeCodes)
|
foreach (var item in MonthFreezeCodes)
|
||||||
{
|
{
|
||||||
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
||||||
{
|
{
|
||||||
FocusAddress = ammeterInfo.FocusAddress,
|
FocusAddress = ammeterInfo.FocusAddress,
|
||||||
Pn = ammeterInfo.MeteringCode,
|
Pn = ammeterInfo.MeteringCode,
|
||||||
ItemCode = item
|
ItemCode = item,
|
||||||
|
DataTimeMark = new Protocol.DataTimeMark()
|
||||||
|
{
|
||||||
|
Density = ammeterInfo.TimeDensity.GetFocusDensity(),//转换成协议的值
|
||||||
|
Point = 1,
|
||||||
|
#if DEBUG
|
||||||
|
DataTime = currentTime.AddMonths(-1),//月冻结抄读时间为上个月
|
||||||
|
#else
|
||||||
|
DataTime = timestamps,//月冻结抄读时间为上个月
|
||||||
|
#endif
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var meterReadingRecords = CreateAmmeterPacketInfo(
|
var meterReadingRecords = CreateAmmeterPacketInfo(
|
||||||
@ -1155,7 +1118,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region 水表采集处理
|
#region 水表采集处理
|
||||||
@ -1190,6 +1153,42 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
throw new NullReferenceException($"{nameof(InitAmmeterCacheData)} 初始化水表缓存数据时,采集项类型数据为空");
|
throw new NullReferenceException($"{nameof(InitAmmeterCacheData)} 初始化水表缓存数据时,采集项类型数据为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meterInfos != null && meterInfos.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var item in meterInfos)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (item.MeterTypeName.Equals("水表") && (item.Protocol.Equals((int)MeterLinkProtocol.CJT_188_2018) || item.Protocol.Equals((int)MeterLinkProtocol.DLT_645_1997) || item.Protocol.Equals((int)MeterLinkProtocol.DLT_645_2007)))
|
||||||
|
{
|
||||||
|
if (item.BrandType.Contains("炬华有线"))
|
||||||
|
{
|
||||||
|
item.ItemCodes = new List<string>() { T37612012PacketItemCodeConst.AFN0CHFN188H };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.ItemCodes = new List<string>() { T37612012PacketItemCodeConst.AFN0CHFN129H };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (item.MeterTypeName.Trim().Equals("西恩超声波流量计"))
|
||||||
|
{
|
||||||
|
item.ItemCodes = new List<string>() { T37612012PacketItemCodeConst.AFN09HFN01H };
|
||||||
|
}
|
||||||
|
else if (item.MeterTypeName.Trim().Equals("江苏华海涡街流量计积算仪"))
|
||||||
|
{
|
||||||
|
item.ItemCodes = new List<string>() { T37612012PacketItemCodeConst.AFN09HFN01H };
|
||||||
|
}
|
||||||
|
else if (item.MeterTypeName.Trim().Equals("V880BR涡街流量计"))
|
||||||
|
{
|
||||||
|
item.ItemCodes = new List<string>() { T37612012PacketItemCodeConst.AFN09HFN01H };
|
||||||
|
}
|
||||||
|
else if (item.MeterTypeName.Trim().Equals("拓思特涡街流量计H880BR"))
|
||||||
|
{
|
||||||
|
item.ItemCodes = new List<string>() { T37612012PacketItemCodeConst.AFN09HFN01H };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<string> deviceIds = new List<string>();//用于处理Kafka主题分区数据的分发和处理。
|
List<string> deviceIds = new List<string>();//用于处理Kafka主题分区数据的分发和处理。
|
||||||
|
|
||||||
//根据采集频率分组,获得采集频率分组
|
//根据采集频率分组,获得采集频率分组
|
||||||
@ -1317,14 +1316,14 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
{
|
{
|
||||||
timeDensity = watermeter.TimeDensity;//水表默认为60分钟
|
timeDensity = watermeter.TimeDensity;//水表默认为60分钟
|
||||||
typeName = watermeter.LinkType;
|
typeName = watermeter.LinkType;
|
||||||
if (watermeter.MeterBrand.Contains("泉高阀门") || watermeter.MeterBrand.Equals("LXSY-山水翔"))
|
if (watermeter.BrandType.Contains("泉高阀门") || watermeter.BrandType.Equals("LXSY-山水翔"))
|
||||||
{
|
{
|
||||||
typeName = watermeter.MeterBrand;
|
typeName = watermeter.BrandType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (watermeter.MeterType == MeterTypeEnum.WaterMeterFlowmeter)
|
else if (watermeter.MeterType == MeterTypeEnum.WaterMeterFlowmeter)
|
||||||
{
|
{
|
||||||
typeName = watermeter.MeterBrand;
|
typeName = watermeter.BrandType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1340,25 +1339,40 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(watermeter.BrandType);
|
var protocolPlugin = await _protocolService.GetProtocolServiceAsync(watermeter.BrandType);
|
||||||
if (protocolPlugin == null)
|
if (protocolPlugin == null)
|
||||||
{
|
{
|
||||||
//_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 定时阀控运行时间{currentTime}没有找到对应的协议组件,-105");
|
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 创建水表待发送的任务数据时{currentTime}没有找到对应的协议组件,-101");
|
||||||
//return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string itemCode = T37612012PacketItemCodeConst.AFN10HFN01H;
|
if (watermeter.ItemCodes == null || watermeter.ItemCodes.Count <=0)
|
||||||
string subItemCode = T1882018PacketItemCodeConst.CTR0190;
|
{
|
||||||
|
_logger.LogError($"{nameof(AmmeterScheduledAutoValveControl)} 创建水表待发送的任务数据时{watermeter.Name}没有相应的采集项,-102");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
foreach (var item in watermeter.ItemCodes)
|
||||||
|
{
|
||||||
|
var tempRequest = new ProtocolBuildRequest()
|
||||||
{
|
{
|
||||||
FocusAddress = watermeter.FocusAddress,
|
FocusAddress = watermeter.FocusAddress,
|
||||||
Pn = watermeter.MeteringCode,
|
Pn = watermeter.MeteringCode,
|
||||||
ItemCode = itemCode,
|
ItemCode = item,
|
||||||
SubProtocolRequest = new SubProtocolBuildRequest()
|
};
|
||||||
|
|
||||||
|
if (item == T37612012PacketItemCodeConst.AFN09HFN01H)
|
||||||
|
{
|
||||||
|
//var itemCodeInfo = T37612012PacketItemCodeConst.MappingItemCodeTo188SubCodeRelationship(T37612012PacketItemCodeConst.AFN10HFN99H, true);//阀控
|
||||||
|
tempRequest.SubProtocolRequest = new SubProtocolBuildRequest()
|
||||||
{
|
{
|
||||||
MeterAddress = watermeter.MeterAddress,
|
MeterAddress = watermeter.MeterAddress,
|
||||||
Password = watermeter.Password,
|
Password = watermeter.Password,
|
||||||
ItemCode = subItemCode,
|
ItemCode = T1882018PacketItemCodeConst.CTR01901F00,
|
||||||
|
MeteringPort = watermeter.MeteringPort,
|
||||||
|
Baudrate = watermeter.Baudrate,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(tempRequest);
|
||||||
|
|
||||||
if (builderResponse == null || builderResponse.Data.Length <= 0)
|
if (builderResponse == null || builderResponse.Data.Length <= 0)
|
||||||
{
|
{
|
||||||
//_logger.LogWarning($"{nameof(AmmerterCreatePublishTask)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}未能正确获取报文。");
|
//_logger.LogWarning($"{nameof(AmmerterCreatePublishTask)} 集中器{ammeterInfo.FocusAddress}的电表{ammeterInfo.Name}采集项{tempItem}未能正确获取报文。");
|
||||||
@ -1367,41 +1381,23 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
if (builderResponse == null || builderResponse.Data.Length <= 0)
|
if (builderResponse == null || builderResponse.Data.Length <= 0)
|
||||||
{
|
{
|
||||||
_logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的水表{watermeter.Name}采集项{itemCode}未能正确获取报文。");
|
_logger.LogWarning($"{nameof(WatermeterCreatePublishTaskAction)} 集中器{watermeter.FocusAddress}的水表{watermeter.Name} 水表采抄读采集项{T1882018PacketItemCodeConst.CTR01901F00}未能正确获取报文。");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var meterReadingRecords = CreateAmmeterPacketInfo(
|
||||||
string taskMark = CommonHelper.GetTaskMark(builderResponse.AFn, builderResponse.Fn, watermeter.MeteringCode, builderResponse.MSA, builderResponse.Seq);
|
ammeterInfo: watermeter,
|
||||||
var meterReadingRecords = new MeterReadingTelemetryPacketInfo()
|
timestamps: currentTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
|
||||||
{
|
builderResponse: builderResponse,
|
||||||
SystemName = SystemType,
|
itemCode: T37612012PacketItemCodeConst.AFN10HFN01H,
|
||||||
ProjectId = $"{watermeter.ProjectID}",
|
subItemCode: T1882018PacketItemCodeConst.CTR01901F00,
|
||||||
DeviceType = $"{MeterTypeEnum.Ammeter}",
|
pendingCopyReadTime: currentTime,
|
||||||
DeviceId = $"{watermeter.MeterId}",
|
creationTime: currentTime,
|
||||||
Timestamps = DateTimeOffset.Now.ToUnixTimeNanoseconds(),
|
packetType: TelemetryPacketTypeEnum.WatermeterAutoReadding,
|
||||||
DatabaseBusiID = watermeter.DatabaseBusiID,
|
_guidGenerator);
|
||||||
PacketType = (int)TelemetryPacketTypeEnum.WatermeterAutoReadding,
|
|
||||||
PendingCopyReadTime = timestamps,
|
|
||||||
CreationTime = currentTime,
|
|
||||||
MeterAddress = watermeter.MeterAddress,
|
|
||||||
AFN = builderResponse.AFn,
|
|
||||||
Fn = builderResponse.Fn,
|
|
||||||
Seq = builderResponse.Seq,
|
|
||||||
MSA = builderResponse.MSA,
|
|
||||||
ItemCode = itemCode,
|
|
||||||
SubItemCode = subItemCode,
|
|
||||||
TaskMark = taskMark,
|
|
||||||
IsSend = false,
|
|
||||||
ManualOrNot = false,
|
|
||||||
Pn = watermeter.MeteringCode,
|
|
||||||
IssuedMessageId = GuidGenerator.Create().ToString(),
|
|
||||||
IssuedMessageHexString = Convert.ToHexString(builderResponse.Data),
|
|
||||||
IsReceived = false,
|
|
||||||
ScoreValue = $"{watermeter.FocusAddress}.{taskMark}".Md5Fun(),
|
|
||||||
};
|
|
||||||
|
|
||||||
taskList.Add(meterReadingRecords);
|
taskList.Add(meterReadingRecords);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return taskList;
|
return taskList;
|
||||||
|
|
||||||
@ -1504,12 +1500,15 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
#else
|
||||||
//判断是否是自动获取版本号时间
|
//判断是否是自动获取版本号时间
|
||||||
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))
|
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"{nameof(ConcentratorScheduledAutomaticGetTelematicsModule)} 自动获取远程通信模块(SIM)版本信息,非自动处理时间");
|
_logger.LogInformation($"{nameof(ConcentratorScheduledAutomaticGetTelematicsModule)} 自动获取远程通信模块(SIM)版本信息,非自动处理时间");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
|
||||||
|
|
||||||
@ -1557,7 +1556,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region 公共处理方法
|
#region 公共处理方法
|
||||||
@ -1776,6 +1775,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
Pn = ammeterInfo.MeteringCode,
|
Pn = ammeterInfo.MeteringCode,
|
||||||
IssuedMessageId = guidGenerator.Create().ToString(),
|
IssuedMessageId = guidGenerator.Create().ToString(),
|
||||||
IssuedMessageHexString = Convert.ToHexString(builderResponse.Data),
|
IssuedMessageHexString = Convert.ToHexString(builderResponse.Data),
|
||||||
|
FocusDensity = ammeterInfo.TimeDensity.GetFocusDensity(),
|
||||||
IsReceived = false,
|
IsReceived = false,
|
||||||
ScoreValue = $"{ammeterInfo.FocusAddress}.{taskMark}".Md5Fun(),
|
ScoreValue = $"{ammeterInfo.FocusAddress}.{taskMark}".Md5Fun(),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -96,77 +96,77 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
//[Route($"ammeter/list")]
|
//[Route($"ammeter/list")]
|
||||||
public override async Task<List<DeviceInfo>> GetAmmeterInfoList(string gatherCode = "V4-Gather-8890")
|
public override async Task<List<DeviceInfo>> GetAmmeterInfoList(string gatherCode = "V4-Gather-8890")
|
||||||
{
|
{
|
||||||
//#if DEBUG
|
#if DEBUG
|
||||||
// var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus109:DeviceInfo";
|
var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus109:DeviceInfo";
|
||||||
|
|
||||||
// List<DeviceInfo> ammeterInfos = FreeRedisProvider.Instance.Get<List<DeviceInfo>>(redisCacheDeviceInfoHashKeyTemp);//542400504
|
List<DeviceInfo> ammeterInfos = FreeRedisProvider.Instance.Get<List<DeviceInfo>>(redisCacheDeviceInfoHashKeyTemp);//542400504
|
||||||
|
|
||||||
// if (ammeterInfos == null || ammeterInfos.Count <= 0)
|
if (ammeterInfos == null || ammeterInfos.Count <= 0)
|
||||||
// {
|
{
|
||||||
// ammeterInfos = new List<DeviceInfo>();
|
ammeterInfos = new List<DeviceInfo>();
|
||||||
// //ammeterInfos.Add(new DeviceInfo()
|
//ammeterInfos.Add(new DeviceInfo()
|
||||||
// //{
|
//{
|
||||||
// // Baudrate = 2400,
|
// Baudrate = 2400,
|
||||||
// // FocusAddress = "442400040",
|
// FocusAddress = "442400040",
|
||||||
// // Name = "保利单箱电表1",
|
// Name = "保利单箱电表1",
|
||||||
// // FocusId = 95780,
|
// FocusId = 95780,
|
||||||
// // DatabaseBusiID = 1,
|
// DatabaseBusiID = 1,
|
||||||
// // MeteringCode = 0,
|
// MeteringCode = 0,
|
||||||
// // MeterAddress = "442405000040",
|
// MeterAddress = "442405000040",
|
||||||
// // MeterId = 127035,
|
// MeterId = 127035,
|
||||||
// // TypeName = 1,
|
// TypeName = 1,
|
||||||
// // DataTypes = "581,589,592,597,601",
|
// DataTypes = "581,589,592,597,601",
|
||||||
// // TimeDensity = 15,
|
// TimeDensity = 15,
|
||||||
// // BrandType = "DTS1980",
|
// BrandType = "DTS1980",
|
||||||
// // MeterType = MeterTypeEnum.Ammeter,
|
// MeterType = MeterTypeEnum.Ammeter,
|
||||||
// // ProjectID = 1,
|
// ProjectID = 1,
|
||||||
// // MeteringPort = MeteringPortConst.MeteringPortTwo,
|
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
// // Password = "000000",
|
// Password = "000000",
|
||||||
// //});
|
//});
|
||||||
|
|
||||||
// //ammeterInfos.Add(new DeviceInfo()
|
//ammeterInfos.Add(new DeviceInfo()
|
||||||
// //{
|
//{
|
||||||
// // Baudrate = 2400,
|
// Baudrate = 2400,
|
||||||
// // FocusAddress = "442400039",
|
// FocusAddress = "442400039",
|
||||||
// // Name = "保利单箱电表2",
|
// Name = "保利单箱电表2",
|
||||||
// // FocusId = 69280,
|
// FocusId = 69280,
|
||||||
// // DatabaseBusiID = 1,
|
// DatabaseBusiID = 1,
|
||||||
// // MeteringCode = 0,
|
// MeteringCode = 0,
|
||||||
// // MeterAddress = "442405000039",
|
// MeterAddress = "442405000039",
|
||||||
// // MeterId = 95594,
|
// MeterId = 95594,
|
||||||
// // TypeName = 1,
|
// TypeName = 1,
|
||||||
// // DataTypes = "581,589,592,597,601",
|
// DataTypes = "581,589,592,597,601",
|
||||||
// // TimeDensity = 15,
|
// TimeDensity = 15,
|
||||||
// // BrandType = "DTS1980",
|
// BrandType = "DTS1980",
|
||||||
// // MeterType = MeterTypeEnum.Ammeter,
|
// MeterType = MeterTypeEnum.Ammeter,
|
||||||
// // ProjectID = 1,
|
// ProjectID = 1,
|
||||||
// // MeteringPort = MeteringPortConst.MeteringPortTwo,
|
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
// // Password = "000000",
|
// Password = "000000",
|
||||||
// //});
|
//});
|
||||||
|
|
||||||
// //ammeterInfos.Add(new DeviceInfo()
|
//ammeterInfos.Add(new DeviceInfo()
|
||||||
// //{
|
//{
|
||||||
// // Baudrate = 2400,
|
// Baudrate = 2400,
|
||||||
// // FocusAddress = "402440506",
|
// FocusAddress = "402440506",
|
||||||
// // Name = "中环半导体9#冷却泵-220KW(三相电表)",
|
// Name = "中环半导体9#冷却泵-220KW(三相电表)",
|
||||||
// // FocusId = 106857,
|
// FocusId = 106857,
|
||||||
// // DatabaseBusiID = 1,
|
// DatabaseBusiID = 1,
|
||||||
// // MeteringCode = 0,
|
// MeteringCode = 0,
|
||||||
// // MeterAddress = "402410040506",
|
// MeterAddress = "402410040506",
|
||||||
// // MeterId = 139059,
|
// MeterId = 139059,
|
||||||
// // TypeName = 3,
|
// TypeName = 3,
|
||||||
// // DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679",
|
// DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679",
|
||||||
// // TimeDensity = 15,
|
// TimeDensity = 15,
|
||||||
// // BrandType = "DTS1980",
|
// BrandType = "DTS1980",
|
||||||
// // Password = "000000",
|
// Password = "000000",
|
||||||
// // ProjectID = 1,
|
// ProjectID = 1,
|
||||||
// // MeterType = MeterTypeEnum.Ammeter,
|
// MeterType = MeterTypeEnum.Ammeter,
|
||||||
// // MeteringPort = MeteringPortConst.MeteringPortTwo,
|
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
// //});
|
//});
|
||||||
|
|
||||||
|
|
||||||
// ammeterInfos.Add(new DeviceInfo()
|
//ammeterInfos.Add(new DeviceInfo()
|
||||||
// {
|
//{
|
||||||
// Baudrate = 2400,
|
// Baudrate = 2400,
|
||||||
// FocusAddress = "942411321",
|
// FocusAddress = "942411321",
|
||||||
// Name = "DDS1980-T4(5-60) ML307A 长稳 942408011321",
|
// Name = "DDS1980-T4(5-60) ML307A 长稳 942408011321",
|
||||||
@ -183,11 +183,11 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
// ProjectID = 1,
|
// ProjectID = 1,
|
||||||
// MeterType = MeterTypeEnum.Ammeter,
|
// MeterType = MeterTypeEnum.Ammeter,
|
||||||
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
// });
|
//});
|
||||||
|
|
||||||
|
|
||||||
// ammeterInfos.Add(new DeviceInfo()
|
//ammeterInfos.Add(new DeviceInfo()
|
||||||
// {
|
//{
|
||||||
// Baudrate = 2400,
|
// Baudrate = 2400,
|
||||||
// FocusAddress = "942411319",
|
// FocusAddress = "942411319",
|
||||||
// Name = "DDS1980-T4(5-60) ML307A 长稳 942408011319",
|
// Name = "DDS1980-T4(5-60) ML307A 长稳 942408011319",
|
||||||
@ -204,17 +204,36 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
// ProjectID = 1,
|
// ProjectID = 1,
|
||||||
// MeterType = MeterTypeEnum.Ammeter,
|
// MeterType = MeterTypeEnum.Ammeter,
|
||||||
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
// MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
// });
|
//});
|
||||||
|
|
||||||
|
ammeterInfos.Add(new DeviceInfo()
|
||||||
|
{
|
||||||
|
Baudrate = 2400,
|
||||||
|
FocusAddress = "322011149",
|
||||||
|
Name = "DDS1980-T4(5-60) ML307A 长稳 322011149",
|
||||||
|
FocusId = 57685,
|
||||||
|
DatabaseBusiID = 1,
|
||||||
|
MeteringCode = 0,
|
||||||
|
MeterAddress = "31240010270",
|
||||||
|
MeterId = 78973,
|
||||||
|
TypeName = 3,
|
||||||
|
DataTypes = "449,503,581,582,583,584,585,586,587,588,589,590,591,592,593,594,597,598,599,600,601,602,603,604,605,606,607,608,661,663,677,679",
|
||||||
|
TimeDensity = 15,
|
||||||
|
BrandType = "DTS1980",
|
||||||
|
Password = "000000",
|
||||||
|
ProjectID = 1,
|
||||||
|
MeterType = MeterTypeEnum.Ammeter,
|
||||||
|
MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
|
});
|
||||||
|
|
||||||
|
FreeRedisProvider.Instance.Set(redisCacheDeviceInfoHashKeyTemp, ammeterInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ammeterInfos;
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
// FreeRedisProvider.Instance.Set(redisCacheDeviceInfoHashKeyTemp, ammeterInfos);
|
#endif
|
||||||
// }
|
|
||||||
|
|
||||||
// return ammeterInfos;
|
|
||||||
//#else
|
|
||||||
|
|
||||||
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -255,8 +274,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
//TODO 记得移除特殊表过滤
|
//TODO 记得移除特殊表过滤
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
//// sql = $@"{sql} and c.Address in('542410000504','442405000040','442405000039','402410040506')";
|
// sql = $@"{sql} and c.Address in('542410000504','442405000040','442405000039','402410040506')";
|
||||||
sql = $@"{sql} and c.Address in('402410040506')";
|
sql = $@"{sql} and c.Address in('402410040506')";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -508,7 +527,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
|
||||||
{
|
{
|
||||||
FocusAddress = ammeterInfo.FocusAddress,
|
FocusAddress = ammeterInfo.FocusAddress,
|
||||||
Pn = ammeterInfo.MeteringCode,
|
Pn = 0,//ammeterInfo.MeteringCode,现有协议里面阀控必须传0,不能根据档案的MeteringCode值走。
|
||||||
ItemCode = itemCode,
|
ItemCode = itemCode,
|
||||||
SubProtocolRequest = new SubProtocolBuildRequest()
|
SubProtocolRequest = new SubProtocolBuildRequest()
|
||||||
{
|
{
|
||||||
@ -560,6 +579,40 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus119:DeviceInfo";
|
||||||
|
|
||||||
|
List<DeviceInfo> deviceInfos = FreeRedisProvider.Instance.Get<List<DeviceInfo>>(redisCacheDeviceInfoHashKeyTemp);
|
||||||
|
|
||||||
|
if (deviceInfos == null || deviceInfos.Count <= 0)
|
||||||
|
{
|
||||||
|
deviceInfos = new List<DeviceInfo>();
|
||||||
|
deviceInfos.Add(new DeviceInfo()
|
||||||
|
{
|
||||||
|
Baudrate = 2400,
|
||||||
|
FocusAddress = "322011149",
|
||||||
|
Name = "LXSY-25E 保利",
|
||||||
|
FocusId = 57675,
|
||||||
|
DatabaseBusiID = 1,
|
||||||
|
MeteringCode = 0,
|
||||||
|
MeterAddress = "341587000473",
|
||||||
|
MeterId = 1025,
|
||||||
|
TypeName = 1,
|
||||||
|
TimeDensity = 60,
|
||||||
|
BrandType = "云集",
|
||||||
|
MeterType = MeterTypeEnum.WaterMeter,
|
||||||
|
ProjectID = 1,
|
||||||
|
MeteringPort = MeteringPortConst.MeteringPortTwo,
|
||||||
|
Password = "000000",
|
||||||
|
LinkType = "RS-485",
|
||||||
|
TimesRate = 1.0000m,
|
||||||
|
});
|
||||||
|
|
||||||
|
FreeRedisProvider.Instance.Set(redisCacheDeviceInfoHashKeyTemp, deviceInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceInfos;
|
||||||
|
#else
|
||||||
string sql = $@"SELECT
|
string sql = $@"SELECT
|
||||||
A.ID as MeterId,
|
A.ID as MeterId,
|
||||||
A.Name,
|
A.Name,
|
||||||
@ -575,7 +628,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
A.LinkType,
|
A.LinkType,
|
||||||
A.HaveValve,
|
A.HaveValve,
|
||||||
A.MeterType AS MeterTypeName,
|
A.MeterType AS MeterTypeName,
|
||||||
A.MeterBrand,
|
A.MeterBrand AS BrandType,
|
||||||
A.TimesRate,
|
A.TimesRate,
|
||||||
A.TimeDensity,
|
A.TimeDensity,
|
||||||
A.TripState,
|
A.TripState,
|
||||||
@ -602,6 +655,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
return await SqlProvider.Instance.Change(DbEnum.EnergyDB)
|
return await SqlProvider.Instance.Change(DbEnum.EnergyDB)
|
||||||
.Ado
|
.Ado
|
||||||
.QueryAsync<DeviceInfo>(sql);
|
.QueryAsync<DeviceInfo>(sql);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -47,13 +47,6 @@ namespace JiShe.CollectBus.IotSystems.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string MeterTypeName { get; set; }
|
public string MeterTypeName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设备品牌;
|
|
||||||
/// (当 MeterType = 水表, 如 威铭、捷先 等)
|
|
||||||
/// (当 MeterType = 流量计, 如 西恩超声波流量计、西恩电磁流量计、涡街流量计 等)
|
|
||||||
/// </summary>
|
|
||||||
public string MeterBrand { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 倍率
|
/// 倍率
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -75,7 +68,7 @@ namespace JiShe.CollectBus.IotSystems.Devices
|
|||||||
public string AreaCode { get; set; }
|
public string AreaCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 电表类别 (1单相、2三相三线、3三相四线),
|
/// 仅当MeterType为电表时,电表类别 (1单相、2三相三线、3三相四线),
|
||||||
/// 07协议: 开合闸指令(1A开闸断电,1C单相表合闸,1B多相表合闸) 645 2007 表
|
/// 07协议: 开合闸指令(1A开闸断电,1C单相表合闸,1B多相表合闸) 645 2007 表
|
||||||
/// 97协议://true(合闸);false(跳闸) 545 1997 没有单相多相 之分 "true" ? "9966" : "3355"
|
/// 97协议://true(合闸);false(跳闸) 545 1997 没有单相多相 之分 "true" ? "9966" : "3355"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -120,7 +113,8 @@ namespace JiShe.CollectBus.IotSystems.Devices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 该电表方案下采集项,JSON格式,如:["0D_80","0D_80"]
|
/// 该电表方案下采集项,JSON格式,如:["0D_80","0D_80"]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ItemCodes { get; set; }
|
[Column(IsIgnore = true)]
|
||||||
|
public List<string> ItemCodes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// State表状态:
|
/// State表状态:
|
||||||
|
|||||||
@ -13,7 +13,8 @@ namespace JiShe.CollectBus.IotSystems.Devices
|
|||||||
/// 设备表型数据信息
|
/// 设备表型数据信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SourceAnalyzers(EntityTypeEnum.TableModel)]
|
[SourceAnalyzers(EntityTypeEnum.TableModel)]
|
||||||
public class DeviceTreeModelDataInfo: IoTEntity
|
[IgnoreInitTable]
|
||||||
|
public class DeviceTableModelDataInfo : IoTEntity
|
||||||
{
|
{
|
||||||
|
|
||||||
[FIELDColumn]
|
[FIELDColumn]
|
||||||
|
|||||||
@ -12,8 +12,8 @@ namespace JiShe.CollectBus.IotSystems.Devices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备树模型数据信息
|
/// 设备树模型数据信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SourceAnalyzers(EntityTypeEnum.TableModel)]
|
[SourceAnalyzers(EntityTypeEnum.TreeModel)]
|
||||||
public class DeviceTableModelDataInfo : IoTEntity
|
public class DeviceTreeModelDataInfo : IoTEntity
|
||||||
{
|
{
|
||||||
|
|
||||||
[FIELDColumn]
|
[FIELDColumn]
|
||||||
|
|||||||
@ -151,6 +151,12 @@ namespace JiShe.CollectBus.IotSystems.MeterReadingRecords
|
|||||||
[FIELDColumn]
|
[FIELDColumn]
|
||||||
public string IssuedMessageId { get; set; }
|
public string IssuedMessageId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 集中器采集密度
|
||||||
|
/// </summary>
|
||||||
|
[FIELDColumn]
|
||||||
|
public int FocusDensity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 消息上报内容
|
/// 消息上报内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -14,9 +14,14 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
#region 下行报文编码
|
#region 下行报文编码
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 基路径
|
/// 基路径,表示主站发起读数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string BasicT1882018 = "CTR";
|
public const string BasicT1882018Read = "CTR0";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基路径,表示主站发起读数据
|
||||||
|
/// </summary>
|
||||||
|
public const string BasicT1882018Write = "CTR3";
|
||||||
|
|
||||||
#region 读数据
|
#region 读数据
|
||||||
|
|
||||||
@ -24,12 +29,12 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取计量数据1
|
/// 读取计量数据1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CTR0190 = $"01_90";
|
public const string CTR01901F00 = $"{BasicT1882018Read}_01_90_1F_00";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取计量数据2
|
/// 读取计量数据2
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CTR0191 = $"01_91";
|
public const string CTR01911F00 = $"{BasicT1882018Read}_01_91_1F_00";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -38,12 +43,12 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 关阀
|
/// 关阀
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CTR30455 = $"_04_55";
|
public const string CTR304A01755 = $"{BasicT1882018Write}_04_A0_17_55";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开阀
|
/// 开阀
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string CTR30499 = $"_04_99";
|
public const string CTR304A01799 = $"{BasicT1882018Write}_04_A0_17_99";
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 透明转发
|
/// 透明转发
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string AFN10HFN01H = $"10_01";
|
public const string AFN10HFN01H = $"10_1";
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -28,12 +28,27 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取终端信息
|
/// 读取终端信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string AFN09HFN01H = $"09_01";
|
public const string AFN09HFN01H = $"09_1";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 远程通信模块版本信息
|
/// 远程通信模块版本信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string AFN09HFN09H = $"09_09";
|
public const string AFN09HFN09H = $"09_9";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 水表阀控
|
||||||
|
/// </summary>
|
||||||
|
public const string AFN10HFN99H = $"10_99";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 炬华有线水表抄读
|
||||||
|
/// </summary>
|
||||||
|
public const string AFN0CHFN188H = $"0C_188";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标准188协议水表抄读
|
||||||
|
/// </summary>
|
||||||
|
public const string AFN0CHFN129H = $"0C_129";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -170,9 +185,9 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 集中器状态字段
|
/// IotDB存储字段字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConcentratorStatusFieldConst
|
public class IotDbFieldConst
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -185,20 +200,45 @@ namespace JiShe.CollectBus.Common.Consts
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string FrameData = "FrameData";
|
public const string FrameData = "FrameData";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否同步
|
||||||
|
/// </summary>
|
||||||
|
public const string IsSync = "IsSync";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据库业务ID
|
||||||
|
/// </summary>
|
||||||
|
public const string DatabaseBusiID= "DatabaseBusiID";
|
||||||
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 特殊645编码关系映射
|
/// 特殊645编码关系映射
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="itemCode"></param>
|
/// <param name="itemCode">特殊3761编码</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static (string,string) MappingItemCodeTo645SubCodeRelationship(string itemCode)
|
public static (string,string) MappingItemCodeTo645SubCodeRelationship(string itemCode)
|
||||||
{
|
{
|
||||||
return itemCode switch
|
return itemCode switch
|
||||||
{
|
{
|
||||||
AFN10HFN97H => (AFN10HFN01H,T6452007PacketItemCodeConst.C1102800002),
|
AFN10HFN97H => (AFN10HFN01H,T6452007PacketItemCodeConst.C1102800002),
|
||||||
_=> (itemCode,""),
|
_ => (itemCode,""),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 特殊188编码关系映射
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="itemCode">特殊3761编码</param>
|
||||||
|
/// <param name="tripState">TripState (0 合闸-开阀, 1 关阀);开阀关阀</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static (string, string) MappingItemCodeTo188SubCodeRelationship(string itemCode,bool tripState)
|
||||||
|
{
|
||||||
|
return itemCode switch
|
||||||
|
{
|
||||||
|
AFN10HFN99H => (AFN10HFN01H, tripState == true ?T1882018PacketItemCodeConst.CTR304A01799: T1882018PacketItemCodeConst.CTR304A01755),
|
||||||
|
_ => (itemCode, ""),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -265,5 +265,79 @@ namespace JiShe.CollectBus.Common.Extensions
|
|||||||
}
|
}
|
||||||
return DateTime.TryParseExact(dateLong.ToString(), "yyyyMMdd HHmmssZZ", null, System.Globalization.DateTimeStyles.None, out DateTime date) ? date : throw new ArgumentException("Date must be between 10000101 and 99991231.");
|
return DateTime.TryParseExact(dateLong.ToString(), "yyyyMMdd HHmmssZZ", null, System.Globalization.DateTimeStyles.None, out DateTime date) ? date : throw new ArgumentException("Date must be between 10000101 and 99991231.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得某月的第一天
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime">要取得月份第一天的时间</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DateTime FirstDayOfMonth(this DateTime datetime)
|
||||||
|
{
|
||||||
|
return datetime.AddDays(1 - datetime.Day);
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// 取得某月的最后一天
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime">要取得月份最后一天的时间</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DateTime LastDayOfMonth(this DateTime datetime)
|
||||||
|
{
|
||||||
|
return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得上个月第一天
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime">要取得上个月第一天的当前时间</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DateTime FirstDayOfPreviousMonth(this DateTime datetime)
|
||||||
|
{
|
||||||
|
return datetime.AddDays(1 - datetime.Day).AddMonths(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得上个月的最后一天
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime">要取得上个月最后一天的当前时间</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DateTime LastDayOfPrdviousMonth(this DateTime datetime)
|
||||||
|
{
|
||||||
|
return datetime.AddDays(1 - datetime.Day).AddDays(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得某月第一天0点以及最后一天的23:59:59时间范围
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Tuple<DateTime, DateTime> GetMonthDateRange(this DateTime datetime)
|
||||||
|
{
|
||||||
|
var lastDayOfMonthDate = LastDayOfMonth(datetime);
|
||||||
|
return new Tuple<DateTime, DateTime>(datetime.FirstDayOfMonth(), new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得某一天0点到当月最后一天的23:59:59时间范围
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Tuple<DateTime, DateTime> GetCurrentDateToLastDayRange(this DateTime datetime)
|
||||||
|
{
|
||||||
|
var lastDayOfMonthDate = LastDayOfMonth(datetime);
|
||||||
|
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得某一天0点到23:59:59时间范围
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="datetime"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Tuple<DateTime, DateTime> GetCurrentDateRange(this DateTime datetime)
|
||||||
|
{
|
||||||
|
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(datetime.Year, datetime.Month, datetime.Day, 23, 59, 59));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,57 +136,7 @@ namespace JiShe.CollectBus.Common.Helpers
|
|||||||
return objModel;
|
return objModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 取得某月的第一天
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="datetime">要取得月份第一天的时间</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static DateTime FirstDayOfMonth(this DateTime datetime)
|
|
||||||
{
|
|
||||||
return datetime.AddDays(1 - datetime.Day);
|
|
||||||
}
|
|
||||||
|
|
||||||
///<summary>
|
|
||||||
/// 取得某月的最后一天
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="datetime">要取得月份最后一天的时间</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static DateTime LastDayOfMonth(this DateTime datetime)
|
|
||||||
{
|
|
||||||
return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 取得某月第一天0点以及最后一天的23:59:59时间范围
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="datetime"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Tuple<DateTime, DateTime> GetMonthDateRange(this DateTime datetime)
|
|
||||||
{
|
|
||||||
var lastDayOfMonthDate = LastDayOfMonth(datetime);
|
|
||||||
return new Tuple<DateTime, DateTime>(datetime.FirstDayOfMonth(), new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 取得某一天0点到当月最后一天的23:59:59时间范围
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="datetime"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Tuple<DateTime, DateTime> GetCurrentDateToLastDayRange(this DateTime datetime)
|
|
||||||
{
|
|
||||||
var lastDayOfMonthDate = LastDayOfMonth(datetime);
|
|
||||||
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 取得某一天0点到23:59:59时间范围
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="datetime"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Tuple<DateTime, DateTime> GetCurrentDateRange(this DateTime datetime)
|
|
||||||
{
|
|
||||||
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(datetime.Year, datetime.Month, datetime.Day, 23, 59, 59));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取指定枚举的所有 Attribute 说明以及value组成的键值对
|
/// 获取指定枚举的所有 Attribute 说明以及value组成的键值对
|
||||||
@ -915,5 +865,72 @@ namespace JiShe.CollectBus.Common.Helpers
|
|||||||
|
|
||||||
return Convert.ToInt64(scoresStr);
|
return Convert.ToInt64(scoresStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载指定名称的程序集
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assemblyNames"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<Assembly> LoadAssemblies(string[] assemblyNames)
|
||||||
|
{
|
||||||
|
var assemblies = new List<Assembly>();
|
||||||
|
|
||||||
|
// 获取已加载的程序集
|
||||||
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
{
|
||||||
|
if (assemblyNames.Contains(asm.GetName().Name))
|
||||||
|
assemblies.Add(asm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试加载未加载的程序集
|
||||||
|
foreach (var name in assemblyNames)
|
||||||
|
{
|
||||||
|
if (!assemblies.Any(a => a.GetName().Name == name))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var assembly = Assembly.Load(name);
|
||||||
|
assemblies.Add(assembly);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
// 若Load失败,尝试从基目录加载
|
||||||
|
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{name}.dll");
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assemblies.Add(Assembly.LoadFrom(path));
|
||||||
|
}
|
||||||
|
catch { /* 记录错误 */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return assemblies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建类型实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="types"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<object> CreateInstances(List<Type> types)
|
||||||
|
{
|
||||||
|
var instances = new List<object>();
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
instances.Add(Activator.CreateInstance(type));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instances;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,8 +76,8 @@ namespace JiShe.CollectBus.Host
|
|||||||
app.UseCors(CollectBusHostConst.DefaultCorsPolicyName);
|
app.UseCors(CollectBusHostConst.DefaultCorsPolicyName);
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
if (env.IsDevelopment())
|
//if (env.IsDevelopment())
|
||||||
{
|
//{
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseAbpSwaggerUI(options =>
|
app.UseAbpSwaggerUI(options =>
|
||||||
{
|
{
|
||||||
@ -88,7 +88,7 @@ namespace JiShe.CollectBus.Host
|
|||||||
options.DocExpansion(DocExpansion.None);
|
options.DocExpansion(DocExpansion.None);
|
||||||
options.DefaultModelsExpandDepth(-1);
|
options.DefaultModelsExpandDepth(-1);
|
||||||
});
|
});
|
||||||
}
|
//}
|
||||||
app.UseAuditing();
|
app.UseAuditing();
|
||||||
app.UseAbpSerilogEnrichers();
|
app.UseAbpSerilogEnrichers();
|
||||||
app.UseUnitOfWork();
|
app.UseUnitOfWork();
|
||||||
|
|||||||
@ -19,6 +19,10 @@
|
|||||||
<Content Remove="C:\Users\Dai Zan\.nuget\packages\volo.abp.aspnetcore\8.3.3\contentFiles\any\net8.0\Volo.Abp.AspNetCore.abppkg.analyze.json" />
|
<Content Remove="C:\Users\Dai Zan\.nuget\packages\volo.abp.aspnetcore\8.3.3\contentFiles\any\net8.0\Volo.Abp.AspNetCore.abppkg.analyze.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Plugins\ignore.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Kafka" Version="9.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.Kafka" Version="9.0.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="8.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="8.0.0" />
|
||||||
@ -52,6 +56,10 @@
|
|||||||
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />-->
|
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />-->
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="Plugins\ignore.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\modules\JiShe.CollectBus.MongoDB\JiShe.CollectBus.MongoDB.csproj" />
|
<ProjectReference Include="..\..\modules\JiShe.CollectBus.MongoDB\JiShe.CollectBus.MongoDB.csproj" />
|
||||||
<ProjectReference Include="..\..\services\JiShe.CollectBus.Application.Contracts\JiShe.CollectBus.Application.Contracts.csproj" />
|
<ProjectReference Include="..\..\services\JiShe.CollectBus.Application.Contracts\JiShe.CollectBus.Application.Contracts.csproj" />
|
||||||
@ -75,9 +83,6 @@
|
|||||||
<None Update="Plugins\JiShe.CollectBus.Protocol.T6452007.dll">
|
<None Update="Plugins\JiShe.CollectBus.Protocol.T6452007.dll">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="Plugins\JiShe.CollectBus.Protocol.Test.dll">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Default": "mongodb://admin:4mFmPTTB8tn6aI@47.110.62.104:27017,47.110.53.196:27017,47.110.60.222:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000",
|
"Default": "mongodb://admin:4mFmPTTB8tn6aI@47.110.62.104:27017,47.110.53.196:27017,47.110.60.222:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000",
|
||||||
"PrepayDB": "server=118.190.144.92;database=jishe.sysdb;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False",
|
"PrepayDB": "server=rm-m5el3d1u1k0wzk70n2o.sqlserver.rds.aliyuncs.com,3433;database=jishe.sysdb;uid=v3sa;pwd=JiShe123;Encrypt=False;Trust Server Certificate=False",
|
||||||
"EnergyDB": "server=118.190.144.92;database=db_energy;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False"
|
"EnergyDB": "server=rm-wz9hw529i3j1e3b5fbo.sqlserver.rds.aliyuncs.com,3433;database=db_energy;uid=yjdb;pwd=Kdjdhf+9*7ad222LL;Encrypt=False;Trust Server Certificate=False"
|
||||||
},
|
},
|
||||||
"Redis": {
|
"Redis": {
|
||||||
"Configuration": "47.110.60.222:6379,password=3JBGfyhTaD46nS,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true",
|
"Configuration": "47.110.60.222:6379,password=3JBGfyhTaD46nS,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true",
|
||||||
@ -18,13 +18,16 @@
|
|||||||
"SaslPassword": "lixiao@1980",
|
"SaslPassword": "lixiao@1980",
|
||||||
"KafkaReplicationFactor": 3,
|
"KafkaReplicationFactor": 3,
|
||||||
"NumPartitions": 30,
|
"NumPartitions": 30,
|
||||||
|
"TaskThreadCount": -1,
|
||||||
"ServerTagName": "JiSheCollectBus100",
|
"ServerTagName": "JiSheCollectBus100",
|
||||||
"FirstCollectionTime": "2025-04-22 16:07:00"
|
"FirstCollectionTime": "2025-04-22 16:07:00"
|
||||||
},
|
},
|
||||||
"IoTDBOptions": {
|
"IoTDBOptions": {
|
||||||
"UserName": "root",
|
"UserName": "root",
|
||||||
"Password": "Yp2eU6MVdIjXCL",
|
"Password": "root",
|
||||||
"ClusterList": [ "47.110.53.196:6667", "47.110.60.222:6667", "47.110.62.104:6667" ],
|
//"ClusterList": [ "47.110.53.196:6667", "47.110.60.222:6667", "47.110.62.104:6667" ],
|
||||||
|
//"Password": "root",
|
||||||
|
"ClusterList": [ "121.42.175.177:16667" ],
|
||||||
"PoolSize": 2,
|
"PoolSize": 2,
|
||||||
"DataBaseName": "energy",
|
"DataBaseName": "energy",
|
||||||
"OpenDebugMode": true,
|
"OpenDebugMode": true,
|
||||||
|
|||||||
@ -1,39 +1,4 @@
|
|||||||
{
|
{
|
||||||
"Serilog": {
|
|
||||||
"Using": [
|
|
||||||
"Serilog.Sinks.Console",
|
|
||||||
"Serilog.Sinks.File"
|
|
||||||
],
|
|
||||||
"MinimumLevel": {
|
|
||||||
"Default": "Warning",
|
|
||||||
"Override": {
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Volo.Abp": "Warning",
|
|
||||||
"Hangfire": "Warning",
|
|
||||||
"DotNetCore.CAP": "Warning",
|
|
||||||
"Serilog.AspNetCore": "Information",
|
|
||||||
"Microsoft.EntityFrameworkCore": "Warning",
|
|
||||||
"Microsoft.AspNetCore": "Warning",
|
|
||||||
"Microsoft.AspNetCore.Diagnostics.HealthChecks": "Warning"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"WriteTo": [
|
|
||||||
{
|
|
||||||
"Name": "Console"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "File",
|
|
||||||
"Args": {
|
|
||||||
"path": "logs/logs-.txt",
|
|
||||||
"rollingInterval": "Day"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"App": {
|
|
||||||
"SelfUrl": "http://localhost:44315",
|
|
||||||
"CorsOrigins": "http://localhost:4200,http://localhost:3100"
|
|
||||||
},
|
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Default": "mongodb://mongo_PmEeF3:lixiao1980@192.168.5.9:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000",
|
"Default": "mongodb://mongo_PmEeF3:lixiao1980@192.168.5.9:27017/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000",
|
||||||
"Kafka": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092",
|
"Kafka": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092",
|
||||||
@ -46,46 +11,21 @@
|
|||||||
"DefaultDB": "14",
|
"DefaultDB": "14",
|
||||||
"HangfireDB": "13"
|
"HangfireDB": "13"
|
||||||
},
|
},
|
||||||
"Jwt": {
|
|
||||||
"Audience": "JiShe.CollectBus",
|
|
||||||
"SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=",
|
|
||||||
"Issuer": "JiShe.CollectBus",
|
|
||||||
"ExpirationTime": 2
|
|
||||||
},
|
|
||||||
"HealthChecks": {
|
|
||||||
"IsEnable": true,
|
|
||||||
"HealthCheckDatabaseName": "HealthChecks",
|
|
||||||
"EvaluationTimeInSeconds": 10,
|
|
||||||
"MinimumSecondsBetweenFailureNotifications": 60
|
|
||||||
},
|
|
||||||
"SwaggerConfig": [
|
|
||||||
{
|
|
||||||
"GroupName": "Basic",
|
|
||||||
"Title": "【后台管理】基础模块",
|
|
||||||
"Version": "V1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"GroupName": "Business",
|
|
||||||
"Title": "【后台管理】业务模块",
|
|
||||||
"Version": "V1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Kafka": {
|
"Kafka": {
|
||||||
"BootstrapServers": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092",
|
"BootstrapServers": "192.168.5.9:29092,192.168.5.9:39092,192.168.5.9:49092",
|
||||||
"EnableFilter": true,
|
"EnableFilter": true,
|
||||||
"EnableAuthorization": false,
|
"EnableAuthorization": false,
|
||||||
"SecurityProtocol": "SaslPlaintext",
|
|
||||||
"SaslMechanism": "Plain",
|
|
||||||
"SaslUserName": "lixiao",
|
"SaslUserName": "lixiao",
|
||||||
"SaslPassword": "lixiao1980",
|
"SaslPassword": "lixiao1980",
|
||||||
"KafkaReplicationFactor": 3,
|
"KafkaReplicationFactor": 3,
|
||||||
"NumPartitions": 30,
|
"NumPartitions": 30,
|
||||||
|
"TaskThreadCount": -1,
|
||||||
"FirstCollectionTime": "2025-04-22 16:07:00"
|
"FirstCollectionTime": "2025-04-22 16:07:00"
|
||||||
},
|
},
|
||||||
"IoTDBOptions": {
|
"IoTDBOptions": {
|
||||||
"UserName": "root",
|
"UserName": "root",
|
||||||
"Password": "root",
|
"Password": "root",
|
||||||
"ClusterList": [ "192.168.5.9:6667" ],
|
"ClusterList": [ "121.42.175.177:16667" ],
|
||||||
"PoolSize": 32,
|
"PoolSize": 32,
|
||||||
"DataBaseName": "energy",
|
"DataBaseName": "energy",
|
||||||
"OpenDebugMode": true,
|
"OpenDebugMode": true,
|
||||||
@ -140,6 +80,65 @@
|
|||||||
"DefaultIdempotence": true
|
"DefaultIdempotence": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Serilog": {
|
||||||
|
"Using": [
|
||||||
|
"Serilog.Sinks.Console",
|
||||||
|
"Serilog.Sinks.File"
|
||||||
|
],
|
||||||
|
"MinimumLevel": {
|
||||||
|
"Default": "Warning",
|
||||||
|
"Override": {
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Volo.Abp": "Warning",
|
||||||
|
"Hangfire": "Warning",
|
||||||
|
"DotNetCore.CAP": "Warning",
|
||||||
|
"Serilog.AspNetCore": "Information",
|
||||||
|
"Microsoft.EntityFrameworkCore": "Warning",
|
||||||
|
"Microsoft.AspNetCore": "Warning",
|
||||||
|
"Microsoft.AspNetCore.Diagnostics.HealthChecks": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WriteTo": [
|
||||||
|
{
|
||||||
|
"Name": "Console"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "File",
|
||||||
|
"Args": {
|
||||||
|
"path": "logs/logs-.txt",
|
||||||
|
"rollingInterval": "Hour"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"SelfUrl": "http://localhost:44315",
|
||||||
|
"CorsOrigins": "http://localhost:4200,http://localhost:3100"
|
||||||
|
},
|
||||||
|
"Jwt": {
|
||||||
|
"Audience": "JiShe.CollectBus",
|
||||||
|
"SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=",
|
||||||
|
"Issuer": "JiShe.CollectBus",
|
||||||
|
"ExpirationTime": 2
|
||||||
|
},
|
||||||
|
"HealthChecks": {
|
||||||
|
"IsEnable": false,
|
||||||
|
"HealthCheckDatabaseName": "HealthChecks",
|
||||||
|
"EvaluationTimeInSeconds": 10,
|
||||||
|
"MinimumSecondsBetweenFailureNotifications": 60
|
||||||
|
},
|
||||||
|
"SwaggerConfig": [
|
||||||
|
{
|
||||||
|
"GroupName": "Basic",
|
||||||
|
"Title": "【后台管理】基础模块",
|
||||||
|
"Version": "V1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "Business",
|
||||||
|
"Title": "【后台管理】业务模块",
|
||||||
|
"Version": "V1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"ServerApplicationOptions": {
|
"ServerApplicationOptions": {
|
||||||
"ServerTagName": "JiSheCollectBus99",
|
"ServerTagName": "JiSheCollectBus99",
|
||||||
"SystemType": "Energy",
|
"SystemType": "Energy",
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
//using Hangfire;
|
using JiShe.CollectBus.Migration.Host.HealthChecks;
|
||||||
//using Hangfire.Redis.StackExchange;
|
|
||||||
using JiShe.CollectBus.Migration.Host.Hangfire;
|
|
||||||
using JiShe.CollectBus.Migration.Host.HealthChecks;
|
|
||||||
using JiShe.CollectBus.Migration.Host.Swaggers;
|
using JiShe.CollectBus.Migration.Host.Swaggers;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
@ -12,7 +9,6 @@ using StackExchange.Redis;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Volo.Abp.AspNetCore.Auditing;
|
using Volo.Abp.AspNetCore.Auditing;
|
||||||
using Volo.Abp.Auditing;
|
using Volo.Abp.Auditing;
|
||||||
using Volo.Abp.BackgroundJobs;
|
|
||||||
using Volo.Abp.Caching;
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.Modularity;
|
using Volo.Abp.Modularity;
|
||||||
|
|
||||||
@ -21,33 +17,6 @@ namespace JiShe.CollectBus.Migration.Host
|
|||||||
{
|
{
|
||||||
public partial class CollectBusMigrationHostModule
|
public partial class CollectBusMigrationHostModule
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Configures the hangfire.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">The context.</param>
|
|
||||||
//private void ConfigureHangfire(ServiceConfigurationContext context)
|
|
||||||
//{
|
|
||||||
// var redisStorageOptions = new RedisStorageOptions()
|
|
||||||
// {
|
|
||||||
// Db = context.Services.GetConfiguration().GetValue<int>("Redis:HangfireDB")
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Configure<AbpBackgroundJobOptions>(options => { options.IsJobExecutionEnabled = false; });
|
|
||||||
|
|
||||||
// context.Services.AddHangfire(config =>
|
|
||||||
// {
|
|
||||||
// config.UseRedisStorage(
|
|
||||||
// context.Services.GetConfiguration().GetValue<string>("Redis:Configuration"), redisStorageOptions)
|
|
||||||
// .WithJobExpirationTimeout(TimeSpan.FromDays(7));
|
|
||||||
// var delaysInSeconds = new[] { 10, 60, 60 * 3 }; // 重试时间间隔
|
|
||||||
// const int Attempts = 3; // 重试次数
|
|
||||||
// config.UseFilter(new AutomaticRetryAttribute() { Attempts = Attempts, DelaysInSeconds = delaysInSeconds });
|
|
||||||
// //config.UseFilter(new AutoDeleteAfterSuccessAttribute(TimeSpan.FromDays(7)));
|
|
||||||
// config.UseFilter(new JobRetryLastFilter(Attempts));
|
|
||||||
// });
|
|
||||||
// context.Services.AddHangfireServer();
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configures the JWT authentication.
|
/// Configures the JWT authentication.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using JiShe.CollectBus.Common;
|
using JiShe.CollectBus.Common;
|
||||||
using JiShe.CollectBus.Migration.Host.HealthChecks;
|
using JiShe.CollectBus.Migration.Host.HealthChecks;
|
||||||
using JiShe.CollectBus.Migration.Host.Swaggers;
|
using JiShe.CollectBus.Migration.Host.Swaggers;
|
||||||
|
using JiShe.CollectBus.MongoDB;
|
||||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
@ -26,6 +27,7 @@ namespace JiShe.CollectBus.Migration.Host
|
|||||||
typeof(AbpAspNetCoreSerilogModule),
|
typeof(AbpAspNetCoreSerilogModule),
|
||||||
typeof(AbpSwashbuckleModule),
|
typeof(AbpSwashbuckleModule),
|
||||||
typeof(AbpTimingModule),
|
typeof(AbpTimingModule),
|
||||||
|
typeof(CollectBusMongoDbModule),
|
||||||
typeof(CollectBusMigrationApplicationModule),
|
typeof(CollectBusMigrationApplicationModule),
|
||||||
typeof(AbpCachingStackExchangeRedisModule)
|
typeof(AbpCachingStackExchangeRedisModule)
|
||||||
)]
|
)]
|
||||||
@ -42,7 +44,6 @@ namespace JiShe.CollectBus.Migration.Host
|
|||||||
ConfigureSwaggerServices(context, configuration);
|
ConfigureSwaggerServices(context, configuration);
|
||||||
//ConfigureNetwork(context, configuration);
|
//ConfigureNetwork(context, configuration);
|
||||||
ConfigureJwtAuthentication(context, configuration);
|
ConfigureJwtAuthentication(context, configuration);
|
||||||
//ConfigureHangfire(context);
|
|
||||||
ConfigureAuditLog(context);
|
ConfigureAuditLog(context);
|
||||||
ConfigureCustom(context, configuration);
|
ConfigureCustom(context, configuration);
|
||||||
ConfigureHealthChecks(context, configuration);
|
ConfigureHealthChecks(context, configuration);
|
||||||
@ -84,7 +85,7 @@ namespace JiShe.CollectBus.Migration.Host
|
|||||||
options.DefaultModelsExpandDepth(-1);
|
options.DefaultModelsExpandDepth(-1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//app.UseAuditing();
|
app.UseAuditing();
|
||||||
app.UseAbpSerilogEnrichers();
|
app.UseAbpSerilogEnrichers();
|
||||||
app.UseUnitOfWork();
|
app.UseUnitOfWork();
|
||||||
//app.UseHangfireDashboard("/hangfire", new DashboardOptions
|
//app.UseHangfireDashboard("/hangfire", new DashboardOptions
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
using Hangfire.Common;
|
|
||||||
using Hangfire.States;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace JiShe.CollectBus.Migration.Host.Hangfire
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 重试最后一次
|
|
||||||
/// </summary>
|
|
||||||
public class JobRetryLastFilter : JobFilterAttribute, IElectStateFilter
|
|
||||||
{
|
|
||||||
private int RetryCount { get; }
|
|
||||||
|
|
||||||
public JobRetryLastFilter(int retryCount)
|
|
||||||
{
|
|
||||||
RetryCount = retryCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void OnStateElection(ElectStateContext context)
|
|
||||||
{
|
|
||||||
var retryAttempt = context.GetJobParameter<int>("RetryCount");
|
|
||||||
if (RetryCount == retryAttempt)
|
|
||||||
{
|
|
||||||
Log.Error("最后一次重试");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -46,6 +46,8 @@
|
|||||||
<!--<PackageReference Include="Volo.Abp.BackgroundWorkers.Hangfire" Version="8.3.3" />-->
|
<!--<PackageReference Include="Volo.Abp.BackgroundWorkers.Hangfire" Version="8.3.3" />-->
|
||||||
|
|
||||||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.3" />
|
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.3" />
|
||||||
|
|
||||||
|
<PackageReference Include="Volo.Abp.Core" Version="8.3.3" />
|
||||||
<PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.3" />
|
<PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.3" />
|
||||||
<!--<PackageReference Include="Hangfire.HttpJob" Version="3.8.5" />
|
<!--<PackageReference Include="Hangfire.HttpJob" Version="3.8.5" />
|
||||||
<PackageReference Include="Hangfire.MySqlStorage" Version="2.0.3" />
|
<PackageReference Include="Hangfire.MySqlStorage" Version="2.0.3" />
|
||||||
@ -53,6 +55,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\modules\JiShe.CollectBus.MongoDB\JiShe.CollectBus.MongoDB.csproj" />
|
||||||
<ProjectReference Include="..\..\services\JiShe.CollectBus.Migration.Application.Contracts\JiShe.CollectBus.Migration.Application.Contracts.csproj" />
|
<ProjectReference Include="..\..\services\JiShe.CollectBus.Migration.Application.Contracts\JiShe.CollectBus.Migration.Application.Contracts.csproj" />
|
||||||
<ProjectReference Include="..\..\services\JiShe.CollectBus.Migration.Application\JiShe.CollectBus.Migration.Application.csproj" />
|
<ProjectReference Include="..\..\services\JiShe.CollectBus.Migration.Application\JiShe.CollectBus.Migration.Application.csproj" />
|
||||||
<ProjectReference Include="..\JiShe.CollectBus.Migration.HttpApi\JiShe.CollectBus.Migration.HttpApi.csproj" />
|
<ProjectReference Include="..\JiShe.CollectBus.Migration.HttpApi\JiShe.CollectBus.Migration.HttpApi.csproj" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user