重构设备管理,移除所有业务系统相关,只保留物联网平台内容,完成异步指令下发

This commit is contained in:
ChenYi 2025-07-24 15:29:12 +08:00
parent 19dd451fbb
commit dd24cc89c7
17 changed files with 162 additions and 317 deletions

View File

@ -6,7 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Workshop.Dto
namespace JiShe.IoT.OneNETAggregation.Dto
{
/// <summary>
/// 生产车间获取OneNET产品列表

View File

@ -7,7 +7,7 @@ using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace JiShe.IoT.Workshop.Dto
namespace JiShe.IoT.OneNETAggregation.Dto
{
/// <summary>
/// 生产设备详情
@ -18,7 +18,7 @@ namespace JiShe.IoT.Workshop.Dto
/// 表计类型
/// 电表= 1,水表= 2,燃气表= 3,热能表= 4,水表流量计=5燃气表流量计=6,特殊电表=7
/// </summary>
public MeterTypeEnum? MeterType { get; set; }
public DeviceTypeEnum? MeterType { get; set; }
/// <summary>
/// 设备地址

View File

@ -0,0 +1,36 @@
using JiShe.IoT.OneNETAggregation.Dto;
using JiShe.ServicePro;
using JiShe.ServicePro.OneNETManagement.OneNETProducts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.OneNETAggregation
{
/// <summary>
/// OneNET聚合服务
/// </summary>
public interface IOneNETAggregationService
{
/// <summary>
/// 接收车间生产信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<HttpDataResult> ReceiveWorkshopProductionInfoAsync(OpenApiRequest input);
/// <summary>
/// 获取OneNET产品列表
/// </summary>
Task<HttpDataResult<List<OneNetWorkshopProductListOutput>>> GetProductListAsync(OpenApiRequest input);
/// <summary>
/// 接收业务系统指令信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<HttpDataResult> ReceiveBusinessSystemCommandInfoAsync(OpenApiRequest input);
}
}

View File

@ -1,16 +0,0 @@
using JiShe.ServicePro;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Workshop.Dto
{
/// <summary>
/// 生产车间获取OneNET产品列表
/// </summary>
public class OneNetWorkshopProductListInput : OpenApiRequest
{
}
}

View File

@ -1,18 +0,0 @@
using JiShe.ServicePro;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace JiShe.IoT.Workshop.Dto
{
/// <summary>
/// 生产设备
/// </summary>
public class ProductionEquipmentInput: OpenApiRequest
{
}
}

View File

@ -1,31 +0,0 @@
using JiShe.IoT.Workshop.Dto;
using JiShe.ServicePro;
using JiShe.ServicePro.OneNETManagement.OneNETProducts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Workshop
{
/// <summary>
/// 生产车间服务
/// </summary>
public interface IProductionWorkshopService
{
/// <summary>
/// 接收车间生产设备信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<HttpDataResult> ReceiveOneNetProductionEquipmentInfoAsync(ProductionEquipmentInput input);
/// <summary>
/// 生产车间获取OneNET产品列表
/// </summary>
Task<HttpDataResult<List<OneNetWorkshopProductListOutput>>> GetOneNetProductListAsync(OneNetWorkshopProductListInput input);
}
}

View File

@ -1,7 +1,6 @@
using JiShe.IoT.CommonServices.Dto;
using JiShe.ServicePro.Commons;
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Focuses;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;

View File

@ -1,5 +1,4 @@
using JiShe.IoT.CommonServices;
using JiShe.IoT.Jobs.ToMysql;
using JiShe.IoT.Jobs.ToRedis;
using JiShe.ServicePro.CTWingManagement;
using JiShe.ServicePro.DeviceManagement;
@ -52,11 +51,7 @@ namespace JiShe.IoT
private static void ConfigureBackgroundJob(ServiceConfigurationContext context)
{
context.Services.AddHostedService<BathSyncFocusDataToMysqlJob>();
context.Services.AddHostedService<BathSyncAmmeterDataToMysqlJob>();
context.Services.AddHostedService<BathSyncWatermeterDataToMysqlJob>();
context.Services.AddHostedService<CacheDeviceDataToRedisJob>();
context.Services.AddHostedService<CacheFocusDataToRedisJob>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)

View File

@ -1,41 +0,0 @@
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Meters;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Jobs.ToMysql
{
/// <summary>
/// 批量同步电表 ammeter 数据到mysql
/// </summary>
public class BathSyncAmmeterDataToMysqlJob : SystemBackGroundWorkService
{
private readonly ILogger<BathSyncAmmeterDataToMysqlJob> _logger;
public readonly MeterAppService _meterAppService;
public BathSyncAmmeterDataToMysqlJob(ILogger<BathSyncAmmeterDataToMysqlJob> logger, MeterAppService meterAppService) : base(logger)
{
_logger = logger;
_meterAppService = meterAppService;
}
/// <summary>
/// 定时执行
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected override Task DoWorkAsync(CancellationToken cancellationToken)
{
return _meterAppService.BathSyncAmmeterDataAsync();
}
protected override TimeSpan GetInterval()
{
// 每隔3小时执行一次
return TimeSpan.FromHours(3);
}
}
}

View File

@ -1,37 +0,0 @@
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Focuses;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Jobs.ToMysql
{
/// <summary>
/// 批量同步集中器 Focus数据到Mysql
/// </summary>
public class BathSyncFocusDataToMysqlJob : SystemBackGroundWorkService
{
private readonly ILogger<BathSyncFocusDataToMysqlJob> _logger;
public readonly FocusAppService _focusAppService;
public BathSyncFocusDataToMysqlJob(ILogger<BathSyncFocusDataToMysqlJob> logger, FocusAppService focusAppService) : base(logger)
{
_logger = logger;
_focusAppService = focusAppService;
}
protected override Task DoWorkAsync(CancellationToken cancellationToken)
{
return _focusAppService.BathSyncFocusDataAsync();
}
protected override TimeSpan GetInterval()
{
// 每隔3小时执行一次
return TimeSpan.FromHours(3);
}
}
}

View File

@ -1,41 +0,0 @@
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Meters;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Jobs.ToMysql
{
/// <summary>
/// 批量同步 水表 watermeter 数据到mysql
/// </summary>
public class BathSyncWatermeterDataToMysqlJob : SystemBackGroundWorkService
{
private readonly ILogger<BathSyncWatermeterDataToMysqlJob> _logger;
public readonly MeterAppService _meterAppService;
public BathSyncWatermeterDataToMysqlJob(ILogger<BathSyncWatermeterDataToMysqlJob> logger, MeterAppService meterAppService) : base(logger)
{
_logger = logger;
_meterAppService = meterAppService;
}
/// <summary>
/// 定时执行
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected override Task DoWorkAsync(CancellationToken cancellationToken)
{
return _meterAppService.BathSyncWatermeterDataAsync();
}
protected override TimeSpan GetInterval()
{
// 每隔3小时执行一次
return TimeSpan.FromHours(3);
}
}
}

View File

@ -1,5 +1,5 @@
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Meters;
using JiShe.ServicePro.DeviceManagement.DeviceInfos;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@ -15,8 +15,8 @@ namespace JiShe.IoT.Jobs.ToRedis
public class CacheDeviceDataToRedisJob : SystemBackGroundWorkService
{
private readonly ILogger<CacheDeviceDataToRedisJob> _logger;
public readonly MeterAppService _meterAppService;
public CacheDeviceDataToRedisJob(ILogger<CacheDeviceDataToRedisJob> logger, MeterAppService meterAppService) : base(logger)
public readonly DeviceAppService _meterAppService;
public CacheDeviceDataToRedisJob(ILogger<CacheDeviceDataToRedisJob> logger, DeviceAppService meterAppService) : base(logger)
{
_logger = logger;
_meterAppService = meterAppService;

View File

@ -1,37 +0,0 @@
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Focuses;
using JiShe.ServicePro.DeviceManagement.Meters;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Jobs.ToRedis
{
/// <summary>
/// 缓存集中器数据到Redis
/// </summary>
public class CacheFocusDataToRedisJob : SystemBackGroundWorkService
{
private readonly ILogger<CacheFocusDataToRedisJob> _logger;
public readonly FocusAppService _focusAppService;
public CacheFocusDataToRedisJob(ILogger<CacheFocusDataToRedisJob> logger, FocusAppService focusAppService) : base(logger)
{
_logger = logger;
_focusAppService= focusAppService;
}
protected override Task DoWorkAsync(CancellationToken cancellationToken)
{
return _focusAppService.CacheFocusDataToRedisAsync();
}
protected override TimeSpan GetInterval()
{
return TimeSpan.FromHours(1);
}
}
}

View File

@ -1,34 +1,39 @@
using JiShe.IoT.Workshop.Dto;
using JiShe.IoT.OneNETAggregation.Dto;
using JiShe.ServicePro;
using JiShe.ServicePro.Core;
using JiShe.ServicePro.DeviceManagement.Focuses;
using JiShe.ServicePro.DeviceManagement.Focuses.Dto;
using JiShe.ServicePro.DeviceManagement.Meters;
using JiShe.ServicePro.DeviceManagement.Meters.Dto;
using JiShe.ServicePro.DeviceManagement.DeivceInfos;
using JiShe.ServicePro.DeviceManagement.DeivceInfos.Dto;
using JiShe.ServicePro.Encrypt;
using JiShe.ServicePro.Enums;
using JiShe.ServicePro.Kafka.Consts;
using JiShe.ServicePro.Kafka.Producer;
using JiShe.ServicePro.OneNETManagement.OneNETDevices;
using JiShe.ServicePro.OneNETManagement.OneNETProducts;
using JiShe.ServicePro.ServerOptions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace JiShe.IoT.Workshop
namespace JiShe.IoT.OneNETAggregation
{
/// <summary>
/// 生产车间服务
/// 生产车间聚合服务
/// </summary>
public class ProductionWorkshopService(IFocusAppService focusAppService, IMeterAppService meterAppService, IOneNETDeviceService oneNETDeviceService, IOptions<ServerApplicationOptions> options, ILogger<ProductionWorkshopService> logger) : IoTAppService, IProductionWorkshopService
/// <param name="deviceAppService">设备管理信息服务</param>
/// <param name="oneNETDeviceService">OneNET设备操作服务</param>
/// <param name="_producerService">Kafka数据生产服务</param>
/// <param name="options">服务配置</param>
/// <param name="logger"></param>
public class OneNETAggregationService(IDeviceAppService deviceAppService, IOneNETDeviceService oneNETDeviceService, IKafkaProducerService _producerService, IOptions<ServerApplicationOptions> options, ILogger<OneNETAggregationService> logger) : IoTAppService, IOneNETAggregationService
{
ServerApplicationOptions srverOptions = options.Value;
/// <summary>
/// 接收车间生产设备信息
/// 接收车间生产信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[AllowAnonymous]
public async Task<HttpDataResult> ReceiveOneNetProductionEquipmentInfoAsync(ProductionEquipmentInput input)
public async Task<HttpDataResult> ReceiveWorkshopProductionInfoAsync(OpenApiRequest input)
{
try
@ -75,31 +80,22 @@ namespace JiShe.IoT.Workshop
{
return HttpDataResultExtensions.Failed("没有找到对应的产品信息", -108, ResponeResultEnum.Fail);
}
CreateFocusInput focusInfoEntity = new CreateFocusInput()
CreateDeviceInput meterInfoEntity = new CreateDeviceInput()
{
FocusAddress = productionEquipmentMessageBody.DeviceAddress,
IoTPlatformProductId = productionEquipmentMessageBody.IoTPlatformProductId,
IoTPlatform = IoTPlatformTypeEnum.OneNET,
IoTPlatformDeviceOpenInfo = productionEquipmentMessageBody.DeviceOpenInfo,
PlatformPassword = productInfo.ProductAccesskey,
};
CreateMeterInput meterInfoEntity = new CreateMeterInput()
{
MeterAddress = productionEquipmentMessageBody.DeviceAddress,
DeviceAddress = productionEquipmentMessageBody.DeviceAddress,
Password = productInfo.ProductAccesskey,
IoTPlatformProductId = productionEquipmentMessageBody.IoTPlatformProductId,
IoTPlatformDeviceOpenInfo = productionEquipmentMessageBody.DeviceOpenInfo,
FocusAddress = productionEquipmentMessageBody.DeviceAddress,//todo: 集中器地址
DeviceName = productionEquipmentMessageBody.DeviceOpenInfo
};
//创建本地设备信息
await focusAppService.CreateAsync(focusInfoEntity);
await meterAppService.CreateAsync(meterInfoEntity);
await deviceAppService.CreateAsync(meterInfoEntity);
//推送至OneNET平台
await oneNETDeviceService.CreateDeviceInfoAsync(new CreateDeviceInfoInput() {
await oneNETDeviceService.CreateDeviceInfoAsync(new CreateDeviceInfoInput()
{
DeviceName = productionEquipmentMessageBody.DeviceOpenInfo,
ProductId = productionEquipmentMessageBody.IoTPlatformProductId,
OneNETAccountId = productInfo.OneNETAccountId,
@ -110,16 +106,16 @@ namespace JiShe.IoT.Workshop
}
catch (Exception ex)
{
logger.LogError($"{nameof(ReceiveOneNetProductionEquipmentInfoAsync)} 生产车间数据推送发生异常:{ex.Serialize()}");
logger.LogError($"{nameof(ReceiveWorkshopProductionInfoAsync)} 生产车间数据推送发生异常:{ex.Serialize()}");
return HttpDataResultExtensions.Failed("生产车间数据推送发生异常", -101, ResponeResultEnum.Exception);
}
}
/// <summary>
/// 生产车间获取OneNET产品列表
/// 获取OneNET产品列表
/// </summary>
[AllowAnonymous]
public async Task<HttpDataResult<List<OneNetWorkshopProductListOutput>>> GetOneNetProductListAsync(OneNetWorkshopProductListInput input)
public async Task<HttpDataResult<List<OneNetWorkshopProductListOutput>>> GetProductListAsync(OpenApiRequest input)
{
try
@ -138,7 +134,39 @@ namespace JiShe.IoT.Workshop
var pageList = await pageListQuery.ToListAsync<OneNetWorkshopProductListOutput>();
return HttpDataResultExtensions.Success<List<OneNetWorkshopProductListOutput>>(pageList);
return HttpDataResultExtensions.Success(pageList);
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 接收业务系统指令信息缓存进Kafka
/// </summary>
[AllowAnonymous]
public async Task<HttpDataResult> ReceiveBusinessSystemCommandInfoAsync(OpenApiRequest input)
{
try
{
bool verifySignatureReult = EncryptUtil.OpenApiVerifySignature(input.Message, input.Nonce, input.Timestamp, input.Signature, srverOptions.VerifySignatureToken);
if (verifySignatureReult == false)//签名校验失败
{
return HttpDataResultExtensions.Failed<List<OneNetWorkshopProductListOutput>>("签名校验失败", -101, ResponeResultEnum.NotAllowed);
}
if (string.IsNullOrWhiteSpace(input.Message))
{
return HttpDataResultExtensions.Failed<List<OneNetWorkshopProductListOutput>>("指令下发内容不能为空", -102, ResponeResultEnum.Fail);
}
//将指令存储Kafka中
await _producerService.ProduceAsync(KafkaTopicConsts.OneNETCommandIssuedEventName, $"{GuidGenerator.Create()}", input);
return HttpDataResultExtensions.Success("指令下发Kafka成功");
}
catch (Exception)
{

View File

@ -2,9 +2,8 @@ using JiShe.ServicePro.BasicManagement.UserRefreshTokens;
using JiShe.ServicePro.CTWingManagement.CTWingAccount;
using JiShe.ServicePro.CTWingManagement.CTWingProduct;
using JiShe.ServicePro.CTWingManagement.EntityFrameworkCore;
using JiShe.ServicePro.DeviceManagement.DeivceInfos;
using JiShe.ServicePro.DeviceManagement.EntityFrameworkCore;
using JiShe.ServicePro.DeviceManagement.Focuses;
using JiShe.ServicePro.DeviceManagement.Meters;
using JiShe.ServicePro.DynamicMenuManagement.EntityFrameworkCore;
using JiShe.ServicePro.DynamicMenuManagement.Menus;
using JiShe.ServicePro.FileManagement.EntityFrameworkCore;
@ -66,8 +65,7 @@ namespace JiShe.IoT.EntityFrameworkCore
public DbSet<FileObject> FileObjects { get; set; }
// 设备管理
public DbSet<FocusInfo> FocusInfo { get; set; }
public DbSet<MeterInfo> MeterInfo { get; set; }
public DbSet<DeviceManagementInfo> DeviceManagementInfo { get; set; }
// CTWing管理
public DbSet<CTWingAccountInfo> CTWingAccountInfo { get; set; }

View File

@ -0,0 +1,60 @@
using JiShe.IoT.CommonServices;
using JiShe.IoT.CommonServices.Dto;
using JiShe.IoT.OneNETAggregation;
using JiShe.IoT.OneNETAggregation.Dto;
using JiShe.ServicePro;
using JiShe.ServicePro.Commons;
using JiShe.ServicePro.OneNETManagement.OneNETProducts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Controllers
{
/// <summary>
/// OneNET聚合服务
/// </summary>
[Route("/Aggregation/OneNET")]
public class OneNETAggregationController : IoTController
{
private readonly IOneNETAggregationService _oneNETAggregationServiceService;
public OneNETAggregationController(IOneNETAggregationService oneNETAggregationServiceService)
{
_oneNETAggregationServiceService = oneNETAggregationServiceService;
}
/// <summary>
/// 接收车间生产信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost(nameof(ReceiveWorkshopProductionInfoAsync))]
[SwaggerOperation(summary: "接收车间生产信息", Tags = new[] { "AggregationOneNET" })]
public async Task ReceiveWorkshopProductionInfoAsync(OpenApiRequest input)
{
await _oneNETAggregationServiceService.ReceiveWorkshopProductionInfoAsync(input);
}
/// <summary>
/// 获取OneNET产品列表
/// </summary>
[HttpPost(nameof(GetProductListAsync))]
[SwaggerOperation(summary: "获取OneNET产品列表", Tags = new[] { "AggregationOneNET" })]
public async Task<HttpDataResult<List<OneNetWorkshopProductListOutput>>> GetProductListAsync(OpenApiRequest input)
{
return await _oneNETAggregationServiceService.GetProductListAsync(input);
}
/// <summary>
/// 接收业务系统指令信息
/// </summary>
[HttpPost(nameof(ReceiveBusinessSystemCommandInfoAsync))]
[SwaggerOperation(summary: "接收业务系统指令信息", Tags = new[] { "AggregationOneNET" })]
public async Task<HttpDataResult> ReceiveBusinessSystemCommandInfoAsync(OpenApiRequest input)
{
return await _oneNETAggregationServiceService.ReceiveBusinessSystemCommandInfoAsync(input);
}
}
}

View File

@ -1,50 +0,0 @@
using JiShe.IoT.CommonServices;
using JiShe.IoT.CommonServices.Dto;
using JiShe.IoT.Workshop;
using JiShe.IoT.Workshop.Dto;
using JiShe.ServicePro;
using JiShe.ServicePro.Commons;
using JiShe.ServicePro.OneNETManagement.OneNETProducts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.IoT.Controllers
{
/// <summary>
/// 车间管理服务
/// </summary>
[Route("Workshop")]
public class ProductionWorkshopController : IoTController
{
private readonly IProductionWorkshopService _productionWorkshopService;
public ProductionWorkshopController(IProductionWorkshopService productionWorkshopService)
{
_productionWorkshopService = productionWorkshopService;
}
/// <summary>
/// 接收车间生产OneNET设备信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost(nameof(ReceiveOneNetProductionEquipmentInfoAsync))]
[SwaggerOperation(summary: "接收车间生产OneNET设备信息", Tags = new[] { "Workshop" })]
public async Task ReceiveOneNetProductionEquipmentInfoAsync(ProductionEquipmentInput input)
{
await _productionWorkshopService.ReceiveOneNetProductionEquipmentInfoAsync(input);
}
/// <summary>
/// 生产车间获取OneNET产品列表
/// </summary>
[HttpPost(nameof(GetOneNetProductListAsync))]
[SwaggerOperation(summary: "生产车间获取OneNET产品列表", Tags = new[] { "Workshop" })]
public async Task<HttpDataResult<List<OneNetWorkshopProductListOutput>>> GetOneNetProductListAsync(OneNetWorkshopProductListInput input)
{
return await _productionWorkshopService.GetOneNetProductListAsync(input);
}
}
}