using LogLibrary.Log; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_DTO.AGV; using WIDESEA_IServices; using WIDESEA_IStorageBasicRepository; using WIDESEA_IStorageSocketServices; using WIDESEA_IStorageTaskRepository; using WIDESEA_IStorageTaskServices; using WIDESEA_IStoragIntegrationServices; using WIDESEA_Model.Models.AGV; using WIDESEA_Repository; using WIDESEA_StorageSocketServices; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_Model.Models; using static WIDESEAWCS_BasicInfoService.Dt_StationManagerService; namespace WIDESEA_StoragIntegrationServices { public partial class AGVService : IAGVService { private readonly ILocationInfoRepository _locationRepository; private readonly IDt_TaskRepository BaseDal; private readonly IDt_TaskService _taskService; private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly LogFactory LogFactory = new LogFactory(); public SocketClientService _Socket { get; set; } private readonly IMapper _mapper; private readonly IDt_DeviceInfoRepository _deviceInfoRepository; private readonly IDt_HandAutomaticRepository _handAutomaticRepository; private readonly IDt_ErrorDescriptionRepository _descriptionRepository; public AGVService(ILocationInfoRepository locationRepository, IDt_TaskRepository taskRepository, IDt_StationManagerRepository stationManagerRepository, IDt_DeviceInfoRepository deviceInfoRepository, IMapper mapper, SocketClientService socketClientService, IDt_TaskService taskService, IDt_HandAutomaticRepository handAutomaticRepository, IDt_ErrorDescriptionRepository descriptionRepository) { _locationRepository = locationRepository; BaseDal = taskRepository; _stationManagerRepository = stationManagerRepository; _deviceInfoRepository = deviceInfoRepository; _mapper = mapper; _Socket = socketClientService; _taskService = taskService; _handAutomaticRepository = handAutomaticRepository; _descriptionRepository = descriptionRepository; } #region 外部接口方法 /// /// 请求入库任务 /// /// /// /// public WebResponseContent RequestInTask(AGVDTO aGVDTO) { WebResponseContent content = new WebResponseContent(); try { var location = _locationRepository.QueryData(x => x.LocationStatus == (int)LocationEnum.Free).ToList(); if (location.Count == 0) { return content.Error("库内无可用库位"); } Dt_StationManager Instation = _stationManagerRepository.QueryFirst(x => x.stationName == aGVDTO.SourceAddress && x.stationType == 1); List Outstation = _stationManagerRepository.QueryData(x => x.stationType == 2).ToList(); if (Instation == null) { return content.Error("未找到入库站台信息"); } Dt_Task task = BaseDal.QueryFirst(x => x.PalletCode == aGVDTO.PalletCode); if (task != null) { return content.Error("该托盘已存在任务"); } //StationStatus stationOut = _Socket.GetStationStatus("B001"); List outStationStatus = new List(); //List outStationStatus = _Socket.GetOutStationStatus(stationOut); #region var taskOutStationO = BaseDal.QueryFirst(x => x.SourceAddress == "B001::1" || x.TargetAddress == "B001::1"); var taskOutStationT = BaseDal.QueryFirst(x => x.SourceAddress == "B001::2" || x.TargetAddress == "B001::2"); outStationStatus.Add(new OutStationStatus() { StationName = "04", StationEnable = aGVDTO.WorkstationO == "1" ? "0" : "1", IsDistributionTask = taskOutStationO == null ? "0" : "1", Spare1 = "00" }); outStationStatus.Add(new OutStationStatus() { StationName = "03", StationEnable = aGVDTO.WorkstationT == "1" ? "0" : "1", IsDistributionTask = taskOutStationT == null ? "0" : "1", Spare1 = "00", }); #endregion AGVStatusRespone status = _Socket.GetAGVStatus(); HOSTAGVStatus AgvStatus = new HOSTAGVStatus() { RuntimeStatus = _Socket.CapitalizeFirstLetter(status.RuntimeStatus), AutoStatus = status.AutoStatus == "MaintenanceMode" ? "1" : "0", Ready = status.AutoStatus == "MaintenanceMode" ? "0" : "1", }; InStationStatus inStationStatus = new InStationStatus() { StationName = Instation.HostName, StationEnable = "0", IsDistributionTask = "0", PallteCode = aGVDTO.PalletCode, }; _Socket.DeviceRequestInbound(AgvStatus, outStationStatus, inStationStatus); LogFactory.GetLog("入库请求").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(aGVDTO)}", ""); return content.OK("已下发入库任务"); } catch (Exception ex) { return content.Error(ex.Message); } } public WebResponseContent ReceiveAGVRuntimeStatus(AGVStatus Status) { WebResponseContent content = new WebResponseContent(); try { //var HandAutomatic = _handAutomaticRepository.QueryFirst(x => true && x.HandAutomatic == "Automatic"); //if (HandAutomatic == null) //{ // _Socket.DeviceAutoStatusReport("1"); // return content.OK(); //} Dt_DeviceInfo device = _deviceInfoRepository.QueryFirst(x => x.DeviceName == Status.AGVName); if (device != null) { if (device.RuntimeStatus != Status.RuntimeStatus) { device.RuntimeStatus = Status.RuntimeStatus; device.AutoStatus = Status.AutoStatus; _deviceInfoRepository.UpdateData(device); switch (Status.RuntimeStatus) { case "Run": //运行 _Socket.DeviceStateReport("R"); Thread.Sleep(1000); _Socket.JobReady("0"); break; case "Idle": //空闲 _Socket.DeviceStateReport("I"); _Socket.JobReady("1"); break; case "Trouble": //故障 _Socket.DeviceStateReport("T"); Thread.Sleep(1000); _Socket.JobReady("0"); break; case "Pause": //暂停 _Socket.DeviceStateReport("S"); Thread.Sleep(1000); _Socket.JobReady("0"); break; case "Charge": //充电 _Socket.DeviceStateReport("C"); Thread.Sleep(1000); _Socket.JobReady("0"); break; case "PowerOn": //开机 _Socket.DeviceStateReport("P"); Thread.Sleep(1000); _Socket.JobReady("0"); break; case "PowerOFF": //关机 _Socket.DeviceStateReport("O"); Thread.Sleep(1000); _Socket.JobReady("0"); break; default: break; } } if (device.AutoStatus != Status.AutoStatus) { device.RuntimeStatus = Status.RuntimeStatus; device.AutoStatus = Status.AutoStatus; _deviceInfoRepository.UpdateData(device); switch (Status.AutoStatus) { case "MaintenanceMode": //手动 _Socket.DeviceAutoStatusReport("1"); Thread.Sleep(500); break; case "ControlMode": //自动 _Socket.DeviceAutoStatusReport("0"); Thread.Sleep(500); break; default: break; } } } else { Dt_DeviceInfo deviceInfo = new Dt_DeviceInfo() { DeviceName = Status.AGVName, RuntimeStatus = Status.RuntimeStatus, AutoStatus = Status.AutoStatus, }; _deviceInfoRepository.AddData(deviceInfo); } LogFactory.GetLog("AGV状态变更").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(Status)}", ""); return content.OK(); } catch (Exception ex) { return content.Error(ex.Message); } } public WebResponseContent AGVStartOrEndJob(AGVDTO aGVDTO) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == Convert.ToInt32(aGVDTO.TaskNum)); if (task != null) { switch (task.TaskType) { case (int)TaskInboundTypeEnum.Inbound: //入库 var station = _stationManagerRepository.QueryFirst(x => x.stationName == task.SourceAddress); if (aGVDTO.Status == "Start") { if (task.Roadway == "PDA") { _taskService.TaskStatus(task); return content.OK(); } else { _Socket.JobStartOrEnd(aGVDTO.Status.Substring(0, 1), "0000" + station.HostName, task.TargetAddress, "I", task.PalletCode); task.TaskState = (int)TaskInStatusEnum.AGV_InExecuting; } } else if (aGVDTO.Status == "Loadel") { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), "0000" + station.HostName, task.TargetAddress, "I", task.PalletCode); } else { if (task.Roadway == "PDA") { _Socket.PalletActionReportPDA("0000" + station.HostName, task.TargetAddress, "I", task.PalletCode); } else { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), "0000" + station.HostName, task.TargetAddress, "I", task.PalletCode); Thread.Sleep(2000); _Socket.PalletActionReport("0000" + station.HostName, task.TargetAddress, "I", task.PalletCode); } task.TaskState = (int)TaskInStatusEnum.AGV_InFinish; _taskService.CompleteInboundTask(task); } break; case (int)TaskOutboundTypeEnum.Outbound: //出库 var stationOut = _stationManagerRepository.QueryFirst(x => x.stationName == task.TargetAddress); if (aGVDTO.Status == "Start") { if (task.Roadway == "PDA") { _taskService.TaskStatus(task); return content.OK(); } else { _Socket.JobStartOrEnd(aGVDTO.Status.Substring(0, 1), task.SourceAddress, "0000" + stationOut.HostName, "O", task.PalletCode); task.TaskState = (int)TaskOutStatusEnum.AGV_OutExecuting; } } else if (aGVDTO.Status == "Loadel") { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), task.SourceAddress, "0000" + stationOut.HostName, "O", task.PalletCode); } else { if (task.Roadway == "PDA") { _Socket.PalletActionReportPDA(task.SourceAddress, "0000" + stationOut.HostName, "O", task.PalletCode); } else { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), task.SourceAddress, "0000" + stationOut.HostName, "O", task.PalletCode); Thread.Sleep(2000); _Socket.PalletActionReport(task.SourceAddress, "0000" + stationOut.HostName, "O", task.PalletCode); } task.TaskState = (int)TaskOutStatusEnum.AGV_OutFinish; _taskService.CompleteOutboundTask(task); } break; case (int)TaskRelocationTypeEnum.Relocation: if (aGVDTO.Status == "Start") { if (task.Roadway == "PDA") { _taskService.TaskStatus(task); return content.OK(); } else { _Socket.JobStartOrEnd(aGVDTO.Status.Substring(0, 1), task.SourceAddress, task.TargetAddress, "R", task.PalletCode); task.TaskState = (int)TaskRelocationStatusEnum.AGV_RelocationExecuting; } } else if (aGVDTO.Status == "Loadel") { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), task.SourceAddress, task.TargetAddress, "R", task.PalletCode); } else { if (task.Roadway == "PDA") { _Socket.PalletActionReportPDA(task.SourceAddress, task.TargetAddress, "R", task.PalletCode); } else { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), task.SourceAddress, task.TargetAddress, "R", task.PalletCode); Thread.Sleep(2000); _Socket.PalletActionReport(task.SourceAddress, task.TargetAddress, "R", task.PalletCode); } task.TaskState = (int)TaskRelocationStatusEnum.AGV_RelocationFinish; _taskService.CompleteRelocationboundTask(task); } break; case (int)TaskStationTypeEnum.StationToStation: var stationIn = _stationManagerRepository.QueryFirst(x => x.stationName == task.SourceAddress); var stationout = _stationManagerRepository.QueryFirst(x => x.stationName == task.TargetAddress); if (aGVDTO.Status == "Start") { if (task.Roadway == "PDA") { _taskService.TaskStatus(task); return content.OK(); } else { _Socket.JobStartOrEnd(aGVDTO.Status.Substring(0, 1), "0000" + stationIn.HostName, "0000" + stationout.HostName, "S", task.PalletCode); task.TaskState = (int)TaskOutStatusEnum.AGV_OutExecuting; } } else if (aGVDTO.Status == "Loadel") { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), "0000" + stationIn.HostName, "0000" + stationout.HostName, "S", task.PalletCode); } else { if (task.Roadway == "PDA") { _Socket.PalletActionReportPDA("0000" + stationIn.HostName, "0000" + stationout.HostName, "S", task.PalletCode); } else { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), "0000" + stationIn.HostName, "0000" + stationout.HostName, "S", task.PalletCode); Thread.Sleep(2000); _Socket.PalletActionReport("0000" + stationIn.HostName, "0000" + stationout.HostName, "S", task.PalletCode); } task.TaskState = (int)TaskOutStatusEnum.AGV_OutFinish; _taskService.TaskMoveHty(task); } break; case (int)TaskFireAlarmTypeEnum.FireAlarmOut: if (aGVDTO.Status == "Start") { _taskService.AddStcokHty(task.PalletCode, task.SourceAddress); task.TaskState = (int)TaskFireAlarmStatusEnum.AGV_FireAlarmExecuting; BaseDal.Update(task); } else if (aGVDTO.Status == "Loadel") { } else { var stationFireAlarm = _stationManagerRepository.QueryFirst(x => x.stationName == task.TargetAddress); if (task.Roadway == "PDA") { _Socket.PalletActionReportFrie(task.SourceAddress, "0000" + stationFireAlarm.HostName, "F", task.PalletCode); ; } task.TaskState = (int)TaskFireAlarmStatusEnum.AGV_FireAlarmFinish; _taskService.TaskMoveHty(task); } break; case (int)TaskOutboundTypeEnum.OutQuality: //抽检 var stationC = _stationManagerRepository.QueryFirst(x => x.stationName == task.TargetAddress); if (aGVDTO.Status == "Start") { if (task.Roadway == "PDA") { _taskService.TaskStatus(task); return content.OK(); } else { _Socket.JobStartOrEnd(aGVDTO.Status.Substring(0, 1), task.SourceAddress, "0000" + stationC.HostName, "C", task.PalletCode); task.TaskState = (int)TaskOutStatusEnum.AGV_OutExecuting; } } else if (aGVDTO.Status == "Loadel") { if (task.Roadway == "PDA") { return content.OK(); } _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), task.SourceAddress, "0000" + stationC.HostName, "C", task.PalletCode); } else { if (task.Roadway == "PDA") { _taskService.TaskComplete(task.TaskNum); _Socket.PalletActionReportPDA(task.SourceAddress, "0000" + stationC.HostName, "O", task.PalletCode); } else { _Socket.PalletActionReport(aGVDTO.Status.Substring(0, 1), task.SourceAddress, "0000" + stationC.HostName, "C", task.PalletCode); Thread.Sleep(2000); _Socket.PalletActionReport(task.SourceAddress, "0000" + stationC.HostName, "C", task.PalletCode); task.TaskState = (int)TaskOutStatusEnum.AGV_OutFinish; _taskService.CompleteOutboundTask(task); } } break; case (int)TaskInboundTypeEnum.InQuality: //抽检 if (aGVDTO.Status == "Start") { if (task.Roadway == "PDA") { _taskService.TaskStatus(task); return content.OK(); } } else if (aGVDTO.Status == "Loadel") { return content.OK(); } else { if (task.Roadway == "PDA") { _taskService.TaskComplete(task.TaskNum); } } break; default: break; } BaseDal.Update(task); LogFactory.GetLog("AGV动作状态变更").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(aGVDTO)}", ""); return content.OK(); } else { return content.Error("未找到任务!"); } } catch (Exception ex) { return content.Error(ex.Message); } } public WebResponseContent DeviceErrorResponse(AGVDTO aGVDTO) { WebResponseContent content = new WebResponseContent(); try { LogFactory.GetLog("AGV异常信息").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(aGVDTO)}", ""); var task = BaseDal.QueryFirst(x => x.TaskNum == Convert.ToInt32(aGVDTO.TaskNum)); if (task != null) { string HostType = string.Empty; if (task.TaskType == (int)TaskInboundTypeEnum.Inbound) { HostType = "I"; } else if (task.TaskType == (int)TaskOutboundTypeEnum.Outbound) { HostType = "O"; } else if (task.TaskType == (int)TaskOutboundTypeEnum.OutQuality) { HostType = "C"; } else if (task.TaskType == (int)TaskRelocationTypeEnum.Relocation) { HostType = "R"; } else if (task.TaskType == (int)TaskStationTypeEnum.StationToStation) { HostType = "S"; } switch (aGVDTO.Message) { //空出库 case "0000400": _Socket.EmptyOutBound(task.SourceAddress, "0000" + StationParse(task.TargetAddress), task.PalletCode); _taskService.AddStcokHty(task.PalletCode, task.SourceAddress); _taskService.TaskMoveHty(task); _Socket.AddErrorMessage("2101", "AGV", ""); break; //重入库 case "0000200": _Socket.RecreateGetLocation("0000" + StationParse(task.SourceAddress), task.TargetAddress, HostType, task.PalletCode); _Socket.AddErrorMessage("2100", "AGV", ""); break; default: break; } } return content.OK(); } catch (Exception ex) { LogFactory.GetLog("AGV异常信息").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(ex.Message)}", ""); return content.Error(ex.Message); } } public string StationParse(string station) { var Station = SqlSugarHelper.DbWMS.Queryable().Where(x => x.stationName == station).First(); if (Station != null) { return Station.HostName; } else { return ""; } } private static readonly SemaphoreSlim _semaphoreUpdate = new SemaphoreSlim(1, 1); public async Task DeviceWarning(AGVDTO DTO) { await _semaphoreUpdate.WaitAsync(); WebResponseContent content = new WebResponseContent(); try { LogFactory.GetLog("AG上传报警信息").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(DTO)}", ""); if (DTO.Message != null) { Dt_ErrorDescription description = _descriptionRepository.QueryFirst(x => x.Type == DTO.Message); if (description != null) { _Socket.ErrorReport(description.ErrorCode, "A", "00"); _Socket.AddErrorMessage(description.ErrorCode, "AGV", ""); return content.OK(); } else { return content.Error("未识别报警源"); } } else { return content.Error("未接收到异常信息"); } } catch (Exception ex) { LogFactory.GetLog("AG上传报警信息").InfoFormat(true, $"请求参数:{JsonConvert.SerializeObject(ex.Message)}", ""); return content.Error(ex.Message); } finally { _semaphoreUpdate.Release(); } } #endregion 外部接口方法 } }