main
洁 任 7 days ago
commit aba79a3ea9

@ -9,7 +9,7 @@ namespace Infrastructure.Helpers
public static IConfigurationRoot GetConfigRoot()
{
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.SetBasePath(System.IO.Directory.GetCurrentDirectory())
configurationBuilder.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"}.json",

@ -14,6 +14,9 @@
public int limit { get; set; }
public string key { get; set; }
public DateTime? startTime { get; set; }
public DateTime? endTime { get; set; }
public PageReq()
{

@ -1,8 +1,9 @@
using Infrastructure;
using Newtonsoft.Json;
using OpenAuth.App.ServiceApp;
using Quartz;
namespace OpenAuth.App.ServiceApp;
namespace OpenAuth.App.OpenJob;
public class FlyTaskJob : IJob
{

@ -20,6 +20,8 @@ public class AiAchievementServiceApp : SqlSugarBaseApp<LasaAiAchievement, SugarD
RefAsync<int> total = 0;
var page = await Repository.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(req.key), x => x.Title.Contains(req.key))
.WhereIF(req.startTime != null, x => x.CreateTime >= req.startTime && x.CreateTime <= req.endTime)
.OrderByDescending(x => x.CreateTime)
.ToPageListAsync(req.page, req.limit, total);
return new Response<PageInfo<List<LasaAiAchievement>>>()
{

@ -77,8 +77,11 @@ public class AlgoInstanceServiceApp : SqlSugarBaseApp<LasaAlgoInstance, SugarDbC
var page = await Repository.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(req.key), x => x.Name.Contains(req.key))
.ToPageListAsync(req.page, req.limit, totalCount);
var ids = page.Select(x => x.Id).ToList();
var sql = @$"SELECT
if (page != null && page.Count > 0)
{
var ids = page.Select(x => x.Id).ToList();
var sql = @$"SELECT
a.""Id"" as ""algoInstanceId"",
l.""Name"" as ""TagName"",
r.""Name"" as ""AlgoName""
@ -90,39 +93,54 @@ public class AlgoInstanceServiceApp : SqlSugarBaseApp<LasaAlgoInstance, SugarDbC
WHERE
a.""Id"" in ( {string.Join(",", ids.Select(id => $"'{id}'"))} )
";
var infos = await Repository.AsSugarClient().SqlQueryable<dynamic>(sql)
.ToListAsync();
var result = page.Select(x => new
{
x.Id,
x.Name,
x.Cover,
x.DisplayScheme,
x.Description,
x.DisplayColor,
x.RecognitionX,
x.RecognitionY,
x.SpaceConstraint,
x.ExpansionDistance,
x.TemporalConstraints,
x.TcStartTime,
x.TcEndTime,
x.FlySpeed,
x.GimbalPitchDegree,
x.RecognitionCoverage,
x.Tags,
x.AlgoIds,
TagNames = infos.Where(y => y.algoInstanceId == x.Id).Select(y => y.TagName).ToArray(),
AlgoNames = infos.Where(y => y.algoInstanceId == x.Id).Select(y => y.AlgoName).ToList()
});
return new Response<PageInfo<IEnumerable<dynamic>>>
var infos = await Repository.AsSugarClient().SqlQueryable<dynamic>(sql)
.ToListAsync();
var result = page.Select(x => new
{
x.Id,
x.Name,
x.Cover,
x.DisplayScheme,
x.Description,
x.DisplayColor,
x.RecognitionX,
x.RecognitionY,
x.SpaceConstraint,
x.ExpansionDistance,
x.TemporalConstraints,
x.TcStartTime,
x.TcEndTime,
x.FlySpeed,
x.GimbalPitchDegree,
x.RecognitionCoverage,
x.Tags,
x.AlgoIds,
TagNames = infos.Where(y => y.algoInstanceId == x.Id).Select(y => y.TagName).ToArray(),
AlgoNames = infos.Where(y => y.algoInstanceId == x.Id).Select(y => y.AlgoName).ToList()
});
return new Response<PageInfo<IEnumerable<dynamic>>>
{
Result = new PageInfo<IEnumerable<dynamic>>
{
Items = result,
Total = totalCount.Value
}
};
}
else
{
Result = new PageInfo<IEnumerable<dynamic>>
return new Response<PageInfo<IEnumerable<dynamic>>>
{
Items = result,
Total = totalCount.Value
}
};
Result = new PageInfo<IEnumerable<dynamic>>
{
Items = null,
Total = 0
}
};
}
}
public async Task<Response<LasaAlgoInstance>> GetAlgoInstance(string id)

