C00225155-02/C00225155/MegaRobo.C00225155/MegaRobo.C00225155.ControlD.../AgvService.cs

305 lines
9.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MegaRobo.Connections;
using MegaRobo.Connections.Web;
using MegaRobo.Contract;
using MegaRobo.ControlDevices.Abstractions;
using MegaRobo.Logger;
namespace MegaRobo.C00225155.ControlDevices;
/// <summary>
/// http://192.168.50.20:8888/swagger/index.html
/// </summary>
public sealed class AgvService : ConnectorBase, IConnection, IDisposable, IConnectionAsync
{
public AgvService()
{
}
public override async Task<string> Initialize(ICoreService coreService, params object[] args)
{
this.CoreService = coreService;
try
{
if(args is [string hostname, ..])
{
this._hostname = hostname.Trim('/');
this._httpService = new HttpClientEx { StringEncoder = Encoding.UTF8, BaseAddress = new Uri(this._hostname) };
this._httpService.Timeout = TimeSpan.FromSeconds(5);
}
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
await Task.Delay(0);
return string.Empty;
}
private string _hostname = "";
private HttpClientEx _httpService;
public decimal ChargeVolume { get; set; } // 电量 0-1 即为 100%为满电
public string CurrentStationName { get; set; } = string.Empty;
public bool IsInChargeLocation => false;
public bool IsInWaitLocation => false;
public string ChargeLocationCode { get; set; }
public string WaitLocationCode { get; set; }
public string TargetLocation = "";
public override async Task<ConnectionState> CheckConnected()
{
await Task.Delay(0);
return ConnectionState.IsConnected;
}
public override async Task<ConnectionState> ReconnectAsync()
{
await Task.Delay(0);
return ConnectionState.IsConnected;
}
#region Status
public async Task<bool> CheckMoveDone()
{
var currStation= await this.ReadCurrentStation();
if(string.IsNullOrWhiteSpace(currStation) || string.IsNullOrWhiteSpace(this.TargetLocation))
{
return false;
}
return string.Equals(currStation, this.TargetLocation, StringComparison.CurrentCultureIgnoreCase);
}
public async Task<bool> CheckMoveing()
{
try
{
this.CurrentStationName = await this.ReadCurrentStation();
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
return false;
}
#endregion Status
#region Init
public async void Comfirmloc()
{
try
{
string apiName = "/RobotControl/Comfirmloc";
var response = await this._httpService.PostJsonAsync(apiName, string.Empty);
this.Logger.LogDebug(response);
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
}
public async void Lock(string name = "mega")
{
try
{
string apiName = this._hostname + "/RobotConfig/Lock";
// var args = new { nick_name = name };
//var response = await this._httpService.PostJsonAsync(apiName, args.ToJson());
IDictionary<string, string> argdict = new Dictionary<string, string>();
argdict.Add("nick_name", name);
apiName = this._httpService.UrlCombine(apiName, argdict);
var response = await this._httpService.PostJsonAsync(apiName, string.Empty);
this.Logger.LogInformation(response);
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
}
public async void Unlock()
{
try
{
string apiName = "/RobotConfig/Unlock";
var response = await this._httpService.PutAsync(apiName, null);
if(response.IsSuccessStatusCode)
{
this.Logger.LogInformation($"释放控制权");
}
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
}
#endregion Init
#region
/// <summary>
/// AGV电量
/// </summary>
/// <returns></returns>
public async Task<string> ReadBattery()
{
try
{
string apiName = this._hostname + "/RobotStatus/Battery";
IDictionary<string, string> argdict = new Dictionary<string, string>();
argdict.Add("simple", false.ToString());
apiName = this._httpService.UrlCombine(apiName, argdict);
var response = await this._httpService.GetStringAsync(apiName);
var batteryLevel = response.GetJsonValueByToken<string>("data.battery_level");
return batteryLevel;
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
return null;
}
public async Task<string> ReadCurrentStation()
{
try
{
string apiName = this._hostname + "/RobotStatus/Loc";
IDictionary<string, string> argDict = new Dictionary<string, string>();
argDict.Add("simple", false.ToString());
apiName = this._httpService.UrlCombine(apiName, argDict);
var response = await this._httpService.GetStringAsync(apiName);
var currentStation = response.GetJsonValueByToken<string>("data.current_station");
return currentStation;
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
return null;
}
public async Task<bool> ReadTaskStatus()
{
try
{
//https://support.seer-group.com/d/1674676593139699713.html
string apiName = this._hostname + "/RobotStatus/Task";
// IDictionary<string, string> argdict = new Dictionary<string, string>();
// argdict.Add("simple", false.ToString());
apiName = this._httpService.UrlCombine(apiName, null);
var response = await this._httpService.GetStringAsync(apiName);
var taskStatus = response.GetJsonValueByToken<string>("data.task_status");
return new[] { "2", "3" }.Contains(taskStatus);
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
return false;
}
public async Task ClearAllErrors()
{
try
{
string apiName = this._hostname + "/RobotConfig/Clearallerrors";
// IDictionary<string, string> argdict = new Dictionary<string, string>();
// argdict.Add("simple", false.ToString());
apiName = this._httpService.UrlCombine(apiName, null);
var response = await this._httpService.GetStringAsync(apiName);
response.GetJsonValueByToken<string>("data.ret_code");
} catch(Exception ex)
{
this.Logger.LogException(ex);
}
}
#endregion
#region Move
private async Task<string> LoadCurrentLocationAsync()
{
try
{
string apiName = this._hostname + "/RobotStatus/Loc";
var response = await this._httpService.GetStringAsync(apiName);
var currentStation = response.GetJsonValueByToken<string>("data.current_station");
return currentStation;
} catch(Exception ex)
{
Console.WriteLine(ex);
}
return null;
}
public async void MoveToLocation(string location)
{
try
{
this.TargetLocation = location;
this.Comfirmloc();
string apiName = this._hostname + "/RobotTask/Gotarget";
string sourceId = "SELF_POSITION";
// sourceId = await this.LoadCurrentLocationAsync();
var locationItem = new { id = location, source_id = sourceId, task_id = $"goto_{DateTime.Now:yyyyMMdd_HHmmssfff}_{location}" };
var jsonRaw = locationItem.ToJson(true);
var response = await this._httpService.PostJsonAsync(apiName, jsonRaw);
this.Logger.LogInformation(response);
} catch(Exception ex)
{
Console.WriteLine(ex);
}
}
/// <summary>
/// 指定路过某点到某点
/// 优点: 会按照任务发送队列执行
/// 缺点: 假如同命令连续发送多次,可能会造成首次命令执行后原地掉头导致碰撞风险;
/// </summary>
/// <param name="locations"></param>
public async void MoveToLocation(IList<string> locations)
{
if(locations == null || !locations.Any())
return;
try
{
this.Comfirmloc();
string apiName = this._hostname + "/RobotTask/Gotargetlist";
string sourceId = "SELF_POSITION";
sourceId = await this.LoadCurrentLocationAsync();
IList<object> orderList = new List<object>();
for(var index = 0; index < locations.Count; index++)
{
string item = locations[index];
if(index > 0)
{
sourceId = locations[index - 1];
}
var locationItem = new { id = item, source_id = sourceId, task_id = $"goto_{DateTime.Now:yyyyMMdd_HHmmssfff}_{item}" };
orderList.Add(locationItem);
}
var args = new { move_task_list = orderList };
var jsonRaw = args.ToJson(true);
var response = await this._httpService.PostJsonAsync(apiName, jsonRaw);
this.Logger.LogInformation(response);
} catch(Exception ex)
{
Console.WriteLine(ex);
}
}
#endregion Move
#region Watcher
#endregion Watcher
}