/// <summary>
        /// Datasafe Power On specified blade
        /// </summary>
        /// <param name="bladeId">Blade ID(1-48)</param>
        /// <returns>Blade Response, indicates success/failure.</returns>
        public DatasafeBladeResponse SetBladeDatasafePowerOn(int bladeId)
        {
            Tracer.WriteInfo("Received SetBladeDatasafePowerOn(bladeId: {0})", bladeId);
            Tracer.WriteUserLog("Invoked SetBladeDatasafePowerOn(bladeId: {0})", bladeId);

            DatasafeBladeResponse response = new DatasafeBladeResponse();
            byte maxbladeCount = (byte)ConfigLoaded.Population;
            response.bladeNumber = bladeId;
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            if (!ConfigLoaded.DatasafeOperationsEnabled)
            {
                Tracer.WriteInfo("SetBladeDatasafePowerOn: User requested API not enabled in app.config");
                response.completionCode = Contracts.CompletionCode.CommandNotValidAtThisTime;
                response.statusDescription = "Datasafe commands are not enabled for this blade";
                return response;
            }

            // Check for correct blade id
            if (ChassisManagerUtil.CheckBladeId(bladeId) == CompletionCode.InvalidBladeId)
            {
                Tracer.WriteWarning("SetBladeDatasafePowerOn. Invalid blade Id {0}", bladeId);
                response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                response.statusDescription = Contracts.CompletionCode.ParameterOutOfRange.ToString();
                return response;
            }

            // Datasafe APIs only valid for compute blades
            if (!FunctionValidityChecker.CheckBladeTypeValidity((byte)bladeId))
            {
                Tracer.WriteWarning("SetBladeDatasafePowerOn({0}) failed, Invalid blade Type", bladeId);

                response.completionCode = Contracts.CompletionCode.CommandNotValidForBlade;
                response.statusDescription = Contracts.CompletionCode.CommandNotValidForBlade.ToString();
                return response;
            }

            // Call ProcessDatasafeAction() so that the current action (command) can be added to the set of pending
            // actions and the processing loop for the pending actions appropriately kicked-off
            DatasafeBladeStatus datasafeResponse = DatasafeOperationSupport.ProcessDatasafeAction(bladeId, DatasafeActions.PowerOn);
            if (datasafeResponse == null)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = Contracts.CompletionCode.Failure.ToString();
                return response;
            }

            if (datasafeResponse.isBackupPending)
            {
                response.RemainingDataSafeDurationInSecs = datasafeResponse.remainingBackupDuration;
            }
            else
            {
                response.RemainingDataSafeDurationInSecs = 0;
            }

            if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandExecuted)
            {
                response.completionCode = Contracts.CompletionCode.Success;
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandDelayed)
            {
                response.completionCode = Contracts.CompletionCode.RequestDelayedDueToPendingDatasafeOperation;
                response.statusDescription = response.completionCode.ToString();
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandFailed)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = response.completionCode.ToString();
            }

            return response;
        }
        /// <summary>
        /// Datasafe Power Off specified blade
        /// </summary>
        /// <param name="bladeId">Blade ID(1-48)</param>
        /// <returns>Blade Response, indicates success/failure.</returns>
        public DatasafeBladeResponse SetBladeDatasafePowerOff(int bladeId)
        {
            Tracer.WriteInfo("Received SetBladeDatasafePowerOff(bladeId: {0})", bladeId);
            Tracer.WriteUserLog("Invoked SetBladeDatasafePowerOff(bladeId: {0})", bladeId);

            DatasafeBladeResponse response = new DatasafeBladeResponse();
            byte maxbladeCount = (byte)ConfigLoaded.Population;
            response.bladeNumber = bladeId;
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            if (!ConfigLoaded.DatasafeOperationsEnabled)
            {
                Tracer.WriteInfo("SetBladeDatasafePowerOff: User requested API not enabled in app.config");
                response.completionCode = Contracts.CompletionCode.CommandNotValidAtThisTime;
                response.statusDescription = "Datasafe commands are not enabled for this blade";
                return response;
            }

            // Datasafe APIs only valid for compute blades. ValidateRequest() also checks if blade is already hard powered off.
            Contracts.ChassisResponse varResponse = ValidateRequest("SetBladeDatasafePowerOff", bladeId);
            if (varResponse.completionCode != Contracts.CompletionCode.Success)
            {
                response.completionCode = varResponse.completionCode;
                response.statusDescription = varResponse.statusDescription;
                return response;
            }

            // Check blade state. Only process command if blade is on
            BladeStateResponse bladeStateResponse = GetBladeState(bladeId);
            if (bladeStateResponse.completionCode != Contracts.CompletionCode.Success)
            {
                response.completionCode = bladeStateResponse.completionCode;
                response.statusDescription = bladeStateResponse.statusDescription;
                return response;
            }
            else
            {
                // If blade is already soft off, do not need any Nvdimm processing.
                // Set hard power off.
                if (bladeStateResponse.bladeState == PowerState.OFF)
                {
                    // Set hard power off.
                    if (BladePowerCommands.PowerOff(bladeId))
                    {
                        response.completionCode = Contracts.CompletionCode.Success;
                        Tracer.WriteInfo("Successfully set power to OFF for blade: " + bladeId);
                    }
                    else
                    {
                        Tracer.WriteError("Failed to set power to OFF for blade: " + bladeId);
                        response.completionCode = Contracts.CompletionCode.Failure;
                        response.statusDescription = response.completionCode.ToString();
                    }
                    return response;
                }
            }

            // Call ProcessDatasafeAction() so that the current action (command) can be added to the set of pending
            // actions and the processing loop for the pending actions appropriately kicked-off
            DatasafeBladeStatus datasafeResponse = DatasafeOperationSupport.ProcessDatasafeAction(bladeId, DatasafeActions.PowerOff);
            if (datasafeResponse == null)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = Contracts.CompletionCode.Failure.ToString();
                return response;
            }

            if (datasafeResponse.isBackupPending)
            {
                response.RemainingDataSafeDurationInSecs = datasafeResponse.remainingBackupDuration;
            }
            else
            {
                response.RemainingDataSafeDurationInSecs = 0;
            }

            if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandExecuted)
            {
                response.completionCode = Contracts.CompletionCode.Success;
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandDelayed)
            {
                response.completionCode = Contracts.CompletionCode.RequestDelayedDueToPendingDatasafeOperation;
                response.statusDescription = response.completionCode.ToString();
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandFailed)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = response.completionCode.ToString();
            }

            return response;
        }
        /// <summary>
        /// Datasafe Power cycle specified blade
        /// </summary>
        /// <param name="bladeId">if bladeId id -1, then bladeId not provided</param>
        /// <returns>Blade response indicating if blade operation was success/failure</returns>
        public DatasafeBladeResponse SetBladeDatasafeActivePowerCycle(int bladeId)
        {
            Tracer.WriteInfo("Received SetBladeDatasafeActivePowerCycle(bladeId: {0})", bladeId);
            Tracer.WriteUserLog("Invoked SetBladeDatasafeActivePowerCycle(bladeId: {0})", bladeId);

            DatasafeBladeResponse response = new DatasafeBladeResponse();
            response.bladeNumber = bladeId;
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            if (!ConfigLoaded.DatasafeOperationsEnabled)
            {
                Tracer.WriteInfo("SetBladeDatasafeActivePowerCycle: User requested API not enabled in app.config");
                response.completionCode = Contracts.CompletionCode.CommandNotValidAtThisTime;
                response.statusDescription = "Datasafe commands are not enabled for this blade";
                return response;
            }

            DatasafeActions action = DatasafeActions.PowerCycle;

            Contracts.ChassisResponse varResponse = ValidateRequest("SetBladeDatasafeActivePowerCycle", bladeId);
            if (varResponse.completionCode != Contracts.CompletionCode.Success)
            {
                response.completionCode = varResponse.completionCode;
                response.statusDescription = varResponse.statusDescription;
                return response;
            }

            // Check blade state. Only process command if blade is on
            BladeStateResponse bladeStateResponse = GetBladeState(bladeId);
            if (bladeStateResponse.completionCode != Contracts.CompletionCode.Success)
            {
                response.completionCode = bladeStateResponse.completionCode;
                response.statusDescription = bladeStateResponse.statusDescription;
                return response;
            }
            else
            {
                // If blade is already soft off, change action to blade on so that NvdimmSupport class
                // does not trigger ADR before executing a power cycle.
                // Hard power off is checked in ValidateRequest().
                if (bladeStateResponse.bladeState == PowerState.OFF)
                {
                    action = DatasafeActions.BladeOn;
                }
            }

            // Call ProcessDatasafeAction() so that the current action (command) can be added to the set of pending
            // actions and the processing loop for the pending actions appropriately kicked-off
            DatasafeBladeStatus datasafeResponse = DatasafeOperationSupport.ProcessDatasafeAction(bladeId, action);
            if (datasafeResponse == null)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = Contracts.CompletionCode.Failure.ToString();
                return response;
            }

            if (datasafeResponse.isBackupPending)
            {
                response.RemainingDataSafeDurationInSecs = datasafeResponse.remainingBackupDuration;
            }
            else
            {
                response.RemainingDataSafeDurationInSecs = 0;
            }

            if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandExecuted)
            {
                response.completionCode = Contracts.CompletionCode.Success;
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandDelayed)
            {
                response.completionCode = Contracts.CompletionCode.RequestDelayedDueToPendingDatasafeOperation;
                response.statusDescription = response.completionCode.ToString();
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandFailed)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = response.completionCode.ToString();
            }

            return response;
        }
        /// <summary>
        /// Datasafe Set blade soft power ON for specified blade
        /// </summary>
        /// <param name="bladeId">Blade ID(1-48)</param>
        /// <returns>Blade response indicating blade operation was success/failure</returns>
        public DatasafeBladeResponse SetBladeDatasafeOn(int bladeId)
        {
            Tracer.WriteInfo("Received SetBladeDatasafeOn(bladeId: {0})", bladeId);
            Tracer.WriteUserLog("Invoked SetBladeDatasafeOn(bladeId: {0})", bladeId);

            DatasafeBladeResponse response = new DatasafeBladeResponse();
            response.bladeNumber = bladeId;
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            if (!ConfigLoaded.DatasafeOperationsEnabled)
            {
                Tracer.WriteInfo("SetBladeDatasafeOn: User requested API not enabled in app.config");
                response.completionCode = Contracts.CompletionCode.CommandNotValidAtThisTime;
                response.statusDescription = "Datasafe commands are not enabled for this blade";
                return response;
            }

            Contracts.ChassisResponse varResponse = ValidateRequest("SetBladeDatasafeOn", bladeId);
            if (varResponse.completionCode != Contracts.CompletionCode.Success)
            {
                response.completionCode = varResponse.completionCode;
                response.statusDescription = varResponse.statusDescription;
                return response;
            }

            // Call ProcessDatasafeAction() so that the current action (command) can be added to the set of pending
            // actions and the processing loop for the pending actions appropriately kicked-off
            DatasafeBladeStatus datasafeResponse = DatasafeOperationSupport.ProcessDatasafeAction(bladeId, DatasafeActions.BladeOn);
            if (datasafeResponse == null)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = Contracts.CompletionCode.Failure.ToString();
                return response;
            }

            if (datasafeResponse.isBackupPending)
            {
                response.RemainingDataSafeDurationInSecs = datasafeResponse.remainingBackupDuration;
            }
            else
            {
                response.RemainingDataSafeDurationInSecs = 0;
            }

            if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandExecuted)
            {
                response.completionCode = Contracts.CompletionCode.Success;
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandDelayed)
            {
                response.completionCode = Contracts.CompletionCode.RequestDelayedDueToPendingDatasafeOperation;
                response.statusDescription = response.completionCode.ToString();
            }
            else if (datasafeResponse.status == DatasafeCommandsReturnStatus.CommandFailed)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = response.completionCode.ToString();
            }

            return response;
        }
        /// <summary>
        /// command specific implementation 
        /// argVal command class member has all user-entered command argument indicators and parameter values
        /// Currently just prints all argument indicators and argument values
        /// </summary>
        internal override void commandImplementation()
        {
            DatasafeBladeResponse myResponse = new DatasafeBladeResponse();
            DatasafeAllBladesResponse myResponses = new DatasafeAllBladesResponse();
            try
            {
                if (this.argVal.ContainsKey('a'))
                {
                    myResponses = WcsCli2CmConnectionManager.channel.SetAllBladesDatasafePowerOn();
                }
                else if (this.argVal.ContainsKey('i'))
                {
                    dynamic bladeId = null;
                    if (this.argVal.TryGetValue('i', out bladeId))
                    {
                        myResponse = WcsCli2CmConnectionManager.channel.SetBladeDatasafePowerOn((int)bladeId);
                    }
                    else
                    {
                        Console.WriteLine(WcsCliConstants.commandFailure +
                            " No blade ID specified, please look at command help");
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                SharedFunc.ExceptionOutput(ex);
                return;
            }

            if ((this.argVal.ContainsKey('a') && myResponses == null) || (this.argVal.ContainsKey('a') &&
                myResponses.datasafeBladeResponseCollection == null) || myResponse == null)
            {
                Console.WriteLine(WcsCliConstants.serviceResponseEmpty);
                return;
            }

            if (this.argVal.ContainsKey('a'))
            {
                foreach (var response in myResponses.datasafeBladeResponseCollection)
                {
                    ResponseValidation.ValidateBladeResponse(response.bladeNumber, "DataSafe power ON", response, true);
                }
            }
            else
            {
                ResponseValidation.ValidateBladeResponse(myResponse.bladeNumber, "DataSafe power ON", myResponse, true);
            }
        }