@ -0,0 +1,249 @@
using Infrastructure;
using Newtonsoft.Json;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.Interface;
using OpenAuth.App.ServiceApp.Algo.Request;
using OpenAuth.App.ServiceApp.Algo.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
namespace OpenAuth.App.ServiceApp.Algo
{
public class DaHuaAiApp : SqlSugarBaseApp<LasaAlgorithmsRepository, SugarDbContext>
{
public DaHuaAiApp(ISugarUnitOfWork<SugarDbContext> unitWork,
ISimpleClient<LasaAlgorithmsRepository> repository, IAuth auth) : base(unitWork, repository, auth)
{
}
#region 大华算法
//分析两次航线图片
public async Task<Response<List<dynamic>>> BehaviorAlarm(string firstId, string secondId)
{
using (var db = UnitWork.CreateContext())
{
//var imageList1 = await db.LasaMediaFile.AsQueryable().Where(r => r.TaskId == firstId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).ToListAsync();
//var imageList2 = await db.LasaMediaFile.AsQueryable().Where(r => r.TaskId == secondId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).ToListAsync();
var imageList1 = await db.LasaMediaFile.AsQueryable().Where(r => r.Id == firstId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).ToListAsync();
var imageList2 = await db.LasaMediaFile.AsQueryable().Where(r => r.Id == secondId && r.AbsoluteAltitude != 0 && r.AbsoluteAltitude != null).ToListAsync();
List<dynamic> dataList = new List<dynamic>();
for (int i = 0; i < imageList1.Count; i++)
{
dataList.Add(new
{
@event = "event.capturePic",
uid = "1",
channelCode = "sdhc04",
recordId = "kQUXlb1Y8oDgCpZSo7l2yG175617335006157587",
sourceId = "kQUXlb1Y8oDgCpZSo7l2yG175617335006157587",
taskSource = 1,
taskId = "8ab0e1e213234a848e20d0d335559786",
capTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
taskTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
imageInfo = new
{
imgSize = 1667235,
imgWidth = 4032,
imgHeight = 3024
},
imageInfoList = new[]
{
new {
imgUrl = "http://175.27.168.120:6013/test/"+imageList1[i].ObjectKey,
imgSize = imageList1[i].Size,
imgWidth = imageList1[i].Width,
imgHeight = imageList1[i].Height,
imgType = 0,
longitude = imageList1[i].Lng,
absAltitude = imageList1[i].AbsoluteAltitude,
latitude = imageList1[i].Lat,
zoom = imageList1[i].DigitalZoomRatio,
yaw = imageList1[i].GimbalYawDegree,
pitch = imageList1[i].GimbalPitchDegree,
roll = imageList1[i].GimbalRollDegree,
focalLength = imageList1[i].FocalLength
},
new {
imgUrl = "http://175.27.168.120:6013/test/"+imageList2[i].ObjectKey,
imgSize = imageList2[i].Size,
imgWidth = imageList2[i].Width,
imgHeight = imageList2[i].Height,
imgType = 1,
longitude =imageList2[i].Lng,
absAltitude = imageList2[i].AbsoluteAltitude,//拍摄绝对高度
latitude = imageList2[i].Lat,
zoom = imageList2[i].DigitalZoomRatio,//放大倍率
yaw =imageList2[i].GimbalYawDegree,//偏航角?
pitch = imageList2[i].GimbalPitchDegree,//滚角?
roll = imageList2[i].GimbalRollDegree,
focalLength = imageList2[i].FocalLength//焦距
}
}
});
}
return new Response<List<dynamic>>
{
Result = dataList,
Message = "获取数据成功"
};
}
}
public async Task<Response<bool>> AddDaHuaImg(string info)
{
using (var db = UnitWork.CreateContext())
{
var data = JsonConvert.DeserializeObject<dynamic>(info);
LasaAiAchievement lasaAiAchievement = new LasaAiAchievement();
lasaAiAchievement.Id = Guid.NewGuid().ToString();
lasaAiAchievement.Title = "疑似耕地破坏";
lasaAiAchievement.CreateTime = DateTime.Now;
lasaAiAchievement.AiModel = "DaHuaAi";
var imageList = data.imageInfoList;
foreach (var item in imageList)
{
//插入详情
LasaAiAchievementDetail lasaAiAchievementDetail = new LasaAiAchievementDetail()
{
Id = Guid.NewGuid().ToString(),
Image = item.imgUrl,
AiAchievementId = lasaAiAchievement.Id
};
lasaAiAchievement.Lat = item.latitude;
lasaAiAchievement.Lng = item.longitude;
lasaAiAchievement.Cover = item.imgUrl;
await db.LasaAiAchievementDetail.InsertAsync(lasaAiAchievementDetail);
}
await db.LasaAiAchievement.InsertAsync(lasaAiAchievement);
if (db.Commit())
return new Response<bool>
{
Result = true,
Message = "添加成功"
};
else
return new Response<bool>
{
Result = false,
Message = "添加失败"
};
}
}
#endregion
#region 本地模型
public async Task<Response<bool>> AddImg(string taskid, string path, string aiid, dynamic drone_info, List<TagItem> tag)
{
using (var db = UnitWork.CreateContext())
{
foreach (var item in tag)
{
var info = await db.LasaAiAchievement.GetFirstAsync(r => r.TaskId == taskid && r.Tag == item.class_id.ToString());
var modelinfo = await db.LasaModelLabel.AsQueryable().Where(r => r.PId == aiid).ToListAsync();
double lat = 0.0, lng = 0.0;
if (drone_info != null)
{
//var root = JsonNode.Parse(drone_info)?.AsObject();
//lat = root?["data"]?["latitude"]?.GetValue<double>() ?? 0.0;
//lng = root?["data"]?["longitude"]?.GetValue<double>() ?? 0.0;
lat = (double?)drone_info.data?.latitude ?? 0.0;
lng = (double?)drone_info.data?.longitude ?? 0.0;
}
if (info == null)
{
LasaAiAchievement lasaAiAchievement = new LasaAiAchievement();
lasaAiAchievement.Id = Guid.NewGuid().ToString();
lasaAiAchievement.CreateTime = DateTime.Now;
lasaAiAchievement.TaskId = taskid;
lasaAiAchievement.AiModel = "yolo12x";
lasaAiAchievement.Tag = item.class_id.ToString();
lasaAiAchievement.AlgoId = aiid;
var modelid = modelinfo.Where(r => r.EnumValue == item.class_id).FirstOrDefault();
if (modelid != null)
{
lasaAiAchievement.Title = modelid.Name + "识别";
}
else
{
if (item.class_id == 1 || item.class_id == 2 || item.class_id == 3 || item.class_id == 5 || item.class_id == 6 || item.class_id == 7)
{
lasaAiAchievement.Title = "车辆识别";
}
else if (item.class_id == 0)
{
lasaAiAchievement.Title = "人员识别";
}
else
{
lasaAiAchievement.Title = "其他识别";
}
}
//var confidence = tag.Select(r => r.confidence).Max();
var confidence = item.confidence;
if (confidence < 0.3)
{
break;
}
lasaAiAchievement.ConfidenceLevel = (float)Math.Round(confidence, 2) * 100;
//插入详情
LasaAiAchievementDetail lasaAiAchievementDetail = new LasaAiAchievementDetail()
{
Id = Guid.NewGuid().ToString(),
Image = "http://175.27.168.120:6013/test/" + path,
AiAchievementId = lasaAiAchievement.Id,
Lat = lat,
Lng = lng
};
lasaAiAchievement.Cover = "http://175.27.168.120:6013/test/" + path;
lasaAiAchievement.Lat = (float)lat;
lasaAiAchievement.Lng = (float)lng;
await db.LasaAiAchievement.InsertAsync(lasaAiAchievement);
await db.LasaAiAchievementDetail.InsertAsync(lasaAiAchievementDetail);
}
else
{
//插入详情
LasaAiAchievementDetail lasaAiAchievementDetail = new LasaAiAchievementDetail()
{
Id = Guid.NewGuid().ToString(),
Image = "http://175.27.168.120:6013/test/" + path,
AiAchievementId = info.Id,
Lat = lat,
Lng = lng
};
await db.LasaAiAchievementDetail.InsertAsync(lasaAiAchievementDetail);
}
}
if (db.Commit())
return new Response<bool>
{
Result = true,
Message = "添加成功"
};
else
return new Response<bool>
{
Result = false,
Message = "添加失败"
};
}
}
#endregion
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenAuth.App.ServiceApp.Algo.Request
{
public class AiImgReq
{
public string taskid;
public string path;
public string aiid;
public dynamic drone_info;
public List<TagItem> tag;
}
public class TagItem
{
public int class_id { get; set; }
public string class_name { get; set; }
public float confidence { get; set; }
public List<double> box { get; set; }
}
}

@ -0,0 +1,103 @@
using DocumentFormat.OpenXml.EMMA;
using SixLabors.ImageSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenAuth.App.ServiceApp.Algo.Response
{
public class DaHuaAiResp
{
public string alarmAction { get; set; }
public string alarmName { get; set; }
public double alarmTime { get; set; }
public string alarmType { get; set; }
public string algoPkgId { get; set; }
public int algorithmType { get; set; }
public long capTime { get; set; }
public string channelCode { get; set; }
public string channelId { get; set; }
public string classType { get; set; }
public int dataSource { get; set; }
public string deviceCode { get; set; }
public string deviceId { get; set; }
public string @event { get; set; }
public string eventId { get; set; }
public string extRecordId { get; set; }
public ImageInfo imageInfo { get; set; }
public List<ImageInfoList> imageInfoList { get; set; }
public List<ImgList> imgList { get; set; }
public Info info { get; set; }
public string paasId { get; set; }
public string recordId { get; set; }
public int ruleId { get; set; }
public string saasExtParam { get; set; }
public string saasTaskId { get; set; }
public string sourceId { get; set; }
public int taskId { get; set; }
public int taskSource { get; set; }
public long taskTime { get; set; }
public double traceServiceInputTime { get; set; }
public string uid { get; set; }
public string userChannelCode { get; set; }
public string userDeviceCode { get; set; }
}
public class ImageInfo
{
public int imgHeight { get; set; }
public int imgSize { get; set; }
public int imgWidth { get; set; }
}
public class ImageInfoList
{
public double absAltitude { get; set; }
public int focalLength { get; set; }
public int imgHeight { get; set; }
public int imgSize { get; set; }
public int imgType { get; set; }
public string imgUrl { get; set; }
public int imgWidth { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public double pitch { get; set; }
public int roll { get; set; }
public double yaw { get; set; }
public int zoom { get; set; }
}
public class ImgList
{
public double capTime { get; set; }
public int imgHeight { get; set; }
public int imgSize { get; set; }
public int imgType { get; set; }
public string imgUrl { get; set; }
public int imgWidth { get; set; }
public List<ObjectRect> objectRect { get; set; }
}
public class ObjectRect
{
public int objBottom { get; set; }
public int objLeft { get; set; }
public int objRight { get; set; }
public int objTop { get; set; }
}
public class Info
{
public List<List<int>> detectRegion { get; set; }
public string name { get; set; }
public List<ObjectGPS> objectGPS { get; set; }
public string plateNum { get; set; }
}
public class ObjectGPS
{
public double latitude { get; set; }
public double longitude { get; set; }
}
}

@ -660,27 +660,9 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<ResData> GetDroneStatus(string deviceid)
public async Task<dynamic> GetDroneStatus(string deviceid)
{
/*string data = @"
{
""code"": 200,
""data"": {
""mode_code"": 0,
""longitude"": 122.45,
""latitude"": 30.45,
""height"": 80,
""elevation"": 50,
""gimbal_pitch"": -45,
""gimbal_yaw"": 23,
""battery_capacity_percent"": 35,
""gps_state"": 2
},
""message"": """",
""traceid"": ""xxx""
}
";*/
dynamic data = new ExpandoObject();
dynamic result = new ExpandoObject();
var dock = await Repository
.ChangeRepository<SugarRepositiry<LasaDronePort>>()
.AsQueryable()
@ -688,14 +670,15 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
.Where((a, b) => b.Sn == deviceid).FirstAsync();
if (dock == null) // 无人机不在线
{
data.code = 200;
result.code = 200;
dynamic inData = new ExpandoObject();
result.data = inData;
inData.mode_code = 1; // 不在线
data.message = "获取无人机状态成功";
result.message = "获取无人机状态成功";
}
else
{
data.code = 200;
result.code = 200;
var dockOsdTopic = $"thing/product/{dock.Sn}/osd";
var now = DateTime.Now;
var time = now.AddSeconds(-5);
@ -760,14 +743,14 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
< 10 => 2, // 高精度
_ => 3 // rtk定位
};
data.data = inData;
data.message = "获取无人机状态成功!";
data.traceid = Guid.NewGuid().ToString();
result.data = inData;
result.message = "获取无人机状态成功!";
result.traceid = Guid.NewGuid().ToString();
}
else
{
data.code = 502;
data.message = "获取无人机状态失败";
result.code = 502;
result.message = "获取无人机状态失败";
}
}
else
@ -792,39 +775,15 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
< 10 => 2,
_ => 3
};
data.data = inData;
data.traceid = Guid.NewGuid().ToString();
data.code = 200;
data.message = "获取无人机状态成功";
result.data = inData;
result.traceid = Guid.NewGuid().ToString();
result.code = 200;
result.message = "获取无人机状态成功";
}
}
}
} // 设备在线
var response = new ResData();
if (data.code == 200)
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态成功!";
response.Code = 200;
response.Secret = xLcSecret;
return response;
}
else
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(" ");
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态失败!";
response.Code = 500;
response.Secret = xLcSecret;
return response;
}
return result;
}
/// <summary>
@ -858,69 +817,86 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
}
/// <summary>
/// 无人机机场设备注册/更新
/// 无人机状态上报
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<Response<string>> reportDroneStatus(List<AirPortStatusApply> req)
public async Task<Response<bool>> ReportDroneStatus()
{
Response<string> Response = new Response<string>();
var handler = new HttpClientHandler();
// 如果需要忽略服务器证书错误(仅测试环境)
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using (var client = new HttpClient())
var droneList = await Repository
.ChangeRepository<SugarRepositiry<LasaUav>>()
.AsQueryable()
.Where(it => it.IsDelete == false)
.ToListAsync();
var dataList = new List<dynamic>();
foreach (var item in droneList)
{
try
var originalData = await GetDroneStatus(item.Sn);
var inData = originalData.data;
// 转换状态值 mode_code -> onlinestate
// 0:在线1:不在线2:任务执行中 -> 设备在线状态00:不在线10:在线20任务执行中
// 增加设备id deviceid
inData.deviceid = item.Sn;
inData.onlinestate = inData.mode_code switch
{
string url = configuration.GetSection("DroneDocking:Url").Value + "/droneAirport/reportDroneStatus";
string x_lc_secret = _helper.getxseret();
string centercode = "UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ";
string x_token = _helper.GetToken(centercode);
// 序列化为 JSON 字符串
string json = JsonSerializer.Serialize(req);
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(json);
var encryptedData = _helper.Encrypt(bytes);
// 创建请求体
var httpContent = new StringContent(encryptedData, Encoding.UTF8, "application/json");
// 添加请求头
client.DefaultRequestHeaders.Add("x-lc-secret", x_lc_secret);
client.DefaultRequestHeaders.Add("x-lc-token", x_token);
//发送请求
HttpResponseMessage response = await client.PostAsync(url, httpContent);
response.EnsureSuccessStatusCode();
// 获取响应头中的 x_cl_screte 参数
string resx_cl_screte = GetHeaderValue(response, "x-lc-secret");
// 读取响应内容并反序列化
string responseBody = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ReciveData<string>>(responseBody);
0 => "10",
1 => "00",
2 => "20",
_ => "00"
};
dataList.Add(inData);
}
//解密数据
byte[] resbytesx = Convert.FromBase64String(resx_cl_screte);
byte[] resdatabytes = Convert.FromBase64String(result?.data);
string data = _helper.Decrypt(resbytesx, resdatabytes);
using var client = new HttpClient();
try
{
// 无人机状态上报接口
var url = configuration.GetSection("DroneDocking:Url").Value +
"/droneAirport/reportDroneStatus";
var xLcSecret = _helper.getxseret();
var centerCode = "UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ";
var xToken = _helper.GetToken(centerCode);
// 序列化为 JSON 字符串
string json = JsonSerializer.Serialize(dataList);
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(json);
Response.Result = data;
Response.Message = result.message;
Response.Code = result.code;
}
catch (HttpRequestException e)
var encryptedData = _helper.Encrypt(bytes);
// 创建请求体
var httpContent = new StringContent(encryptedData, Encoding.UTF8, "application/json");
// 添加请求头
client.DefaultRequestHeaders.Add("x-lc-secret", xLcSecret);
client.DefaultRequestHeaders.Add("x-lc-token", xToken);
//发送请求
HttpResponseMessage response = await client.PostAsync(url, httpContent);
response.EnsureSuccessStatusCode();
// 获取响应头中的 x_cl_screte 参数
var resxClScrete = GetHeaderValue(response, "x-lc-secret");
// 读取响应内容并反序列化
var responseBody = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ReciveData<string>>(responseBody);
//解密数据
byte[] resbytesx = Convert.FromBase64String(resxClScrete);
byte[] resdatabytes = Convert.FromBase64String(result?.data);
string data = _helper.Decrypt(resbytesx, resdatabytes);
// 结果
}
catch (HttpRequestException e)
{
return new Response<bool>()
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ", e.Message);
Response.Result = "连接错误";
}
Result = false,
Message = e.Message
};
}
return Response;
return new Response<bool>()
{
Result = true,
};
}
@ -1409,35 +1385,37 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
{
RefAsync<int> totalCount = 0;
var info = await base.Repository.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(keyWord), t => t.taskname.Contains(keyWord)||t.bizidname.Contains(keyWord))
.Select(t=>new DroneDockRes
{
id= t.id,
bizidname= t.bizidname,
taskname= t.taskname,
createtime= t.createtime,
state= t.state,
datacode= t.datacode,
deviceid= t.deviceid,
taskid= t.taskid,
tasklist = SqlFunc.Subqueryable<DroneDocktaskdetail>().Where(r => r.taskid == t.id).LeftJoin<LasaTask>((r, s) => r.flighttaskid == s.FlightId).ToList((r,s)=> new DetailRes
.WhereIF(!string.IsNullOrEmpty(keyWord),
t => t.taskname.Contains(keyWord) || t.bizidname.Contains(keyWord))
.Select(t => new DroneDockRes
{
id = r.id,
bsm=r.bsm,
Status=s.Status,
bz=r.bz,
dkbh=r.dkbh,
dkfw=r.dkfw,
dklx=r.dklx,
dkmc=r.dkmc,
dkmj=r.dkmj,
flighttaskid=r.flighttaskid,
taskid=r.taskid,
xzqdm=r.xzqdm,
zdkbh=r.zdkbh
id = t.id,
bizidname = t.bizidname,
taskname = t.taskname,
createtime = t.createtime,
state = t.state,
datacode = t.datacode,
deviceid = t.deviceid,
taskid = t.taskid,
tasklist = SqlFunc.Subqueryable<DroneDocktaskdetail>().Where(r => r.taskid == t.id)
.LeftJoin<LasaTask>((r, s) => r.flighttaskid == s.FlightId).ToList((r, s) => new DetailRes
{
id = r.id,
bsm = r.bsm,
Status = s.Status,
bz = r.bz,
dkbh = r.dkbh,
dkfw = r.dkfw,
dklx = r.dklx,
dkmc = r.dkmc,
dkmj = r.dkmj,
flighttaskid = r.flighttaskid,
taskid = r.taskid,
xzqdm = r.xzqdm,
zdkbh = r.zdkbh
})
})
})
.ToPageListAsync(page, limit, totalCount);
.ToPageListAsync(page, limit, totalCount);
return new Response<PageInfo<List<DroneDockRes>>>
{
Result = new PageInfo<List<DroneDockRes>>

@ -0,0 +1,28 @@
namespace OpenAuth.App.ServiceApp.FlyTask.Request;
public class CallAiModel
{
/// <summary>
/// 飞行任务id
/// </summary>
public string TaskId { get; set; }
/// <summary>
///算法实例id
/// </summary>
public string AlgoInstanceId { get; set; }
/// <summary>
/// 直播推流地址
/// </summary>
public string RtmpUrl { get; set; }
/// <summary>
/// 告警标题
/// </summary>
public string WarningTitle { get; set; }
/// <summary>
/// 告警内容
/// </summary>
public string WarningContent { get; set; }
}

@ -0,0 +1,11 @@
namespace OpenAuth.App.ServiceApp.FlyTask.Request;
public class LasaHandFlyTask
{
/// <summary>
/// 计划id
/// </summary>
public string FlightId { get; set; }
public string WorkspaceId { get; set; }
}

@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Drawing;
using System.Dynamic;
@ -13,15 +14,18 @@ using MetadataExtractor;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor.Formats.Xmp;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.BaseApp.Subscribe;
using OpenAuth.App.BasicQueryService;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.App.ServiceApp.AirLine.Request;
using OpenAuth.App.ServiceApp.FlyTask.Request;
using OpenAuth.App.ServiceApp.FlyTask.Response;
using OpenAuth.App.ServiceApp.Request;
using OpenAuth.App.ServiceApp.Response;
@ -40,17 +44,21 @@ namespace OpenAuth.App.ServiceApp
private readonly MqttClientManager _mqttClientManager;
private readonly MinioService _minioService;
private readonly OpenJobApp _openJobApp;
private readonly ILogger<LasaDronePort> _logger;
CommonDataManager _commonDataManager;
private readonly ConcurrentDictionary<string, DateTime> _processedMessages = new();
private readonly TimeSpan _deduplicationWindow = TimeSpan.FromMinutes(1);
public ManageApp(ISugarUnitOfWork<SugarDbContext> unitWork, ISimpleClient<LasaDronePort> repository, IAuth auth,
MqttClientManager mqttClientManager, CommonDataManager commonDataManager, MinioService minioService,
OpenJobApp openJobApp)
OpenJobApp openJobApp, ILogger<LasaDronePort> logger)
: base(unitWork, repository, auth)
{
_mqttClientManager = mqttClientManager;
_minioService = minioService;
_commonDataManager = commonDataManager;
_openJobApp = openJobApp;
_logger = logger;
}
#region 机场管理
@ -416,7 +424,7 @@ namespace OpenAuth.App.ServiceApp
task.CreateTime = DateTime.Now;
//task.FlightId = Guid.NewGuid().ToString();
// 如:执行时长,单次定时的时间
// 0-飞行计划 1-指点飞行
// 0-飞行计划 1-手飞任务
task.FlightTaskType = 0; //
task.PlanExecuteDuration = airLine.ScheduleTime;
task.ExpectedFileCount = airLine.PictureTotal;
@ -428,11 +436,20 @@ namespace OpenAuth.App.ServiceApp
Id = Guid.NewGuid().ToString(),
TaskId = task.Id,
AlgoInstanceId = task.AlgoInstanceId,
WarningTitle = task.WarningTitle,
WarningContent = task.WarningContent
};
if (!string.IsNullOrEmpty(task.WarningTitle))
{
aiInspection.WarningTitle = task.WarningTitle;
}
if (!string.IsNullOrEmpty(task.WarningContent))
{
aiInspection.WarningContent = task.WarningContent;
}
await db.LasaAiInspection.InsertAsync(aiInspection);
}
// //{"0":"立即任务","1":"定时任务",
var type = task.TaskType;
if (type.Equals(1) || type.Equals(2)) // 定时任务
@ -445,10 +462,10 @@ namespace OpenAuth.App.ServiceApp
{
JobName = $"{task.Id}",
JobType = 0, // 本地任务
JobCall = "OpenAuth.App.ServiceApp.FlyTaskJob",
JobCall = "OpenAuth.App.OpenJob.FlyTaskJob",
JobCallParams = "{\"taskId\":\"" + task.Id + "\"}",
Cron = task.PeriodicFormula,
Status = 1, // 开启运行 todo 关于修改后关闭问题
Status = 1, // 开启运行
Remark = "定时任务",
};
var jobId = _openJobApp.Add(record);
@ -1183,7 +1200,6 @@ namespace OpenAuth.App.ServiceApp
Wpml = wpml
};
await Repository.ChangeRepository<SugarRepositiry<LasaTaskAssign>>().InsertAsync(taskAssign);
// todo 更新任务状态?
}
public async Task PendingFlyTask(string taskId)
@ -2345,5 +2361,392 @@ namespace OpenAuth.App.ServiceApp
Result = true
};
}
/// <summary>
/// 保存手飞任务信息
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public async Task<Response<dynamic>> SaveHandFlyTask(LasaHandFlyTask task)
{
var user = _auth.GetCurrentUser().User;
var date = DateTime.Now;
var lasaTask = new LasaTask
{
Id = Guid.NewGuid().ToString(),
TaskName = $"手飞任务 {date:yyyyMMddHHmmss}",
TaskType = 0,
//0 计划任务 1 手飞任务
FlightTaskType = 1,
AIInspection = "true",
WorkspaceId = task.WorkspaceId,
FlightId = task.FlightId,
Status = 1, // 待执行
CreateTime = date,
ScheduledStartTime = date, // 任务计划执行时间
ExecuteTime = date, // 任务开始执行时间
CreateUserName = user.Name,
CreateId = user.Id
};
await Repository.ChangeRepository<SugarRepositiry<LasaTask>>().InsertAsync(lasaTask);
return new Response<dynamic>()
{
Result = new
{
taskId = lasaTask.Id
}
};
}
public async Task<Response<bool>> CallAiModel(CallAiModel req)
{
_logger.LogDebug("成功调用CallAIModel");
var task = await Repository
.ChangeRepository<SugarRepositiry<LasaTask>>()
.GetByIdAsync(req.TaskId);
;
using var db = Repository.AsSugarClient();
try
{
db.Ado.BeginTran();
if (task.FlightTaskType.Equals(1)) // 手飞任务
{
var aiInspection = new LasaAiInspection
{
Id = Guid.NewGuid().ToString(),
TaskId = req.TaskId,
AlgoInstanceId = req.AlgoInstanceId,
};
if (!string.IsNullOrEmpty(req.WarningContent))
{
aiInspection.WarningTitle = req.WarningTitle;
}
if (!string.IsNullOrEmpty(req.WarningContent))
{
aiInspection.WarningContent = req.WarningContent;
}
// 更新
// todo 关于多次调用问题
var count = await db.Queryable<LasaAiInspection>().Where(x => x.TaskId == req.TaskId).CountAsync();
if (count == 0)
{
await db.Insertable(aiInspection).ExecuteCommandAsync();
}
}
else
{
var aiInspection = await Repository
.ChangeRepository<SugarRepositiry<LasaAiInspection>>()
.AsQueryable().Where(x => x.TaskId == req.TaskId).FirstAsync();
req.AlgoInstanceId = aiInspection.AlgoInstanceId;
}
var algoInstances = await db
.Queryable<LasaAlgoInstance>()
.Where(x => x.Id == req.AlgoInstanceId)
.ToListAsync();
var tagsIds = algoInstances.Select(x => x.Tags).ToList();
// todo 关于存在多个算法的处理
var algoIds = algoInstances.First().AlgoIds.Split(",").ToArray();
var algo = await db
.Queryable<LasaAlgorithmsRepository>()
.Where(x => x.Id == algoIds[0])
.FirstAsync();
dynamic json = new
ExpandoObject();
var x = SnowFlakeSingle.instance;
//var pushUrl = $"rtmp://box.wisestcity.com:1935/live/{x.NextId()}";
var config = ConfigHelper.GetConfigRoot();
var pushUrl = config["AIModelApi:PushUrl"];
json.rtmp_url = req.RtmpUrl;
json.push_url = pushUrl;
json.imgsz = 640;
json.frame_skip = 1;
json.model_name = algo.Path;
//json.model_name = "yolo12x.pt";
json.taskname = task.TaskName;
json.taskid = req.TaskId;
// 算法id
json.AlgoId = algo.Id;
var taskRecord = new LasaTask()
{
Id = req.TaskId,
Status = 6, // 智能巡检状态
PushUrl = pushUrl
};
var tagIdArray = new List<string>();
foreach (var tagId in tagsIds)
{
tagIdArray.AddRange(tagId.Split(",").ToList());
}
await db.Updateable(taskRecord).IgnoreNullColumns().ExecuteCommandAsync();
var tag = await db
.Queryable<LasaModelLabel>()
.Where(l => tagIdArray.Contains(l.Id))
.ToArrayAsync();
IDictionary<string, object> jsonTag = new Dictionary<string, object>();
foreach (var lasaModelLabel in tag)
{
var model = new
{
name = lasaModelLabel.Name,
reliability = lasaModelLabel.Reliability
};
jsonTag[lasaModelLabel.EnumValue.ToString()] = model;
}
json.tag = jsonTag;
Console.WriteLine(JsonConvert.SerializeObject(json));
var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
var url = config["AIModelApi:Url"];
using var httpClient = new HttpClient();
var response = await httpClient.PostAsync($"{url}/start_detection", content);
//var response = await httpClient.PostAsync("http://192.168.10.131:9025/start_detection", content);
_logger.LogDebug($"成功调用{response.IsSuccessStatusCode}");
db.Ado.CommitTran();
}
catch (Exception ex)
{
db.Ado.RollbackTran();
throw ex;
//throw new Exception("调用智能巡检失败");
}
return new Response<bool>()
{
Result = true
};
}
public async Task<Response<bool>> EndHandFlyTask(string taskid)
{
var task = new LasaTask()
{
Id = taskid,
// ScheduledEndTime = DateTime.Now,
CompletedTime = DateTime.Now,
Status = 5 // 成功
};
using var db = Repository.AsSugarClient();
try
{
db.Ado.BeginTran();
await db.Updateable(task).IgnoreNullColumns().ExecuteCommandAsync();
var config = ConfigHelper.GetConfigRoot();
var url = config["AIModelApi:Url"];
// 结束智能巡检
using var httpClient = new HttpClient();
await httpClient.PostAsync($"{url}/stop_detection", null);
db.Ado.CommitTran();
}
catch (Exception ex)
{
db.Ado.RollbackTran();
throw new Exception("结束任务失败");
}
return new Response<bool>()
{
Result = true
};
}
public bool IsDuplicate(string messageId)
{
var now = DateTime.UtcNow;
// 清理过期消息
foreach (var kvp in _processedMessages)
{
if (now - kvp.Value > _deduplicationWindow)
{
_processedMessages.TryRemove(kvp.Key, out _);
}
}
// 检查是否已存在
if (_processedMessages.ContainsKey(messageId))
{
return true;
}
_processedMessages[messageId] = now;
return false;
}
public async Task<Response<bool>> TestZhiBao(string message)
{
var sn = "8UUXN5400A079H";
var result = JsonConvert.DeserializeObject<TopicServicesRequest<dynamic>>(message);
var method = result.method;
var data = result.data;
//_logger.LogInformation($"主题:{topic}\n消息{message}");
long code = 0;
var isHandle = IsDuplicate(Md5.Encrypt(message));
//_logger.LogDebug($"md5: {isHandle} 重复否:{IsDuplicate(Md5.Encrypt(message))} 信息:{message} ");
if (isHandle)
{
_logger.LogInformation("跳过处理");
return null;
}
_logger.LogDebug("航线进度未跳过处理");
code = data.result; // result
var waylineMissionState = (int)data.output.ext.wayline_mission_state;
string flightId1 = (string)data.output.ext.flight_id;
var taskAssign1 = GetTaskAssignByFlightId(flightId1);
// 处理航线进度 ,也有可能是失败
var step = (int)data.output.progress.current_step;
_logger.LogDebug($"航线进度:{waylineMissionState} {step} {message}");
if (step.Equals(25)) // 航线执行
{
var task = await Repository.AsSugarClient().Queryable<LasaTask>()
.FirstAsync(y => y.Id == taskAssign1.TaskId);
if (task != null && !string.IsNullOrEmpty(task.AIInspection) &&
task.AIInspection.Equals("true") && string.IsNullOrEmpty(task.PushUrl))
{
_logger.LogDebug("执行AI 智能巡检。。。。。");
var rtmp = "rtmp://box.wisestcity.com:1935/live/55";
var param =
@$"{{""bid"": ""{Guid.NewGuid().ToString()}"",""method"": ""live_start_push"",""tid"": ""{Guid.NewGuid().ToString()}"",
""timestamp"": {DateTimeOffset.Now.ToUnixTimeMilliseconds()},
""data"": {{
""url_type"": 1,
""url"": ""{rtmp}"",
""video_id"": ""8UUXN5400A079H/165-0-7/normal-0"",
""video_quality"": 3
}}
}}";
//thing/product/{gateway_sn}/services
var topicRequest = $"thing/product/{sn}/services";
var x = RemoveSpecificChars(param);
_logger.LogDebug($"直播参数:{x}");
await _mqttClientManager.PublishAsync(topicRequest, x);
var req = new CallAiModel { TaskId = taskAssign1.TaskId, RtmpUrl = rtmp };
await CallAiModel(req);
}
}
// 航线成功
/*
if (waylineMissionState.Equals(9)) // 航结结束,更新任务状态
{
var task = await Repository.AsSugarClient().Queryable<LasaTask>()
.FirstAsync(y => y.Id == taskAssign1.TaskId);
if (!string.IsNullOrEmpty(task.AIInspection) && task.AIInspection.Equals(true) &&
!string.IsNullOrEmpty(task.PushUrl))
{
// 停止直播
// 停止 aimodel 运行
var para = @$"{{
""bid"": ""{Guid.NewGuid().ToString()}"",
""data"": {{
""video_id"": ""8UUXN5400A079H/165-0-7/normal-0""
}},
""tid"":""{Guid.NewGuid().ToString()}"",
""timestamp:"": {DateTimeOffset.Now.ToUnixTimeMilliseconds()},
""method"": ""live_stop_push""
}}";
var topicRequest = $"thing/product/{sn}/services";
await _mqttClientManager.PublishAsync(topicRequest, RemoveSpecificChars(para));
using var httpClient = new HttpClient();
await httpClient.PostAsync("http://192.168.10.131:9025/stop_detection", null);
}
var record = new LasaTask()
{
Id = taskAssign1.TaskId,
Status = 5
};
// await Repository.AsSugarClient().Updateable(record).IgnoreNullColumns().ExecuteCommandAsync();
}
*/
return null;
}
public void CloseZhibo(string videoId)
{
var sn = "8UUXN5400A079H";
var para = @$"{{
""bid"": ""{Guid.NewGuid().ToString()}"",
""data"": {{
""video_id"": ""8UUXN5400A079H/165-0-7/normal-0""
}},
""tid"":""{Guid.NewGuid().ToString()}"",
""timestamp:"": {DateTimeOffset.Now.ToUnixTimeMilliseconds()},
""method"": ""live_stop_push""
}}";
var topicRequest = $"thing/product/{sn}/services";
_mqttClientManager.PublishAsync(topicRequest, para);
var config = ConfigHelper.GetConfigRoot();
var url = config["AIModelApi:Url"];
using var httpClient = new HttpClient();
httpClient.PostAsync($"{url}/stop_detection", null);
}
public static string RemoveSpecificChars(string input)
{
if (string.IsNullOrEmpty(input))
return input;
var charsToRemove = new char[] { ' ', '\r', '\n', '\t' };
return string.Concat(input.Where(c => !charsToRemove.Contains(c)));
}
public async Task<Response<dynamic>> GetLastHandFlyTask()
{
var result = await Repository.ChangeRepository<SugarRepositiry<LasaTask>>()
.AsQueryable().Where(r => r.FlightTaskType == 1)
.OrderByDescending(r => r.CreateTime)
.Select<dynamic>(r => new
{
r.Id,
r.Status
})
.FirstAsync();
return new Response<dynamic>
{
Result = result
};
}
public async Task<Response<bool>> EndAiInspection(string taskid)
{
var task = new LasaTask()
{
Id = taskid,
// ScheduledEndTime = DateTime.Now,
//CompletedTime = DateTime.Now,
Status = 1 // 成功
};
using var db = Repository.AsSugarClient();
try
{
db.Ado.BeginTran();
await db.Updateable(task).IgnoreNullColumns().ExecuteCommandAsync();
var config = ConfigHelper.GetConfigRoot();
var url = config["AIModelApi:Url"];
// 结束智能巡检
using var httpClient = new HttpClient();
await httpClient.PostAsync($"{url}/stop_detection", null);
db.Ado.CommitTran();
}
catch (Exception ex)
{
db.Ado.RollbackTran();
throw new Exception("结束任务失败");
}
return new Response<bool>()
{
Result = true
};
}
}
}

