diff --git a/backend/api/Controllers/MissionController.cs b/backend/api/Controllers/MissionController.cs index e2add2b17..b71457e1d 100644 --- a/backend/api/Controllers/MissionController.cs +++ b/backend/api/Controllers/MissionController.cs @@ -158,6 +158,7 @@ public async Task> GetMap([FromRoute] string id) [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task> Create( [FromBody] ScheduledMissionQuery scheduledMissionQuery @@ -234,6 +235,52 @@ [FromBody] ScheduledMissionQuery scheduledMissionQuery return CreatedAtAction(nameof(GetMissionById), new { id = newMission.Id }, newMission); } + /// + /// Schedule a custom mission + /// + /// + /// This query schedules a custom mission defined in the incoming json + /// + [HttpPost] + [Route("custom")] + [ProducesResponseType(typeof(Mission), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> Create( + [FromBody] CustomMissionQuery customMissionQuery + ) + { + var robot = await _robotService.ReadById(customMissionQuery.RobotId); + if (robot is null) + return NotFound($"Could not find robot with id {customMissionQuery.RobotId}"); + + var missionTasks = customMissionQuery.Tasks.Select(task => new MissionTask(task)).ToList(); + + var scheduledMission = new Mission + { + Name = customMissionQuery.Name, + Robot = robot, + EchoMissionId = 0, + Status = MissionStatus.Pending, + DesiredStartTime = customMissionQuery.DesiredStartTime, + Tasks = missionTasks, + AssetCode = customMissionQuery.AssetCode, + Map = new MissionMap() + }; + + await _mapService.AssignMapToMission(scheduledMission); + + if (scheduledMission.Tasks.Any()) + scheduledMission.CalculateEstimatedDuration(); + + var newMission = await _missionService.Create(scheduledMission); + + return CreatedAtAction(nameof(GetMissionById), new { id = newMission.Id }, newMission); + } + /// /// Deletes the mission with the specified id from the database. /// diff --git a/backend/api/Controllers/Models/CustomMissionQuery.cs b/backend/api/Controllers/Models/CustomMissionQuery.cs new file mode 100644 index 000000000..75c036d3b --- /dev/null +++ b/backend/api/Controllers/Models/CustomMissionQuery.cs @@ -0,0 +1,41 @@ +using Api.Database.Models; + +namespace Api.Controllers.Models +{ + public struct CustomInspectionQuery + { + public InspectionType InspectionType { get; set; } + + public float? VideoDuration { get; set; } + + public string? AnalysisTypes { get; set; } + } + + public struct CustomTaskQuery + { + public int TaskOrder { get; set; } + + public Position InspectionTarget { get; set; } + + public Pose RobotPose { get; set; } + + public List Inspections { get; set; } + } + + public struct CustomMissionQuery + { + public string RobotId { get; set; } + + public DateTimeOffset DesiredStartTime { get; set; } + + public string AssetCode { get; set; } + + public string Name { get; set; } + + public string? Description { get; set; } + + public string? Comment { get; set; } + + public List Tasks { get; set; } + } +} diff --git a/backend/api/Database/Models/Inspection.cs b/backend/api/Database/Models/Inspection.cs index 80d31bd70..a637c055f 100644 --- a/backend/api/Database/Models/Inspection.cs +++ b/backend/api/Database/Models/Inspection.cs @@ -69,6 +69,14 @@ public Inspection(EchoInspection echoInspection) Status = InspectionStatus.NotStarted; } + public Inspection(CustomInspectionQuery inspectionQuery) + { + InspectionType = inspectionQuery.InspectionType; + VideoDuration = inspectionQuery.VideoDuration; + AnalysisTypes = inspectionQuery.AnalysisTypes; + Status = InspectionStatus.NotStarted; + } + public void UpdateWithIsarInfo(IsarStep isarStep) { UpdateStatus(isarStep.StepStatus); diff --git a/backend/api/Database/Models/MissionTask.cs b/backend/api/Database/Models/MissionTask.cs index 4c83ecfc6..b71f93f49 100644 --- a/backend/api/Database/Models/MissionTask.cs +++ b/backend/api/Database/Models/MissionTask.cs @@ -83,6 +83,18 @@ public MissionTask(EchoTag echoTag, Position tagPosition) Status = TaskStatus.NotStarted; } + // ReSharper disable once NotNullOrRequiredMemberIsNotInitialized + public MissionTask(CustomTaskQuery taskQuery) + { + Inspections = taskQuery.Inspections + .Select(inspection => new Inspection(inspection)) + .ToList(); + InspectionTarget = taskQuery.InspectionTarget; + RobotPose = taskQuery.RobotPose; + TaskOrder = taskQuery.TaskOrder; + Status = TaskStatus.NotStarted; + } + public void UpdateWithIsarInfo(IsarTask isarTask) { UpdateStatus(isarTask.TaskStatus);