Merge pull request 'dev_lx' (#8) from dev_lx into main

Reviewed-on: #8
pull/10/head^2
刘鑫 3 months ago
commit a14dcd3434
  1. 98
      WeiCloud.Fusion/AlarmService/Alarm.Application/ResponeDto/EventEnvelopeDto.cs
  2. 98
      WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs
  3. 4
      WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/IDahuaGeneralCtlService.cs
  4. 23
      WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs
  5. 2
      WeiCloud.Fusion/AlarmService/AlarmService.API/appsettings.json
  6. 15
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/DaHApiResult.cs
  7. 1
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs

@ -119,4 +119,102 @@ namespace Alarm.Application.ResponeDto
[JsonPropertyName("extend")]
public JsonElement? Extend { get; set; }
}
/// <summary>
/// 订阅映射配置
/// 用于定义不同服务节点的订阅参数配置
/// </summary>
public class SubscriptionMapDto
{
/// <summary>
/// 订阅配置字典
/// 键:服务节点标识(格式:IP地址_端口号)
/// 值:该节点的订阅参数列表
/// </summary>
public Dictionary<string, List<SubscriptionConfig>>? Items { get; set; } = new Dictionary<string, List<SubscriptionConfig>>();
}
/// <summary>
/// 订阅配置项
/// 定义单个订阅的具体参数
/// </summary>
public class SubscriptionConfig
{
/// <summary>
/// 订阅类型列表
/// 可为空,表示订阅所有类型
/// </summary>
[JsonPropertyName("types")]
public List<string>? Types { get; set; }
/// <summary>
/// 节点编码列表
/// 可为空,表示订阅所有节点
/// </summary>
[JsonPropertyName("nodeCodes")]
public List<string>? NodeCodes { get; set; }
/// <summary>
/// 组织机构列表
/// 可为空,表示订阅所有组织
/// </summary>
[JsonPropertyName("orgs")]
public List<string>? Orgs { get; set; }
/// <summary>
/// 等级列表
/// 可为空,表示订阅所有等级
/// </summary>
[JsonPropertyName("grades")]
public List<string>? Grades { get; set; }
/// <summary>
/// 域订阅级别
/// 枚举值:
/// 0 = 不订阅
/// 1 = 订阅本域
/// 2 = 订阅本域及下级域
/// </summary>
[JsonPropertyName("domainSubscribe")]
public int DomainSubscribe { get; set; }
/// <summary>
/// 传输方案
/// 枚举值:
/// 0 = HTTP
/// 1 = HTTPS
/// 2 = WebSocket
/// 3 = MQTT
/// </summary>
[JsonPropertyName("scheme")]
public int Scheme { get; set; }
/// <summary>
/// 事件类型
/// 枚举值:
/// 0 = 所有事件
/// 1 = 告警事件
/// 2 = 状态事件
/// 3 = 操作事件
/// </summary>
[JsonPropertyName("eventType")]
public int EventType { get; set; }
/// <summary>
/// 监控回调地址
/// 接收事件推送的目标URL
/// </summary>
[JsonPropertyName("monitor")]
public string Monitor { get; set; } = string.Empty;
/// <summary>
/// 监控类型
/// 枚举值:
/// "url" = HTTP/HTTPS 回调
/// "websocket" = WebSocket 连接
/// "queue" = 消息队列
/// </summary>
[JsonPropertyName("monitorType")]
public string MonitorType { get; set; } = string.Empty;
}
}

