using NLog; using RobotNet.VDA5050.Type; using RobotNet10.RobotApp.Client.Pages; using RobotNet10.RobotApp.Interfaces; using RobotNet10.RobotApp.Modules; namespace RobotNet10.RobotApp.Services.Robot.Actions; [RobotAction(ActionType.PICK, [ActionScope.INSTANT, ActionScope.NODE, ActionScope.EDGE], [BlockingType.HARD], "Nâng cao pallet.", "Robot đã nâng cao pallet.")] public class RobotPickAction(IServiceProvider ServiceProvider) : RobotAction(ServiceProvider) { private const int MAX_TIMEOUT = 60000; private int CountTimeout = 0; private ILoad? LoadManager; private ILiftModule? LiftModule; private IPlcController? PlcController; private CancellationTokenSource CancellationToken = new(); protected override async Task StartAction() { try { LoadManager = ServiceProvider.GetRequiredService(); LiftModule = ServiceProvider.GetRequiredService(); PlcController = ServiceProvider.GetRequiredService(); if (!LiftModule.IsReady) { SetStatus(ActionEvent.FAILED); ResultDescription = "Lift module not ready"; return; } CancellationToken = new CancellationTokenSource(); PlcController.SetOperationState(OperationState.Lifting); _ = LiftModule.LiftUpAsync(CancellationToken.Token); CountTimeout = 0; await base.StartAction(); } catch (Exception ex) { SetStatus(ActionEvent.FAILED); ResultDescription = "Pick failed: " + ex.Message; } } protected override Task StopAction() { CancellationToken.Cancel(); return base.StopAction(); } protected override Task CleanupAction() { CancellationToken.Dispose(); PlcController?.SetOperationState(OperationState.None); return base.CleanupAction(); } protected override async Task ExecuteAction() { if (LiftModule is null) { SetStatus(ActionEvent.FAILED); ResultDescription = "Lift module not found"; } else if (LiftModule.State == LiftModuleState.Error) { SetStatus(ActionEvent.FAILED); ResultDescription = "Lift module error"; } else if (LiftModule.Position == LiftPosition.Top) { LoadManager?.AddLoad(new()); SetStatus(ActionEvent.FINISHED); ResultDescription = string.IsNullOrEmpty(ActionAttribute.ResultDescription) ? "Robot has picked up the load." : ActionAttribute.ResultDescription; } else if (CountTimeout++ > MAX_TIMEOUT / ActionInterval) { CancellationToken.Cancel(); SetStatus(ActionEvent.FAILED); ResultDescription = "Timeout action"; } await base.ExecuteAction(); } }