@ -1,4 +1,5 @@
using System.Dynamic;
using System.Collections.Concurrent;
using System.Dynamic;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
@ -7,14 +8,15 @@ using Infrastructure.CloudSdk;
using Infrastructure.CloudSdk.minio;
using Infrastructure.CloudSdk.wayline;
using Infrastructure.Extensions;
using Infrastructure.Helpers;
using MetadataExtractor;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor.Formats.Xmp;
using Microsoft.Extensions.Logging;
using MQTTnet.Client;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using OpenAuth.App.ServiceApp;
using OpenAuth.App.ServiceApp.FlyTask.Request;
using OpenAuth.Repository.Domain;
using OpenAuth.WebApi;
using Quartz;
@ -32,6 +34,8 @@ public class ConfigSubscribe : IJob
private object _locker = new();
private object _dockUploadFileLocker = new();
private readonly ILogger<ConfigSubscribe> _logger;
private readonly ConcurrentDictionary<string, DateTime> _processedMessages = new();
private readonly TimeSpan _deduplicationWindow = TimeSpan.FromMinutes(1);
public ConfigSubscribe(MqttClientManager mqttClientManager, ISqlSugarClient sqlSugarClient,
ICacheContext redisCacheContext, ManageApp manageApp, MinioService minioService,
@ -98,7 +102,7 @@ public class ConfigSubscribe : IJob
var result = JsonConvert.DeserializeObject<TopicServicesRequest<dynamic>>(message);
var method = result.method;
var data = result.data;
_logger.LogInformation($"主题:{topic}\n消息{message}");
//_logger.LogInformation($"主题:{topic}\n消息{message}");
long code = 0;
switch (tempStr)
{
@ -149,12 +153,6 @@ public class ConfigSubscribe : IJob
case "flight_areas_get":
//Console.WriteLine("跳过自定义飞行区文件获取");
break;
//{"bid":"f936a236-030c-4358-bee9-b5075e1e2ddf",
//"data":{"flight_id":"e5ce8433-c264-4357-84d9-b701faf90d9e"},
//"method":"flighttask_resource_get",
//"tid":"61b6389a-7b72-49ae-bb46-0729e85c95d2",
//"timestamp":1750554644321,
//"gateway":"8UUXN5400A079H"}
// 获取航线
case "flighttask_resource_get":
string flightId = data.flight_id + "";
@ -210,7 +208,8 @@ public class ConfigSubscribe : IJob
// 文件上传
_logger.LogDebug("进入文件上传处理");
_logger.LogDebug($"文件上传处理:{message}");
//飞行任务 0 指令飞行 1
//飞行任务 0 手飞任务 1
// todo 如果是手飞任务,生成任务 关于任务类型?
int flightType = data.flight_task.flight_type;
string flightId = data.file.ext.flight_id;
// 关于flightId 没有值的问题怎么办???
@ -218,10 +217,11 @@ public class ConfigSubscribe : IJob
var taskId = "";
var taskName = "";
var workspaceId = "";
LasaTask executeTask = null;
if (taskAssign != null)
{
taskId = taskAssign.TaskId;
var executeTask = await _sqlSugarClient
executeTask = await _sqlSugarClient
.Queryable<LasaTask>()
.SingleAsync(a => a.Id == taskId);
if (!string.IsNullOrEmpty(executeTask.TaskName))
@ -332,20 +332,14 @@ public class ConfigSubscribe : IJob
var y = response.Content.ReadAsByteArrayAsync().Result;
var ms = new MemoryStream(y);
var directories = ImageMetadataReader.ReadMetadata(ms);
// 获取 XMP 目录(包含 XMP 原始 XML 数据)
var xmpDirectory = directories.OfType<XmpDirectory>().FirstOrDefault();
if (xmpDirectory != null)
{
// 获取 XMP 的 XML 字符串(原始数据)
var xmpXml = xmpDirectory.GetXmpProperties();
foreach (var keyValuePair in xmpXml)
{
switch (keyValuePair.Key)
{
// // drone-dji:GimbalPitchDegree: -90.00
//drone-dji:GimbalReverse: 0
//drone-dji:GimbalRollDegree: +180.00
//drone-dji:GimbalYawDegree: -96.40
case "drone-dji:GimbalPitchDegree":
gimbalPitch = float.Parse(keyValuePair.Value);
break;
@ -488,6 +482,20 @@ public class ConfigSubscribe : IJob
GimbalRollDegree = gimbalRoll,
DigitalZoomRatio = digitalZoomRatio
};
if (executeTask != null)
{
_logger.LogDebug($"任务信息:{JsonConvert.SerializeObject(executeTask)}");
if (!string.IsNullOrEmpty(executeTask.CreateUserName))
{
fileUpload.CreateUserName = executeTask.CreateUserName;
}
if (executeTask.CreateId != null)
{
fileUpload.CreateUserId = executeTask.CreateId;
}
}
// 添加事务
await _sqlSugarClient.Insertable(fileUpload).ExecuteCommandAsync();
}
@ -568,9 +576,20 @@ public class ConfigSubscribe : IJob
// "28":"降落以后的关盖"
// "29":"机场退出工作模式"
// "30":"机场异常恢复","31":"机场上传飞行系统日志","32":"相机录像状态检查","33":"获取媒体文件数量","34":"机场起飞开盖的异常恢复","35":"通知任务结果","36":"日志列表拉取 - 飞行器列表","37":"日志列表拉取 - 拉取机场列表","38":"日志列表拉取 - 上传日志列表结果","39":"日志拉取-拉取飞行器日志","40":"日志拉取-拉取机场日志","41":"日志拉取-压缩飞行器日志","42":"日志拉取-压缩机场日志","43":"日志拉取-上传飞行器日志","44":"日志拉取-上传机场日志","45":"日志拉取-通知结果","46":"自定义飞行区文件更新准备中","47":"自定义飞行区更新中","48":"离线地图更新准备中","49":"离线地图更新中","65533":"结束后等待服务回包","65534":"无具体状态","65535":"UNKNOWN"}
var isHandle = IsDuplicate(Md5.Encrypt(message));
_logger.LogDebug($"md5: {isHandle} 重复否:{IsDuplicate(Md5.Encrypt(message))} 信息:{message} ");
if (isHandle)
{
_logger.LogInformation("跳过处理");
break;
}
_logger.LogDebug("航线进度未跳过处理");
code = data.result; // result
var x = (int)data.output.ext.wayline_mission_state;
var flightId2 = (string)data.output.ext.flight_id;
var waylineMissionState = (int)data.output.ext.wayline_mission_state;
string flightId1 = (string)data.output.ext.flight_id;
var taskAssign1 = _manageApp.GetTaskAssignByFlightId(flightId1);
// 处理航线进度 ,也有可能是失败
if (code != 0)
{
@ -591,14 +610,13 @@ public class ConfigSubscribe : IJob
await _mqttClientManager.PublishAsync(cancelTaskTopic,
JsonConvert.SerializeObject(cancelTaskRequest));
//更新任务状态及失败原因?
string flightId1 = data.output.ext.flight_id;
var taskId1 = _manageApp.GetTaskAssignByFlightId(flightId1).TaskId;
// "773":"低电量返航导致航线中断"
int reasonCode = data.output.ext.break_point.break_reason;
// 添加断点信息
var taskRecord1 = new LasaTask()
{
Id = taskId1,
Id = taskAssign1.TaskId,
Status = 2,
Reason = ErrorMap[code],
BreakPoint = JsonConvert.SerializeObject(data.output.ext.break_point)
@ -610,22 +628,73 @@ public class ConfigSubscribe : IJob
}
else
{
var step = (int)data.output.progress.current_step;
_logger.LogDebug($"航线进度:{waylineMissionState} {step} {message}");
if (step.Equals(25)) // 航线执行
{
var task = await _sqlSugarClient.Queryable<LasaTask>()
.FirstAsync(y => y.Id == taskAssign1.TaskId);
if (task != null && !string.IsNullOrEmpty(task.AIInspection) &&
task.AIInspection.Equals("true") && string.IsNullOrEmpty(task.PushUrl))
{
_logger.LogDebug("执行AI 智能巡检。。。。。");
var rtmp = "rtmp://box.wisestcity.com:1935/live/7";
var param = @$"{{
""bid"": ""{Guid.NewGuid().ToString()}"",
""method"": ""live_start_push"",
""tid"": ""{Guid.NewGuid().ToString()}"",
""timestamp"": {DateTimeOffset.Now.ToUnixTimeMilliseconds()},
""data"": {{
""url_type"": 1,
""url"": ""{rtmp}"",
""video_id"": ""1581F8HGX254V00A0BUY/99-0-0/normal-0"",
""video_quality"": 3
}}
}}";
_logger.LogDebug($"直播参数:{param}");
var topicRequest = $"thing/product/{sn}/services";
await _mqttClientManager.PublishAsync(topicRequest, param);
var req = new CallAiModel { TaskId = taskAssign1.TaskId, RtmpUrl = rtmp };
await _manageApp.CallAiModel(req);
}
}
// 航线成功
if (x.Equals(9)) // 航结结束,更新任务状态
if (waylineMissionState.Equals(9)) // 航结结束,更新任务状态
{
var task1 = await _sqlSugarClient
.Queryable<LasaTask>()
.SingleAsync(a => a.FlightId == flightId2);
var task = await _sqlSugarClient.Queryable<LasaTask>()
.FirstAsync(y => y.Id == taskAssign1.TaskId);
if (!string.IsNullOrEmpty(task.AIInspection) && task.AIInspection.Equals(true) &&
!string.IsNullOrEmpty(task.PushUrl))
{
// todo video_id 需要根据不同设备改变
var para = @$"{{
""bid"": {Guid.NewGuid().ToString()},
""data"": {{
""video_id"": ""1581F8HGX254V00A0BUY/99-0-0/normal-0""
}},
""tid"":{Guid.NewGuid().ToString()},
""timestamp:"": {DateTimeOffset.Now.ToUnixTimeMilliseconds()},
""method"": ""live_stop_push""
}}";
var topicRequest = $"thing/product/{sn}/services";
await _mqttClientManager.PublishAsync(topicRequest, para);
var config = ConfigHelper.GetConfigRoot();
var url = config["AIModelApi:Url"];
using var httpClient = new HttpClient();
await httpClient.PostAsync($"{url}/stop_detection", null);
}
var record = new LasaTask()
{
Id = task1.Id,
Id = taskAssign1.TaskId,
Status = 5
};
await _sqlSugarClient.Updateable(record).IgnoreNullColumns().ExecuteCommandAsync();
}
}
if (result.need_reply.Equals(1))
/*if (result.need_reply.Equals(1))
{
var fileUploadCallbackEventReply = new FileUploadCallbackEventReply<object>()
{
@ -641,9 +710,9 @@ public class ConfigSubscribe : IJob
};
await _mqttClientManager.PublishAsync($"thing/product/{sn}/events_reply",
JsonConvert.SerializeObject(fileUploadCallbackEventReply));
}
}*/
Console.WriteLine($"航线进度:{message}");
//Console.WriteLine($"航线进度:{message}");
break;
}
default:
@ -664,6 +733,17 @@ public class ConfigSubscribe : IJob
case "thing/product/*/services_reply":
switch (method)
{
case "live_start_push":
if (IsDuplicate(Md5.Encrypt(message)))
{
break;
}
_logger.LogDebug($"开启直播成功 {message}");
break;
case "live_stop_push":
_logger.LogDebug($"停止直播成功 {message}");
break;
case "flighttask_prepare": // 下发任务响应
// 顺序处理,多余的不再处理
lock (_locker)
@ -777,6 +857,29 @@ public class ConfigSubscribe : IJob
return DateTimeOffset.FromUnixTimeSeconds(seconds).DateTime;
}
public bool IsDuplicate(string messageId)
{
var now = DateTime.UtcNow;
// 清理过期消息
foreach (var kvp in _processedMessages)
{
if (now - kvp.Value > _deduplicationWindow)
{
_processedMessages.TryRemove(kvp.Key, out _);
}
}
// 检查是否已存在
if (_processedMessages.ContainsKey(messageId))
{
return true;
}
_processedMessages[messageId] = now;
return false;
}
public static Dictionary<long, string> ErrorMap = new()
{
{ 312014, "设备升级中,请勿重复操作" },

@ -31,9 +31,17 @@ public class LasaAiAchievement
[SugarColumn(ColumnName = "AiModel")]
public string AiModel { get; set; }
[SugarColumn(ColumnName = "TaskId")]
public string TaskId { get; set; }
[SugarColumn(ColumnName = "Tag")]
public string Tag { get; set; }
[SugarColumn(ColumnName = "Cover")]
public string Cover { get; set; }
[SugarColumn(ColumnName = "Description")]
public string Description { get; set; }
[SugarColumn(ColumnName = "AlgoId")]
public string AlgoId { get; set; }
[SugarColumn(IsIgnore = true)] public List<LasaAiAchievementDetail> AiAchievementDetailList { get; set; }
}

