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; /// /// http://192.168.50.20:8888/swagger/index.html /// public sealed class AgvService : ConnectorBase, IConnection, IDisposable, IConnectionAsync { public AgvService() { } public override async Task 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 CheckConnected() { await Task.Delay(0); return ConnectionState.IsConnected; } public override async Task ReconnectAsync() { await Task.Delay(0); return ConnectionState.IsConnected; } #region Status public async Task 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 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 argdict = new Dictionary(); 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 状态 /// /// AGV电量 /// /// public async Task ReadBattery() { try { string apiName = this._hostname + "/RobotStatus/Battery"; IDictionary argdict = new Dictionary(); argdict.Add("simple", false.ToString()); apiName = this._httpService.UrlCombine(apiName, argdict); var response = await this._httpService.GetStringAsync(apiName); var batteryLevel = response.GetJsonValueByToken("data.battery_level"); return batteryLevel; } catch(Exception ex) { this.Logger.LogException(ex); } return null; } public async Task ReadCurrentStation() { try { string apiName = this._hostname + "/RobotStatus/Loc"; IDictionary argDict = new Dictionary(); argDict.Add("simple", false.ToString()); apiName = this._httpService.UrlCombine(apiName, argDict); var response = await this._httpService.GetStringAsync(apiName); var currentStation = response.GetJsonValueByToken("data.current_station"); return currentStation; } catch(Exception ex) { this.Logger.LogException(ex); } return null; } public async Task ReadTaskStatus() { try { //https://support.seer-group.com/d/1674676593139699713.html string apiName = this._hostname + "/RobotStatus/Task"; // IDictionary argdict = new Dictionary(); // argdict.Add("simple", false.ToString()); apiName = this._httpService.UrlCombine(apiName, null); var response = await this._httpService.GetStringAsync(apiName); var taskStatus = response.GetJsonValueByToken("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 argdict = new Dictionary(); // argdict.Add("simple", false.ToString()); apiName = this._httpService.UrlCombine(apiName, null); var response = await this._httpService.GetStringAsync(apiName); response.GetJsonValueByToken("data.ret_code"); } catch(Exception ex) { this.Logger.LogException(ex); } } #endregion #region Move private async Task LoadCurrentLocationAsync() { try { string apiName = this._hostname + "/RobotStatus/Loc"; var response = await this._httpService.GetStringAsync(apiName); var currentStation = response.GetJsonValueByToken("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); } } /// /// 指定路过某点到某点 /// 优点: 会按照任务发送队列执行 /// 缺点: 假如同命令连续发送多次,可能会造成首次命令执行后原地掉头导致碰撞风险; /// /// public async void MoveToLocation(IList 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 orderList = new List(); 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 }