using MainShell.Common; using MainShell.Hardware; using MainShell.Process; using MainShell.ProcessResult; using MaxwellFramework.Core.Attributes; using System; using System.Collections.Generic; namespace MainShell.Motion { [Singleton] public sealed class MotionSafetyStateProvider { private readonly IDeviceIoMonitorService _deviceIoMonitorService; private readonly ProcessResultManager _processResultManager; private readonly MachineState _machineState; public MotionSafetyStateProvider(IDeviceIoMonitorService deviceIoMonitorService, ProcessResultManager processResultManager, MachineState machineState = null) { _deviceIoMonitorService = deviceIoMonitorService ?? throw new ArgumentNullException(nameof(deviceIoMonitorService)); _processResultManager = processResultManager ?? throw new ArgumentNullException(nameof(processResultManager)); _machineState = machineState; } public MachineMode CurrentMachineMode => _machineState != null ? _machineState.CurrentMode : MachineMode.Manual; public bool IsEmergencyStopReleased() { if (!_deviceIoMonitorService.IsOnline) { return false; } return !_deviceIoMonitorService.IsPointOn(DeviceIoNames.WZ.EmergencyStopButton) && !IsSafetyCircuitHealthy(); } public bool AreSafetyDoorsClosed() { if (!_deviceIoMonitorService.IsOnline) { return false; } if (_deviceIoMonitorService.IsPointOn(DeviceIoNames.WZ.SecurityDoorShield)) { return true; } return _deviceIoMonitorService.IsPointOn(DeviceIoNames.WZ.SafetyDoor1Closed) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.WZ.SafetyDoor2Closed) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.WZ.SafetyDoor3Closed) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.WZ.SafetyDoor4Closed); } public bool IsFlowRunning() { var status = _processResultManager.FlowState.Status; return string.Equals(status, ProcessExecutionStatus.Running.ToString(), StringComparison.OrdinalIgnoreCase); } public string CurrentFlowName => _processResultManager.FlowState.WorkflowName; public bool AreStageVacuumsReady() { if (!_deviceIoMonitorService.IsOnline) { return false; } return _deviceIoMonitorService.IsPointOn(DeviceIoNames.Stage.Vacuum1) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.Stage.Vacuum2) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.Stage.Vacuum3) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.Stage.Vacuum4); } public IReadOnlyList GetUnsafeBondHeadSignals() { if (!_deviceIoMonitorService.IsOnline) { return new[] { "DeviceIoOffline" }; } var unsafeSignals = new List(); AddIfOff(unsafeSignals, DeviceIoNames.WS.BondHead1InPlace); AddIfOff(unsafeSignals, DeviceIoNames.WS.BondHead2InPlace); AddIfOff(unsafeSignals, DeviceIoNames.WS.BondHead3InPlace); AddIfOff(unsafeSignals, DeviceIoNames.WS.BondHead4InPlace); return unsafeSignals; } public bool IsAutoWorkflowSource(string source) { if (string.IsNullOrWhiteSpace(source)) { return false; } return string.Equals(source, ProcessFlowName.AutoProduction, StringComparison.OrdinalIgnoreCase) || source.IndexOf("Auto", StringComparison.OrdinalIgnoreCase) >= 0; } private bool IsSafetyCircuitHealthy() { return _deviceIoMonitorService.IsPointOn(DeviceIoNames.General.SafetyCircuitStatus1) && _deviceIoMonitorService.IsPointOn(DeviceIoNames.General.SafetyCircuitStatus2); } private void AddIfOff(ICollection unsafeSignals, string signalName) { if (!_deviceIoMonitorService.IsPointOn(signalName)) { unsafeSignals.Add(signalName); } } } }