@ -12,4 +12,9 @@ public class LasaAiAchievementDetail
[SugarColumn(ColumnName = "AiAchievementId")]
public string AiAchievementId { get; set; }
[SugarColumn(ColumnName = "Lng")]
public double Lng { get; set; }
[SugarColumn(ColumnName = "Lat")]
public double Lat { get; set; }
}

@ -2,6 +2,8 @@
namespace OpenAuth.Repository.Domain;
[SugarTable("lasa_aiinspection")]
public class LasaAiInspection
{
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true)]

@ -15,7 +15,6 @@ public class LasaAlgoInstance
/// </summary>
[Key]
[SugarColumn(IsPrimaryKey = true, ColumnName = "Id")]
[MaxLength(50)]
public string Id { get; set; }
/// <summary>
@ -23,35 +22,30 @@ public class LasaAlgoInstance
/// </summary>
[SugarColumn(ColumnName = "Name")]
[Required]
[MaxLength(50)]
public string Name { get; set; }
/// <summary>
/// 封面
/// </summary>
[SugarColumn(ColumnName = "Cover")]
[MaxLength(1000)]
public string Cover { get; set; }
/// <summary>
/// 显示方案
/// </summary>
[SugarColumn(ColumnName = "DisplayScheme")]
[MaxLength(30)]
public string DisplayScheme { get; set; }
/// <summary>
/// 描述
/// </summary>
[SugarColumn(ColumnName = "Description")]
[MaxLength(2000)]
public string Description { get; set; }
/// <summary>
/// 显示颜色
/// </summary>
[SugarColumn(ColumnName = "DisplayColor")]
[MaxLength(15)]
public string DisplayColor { get; set; }
/// <summary>
@ -100,28 +94,24 @@ public class LasaAlgoInstance
/// 飞行速度
/// </summary>
[SugarColumn(ColumnName = "FlySpeed")]
[MaxLength(30)]
public string FlySpeed { get; set; }
/// <summary>
/// 云台俯仰角
/// </summary>
[SugarColumn(ColumnName = "GimbalPitchDegree")]
[MaxLength(35)]
public string GimbalPitchDegree { get; set; }
/// <summary>
/// 识别对象画面占比
/// </summary>
[SugarColumn(ColumnName = "RecognitionCoverage")]
[MaxLength(10)]
public string RecognitionCoverage { get; set; }
/// <summary>
/// 标签
/// </summary>
[SugarColumn(ColumnName = "Tags")]
[MaxLength(255)]
public string Tags { get; set; }
[SugarColumn(ColumnName = "AlgoIds")]
public string AlgoIds { get; set; }

