feat(mqtt): 添加设备数据上传功能及相关服务
实现设备数据通过MQTT上传功能,包括: 1. 新增DeviceUploadData实体及DTO 2. 添加MQTT服务处理设备消息 3. 实现设备数据存储逻辑 4. 创建相关控制器和服务接口
This commit is contained in:
parent
b27a3ffa8d
commit
8e459d0ccd
105
ZR.Admin.WebApi/Controllers/mes/dc/DeviceUploadDataController.cs
Normal file
105
ZR.Admin.WebApi/Controllers/mes/dc/DeviceUploadDataController.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using ZR.Model.Dto;
|
||||||
|
using ZR.Model.Business;
|
||||||
|
using ZR.Service.Business.IBusinessService;
|
||||||
|
using ZR.Admin.WebApi.Extensions;
|
||||||
|
using ZR.Admin.WebApi.Filters;
|
||||||
|
using ZR.Service.MES.dc.IService;
|
||||||
|
using ZR.Model.dc;
|
||||||
|
|
||||||
|
//创建时间:2025-09-21
|
||||||
|
namespace ZR.Admin.WebApi.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备数据上传
|
||||||
|
/// </summary>
|
||||||
|
[Route("business/DeviceUploadData")]
|
||||||
|
public class DeviceUploadDataController : BaseController
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 接口
|
||||||
|
/// </summary>
|
||||||
|
private readonly IDeviceUploadDataService _DeviceUploadDataService;
|
||||||
|
|
||||||
|
public DeviceUploadDataController(IDeviceUploadDataService DeviceUploadDataService)
|
||||||
|
{
|
||||||
|
_DeviceUploadDataService = DeviceUploadDataService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parm"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("list")]
|
||||||
|
public IActionResult QueryDeviceUploadData([FromQuery] DeviceUploadDataQueryDto parm)
|
||||||
|
{
|
||||||
|
var response = _DeviceUploadDataService.GetList(parm);
|
||||||
|
return SUCCESS(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询详情
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("{Id}")]
|
||||||
|
public IActionResult GetDeviceUploadData(long Id)
|
||||||
|
{
|
||||||
|
var response = _DeviceUploadDataService.GetInfo(Id);
|
||||||
|
|
||||||
|
var info = response.Adapt<DeviceUploadData>();
|
||||||
|
return SUCCESS(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Log(Title = "", BusinessType = BusinessType.INSERT)]
|
||||||
|
public IActionResult AddDeviceUploadData([FromBody] DeviceUploadDataDto parm)
|
||||||
|
{
|
||||||
|
var modal = parm.Adapt<DeviceUploadData>().ToCreate(HttpContext);
|
||||||
|
|
||||||
|
var response = _DeviceUploadDataService.AddDeviceUploadData(modal);
|
||||||
|
|
||||||
|
return SUCCESS(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut]
|
||||||
|
[Log(Title = "", BusinessType = BusinessType.UPDATE)]
|
||||||
|
public IActionResult UpdateDeviceUploadData([FromBody] DeviceUploadDataDto parm)
|
||||||
|
{
|
||||||
|
var modal = parm.Adapt<DeviceUploadData>().ToUpdate(HttpContext);
|
||||||
|
var response = _DeviceUploadDataService.UpdateDeviceUploadData(modal);
|
||||||
|
|
||||||
|
return ToResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("{ids}")]
|
||||||
|
[Log(Title = "", BusinessType = BusinessType.DELETE)]
|
||||||
|
public IActionResult DeleteDeviceUploadData(string ids)
|
||||||
|
{
|
||||||
|
int[] idsArr = Tools.SpitIntArrary(ids);
|
||||||
|
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||||
|
|
||||||
|
var response = _DeviceUploadDataService.Delete(idsArr);
|
||||||
|
|
||||||
|
return ToResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
using ZR.Common.MqttHelper;
|
using ZR.Common.MqttHelper;
|
||||||
|
using ZR.Service.mqtt;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers
|
namespace ZR.Admin.WebApi.Controllers
|
||||||
{
|
{
|
||||||
|
|||||||
@ -12,6 +12,7 @@ using ZR.Admin.WebApi.Hubs;
|
|||||||
using ZR.Admin.WebApi.Middleware;
|
using ZR.Admin.WebApi.Middleware;
|
||||||
using ZR.Common.Cache;
|
using ZR.Common.Cache;
|
||||||
using ZR.Common.MqttHelper;
|
using ZR.Common.MqttHelper;
|
||||||
|
using ZR.Service.mqtt;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
|
|||||||
BIN
ZR.Admin.WebApi/wwwroot/Generatecode/ZrAdmin.NET--0921123904.zip
Normal file
BIN
ZR.Admin.WebApi/wwwroot/Generatecode/ZrAdmin.NET--0921123904.zip
Normal file
Binary file not shown.
@ -18,5 +18,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
|
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
|
||||||
|
<ProjectReference Include="..\ZR.Model\ZR.Model.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
114
ZR.Model/MES/dc/DeviceUploadData.cs
Normal file
114
ZR.Model/MES/dc/DeviceUploadData.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
namespace ZR.Model.dc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
[SugarTable("device_upload_data")]
|
||||||
|
public class DeviceUploadData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 工厂
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "factory_code")]
|
||||||
|
public string FactoryCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 车间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "workshop_code")]
|
||||||
|
public string WorkshopCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 线别
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "line_code")]
|
||||||
|
public string LineCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "device_code")]
|
||||||
|
public string DeviceCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 字典编号
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "dict_code")]
|
||||||
|
public string DictCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
public string Remark { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 底漆循环温度DB1014.444
|
||||||
|
/// </summary>
|
||||||
|
public string Value01 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 底漆循环湿度DB1014.498
|
||||||
|
/// </summary>
|
||||||
|
public string Value02 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 色漆循环温度DB1014.552
|
||||||
|
/// </summary>
|
||||||
|
public string Value03 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 色漆循环湿度DB1014.610
|
||||||
|
/// </summary>
|
||||||
|
public string Value04 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清漆循环温度DB1014.664
|
||||||
|
/// </summary>
|
||||||
|
public string Value05 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清漆循环湿度DB1014.722
|
||||||
|
/// </summary>
|
||||||
|
public string Value06 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 纯水电导率DB1012.220
|
||||||
|
/// </summary>
|
||||||
|
public string Value07 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 水份烘干温度DB1014.776
|
||||||
|
/// </summary>
|
||||||
|
public string Value08 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清漆烘干温度DB1014.892
|
||||||
|
/// </summary>
|
||||||
|
public string Value09 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value10
|
||||||
|
/// </summary>
|
||||||
|
public string Value10 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "upload_time")]
|
||||||
|
public DateTime UploadTime { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 采集时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "collection_time")]
|
||||||
|
public DateTime CollectionTime { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
129
ZR.Model/MES/dc/Dto/DeviceUploadDataDto.cs
Normal file
129
ZR.Model/MES/dc/Dto/DeviceUploadDataDto.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace ZR.Model.Dto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 查询对象
|
||||||
|
/// </summary>
|
||||||
|
public class DeviceUploadDataQueryDto : PagerInfo
|
||||||
|
{
|
||||||
|
}
|
||||||
|
// 网关发来数据
|
||||||
|
public class DeviceUploadDataGatWayDto
|
||||||
|
{
|
||||||
|
[JsonPropertyName("time")]
|
||||||
|
public long Time { get; set; }
|
||||||
|
[JsonPropertyName("params")]
|
||||||
|
public DeviceUploadDataParamsDto DeviceParams { get; set; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 传来参数对象
|
||||||
|
/// </summary>
|
||||||
|
public class DeviceUploadDataParamsDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 底漆循环温度DB1014.444
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value01")]
|
||||||
|
public decimal Value01 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 底漆循环湿度DB1014.498
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value02")]
|
||||||
|
public decimal Value02 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 色漆循环温度DB1014.552
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value03")]
|
||||||
|
public decimal Value03 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 色漆循环湿度DB1014.610
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value04")]
|
||||||
|
public decimal Value04 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清漆循环温度DB1014.664
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value05")]
|
||||||
|
public decimal Value05 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清漆循环湿度DB1014.722
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value06")]
|
||||||
|
public decimal Value06 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 纯水电导率DB1012.220
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value07")]
|
||||||
|
public decimal Value07 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 水份烘干温度DB1014.776
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value08")]
|
||||||
|
public decimal Value08 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清漆烘干温度DB1014.892
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value09")]
|
||||||
|
public decimal Value09 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value10
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("Value10")]
|
||||||
|
public decimal Value10 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输入输出对象
|
||||||
|
/// </summary>
|
||||||
|
public class DeviceUploadDataDto
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "主键不能为空")]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public string FactoryCode { get; set; }
|
||||||
|
|
||||||
|
public string WorkshopCode { get; set; }
|
||||||
|
|
||||||
|
public string LineCode { get; set; }
|
||||||
|
|
||||||
|
public string DeviceCode { get; set; }
|
||||||
|
|
||||||
|
public string DictCode { get; set; }
|
||||||
|
|
||||||
|
public string Remark { get; set; }
|
||||||
|
|
||||||
|
public string Value01 { get; set; }
|
||||||
|
|
||||||
|
public string Value02 { get; set; }
|
||||||
|
|
||||||
|
public string Value03 { get; set; }
|
||||||
|
|
||||||
|
public string Value04 { get; set; }
|
||||||
|
|
||||||
|
public string Value05 { get; set; }
|
||||||
|
|
||||||
|
public string Value06 { get; set; }
|
||||||
|
|
||||||
|
public string Value07 { get; set; }
|
||||||
|
|
||||||
|
public string Value08 { get; set; }
|
||||||
|
|
||||||
|
public string Value09 { get; set; }
|
||||||
|
|
||||||
|
public string Value10 { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="mes\qc\defectReport\" />
|
<Folder Include="mes\qc\defectReport\" />
|
||||||
<Folder Include="mqtt\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
89
ZR.Service/mes/dc/DeviceUploadDataService.cs
Normal file
89
ZR.Service/mes/dc/DeviceUploadDataService.cs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
using Infrastructure.Attribute;
|
||||||
|
using SqlSugar;
|
||||||
|
using ZR.Model;
|
||||||
|
using ZR.Model.dc;
|
||||||
|
using ZR.Model.Dto;
|
||||||
|
using ZR.Repository;
|
||||||
|
using ZR.Service.MES.dc.IService;
|
||||||
|
|
||||||
|
namespace ZR.Service.Business
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Service业务层处理
|
||||||
|
/// </summary>
|
||||||
|
[AppService(ServiceType = typeof(IDeviceUploadDataService), ServiceLifetime = LifeTime.Transient)]
|
||||||
|
public class DeviceUploadDataService : BaseService<DeviceUploadData>, IDeviceUploadDataService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 查询列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parm"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public PagedInfo<DeviceUploadDataDto> GetList(DeviceUploadDataQueryDto parm)
|
||||||
|
{
|
||||||
|
var predicate = Expressionable.Create<DeviceUploadData>();
|
||||||
|
|
||||||
|
var response = Queryable()
|
||||||
|
.Where(predicate.ToExpression())
|
||||||
|
.ToPage<DeviceUploadData, DeviceUploadDataDto>(parm);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取详情
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public DeviceUploadData GetInfo(long Id)
|
||||||
|
{
|
||||||
|
var response = Queryable()
|
||||||
|
.Where(x => x.Id == Id)
|
||||||
|
.First();
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public DeviceUploadData AddDeviceUploadData(DeviceUploadData model)
|
||||||
|
{
|
||||||
|
return Context.Insertable(model).ExecuteReturnEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int UpdateDeviceUploadData(DeviceUploadData model)
|
||||||
|
{
|
||||||
|
//var response = Update(w => w.Id == model.Id, it => new DeviceUploadData()
|
||||||
|
//{
|
||||||
|
// FactoryCode = model.FactoryCode,
|
||||||
|
// WorkshopCode = model.WorkshopCode,
|
||||||
|
// LineCode = model.LineCode,
|
||||||
|
// DeviceCode = model.DeviceCode,
|
||||||
|
// DictCode = model.DictCode,
|
||||||
|
// Remark = model.Remark,
|
||||||
|
// Value01 = model.Value01,
|
||||||
|
// Value02 = model.Value02,
|
||||||
|
// Value03 = model.Value03,
|
||||||
|
// Value04 = model.Value04,
|
||||||
|
// Value05 = model.Value05,
|
||||||
|
// Value06 = model.Value06,
|
||||||
|
// Value07 = model.Value07,
|
||||||
|
// Value08 = model.Value08,
|
||||||
|
// Value09 = model.Value09,
|
||||||
|
// Value10 = model.Value10,
|
||||||
|
//});
|
||||||
|
//return response;
|
||||||
|
return Update(model, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
21
ZR.Service/mes/dc/IService/IDeviceUploadDataService.cs
Normal file
21
ZR.Service/mes/dc/IService/IDeviceUploadDataService.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using ZR.Model;
|
||||||
|
using ZR.Model.dc;
|
||||||
|
using ZR.Model.Dto;
|
||||||
|
|
||||||
|
namespace ZR.Service.MES.dc.IService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// service接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IDeviceUploadDataService : IBaseService<DeviceUploadData>
|
||||||
|
{
|
||||||
|
PagedInfo<DeviceUploadDataDto> GetList(DeviceUploadDataQueryDto parm);
|
||||||
|
|
||||||
|
DeviceUploadData GetInfo(long Id);
|
||||||
|
|
||||||
|
DeviceUploadData AddDeviceUploadData(DeviceUploadData parm);
|
||||||
|
|
||||||
|
int UpdateDeviceUploadData(DeviceUploadData parm);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ using ZR.Model.Business;
|
|||||||
using ZR.Model.Dto;
|
using ZR.Model.Dto;
|
||||||
using ZR.Model.MES.wms;
|
using ZR.Model.MES.wms;
|
||||||
using ZR.Service.Business.IBusinessService;
|
using ZR.Service.Business.IBusinessService;
|
||||||
|
using ZR.Service.mqtt;
|
||||||
|
|
||||||
namespace ZR.Service.Business
|
namespace ZR.Service.Business
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,19 +1,24 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Infrastructure.Extensions;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MQTTnet;
|
using MQTTnet;
|
||||||
using MQTTnet.Client;
|
using MQTTnet.Client;
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using ZR.Common.MqttHelper;
|
||||||
|
using ZR.Model.dc;
|
||||||
|
using ZR.Model.Dto;
|
||||||
|
using ZR.Model.mes.md;
|
||||||
|
|
||||||
namespace ZR.Common.MqttHelper
|
namespace ZR.Service.mqtt
|
||||||
{
|
{
|
||||||
public class MqttService : IHostedService, IDisposable
|
public class MqttService :BaseService<DeviceUploadData>, IHostedService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly ILogger<MqttService> _logger;
|
private readonly ILogger<MqttService> _logger;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
@ -168,15 +173,9 @@ namespace ZR.Common.MqttHelper
|
|||||||
{
|
{
|
||||||
_logger.LogInformation($"MQTT连接已建立,会话是否存在: {e.ConnectResult.IsSessionPresent}");
|
_logger.LogInformation($"MQTT连接已建立,会话是否存在: {e.ConnectResult.IsSessionPresent}");
|
||||||
|
|
||||||
// 仅在会话不存在时订阅(首次连接或会话失效)
|
// 无论会话是否存在,都检查并确保订阅配置的主题
|
||||||
if (!e.ConnectResult.IsSessionPresent)
|
// 这解决了配置文件修改后重启服务不订阅新主题的问题
|
||||||
{
|
await SubscribeToTopicsAsync();
|
||||||
await SubscribeToTopicsAsync();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogInformation("会话已存在,服务器保留订阅状态,跳过订阅");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnDisconnectedAsync(MqttClientDisconnectedEventArgs e)
|
private async Task OnDisconnectedAsync(MqttClientDisconnectedEventArgs e)
|
||||||
@ -220,7 +219,7 @@ namespace ZR.Common.MqttHelper
|
|||||||
// 这里可以根据主题路由消息到不同的处理程序
|
// 这里可以根据主题路由消息到不同的处理程序
|
||||||
switch (topic)
|
switch (topic)
|
||||||
{
|
{
|
||||||
case string t when t.StartsWith("devices/"):
|
case string t when t.StartsWith("shgx_tz/device/"):
|
||||||
await HandleDeviceMessage(topic, payload);
|
await HandleDeviceMessage(topic, payload);
|
||||||
break;
|
break;
|
||||||
case "system/alert":
|
case "system/alert":
|
||||||
@ -256,17 +255,71 @@ namespace ZR.Common.MqttHelper
|
|||||||
|
|
||||||
// 提取需要订阅的主题
|
// 提取需要订阅的主题
|
||||||
var topicsToSubscribe = subscribeOptions.TopicFilters.Select(f => f.Topic).ToList();
|
var topicsToSubscribe = subscribeOptions.TopicFilters.Select(f => f.Topic).ToList();
|
||||||
|
var topicFilters = subscribeOptions.TopicFilters.ToList();
|
||||||
|
|
||||||
// 检查是否已订阅所有主题,避免重复
|
// 获取当前已订阅的主题
|
||||||
if (_subscribedTopics.SetEquals(topicsToSubscribe))
|
HashSet<string> currentlySubscribedTopics;
|
||||||
|
lock (_subscribedTopics)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("所有主题已订阅,跳过订阅操作");
|
currentlySubscribedTopics = new HashSet<string>(_subscribedTopics);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有新的主题需要订阅
|
||||||
|
var newTopics = topicsToSubscribe.Except(currentlySubscribedTopics).ToList();
|
||||||
|
var removedTopics = currentlySubscribedTopics.Except(topicsToSubscribe).ToList();
|
||||||
|
|
||||||
|
if (!newTopics.Any() && !removedTopics.Any())
|
||||||
|
{
|
||||||
|
_logger.LogInformation("所有主题已正确订阅,无需变更");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行订阅并更新本地状态
|
// 处理新增的主题
|
||||||
_logger.LogInformation($"订阅主题: {string.Join(", ", topicsToSubscribe)}");
|
if (newTopics.Any())
|
||||||
var result = await _mqttClient.SubscribeAsync(subscribeOptions);
|
{
|
||||||
|
var newTopicFilters = topicFilters.Where(f => newTopics.Contains(f.Topic)).ToList();
|
||||||
|
if (newTopicFilters.Any())
|
||||||
|
{
|
||||||
|
var newSubscribeOptionsBuilder = new MqttClientSubscribeOptionsBuilder();
|
||||||
|
|
||||||
|
foreach (var topicFilter in newTopicFilters)
|
||||||
|
{
|
||||||
|
newSubscribeOptionsBuilder.WithTopicFilter(topicFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
var newSubscribeOptions = newSubscribeOptionsBuilder.Build();
|
||||||
|
|
||||||
|
_logger.LogInformation($"订阅新主题: {string.Join(", ", newTopics)}");
|
||||||
|
var result = await _mqttClient.SubscribeAsync(newSubscribeOptions);
|
||||||
|
|
||||||
|
foreach (var item in result.Items)
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"订阅结果:{item.TopicFilter.Topic} -> {item.ResultCode}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理移除的主题(可选,根据业务需求决定是否取消订阅)
|
||||||
|
if (removedTopics.Any())
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"配置中移除的主题: {string.Join(", ", removedTopics)}");
|
||||||
|
// 注意:这里没有执行取消订阅操作,因为有些场景下可能希望保留历史订阅
|
||||||
|
// 如果需要取消订阅,请取消注释下面的代码
|
||||||
|
|
||||||
|
// 使用构建器模式创建取消订阅选项
|
||||||
|
var unsubscribeOptionsBuilder = new MqttClientUnsubscribeOptionsBuilder();
|
||||||
|
|
||||||
|
// 为每个要取消订阅的主题调用WithTopic方法
|
||||||
|
foreach (var topic in removedTopics)
|
||||||
|
{
|
||||||
|
unsubscribeOptionsBuilder.WithTopicFilter(topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
var unsubscribeOptions = unsubscribeOptionsBuilder.Build();
|
||||||
|
await _mqttClient.UnsubscribeAsync(unsubscribeOptions);
|
||||||
|
_logger.LogInformation($"已取消订阅: {string.Join(", ", removedTopics)}");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 更新本地已订阅主题列表
|
// 更新本地已订阅主题列表
|
||||||
lock (_subscribedTopics)
|
lock (_subscribedTopics)
|
||||||
@ -274,11 +327,6 @@ namespace ZR.Common.MqttHelper
|
|||||||
_subscribedTopics.Clear();
|
_subscribedTopics.Clear();
|
||||||
_subscribedTopics.UnionWith(topicsToSubscribe);
|
_subscribedTopics.UnionWith(topicsToSubscribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var item in result.Items)
|
|
||||||
{
|
|
||||||
_logger.LogInformation($"订阅结果:{item.TopicFilter.Topic} -> {item.ResultCode}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScheduleReconnect()
|
private void ScheduleReconnect()
|
||||||
@ -320,7 +368,32 @@ namespace ZR.Common.MqttHelper
|
|||||||
private Task HandleDeviceMessage(string topic, string payload)
|
private Task HandleDeviceMessage(string topic, string payload)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"处理设备消息: {topic} - {payload}");
|
_logger.LogInformation($"处理设备消息: {topic} - {payload}");
|
||||||
|
|
||||||
|
DeviceUploadDataGatWayDto deviceUploadDataGatWayDto = JsonSerializer.Deserialize<DeviceUploadDataGatWayDto>(payload);
|
||||||
// 这里添加设备消息处理逻辑
|
// 这里添加设备消息处理逻辑
|
||||||
|
string deviceCode = topic.Split("/")[2];
|
||||||
|
DeviceUploadData deviceUploadData = new()
|
||||||
|
{
|
||||||
|
FactoryCode = "上海干巷",
|
||||||
|
WorkshopCode = "涂装车间",
|
||||||
|
LineCode = "涂装生产线",
|
||||||
|
DeviceCode = deviceCode,
|
||||||
|
DictCode = "device_dict_plc_001",
|
||||||
|
Remark = "网关采集设备数据",
|
||||||
|
UploadTime = DateTime.Now,
|
||||||
|
CollectionTime = DateTimeOffset.FromUnixTimeMilliseconds(deviceUploadDataGatWayDto.Time).LocalDateTime,
|
||||||
|
Value01 = deviceUploadDataGatWayDto.DeviceParams.Value01.ToString(),
|
||||||
|
Value02 = deviceUploadDataGatWayDto.DeviceParams.Value02.ToString(),
|
||||||
|
Value03 = deviceUploadDataGatWayDto.DeviceParams.Value03.ToString(),
|
||||||
|
Value04 = deviceUploadDataGatWayDto.DeviceParams.Value04.ToString(),
|
||||||
|
Value05 = deviceUploadDataGatWayDto.DeviceParams.Value05.ToString(),
|
||||||
|
Value06 = deviceUploadDataGatWayDto.DeviceParams.Value06.ToString(),
|
||||||
|
Value07 = deviceUploadDataGatWayDto.DeviceParams.Value07.ToString(),
|
||||||
|
Value08 = deviceUploadDataGatWayDto.DeviceParams.Value08.ToString(),
|
||||||
|
Value09 = deviceUploadDataGatWayDto.DeviceParams.Value09.ToString(),
|
||||||
|
Value10 = deviceUploadDataGatWayDto.DeviceParams.Value10.ToString()
|
||||||
|
};
|
||||||
|
Context.Insertable(deviceUploadData).ExecuteCommand();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user