zhangbin 3 months ago
commit 872b71253a

@ -15,7 +15,7 @@ public class GatewayManager
/// <summary>
/// 下发任务 down(向设备端发布消息) flighttask_prepare(method) thing/product/{gateway_sn}/services(topic)
/// </summary>
public static string FlightTaskPrepare = TopicConst.ThingModelPre + TopicConst.Product + "%s" + TopicConst.ServicesSuffix;
public static string FlightTaskPrepare = TopicConst.ThingModelPre + TopicConst.Product + "{0}" + TopicConst.ServicesSuffix;
public GatewayManager(string gatewaySn, string droneSn, GatewayType gatewayType)
{

@ -1,4 +1,5 @@
using Infrastructure.Helpers;
using Infrastructure.Extensions;
using Infrastructure.Helpers;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Minio;
@ -13,6 +14,7 @@ public class MinioService
private IMinioClient _minioClient;
public string _bucketName;
public string endPoint;
public bool UseSSL;
public MinioService()
{
@ -33,6 +35,7 @@ public class MinioService
var configuration = builder.Build();
_bucketName = configuration["Minio:BucketName"];
endPoint = configuration["Minio:Endpoint"];
UseSSL = configuration["Minio:UseSSL"].ToBool();
_minioClient = new MinioClient()
.WithEndpoint(endPoint)
.WithCredentials(configuration["Minio:AccessKey"], configuration["Minio:SecretKey"])
@ -181,7 +184,8 @@ public class MinioService
await _minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
}
var objectName = $"{GenerateId.GenerateOrderNumber()}.wpml";
var suffix = Path.GetExtension(file.FileName);
var objectName = $"{GenerateId.GenerateOrderNumber()}{suffix}";
// 使用内存流上传
using var stream = new MemoryStream();
await file.CopyToAsync(stream);
@ -201,7 +205,7 @@ public class MinioService
.WithContentType("application/octet-stream");
//.WithContentType(file.ContentType);
await _minioClient.PutObjectAsync(putArgs);
return "http://" + endPoint + "/" + bucketName + "/" + objectName;
return UseSSL ? "https://" : "http://" + endPoint + "/" + bucketName + "/" + objectName;
}
catch (Exception ex)
{

@ -1,4 +1,8 @@
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;
@ -77,6 +81,7 @@ public class MqttClientManager
/// <param name="message">json</param>
public async Task PublishAsync(string topic, string message)
{
Console.WriteLine($"Publish: {topic} - {message}");
// MqttChannelAdapter
var mqttMsg = new MqttApplicationMessageBuilder()
.WithTopic(topic)

@ -1,51 +0,0 @@
using System.Text;
using ce.autofac.extension;
using Infrastructure.Cache;
using OpenAuth.WebApi;
using Quartz;
namespace OpenAuth.App.BaseApp.HostedService;
/// <summary>
/// 离线去订阅
/// </summary>
public class GlobalSubscribe : IJob
{
public async Task Execute(IJobExecutionContext context)
{
Console.WriteLine($"running !{DateTime.Now}");
var redisCacheContext = context.JobDetail.JobDataMap.Get("redisCacheContext") as RedisCacheContext;
var serviceProvider = context.JobDetail.JobDataMap.Get("serviceProvider") as IServiceProvider;
var mqttManager = serviceProvider.GetService(typeof(MqttClientManager)) as MqttClientManager;
/*var ioc = IocManager.Instance;
var redisCacheContext = IocManager.Instance.GetService<ICacheContext>();*/
// todo 如果无人机不在线,则订阅
if (redisCacheContext == null) return;
var keys = redisCacheContext.GetAllKeys("online:*");
foreach (var redisKey in keys)
{
// todo 取得sn值
// todo 取得设备信息
// todo
// todo 需要判断是不是要订阅,避免重复订阅
if (mqttManager != null)
await mqttManager.SubscribeAsync("thing/product/{gateway_sn}/services_reply", async (args) =>
{
var topic = args.ApplicationMessage.Topic;
var payload = args.ApplicationMessage.Payload;
var message = Encoding.UTF8.GetString(payload);
// todo 解析是否是需要的
// flighttask_prepare method
});
//statusSubscribe.subscribe(gateway);
//stateSubscribe.subscribe(gateway, true);
//osdSubscribe.subscribe(gateway, true);
//servicesSubscribe.subscribe(gateway);
//eventsSubscribe.subscribe(gateway, true);
//requestsSubscribe.subscribe(gateway);
//propertySetSubscribe.subscribe(gateway);
}
// todo
return ;
}
}

@ -5,7 +5,7 @@ using Infrastructure.Cache;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenAuth.App.BaseApp.HostedService;
using OpenAuth.App.BaseApp.Subscribe;
using Quartz;
using Quartz.Impl;
@ -32,7 +32,41 @@ namespace OpenAuth.App.HostedService
public Task StartAsync(CancellationToken cancellationToken)
{
var map = new JobDataMap();
_scheduler.Start(cancellationToken);
// 此种方法创建任务,可用构造函数,注入对象
var jobBuilderType = typeof(JobBuilder);
var method = jobBuilderType.GetMethods().FirstOrDefault(
x => x.Name.Equals("Create", StringComparison.OrdinalIgnoreCase) &&
x.IsGenericMethod && x.GetParameters().Length == 0)
?.MakeGenericMethod(typeof(GlobalSubscribe));
var jobBuilder = (JobBuilder)method.Invoke(null, null);
IJobDetail jobDetail = jobBuilder.WithIdentity("GlobalSubscribe").Build();
var trigger = TriggerBuilder.Create()
.WithIdentity("SubscribeJobTrigger", "GlobalSubscribe")
.WithSimpleSchedule(x => { x.WithIntervalInSeconds(30).RepeatForever(); })
.Build();
//todo 临时注销
//_scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);
var method1 = jobBuilderType.GetMethods().FirstOrDefault(
x => x.Name.Equals("Create", StringComparison.OrdinalIgnoreCase) &&
x.IsGenericMethod && x.GetParameters().Length == 0)
?.MakeGenericMethod(typeof(ConfigSubscribe));
var jobBuilder1 = (JobBuilder)method1.Invoke(null, null);
IJobDetail jobDetail1 = jobBuilder1.WithIdentity("ConfigSubscribe").Build();
var bootTrigger = TriggerBuilder.Create()
.WithIdentity("bootTrigger")
.StartNow()
.WithSimpleSchedule(x => x.WithRepeatCount(0)).Build();
_scheduler.ScheduleJob(jobDetail1, bootTrigger, cancellationToken);
/*var map = new JobDataMap();
map.Put("redisCacheContext", _serviceProvider.GetService<ICacheContext>());
map.Put("ServiceProvider", _serviceProvider);
var job = JobBuilder.Create<GlobalSubscribe>().UsingJobData(map)
@ -40,13 +74,13 @@ namespace OpenAuth.App.HostedService
//创建一个触发条件
var trigger = TriggerBuilder.Create()
.WithIdentity("SubscribeJobTrigger", "GlobalSubscribe")
.WithSimpleSchedule(x => { x.WithIntervalInSeconds(3).RepeatForever(); })
.WithSimpleSchedule(x => { x.WithIntervalInSeconds(30).RepeatForever(); })
.Build();
var onceTrigger = TriggerBuilder.Create()
.WithIdentity("onceTrigger")
.WithSimpleSchedule(x => x.WithRepeatCount(0)).Build();
_scheduler.Start(cancellationToken);
_scheduler.ScheduleJob(job, trigger, cancellationToken);
_scheduler.ScheduleJob(job, trigger, cancellationToken);*/
var result = _openJobApp.StartAll();
return result;
}

@ -0,0 +1,677 @@
using System.Dynamic;
using System.Text;
using Infrastructure.Cache;
using Infrastructure.CloudSdk.wayline;
using Newtonsoft.Json;
using OpenAuth.App.ServiceApp;
using OpenAuth.Repository.Domain;
using OpenAuth.WebApi;
using Quartz;
using SqlSugar;
namespace OpenAuth.App.BaseApp.Subscribe;
public class ConfigSubscribe : IJob
{
private readonly MqttClientManager mqttClientManager;
private readonly ISqlSugarClient sqlSugarClient;
private readonly RedisCacheContext redisCacheContext;
private readonly ManageApp manageApp;
public ConfigSubscribe(MqttClientManager mqttClientManager, ISqlSugarClient sqlSugarClient,
ICacheContext redisCacheContext, ManageApp manageApp)
{
this.mqttClientManager = mqttClientManager;
this.sqlSugarClient = sqlSugarClient;
this.redisCacheContext = redisCacheContext as RedisCacheContext;
this.manageApp = manageApp;
}
private async Task Subscribe()
{
string gatewaySn = "8UUXN5400A079H";
await mqttClientManager
.SubscribeAsync($"thing/product/{gatewaySn}/services_reply",
async (args) => await HandleTopic(gatewaySn, args.ApplicationMessage.Topic,
Encoding.UTF8.GetString(args.ApplicationMessage.Payload)));
await mqttClientManager
.SubscribeAsync($"thing/product/{gatewaySn}/events",
async (args) => await HandleTopic(gatewaySn, args.ApplicationMessage.Topic,
Encoding.UTF8.GetString(args.ApplicationMessage.Payload)));
}
public async Task Execute(IJobExecutionContext context)
{
await Subscribe();
}
// todo 暂时不使用
public static readonly string[] TopicList =
{
"thing/product/**/osd",
"thing/product/**/state",
"thing/product/**/services_reply",
"thing/product/**/events",
"thing/product/**/requests",
"sys/product/**/status",
"thing/product/**/property/set_reply",
"thing/product/**/drc/up"
};
private async Task HandleTopic(string sn, string topic, string message)
{
/*
thing/product/{device_sn}/osd properties
thing/product/{device_sn}/state properties
thing/product/{gateway_sn}/services_reply service 线
thing/product/{gateway_sn}/events
SD
thing/product/{gateway_sn}/requests
sys/product/{gateway_sn}/status 线
thing/product/{gateway_sn}/property/set_reply
thing/product/{gateway_sn}/drc/up DRC */
// thing/product/8UUXN5400A079H/requests
if (topic.Equals("thing/product/8UUXN5400A079H/requests"))
{
Console.WriteLine("收到的资源请求-未处理字符串");
}
var tempStr = topic.Replace(sn, "*");
if (tempStr.Equals("thing/product/*/requests"))
{
Console.WriteLine("收到的资源请求");
}
//Console.WriteLine($"成功调用主题 [{topic}] 的消息: {message}");
// 主题方法
var result = JsonConvert.DeserializeObject<TopicServicesRequest<dynamic>>(message);
var method = result.method;
var data = result.data;
var hasProperty = false;
foreach (var property in data.GetType().GetProperties())
{
if (property.Name != "result") continue;
hasProperty = true;
break;
}
long code = 0;
if (hasProperty)
{
code = data.result;
}
switch (tempStr)
{
case "thing/product/*/requests":
//{"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"}
// todo 处理资源获取请求
switch (method)
{
case "flighttask_resource_get":
Console.WriteLine($"获取资源请求:{JsonConvert.SerializeObject(data)}");
var flightId = data.flight_id;
LasaTaskAssign taskAssign =
manageApp.GetTaskAssignByBidAndTidAndFlightId(result.bid, result.tid, flightId);
var flightTaskResourceGetTopic = $"thing/product/{sn}/requests_reply";
dynamic outData = new ExpandoObject();
var outRequest = new TopicServicesRequest<object>()
{
method = "flighttask_resource_get",
tid = result.tid,
bid = result.bid,
timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
data = outData
};
outData.result = 0;
outData.output = new
{
file = new
{
fingerprint = taskAssign.Md5,
url = taskAssign.Wpml
}
};
await mqttClientManager.PublishAsync(flightTaskResourceGetTopic,
JsonConvert.SerializeObject(outRequest));
break;
default:
Console.WriteLine($"未知请求:{message}");
break;
}
break;
// thing/product/8UUXN5400A079H/events
// {"bid":"0ebc789e-7f06-4830-a58a-8c4753cd493c",
// "data":{"output":{"ext":{"current_waypoint_index":0,
// "flight_id":"d6c00cc5-ec59-4bab-8508-fcb259f00a60",
// "media_count":0,"track_id":"","wayline_id":65535,"wayline_mission_state":2},
// "progress":{"current_step":36,"percent":15},"status":"failed"},"result":314013},
// "method":"flighttask_progress","need_reply":1,"tid":"84b048f7-43db-41c5-86c5-8938dc446ea4","timestamp":1750411329943,"gateway":"8UUXN5400A079H"}
case "thing/product/*/events":
if (method.Equals("flighttask_progress"))
{
// todo 处理航线进度 ,也有可能是失败
if (code != 0)
{
Console.WriteLine($"航线进度错误信息:{ErrorMap[code]}");
}
}
break;
// todo
// 任务资源处理
// 航线进度处理
// 任务取消 thing/product/*/services_reply
case "thing/product/*/services_reply":
switch (method)
{
case "flighttask_prepare": // 下发任务响应
// 报错处理
Console.WriteLine("处理prepare消息");
var taskAssign = manageApp.GetTaskAssignByBidAndTid(result.bid, result.tid);
if (code == 0)
{
if (taskAssign == null) return; // 不存在不操作
var flightId = taskAssign.FlightId;
var request = new TopicServicesRequest<object>();
dynamic data1 = new ExpandoObject();
data1.flight_id = flightId;
request.SetMethod("flighttask_execute")
.SetTid(Guid.NewGuid().ToString())
.SetBid(Guid.NewGuid().ToString())
.SetTimestamp(DateTimeOffset.Now.ToUnixTimeMilliseconds())
.SetData(data1);
// 任务执行
await mqttClientManager.PublishAsync($"thing/product/{sn}/services",
JsonConvert.SerializeObject(request));
}
else
{
// 错误处理
var errorMsg = ErrorMap[code];
var taskAssignRecord = new LasaTaskAssign()
{
Id = taskAssign.Id,
Reason = errorMsg,
Status = 2
};
await sqlSugarClient.Updateable(taskAssignRecord).ExecuteCommandAsync();
}
break;
case "flighttask_execute": // 执行任务响应
if (code != 0)
{
var errorMsg = ErrorMap[code];
Console.WriteLine($"任务失败: 错误码 {code} 错误信息 {errorMsg}");
// todo 任务执行失败
}
else
{
Console.WriteLine($"flighttask_execute 任务成功");
}
break;
}
break;
default:
Console.WriteLine($"未进入主题处理");
break;
}
}
public static Dictionary<long, string> ErrorMap = new()
{
{ 312014, "设备升级中,请勿重复操作" },
{ 312015, "机场:{dock_org_name},业务繁忙无法进行设备升级,请等待机场处于空闲中后再试" },
{ 312016, "升级失败,机场和飞行器图传链路异常,请重启机场和飞行器后重试" },
{ 312022, "飞行器开机失败或未连接,请检查飞行器是否在舱内,是否安装电池,机场和飞行器是否已对频" },
{ 312023, "推杆闭合失败无法升级飞行器,请检查急停按钮是否被按下,推杆是否有异物卡住" },
{ 312027, "升级失败,机场未检测到飞行器" },
{ 312028, "升级失败,设备升级过程中设备被重启" },
{ 312029, "设备重启中无法进行设备升级,请等待设备重启完成后重试" },
{ 312030, "升级失败,飞行器增强图传开启后无法升级,请关闭飞行器增强图传后重试" },
{ 312704, "设备电量过低请充电至20%以上后重试" },
{ 314000, "设备当前无法支持该操作,建议检查设备当前工作状态" },
{ 314001, "飞行任务下发失败,请稍后重试" },
{ 314002, "飞行任务下发失败,请稍后重试" },
{ 314003, "航线文件格式不兼容,请检查航线文件是否正确" },
{ 314005, "飞行任务下发失败,请稍后重试或重启机场后重试" },
{ 314006, "飞行器初始化失败,请重启机场后重试" },
{ 314007, "机场传输航线至飞行器失败,请重启机场后重试" },
{ 314008, "飞行器起飞前准备超时,请重启机场后重试" },
{ 314009, "飞行器初始化失败,请重启机场后重试" },
{ 314010, "航线执行失败,请重启机场后重试" },
{ 314011, "机场系统异常,无法获取飞行任务执行结果" },
{ 314012, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试" },
{ 314013, "飞行任务下发失败,机场无法获取到本次飞行任务的航线,无法执行飞行任务,请稍后重试" },
{ 314014, "机场系统异常,飞行任务执行失败,请稍后重试" },
{ 314015, "机场传输精准复拍航线至飞行器失败,无法执行飞行任务,请稍后重试或重启机场后重试" },
{ 314016, "航线文件解析失败,无法执行飞行任务,请检查航线文件" },
{ 314017, "航线文件解析失败,请检查航线后再试" },
{ 314018, "飞行器RTK定位异常无法执行飞行任务请稍后重试或重启机场后重试" },
{ 314019, "飞行器RTK收敛失败无法执行飞行任务请稍后重试或重启机场后重试" },
{ 314020, "飞行器不在停机坪正中间或飞行器朝向不正确,无法执行飞行任务,请检查飞行器位置和朝向" },
{ 314021, "飞行器RTK定位异常无法执行飞行任务请稍后重试或重启机场后重试" },
{ 314024, "进离场航线下发失败,请稍后重试或重启机场后重试" },
{ 314025, "RTK收敛超时用户手动取消任务" },
{ 314200, "任务失败,由于机场网络断开,飞行器已自动返航,请确保机场已连接网络后再试" },
{ 315000, "机场通信异常,请重启机场后重试" },
{ 315001, "机场通信异常请远程开启飞机并等待1min后再次下发任务重试" },
{ 315002, "机场通信异常,请重启机场后重试" },
{ 315003, "机场通信异常,请重启机场后重试" },
{ 315004, "任务失败,请等待两个机场都空闲后,再次下发任务重试" },
{ 315005, "机场通信异常,请重启机场后重试" },
{ 315006, "机场通信异常,请重启机场后重试" },
{ 315007, "机场通信异常,请将机场升级到最新版本或重启机场后重试" },
{ 315008, "降落机场和起飞机场标定信息不一致,请确认两个机场均链路通畅且使用了相同的网络信息标定" },
{ 315009, "机场通信异常,请重启机场后重试" },
{ 315010, "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后" },
{ 315011, "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后" },
{ 315012, "无法停止飞行任务,请稍后重试,如果仍报错请联系大疆售后" },
{ 315013, "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后" },
{ 315014, "当前任务类型不支持设置返航点" },
{ 315015, "返航点设置失败,请稍后重试,如果仍报错请联系大疆售后" },
{ 315016, "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后" },
{ 315017, "飞行任务下发失败,请稍后重试,如果仍报错请联系大疆售后" },
{ 315018, "任务失败,请等待两个机场都空闲后,再次下发任务重试" },
{ 315019, "设备部署位置不佳,无法执行蛙跳任务,请选择其它机场再试" },
{ 315050, "机场系统异常,请重启机场后重试" },
{ 315051, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315052, "机场位置未收敛,请等待一段时间后重试" },
{ 315053, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315054, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315055, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315056, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315057, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315058, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315059, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315060, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315061, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315062, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315063, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315064, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 315065, "任务失败,请重启机场并再次下发任务后重试,如果仍报错请联系大疆售后" },
{ 316001, "飞行器参数配置失败,请重启机场后重试" },
{ 316002, "飞行器参数配置失败,请重启机场后重试" },
{ 316003, "飞行器参数配置失败,请重启机场后重试" },
{ 316004, "飞行器参数配置失败,请重启机场后重试" },
{ 316005, "飞行器RTK收敛失败无法执行飞行任务请重启机场后重试" },
{ 316006, "任务超时,飞行器已丢失或降落时机场未开启舱盖或展开推杆,飞行器无法降落回机场,请尽快至机场部署现场检查飞行器状况" },
{ 316007, "飞行器初始化失败,请重启机场后重试" },
{ 316008, "机场获取飞行器控制权失败,无法执行飞行任务,请确认遥控器未锁定控制权" },
{ 316009, "飞行器电量低于30%无法执行飞行任务请充电后重试建议电量≥50%" },
{ 316010, "机场未检测到飞行器,无法执行飞行任务,请检查舱内是否有飞行器,机场与飞行器是否已对频,或重启机场后重试" },
{ 316011, "飞行器降落位置偏移过大,请检查飞行器是否需要现场摆正" },
{ 316012, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试" },
{ 316013, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试" },
{ 316014, "飞行器起飞前准备失败,无法执行飞行任务,请重启机场后重试" },
{ 316015, "飞行器RTK收敛位置距离机场过远无法执行飞行任务请重启机场后重试" },
{ 316016, "飞行器降落至机场超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内" },
{ 316017, "获取飞行器媒体数量超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内" },
{ 316018, "飞行任务执行超时,可能是机场与飞行器断连导致,请通过直播查看飞行器是否降落至舱内" },
{ 316019, "机场系统错误,无法执行飞行任务,请稍后重试" },
{ 316020, "飞行器使用的RTK信号源错误请稍后重试" },
{ 316021, "飞行器RTK信号源检查超时请稍后重试" },
{ 316022, "飞行器无法执行返航指令,请检查飞行器是否已开机,机场与飞行器是否已断连,请确认无以上问题后重试" },
{ 316023, "飞行器无法执行返航指令飞行器已被B控接管请在B控操控飞行器或关闭B控后重试" },
{ 316024, "飞行器执行返航指令失败,请检查飞行器是否已起飞,确认飞行器已起飞后请重试" },
{ 316025, "飞行器参数配置失败,请稍后重试或重启机场后重试" },
{ 316026, "机场急停按钮被按下,无法执行飞行任务,请释放急停按钮后重试" },
{ 316027, "飞行器参数配置超时,请稍后重试或重启机场后重试" },
{ 316029, "机场急停按钮被按下,飞行器将飞往备降点降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场" },
{ 316032, "获取电池数据超时,请稍后重试或重启飞行器后重试" },
{ 316033, "飞行器电池循环次数过高,为保证飞行安全,已自动终止任务,建议更换该电池" },
{ 316034, "无法起飞,飞行器固件版本与机场固件版本不匹配,为保证飞行安全请升级固件后再试" },
{ 316035, "进离场航线下发失败,请确保设备固件为最新版本后重新下发任务,如果持续报错,请联系大疆售后。" },
{ 316050, "飞行器因电量过低在舱外降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场" },
{ 316051, "飞行任务异常,飞行器在舱外降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场" },
{ 316052, "飞行任务异常,飞行器将飞往备降点降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场" },
{ 316053, "用户已操控飞行器降落,请立即检查飞行器是否已安全降落并将飞行器放回至机场" },
{ 316100, "获取相机概要信息失败,请重试" },
{ 316101, "设置相机为单拍模式失败,请重试" },
{ 316102, "关闭相机水印失败,请重试" },
{ 316103, "设置测光模式到平均测光失败,请重试" },
{ 316104, "切换镜头到广角镜头失败,请重试" },
{ 316105, "设置相机存储照片失败,请重试" },
{ 316106, "红外变焦倍数设置失败,请重试" },
{ 316107, "照片尺寸设置4k失败请重试" },
{ 316108, "设置照片存储格式为jpeg格式失败请重试" },
{ 316109, "关闭相机畸变矫正失败,请重试" },
{ 316110, "打开相机机械快门失败,请重试" },
{ 316111, "设置对焦模式失败,请重试" },
{ 317001, "获取飞行器媒体文件数量失败,请重启机场后重试" },
{ 317002, "飞行器存储格式化失败,飞行器未开机、未连接或未检测到相机,请确认无以上问题后重试,或重启飞行器后重试" },
{ 317003, "飞行器存储格式化失败,请重启飞行器后重试" },
{ 317004, "机场媒体文件格式化失败,请稍后重试或重启机场后重试" },
{ 317005, "飞行器结束录像失败,本次飞行任务的媒体文件可能无法上传" },
{ 317006, "无法格式化,请等待当前飞行器媒体文件下载完成后再试" },
{ 317007, "获取媒体文件数量失败,请稍后重试,如本架次任务有媒体文件且持续报错可联系大疆售后" },
{ 319001, "机场作业中或设备异常反馈上传日志中,无法执行飞行任务,请等待当前飞行任务或操作执行完成后重试" },
{ 319002, "机场系统运行异常,请重启机场后重试" },
{ 319003, "机场系统运行异常,请重新下发任务" },
{ 319004, "飞行任务执行超时,已自动终止本次飞行任务" },
{ 319005, "云端与机场通信异常,无法执行飞行任务" },
{ 319006, "取消飞行任务失败,飞行任务已经在执行中" },
{ 319007, "修改飞行任务失败,飞行任务已经在执行中" },
{ 319008, "机场时间与云端时间不同步,机场无法执行飞行任务" },
{ 319009, "飞行任务下发失败,请稍后重试或重启机场后重试" },
{ 319010, "机场固件版本过低,无法执行飞行任务,请升级机场固件为最新版本后重试" },
{ 319015, "机场正在初始化中,无法执行飞行任务,请等待机场初始化完成后重试" },
{ 319016, "机场正在执行其他飞行任务,无法执行本次飞行任务" },
{ 319017, "机场正在处理上次飞行任务媒体文件,无法执行本次飞行任务,请稍后重试" },
{ 319018, "机场正在自动导出日志中(设备异常反馈),无法执行飞行任务,请稍后重试" },
{ 319019, "机场正在拉取日志中(设备异常反馈),无法执行飞行任务,请稍后重试" },
{ 319020, "航线中断失败,请稍后重试" },
{ 319021, "退出远程控制失败,请稍后重试" },
{ 319022, "指点飞行失败,请稍后重试" },
{ 319023, "指点飞行停止失败,请稍后重试" },
{ 319024, "一键起飞失败,请稍后重试" },
{ 319025, "机场未准备完成,无法执行云端下发的飞行任务,请稍后重试" },
{ 319026, "飞行器电池电量低于用户设置的任务开始执行的电量,请等待充电完成后再执行飞行任务" },
{ 319027, "机场或飞行器剩余存储容量过低,无法执行飞行任务,请等待媒体文件上传,机场和飞行器存储容量释放后再执行飞行任务" },
{ 319028, "正在更新自定义飞行区" },
{ 319029, "正在更新离线地图" },
{ 319030, "操作失败,无飞行器控制权" },
{ 319031, "控制权异常,请刷新重试" },
{ 319032, "指点飞行失败,请稍后重试" },
{ 319033, "虚拟摇杆操作失败,请稍后重试" },
{ 319034, "虚拟摇杆操作失败,请稍后重试" },
{ 319035, "急停失败,请稍后重试" },
{ 319036, "设备远程调试中,请稍后重试" },
{ 319037, "设备本地调试中,请稍后重试" },
{ 319038, "设备正在升级,请稍后重试" },
{ 319042, "航线恢复失败,请稍后重试" },
{ 319043, "取消返航失败,请稍后重试" },
{ 319044, "航线任务已结束,无法恢复" },
{ 319045, "急停成功,请重新按键操作" },
{ 319046, "无法暂停航线,飞行器尚未进入航线或已退出航线" },
{ 319999, "机场系统运行异常,请重启机场后重试" },
{ 321000, "航线执行异常,请稍后重试或重启机场后重试" },
{ 321004, "航线文件解析失败,无法执行飞行任务,请检查航线文件" },
{ 321005, "航线缺少断点信息,机场无法执行飞行任务" },
{ 321257, "飞行任务已在执行中,请勿重复执行" },
{ 321258, "飞行任务无法终止,请检查飞行器状态" },
{ 321259, "飞行任务未开始执行,无法终止飞行任务" },
{ 321260, "飞行任务未开始执行,无法中断飞行任务" },
{ 321513, "航线规划高度已超过飞行器限高,机场无法执行飞行任务" },
{ 321514, "任务失败,起点或终点位于限远区域的缓冲区内或超过了限远距离" },
{ 321515, "航线穿过限飞区,机场无法执行飞行任务" },
{ 321516, "飞行器飞行高度过低,飞行任务执行被终止" },
{ 321517, "飞行器触发避障,飞行任务执行被终止。为保证飞行安全,请勿用当前航线执行断点续飞任务" },
{ 321519, "飞行器接近限飞区或限远距离自动返航,无法完成航线飞行" },
{ 321523, "飞行器起飞失败,请稍后重试,如果仍报错请联系大疆售后。" },
{ 321524, "飞行器起飞前准备失败,可能是飞行器无法定位或档位错误导致,请检查飞行器状态" },
{ 321528, "触碰自定义飞行区边界,航线任务已暂停" },
{ 321529, "目标点位于禁飞区域或者障碍物内,无法到达,航线任务已暂停,请重新规划后再试" },
{ 321530, "飞行器飞行航线过程中轨迹规划失败,航线任务已暂停" },
{ 321531, "进离场航线执行失败,请联系大疆售后。" },
{ 321532, "进离场航线执行失败,请联系大疆售后。" },
{ 321533, "进离场航线执行失败,请联系大疆售后。" },
{ 321769, "飞行器卫星定位信号差,无法执行飞行任务,请重启机场后重试" },
{ 321770, "飞行器挡位错误,无法执行飞行任务,请重启机场后重试" },
{ 321771, "飞行器返航点未设置,无法执行飞行任务,请重启机场后重试" },
{ 321772, "飞行器电量低于30%无法执行飞行任务请充电后重试建议电量≥50%" },
{ 321773, "飞行器执行飞行任务过程中低电量返航,无法完成航线飞行" },
{ 321775, "飞行器航线飞行过程中失联,无法完成航线飞行" },
{ 321776, "飞行器RTK收敛失败无法执行飞行任务请重启机场后重试" },
{ 321777, "飞行器未悬停,无法开始执行飞行任务" },
{ 321778, "用户使用B控操控飞行器起桨机场无法执行飞行任务" },
{ 321784, "任务过程中遇到大风紧急返航" },
{ 322281, "任务失败,机场执行飞行任务过程被手动打断或异常终止" },
{ 322282, "机场执行飞行任务过程中被中断,飞行器被云端用户或遥控器接管" },
{ 322283, "机场执行飞行任务过程中被用户触发返航,无法完成航线飞行" },
{ 322539, "航线的断点信息错误,机场无法执行飞行任务" },
{ 322563, "航线轨迹生成失败,请检查飞行器视觉镜头是否存在脏污或重启飞行器后再试,如果仍报错请联系大疆售后" },
{ 324012, "日志压缩过程超时,所选日志过多,请减少选择的日志后重试" },
{ 324013, "设备日志列表获取失败,请稍后重试" },
{ 324014, "设备日志列表为空,请刷新页面或重启机场后重试" },
{ 324015, "飞行器已关机或未连接,无法获取日志列表,请确认飞行器在舱内,通过远程调试将飞行器开机后重试" },
{ 324016, "机场存储空间不足,日志压缩失败,请清理机场存储空间或稍后重试" },
{ 324017, "日志压缩失败,无法获取所选飞行器日志,请刷新页面或重启机场后重试" },
{ 324018, "日志文件拉取失败,导致本次设备异常反馈上传失败,请稍后重试或重启机场后重试" },
{ 324019, "因机场网络异常,日志上传失败,请稍后重试。如果连续多次出现该问题,请联系代理商或大疆售后进行网络排障" },
{ 324021, "因机场断电或重启导致日志导出中断,日志导出失败,请稍后重试" },
{ 324030, "因机场网络异常、飞行器图传链路异常等原因,媒体文件暂时无法上传或文件已上传但云端读取失败" },
{ 325001, "云端下发命令不符合格式要求,设备无法执行" },
{ 325003, "指令响应失败,请重试" },
{ 325004, "设备端命令请求已超时,请重试" },
{ 325005, "当前机场无法响应任务,请稍后重试" },
{ 325006, "当前机场启动检查中,请稍后重试" },
{ 325007, "当前机场执行作业任务中,请稍后重试" },
{ 325008, "当前机场处理作业任务结果中,请稍后重试" },
{ 325009, "当前机场执行远程日志导出中,请稍后重试" },
{ 325010, "当前机场更新自定义飞行区中,请稍后重试" },
{ 325011, "当前机场更新离线地图中,请稍后重试" },
{ 325012, "当前飞机未连接,请稍后重试" },
{ 326002, "飞行器未安装DJICellualr模块" },
{ 326003, "飞行器DJICellualr模块中未安装SIM卡" },
{ 326004, "飞行器DJICellualr模块需要强制升级否则无法使用" },
{ 326005, "操作失败增强图传无法建立连接请检查4G信号强度或咨询运营商查询套餐流量和APN设置" },
{ 326006, "增强图传开关切换失败,请稍后重试" },
{ 326008, "机场未安装DJICellualr模块" },
{ 326009, "机场DJICellualr模块中未安装SIM卡" },
{ 326010, "机场DJICellualr模块需要强制升级否则无法使用" },
{ 326103, "当前eSIM正在激活中请稍后再试" },
{ 326104, "当前eSIM正在切换运营商中请稍后再试" },
{ 326105, "DJI增强图传模块正在切换模式中请稍后再试" },
{ 326106, "DJI增强图传模块异常请重启设备后再试如果仍报错请联系大疆售后" },
{ 326107, "请在设备管理>机场>设备运维中激活DJI增强图传模块的eSIM或插入SIM卡后再试" },
{ 327000, "参数设置失败,请稍后重试" },
{ 327001, "参数设置失败,请稍后重试" },
{ 327002, "获取控制权失败,请稍后重试" },
{ 327003, "获取控制权失败,请稍后重试" },
{ 327004, "画面拖动失败,请重试" },
{ 327005, "双击画面归中失败" },
{ 327006, "拍照失败" },
{ 327007, "开始录像失败" },
{ 327008, "停止录像失败" },
{ 327009, "切换相机模式失败" },
{ 327010, "ZOOM相机变焦失败" },
{ 327011, "IR相机变焦失败" },
{ 327012, "获取控制权失败,请稍后重试" },
{ 327013, "参数设置失败,请稍后重试" },
{ 327014, "云台已达限位" },
{ 327015, "直播启动失败,建议刷新直播或重新打开设备小窗" },
{ 327016, "失联动作设置失败,请重试" },
{ 327017, "指点飞行高度设置失败,请重试" },
{ 327018, "指点飞行模式切换失败,请重试" },
{ 327019, "当前状态无法看向标注点" },
{ 327020, "全景拍照停止命令超时" },
{ 327050, "当前设备状态不支持播放音频" },
{ 327051, "下载音频文件失败" },
{ 327052, "喊话器处理模式切换失败" },
{ 327053, "上传音频文件失败" },
{ 327054, "播放音频失败" },
{ 327055, "设置工作模式失败" },
{ 327056, "上传文本失败" },
{ 327057, "停止播放失败" },
{ 327058, "设置播放模式失败" },
{ 327059, "设置音量失败" },
{ 327060, "设置控件值失败" },
{ 327061, "发送文本值失败" },
{ 327062, "切换系统语言失败" },
{ 327063, "获取设备功能列表失败" },
{ 327064, "获取设备配置文件失败" },
{ 327065, "获取设备图片文件失败" },
{ 327066, "设备文件压缩失败" },
{ 327067, "设备文件上传失败" },
{ 327068, "上传音频文件失败md5校验失败" },
{ 327069, "上传音频文件失败" },
{ 327070, "上传音频文件失败,异常终止" },
{ 327071, "上传TTS文本失败md5校验失败" },
{ 327072, "上传TTS文本失败" },
{ 327073, "上传TTS文本失败异常终止" },
{ 327074, "喊话器重播失败" },
{ 327075, "喊话器编码失败" },
{ 327201, "全景拍照失败" },
{ 327202, "全景拍摄终止" },
{ 327203, "当前设备不支持全景拍照" },
{ 327204, "系统繁忙,无法全景拍照" },
{ 327205, "请求失败,无法全景拍照" },
{ 327206, "飞机未起飞,无法开始全景拍摄" },
{ 327207, "控制权获取失败,全景拍摄终止" },
{ 327208, "未知相机错误,无法开始全景拍摄" },
{ 327209, "相机超时,全景拍摄终止" },
{ 327210, "无法全景拍照" },
{ 327211, "存储空间不足,全景拍摄终止" },
{ 327212, "飞机运动中,无法开始全景拍摄" },
{ 327213, "云台运动中,无法开始全景拍摄" },
{ 327214, "用户操作摇杆,全景拍摄终止" },
{ 327215, "碰到限飞区,全景拍摄终止" },
{ 327216, "触发距离限制,全景拍摄终止" },
{ 327217, "云台受阻,全景拍摄终止" },
{ 327218, "拍照失败,全景拍摄终止" },
{ 327219, "全景图片拼接失败" },
{ 327220, "加载标定参数失败,全景拍摄终止" },
{ 327221, "调整相机参数失败,全景拍摄终止" },
{ 327500, "飞行器镜头除雾失败,请稍后重试" },
{ 328051, "飞机未完成实名登记,请连接遥控器,按照指引完成、实名登记后飞行" },
{ 328052, "飞机实名登记状态已注销,请连接遥控器,按照指引完成实名登记后飞行" },
{ 336000, "指点飞行命令发送失败,请重试" },
{ 336001, "飞行器数据异常,无法响应指令" },
{ 336002, "飞行器GPS信号差" },
{ 336003, "飞行器定位失效,无法响应指令" },
{ 336004, "指点飞行自主规划失败" },
{ 336005, "飞行器返航点未更新" },
{ 336006, "飞行器已失联,已退出指点飞行" },
{ 336017, "飞行器电量不足以完成当前任务" },
{ 336018, "已切换飞行器规划模式" },
{ 336019, "指点飞行因限高自动调整飞行高度" },
{ 336513, "目标点在禁飞区内" },
{ 336514, "目标点超出飞行器限远" },
{ 336515, "目标点在禁飞区内" },
{ 336516, "目标点超出飞行器限高" },
{ 336517, "目标点超出飞行器限低" },
{ 337025, "飞行器无法起飞" },
{ 337026, "目标点异常,请重试" },
{ 337027, "飞行器速度设置异常,请重试" },
{ 337028, "飞行器版本异常,请检查飞行器版本" },
{ 337029, "飞行器无法响应当前任务,请稍后重试" },
{ 337030, "指令飞行安全离场高过低" },
{ 337537, "已触碰禁飞区" },
{ 337538, "已触碰飞行器限远" },
{ 337539, "已触碰禁飞区" },
{ 337540, "已触碰飞行器限高或限高区" },
{ 337541, "已触碰飞行器限低" },
{ 337542, "飞行器起飞失败,请重试" },
{ 337543, "目标点可能在障碍物内,请检查周边环境" },
{ 337544, "检测到障碍物,请检查周边环境" },
{ 337545, "飞行器规划异常,请重试" },
{ 337546, "已触碰自定义飞行区边界" },
{ 338001, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试" },
{ 338002, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试" },
{ 338003, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试" },
{ 338004, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试" },
{ 338005, "起飞机场与降落机场部署距离超出限制无法执行飞行任务请选择两个部署距离不超过15km的机场执行任务" },
{ 338006, "无法执行飞行任务,请检查降落机场是否已申请解禁证书、是否位于自定义禁飞区或是否位于自定义飞行区外" },
{ 338007, "目标降落机场部署突破限高区限高,无法执行任务,请申请解禁证书后再试" },
{ 338008, "目标降落机场部署突破飞行器设置的限高,无法执行任务,请调整限高后重试" },
{ 338009, "飞行器GPS定位信号差无法执行任务请重启飞行器后重试" },
{ 338010, "飞行器定位失效,无法执行任务,请重启飞行器后重试" },
{ 338011, "任务失败,目标机场处于地理鸟笼作业区域外,请重新规划任务后再试" },
{ 338017, "飞行器数据更新失败,无法执行任务,请重启飞行器后重试" },
{ 338018, "飞行器数据更新失败,无法执行任务,请重启飞行器后重试" },
{ 338019, "飞行器到目标机场的返航路线正在规划中,无法执行任务,请重启飞行器后重试" },
{ 338020, "飞行器无法根据规划的路径到达目标降落机场,无法执行任务,请重新选择降落机场后再试" },
{ 338021, "飞行器当前电量不足以到达目标降落机场,无法执行任务,请给飞行器充电后重试" },
{ 338049, "响应遥控器杆量,已退出指点飞行" },
{ 338050, "响应终止指令,已退出指点飞行" },
{ 338051, "飞行器低电量返航,已退出指点飞行" },
{ 338052, "飞行器低电量降落,已退出指点飞行" },
{ 338053, "附近有载人机,已退出指点飞行" },
{ 338054, "响应其他高优先级任务,已退出指点飞行" },
{ 338255, "飞行器通信异常,无法执行飞行任务,请重启飞行器与机场后重试" },
{ 386535, "航线执行异常,请稍后重试或重启机场后重试" },
{ 513002, "直播失败,相机不存在或相机类型错误" },
{ 513003, "相机已经在直播中,请勿重复开启直播" },
{ 513005, "直播失败,直播参数(清晰度)设置错误" },
{ 513006, "直播启动失败,请刷新重试" },
{ 513008, "直播失败,设备端图传数据异常" },
{ 513010, "直播失败,设备无法联网" },
{ 513011, "操作失败,设备未开启直播" },
{ 513012, "操作失败,设备已在直播中,不支持切换镜头" },
{ 513013, "直播失败,直播使用的视频传输协议不支持" },
{ 513014, "直播失败,直播参数错误或者不完整" },
{ 513015, "直播异常,网络卡顿,请刷新后重试" },
{ 513016, "直播异常,视频解码失败" },
{ 513017, "直播已暂停,请等待当前飞行器媒体文件下载完成后再试" },
{ 513099, "直播失败,请稍后重试" },
{ 514100, "机场运行异常,请重启机场后重试" },
{ 514101, "推杆闭合失败,请检查停机坪上是否存在异物,飞行器方向是否放反,或重启机场后重试" },
{ 514102, "推杆展开失败,请检查停机坪上是否存在异物,或重启机场后重试" },
{ 514103, "飞行器电量低于30%无法执行飞行任务请充电后重试建议电量≥50%" },
{ 514104, "飞行器电池开始充电失败,请重启机场后重试" },
{ 514105, "飞行器电池停止充电失败,请重启机场后重试" },
{ 514106, "飞行器电源控制异常,请重启机场后重试" },
{ 514107, "舱盖开启失败,请检查舱盖周围是否存在异物,或重启机场后重试" },
{ 514108, "舱盖关闭失败,请检查舱盖周围是否存在异物,或重启机场后重试" },
{ 514109, "飞行器开机失败,请检查飞行器是否在舱和飞机电量是否正常,或重启机场后重试" },
{ 514110, "飞行器关机失败,请重启机场后重试" },
{ 514111, "飞行器慢转收桨控制异常,请重启机场后重试" },
{ 514112, "飞行器慢转收桨控制异常,请重启机场后重试" },
{ 514113, "机场推杆与飞行器无法连接,请检查飞行器是否在舱内,推杆闭合时是否被卡住,充电连接器是否脏污或损坏" },
{ 514114, "获取飞行器电源状态失败,请重启机场后重试" },
{ 514116, "无法执行当前操作,机场正在执行其他控制指令,请稍后重试" },
{ 514117, "舱盖开启或关闭未到位,请重启机场后重试" },
{ 514118, "推杆展开或闭合未到位,请重启机场后重试" },
{ 514120, "机场与飞行器断连,请重启机场后重试或重新对频" },
{ 514121, "机场急停按钮被按下,请释放急停按钮" },
{ 514122, "获取飞行器充电状态失败,请重启机场后重试" },
{ 514123, "飞行器电池电量过低无法开机" },
{ 514124, "获取飞行器电池信息失败,无法执行飞行任务,请重启机场后重试" },
{ 514125, "飞行器电池电量已接近满电状态无法开始充电请使用至95%以下再进行充电" },
{ 514134, "雨量过大,机场无法执行飞行任务,请稍后重试" },
{ 514135, "风速过大,机场无法执行飞行任务,请稍后重试" },
{ 514136, "机场供电断开,机场无法执行飞行任务,请恢复机场供电后重试" },
{ 514137, "环境温度过低于-20℃(-4°F),机场无法执行飞行任务,请稍后重试" },
{ 514138, "飞行器电池正在保养中,机场无法执行飞行任务,请等待保养结束后重试" },
{ 514139, "飞行器电池无法执行保养指令,飞行器电池无需保养" },
{ 514140, "飞行器电池无法执行保养指令,飞行器电池无需保养" },
{ 514141, "机场系统运行异常,请重启机场后重试" },
{ 514142, "飞行器起飞前,机场推杆与飞行器无法连接,请检查飞行器是否在舱内,推杆闭合时是否被卡住,充电连接器是否脏污或损坏" },
{ 514143, "推杆未闭合或闭合不到位,请稍后重试或重启机场后重试" },
{ 514144, "舱盖未关闭或关闭不到位,请稍后重试或重启机场后重试" },
{ 514145, "机场处于现场调试中,无法执行当前操作或执行飞行任务,请断开遥控器和机场的数据线连接后重试" },
{ 514146, "机场处于远程调试中,无法执行飞行任务,请退出远程调试后重试" },
{ 514147, "设备升级中,无法进行远程调试或执行飞行任务,请等待升级完成后重试" },
{ 514148, "机场已经在作业中,无法进行远程调试或再次执行飞行任务,请等待当前任务执行完成后重试" },
{ 514149, "机场系统运行异常,无法执行飞行任务,请重启机场后重试" },
{ 514150, "设备重启中,无法执行飞行任务,请等待重启完成后重试" },
{ 514151, "设备升级中,无法执行设备重启指令,请等待升级完成后重试" },
{ 514153, "机场已退出远程调试模式,无法执行当前操作" },
{ 514154, "获取内循环出风口温度失败,请稍后再试" },
{ 514156, "飞机不在舱内,请立即检查飞行器是否已安全降落并将飞行器放回至机场" },
{ 514157, "执行开机失败,无线充电线圈业务繁忙,请重启机场后再试复" },
{ 514158, "无法起飞机场RTK业务异常请重启机场后再试" },
{ 514159, "任务失败,降落机场检测到飞行器,请确保降落机场没有飞行器后再试" },
{ 514162, "飞行器和机场连接失败,请关闭机场舱盖或重启机场后再试" },
{ 514163, "电池功能异常,请确保飞行器电池插入到位或重启飞行器后再试" },
{ 514164, "设备重启失败,请稍后重试,如果仍报错请联系大疆售后" },
{ 514165, "设备重启失败,请稍后重试,如果仍报错请联系大疆售后" },
{ 514170, "机场系统初始化中,无法执行当前操作或指令,请等待机场系统初始化完成后重试" },
{ 514171, "云端下发给机场的命令不符合格式要求,机场无法执行" },
{ 514172, "飞行器无法关机,蓝牙连接状态为未连接,请尝试重启飞行器和机场,或去现场重新对频飞行器与机场后再试" },
{ 514173, "由于天气原因环境温度低于5度并且降雨大于等于中雨可能导致桨叶结冰影响作业安全暂无法执行任务" },
{ 514174, "飞行器充电失败,机场舱盖开启或关闭未到位,请关闭舱盖后再试" },
{ 514180, "停止空调制冷或停止空调制热失败,请稍后重试" },
{ 514181, "开启空调制冷失败,请稍后重试" },
{ 514182, "开启空调制热失败,请稍后重试" },
{ 514183, "开启空调除湿失败,请稍后重试" },
{ 514184, "当前温度低于0℃32°F无法开启空调制冷" },
{ 514185, "当前温度高于45℃115°F无法开启空调制热" },
{ 514300, "网关异常" },
{ 514301, "请求超时,连接断开" },
{ 514302, "网络证书异常,连接失败" },
{ 514303, "网络异常,连接断开" },
{ 514304, "请求被拒,连接失败" }
};
}

@ -0,0 +1,69 @@
using Infrastructure.Cache;
using OpenAuth.App.ServiceApp;
using OpenAuth.WebApi;
using Quartz;
namespace OpenAuth.App.BaseApp.Subscribe;
/// <summary>
/// 离线去订阅
/// </summary>
public class GlobalSubscribe : IJob
{
public bool x = true; // 临时只执行一次
public ManageApp manageApp;
private MqttClientManager mqttManager;
private RedisCacheContext redisCacheContext;
public GlobalSubscribe(ManageApp manageApp, MqttClientManager mqttManager, ICacheContext redisCacheContext)
{
this.manageApp = manageApp;
this.mqttManager = mqttManager;
this.redisCacheContext = redisCacheContext as RedisCacheContext;
}
public Task Execute(IJobExecutionContext context)
{
Console.WriteLine($"running !{DateTime.Now}");
/*var redisCacheContext = context.JobDetail.JobDataMap.Get("redisCacheContext") as RedisCacheContext;
var serviceProvider = context.JobDetail.JobDataMap.Get("ServiceProvider") as IServiceProvider;
var mqttManager = serviceProvider.GetService(typeof(MqttClientManager)) as MqttClientManager;
if (manageApp == null)
{
manageApp = serviceProvider.GetService(typeof(ManageApp)) as ManageApp;
}
/*var ioc = IocManager.Instance;
var redisCacheContext = IocManager.Instance.GetService<ICacheContext>();#1#
// todo 如果无人机不在线,则订阅
if (redisCacheContext == null) return Task.CompletedTask;*/
var keys = redisCacheContext.GetAllKeys("online:*");
foreach (var redisKey in keys)
{
var gatewaySn = redisKey.ToString()[7..];
// todo 取得sn值
// todo 取得设备信息
// todo 需要判断是不是要订阅,避免重复订阅
if (mqttManager != null)
{
var droneDock = manageApp.GetDroneDockBySn(gatewaySn);
/*if(droneDock)
/*mqttManager.SubscribeAsync($"thing/product/{gatewaySn}/services_reply",
async (args) => await TopicHandler.HandleTopic(gatewaySn, args.ApplicationMessage.Topic,
Encoding.UTF8.GetString(args.ApplicationMessage.Payload), serviceProvider));#1#
x = false;
*/
}
//statusSubscribe.subscribe(gateway);
//stateSubscribe.subscribe(gateway, true);
//osdSubscribe.subscribe(gateway, true);
//servicesSubscribe.subscribe(gateway);
//eventsSubscribe.subscribe(gateway, true);
//requestsSubscribe.subscribe(gateway);
//propertySetSubscribe.subscribe(gateway);
}
// todo
return Task.CompletedTask;
}
}

@ -109,6 +109,7 @@ namespace OpenAuth.App.ServiceApp
return false;
}
}
#endregion
/// <summary>
@ -168,6 +169,7 @@ namespace OpenAuth.App.ServiceApp
return new Response<bool> { Result = false, Message = "删除失败" };
}
}
//添加无人机
public bool AddLasaUav(LasaUav info)
{
@ -493,7 +495,8 @@ namespace OpenAuth.App.ServiceApp
using (var db = UnitWork.CreateContext())
{
WorkSpaceRes res = new WorkSpaceRes();
var workspace = await db.LasaWorkspace.AsQueryable().Where(r => r.Id == id && r.IsDelete == false).FirstAsync();
var workspace = await db.LasaWorkspace.AsQueryable().Where(r => r.Id == id && r.IsDelete == false)
.FirstAsync();
if (workspace != null)
{
var sysuser = db.User.AsQueryable()
@ -510,6 +513,7 @@ namespace OpenAuth.App.ServiceApp
res.lasaSpaceLockFlies = lockfly;
res.workspace = workspace;
}
return new Response<WorkSpaceRes>
{
Result = res
@ -551,15 +555,15 @@ namespace OpenAuth.App.ServiceApp
#endregion
public async Task ExecuteFlyTask(string taskId)
public async Task<String> ExecuteFlyTask(string taskId)
{
var task = await Repository.ChangeRepository<SugarRepositiry<LasaTask>>().GetByIdAsync(taskId);
var airLine = await Repository.ChangeRepository<SugarRepositiry<LasaAirLine>>()
.GetByIdAsync(task.AirLineId);
var wpml = airLine.WPML;
// todo 查询sn
// 查询sn
var dronePort = await Repository.ChangeRepository<SugarRepositiry<LasaDronePort>>()
.GetByIdAsync(airLine.UavId);
.GetByIdAsync(task.TaskDronePort);
if (dronePort == null)
{
throw new Exception("指定机场不存在");
@ -572,7 +576,7 @@ namespace OpenAuth.App.ServiceApp
method = "flighttask_prepare",
tid = Guid.NewGuid().ToString(),
bid = Guid.NewGuid().ToString(),
timestamp = DateTime.Now.Ticks,
timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds()
};
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
@ -588,15 +592,19 @@ namespace OpenAuth.App.ServiceApp
//var serverIp = configuration["MQTT:Server"];
dynamic data = new ExpandoObject();
data.flight_id = Guid.NewGuid().ToString();
data.execute_time = DateTime.Now.Ticks;
data.execute_time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
//{"0":"立即任务","1":"定时任务","2":"条件任务"}
// 立即任务和定时任务均由execute_time指定执行时间条件任务支持ready_conditions字段指定任务就绪条件设备可在指定时间段内满足就绪条件后即可执行立即任务媒体上传优先级最高定时任务和条件任务媒体上传优先级相同
// 若task_type任务类型指定为“立即执行”时设备端限制了30s的时间误差若设备收到指令的时间与execute_time相差超过30s将报错且该任务无法正常执行。
data.task_type = task.TaskType;
var md5 = await _minioService.GetMetaObject(wpml, "");
data.file = new
{
url = wpml,
fingerprint = _minioService.GetMetaObject(wpml, "")
fingerprint = md5
};
//任务执行条件
data.executable_conditions = new
data.executable_conditions = new
{
// 可执行任务的机场或飞行器最低存储容量,机场或飞行器存储容量不满足 storage_capacity 时,任务执行失败。
// todo 容量单位是什么? 一个图片多少兆,预计拍多少图片?
@ -617,6 +625,7 @@ namespace OpenAuth.App.ServiceApp
wayline_id = "" // 航线id
};
}
// 返航高度 {"max":1500,"min":20,"step":"","unit_name":"米 / m"}
data.rth_altitude = 150; // todo 取自任务
// 返航高度模式 {"0":"智能高度","1":"设定高度"}
@ -632,18 +641,19 @@ namespace OpenAuth.App.ServiceApp
// 高精度 RTK 任务:飞行器起飞后会在空中等待 RTK 收敛后再执行任务,等待 RTK 收敛的过程中无法暂停任务。默认场景建议使用该模式。GPS 任务:飞行器无需等待 RTK 收敛便可以直接开始执行。精度要求不高的任务或对起飞时效性要求较高的任务建议使用该模式。
data.wayline_precision_type = task.WaylinePrecisionType; // 值来自任务
// 是否在模拟器中执行任务 todo 调试时使用
/*data.simulate_mission = new
data.simulate_mission = new
{
//118.309405,35.14035 应用科学城坐标
//是否开启模拟器任务
//{"0":"不开启","1":"开启"}
is_enable = 1,
// 纬度 {"max":"90.0","min":"-90.0"}
latitude = 35.0,
latitude = 35.140331,
// 经度 {"max":"180.0","min":"-180.0"}
longitude = 120.0,
longitude = 118.309419,
// 高度 {"max":"9999.9","min":"-9999.9"unit_name":"米 / m"}
altitude = 200.0
};*/
altitude = 150.0
};
// 飞行安全预检查
// {"0":"关闭","1":"开启"}
// 设置一键起飞和航线任务中的飞行安全是否预先检查。此字段为可选默认为0值为0表示关闭1表示开启。飞行安全预先检查表示: 飞行器执行任务前,检查自身作业区文件是否与云端一致,如果不一致则拉取文件更新,如果一致则不处理
@ -658,15 +668,33 @@ namespace OpenAuth.App.ServiceApp
// todo 获取指定值 计算 还是
battery_capacity = 77, // 设备电量百分比,范围 0-100
// todo 设定时间
begin_time = DateTime.Now.Ticks, // 任务开始执行时间必须大于该值
begin_time = DateTimeOffset.Now.ToUnixTimeMilliseconds() + 50000, // 任务开始执行时间必须大于该值
// todo 设定结束时间
end_time = DateTime.Now.Ticks, // 任务结束时间必须
end_time = DateTimeOffset.Now.ToUnixTimeMilliseconds() + 100000, // 任务结束时间必须
};
}
request.SetData(data);
var taskAssign = new LasaTaskAssign
{
Id = Guid.NewGuid().ToString(),
Bid = request.bid,
Tid = request.tid,
FlightId = data.flight_id,
GatewaySn = dronePort.Sn,
AirlineId = task.AirLineId,
Status = 1,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now,
TaskId = taskId,
Md5 = md5,
Wpml = wpml
};
await Repository.ChangeRepository<SugarRepositiry<LasaTaskAssign>>().InsertAsync(taskAssign);
// 任务下发
await _mqttClientManager.PublishAsync(topic, JsonConvert.SerializeObject(request));
return JsonConvert.SerializeObject(request);
}
public async Task PendingFlyTask(string taskId)
@ -682,6 +710,7 @@ namespace OpenAuth.App.ServiceApp
}
#region 添加地图作业区域
/// <summary>
/// 添加地图作业区域
/// </summary>
@ -705,15 +734,18 @@ namespace OpenAuth.App.ServiceApp
model.Geom = null;
StringBuilder geomSql = new StringBuilder();
geomSql.AppendFormat($" update lasa_shpdata set \"Geom\" = st_geomfromtext('{_wktModel}',4326) where \"Id\" = '{id}'");
geomSql.AppendFormat(
$" update lasa_shpdata set \"Geom\" = st_geomfromtext('{_wktModel}',4326) where \"Id\" = '{id}'");
//更新面积
StringBuilder sql = new StringBuilder();
sql.AppendFormat($" update lasa_shpdata set \"Area\" = st_area(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{id}'");
sql.AppendFormat(
$" update lasa_shpdata set \"Area\" = st_area(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{id}'");
//更新周长
StringBuilder sqlle = new StringBuilder();
sqlle.AppendFormat($" update lasa_shpdata set \"Length\" = ST_Perimeter(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{id}'");
sqlle.AppendFormat(
$" update lasa_shpdata set \"Length\" = ST_Perimeter(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{id}'");
//使用事务提交数据
var transFlag = await db.UseTranAsync(async () =>
@ -759,15 +791,18 @@ namespace OpenAuth.App.ServiceApp
model.Geom = null;
StringBuilder geomSql = new StringBuilder();
geomSql.AppendFormat($" update lasa_shpdata set \"Geom\" = st_geomfromtext('{_wktModel}',4326) where \"Id\" = '{model.Id}'");
geomSql.AppendFormat(
$" update lasa_shpdata set \"Geom\" = st_geomfromtext('{_wktModel}',4326) where \"Id\" = '{model.Id}'");
//更新面积
StringBuilder sql = new StringBuilder();
sql.AppendFormat($" update lasa_shpdata set \"Area\" = st_area(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{model.Id}'");
sql.AppendFormat(
$" update lasa_shpdata set \"Area\" = st_area(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{model.Id}'");
//更新周长
StringBuilder sqlle = new StringBuilder();
sqlle.AppendFormat($" update lasa_shpdata set \"Length\" = ST_Perimeter(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{model.Id}'");
sqlle.AppendFormat(
$" update lasa_shpdata set \"Length\" = ST_Perimeter(st_transform(\"Geom\",4527)) where \"Geom\" is not null and \"Id\" = '{model.Id}'");
//使用事务提交数据
var transFlag = await db.UseTranAsync(async () =>
@ -796,7 +831,6 @@ namespace OpenAuth.App.ServiceApp
Message = "更新失败"
};
}
}
//删除地图作业区域
@ -804,7 +838,7 @@ namespace OpenAuth.App.ServiceApp
{
using (var db = UnitWork.CreateContext())
{
await db.LasaShpData.DeleteByIdAsync(id);
await db.LasaShpData.DeleteByIdAsync(id);
if (db.Commit())
return new Response<bool> { Result = true, Message = "删除成功" };
else
@ -817,28 +851,65 @@ namespace OpenAuth.App.ServiceApp
/// </summary>
/// <param name="workspaceid">项目id</param>
/// <returns></returns>
public async Task<Response<List<LasaShpData>>> GetWorkAreaList(string workspaceid,int? state, string type)
public async Task<Response<List<LasaShpData>>> GetWorkAreaList(string workspaceid, int? state, string type)
{
using (var db = UnitWork.CreateContext())
{
StringBuilder sql = new StringBuilder();
sql.AppendFormat($" Select * from lasa_shpdata where \"WorkSpaceId\" = '{workspaceid}'");
var list = db.Db.SqlQueryable<LasaShpData>(sql.ToString()).ToList();
if (!string.IsNullOrEmpty(type)&&list.Count>0)
if (!string.IsNullOrEmpty(type) && list.Count > 0)
{
list=list.Where(r=>r.Type == type).ToList();
list = list.Where(r => r.Type == type).ToList();
}
if(state!=null)
if (state != null)
{
list=list.Where(r=>r.State==state).ToList();
list = list.Where(r => r.State == state).ToList();
}
return new Response<List<LasaShpData>>
{
Result = list
};
}
}
#endregion
public async Task<string> TestExecuteFlyTask(string flightid)
{
// flighttask_prepare method
/// thing/product/{gateway_sn}/services 主题
// todo 执行下发任务
var request = new TopicServicesRequest<object>();
dynamic data = new ExpandoObject();
data.flight_id = flightid;
request.SetMethod("flighttask_execute")
.SetTid(flightid)
.SetBid(Guid.NewGuid().ToString())
.SetData(data);
return JsonConvert.SerializeObject(request);
}
public LasaDronePort GetDroneDockBySn(string gatewaySn)
{
var droneDock = Repository.GetSingle(r => r.Sn == gatewaySn);
return droneDock;
}
public LasaTaskAssign GetTaskAssignByBidAndTid(string bid, string tid)
{
return Repository
.ChangeRepository<SugarRepositiry<LasaTaskAssign>>()
.GetSingle(r => r.Bid == bid && r.Tid == tid);
}
public LasaTaskAssign GetTaskAssignByBidAndTidAndFlightId(string bid, string tid, string flightId)
{
return Repository
.ChangeRepository<SugarRepositiry<LasaTaskAssign>>()
.GetSingle(r => r.Bid == bid && r.Tid == tid && r.FlightId == flightId);
}
}
}

@ -10,6 +10,7 @@ namespace OpenAuth.Repository.Domain
[SugarTable("lasa_airline")]
public class LasaAirLine
{
[SugarColumn(IsPrimaryKey = true, ColumnName = "Id")]
public string Id { get; set; } // 主键
public string AirLineName { get; set; } // 航线名称
public string AirLineType { get; set; } // 航线类型

@ -16,6 +16,7 @@ namespace OpenAuth.Repository.Domain
/// <summary>
/// id
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "Id")]
public string Id { get; set; }
/// <summary>

@ -0,0 +1,22 @@
using SqlSugar;
namespace OpenAuth.Repository.Domain;
[SugarTable("lasa_taskassign")]
public class LasaTaskAssign
{
[SugarColumn(IsPrimaryKey = true)]
public string Id { get; set; }
public string Bid { get; set; }
public string Tid { get; set; }
public string FlightId { get; set; }
public string GatewaySn { get; set; }
public string AirlineId { get; set; }
public short? Status { get; set; }
public DateTime? CreateTime { get; set; }
public DateTime? UpdateTime { get; set; }
public string Reason { get; set; }
public string TaskId { get; set; }
public string Md5 { get; set; }
public string Wpml { get; set; }
}

@ -406,9 +406,10 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
/// </summary>
/// <param name="taskId"></param>
[HttpPost]
public async Task ExecuteFlyTask(string taskId)
[AllowAnonymous] // todo 临沂
public async Task<string> ExecuteFlyTask(string taskId)
{
await _app.ExecuteFlyTask(taskId);
return await _app.ExecuteFlyTask(taskId);
}
/// <summary>
@ -421,6 +422,13 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
await _app.PendingFlyTask(taskId);
}
[HttpPost]
[AllowAnonymous]
public async Task<string> TestExecuteFlyTask(string flightid)
{
return await _app.TestExecuteFlyTask(flightid);
}
/// <summary>
/// 测试
/// </summary>