@ -143,7 +143,8 @@ public class LasaMediaFile
[SugarColumn(IsIgnore = true)] public List<LasaMediaFile> Children { get; set; }
[SugarColumn(IsIgnore = true)] public string CreateUserName { get; set; }
public string CreateUserName { get; set; }
[SugarColumn(IsIgnore = true)] public string TaskName { get; set; }
[SugarColumn(IsIgnore = true)] public string AirLineName { get; set; }
public long? CreateUserId { get; set; }
}

@ -23,7 +23,7 @@ namespace OpenAuth.Repository.Domain
/// 任务名称
/// </summary>
public string TaskName { get; set; }
public string CreateUserName { get; set; }
/// <summary>
@ -31,11 +31,11 @@ namespace OpenAuth.Repository.Domain
/// </summary>
public int? TaskType { get; set; }
public string TaskAirLineName { get; set; }
public string TaskDronePortName { get; set; }
/// <summary>
/// 执行机场
/// </summary>
@ -81,7 +81,7 @@ namespace OpenAuth.Repository.Domain
/// </summary>
public string AirLineId { get; set; }
public long CreateId { get; set; }
public long? CreateId { get; set; }
public DateTime? CreateTime { get; set; }
/// <summary>
@ -130,22 +130,34 @@ namespace OpenAuth.Repository.Domain
/// 已上传媒体数量
/// </summary>
public int? UploadedFileCount { get; set; }
/// <summary>
/// 计划id
/// </summary>
public string FlightId { get; set; }
// 飞行任务失败原因
public string? Reason { get; set; }
/// <summary>
/// 0-飞行计划 1-手飞任务
/// </summary>
public int? FlightTaskType { get; set; }
/// <summary>
/// 省任务detail id
/// </summary>
public string ExternalTaskId { get; set; }
/// <summary>
/// 断点信息
/// </summary>
public string BreakPoint { get; set; }
[SugarColumn(IsIgnore = true)]
public string AlgoInstanceId { get; set; }
[SugarColumn(IsIgnore = true)]
public string WarningTitle { get; set; }
[SugarColumn(IsIgnore = true)]
public string WarningContent { get; set; }
public string PushUrl { get; set; }
[SugarColumn(IsIgnore = true)] public string AlgoInstanceId { get; set; }
[SugarColumn(IsIgnore = true)] public string WarningTitle { get; set; }
[SugarColumn(IsIgnore = true)] public string WarningContent { get; set; }
}
}

