using RobotNet.VDA5050.Type; using RobotNet10.RobotApp.Devices; namespace RobotNet10.RobotApp.Services.Robot.Actions; /// /// Action homing camera (lift): gọi trực tiếp xuống động cơ CiA402 (giống device/hub). /// blockingType NONE: gửi lệnh homing và kết thúc ngay, không chờ hoàn thành. /// [RobotAction(ActionType.HOMING_CAMERA, [ActionScope.INSTANT, ActionScope.NODE, ActionScope.EDGE], [BlockingType.NONE], "Homing camera (lift).", "Homing camera requested.")] public class HomingCameraAction(IServiceProvider ServiceProvider) : RobotAction(ServiceProvider) { protected override async Task StartAction() { try { var config = ServiceProvider.GetRequiredService(); var deviceProvider = ServiceProvider.GetRequiredService(); var deviceId = config.GetValue("Modules:LiftModule:DeviceId") ?? "lift-motor"; var enable = config.GetValue("Modules:LiftModule:Enable", true); if (!enable) { SetStatus(ActionEvent.FAILED); ResultDescription = "Lift module is disabled in config."; return; } var device = deviceProvider.GetDevice(deviceId); if (device is not ICiA402Servo servo) { SetStatus(ActionEvent.FAILED); ResultDescription = $"Device '{deviceId}' not found or is not ICiA402Servo."; return; } var homingMethod = config.GetValue("Modules:LiftModule:HomingMethod", 21); var homingSpeed = config.GetValue("Modules:LiftModule:HomingSpeed", 30000); var homingOffset = config.GetValue("Modules:LiftModule:HomingOffset", 0); // Giống device UI: bước 1 SetParam (Apply Params), bước 2 Start Homing Logger?.LogInformation("HomingCamera: SetParam (method={Method}, speed={Speed}, offset={Offset}) then Start Homing.", homingMethod, homingSpeed, homingOffset); await servo.SetHomingMethodAsync(homingMethod, CancellationToken.None); await servo.SetHomingSpeedAsync(homingSpeed, CancellationToken.None); await servo.SetHomingOffsetAsync(homingOffset, CancellationToken.None); await Task.Delay(100, CancellationToken.None); // delay giữa SetParam và Start như khi bấm trên device await servo.StartHomingAsync(homingMethod, homingSpeed, CancellationToken.None); SetStatus(ActionEvent.FINISHED); ResultDescription = "Homing camera requested (direct to drive)."; } catch (Exception ex) { SetStatus(ActionEvent.FAILED); ResultDescription = $"Homing camera failed: {ex.Message}"; } await base.StartAction(); } }