You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
8.6 KiB
239 lines
8.6 KiB
using Newtonsoft.Json; |
|
using System; |
|
using System.IO; |
|
using System.Net.Http; |
|
using System.Text; |
|
using System.Threading.Tasks; |
|
using System.Windows; |
|
using HandyControl.Tools.Extension; |
|
using SparkClient.Model.Common; |
|
using SparkClient.Model.Entity.ApiEntity; |
|
|
|
namespace SparkClient.Model.Services |
|
{ |
|
/// <summary> |
|
/// SOC 客户端服务类,用于与远程服务器进行交互,包括启动图片收集任务、获取图片、获取采集状态等操作。 |
|
/// </summary> |
|
public class SOCClientService |
|
{ |
|
// Log地址 |
|
private const string LogFilePath = @"..\..\..\Resource\Document\log.txt"; |
|
|
|
private static readonly Dictionary<string, string> StatusDescriptions = new Dictionary<string, string> |
|
{ |
|
{ "S000", "成功" }, |
|
{ "S001", "采图正在进行中" }, |
|
{ "S002", "缓存图片被清理(读取不够及时)" }, |
|
{ "S003", "无法向单片机发送指令" }, |
|
{ "S004", "单片机访问超时" }, |
|
{ "S005", "单片机返回错误码" }, |
|
{ "P001", "未找到切工仪" }, |
|
{ "P002", "算法调用失败" } |
|
}; |
|
|
|
/// <summary> |
|
/// 基础URL,用于构建完整的API请求地址。 |
|
/// </summary> |
|
private readonly string _baseUrl; |
|
|
|
/// <summary> |
|
/// 认证令牌,用于HTTP请求的认证。 |
|
/// </summary> |
|
private readonly string _authToken; |
|
|
|
/// <summary> |
|
/// 构造函数,初始化基础URL和认证令牌。 |
|
/// </summary> |
|
/// <param name="baseUrl">基础URL</param> |
|
/// <param name="authToken">认证令牌</param> |
|
public SOCClientService(string baseUrl, string authToken) |
|
{ |
|
_baseUrl = baseUrl; |
|
_authToken = authToken; |
|
} |
|
|
|
/// <summary> |
|
/// 发送GET请求的通用方法。 |
|
/// </summary> |
|
/// <param name="url">请求的完整URL</param> |
|
/// <returns>HTTP响应</returns> |
|
private async Task<HttpResponseMessage> SendGetRequestAsync(string url) |
|
{ |
|
using (var client = new HttpClient()) |
|
{ |
|
client.DefaultRequestHeaders.Add("Authorization", "Basic " + _authToken); |
|
return await client.GetAsync(url); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 启动图片收集任务。 |
|
/// </summary> |
|
/// <param name="lightLevel">光照级别</param> |
|
/// <returns>任务状态</returns> |
|
public async Task<string> CollectImagesAsync(int lightLevel) |
|
{ |
|
string url = $"{_baseUrl}/collect_images?light_level={lightLevel}"; |
|
var response = await SendGetRequestAsync(url); |
|
|
|
if (response.IsSuccessStatusCode) |
|
{ |
|
var jsonResponse = await response.Content.ReadAsStringAsync(); |
|
var result = JsonConvert.DeserializeObject<ResponseStatus>(jsonResponse); |
|
return result.Status; |
|
} |
|
else |
|
{ |
|
return "collect_images_Error: " + (int)response.StatusCode; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 获取指定索引的图片。 |
|
/// </summary> |
|
/// <param name="index">图片索引</param> |
|
/// <returns>图片的字节数组</returns> |
|
public async Task<List<string>> RetrieveImageAsync(string savePath) |
|
{ |
|
List<string> imageNames = new List<string>(); |
|
// 读取图片接口 |
|
int imageIndex = 0; |
|
while (true) |
|
{ |
|
string url = $"{_baseUrl}/retrieve_image/{imageIndex}"; |
|
var response = await SendGetRequestAsync(url); |
|
int status = (int)response.StatusCode; |
|
|
|
if (status == 200) |
|
{ |
|
byte[] imageBytes = await response.Content.ReadAsByteArrayAsync(); |
|
string fileName = Path.Combine(savePath, $"image_{imageIndex}.bmp"); |
|
// 图片名称List |
|
imageNames.Add(Path.GetFileName(fileName)); |
|
// 保存图片 |
|
await File.WriteAllBytesAsync(fileName, imageBytes); |
|
imageIndex++; |
|
} |
|
else if (status == 425) |
|
{ |
|
await Task.Delay(1000); |
|
} |
|
else if (status == 410) |
|
{ |
|
imageIndex++; |
|
} |
|
else if (status == 404) |
|
{ |
|
return imageNames; |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 获取图片采集状态。 |
|
/// </summary> |
|
/// <returns>采集状态</returns> |
|
public async Task<string> CollectStatusAsync() |
|
{ |
|
string url = $"{_baseUrl}/collect_status"; |
|
var response = await SendGetRequestAsync(url); |
|
|
|
if (response.IsSuccessStatusCode) |
|
{ |
|
var jsonResponse = await response.Content.ReadAsStringAsync(); |
|
var result = JsonConvert.DeserializeObject<ResponseStatus>(jsonResponse); |
|
return result.Status; |
|
} |
|
else |
|
{ |
|
return "collect_status_Error: " + (int)response.StatusCode; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 处理图片收集、保存和状态检查。 |
|
/// </summary> |
|
/// <param name="lightLevel">光照级别</param> |
|
/// <param name="savePath">图片保存路径</param> |
|
/// <returns>操作结果</returns> |
|
public async Task<SocResultEntity> ProcessImageCollectionAsync(int lightLevel, string savePath) |
|
{ |
|
try |
|
{ |
|
// 清理 savePath 文件夹 |
|
if (Directory.Exists(savePath)) |
|
{ |
|
Directory.Delete(savePath, true); |
|
} |
|
Directory.CreateDirectory(savePath); |
|
|
|
// 启动任务接口 |
|
string startStatus = await CollectImagesAsync(lightLevel); |
|
// 成功 |
|
if (startStatus != StatusCodes.Success) |
|
{ |
|
// 启动任务失败 |
|
return new SocResultEntity { Status = startStatus, Images = new List<string>() }; |
|
} |
|
|
|
// 读取图片接口 |
|
List<string> imageNames = await RetrieveImageAsync(savePath); |
|
if (imageNames.Count != 0) |
|
{ |
|
// 采集状态接口 |
|
string acquisitionStatus = await CollectStatusAsync(); |
|
// 成功 |
|
if (acquisitionStatus != StatusCodes.Success) |
|
{ |
|
// 采集状态失败 |
|
return new SocResultEntity { Status = acquisitionStatus, Images = new List<string>() }; |
|
} |
|
} |
|
// 按下载时间排序图片名称 |
|
return new SocResultEntity { Status = StatusCodes.Success, Images = imageNames }; |
|
} |
|
catch (Exception e) |
|
{ |
|
// 日志记录 |
|
// logger.Error(e, "发生异常"); |
|
string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {e.Message}{Environment.NewLine}"; |
|
File.AppendAllText(LogFilePath, logMessage); |
|
return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List<string>() }; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 根据状态码获取相应的描述信息。 |
|
/// 如果状态码在预定义的状态字典中存在,则返回对应的描述信息; |
|
/// 否则返回“未知状态: [状态码]”。 |
|
/// </summary> |
|
/// <param name="status">状态码。</param> |
|
/// <returns>状态描述信息。</returns> |
|
private string GetDescription(string status) |
|
{ |
|
if (StatusDescriptions.TryGetValue(status, out string description)) |
|
{ |
|
return description; |
|
} |
|
return "未知状态: " + status; |
|
} |
|
|
|
} |
|
|
|
|
|
/// <summary> |
|
/// 响应状态类,用于解析服务器返回的状态信息。 |
|
/// </summary> |
|
public class ResponseStatus |
|
{ |
|
/// <summary> |
|
/// 状态码 |
|
/// </summary> |
|
public string Status { get; set; } |
|
|
|
/// <summary> |
|
/// 状态消息 |
|
/// </summary> |
|
public string Message { get; set; } |
|
} |
|
}
|
|
|