@ -84,6 +84,8 @@ namespace OpenAuth.Repository
public SugarRepositiry<LasaMediaFile> LasaMediaFile { get; set; }
public SugarRepositiry<LasaAlgorithmsRepository> LasaAlgorithmsRepository { get; set; }
public SugarRepositiry<LasaModelLabel> LasaModelLabel { get; set; }
public SugarRepositiry<LasaAiAchievement> LasaAiAchievement { get; set; }
public SugarRepositiry<LasaAiAchievementDetail> LasaAiAchievementDetail { get; set; }
public SugarRepositiry<DbfineInfo> DbfineInfo { get; set; }
public SugarRepositiry<SysOpenJob> SysOpenJob { get; set; }

@ -41,4 +41,6 @@ public class AiAchievementController : ControllerBase
{
return await _app.GetAiAchievement(id);
}
// 根据时间查询
}

@ -1,11 +1,13 @@
using System.Text;
using Infrastructure;
using Infrastructure;
using Infrastructure.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using OpenAuth.App.ServiceApp.Algo;
using OpenAuth.App.ServiceApp.Algo.Request;
using OpenAuth.App.ServiceApp.Request;
using OpenAuth.WebApi.Model.RabbitMQService;
using System.Text;
namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
@ -20,9 +22,11 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
private readonly string sk = "cf83a12caa155b994eb34fa9";
private readonly string baseUrl = "https://123.132.248.154:6405";
private readonly RabbitMqListenerService _listener;
public DaHuaAiController(RabbitMqListenerService listener)
private readonly DaHuaAiApp _app;
public DaHuaAiController(RabbitMqListenerService listener, DaHuaAiApp app)
{
_listener = listener;
_app = app;
}
private async Task<Response<string>> PostJsonAsync(string path, object body)
{
@ -213,5 +217,40 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
return PostJsonAsync($"/processing/inner/play/channel/{id}?streamType={streamType}&type={type}", new { });
}
/// <summary>
/// 大华数据分析
/// </summary>
/// <param name="firstId"></param>
/// <param name="secondId"></param>
[HttpPost]
[AllowAnonymous]
public async void BehaviorAlarm(string firstId, string secondId)
{
var mq = await RabbitMqSender.CreateAsync("123.132.248.154", 9103, "DHCloudg1", "Cloud0#4fCraQrm");
var dataList = await _app.BehaviorAlarm(firstId, secondId);
foreach (var data in dataList.Result)
{
await mq.SendAsync("event.capturePic.1.sdhc04", JsonConvert.SerializeObject(data));
}
}
/// <summary>
/// 测试插入数据
/// </summary>
/// <param name="info"></param>
[HttpPost]
[AllowAnonymous]
public async void AddBehaviorAlarm(string info)
{
await _app.AddDaHuaImg(info);
}
#region 接收本地模型数据
[HttpPost]
[AllowAnonymous]
public async Task<Response<bool>> AddImg([FromBody] AiImgReq request)
{
return await _app.AddImg(request.taskid, request.path, request.aiid,request.drone_info, request.tag);
}
#endregion
}
}

