using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Lebai.SDK.Dtos; using Lebai.SDK.Exceptions; using TaskStatus = Lebai.SDK.Dtos.TaskStatus; #if NET5_0||NET6_0 using System.Net.Http.Json; #endif namespace Lebai.SDK { public class EnumExtension { /// /// /// /// /// /// public static string GetEnumDescription(T tField) { var description = string.Empty; //结果 var inputType = tField.GetType(); //输入的类型 var descType = typeof(DescriptionAttribute); //目标查找的描述类型 var fieldStr = tField.ToString(); //输入的字段字符串 var field = inputType.GetField(fieldStr); //目标字段 var isDefined = field.IsDefined(descType, false); //判断描述是否在字段的特性 if (isDefined) { var enumAttributes = (DescriptionAttribute[]) field //得到特性信息 .GetCustomAttributes(descType, false); description = enumAttributes.FirstOrDefault()?.Description ?? string.Empty; } return description; } } public partial class LebaiRobotClient { public static Dictionary CodeMessage = new() { [2001] = "系统异常", [2002] = "登录授权码错误", [2003] = "登录授权码已失效", [2004] = "机器人控制系统异常", [2005] = "404", [2006] = "参数错误", [2007] = "数据不存在", [2009] = "请登录", [2010] = "同一时间只能有一个用户登录", [2011] = "队列任务执行报错", [2012] = "机器人任务运行中不能运行其他任务", [2015] = "场景导入失败,导入文件格式错误", [2021] = "数据库异常", [2022] = "签名失败", [2023] = "任务队列恢复失败,手臂当前位置与即将运行轨迹的首个位置数据校验失败", [2024] = "无效机器人操作命令", [2025] = "机器人当前状态没有满足执行当前指令的预期(废弃)", [2026] = "请求超时", [2027] = "网络配置中,不能频繁进行操作", [2028] = "条件任务执行超时", [2029] = "机器人控制系统故障,请重启机器人后再试", [2030] = "机器人通信故障,请检查机器人是否已正确连接", [2031] = "机器人初始化中,请稍候再试", [2032] = "机器人更新中,请稍候再试", [2033] = "机器人启动中,请稍候再试", [2034] = "机器人停止中,请稍候再试", [2035] = "请结束示教操作后再试", [2036] = "请先停止任务历史中的当前任务后再执行相应操作", [2037] = "仿真模式暂不支持该功能" }; /// /// 获取指定任务信息 /// /// /// /// public virtual async ValueTask GetTask(int id, CancellationToken cancellationToken = default) { var response = await _httpClient.GetAsync($"/public/task?id={id}", cancellationToken); var r = await response.Content.ReadFromJsonAsync>( cancellationToken: cancellationToken); HandleResult(r, $"场景Id:{id}"); return r?.Data.ToTaskInfo(); } /// /// 获取任务信息 /// /// /// /// public virtual async ValueTask GetTasks(GetTasksInput input, CancellationToken cancellationToken = default) { var response = _httpClient .GetAsync($"/public/tasks?pi={input.PageIndex}&ps={input.PageSize}", cancellationToken).Result; var r = await response.Content.ReadFromJsonAsync>( cancellationToken: cancellationToken); HandleResult(r); return r?.Data?.ToResult(); } /// /// 检测是否能运行任务(机器人是否正在运行其他任务) /// /// public virtual async ValueTask GetIsCanRunTask(CancellationToken cancellationToken = default) { var result = await GetTasks(new GetTasksInput {PageIndex = 1, PageSize = 1}, cancellationToken); var first = result?.Items?.FirstOrDefault(); return first == null || first.Status != TaskStatus.Running && first.Status != TaskStatus.Pause; } /// /// /// /// /// protected virtual async ValueTask CheckRobotStatus(CancellationToken cancellationToken = default) { var result = await GetTasks(new GetTasksInput {PageIndex = 1, PageSize = 1}, cancellationToken); var first = result?.Items?.FirstOrDefault(); var r= first == null || first.Status != TaskStatus.Running && first.Status != TaskStatus.Pause; if (!r) throw new Exception($"机器人正在执行其他任务!,任务数量:{result?.Items} 真正运行的其他任务: {first.Status}"); } /// /// 运行任务 /// /// 任务Id /// 执行次数 /// 是否强制停止正在运行的任务 /// /// public virtual async Task RunTask(int id, int executeCount = 1, bool clear = true, CancellationToken cancellationToken = default) { await CheckRobotStatus(cancellationToken); var response = _httpClient.PostAsJsonAsync("/public/task", new { execute_count = executeCount, clear = clear ? 1 : 0, task_id = id }, cancellationToken).Result; var r = await response.Content.ReadFromJsonAsync>( cancellationToken: cancellationToken); HandleResult(r); return r?.Data; } /// /// 运行场景 /// /// 场景Id /// 运行次数 /// 是否强制停止正在运行的场景 /// /// public virtual async Task RunScene(int id, int executeCount = 1, bool clear = false, CancellationToken cancellationToken = default) { await CheckRobotStatus(cancellationToken); var response = _httpClient.PostAsJsonAsync("/public/task", new { execute_count = executeCount, clear = clear ? 1 : 0, scene_id = id }, cancellationToken).Result; var r = await response.Content.ReadFromJsonAsync>( cancellationToken: cancellationToken); HandleResult(r, $"场景Id:{id}"); return r?.Data; } /// /// /// /// /// /// /// protected void HandleResult(LebaiHttpResult result, string message = "") { if (result?.Code != 0) throw new HttpRequestException($"调用失败,{message},Code:{result.Code}" + (CodeMessage.ContainsKey(result.Code) ? $",{CodeMessage[result.Code]}" : "")); } /// /// 等待任务运行完成 /// /// 任务Id /// /// /// /// public virtual async ValueTask WaitTaskRunCompleted(int id, CancellationToken cancellationToken = default) { TaskInfo taskInfo = await GetTask(id, cancellationToken); while (true) { if (cancellationToken.IsCancellationRequested) throw new OperationCanceledException(); if (taskInfo?.Status is TaskStatus.Running or TaskStatus.Idea) { await Task.Delay(100, cancellationToken); taskInfo = await GetTask(id, cancellationToken); } else if (taskInfo?.Status is TaskStatus.RunSuccess) { break; } else { throw new RobotTaskException(taskInfo?.Status); } } return taskInfo; } /// /// 运行场景直到运行完成 /// /// 场景Id /// 执行次数 /// 是否强制停止正在运行的场景 /// /// public virtual async Task RunSceneUntilDone(int id, int executeCount = 1, bool clear = false, CancellationToken cancellationToken = default) { var r = await RunScene(id, executeCount, clear, cancellationToken); return await WaitTaskRunCompleted(r.Id, cancellationToken); } /// /// 执行Lua 代码 /// /// /// /// public virtual async Task ExecuteLua(string luaCode, CancellationToken cancellationToken = default) { var response = await _httpClient.PostAsync("/public/executor/lua", new StringContent(luaCode), cancellationToken); var r = await response.Content.ReadFromJsonAsync>( cancellationToken: cancellationToken); HandleResult(r); return r?.Data; } } }