@ -2,10 +2,8 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using ce.autofac.extension;
using DocumentFormat.OpenXml.Validation;
using IdentityServer4.AccessTokenValidation;
using Infrastructure;
using Infrastructure.Cache;
using Infrastructure.CloudSdk.minio;
using Infrastructure.CloudSdk.mqttmessagecenter;
using Infrastructure.Extensions.AutofacManager;
@ -13,26 +11,21 @@ using Infrastructure.Middleware;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using Microsoft.IdentityModel.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Npgsql;
using OpenAuth.App;
using OpenAuth.App.BaseApp.HostedService;
using OpenAuth.App.BaseApp.ImMsgManager;
using OpenAuth.App.HostedService;
using OpenAuth.Repository;
using OpenAuth.WebApi.Model;
using OpenAuth.WebApi.Model.mqtt;
using Quartz;
using Quartz.Impl;
using SqlSugar;
using Swashbuckle.AspNetCore.SwaggerUI;
using Yitter.IdGenerator;
namespace OpenAuth.WebApi
{
@ -258,14 +251,14 @@ namespace OpenAuth.WebApi
////没有直接 using SqlSugar因为如果引用命名空间的话会和Microsoft的一个GetTypeInfo存在二义性所以就直接这么使用了
services.AddScoped<ISqlSugarClient>(s =>
{
StaticConfig.CustomSnowFlakeFunc = () => { return Yitter.IdGenerator.YitIdHelper.NextId(); };
StaticConfig.CustomSnowFlakeFunc = () => { return YitIdHelper.NextId(); };
var sqlSugar = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.PostgreSQL,
DbType = DbType.PostgreSQL,
ConnectionString = Configuration.GetConnectionString("OpenAuthDBContext"),
IsAutoCloseConnection = true,
MoreSettings = new SqlSugar.ConnMoreSettings()
MoreSettings = new ConnMoreSettings()
{
PgSqlIsAutoToLower = false,
PgSqlIsAutoToLowerCodeFirst = false
@ -304,8 +297,8 @@ namespace OpenAuth.WebApi
});
return sqlSugar;
});
services.AddScoped<SqlSugar.ISugarUnitOfWork<SugarDbContext>>(s =>
new SqlSugar.SugarUnitOfWork<SugarDbContext>(s.GetService<ISqlSugarClient>()));
services.AddScoped<ISugarUnitOfWork<SugarDbContext>>(s =>
new SugarUnitOfWork<SugarDbContext>(s.GetService<ISqlSugarClient>()));
#endregion
@ -374,7 +367,7 @@ namespace OpenAuth.WebApi
//可以在这里为静态文件添加其他http头信息默认添加跨域信息
ctx.Context.Response.Headers["Access-Control-Allow-Origin"] = "*";
},
ContentTypeProvider = new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider(
ContentTypeProvider = new FileExtensionContentTypeProvider(
new Dictionary<string, string>
{
{ ".amr", "audio/AMR" },
@ -446,7 +439,7 @@ namespace OpenAuth.WebApi
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "V1 Docs");
c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
c.DocExpansion(DocExpansion.None);
c.OAuthClientId("OpenAuth.WebApi"); //oauth客户端名称
c.OAuthAppName("开源版webapi认证"); // 描述
});

