diff --git a/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs index 02ac3ee..b896bdf 100644 --- a/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs +++ b/modules/JiShe.CollectBus.IoTDB/Interface/IIoTDBProvider.cs @@ -1,6 +1,6 @@ using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.IoTDB.Model; using JiShe.CollectBus.IoTDB.Options; -using JiShe.CollectBus.IoTDB.Provider; namespace JiShe.CollectBus.IoTDB.Interface { diff --git a/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj b/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj index dc8f2fb..8cc4b33 100644 --- a/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj +++ b/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj @@ -6,7 +6,6 @@ enable - diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs similarity index 79% rename from modules/JiShe.CollectBus.IoTDB/Provider/IoTEntity.cs rename to modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs index fc965e6..6431e6f 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTEntity.cs +++ b/modules/JiShe.CollectBus.IoTDB/Model/IoTEntity.cs @@ -1,9 +1,9 @@ using JiShe.CollectBus.IoTDB.Attribute; -namespace JiShe.CollectBus.IoTDB.Provider +namespace JiShe.CollectBus.IoTDB.Model { /// - /// IoT实体基类 + /// IoT实体基类,此类适用于多个数据测点记录场景,单个测点请使用子类 SingleMeasuringEntity /// public abstract class IoTEntity { @@ -32,7 +32,7 @@ namespace JiShe.CollectBus.IoTDB.Provider public required string DeviceId { get; set; } /// - /// 当前时间戳,单位毫秒 + /// 当前时间戳,单位毫秒,必须通过DateTimeOffset获取 /// public required long Timestamps { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } diff --git a/services/JiShe.CollectBus.Domain/IotSystems/AFNEntity/SingleMeasuringAFNDataEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/SingleMeasuringEntity.cs similarity index 58% rename from services/JiShe.CollectBus.Domain/IotSystems/AFNEntity/SingleMeasuringAFNDataEntity.cs rename to modules/JiShe.CollectBus.IoTDB/Model/SingleMeasuringEntity.cs index 0440c1d..72a8ae6 100644 --- a/services/JiShe.CollectBus.Domain/IotSystems/AFNEntity/SingleMeasuringAFNDataEntity.cs +++ b/modules/JiShe.CollectBus.IoTDB/Model/SingleMeasuringEntity.cs @@ -4,19 +4,21 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using JiShe.CollectBus.IoTDB.Attribute; +using JiShe.CollectBus.IoTDB.Enums; using JiShe.CollectBus.IoTDB.Provider; -namespace JiShe.CollectBus.IotSystems.AFNEntity +namespace JiShe.CollectBus.IoTDB.Model { /// - /// AFN单项数据实体 + /// 单项数据实体 /// - public class SingleMeasuringAFNDataEntity : IoTEntity + [EntityType(EntityTypeEnum.TreeModel)] + public class SingleMeasuringEntity : IoTEntity { /// /// 单项数据对象 /// [SingleMeasuring(nameof(SingleMeasuring))] - public Tuple SingleMeasuring { get; set; } + public required Tuple SingleMeasuring { get; set; } } } diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/DevicePathBuilder.cs b/modules/JiShe.CollectBus.IoTDB/Provider/DevicePathBuilder.cs index b78dfa3..a858c73 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/DevicePathBuilder.cs +++ b/modules/JiShe.CollectBus.IoTDB/Provider/DevicePathBuilder.cs @@ -1,4 +1,6 @@ -namespace JiShe.CollectBus.IoTDB.Provider +using JiShe.CollectBus.IoTDB.Model; + +namespace JiShe.CollectBus.IoTDB.Provider { /// /// 设备路径构建器 diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs index fdb9789..1fac82a 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs +++ b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs @@ -8,8 +8,10 @@ using JiShe.CollectBus.Common.Models; using JiShe.CollectBus.IoTDB.Attribute; using JiShe.CollectBus.IoTDB.Context; using JiShe.CollectBus.IoTDB.Interface; +using JiShe.CollectBus.IoTDB.Model; using JiShe.CollectBus.IoTDB.Options; using Microsoft.Extensions.Logging; +using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities; namespace JiShe.CollectBus.IoTDB.Provider @@ -56,13 +58,7 @@ namespace JiShe.CollectBus.IoTDB.Provider var tablet = BuildTablet(new[] { entity }, metadata); - await CurrentSession.InsertAsync(tablet); - - //int result = await _currentSession.InsertAsync(tablet); - //if (result <= 0) - //{ - // _logger.LogError($"{typeof(T).Name}插入数据没有成功"); - //} + await CurrentSession.InsertAsync(tablet); } /// @@ -80,12 +76,7 @@ namespace JiShe.CollectBus.IoTDB.Provider foreach (var batch in batches) { var tablet = BuildTablet(batch, metadata); - await CurrentSession.InsertAsync(tablet); - //var result = await _currentSession.InsertAsync(tablet); - //if (result <= 0) - //{ - // _logger.LogWarning($"{typeof(T).Name} 批量插入数据第{batch}批次没有成功,共{batches}批次。"); - //} + await CurrentSession.InsertAsync(tablet); } } @@ -159,7 +150,7 @@ namespace JiShe.CollectBus.IoTDB.Provider throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 {nameof(T)}的EntityType 和{nameof(DeviceMetadata)}的 EntityType 不一致,属于异常情况,-102"); } - if(metadata.EntityType == Enums.EntityTypeEnum.TreeModel && _runtimeContext.UseTableSessionPool == true) + if (metadata.EntityType == Enums.EntityTypeEnum.TreeModel && _runtimeContext.UseTableSessionPool == true) { throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 tree模型不能使用table模型Session连接,属于异常情况,-103"); } @@ -169,77 +160,65 @@ namespace JiShe.CollectBus.IoTDB.Provider } - foreach (var entity in entities) + foreach (var entity in entities) + { + timestamps.Add(entity.Timestamps); + var rowValues = new List(); + + foreach (var measurement in tempColumnNames) { - timestamps.Add(entity.Timestamps); - var rowValues = new List(); - foreach (var measurement in tempColumnNames) + PropertyInfo propertyInfo = typeof(T).GetProperty(measurement); + if (propertyInfo == null) { + throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,没有找到{measurement}属性,属于异常情况,-101。"); + } - PropertyInfo propertyInfo = typeof(T).GetProperty(measurement); - if (propertyInfo == null) + var value = propertyInfo.GetValue(entity); + if (propertyInfo.IsDefined(typeof(SingleMeasuringAttribute), false) && metadata.IsSingleMeasuring == true)//表示当前对象是单测点模式 + { + if (value != null) { - throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,没有找到{measurement}属性,属于异常情况,-101。"); - } - - var value = propertyInfo.GetValue(entity); - if (propertyInfo.IsDefined(typeof(SingleMeasuringAttribute), false) && metadata.IsSingleMeasuring == true)//表示当前对象是单测点模式 - { - if (value != null) + Type tupleType = value.GetType(); + Type[] tupleArgs = tupleType.GetGenericArguments(); + Type item2Type = tupleArgs[1]; // T 的实际类型 + var item1 = tupleType.GetProperty("Item1")!.GetValue(value); + var item2 = tupleType.GetProperty("Item2")!.GetValue(value); + if (item1 == null || item2 == null) { - Type tupleType = value.GetType(); - Type[] tupleArgs = tupleType.GetGenericArguments(); - Type item2Type = tupleArgs[1]; // T 的实际类型 - var item1 = tupleType.GetProperty("Item1")!.GetValue(value); - var item2 = tupleType.GetProperty("Item2")!.GetValue(value); - if (item1 == null || item2 == null) - { - throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,单测点模式构建失败,没有获取测点名称或者测点值,-102。"); - } - - var indexOf = metadata.ColumnNames.IndexOf(measurement); - metadata.ColumnNames[indexOf] = (string)item1!; - - rowValues.Add(item2); - } - else - { - rowValues.Add(null); + throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,单测点模式构建失败,没有获取测点名称或者测点值,-102。"); } + + var indexOf = metadata.ColumnNames.IndexOf(measurement); + metadata.ColumnNames[indexOf] = (string)item1!; + + rowValues.Add(item2); } else { - - rowValues.Add(value); - - //if (value != null) - //{ - // rowValues.Add(value); - //} - //else - //{ - // ////填充默认数据值 - // //DataTypeDefaultValueMap.TryGetValue(propertyInfo.PropertyType.Name, out object defaultValue); - - // rowValues.Add(null); - //} + rowValues.Add(null); } - - } - - values.Add(rowValues); - - if (!_runtimeContext.UseTableSessionPool)//树模型 - { - devicePaths.Add(DevicePathBuilder.GetDevicePath(entity)); } else { - devicePaths.Add(DevicePathBuilder.GetTableName()); + + rowValues.Add(value); } + } + values.Add(rowValues); + + if (!_runtimeContext.UseTableSessionPool)//树模型 + { + devicePaths.Add(DevicePathBuilder.GetDevicePath(entity)); + } + else + { + devicePaths.Add(DevicePathBuilder.GetTableName()); + } + } + if (devicePaths.Count > 1) { throw new Exception($"{nameof(BuildTablet)} 构建Tablet《{typeof(T).Name}》时,批量插入的设备路径不一致。"); @@ -434,36 +413,21 @@ namespace JiShe.CollectBus.IoTDB.Provider /// private DeviceMetadata GetMetadata() where T : IoTEntity { - - if (_runtimeContext.UseTableSessionPool)//表模型 - { - return _metadataCache.GetOrAdd(typeof(T), type => + var columns = CollectColumnMetadata(typeof(T)); + var metadata = BuildDeviceMetadata(columns); + return MetadataCache.AddOrUpdate( + typeof(T), + addValueFactory: t => metadata, // 如果键不存在,用此值添加 + updateValueFactory: (t, existingValue) => { - var columns = CollectColumnMetadata(type); + var columns = CollectColumnMetadata(t); var metadata = BuildDeviceMetadata(columns); - return metadata; - }); - } - else - { - // 树模型 - var columns = CollectColumnMetadata(typeof(T)); - var metadata = BuildDeviceMetadata(columns); - return _metadataCache.AddOrUpdate( - typeof(T), - addValueFactory: t => metadata, // 如果键不存在,用此值添加 - updateValueFactory: (t, existingValue) => - { - var columns = CollectColumnMetadata(t); - var metadata = BuildDeviceMetadata(columns); - - //对现有值 existingValue 进行修改,返回新值 - existingValue.ColumnNames = metadata.ColumnNames; - return existingValue; - } - ); - } + //对现有值 existingValue 进行修改,返回新值 + existingValue.ColumnNames = metadata.ColumnNames; + return existingValue; + } + ); } /// @@ -477,21 +441,36 @@ namespace JiShe.CollectBus.IoTDB.Provider foreach (var prop in type.GetProperties()) { + + string typeName = string.Empty; + + Type declaredType = prop.PropertyType; + // 处理可空类型 + if (declaredType.IsGenericType && declaredType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + Type underlyingType = Nullable.GetUnderlyingType(declaredType); + typeName = underlyingType.Name; + } + else + { + typeName = declaredType.Name; + } + //先获取Tag标签和属性标签 ColumnInfo? column = prop.GetCustomAttribute() is not null ? new ColumnInfo( name: prop.Name, category: ColumnCategory.TAG, - dataType: GetDataTypeFromTypeName(prop.PropertyType.Name), + dataType: GetDataTypeFromTypeName(typeName), false ) : prop.GetCustomAttribute() is not null ? new ColumnInfo( prop.Name, ColumnCategory.ATTRIBUTE, - GetDataTypeFromTypeName(prop.PropertyType.Name), + GetDataTypeFromTypeName(typeName), false ) : prop.GetCustomAttribute() is not null ? new ColumnInfo( prop.Name, ColumnCategory.FIELD, - GetDataTypeFromTypeName(prop.PropertyType.Name), + GetDataTypeFromTypeName(typeName), false) : null; @@ -544,7 +523,7 @@ namespace JiShe.CollectBus.IoTDB.Provider var groupedColumns = columns .GroupBy(c => c.Category) .ToDictionary(g => g.Key, g => g.ToList()); - + ProcessCategory(groupedColumns, ColumnCategory.TAG, metadata); ProcessCategory(groupedColumns, ColumnCategory.ATTRIBUTE, metadata); ProcessCategory(groupedColumns, ColumnCategory.FIELD, metadata); diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/SessionPoolAdapter.cs b/modules/JiShe.CollectBus.IoTDB/Provider/SessionPoolAdapter.cs index dd04f60..fcb0c02 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/SessionPoolAdapter.cs +++ b/modules/JiShe.CollectBus.IoTDB/Provider/SessionPoolAdapter.cs @@ -56,7 +56,7 @@ namespace JiShe.CollectBus.IoTDB.Provider var result = await _sessionPool.InsertAlignedTabletAsync(tablet); if (result != 0) { - throw new Exception($"{nameof(TableSessionPoolAdapter)} "); + throw new Exception($"{nameof(SessionPoolAdapter)} Tree模型数据入库没有成功,返回结果为:{result}"); } return result; diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/TableSessionPoolAdapter.cs b/modules/JiShe.CollectBus.IoTDB/Provider/TableSessionPoolAdapter.cs index be42ad7..d22f356 100644 --- a/modules/JiShe.CollectBus.IoTDB/Provider/TableSessionPoolAdapter.cs +++ b/modules/JiShe.CollectBus.IoTDB/Provider/TableSessionPoolAdapter.cs @@ -54,7 +54,7 @@ namespace JiShe.CollectBus.IoTDB.Provider var result = await _sessionPool.InsertAsync(tablet); if (result != 0) { - throw new Exception($"{nameof(TableSessionPoolAdapter)} "); + throw new Exception($"{nameof(TableSessionPoolAdapter)} table模型数据入库没有成功,返回结果为:{result}"); } return result; diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs index d729fe1..101ab0f 100644 --- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs @@ -1,33 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Apache.IoTDB.DataStructure; -using Apache.IoTDB; -using Confluent.Kafka; -using JiShe.CollectBus.Ammeters; -using JiShe.CollectBus.FreeSql; -using JiShe.CollectBus.IotSystems.PrepayModel; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Logging; -using JiShe.CollectBus.IotSystems.AFNEntity; -using JiShe.CollectBus.Protocol.Contracts.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using JiShe.CollectBus.Common.Consts; -using JiShe.CollectBus.Common.Enums; -using System.Diagnostics.Metrics; -using JiShe.CollectBus.Common.DeviceBalanceControl; -using JiShe.CollectBus.Kafka.Attributes; -using System.Text.Json; +using JiShe.CollectBus.Ammeters; using JiShe.CollectBus.Application.Contracts; -using JiShe.CollectBus.Common.Models; -using System.Diagnostics; +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.DeviceBalanceControl; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.FreeSql; using JiShe.CollectBus.IoTDB.Context; using JiShe.CollectBus.IoTDB.Interface; +using JiShe.CollectBus.IoTDB.Model; using JiShe.CollectBus.IoTDB.Options; +using JiShe.CollectBus.IotSystems.PrepayModel; +using JiShe.CollectBus.Kafka.Attributes; using JiShe.CollectBus.Kafka.Internal; -using JiShe.CollectBus.Common.Extensions; +using JiShe.CollectBus.Protocol.Contracts.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; namespace JiShe.CollectBus.Samples; @@ -52,21 +46,11 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS /// /// 测试 UseSessionPool /// - /// + /// /// [HttpGet] - public async Task UseSessionPool(long timestamps) - { - string? messageHexString = null; - if (timestamps == 0) - { - timestamps = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - _logger.LogError($"timestamps_{timestamps}"); - } - else - { - messageHexString = messageHexString + timestamps; - } + public async Task UseSessionPool(DateTime testTime) + { ElectricityMeterTreeModel meter = new ElectricityMeterTreeModel() { @@ -77,8 +61,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS MeterModel = "DDZY-1980", ProjectCode = "10059", Voltage = 10, - IssuedMessageHexString = messageHexString, - Timestamps = timestamps, + IssuedMessageHexString = "messageHexString", + Timestamps = testTime.GetDateTimeOffset().ToUnixTimeMilliseconds(), }; await _iotDBProvider.InsertAsync(meter); } @@ -88,10 +72,9 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS /// /// [HttpGet] - public async Task UseTableSessionPool() + public async Task UseTableSessionPool(DateTime time) { - var testTime = Convert.ToDateTime("2025-04-21 08:35:55"); - + var testTime = time; ElectricityMeterTreeModel meter2 = new ElectricityMeterTreeModel() { SystemName = "energy", @@ -101,7 +84,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS MeterModel = "DDZY-1980", ProjectCode = "10059", Voltage = 10, - Timestamps = new DateTimeOffset(testTime).ToUnixTimeMilliseconds(), + Timestamps = testTime.GetDateTimeOffset().ToUnixTimeMilliseconds(), }; await _iotDBProvider.InsertAsync(meter2); @@ -117,10 +100,39 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS MeterModel = "DDZY-1980", ProjectCode = "10059", Voltage = 10, - Timestamps = new DateTimeOffset(testTime).ToUnixTimeMilliseconds(), + Timestamps = testTime.GetDateTimeOffset().ToUnixTimeMilliseconds(), }; await _iotDBProvider.InsertAsync(meter); + } + + /// + /// 测试Session切换3 + /// + /// + [HttpGet] + public async Task UseTableSessionPool3(DateTime time) + { + var testTime = time; + ElectricityMeterTreeModel meter2 = new ElectricityMeterTreeModel() + { + SystemName = "energy", + DeviceId = "402440506", + DeviceType = "Ammeter", + Current = 10, + MeterModel = "DDZY-1980", + ProjectCode = "10059", + Voltage = 10, + IssuedMessageHexString = "dsdfsfd", + Timestamps = testTime.GetDateTimeOffset().ToUnixTimeMilliseconds(), + + }; + + await _iotDBProvider.InsertAsync(meter2); + + _dbContext.UseTableSessionPool = true; + + ElectricityMeter meter3 = new ElectricityMeter() { SystemName = "energy", @@ -131,7 +143,48 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS ProjectCode = "10059", Voltage = 10, Currentd = 22, - Timestamps = new DateTimeOffset(testTime).ToUnixTimeMilliseconds(), + IssuedMessageHexString = "dsdfsfd", + Timestamps = testTime.GetDateTimeOffset().ToUnixTimeMilliseconds(), + }; + await _iotDBProvider.InsertAsync(meter3); + } + + /// + /// 测试单个测点数据项 + /// + /// + /// + [HttpGet] + public async Task TestSingleMeasuringAFNData(string measuring, string value, DateTime time) + { + var meter = new SingleMeasuringEntity() + { + SystemName = "energy", + DeviceId = "402440506", + DeviceType = "Ammeter", + ProjectCode = "10059", + Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(), + SingleMeasuring = new Tuple(measuring, value) + }; + await _iotDBProvider.InsertAsync(meter); + } + + /// + /// 测试单个测点数据项2 + /// + /// + /// + [HttpGet] + public async Task TestSingleMeasuringAFNData2(string measuring, int value, DateTime time) + { + var meter = new SingleMeasuringEntity() + { + SystemName = "energy", + DeviceId = "402440506", + DeviceType = "Ammeter", + ProjectCode = "10059", + Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(), + SingleMeasuring = new Tuple(measuring, value) }; await _iotDBProvider.InsertAsync(meter); } @@ -186,27 +239,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS await Task.CompletedTask; } - - - /// - /// 测试单个测点数据项 - /// - /// - /// - [HttpGet] - public async Task TestSingleMeasuringAFNData(string measuring, string value) - { - var meter = new SingleMeasuringAFNDataEntity() - { - SystemName = "energy", - DeviceId = "402440506", - DeviceType = "Ammeter", - ProjectCode = "10059", - Timestamps = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), - SingleMeasuring = new Tuple(measuring, value) - }; - await _iotDBProvider.InsertAsync(meter); - } + /// /// 测试Redis批量读取10万条数据性能 diff --git a/services/JiShe.CollectBus.Application/Samples/TestAppService.cs b/services/JiShe.CollectBus.Application/Samples/TestAppService.cs index 68d367c..292824e 100644 --- a/services/JiShe.CollectBus.Application/Samples/TestAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/TestAppService.cs @@ -11,8 +11,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; -using JiShe.CollectBus.Common.Helpers; -using JiShe.CollectBus.IotSystems.AFNEntity; +using JiShe.CollectBus.Common.Helpers; using JiShe.CollectBus.Protocol.Contracts.Interfaces; using Microsoft.Extensions.DependencyInjection; using JiShe.CollectBus.Cassandra; diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs index cf936fe..ee132d3 100644 --- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs +++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using JiShe.CollectBus.IoTDB.Attribute; using JiShe.CollectBus.IoTDB.Enums; -using JiShe.CollectBus.IoTDB.Provider; +using JiShe.CollectBus.IoTDB.Model; namespace JiShe.CollectBus.Ammeters { diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs index ddc7daa..7fe7ebc 100644 --- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs +++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using JiShe.CollectBus.IoTDB.Attribute; +using JiShe.CollectBus.IoTDB.Attribute; using JiShe.CollectBus.IoTDB.Enums; -using JiShe.CollectBus.IoTDB.Provider; +using JiShe.CollectBus.IoTDB.Model; namespace JiShe.CollectBus.Ammeters { diff --git a/shared/JiShe.CollectBus.Common/Extensions/DateTimeExtensions.cs b/shared/JiShe.CollectBus.Common/Extensions/DateTimeExtensions.cs index e6136df..2bdcf6c 100644 --- a/shared/JiShe.CollectBus.Common/Extensions/DateTimeExtensions.cs +++ b/shared/JiShe.CollectBus.Common/Extensions/DateTimeExtensions.cs @@ -233,5 +233,22 @@ namespace JiShe.CollectBus.Common.Extensions .AddHours(hours) .AddMinutes(minutes); } + + + /// + /// 将 DateTime 时间转换为 DateTimeOffset 时间 + /// + /// + /// + public static DateTimeOffset GetDateTimeOffset(this DateTime rawDateTime) + { + //确保 Kind 为 Local(如果是 Unspecified) + DateTime localDateTime = rawDateTime.Kind == DateTimeKind.Unspecified + ? DateTime.SpecifyKind(rawDateTime, DateTimeKind.Local) + : rawDateTime; + + // 转换为 DateTimeOffset(自动应用本地时区偏移) + return new DateTimeOffset(localDateTime); + } } }