@ -10,6 +10,7 @@ using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository.Domain;
using Org.BouncyCastle.Ocsp;
using System.Text;
using Newtonsoft.Json;
namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
@ -305,25 +306,47 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
var result = new ReciveData<string>();
if (Request.Headers.TryGetValue("x-lc-token", out var tokenValue))
{
// todo 完成后,需要恢复
//var tokenflag = _helper.Verify(tokenValue);
var tokenflag = true;
var tokenflag = _helper.Verify(tokenValue);
//var tokenflag = true;
if (tokenflag)
{
try
{
var data = await _app.GetDroneStatus(deviceid);
result.data = data.Result;
result.code = data.Code;
result.message = data.Message;
var inResult = await _app.GetDroneStatus(deviceid);
var response = new ResData();
if (inResult.code == 200)
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(result));
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态成功!";
response.Code = 200;
response.Secret = xLcSecret;
}
else
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(" ");
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态失败!";
response.Code = 500;
response.Secret = xLcSecret;
}
result.data = inResult.Result;
result.code = inResult.Code;
result.message = inResult.Message;
result.traceid = Guid.NewGuid().ToString();
Response.Headers.Add("x-lc-secret", data.Secret);
Response.Headers.Add("x-lc-secret", inResult.Secret);
}
catch (Exception ex)
{
result.code = 200;
result.message = "error";
result.traceid = Guid.NewGuid().ToString();
}
return result;
@ -339,26 +362,7 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
}
}
/// <summary>
/// 无人机状态上报
/// </summary>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public async Task<Response<string>> reportDroneStatus([FromBody] List<AirPortStatusApply> req)
{
var result = new Response<string>();
try
{
result = await _app.reportDroneStatus(req);
}
catch (Exception ex)
{
result.Code = 500;
result.Message = ex.Message;
}
return result;
}
/// <summary>
/// 无人机任务进度查询
/// </summary>

@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenAuth.App.ServiceApp;
using OpenAuth.App.ServiceApp.AirLine.Request;
using OpenAuth.App.ServiceApp.FlyTask.Request;
using OpenAuth.App.ServiceApp.FlyTask.Response;
using OpenAuth.App.ServiceApp.Request;
using OpenAuth.App.ServiceApp.Response;
@ -837,27 +838,92 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
return await _app.ListMediaFolder(workspaceId);
}
/// <summary>
/// 媒体库新建文件夹记录
/// </summary>
/// <returns></returns>
/// todo 应该传什么参数?
[HttpPost]
public async Task<Response<bool>> CreateMediaFolder(string name ,string parentKey)
public async Task<Response<bool>> CreateMediaFolder(string name, string parentKey)
{
return await _app.CreateMediaFolder(name,parentKey);
return await _app.CreateMediaFolder(name, parentKey);
}
#endregion
/// <summary>
/// 媒体保存测试
/// </summary>
/// <param name="msg"></param>
/// <param name="msg">mqtt message</param>
/// <returns></returns>
[HttpPost]
public async Task<Response<bool>> Test1111(string msg)
{
return await _app.Test1111(msg);
}
/// <summary>
/// 手飞任务保存接口
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
[HttpPost]
public async Task<Response<dynamic>> SaveHandFlyTask([FromBody] LasaHandFlyTask task)
{
return await _app.SaveHandFlyTask(task);
}
/// <summary>
/// 开启智能Ai巡检
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
[HttpPost]
public async Task<Response<bool>> CallAiModel([FromBody] CallAiModel req)
{
return await _app.CallAiModel(req);
}
/// <summary>
/// 结束手飞任务智能巡检
/// </summary>
/// <param name="taskid"></param>
/// <returns></returns>
[HttpPost]
public async Task<Response<bool>> EndAiInspection(string taskid)
{
return await _app.EndAiInspection(taskid);
}
/// <summary>
/// 结束手飞任务
/// </summary>
/// <param name="taskid"></param>
/// <returns></returns>
[HttpPost]
public async Task<Response<bool>> EndHandFlyTask(string taskid)
{
return await _app.EndHandFlyTask(taskid);
}
[HttpPost]
[AllowAnonymous]
public async Task<Response<bool>> TestZhiBao(string message)
{
return await _app.TestZhiBao(message);
}
[HttpPost]
[AllowAnonymous]
public async void CloseZhibo(string videoId)
{
_app.CloseZhibo(videoId);
}
[HttpGet]
public async Task<Response<dynamic>> GetLastHandFlyTask()
{
return await _app.GetLastHandFlyTask();
}
}
}