@ -4,15 +4,13 @@ using Common.Shared.Application.DaHua;
using Common.Shared.DomainService;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using NewLife.Remoting;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using Org.BouncyCastle.Ocsp;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Security.Cryptography;
using System.Text.Json;
using System.Text.Json.Serialization;
using WeiCloud.Core.BaseModels;
namespace Alarm.DomainService.DahAlarm
{
@ -59,9 +57,9 @@ namespace Alarm.DomainService.DahAlarm
/// <summary>
/// 开发测试的时候,忽略证书
/// </summary>
private static readonly HttpClient _http = new HttpClient(new HttpClientHandler
private static readonly HttpClient _http = new(new HttpClientHandler
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
});
/// <summary>
@ -206,11 +204,11 @@ namespace Alarm.DomainService.DahAlarm
if (dto.Info.AlarmType == 4321)
{
//拼接物联平台标准的mqtt消息格式
var payload = "[{\"taglabel\":\"" + dto.Info.DeviceCode + " + \".alart.\" + " + dto.Info.DeviceName + "\",\"value\":\"" + dto.Info.AlarmStat + "\",\"time\":\"" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\"}]";
var payload = "[{\"taglabel\":\"" + dto.Info.DeviceCode + ".alart." + dto.Info.DeviceName + "\",\"value\":\"" + dto.Info.AlarmStat + "\",\"time\":\"" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\"}]";
await _mqttClient.EnsureConnectedAsync(mqttHostIp, mqttHostPort, mqttUsername, mqttPassword, topicName, mqttClientId);
await _mqttClientService.PublishAsync("/zrh/sun/alarm", payload);
await _mqttClientService.PublishAsync(topicName, payload);
}
}
}
@ -229,9 +227,85 @@ namespace Alarm.DomainService.DahAlarm
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public async Task<DaHApiResult<object>> DeleteSubscribe(string name)
public async Task<bool> DeleteEvent(string name)
{
throw new NotImplementedException("该方法未实现");
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-event/1.0.0/subscribe/mqinfo?name={name}";
try
{
var request = new HttpRequestMessage(HttpMethod.Delete, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Authorization", token);
using var resp = await _http.SendAsync(request);
var body = await resp.Content.ReadAsStringAsync();
if (!resp.IsSuccessStatusCode)
{
_logger.LogWarning("实时流请求 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
return false;
}
var result = JsonSerializer.Deserialize<DaHApiResult<object>>(body);
if (result == null || !result.Success)
{
_logger.LogWarning("实时流请求业务失败: {Body}", body);
return false;
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "大华实时流请求出错");
return false;
}
}
/// <summary>
/// 获取事件列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<DaHApiResult<SubscriptionMapDto>> GetEventList(string name = "alarm")
{
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-event/1.0.0/subscribe/subscribe-list?monitorType=url&category={name}";
try
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.TryAddWithoutValidation("Authorization", token);
using var resp = await _http.SendAsync(request);
var body = await resp.Content.ReadAsStringAsync();
if (!resp.IsSuccessStatusCode)
{
_logger.LogWarning("实时流请求 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
return new DaHApiResult<SubscriptionMapDto> { Success = false, Code = "1010", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
}
var result = JsonSerializer.Deserialize<DaHApiResult<SubscriptionMapDto>>(body);
if (result == null || !result.Success)
{
_logger.LogWarning("实时流请求业务失败: {Body}", body);
return new DaHApiResult<SubscriptionMapDto> { Success = false, Code = "1010", Msg = "实时流请求失败" };
}
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "大华实时流请求出错");
return new DaHApiResult<SubscriptionMapDto> { Success = false, Code = "1010", Msg = "实时流请求失败" };
}
}
/// <summary>

@ -16,6 +16,10 @@ namespace Alarm.DomainService.DahAlarm
/// <returns></returns>
Task<DaHApiResult<object>> AddSubscribeEvent();
Task<bool> DeleteEvent(string name);
Task<DaHApiResult<SubscriptionMapDto>> GetEventList(string name = "alarm");
/// <summary>
/// AddSubscribeEvent回调函数处理
/// </summary>

@ -40,5 +40,28 @@ namespace AlarmService.API.Controllers
{
return await _generalCtlService.HandleAsync(env);
}
/// <summary>
/// 获取监听报警列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpGet]
public async Task<DaHApiResult<SubscriptionMapDto>> GetEventList(string name = "alarm")
{
return await _generalCtlService.GetEventList(name);
}
/// <summary>
/// 取消订阅某个事件
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpDelete]
public async Task<bool> DeleteEvent(string name)
{
return await _generalCtlService.DeleteEvent(name);
}
}
}

@ -6,7 +6,7 @@
}
},
"SubscribeMQTT": {
"TopicName": "datasource_points_AXYJPT_v4",
"TopicName": "/zrh/sun/alarm",
"ProjectId": 530522108656160,
"HostIP": "v4.weienergy.cn",
"HostPort": 18883,

@ -70,19 +70,4 @@ namespace Common.Shared.Application.DaHua
writer.WriteStringValue(value);
}
}
public class DaHApiDescResult<T>
{
[JsonPropertyName("code")]
public int Code { get; set; } // 修改为 int 类型
[JsonPropertyName("desc")] // 修改为 "desc" 而不是 "errMsg"
public string Desc { get; set; }
[JsonPropertyName("data")]
public T Data { get; set; }
[JsonPropertyName("success")]
public bool Success { get; set; }
}
}

@ -355,6 +355,7 @@ namespace Video.DomainService
/// <summary>
/// rtsp实时预览接口方式
/// (播放命令:ffplay -rtsp_transport tcp -i "rtsp://demo.weienergy.cn:15210/dss/monitor/param/cameraid=1000021%24104%26substream=1?token=68")强制走tcp
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>

Loading…
Cancel
Save