diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs index ecb9c78..9212cda 100644 --- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs +++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs @@ -531,7 +531,14 @@ namespace JiShe.CollectBus.IncrementalGenerator var entityType = prop.ContainingType.ToDisplayString();//entity 实体类型名称 var propType = prop.Type;//实体属性的类型 var propTypeName = propType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - var declaredTypeName = propType.Name; // 直接获取类型名称(如 "Int32") + // var declaredTypeName = propType.Name; // 直接获取类型名称(如 "Int32") + // 处理可空类型,获取底层具体类型名称 + var declaredTypeName = propType switch + { + INamedTypeSymbol { OriginalDefinition.SpecialType: SpecialType.System_Nullable_T } nullableType => + nullableType.TypeArguments[0].Name, // 提取如 "Int32" + _ => propType.Name + }; // 处理主属性 var propAttributes = prop.GetAttributes() diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs index 88c6b92..963d45f 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs +++ b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs @@ -283,7 +283,7 @@ namespace JiShe.CollectBus.IoTDB.Provider }; stopwatch2.Stop(); - + //int totalPageCount = (int)Math.Ceiling((double)result.TotalCount / options.PageSize); if (result.Items.Count() < result.PageSize) @@ -400,7 +400,7 @@ namespace JiShe.CollectBus.IoTDB.Provider { tempColumnNames[i] = (string)processor.SingleMeasuringNameGetter(entity); } - + // 获取并转换值 values[row][i] = processor.ValueGetter(entity); } @@ -576,7 +576,7 @@ namespace JiShe.CollectBus.IoTDB.Provider var accessor = SourceEntityAccessorFactory.GetAccessor(); var memberCache = BuildMemberCache(accessor); - + while (dataSet.HasNext() && results.Count < pageSize) { @@ -589,9 +589,12 @@ namespace JiShe.CollectBus.IoTDB.Provider for (int i = 0; i < metadata.Processors.Count; i++) { var value = record.Values[i]; - metadata.Processors[i].ValueSetter(entity, value); + if (!(value is System.DBNull)) + { + metadata.Processors[i].ValueSetter(entity, value); + } } - + results.Add(entity); } @@ -614,10 +617,8 @@ namespace JiShe.CollectBus.IoTDB.Provider // 过滤元组子项 if (member.NameOrPath.Contains(".Item")) continue; - // 类型名称处理 - Type declaredType = member.DeclaredType; - var underlyingType = Nullable.GetUnderlyingType(declaredType); - string declaredTypeName = underlyingType?.Name ?? member.DeclaredTypeName; + // 类型名称处理 + string declaredTypeName = member.DeclaredTypeName; // 特性查询优化 var attributes = member.CustomAttributes ?? Enumerable.Empty(); @@ -630,15 +631,15 @@ namespace JiShe.CollectBus.IoTDB.Provider ColumnInfo? column = null; if (tagAttr != null) { - column = new ColumnInfo(member.NameOrPath, ColumnCategory.TAG, GetDataTypeFromTypeName(declaredTypeName), false, member.DeclaredTypeName); + 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(declaredTypeName), false, member.DeclaredTypeName); + 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(declaredTypeName), false, member.DeclaredTypeName); + column = new ColumnInfo(member.NameOrPath, ColumnCategory.FIELD, GetDataTypeFromTypeName(member.DeclaredTypeName), false, member.DeclaredTypeName); } // 单测模式处理 @@ -715,7 +716,8 @@ namespace JiShe.CollectBus.IoTDB.Provider var item2Member = accessor.MemberList .First(m => m.NameOrPath == $"{column.Name}.Item2"); - processor.ValueGetter = (obj) => { + processor.ValueGetter = (obj) => + { object rawValue = item2Member.Getter(obj); return processor.GetConverter(rawValue); }; @@ -724,7 +726,8 @@ namespace JiShe.CollectBus.IoTDB.Provider { // 获取对应的成员访问器 var member = accessor.MemberList.First(m => m.NameOrPath == column.Name); - processor.ValueGetter = (obj) => { + processor.ValueGetter = (obj) => + { object rawValue = member.Getter(obj); return processor.GetConverter(rawValue); }; @@ -793,7 +796,7 @@ namespace JiShe.CollectBus.IoTDB.Provider { return declaredTypeName switch { - "DATETIME" => value => ((DateTime)value).GetDateTimeOffset().ToUnixTimeNanoseconds(), + "DATETIME" => value => value != null ? ((DateTime)value).GetDateTimeOffset().ToUnixTimeNanoseconds() : null, _ => value => value }; } @@ -803,9 +806,9 @@ namespace JiShe.CollectBus.IoTDB.Provider /// /// /// - private Func SetterConverter(string columnName) => + private Func SetterConverter(string columnName) => columnName.ToLower().EndsWith("time") - ? value => new DateTime(Convert.ToInt64(value), DateTimeKind.Utc) + ? value => value != null ? TimestampHelper.ConvertToDateTime(Convert.ToInt64(value), TimestampUnit.Nanoseconds) : null : value => value; /// diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs index 3035633..e4c61d6 100644 --- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs @@ -87,8 +87,9 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS //ElectricityMeterTreeModelAccessor. //TableModelSingleMeasuringEntityExtension - //TableModelSingleMeasuringEntityAccessor.GetSystemName(meter); - await _iotDBProvider.InsertAsync(meter); + //TableModelSingleMeasuringEntityAccessor.GetSystemName(meter); + //ElectricityMeterAccessor + await _iotDBProvider.InsertAsync(meter); } /// @@ -124,10 +125,29 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS MeterModel = "DDZY-1980", ProjectId = "10059", Voltage = 10, + CurrentdDateTime = DateTime.Now, Timestamps = DateTimeOffset.Now.ToUnixTimeNanoseconds(), }; await _iotDBProvider.InsertAsync(meter); + QueryCondition conditions = new QueryCondition() + { + Field = "DeviceId", + Operator = "=", + Value = meter.DeviceId + }; + + + var query = new IoTDBQueryOptions() + { + TableNameOrTreePath = nameof(ElectricityMeter), + PageIndex = 1, + PageSize = 1, + Conditions = new List() { conditions }, + }; + + var pageResult = await _iotDBProvider.QueryAsync(query); + } /// diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs index c8826ba..cd694cf 100644 --- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs @@ -371,8 +371,8 @@ namespace JiShe.CollectBus.ScheduledMeterReading timer1.Stop(); _logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒"); - DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions); - return; + //DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions); + //return; #else var meterInfos = await GetAmmeterInfoList(gatherCode); #endif diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs index 1e1e6cb..796f328 100644 --- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs +++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs @@ -1,6 +1,7 @@ using JiShe.CollectBus.Analyzers.Shared; using JiShe.CollectBus.IoTDB.Attributes; using JiShe.CollectBus.IoTDB.Model; +using System; namespace JiShe.CollectBus.Ammeters { @@ -33,5 +34,8 @@ namespace JiShe.CollectBus.Ammeters [FIELDColumn] public double? Currentd { get; set; } + + [FIELDColumn] + public DateTime? CurrentdDateTime { get; set; } } } diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs index 49b5abe..6eb5ef4 100644 --- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs +++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs @@ -34,7 +34,5 @@ namespace JiShe.CollectBus.Ammeters [FIELDColumn] public double? Currentd { get; set; } - - public ValueTuple TupleData { get; set; } } } diff --git a/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs index 4cd69ba..a7792c3 100644 --- a/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs +++ b/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs @@ -79,12 +79,7 @@ namespace JiShe.CollectBus.IotSystems.Ammeters /// 电表密码 /// public string Password { get; set; } - - /// - /// 采集时间间隔(分钟,如15) - /// - public int TimeDensity { get; set; } - + /// /// 该电表方案下采集项,JSON格式,如:["0D_80","0D_80"] /// diff --git a/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceCacheInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceCacheInfo.cs new file mode 100644 index 0000000..26bc6aa --- /dev/null +++ b/services/JiShe.CollectBus.Domain/IotSystems/Devices/DeviceCacheInfo.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using JiShe.CollectBus.Analyzers.Shared; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.IoTDB.Attributes; +using JiShe.CollectBus.IoTDB.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.IotSystems.Devices +{ + /// + /// 设备缓存信息 + /// + public class DeviceCacheInfo : DeviceCacheBasicModel + { + /// + /// 关系映射标识,用于ZSet的Member字段和Set的Value字段,具体值可以根据不同业务场景进行定义 + /// + [Column(IsIgnore = true)] + public override string MemberId => $"{FocusAddress}:{MeteringCode}"; + + /// + /// ZSet排序索引分数值,具体值可以根据不同业务场景进行定义,例如时间戳 + /// + [Column(IsIgnore = true)] + public override long ScoreValue => Common.Helpers.CommonHelper.GetFocusScores(FocusAddress, MeteringCode); + + /// + /// 标记信息设备类型 + /// + [Column(IsIgnore = true)] + public MeterTypeEnum MeterType { get; set; } + + /// + /// 电表名称 + /// + public string Name { get; set; } + + /// + /// 集中器地址 + /// + public string Address { get; set; } + + /// + /// 集中器区域代码 + /// + public string AreaCode { get; set; } + + /// + /// 电表类别 (1单相、2三相三线、3三相四线), + /// 07协议: 开合闸指令(1A开闸断电,1C单相表合闸,1B多相表合闸) 645 2007 表 + /// 97协议://true(合闸);false(跳闸) 545 1997 没有单相多相 之分 "true" ? "9966" : "3355" + /// + public int TypeName { get; set; } + + /// + /// 跳合闸状态字段: 0 合闸,1 跳闸 + /// 电表:TripState (0 合闸-通电, 1 断开、跳闸); + /// + public int TripState { get; set; } + + /// + /// 规约 -电表default(30) 1:97协议,30:07协议 + /// + public int? Protocol { get; set; } + + /// + /// 一个集中器下的[MeteringCode]必须唯一。 PN + /// + public int MeteringCode { get; set; } + + /// + /// 电表通信地址 + /// + public string AmmerterAddress { get; set; } + + /// + /// 波特率 default(2400) + /// + public int Baudrate { get; set; } + + /// + /// MeteringPort 端口就几个可以枚举。 + /// + public int MeteringPort { get; set; } + + /// + /// 电表密码 + /// + public string Password { get; set; } + + /// + /// 该电表方案下采集项,JSON格式,如:["0D_80","0D_80"] + /// + public string ItemCodes { get; set; } + + /// + /// State表状态: + /// 0新装(未下发),1运行(档案下发成功时设置状态值1), 2暂停, 100销表(销表后是否重新启用) + /// 特定:State -1 已删除 + /// + public int State { get; set; } + + /// + /// 是否自动采集(0:主动采集,1:自动采集) + /// + public int AutomaticReport { get; set; } + + /// + /// 该电表方案下采集项编号 + /// + public string DataTypes { get; set; } + + /// + /// 品牌型号 + /// + public string BrandType { get; set; } + + /// + /// 采集器编号 + /// + public string GatherCode { get; set; } + + /// + /// 是否特殊表,1是特殊电表 + /// + public int Special { get; set; } + + /// + /// 费率类型,单、多 (SingleRate :单费率(单相表1),多费率(其他0) ,与TypeName字段无关) + /// SingleRate ? "单" : "复" + /// [SingleRate] --0 复费率 false , 1 单费率 true (与PayPlanID保持一致) + ///对应 TB_PayPlan.Type: 1复费率,2单费率 + /// + public bool SingleRate { get; set; } + + /// + /// 项目ID + /// + public int ProjectID { get; set; } + + /// + /// 数据库业务ID + /// + public int DatabaseBusiID { get; set; } + + /// + /// 是否异常集中器 0:正常,1异常 + /// + public int AbnormalState { get; set; } + } +} diff --git a/shared/JiShe.CollectBus.Common/Models/DeviceCacheBasicModel.cs b/shared/JiShe.CollectBus.Common/Models/DeviceCacheBasicModel.cs index 1edc46a..e3f79ce 100644 --- a/shared/JiShe.CollectBus.Common/Models/DeviceCacheBasicModel.cs +++ b/shared/JiShe.CollectBus.Common/Models/DeviceCacheBasicModel.cs @@ -40,5 +40,10 @@ namespace JiShe.CollectBus.Common.Models /// 集中器地址 /// public string FocusAddress { get; set;} + + /// + /// 采集时间间隔(分钟,如15) + /// + public int TimeDensity { get; set; } } }