@ -1,6 +1,9 @@
using System.Text;
using DocumentFormat.OpenXml.Spreadsheet;
using OpenAuth.App.ServiceApp.Algo;
using OpenAuth.WebApi.Model.mqtt;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
namespace OpenAuth.WebApi.Model.RabbitMQService
{
@ -12,8 +15,12 @@ namespace OpenAuth.WebApi.Model.RabbitMQService
private readonly Dictionary<string, string> _queueRoutingMap = new();
private readonly object _lock = new();
private readonly List<QueueBinding> _bindings = new();
public RabbitMqListenerService()
{
private readonly ILogger<RabbitMqListenerService> _logger;
private DaHuaAiApp _app;
public RabbitMqListenerService(ILogger<RabbitMqListenerService> logger, DaHuaAiApp app)
{
_logger = logger;
_app = app;
_factory = new ConnectionFactory
{
HostName = "123.132.248.154",
@ -45,22 +52,57 @@ namespace OpenAuth.WebApi.Model.RabbitMQService
_connection = await _factory.CreateConnectionAsync(stoppingToken);
_channel = await _connection.CreateChannelAsync();
//await BindQueueAsync(_channel, "processing_event", "topic", "event.trafficJunction.1.sdhc");
foreach (var binding in _bindings)
var queueOk = await _channel.QueueDeclareAsync(queue: "",
durable: false,
exclusive: true,
autoDelete: true);
//await _channel.QueueBindAsync(queueOk.QueueName, "processing_event", "event.eventNotAlarm.picture.1.#");
await _channel.QueueBindAsync(queueOk.QueueName, "processing_event", "event.behaviorAlarm.picture.1.#");
var consumer = new AsyncEventingBasicConsumer(_channel);
consumer.ReceivedAsync += async (sender, ea) =>
{
await BindQueueAsync(_channel, binding.Exchange, binding.ExchangeType, binding.RoutingKey);
}
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($"接收数据[processing_event]: {message}");
// Exchange 来做不同处理
switch (ea.Exchange)
{
case "processing_event":
await _app.AddDaHuaImg(message);
break;
case "thing_event":
Console.WriteLine($"[thing_event] {message}");
break;
default:
Console.WriteLine($"[Other:{ea.RoutingKey}] {message}");
break;
}
await Task.Yield();
};
await _channel.BasicConsumeAsync("", autoAck: true, consumer);
//foreach (var binding in _bindings)
//{
// await BindQueueAsync(_channel, binding.Exchange, binding.ExchangeType, binding.RoutingKey);
//}
}
private async Task BindQueueAsync(IChannel channel, string exchange, string exchangeType, string routingKey)
{
await channel.ExchangeDeclareAsync(exchange, exchangeType, durable: true);
await channel.QueueDeclareAsync("", durable: true, exclusive: false, autoDelete: false);
await channel.QueueBindAsync("", exchange, routingKey);
//await channel.ExchangeDeclareAsync(exchange, exchangeType, durable: true);
//await channel.QueueDeclareAsync("", durable: true, exclusive: false, autoDelete: false);
//var queueOk = await _channel.QueueDeclareAsync(queue: "",
// durable: false,
// exclusive: true,
// autoDelete: true);
//await channel.QueueBindAsync(queueOk.QueueName, exchange, routingKey);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (sender, ea) =>
{
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($"[processing_event]: {message}");
@ -82,7 +124,7 @@ namespace OpenAuth.WebApi.Model.RabbitMQService
};
await channel.BasicConsumeAsync("", autoAck: true, consumer);
}
}
//public async Task AddListenerAsync(string exchange, string exchangeType, string routingKey)
//{
// _connection = await _factory.CreateConnectionAsync();

@ -0,0 +1,75 @@
using RabbitMQ.Client;
using System.Text;
namespace OpenAuth.WebApi.Model.RabbitMQService
{
public class RabbitMqSender : IAsyncDisposable
{
private readonly IConnection _connection;
private readonly IChannel _channel;
private const string ExchangeName = "mps_event";
private const string ExchangeType = "topic";
public RabbitMqSender(IConnection connection, IChannel channel)
{
_connection = connection;
_channel = channel;
}
public static async Task<RabbitMqSender> CreateAsync(string hostName, int port, string userName, string password)
{
var factory = new ConnectionFactory()
{
HostName = hostName,
UserName = userName,
Password = password,
Port = port,
AutomaticRecoveryEnabled = true, // 自动重连
NetworkRecoveryInterval = TimeSpan.FromSeconds(5),
};
var connection = await factory.CreateConnectionAsync();
var channel = await connection.CreateChannelAsync();
await channel.ExchangeDeclareAsync(exchange: ExchangeName, type: ExchangeType, durable: true);
//await channel.QueueDeclareAsync("sdhc", durable: true, exclusive: false, autoDelete: false);
var queueOk = await channel.QueueDeclareAsync(queue: "",
durable: false,
exclusive: true,
autoDelete: true);
await channel.QueueBindAsync(queueOk.QueueName, "mps_event", "event.capturePic.1.sdhc04");
return new RabbitMqSender(connection, channel);
}
public async Task SendAsync(string routeKey, string message)
{
var body = Encoding.UTF8.GetBytes(message);
var properties = new BasicProperties()
{
Persistent = true
};
// 监听 BasicReturn 事件
_channel.BasicReturnAsync += (sender, args) =>
{
var returnedMessage = Encoding.UTF8.GetString(args.Body.ToArray());
Console.WriteLine($"[BasicReturn] Message returned: {returnedMessage}");
Console.WriteLine($"ReplyCode: {args.ReplyCode}, ReplyText: {args.ReplyText}");
Console.WriteLine($"Exchange: {args.Exchange}, RoutingKey: {args.RoutingKey}");
return Task.CompletedTask;
};
await _channel.BasicPublishAsync(exchange: "mps_event",
routingKey: routeKey,
mandatory: true,
basicProperties: properties,
body: body);
Console.WriteLine($"[RabbitMQ] 已发送到routeKey {routeKey}{message}");
}
public async ValueTask DisposeAsync()
{
if (_channel != null)
await _channel.CloseAsync();
if (_connection != null)
await _connection.CloseAsync();
}
}
}

@ -25,6 +25,9 @@
<None Remove="log\**" />
<None Remove="wwwroot\**" />
<EmbeddedResource Include="index.html" />
<None Update="Sqlite.db">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>

Binary file not shown.

@ -184,8 +184,8 @@ namespace OpenAuth.WebApi
#endregion
#region rabbitmq
//services.AddSingleton<RabbitMqListenerService>();
//services.AddHostedService(sp => sp.GetRequiredService<RabbitMqListenerService>());
services.AddSingleton<RabbitMqListenerService>();
services.AddHostedService(sp => sp.GetRequiredService<RabbitMqListenerService>());
#endregion
#region AppSetting
@ -402,7 +402,8 @@ namespace OpenAuth.WebApi
{ ".xls", "application/vnd.ms-excel" },
{ ".pdf", "application/pdf" },
{ ".js","application/javascript" },
{ ".cjs","application/javascript" }
{ ".cjs","application/javascript" },
{ ".pt", "application/octet-stream" },
})
};
app.UseStaticFiles(staticfile);

@ -0,0 +1,47 @@
using OpenAuth.App.ServiceApp.DroneDocking;
namespace OpenAuth.WebApi.SystemTask;
public class DelayedExecutionService : BackgroundService
{
private readonly ILogger<DelayedExecutionService> _logger;
private readonly DroneDockApp _droneDockApp;
public DelayedExecutionService(ILogger<DelayedExecutionService> logger, DroneDockApp droneDockApp)
{
_logger = logger;
_droneDockApp = droneDockApp;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("定时任务已启动将每5秒执行一次");
while (!stoppingToken.IsCancellationRequested)
{
try
{
await PerformDelayedTask();
// 等待5秒
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
catch (OperationCanceledException)
{
_logger.LogInformation("定时任务被取消");
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "定时任务执行时发生错误");
// 即使出错也继续下一次执行
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
}
}
private async Task PerformDelayedTask()
{
await _droneDockApp.ReportDroneStatus();
await Task.CompletedTask;
}
}

@ -84,7 +84,10 @@
},
"DroneDocking": {
"Url": "https://wp.tianmu.cloud:5443/zhcfzx",
//"DbFile": "D:\\dkongtaishiganzhi.db",
"DbFile": "D:\\"
"DbFile": "Sqlite.db"
},
"AIModelApi":{
"Url": "http://192.168.10.131:9025",
"PushUrl":"rtmp://192.168.3.17:1935/live/11"
}
}

Loading…
Cancel
Save