From 180b654f2621f2e383c4e3be6728bbfe207c3a65 Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Tue, 9 Dec 2025 17:19:34 +0800
Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=AB=AF=E7=89=A9=E6=A8=A1?=
=?UTF-8?q?=E5=9E=8B=E7=BB=93=E6=9E=84=E4=BD=93=E5=B1=9E=E6=80=A7=E8=AE=BE?=
=?UTF-8?q?=E7=BD=AE=E8=AF=B7=E6=B1=82=E4=BD=93=E5=B0=81=E8=A3=85=E3=80=81?=
=?UTF-8?q?=E5=B9=B3=E5=8F=B0=E4=BA=A7=E5=93=81=E7=89=A9=E6=A8=A1=E5=9E=8B?=
=?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=BB=93=E6=9E=84=E4=BD=93=E6=8B=86=E8=A7=A3?=
=?UTF-8?q?=E5=87=BD=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Dto/DeviceCommandForApiInput.cs | 14 +-
.../DeviceAggregationService.cs | 132 ++++++++++--------
src/JiShe.IoT.Application/IoTAppService.cs | 1 -
3 files changed, 73 insertions(+), 74 deletions(-)
diff --git a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs
index a7f6e22..2a6bd8b 100644
--- a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs
+++ b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs
@@ -11,19 +11,9 @@ namespace JiShe.IoT.DeviceAggregation
public class DeviceCommandForApiInput:IdInput
{
///
- /// 设备在物联网平台中发送的命令内容,JSON格式
+ /// 设备在物联网平台中属性设置的参数键值对
///
[Required(ErrorMessage = "命令内容不能为空")]
- public string CommandContent { get; set; }
-
- ///
- /// 设备类型
- ///
- public DeviceTypeEnum? DeviceType { get; set; }
-
- ///
- /// 设备指令类型
- ///
- public DeviceTelemetryCommandTypeEnum? TelemetryType { get; set; }
+ public Dictionary CommandContent { get; set; }
}
}
\ No newline at end of file
diff --git a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs
index 83a814b..a2ffda4 100644
--- a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs
+++ b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs
@@ -6,6 +6,7 @@ using JiShe.ServicePro.DataChannelManages;
using JiShe.ServicePro.DeviceManagement.DeviceInfos;
using JiShe.ServicePro.DeviceManagement.DeviceInfos.Dto;
using JiShe.ServicePro.DeviceManagement.Permissions;
+using JiShe.ServicePro.DeviceManagement.ThingModels;
using JiShe.ServicePro.Dto;
using JiShe.ServicePro.Enums;
using JiShe.ServicePro.FreeRedisProvider;
@@ -29,7 +30,9 @@ namespace JiShe.IoT.DeviceAggregation
/// Redis发布订阅服务
/// 数据通道
/// IoTDBOptions
- public class DeviceAggregationService(ILogger logger, IDeviceAppService deviceAppService, IOneNETDeviceService oneNETDeviceService, IReliableRedisPubSubService redisPubSubService, IIoTDBDataChannelManageService ioTDBDataChannelManageService,IOptions _ioTDBOptions) : IoTAppService, IDeviceAggregationService
+ /// OneNET产品服务
+ /// 设备端物模型服务
+ public class DeviceAggregationService(ILogger logger, IDeviceAppService deviceAppService, IOneNETDeviceService oneNETDeviceService, IReliableRedisPubSubService redisPubSubService, IIoTDBDataChannelManageService ioTDBDataChannelManageService,IOptions _ioTDBOptions, IOneNETProductService oneNETProductService, IDeviceThingModelManagementAppService deviceThingModelService) : IoTAppService, IDeviceAggregationService
{
IoTDBOptions ioTDBOptions = _ioTDBOptions.Value;
@@ -288,47 +291,35 @@ namespace JiShe.IoT.DeviceAggregation
{
try
{
+ if (input.CommandContent == null || input.CommandContent.Keys.Count <=0)
+ {
+ throw new UserFriendlyException($"指令参数异常");
+ }
+
var deviceInfo = await deviceAppService.FindByIdAsync(input);
if (deviceInfo == null)
{
throw new UserFriendlyException($"设备不存在");
}
- //将指令存储
- var commandRequest = new OpenApiRequest()
- {
- Message = new ReceiveCommandInfoDto()
- {
- DeviceAddress = deviceInfo.DeviceAddress,
- Commands = input.CommandContent.Deserialize>(),
- DeviceType = input.DeviceType ?? DeviceTypeEnum.GATEWAY,//todo 设备类型 需要跟设备统一什么情况下知道具体设备类型
- SourceType = DeviceTelemetrySourceTypeEnum.AdminSystem,
- TelemetryType = input.TelemetryType ?? DeviceTelemetryCommandTypeEnum.抄读,
- IoTPlatform = deviceInfo.IoTPlatform,
- }.Serialize(),
- };
-
- var packetTaskInfo = GetDeviceTelemetryPacketTaskInfo(ioTDBOptions, commandRequest, deviceInfo.Adapt(), commandRequest.Message);
-
+
//数据写入遥测任务数据存储通道
if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET)
- {
- await ioTDBDataChannelManageService.DeviceTelemetryTaskWriterAsync(DataChannelManage.DeviceTelemetryTaskDataChannel.Writer, (DistributedMessageCenterConst.OneNETCommandIssuedEventName, packetTaskInfo));
-
- return await DeviceCommandInfoToOneNET(deviceInfo, packetTaskInfo);
+ {
+ return await DeviceCommandInfoToOneNET(deviceInfo, input);
}
else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing)
{
- await redisPubSubService.PublishReliableAsync(DistributedMessageCenterConst.CTWingAepCommandIssuedEventName,commandRequest);
- return true;
+ //await redisPubSubService.PublishReliableAsync(DistributedMessageCenterConst.CTWingAepCommandIssuedEventName,commandRequest);
+ //return true;
+ throw new UserFriendlyException($"发送设备指令信息失败,CTWing暂未实现。");
}
else
{
- throw new UserFriendlyException($"创建设备失败,未找到对应的产品配置信息。");
+ throw new UserFriendlyException($"发送设备指令信息失败,未找到对应的产品配置信息。");
}
}
catch (Exception)
{
-
throw;
}
}
@@ -387,15 +378,17 @@ namespace JiShe.IoT.DeviceAggregation
try
{
CreateDeviceInput createDeviceInput = input.Adapt();
-
- var productInfo = await FreeSqlDbContext.Instance.Select()
- .Where(e => e.IoTPlatformProductId == input.IoTPlatformProductId)//此处不需要过滤产品状态,方便测试产品配置信息是否准确,避免跟车间生产搞混
- .WhereIf(input.DeviceSourceTypeEnum == DeviceSourceTypeEnum.Workshop, e => e.IsEnabled == true)
- .FirstAsync();
+
+ var productInfo = await oneNETProductService.GetProductInfoAsync(new IdInput() { Id = input.IoTPlatformProductId });
if (productInfo == null)
{
- throw new UserFriendlyException($"创建设备失败,未找到对应的产品配置信息。");
+ throw new UserFriendlyException($"OneNET创建设备失败,未找到对应的产品配置信息。");
+ }
+
+ if (input.DeviceSourceTypeEnum == DeviceSourceTypeEnum.Workshop && !productInfo.IsEnabled) //车间生产推送,必须是已经启用的产品才可以
+ {
+ throw new UserFriendlyException($"车间生产推送OneNET创建设备失败,产品未启用。");
}
createDeviceInput.DeviceName = input.DeviceAddress;
@@ -532,35 +525,26 @@ namespace JiShe.IoT.DeviceAggregation
public async Task RepushDeviceInfoToOneNET(DeviceManagementInfoDto input)
{
try
- {
- var productInfo = await FreeSqlDbContext.Instance.Select()
- .Where(e => e.IoTPlatformProductId == input.IoTPlatformProductId)
- .FirstAsync();
-
- if (productInfo == null)
- {
- throw new UserFriendlyException($"推送失败,未找到对应的产品配置信息。");
- }
-
+ {
//检查OneNET平台设备是否已经存在
var oneNETDeviceInfoResult = await oneNETDeviceService.DeviceInfoDetailAsync(new DeviceInfoDetailInput()
{
DeviceName = input.IoTPlatformDeviceOpenInfo,
- ProductId = productInfo.IoTPlatformProductId,
- OneNETAccountId = productInfo.OneNETAccountId,
+ ProductId = input.IoTPlatformProductId,
+ OneNETAccountId = input.IoTPlatformAccountId,
});
if (oneNETDeviceInfoResult != null && oneNETDeviceInfoResult.Code == ServicePro.Enums.ResponeResultEnum.Success)
{
- throw new UserFriendlyException($"推送失败,OneNET账号{productInfo.AccountPhoneNumber}的产品下{productInfo.ProductName}已经存在该设备{input.DeviceAddress}。");
+ throw new UserFriendlyException($"OneNET推送失败,账号产品下{input.IoTPlatformProductId}已经存在该设备{input.DeviceAddress}。");
}
//推送至OneNET平台
var pushResult = await oneNETDeviceService.CreateDeviceInfoAsync(new CreateDeviceInfoInput()
{
DeviceName = input.IoTPlatformDeviceOpenInfo,
- ProductId = productInfo.IoTPlatformProductId,
- OneNETAccountId = productInfo.OneNETAccountId,
+ ProductId = input.IoTPlatformProductId,
+ OneNETAccountId = input.IoTPlatformAccountId,
Description = input.DeviceAddress,
});
@@ -589,23 +573,13 @@ namespace JiShe.IoT.DeviceAggregation
public async Task DeleteDeviceInfoToOneNET(DeviceManagementInfoDto input)
{
try
- {
- var productInfo = await FreeSqlDbContext.Instance.Select()
- .Where(e => e.IoTPlatformProductId == input.IoTPlatformProductId)
- .FirstAsync();
-
- if (productInfo == null)
- {
- throw new UserFriendlyException($"删除失败,未找到对应的产品配置信息。");
- }
-
-
+ {
//删除OneNET平台设备信息
var deleteResult = await oneNETDeviceService.DeleteDeviceInfoAsync(new DeleteDeviceInfoInput()
{
DeviceName = input.IoTPlatformDeviceOpenInfo,
- ProductId = productInfo.IoTPlatformProductId,
- OneNETAccountId = productInfo.OneNETAccountId,
+ ProductId = input.IoTPlatformProductId,
+ OneNETAccountId = input.IoTPlatformAccountId,
});
if (deleteResult == null || deleteResult.Code != ServicePro.Enums.ResponeResultEnum.Success)
@@ -634,13 +608,49 @@ namespace JiShe.IoT.DeviceAggregation
/// 发送OneNET平台设备指令
///
///
- ///
+ ///
///
///
- public async Task DeviceCommandInfoToOneNET(DeviceManagementInfoDto deviceInfo, DeviceTelemetryPacketTaskInfo packetTaskInfo)
+ public async Task DeviceCommandInfoToOneNET(DeviceManagementInfoDto deviceInfo, DeviceCommandForApiInput input)
{
try
{
+ //将指令存储
+ var receiveCommandInfoDto = new ReceiveCommandInfoDto()
+ {
+ DeviceAddress = deviceInfo.DeviceAddress,
+ Commands = input.CommandContent,
+ DeviceType = deviceInfo.DeviceType,
+ SourceType = DeviceTelemetrySourceTypeEnum.AdminSystem,
+ IoTPlatform = deviceInfo.IoTPlatform,
+ };
+
+ //检查设备是否有配置设备端物模型信息
+ //如果有配置,就检查指令字典中是否有SpecialCommand标识符
+ //如果有就需要构建 SpecialCommand 的特别指令
+
+ if (deviceInfo.IsNeedConfigDevicMdoel && deviceInfo.DeviceThingModelDataId.HasValue && receiveCommandInfoDto.Commands.ContainsKey(ThingModelFixedTypeConst.SpecialCommand))
+ {
+ var propertyInfo = await oneNETProductService.GetProductThingModelSpecialCommandDataTypeListAsync(new IdInput() { Id = deviceInfo.IoTPlatformProductId });
+
+ if (propertyInfo == null)
+ {
+ throw new UserFriendlyException($"{nameof(DeviceCommandInfoToOneNET)} OneNET设备属性设置失败,产品Id{deviceInfo.IoTPlatformProductId}未找到对应的属性信息。");
+ }
+
+ Dictionary tempSpecialCommand = await deviceThingModelService.BuildThingModelSpecialCommandAsync(propertyInfo, deviceInfo.DeviceThingModelDataId.Value);
+
+ receiveCommandInfoDto.Commands[ThingModelFixedTypeConst.SpecialCommand] = tempSpecialCommand;
+ }
+
+ var commandRequest = new OpenApiRequest()
+ {
+ Message = receiveCommandInfoDto.Serialize(),
+ };
+ var packetTaskInfo = GetDeviceTelemetryPacketTaskInfo(ioTDBOptions, commandRequest, deviceInfo.Adapt(), commandRequest.Message);
+
+ await ioTDBDataChannelManageService.DeviceTelemetryTaskWriterAsync(DataChannelManage.DeviceTelemetryTaskDataChannel.Writer, (DistributedMessageCenterConst.OneNETCommandIssuedEventName, packetTaskInfo));
+
//检查下设备是否在线
var deviceOnlineStatus = await oneNETDeviceService.DeviceInfoDetailAsync(new DeviceInfoDetailInput()
{
diff --git a/src/JiShe.IoT.Application/IoTAppService.cs b/src/JiShe.IoT.Application/IoTAppService.cs
index 8c73968..ab444a7 100644
--- a/src/JiShe.IoT.Application/IoTAppService.cs
+++ b/src/JiShe.IoT.Application/IoTAppService.cs
@@ -53,7 +53,6 @@ namespace JiShe.IoT
DeviceAddress = commandIssueInfo.DeviceAddress,
IssueRawMessage = input.Serialize(),
IoTDataType = IoTDBDataTypeConst.Command,
- TelemetryType = (int)commandIssueInfo.TelemetryType,
TelemetrySource = (int)commandIssueInfo.SourceType,
IoTPlatform = (int)commandIssueInfo.IoTPlatform,
IoTPlatformProductId = deviceInfo.IoTPlatformProductId,