修复IoTDB驱动适配增量源码生成器以后,单侧点模式失效的问题

This commit is contained in:
ChenYi 2025-05-08 22:44:01 +08:00
parent 8d1fc46e8f
commit 541c118dbb
7 changed files with 370 additions and 127 deletions

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.CollectBus.IoTDB.Exceptions
{
/// <summary>
/// IoTDB异常
/// </summary>
public class IoTException : Exception
{
public int ErrorCode { get; }
public IoTException(string message, int errorCode)
: base($"{message} (Code: {errorCode})")
{
ErrorCode = errorCode;
}
}
}

View File

@ -14,7 +14,6 @@
<ProjectReference Include="..\..\shared\JiShe.CollectBus.Analyzers.Shared\JiShe.CollectBus.Analyzers.Shared.csproj" /> <ProjectReference Include="..\..\shared\JiShe.CollectBus.Analyzers.Shared\JiShe.CollectBus.Analyzers.Shared.csproj" />
<ProjectReference Include="..\..\shared\JiShe.CollectBus.Common\JiShe.CollectBus.Common.csproj" /> <ProjectReference Include="..\..\shared\JiShe.CollectBus.Common\JiShe.CollectBus.Common.csproj" />
<ProjectReference Include="..\..\modules\JiShe.CollectBus.Analyzers\JiShe.CollectBus.Analyzers.csproj" <ProjectReference Include="..\..\modules\JiShe.CollectBus.Analyzers\JiShe.CollectBus.Analyzers.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -21,6 +21,7 @@ using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using JiShe.CollectBus.Analyzers.Shared; using JiShe.CollectBus.Analyzers.Shared;
using JiShe.CollectBus.IoTDB.Exceptions;
namespace JiShe.CollectBus.IoTDB.Provider namespace JiShe.CollectBus.IoTDB.Provider
{ {
@ -250,128 +251,337 @@ namespace JiShe.CollectBus.IoTDB.Provider
} }
} }
///// <summary>
///// 构建Tablet
///// </summary>
///// <typeparam name="T"></typeparam>
///// <param name="entities">表实体</param>
///// <param name="metadata">设备元数据</param></param>
///// <returns></returns>
//private Tablet BuildTablet<T>(IEnumerable<T> entities, DeviceMetadata metadata) where T : IoTEntity
//{
// var timestamps = new List<long>();
// var values = new List<List<object>>();
// var devicePaths = new HashSet<string>();
// List<string> tempColumnNames = new List<string>();
// tempColumnNames.AddRange(metadata.ColumnNames);
// var accessor = SourceEntityAccessorFactory.GetAccessor<T>();
// var memberCache = new Dictionary<string, EntityMemberInfo>(); // 缓存优化查询
// // 预构建成员缓存Key: NameOrPath
// foreach (var member in accessor.MemberList)
// {
// memberCache[member.NameOrPath] = member;
// }
// if (accessor.EntityType == null || metadata.EntityType == null)
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 {nameof(T)}的EntityType 没有指定,属于异常情况,-101");
// }
// if (metadata.EntityType != accessor.EntityType)
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 {nameof(T)}的EntityType 和{nameof(DeviceMetadata)}的 EntityType 不一致,属于异常情况,-102");
// }
// if (metadata.EntityType == EntityTypeEnum.TreeModel && _runtimeContext.UseTableSessionPool == true)
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 tree模型不能使用table模型Session连接属于异常情况-103");
// }
// else if (metadata.EntityType == EntityTypeEnum.TableModel && _runtimeContext.UseTableSessionPool == false)
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 table模型不能使用tree模型Session连接属于异常情况-104");
// }
// string tableNameOrTreePath = string.Empty;
// var tableNameOrTreePathAttribute = typeof(T).GetCustomAttribute<TableNameOrTreePathAttribute>();
// if (tableNameOrTreePathAttribute != null)
// {
// tableNameOrTreePath = tableNameOrTreePathAttribute.TableNameOrTreePath;
// }
// foreach (var entity in entities)
// {
// timestamps.Add(entity.Timestamps);
// var rowValues = new List<object>();
// foreach (var measurement in metadata.ColumnNames)
// {
// if (!memberCache.TryGetValue(measurement, out var member))
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构时{accessor.EntityName}没有找到{measurement}对应的member信息-105");
// }
// var value = member.GetValue(entity);
// // 特性查询优化
// var attributes = member.CustomAttributes ?? Enumerable.Empty<Attribute>();
// var singleMeasuringAttr = attributes.OfType<SingleMeasuringAttribute>().FirstOrDefault();
// if (singleMeasuringAttr != null)//如果是单侧点
// {
// var tupleItem1Key = $"{member.NameOrPath}.Item1";
// if (!memberCache.TryGetValue(tupleItem1Key, out var tuple1Member))
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构时{accessor.EntityName} 没有找到{measurement}对应的member Item1 信息,-106");
// }
// int indexOf = metadata.ColumnNames.IndexOf(measurement);
// tempColumnNames[indexOf] = (string)tuple1Member.GetValue(entity);
// var tupleItem2Key = $"{member.NameOrPath}.Item2";
// if (!memberCache.TryGetValue(tupleItem2Key, out var tuple2Member))
// {
// throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构时{accessor.EntityName} 没有找到{measurement}对应的member Item2 信息,-107");
// }
// value = tuple2Member.GetValue(entity);
// }
// if (value != null)
// {
// var tempValue = member.DeclaredTypeName.ToUpper() switch
// {
// "DATETIME" => Convert.ToDateTime(value).GetDateTimeOffset().ToUnixTimeNanoseconds(),
// _ => value
// };
// rowValues.Add(tempValue);
// }
// else
// {
// rowValues.Add(value);
// }
// }
// values.Add(rowValues);
// //如果指定了路径
// if (!string.IsNullOrWhiteSpace(tableNameOrTreePath))
// {
// devicePaths.Add(tableNameOrTreePath);
// }
// else
// {
// if (!_runtimeContext.UseTableSessionPool)//树模型
// {
// devicePaths.Add(DevicePathBuilder.GetDevicePath(entity));
// }
// else
// {
// devicePaths.Add(DevicePathBuilder.GetTableName<T>());
// }
// }
// }
// if (devicePaths.Count > 1)
// {
// throw new Exception($"{nameof(BuildTablet)} 构建Tablet《{typeof(T).Name}》时,批量插入的设备路径不一致。");
// }
// return _runtimeContext.UseTableSessionPool
// ? BuildTableSessionTablet(metadata, devicePaths.First(), tempColumnNames, values, timestamps)
// : BuildSessionTablet(metadata, devicePaths.First(), tempColumnNames,values, timestamps);
//}
/// <summary> /// <summary>
/// 构建Tablet /// 构建Tablet
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="entities">表实体</param> /// <param name="entities">表实体集合</param>
/// <param name="metadata">设备元数据</param></param> /// <param name="metadata">设备元数据</param></param>
/// <returns></returns> /// <returns></returns>
private Tablet BuildTablet<T>(IEnumerable<T> entities, DeviceMetadata metadata) where T : IoTEntity private Tablet BuildTablet<T>(IEnumerable<T> entities, DeviceMetadata metadata) where T : IoTEntity
{ {
var timestamps = new List<long>(); // 前置校验
var values = new List<List<object>>(); ValidateMetadataAndAccessor<T>(metadata, out var accessor);
var devicePaths = new HashSet<string>();
List<string> tempColumnNames = new List<string>();
tempColumnNames.AddRange(metadata.ColumnNames);
var accessor = SourceEntityAccessorFactory.GetAccessor<T>(); // 初始化数据结构
var (timestamps, values, devicePaths) = (new List<long>(), new List<List<object>>(), new HashSet<string>());
var tempColumnNames = new List<string>(metadata.ColumnNames);
var memberCache = BuildMemberCache(accessor);
var tableNameOrTreePath = GetTableNameOrTreePath<T>();
var memberCache = new Dictionary<string, EntityMemberInfo>(); // 缓存优化查询 // 处理每个实体
// 预构建成员缓存Key: NameOrPath foreach (var entity in entities)
foreach (var member in accessor.MemberList)
{ {
memberCache[member.NameOrPath] = member; ProcessEntity(entity, accessor, metadata, memberCache, tempColumnNames, timestamps, values);
UpdateDevicePaths(entity, tableNameOrTreePath, devicePaths);
} }
// 后置校验与返回
ValidateDevicePaths(devicePaths);
// return CreateFinalTablet(metadata, devicePaths.First(), tempColumnNames, values, timestamps);
return _runtimeContext.UseTableSessionPool
? BuildTableSessionTablet(metadata, devicePaths.First(), tempColumnNames, values, timestamps)
: BuildSessionTablet(metadata, devicePaths.First(), tempColumnNames, values, timestamps);
}
private void ValidateMetadataAndAccessor<T>(DeviceMetadata metadata, out ISourceEntityAccessor<T> accessor) where T : IoTEntity
{
accessor = SourceEntityAccessorFactory.GetAccessor<T>();
if (accessor.EntityType == null || metadata.EntityType == null) if (accessor.EntityType == null || metadata.EntityType == null)
{ {
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 {nameof(T)}的EntityType 没有指定,属于异常情况,-101"); throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时EntityType未指定", -101);
} }
if (metadata.EntityType != accessor.EntityType) if (metadata.EntityType != accessor.EntityType)
{ {
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 {nameof(T)}的EntityType 和{nameof(DeviceMetadata)}的 EntityType 不一致,属于异常情况,-102"); throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时EntityType不一致", -102);
} }
if (metadata.EntityType == EntityTypeEnum.TreeModel && _runtimeContext.UseTableSessionPool == true) bool isTableModel = accessor.EntityType == EntityTypeEnum.TableModel;
if (_runtimeContext.UseTableSessionPool != isTableModel)
{ {
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 tree模型不能使用table模型Session连接属于异常情况-103"); throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时Session类型不匹配: 预期{(isTableModel ? "Table" : "Tree")}模型", isTableModel ? -104 : -103);
}
else if (metadata.EntityType == EntityTypeEnum.TableModel && _runtimeContext.UseTableSessionPool == false)
{
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 table模型不能使用tree模型Session连接属于异常情况-104");
} }
}
string tableNameOrTreePath = string.Empty; /// <summary>
var tableNameOrTreePathAttribute = typeof(T).GetCustomAttribute<TableNameOrTreePathAttribute>(); /// 处理实体并获取值
if (tableNameOrTreePathAttribute != null) /// </summary>
{ /// <typeparam name="T"></typeparam>
tableNameOrTreePath = tableNameOrTreePathAttribute.TableNameOrTreePath; /// <param name="entity"></param>
} /// <param name="accessor"></param>
/// <param name="metadata"></param>
/// <param name="memberCache"></param>
/// <param name="tempColumnNames"></param>
/// <param name="timestamps"></param>
/// <param name="values"></param>
/// <exception cref="IoTException"></exception>
private void ProcessEntity<T>(
T entity,
ISourceEntityAccessor<T> accessor,
DeviceMetadata metadata,
Dictionary<string, EntityMemberInfo> memberCache,
List<string> tempColumnNames,
List<long> timestamps,
List<List<object>> values) where T : IoTEntity
{
timestamps.Add(entity.Timestamps);
var rowValues = new object[metadata.ColumnNames.Count];
foreach (var entity in entities) Parallel.ForEach(metadata.ColumnNames, (measurement, state, index) =>
{ {
timestamps.Add(entity.Timestamps); if (!memberCache.TryGetValue(measurement, out var member))
var rowValues = new List<object>();
foreach (var measurement in tempColumnNames)
{ {
if (!memberCache.TryGetValue(measurement, out var member)) throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时找不到成员: {measurement}", -105);
{
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构时{accessor.EntityName}没有找到{measurement}对应的member信息-105");
}
var value = member.GetValue(entity);
// 特性查询优化
var attributes = member.CustomAttributes ?? Enumerable.Empty<Attribute>();
var singleMeasuringAttr = attributes.OfType<SingleMeasuringAttribute>().FirstOrDefault();
if (singleMeasuringAttr != null)//如果是单侧点
{
var tupleItemKey = $"{member.NameOrPath}.Item2";
if (!memberCache.TryGetValue(tupleItemKey, out var tupleMember))
{
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构时{accessor.EntityName} 没有找到{measurement}对应的member Item2 信息,-106");
}
value = tupleMember.GetValue(entity);
}
if (value != null)
{
var tempValue = member.DeclaredTypeName.ToUpper() switch
{
"DATETIME" => Convert.ToDateTime(value).GetDateTimeOffset().ToUnixTimeNanoseconds(),
_ => value
};
rowValues.Add(tempValue);
}
else
{
rowValues.Add(value);
}
} }
values.Add(rowValues); object value = ResolveMemberValue(entity, member, memberCache, tempColumnNames, (int)index);
rowValues[index] = ConvertValueByType(member, value);
});
//如果指定了路径 values.Add(rowValues.ToList());
if (!string.IsNullOrWhiteSpace(tableNameOrTreePath)) }
private object ResolveMemberValue<T>(
T entity,
EntityMemberInfo member,
Dictionary<string, EntityMemberInfo> memberCache,
List<string> tempColumnNames,
int columnIndex) where T : IoTEntity
{
// 单测点逻辑
if (member.CustomAttributes?.OfType<SingleMeasuringAttribute>().FirstOrDefault() is { } attr)
{
var tuple1Key = $"{member.NameOrPath}.Item1";
var tuple2Key = $"{member.NameOrPath}.Item2";
if (!memberCache.TryGetValue(tuple1Key, out var tuple1) || !memberCache.TryGetValue(tuple2Key, out var tuple2))
{ {
devicePaths.Add(tableNameOrTreePath); throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时单侧点元组成员缺失", -106);
}
else
{
if (!_runtimeContext.UseTableSessionPool)//树模型
{
devicePaths.Add(DevicePathBuilder.GetDevicePath(entity));
}
else
{
devicePaths.Add(DevicePathBuilder.GetTableName<T>());
}
} }
tempColumnNames[columnIndex] = (string)tuple1.GetValue(entity);
return tuple2.GetValue(entity);
}
return member.GetValue(entity);
}
/// <summary>
/// 设置实体的成员值
/// </summary>
/// <param name="member"></param>
/// <param name="value"></param>
/// <returns></returns>
private object ConvertValueByType(EntityMemberInfo member, object value)
{
return member.DeclaredTypeName switch
{
"DATETIME" => Convert.ToDateTime(value).GetDateTimeOffset().ToUnixTimeNanoseconds(),
_ => value
};
}
/// <summary>
/// 处理设备路径
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="tableNameOrTreePath"></param>
/// <param name="devicePaths"></param>
private void UpdateDevicePaths<T>(
T entity,
string tableNameOrTreePath,
HashSet<string> devicePaths) where T : IoTEntity
{
if (!string.IsNullOrEmpty(tableNameOrTreePath))
{
devicePaths.Add(tableNameOrTreePath);
return;
}
var path = _runtimeContext.UseTableSessionPool
? DevicePathBuilder.GetTableName<T>()
: DevicePathBuilder.GetDevicePath(entity);
devicePaths.Add(path);
}
/// <summary>
/// 验证设备路径
/// </summary>
/// <param name="devicePaths"></param>
private void ValidateDevicePaths(HashSet<string> devicePaths)
{
if (devicePaths.Count == 0)
{
throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时设备路径集合为空", -108);
} }
if (devicePaths.Count > 1) if (devicePaths.Count > 1)
{ {
throw new Exception($"{nameof(BuildTablet)} 构建Tablet《{typeof(T).Name}》时,批量插入的设备路径不一致。"); var paths = string.Join(", ", devicePaths.Take(3));
{
throw new IoTException($"{nameof(BuildTablet)} 构建IoTDB数据结构时设备路径不一致。检测到路径: {paths}...", -109);
}
} }
}
return _runtimeContext.UseTableSessionPool /// <summary>
? BuildTableSessionTablet(metadata, devicePaths.First(), values, timestamps) /// 缓存优化:避免重复反射
: BuildSessionTablet(metadata, devicePaths.First(), values, timestamps); /// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private string GetTableNameOrTreePath<T>()
{
return AttributeCache<T>.TableNameOrTreePath;
}
/// <summary>
/// 特性缓存辅助类
/// </summary>
/// <typeparam name="T"></typeparam>
private static class AttributeCache<T>
{
public static readonly string TableNameOrTreePath;
static AttributeCache()
{
var attr = typeof(T).GetCustomAttribute<TableNameOrTreePathAttribute>();
TableNameOrTreePath = attr?.TableNameOrTreePath ?? string.Empty;
}
} }
/// <summary> /// <summary>
@ -379,16 +589,17 @@ namespace JiShe.CollectBus.IoTDB.Provider
/// </summary> /// </summary>
/// <param name="metadata">已解析的设备数据元数据</param> /// <param name="metadata">已解析的设备数据元数据</param>
/// <param name="devicePath">设备路径</param> /// <param name="devicePath">设备路径</param>
/// <param name="columns">数据列集合</param>
/// <param name="values">数据集合</param> /// <param name="values">数据集合</param>
/// <param name="timestamps">时间戳集合</param> /// <param name="timestamps">时间戳集合</param>
/// <returns></returns> /// <returns></returns>
private Tablet BuildSessionTablet(DeviceMetadata metadata, string devicePath, List<List<object>> values, List<long> timestamps) private Tablet BuildSessionTablet(DeviceMetadata metadata, string devicePath, List<string> columns, List<List<object>> values, List<long> timestamps)
{ {
//todo 树模型需要去掉TAG类型和ATTRIBUTE类型的字段只需要保留FIELD类型字段即可 //todo 树模型需要去掉TAG类型和ATTRIBUTE类型的字段只需要保留FIELD类型字段即可
return new Tablet( return new Tablet(
devicePath, devicePath,
metadata.ColumnNames, columns,
metadata.DataTypes, metadata.DataTypes,
values, values,
timestamps timestamps
@ -400,14 +611,15 @@ namespace JiShe.CollectBus.IoTDB.Provider
/// </summary> /// </summary>
/// <param name="metadata">已解析的设备数据元数据</param> /// <param name="metadata">已解析的设备数据元数据</param>
/// <param name="tableName">表名称</param> /// <param name="tableName">表名称</param>
/// <param name="columns">数据列集合</param>
/// <param name="values">数据集合</param> /// <param name="values">数据集合</param>
/// <param name="timestamps">时间戳集合</param> /// <param name="timestamps">时间戳集合</param>
/// <returns></returns> /// <returns></returns>
private Tablet BuildTableSessionTablet(DeviceMetadata metadata, string tableName, List<List<object>> values, List<long> timestamps) private Tablet BuildTableSessionTablet(DeviceMetadata metadata, string tableName, List<string> columns,List<List<object>> values, List<long> timestamps)
{ {
var tablet = new Tablet( var tablet = new Tablet(
tableName, tableName,
metadata.ColumnNames, columns,
metadata.ColumnCategories, metadata.ColumnCategories,
metadata.DataTypes, metadata.DataTypes,
values, values,
@ -535,13 +747,7 @@ namespace JiShe.CollectBus.IoTDB.Provider
var metadata = await GetMetadata<T>(); var metadata = await GetMetadata<T>();
var accessor = SourceEntityAccessorFactory.GetAccessor<T>(); var accessor = SourceEntityAccessorFactory.GetAccessor<T>();
var memberCache = new Dictionary<string, EntityMemberInfo>(); // 缓存优化查询 var memberCache = BuildMemberCache(accessor);
// 预构建成员缓存Key: NameOrPath
foreach (var member in accessor.MemberList)
{
memberCache[member.NameOrPath] = member;
}
var columns = new List<string>() { "Timestamps" }; var columns = new List<string>() { "Timestamps" };
var dataTypes = new List<TSDataType>() { TSDataType.TIMESTAMP }; var dataTypes = new List<TSDataType>() { TSDataType.TIMESTAMP };
@ -596,13 +802,7 @@ namespace JiShe.CollectBus.IoTDB.Provider
private List<ColumnInfo> CollectColumnMetadata<T>(ISourceEntityAccessor<T> accessor) private List<ColumnInfo> CollectColumnMetadata<T>(ISourceEntityAccessor<T> accessor)
{ {
var columns = new List<ColumnInfo>(); var columns = new List<ColumnInfo>();
var memberCache = new Dictionary<string, EntityMemberInfo>(); // 缓存优化查询 var memberCache = BuildMemberCache(accessor);
// 预构建成员缓存Key: NameOrPath
foreach (var member in accessor.MemberList)
{
memberCache[member.NameOrPath] = member;
}
foreach (var member in accessor.MemberList) foreach (var member in accessor.MemberList)
{ {
@ -807,5 +1007,21 @@ namespace JiShe.CollectBus.IoTDB.Provider
TSDataType.STRING => Convert.ToString(value), TSDataType.STRING => Convert.ToString(value),
_ => Convert.ToString(value) _ => Convert.ToString(value)
}; };
/// <summary>
/// 缓存实体属性信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="accessor"></param>
/// <returns></returns>
private Dictionary<string, EntityMemberInfo> BuildMemberCache<T>(ISourceEntityAccessor<T> accessor)
{
var cache = new Dictionary<string, EntityMemberInfo>(StringComparer.Ordinal);
foreach (var member in accessor.MemberList)
{
cache[member.NameOrPath] = member;
}
return cache;
}
} }
} }

View File

@ -7,8 +7,9 @@ using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Extensions; 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.DataMigration.Options;
using JiShe.CollectBus.GatherItem; using JiShe.CollectBus.GatherItem;
using JiShe.CollectBus.IoTDB.Context;
using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IoTDB.Interface;
using JiShe.CollectBus.IoTDB.Model; using JiShe.CollectBus.IoTDB.Model;
using JiShe.CollectBus.IoTDB.Options; using JiShe.CollectBus.IoTDB.Options;
@ -17,8 +18,8 @@ using JiShe.CollectBus.IotSystems.Ammeters;
using JiShe.CollectBus.IotSystems.MeterReadingRecords; using JiShe.CollectBus.IotSystems.MeterReadingRecords;
using JiShe.CollectBus.IotSystems.Watermeter; using JiShe.CollectBus.IotSystems.Watermeter;
using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Internal;
using JiShe.CollectBus.Kafka.Producer;
using JiShe.CollectBus.Protocol.Interfaces; using JiShe.CollectBus.Protocol.Interfaces;
using JiShe.CollectBus.Protocol.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
@ -26,14 +27,6 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using JiShe.CollectBus.Protocol.Models;
using System.Threading.Channels;
using static IdentityModel.ClaimComparer;
using JiShe.CollectBus.DataChannels;
using JiShe.CollectBus.DataMigration.Options;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static System.Formats.Asn1.AsnWriter;
using System.Threading;
namespace JiShe.CollectBus.ScheduledMeterReading namespace JiShe.CollectBus.ScheduledMeterReading
{ {
@ -329,7 +322,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
/// <returns></returns> /// <returns></returns>
public virtual async Task InitAmmeterCacheData(string gatherCode = "") public virtual async Task InitAmmeterCacheData(string gatherCode = "")
{ {
return; //return;
// 创建取消令牌源 // 创建取消令牌源
//var cts = new CancellationTokenSource(); //var cts = new CancellationTokenSource();
@ -744,7 +737,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
ItemCode = tempItem, ItemCode = tempItem,
DataTimeMark = new Protocol.DataTimeMark() DataTimeMark = new Protocol.DataTimeMark()
{ {
Density = ammeterInfo.TimeDensity,//todo 转换成协议的值 Density = ammeterInfo.TimeDensity.GetDensity(),//转换成协议的值
Point = 1, Point = 1,
DataTime = timestamps, DataTime = timestamps,
} }
@ -1354,7 +1347,6 @@ namespace JiShe.CollectBus.ScheduledMeterReading
} }
List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>(); List<MeterReadingTelemetryPacketInfo> taskList = new List<MeterReadingTelemetryPacketInfo>();
var metadata = await _dbProvider.GetMetadata<MeterReadingTelemetryPacketInfo>();
var itemCode = T37612012PacketItemCodeConst.AFN09HFN01H; var itemCode = T37612012PacketItemCodeConst.AFN09HFN01H;
//var subItemCode = T6452007PacketItemCodeConst.C08; //var subItemCode = T6452007PacketItemCodeConst.C08;

View File

@ -859,6 +859,21 @@ namespace JiShe.CollectBus.Common.Helpers
} }
/// <summary>
/// 采集频率转换为集中器采集密度
/// </summary>
/// <param name="timeDensity"></param>
/// <returns></returns>
public static int GetDensity(this int timeDensity) =>
timeDensity switch
{
0 => 0,//无
1 => 255,//1分钟
5 => 245,//5分钟
15 => 1,//15分钟
30 => 2,//30分钟
60 => 3,//60分钟
_ => -1//采集项本身无密度位
};
} }
} }

View File

@ -16,7 +16,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<title>后端服务</title> <title>后端服务</title>
</head> </head>
<body> <body>

View File

@ -141,7 +141,7 @@
} }
}, },
"ServerApplicationOptions": { "ServerApplicationOptions": {
"ServerTagName": "JiSheCollectBus99", "ServerTagName": "JiSheCollectBus4",
"SystemType": "Energy", "SystemType": "Energy",
"FirstCollectionTime": "2025-04-28 15:07:00", "FirstCollectionTime": "2025-04-28 15:07:00",
"AutomaticVerificationTime": "16:07:00", "AutomaticVerificationTime": "16:07:00",