using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis.Text;
using ServerApp.Interfaces;
using ServerApp.Interfaces.Repositories;
using ServerApp.Models.Controller;
using ServerApp.Models.Entities;
using ServerApp.Pages.Management;
using ServerApp.Services;
namespace ServerApp.Controllers
public class CallbackService : Controller
private readonly MqttClientService _mqttService;
private readonly ILogger<CallbackService> _logger;
private ILogDataService _logDataService;
private IUnitOfWork _unit;
private ICTUService _ctuService;
private object lockHung = new object();
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
public CallbackService(ILogger<CallbackService> logger, ILogDataService logDataService,
IUnitOfWork initwork, ICTUService ctuService, MqttClientService mqttService)
_logDataService = logDataService;
_ctuService = ctuService;
_logger.LogInformation("Callback Controller is running");
_mqttService = mqttService;
[HttpPost("agv/agvCallbackService/agvCallback")]
public async Task<IActionResult> CTUCallbackAsync([FromBody] CTUCallbackModel data)
CallBackMsgResp resp = new CallBackMsgResp();
resp.reqCode = data.reqCode;
_logger.LogWarning(JsonConvert.SerializeObject(data));
_logDataService.Update(JsonConvert.SerializeObject(data));
await _semaphore.WaitAsync();
var _missions = await _unit.CTUMissions.FindAsync(m => m.CMDReturn == data.taskCode);
var _maMgz = data.ctnrCode;
var _mgzid = await _unit.MaterialMgzes.FindFirstAsync(s => s.mgzID == _maMgz);
var _buff = await _unit.MaterialMagBuffes.FindFirstAsync(s => s.PositionCode == data.stgBinCode);
CTUMissionEntity _ctu = new CTUMissionEntity();
_ctu.StartPosCode = data.stgBinCode;
_ctu.EndPosCode = data.dstBinCode;
_ctu.CreateAt = DateTime.Now;
_ctu.TaskType = BufferTypes.INPUT;
_ctu.ModifiedAt = DateTime.Now;
_ctu.UseStatus = UseStatus.USE;
_ctu.MissionStatus = MissionStatus.START;
_ctu.CMDReturn = data.taskCode;
_ctu.MagazineId = _mgzid != null ? _mgzid.Id : Guid.Empty;
_ctu.Remark = _buff != null ? _buff.BufferIP : "0.0.0.0";
_ctu.IdMatching = _buff != null ? _buff.IdMatch_1 : 0;
_ctu.IpBuffer = _buff != null ? _buff.BufferIP : "0.0.0.0";
await _unit.CTUMissions.AddAsync(_ctu);
await _unit.CompleteAsync();
var _buffout = await _unit.MaterialMagBuffes.FindFirstAsync(s => s.PositionCode == data.dstBinCode);
CTUMissionEntity _ctu = new CTUMissionEntity();
_ctu.StartPosCode = data.stgBinCode;
_ctu.EndPosCode = data.dstBinCode;
_ctu.CreateAt = DateTime.Now;
_ctu.TaskType = BufferTypes.OUTPUT;
_ctu.ModifiedAt = DateTime.Now;
_ctu.UseStatus = UseStatus.USE;
_ctu.MissionStatus = MissionStatus.START;
_ctu.CMDReturn = data.taskCode;
_ctu.MagazineId = _mgzid != null ? _mgzid.Id : Guid.Empty;
_ctu.Remark = _buffout != null ? _buffout.BufferIP : "0.0.0.0";
_ctu.IdMatching = _buffout != null ? _buffout.IdMatch_1 : 0;
_ctu.IpBuffer = _buffout != null ? _buffout.BufferIP : "0.0.0.0";
await _unit.CTUMissions.AddAsync(_ctu);
await _unit.CompleteAsync();
foreach(var mission in _missions )
if (data.method == "start")
if (mission.TaskType == BufferTypes.INPUT)
if (mission.MissionStatus != MissionStatus.IN_GET)
mission.MissionStatus = MissionStatus.START;
mission.ModifiedAt = DateTime.Now;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
else if (data.method == "cancel")
if (mission.TaskType == BufferTypes.INPUT)
var _rack = await _unit.MaterialMagRacks.FindFirstAsync(s => s.PositionCode == mission.EndPosCode);
_rack.RackStatus = RackStatus.UNDEFINED;
_rack.ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack);
_unit.CTUMissions.Delete(mission);
else if (mission.TaskType == BufferTypes.OUTPUT)
var _mgz = await _unit.MaterialMgzes.FindFirstAsync(m => m.Id == mission.MagazineId);
var _buffer = await _unit.MaterialMagBuffes.FindFirstAsync(m => m.BufferIP == mission.IpBuffer);
if (mission.MissionStatus >= MissionStatus.OUT_IN_CTU)
var _his2 = JsonConvert.DeserializeObject<MaterialMgzHisEntity>(JsonConvert.SerializeObject(_mgz));
_his2.Id = Guid.NewGuid();
_his2.ParentId = _mgz.Id;
_his2.ModifiedAt = DateTime.Now;
_his2.Tracking = MagazineTracking.COMPLETED;
await _unit.MaterialMgzHises.AddAsync(_his2);
_unit.MaterialMgzes.Delete(_mgz);
_mgz.Tracking = MagazineTracking.IN_RACK;
_mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgz);
var _his1 = JsonConvert.DeserializeObject<CTUMissionHisEntity>(JsonConvert.SerializeObject(mission));
_his1.Id = Guid.NewGuid();
_his1.ModifiedAt = DateTime.Now;
await _unit.CTUMissionHises.AddAsync(_his1); ;
_unit.CTUMissions.Delete(mission);
await _unit.CompleteAsync();
var _miscount = (await _unit.CTUMissions.FindAsync(m => m.IpBuffer == _buffer.BufferIP)).Count();
if (_miscount == 0 && _buffer.UseStatus != BufferUseStatus.MANUAL)
if (_buffer.UseStatus == BufferUseStatus.AUTO2MANUAL)
_buffer.UseStatus = BufferUseStatus.MANUAL;
_buffer.ModifiedAt = DateTime.Now;
_unit.MaterialMagBuffes.Update(_buffer);
await _unit.CompleteAsync();
else if (data.method == "outbin")
if (mission.TaskType == BufferTypes.OUTPUT || mission.TaskType == BufferTypes.BOTH)
mission.MissionStatus = MissionStatus.OUT_IN_CTU;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
var _rack = await _unit.MaterialMagRacks.FindFirstAsync(s => s.PositionCode == mission.StartPosCode);
var _mgz = await _unit.MaterialMgzes.FindFirstAsync(s => s.Id == _rack.MagazineId);
_rack.RackStatus = RackStatus.EMPTY;
_rack.ModifiedAt = DateTime.Now;
_rack.MagazineId = Guid.Empty;
_unit.MaterialMagRacks.Update(_rack);
_mgz.Tracking = MagazineTracking.IN_CTU;
_mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgz);
await _unit.CompleteAsync();
var request = new MccBin_In()
zName = $"{_rack.RackNumber.ToString("D2")}",
bName = $"{_rack.RowNumber.ToString("D2")}-{_rack.ColNumber.ToString("D2")}"
await _mqttService.PublishAsync("res/smart-transfer/BIN_OUT", JsonConvert.SerializeObject(request));
mission.MissionStatus = MissionStatus.MAGAZINE_NOT_FOUND;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
_logDataService.Update($"CTU just take one BOX but can not found magazine regard this BOX => rack {_rack.RackNumber} column {_rack.ColNumber} row {_rack.RowNumber}");
mission.MissionStatus = MissionStatus.RACK_NOT_FOUND;
_logDataService.Update($"CTU just take one BOX but can not found RACK regard this BOX => rack {_rack.RackNumber} column {_rack.ColNumber} row {_rack.RowNumber}");
else if (mission.TaskType == BufferTypes.INPUT)
mission.MissionStatus = MissionStatus.OUT_BIN;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
mission.ModifiedAt = DateTime.Now;
_unit.CTUMissions.Update(mission);
else if (data.method == "complete")
var _mathung = data.ctnrCode;
if (mission.TaskType == BufferTypes.INPUT)
var _rack = await _unit.MaterialMagRacks.FindFirstAsync(s => s.PositionCode == mission.EndPosCode);
var _mgz = await _unit.MaterialMgzes.FindFirstAsync(s => s.Id == mission.MagazineId);
if (_rack != null && _mgz != null)
if (_mgz.Type == MagType.NO_GMES)
var _plan = await _unit.MccMaterialTransPlans.FindFirstAsync(s => s.code == _mgz.code && s.site == _mgz.Site);
if (_mgz.Qty + _plan.actqty < _plan.qty)
_mgz.depTime = _plan.deptime;
_mgz.Type = MagType.GMES;
_mgz.GIPart = _plan.giPart;
_mgz.GRPart = _plan.grPart;
_mgz.GRLineStorage = _plan.grLineStorage;
_mgz.Arrival = _plan.arrivalTime;
_plan.actqty += _mgz.Qty;
_unit.MccMaterialTransPlans.Update(_plan);
_rack.RackStatus = _mgz.Type == MagType.NO_GMES ? RackStatus.HASNT_DPT : RackStatus.HAS_DPT;
_rack.ModifiedAt = DateTime.Now;
_rack.MagazineId = _mgz.Id;
_unit.MaterialMagRacks.Update(_rack);
_mgz.Tracking = MagazineTracking.IN_RACK;
_mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgz);
var requestmgzID = mission.MagazineId;
var request = new MccBin_In()
zName = $"{_rack.RackNumber.ToString("D2")}",
bName = $"{_rack.RowNumber.ToString("D2")}-{_rack.ColNumber.ToString("D2")}"
await _mqttService.PublishAsync("res/smart-transfer/BIN_IN", JsonConvert.SerializeObject(request));
var _similarmission = await _unit.CTUMissions.FindAsync(m => m.CMDReturn == data.taskCode);
if (_similarmission != null)
foreach (var mis in _similarmission)
var _hismission = JsonConvert.DeserializeObject<CTUMissionHisEntity>(JsonConvert.SerializeObject(mission));
_hismission.Id = Guid.NewGuid();
await _unit.CTUMissionHises.AddAsync(_hismission); ;
_unit.CTUMissions.Delete(mis);
await _unit.CompleteAsync();
else if (mission.TaskType == BufferTypes.OUTPUT)
var _rack = await _unit.MaterialMagRacks.FindFirstAsync(s => s.PositionCode == mission.StartPosCode);
var _mgz = await _unit.MaterialMgzes.FindFirstAsync(s => s.Id == mission.MagazineId);
if (_rack != null && _mgz != null)
_mgz.Status = MagazineStatus.TRANSFERED;
_mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgz);
if (mission.MissionStatus < MissionStatus.OUT_IN_BUFFER)
mission.MissionStatus = MissionStatus.OUT_SCAN;
mission.ModifiedAt = DateTime.Now;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
_unit.CTUMissions.Delete(mission);
else if (data.method == "put")
resp.reqCode = DateTime.Now.ToString("yyyyMMDDHHmmssfff");
mission.MissionStatus = MissionStatus.OUT_PUT;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
else if (data.method == "get")
resp.reqCode = DateTime.Now.ToString("yyyyMMDDHHmmssfff");
mission.MissionStatus = MissionStatus.IN_GET;
_unit.CTUMissions.Update(mission);
await _unit.CompleteAsync();
var e = await _ctuService.SetTimeOut("60", data.callCode);
_logDataService.Update($"bufCallback {JsonConvert.SerializeObject(e)}");
var b = await _unit.CompleteAsync();
_logDataService.Update($"agvCallback Save => {b}");
[HttpPost("buf/bufCallbackService/bufCallback")]
public async Task<IActionResult> BufferCheckAsync([FromBody] BoxApplyPassMsg data)
_logDataService.Update($"bufCallback {JsonConvert.SerializeObject(data)}");
_logger.LogWarning($"bufCallback {JsonConvert.SerializeObject(data)}");
CommonResMsg resp = new CommonResMsg();
resp.reqCode = data.reqCode;
var _mission = await _unit.CTUMissions.GetByCMDReturn(data.taskCode);
_mission.MissionStatus = MissionStatus.OUT_PUT;
await _unit.CompleteAsync();
var _ctucode = _mission.EndPosCode;
resp.taskCode = data.taskCode;
var _bufferOut = await _unit.MaterialMagBuffes.FindFirstAsync(s => s.PositionCode == _ctucode && s.BufferType == BufferTypes.OUTPUT);
if(_bufferOut.PosStatus == BufferStatus.NO_BOX )
_logDataService.Update($"[WRN] buffer output ip {_mission.Remark} - {_ctucode} allow");
_logDataService.Update($"[WRN] buffer output ip {_mission.Remark} - {_ctucode} not ready");
_logDataService.Update($"[ERR] buffer output ip {_mission.Remark} - {_ctucode} not found");
_logger.LogWarning($"[ERR] buffer output ip {_mission.Remark} - {_ctucode} not found");
resp.message = $"[ERR] buffer output ip {_mission.Remark} - {_ctucode} not found";
_logDataService.Update($"[ERR] mission task code {data.taskCode} not found");
_logger.LogWarning($"[ERR] mission task code {data.taskCode} not found");
resp.message = $"[ERR] mission task code {data.taskCode} not found";
public async Task<IActionResult> BufferStatusUpdate([FromBody] BufferInterfaceModel_temp data_temp)
var clientIp = HttpContext.Connection.RemoteIpAddress?.ToString();
_logger.LogInformation($"Client IP: {clientIp}");
_logDataService.Update($"Client IP: {clientIp}");
_logDataService.Update(JsonConvert.SerializeObject(data_temp));
_logger.LogWarning(JsonConvert.SerializeObject(data_temp));
dynamic response = new ExpandoObject();
foreach (var item in data_temp.plc)
var _buffer = await _unit.MaterialMagBuffes.GetBufferInfor_new(clientIp, item.id);
if (_buffer.BufferType == BufferTypes.INPUT)
var _mag = await _unit.MaterialMgzes.FindFirstAsync(S => S.mgzID == item.mgz);
var _mis = await _unit.CTUMissions.FindFirstAsync(s => s.MagazineId == _mag.Id);
var _rack = await _unit.MaterialMagRacks.GetRackPriority(_numberBox, 0);
if (_rack.Count() == _numberBox)
for (int i = 0; i < _numberBox; i++)
CTUMissionEntity _ctu = new CTUMissionEntity();
_ctu.StartPosCode = _buffer.PositionCode;
_ctu.EndPosCode = _rack[i].PositionCode;
_ctu.CreateAt = DateTime.Now;
_ctu.TaskType = BufferTypes.INPUT;
_ctu.ModifiedAt = DateTime.Now;
_ctu.UseStatus = UseStatus.USE;
_ctu.MissionStatus = MissionStatus.PENDING;
_ctu.MagazineId = _mag.Id;
_ctu.Remark = _rack[i].Id.ToString();
var a = await _ctuService.RunTask(_ctu.StartPosCode, _ctu.EndPosCode, _ctu.TaskType, _mag.mgzID, "");
_logDataService.Update(JsonConvert.SerializeObject(a));
if (a.TaskResponseInfo.code != "99")
_rack[i].MissionId = _ctu.Id;
_rack[i].RackStatus = RackStatus.UNDEFINED;
_rack[i].ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack[i]);
_ctu.MissionStatus = MissionStatus.SEND_CTU_OK;
_ctu.CMDReturn = a.TaskResponseInfo.data;
await _unit.CTUMissions.AddAsync(_ctu);
_rack[i].MissionId = _ctu.Id;
_rack[i].RackStatus = RackStatus.IN_WAITING;
_rack[i].ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack[i]);
var b = await _unit.CompleteAsync();
_logDataService.Update($"Mission Save => {b}");
var request = new MccBufferIn_req()
await _mqttService.PublishAsync("req/mcc/smart-transfer/BUFF_IN", JsonConvert.SerializeObject(request));
else if (_buffer.BufferType == BufferTypes.OUTPUT)
if (!string.IsNullOrEmpty(item.mgz))
var response_BUFF_OUT = new MccBufferOut_res()
await _mqttService.PublishAsync("res/mcc/smart-transfer/BUFF_OUT", JsonConvert.SerializeObject(response_BUFF_OUT));
var _mgz = await _unit.MaterialMgzes.FindFirstAsync(s => s.MagazineCode == item.mgz);
_unit.MaterialMgzes.Delete(_mgz);
_logDataService.Update($"Remove magazine {item.mgz} successfully");
var sl_mission = (await _unit.CTUMissions.FindAsync(m => m.Remark == $"{clientIp}-{item.id}")).Count();
if (sl_mission < item.slot)
var sl_need = item.slot - sl_mission;
var mgzlist = (await _unit.MaterialMgzes.FindAsync(m => m.Type == MagType.GMES && m.Tracking == MagazineTracking.IN_RACK && m.depTime <= DateTime.Now.AddMinutes(30))).OrderBy(m => m.depTime).ThenBy(m => m.code).ToList();
for (int i = 0; i < Math.Min(mgzlist.Count, sl_need); i++)
var _rack = await _unit.MaterialMagRacks.FindFirstAsync(s => s.MagazineId == mgzlist[i].Id);
CTUMissionEntity _ctu = new CTUMissionEntity();
_ctu.StartPosCode = _rack.PositionCode;
_ctu.EndPosCode = _buffer.PositionCode;
_ctu.CreateAt = DateTime.Now;
_ctu.TaskType = BufferTypes.OUTPUT;
_ctu.ModifiedAt = DateTime.Now;
_ctu.UseStatus = UseStatus.USE;
_ctu.MissionStatus = MissionStatus.PENDING;
_ctu.MagazineId = mgzlist[i].Id;
_ctu.Remark = $"{clientIp}-{item.id}";
var c = await _ctuService.RunTask(_ctu.StartPosCode, _ctu.EndPosCode, _ctu.TaskType, mgzlist[i].mgzID, "");
_logDataService.Update(JsonConvert.SerializeObject(c));
if (c.TaskResponseInfo.code != "99")
_rack.MissionId = _ctu.Id;
_rack.RackStatus = RackStatus.UNDEFINED;
_rack.ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack);
_ctu.MissionStatus = MissionStatus.SEND_CTU_OK;
_ctu.CMDReturn = c.TaskResponseInfo.data;
await _unit.CTUMissions.AddAsync(_ctu);
_rack.MissionId = _ctu.Id;
_rack.RackStatus = RackStatus.OUT_WAITING;
_rack.ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack);
mgzlist[i].Tracking = MagazineTracking.IN_MISSION_OUT;
_unit.MaterialMgzes.Update(mgzlist[i]);
var d = await _unit.CompleteAsync();
_logDataService.Update($"Mission Save => {d}");
_logDataService.Update($"The quantity of available buffer slot is not positive ");
Console.WriteLine(ex.Message);
response.msg = ex.Message;
[HttpPost("buf/getinfor")]
public IActionResult BufferGetInfo([FromBody] string ip)
_logDataService.Update(JsonConvert.SerializeObject(ip));
_logger.LogWarning(JsonConvert.SerializeObject(ip));
[HttpPost("buf/get-boxcode-infor")]
public async Task<IActionResult> BufferGetBoxCodeInfoAsync([FromBody] string dsboxcode)
_logDataService.Update(JsonConvert.SerializeObject(dsboxcode));
_logger.LogWarning(JsonConvert.SerializeObject(dsboxcode));
dynamic response = new ExpandoObject();
if(!string.IsNullOrEmpty(dsboxcode))
var lstLineName = new List<string>();
var _dsboxcode = dsboxcode.Split(';').ToList();
foreach(var _mathung in _dsboxcode)
var _box1 = await _unit.MaterialMagBoxes.FindFirstAsync(s => s.BoxName == _mathung);
var _mgz = await _unit.MaterialMgzes.FindFirstAsync(s => s.Id == _box1.MagazineId);
var _magazinExist1 = await _unit.MaterialTransPlanKitMgzHises.GetMagazinInfo(_mgz.MagazineCode);
if (_magazinExist1 != null)
var _magTransPlan = await _unit.MaterialTransPlans.FindFirstAsync(s => s.Id == _magazinExist1.PlanId);
if (_magTransPlan != null)
_lineName = _magTransPlan.LineName;
lstLineName.Add(_lineName);
response.info = lstLineName;
response.msg = "data null";