using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using RobotNet.MapShares.Models; using RobotNet.RobotManager.Data; using RobotNet.RobotManager.Services; using RobotNet.RobotShares.Models; using RobotNet.Script.Expressions; using RobotNet.Shares; using Serialize.Linq.Serializers; using System.Linq.Expressions; namespace RobotNet.RobotManager.Controllers; [Route("api/[controller]")] [ApiController] [AllowAnonymous] public class RobotManagerController(RobotEditorDbContext RobotDb, MapManager MapManager, Services.RobotManager RobotManager, ILogger Logger) : ControllerBase { private static readonly ExpressionSerializer expressionSerializer; static RobotManagerController() { var jss = new Serialize.Linq.Serializers.JsonSerializer(); expressionSerializer = new ExpressionSerializer(jss); expressionSerializer.AddKnownType(typeof(RobotState)); } [HttpPost] [Route("MoveToNode")] public async Task MoveToNode([FromBody] RobotMoveToNodeModel model) { try { if (string.IsNullOrEmpty(model.NodeName)) return new(false, "NodeName cannot be empty.."); var robot = await RobotDb.Robots.FirstOrDefaultAsync(r => r.RobotId == model.RobotId); if (robot is null) return new(false, "RobotId does not exist."); var robotController = RobotManager[robot.RobotId]; if (robotController is null || !robotController.IsOnline) return new(false, "The robot is not online."); var map = await MapManager.GetMapData(robot.MapId); if (!map.IsSuccess) return new(false, map.Message); if (map is null || map.Data is null) return new(false, "The robot has not been assigned a map."); var node = map.Data.Nodes.FirstOrDefault(n => n.Name == model.NodeName && n.MapId == map.Data.Id); if (node is null) return new(false, "This Node does not exist."); if (!robotController.StateMsg.NewBaseRequest) return new(false, "The robot is busy."); var move = await robotController.MoveToNode(node.Name, model.Actions, model.LastAngle); if (move.IsSuccess) { robotController.Log($"RobotManager API Controller Log: Goi Robot {model.RobotId} di chuyển tới node {model.NodeName} thành công "); return new(true); } robotController.Log($"RobotManager API Controller Log: Goi Robot {model.RobotId} di chuyển tới node {model.NodeName} không thành công thành công do {move.Message}"); return new(false, "Request failed."); } catch (Exception ex) { Logger.LogError("RobotManager API Controller Log: Goi MoveToNode Robot {RobotId} di chuyển tới node {NodeName} xảy ra ngoại lệ: {Message}", model.RobotId, model.NodeName, ex.Message); return new(false, "An error occurred."); } } [HttpDelete] [Route("MoveToNode/{robotId}")] public async Task Cancel(string robotId) { try { var robot = await RobotDb.Robots.FirstOrDefaultAsync(r => r.RobotId == robotId); if (robot is null) return new(false, "RobotId does not exist."); var robotController = RobotManager[robot.RobotId]; if (robotController is null || !robotController.IsOnline) return new(false, "The robot is not online."); var cancel = await robotController.CancelOrder(); if (cancel.IsSuccess) { robotController.Log($"RobotManager API Controller Log: Hủy bỏ nhiệm vụ của Robot {robotId} thành công "); return new(true); } robotController.Log($"RobotManager API Controller Log: Hủy bỏ nhiệm vụ của Robot {robotId} không thành công do {cancel.Message}"); return new(false, "Request failed."); } catch (Exception ex) { Logger.LogError("RobotManager API Controller Log: Goi Cancel Robot {RobotId} xảy ra ngoại lệ: {Message}", robotId, ex.Message); return new(false, "An error occurred."); } } [HttpPost] [Route("InstantActions")] public async Task InstantAction([FromBody] RobotInstantActionModel model) { try { var robot = await RobotDb.Robots.FirstOrDefaultAsync(r => r.RobotId == model.RobotId); if (robot is null) return new(false, "RobotId does not exist."); var robotController = RobotManager[robot.RobotId]; if (robotController is null || !robotController.IsOnline) return new(false, "The robot is not online."); var instantAction = await robotController.InstantAction(model.Action, false); if (instantAction.IsSuccess) { robotController.Log($"RobotManager API Controller Log: Gửi Action Robot {model.RobotId} thành công "); return new(true); } robotController.Log($"RobotManager API Controller Log: Gửi Action Robot {model.RobotId} không thành công do {instantAction.Message}"); return new(false, "Request failed."); } catch (Exception ex) { Logger.LogError("RobotManager API Controller Log: Goi InstantAction Robot {RobotId}, Action type {action} xảy ra ngoại lệ: {Message}", model.RobotId, model.Action.ActionType, ex.Message); return new(false, "An error occurred."); } } [HttpGet] [Route("State/{robotId}")] public async Task> GetState(string robotId) { try { var robot = await RobotDb.Robots.FirstOrDefaultAsync(r => r.RobotId == robotId); if (robot is null) return new(false, "RobotId does not exist."); var robotController = RobotManager[robot.RobotId]; if (robotController is null) return new(false, "The robot has not logged into the system."); return new(true) { Data = new() { RobotId = robotId, MapId = robot.MapId, IsOnline = robotController.IsOnline, State = robotController.State, OrderState = robotController.OrderState, NewBaseRequest = robotController.StateMsg.NewBaseRequest, NodeStates = [.. robotController.StateMsg.NodeStates], EdgeStates = [.. robotController.StateMsg.EdgeStates], Loads = [.. robotController.StateMsg.Loads], ActionStates = robotController.ActionStates, BatteryState = robotController.StateMsg.BatteryState, Errors = [.. robotController.StateMsg.Errors], Information = [.. robotController.StateMsg.Information], SafetyState = robotController.StateMsg.SafetyState, AgvPosition = robotController.VisualizationMsg.AgvPosition, Velocity = robotController.VisualizationMsg.Velocity, } }; } catch (Exception ex) { Logger.LogError("RobotManager API Controller Log: Goi GetState Robot {RobotId} xảy ra ngoại lệ: {Message}", robotId, ex.Message); return new(false, "An error occurred."); } } [HttpPost] [Route("Search")] public async Task> SearchRobot([FromBody] RobotSearchExpressionModel model) { var expr = expressionSerializer.DeserializeText(model.Expression); var lambda = (Expression>)expr; // Compile và chạy: var func = lambda.Compile(); return await RobotManager.SearchRobot(model.ModelName, model.MapName, func); } }