@ -8,7 +8,7 @@
"DataProtection": "temp-keys/",
"ConnectionStrings": {
//"OpenAuthDBContext": "PORT=5432;Database=hopetrycore;HOST=192.168.10.124;PASSWORD=123456;USER ID=postgres;",
"OpenAuthDBContext": "PORT=5432;Database=LASAPlatform;HOST=192.168.10.163;PASSWORD=123456;USER ID=postgres;"
"OpenAuthDBContext": "PORT=5432;Database=LASAPlatform;HOST=192.168.10.163;PASSWORD=123456;USER ID=postgres;Pooling=true"
//"OpenAuthDBContext": "PORT=5432;Database=;HOST=192.168.10.131;PASSWORD=123456;USER ID=postgres;"
},
"AppSetting": {
@ -75,6 +75,7 @@
"Password": ""
},
"Minio": {
"UseSSL": false,
"Endpoint": "175.27.168.120:6013",
"AccessKey": "minioadmin",
"SecretKey": "minioadmin",

@ -1,35 +0,0 @@
using System.Text;
using Quartz;
namespace OpenAuth.WebApi.boot;
public class ConfigSubscribe : IJob
{
private MqttClientManager mqttClientManager;
public void Subscribe()
{
// todo 订阅 "thing/product/{gateway_sn}/services_reply",
string gatewaySn = "8UUXN5400A079H";
mqttClientManager.SubscribeAsync($"thing/product/{gatewaySn}/services_reply", async (args) =>
{
// 确定主题 确定payload方法是 method
var topic = args.ApplicationMessage.Topic;
var payload = args.ApplicationMessage.Payload;
var message = Encoding.UTF8.GetString(payload);
});
}
public async Task Execute(IJobExecutionContext context)
{
var serviceProvider = context.JobDetail.JobDataMap.Get("serviceProvider") as IServiceProvider;
if (mqttClientManager != null) return;
if (serviceProvider != null)
{
mqttClientManager = serviceProvider.GetService(typeof(MqttClientManager)) as MqttClientManager;
Subscribe();
}
return;
}
}

@ -0,0 +1,19 @@
using System.Dynamic;
using Infrastructure.CloudSdk.wayline;
using Newtonsoft.Json;
using NUnit.Framework;
namespace OpenAuth.WebApi.boot;
public class TestAbc
{
[Test]
public void TestDser()
{
var json =
@"{""bid"":""e62da5f5-acaa-442a-8134-38ea56f88347"",""data"":{""result"":319003},""method"":""flighttask_execute"",""tid"":""6d638f18-20d7-4625-ac58-3cca1e5d100e"",""timestamp"":1750379532217}";
var result = JsonConvert.DeserializeObject<TopicServicesRequest<dynamic>>(json);
long code = result.data.result;
Console.WriteLine(code);
}
}
Loading…
Cancel
Save