Ejemplo n.º 1
0
        /// <summary>
        /// Gets the PSU status for all PSUs
        /// </summary>
        private void GetAllPsuStatus()
        {
            int countStatus = 0;

            for (int numPsus = 0; numPsus < MaxPsuCount; numPsus++)
            {
                try
                {
                    PsuStatusPacket psuStatusPacket = new PsuStatusPacket();
                    psuStatusPacket = ChassisState.Psu[numPsus].GetPsuStatus();
                    if (psuStatusPacket.CompletionCode != CompletionCode.Success)
                    {
                        Tracer.WriteWarning("PSU ({0}) get status request failed with return code {1}", numPsus + 1, psuStatusPacket.CompletionCode);
                    }
                    else
                    {
                        if (psuStatusPacket.PsuStatus == (byte)Contracts.PowerState.ON)
                        {
                            countStatus++;
                        }
                        else
                        {
                            Tracer.WriteWarning("PSU ({0}) PowerGood signal is negated - check trace log for fault information", numPsus + 1);
                            CompletionCode clearFaultCompletionCode = ChassisState.Psu[numPsus].SetPsuClearFaults();
                            if (clearFaultCompletionCode != CompletionCode.Success)
                            {
                                Tracer.WriteError("PsuStatus clear fault (invoked upon negated power good signal) command failed. Completion code({0})", clearFaultCompletionCode);
                            }
                            else
                            {
                                Tracer.WriteWarning("PsuStatus clear fault (invoked upon negated power good signal) command succeeded.");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Tracer.WriteError("PSU {0} status check failed with Exception: {1}", numPsus + 1, e);
                }
            }

            // Identify whether there is a PSU failure or not
            if (countStatus != MaxPsuCount)
            {
                ChassisState.PsuFailure = true;
            }
            else
            {
                ChassisState.PsuFailure = false;
            }
        }
        /// <summary>
        /// Attempts to retrieve the Psu Status. This method
        /// calls down to the Chassis Manager with SendReceive
        /// </summary>
        private PsuStatusPacket GetPsuStatus(byte psuId)
        {
            // Initialize return packet
            PsuStatusPacket returnPacket = new PsuStatusPacket();

            returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
            returnPacket.PsuStatus      = 0;
            returnPacket.FaultPresent   = false;

            try
            {
                PsuStatusResponse myResponse = new PsuStatusResponse();
                myResponse = (PsuStatusResponse)this.SendReceive(this.PsuDeviceType, this.PsuId,
                                                                 new PsuRequest((byte)PmBusCommand.STATUS_WORD, (byte)PmBusResponseLength.STATUS_WORD), typeof(PsuStatusResponse));

                if (myResponse.CompletionCode != 0)
                {
                    returnPacket.CompletionCode = (CompletionCode)myResponse.CompletionCode;
                    Tracer.WriteWarning("GetPsuStatus Failure for PSU {0}: Completion Code: {1}", psuId, myResponse.CompletionCode);
                }
                else
                {
                    returnPacket.CompletionCode = CompletionCode.Success;
                    byte   varStatus;
                    byte[] psuStatus = myResponse.PsuStatus;

                    // If there are any other faults, indicate fault is present and log the full status word
                    if (!PmBus.ExtractPowerGoodFromPsuStatus(psuStatus, out varStatus))
                    {
                        Tracer.WriteWarning("GetPsuStatus: Psu ({0}) STATUS_WORD is non-zero: " +
                                            "(High Byte: {1} Low Byte: {2}) (See STATUS_WORD register in PmBusII Manual)",
                                            this.PsuId,
                                            System.Convert.ToString(psuStatus[1], 2).PadLeft(8, '0'),
                                            System.Convert.ToString(psuStatus[0], 2).PadLeft(8, '0'));

                        returnPacket.FaultPresent = true;
                    }

                    returnPacket.PsuStatus = varStatus;
                }
            }
            catch (System.Exception ex)
            {
                returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
                returnPacket.PsuStatus      = 0;
                Tracer.WriteError("GetPsuStatus Exception: " + ex);
            }
            return(returnPacket);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Attempts to retrieve the Psu Status. This method
        /// calls down to the Chassis Manager with SendReceive
        /// </summary>
        private PsuStatusPacket GetPsuStatus(byte psuId)
        {
            // Initialize return packet
            PsuStatusPacket returnPacket = new PsuStatusPacket();

            returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
            returnPacket.PsuStatus      = 0;

            try
            {
                PsuStatusResponse myResponse = new PsuStatusResponse();
                myResponse = (PsuStatusResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_WORD, (byte)PmBusResponseLength.STATUS_WORD), typeof(PsuStatusResponse));

                if (myResponse.CompletionCode != 0)
                {
                    returnPacket.CompletionCode = (CompletionCode)myResponse.CompletionCode;
                    Tracer.WriteWarning("GetPsuStatus Failure: status({0})", returnPacket.PsuStatus);
                }
                else
                {
                    returnPacket.CompletionCode = CompletionCode.Success;
                    byte   varStatus;
                    byte[] psuStatus = myResponse.PsuStatus;

                    // If there are any other faults, print the full status word
                    if (!PmBus.ExtractPowerGoodFromPsuStatus(psuStatus, out varStatus))
                    {
                        Tracer.WriteWarning("Psu({0}) PowerGood Negated ({1} {2}) in/out curr/volt faults (See StatusWord in PmBusII Manual)", this.PsuId, System.Convert.ToString(psuStatus[0], 2).PadLeft(8, '0'), System.Convert.ToString(psuStatus[1], 2).PadLeft(8, '0'));
                    }

                    returnPacket.PsuStatus = varStatus;
                }
            }
            catch (System.Exception ex)
            {
                returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
                returnPacket.PsuStatus      = 0;
                Tracer.WriteError("GetPsuStatus Exception: " + ex);
            }
            return(returnPacket);
        }
        /// <summary>
        /// Attempts to retrieve the Psu Status. This method
        /// calls down to the Chassis Manager with SendReceive
        /// </summary>
        private PsuStatusPacket GetPsuStatus(byte psuId)
        {
            // Initialize return packet
            PsuStatusPacket returnPacket = new PsuStatusPacket();
            returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
            returnPacket.PsuStatus = 0;
            returnPacket.FaultPresent = false;

            try
            {
                PsuStatusResponse myResponse = new PsuStatusResponse();
                myResponse = (PsuStatusResponse)this.SendReceive(this.PsuDeviceType, this.PsuId,
                    new PsuRequest((byte)PmBusCommand.STATUS_WORD,(byte)PmBusResponseLength.STATUS_WORD), typeof(PsuStatusResponse));

                if (myResponse.CompletionCode != 0)
                {
                    returnPacket.CompletionCode = (CompletionCode)myResponse.CompletionCode;
                    Tracer.WriteWarning("GetPsuStatus Failure for PSU {0}: Completion Code: {1}", psuId, myResponse.CompletionCode);
                }
                else
                {
                    returnPacket.CompletionCode = CompletionCode.Success;
                    byte varStatus;
                    byte[] psuStatus = myResponse.PsuStatus;

                    // If there are any other faults, indicate fault is present and log the full status word
                    if (!PmBus.ExtractPowerGoodFromPsuStatus(psuStatus, out varStatus))
                    {
                        Tracer.WriteWarning("GetPsuStatus: Psu ({0}) STATUS_WORD is non-zero: " +
                            "(High Byte: {1} Low Byte: {2}) (See STATUS_WORD register in PmBusII Manual)",
                            this.PsuId,
                            System.Convert.ToString(psuStatus[1], 2).PadLeft(8, '0'),
                            System.Convert.ToString(psuStatus[0], 2).PadLeft(8, '0'));

                        returnPacket.FaultPresent = true;
                    }

                    returnPacket.PsuStatus = varStatus;
                }
            }
            catch (System.Exception ex)
            {
                returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
                returnPacket.PsuStatus = 0;
                Tracer.WriteError("GetPsuStatus Exception: " + ex);
            }
            return returnPacket;
        }
        /// <summary>
        /// Standalone Command to get Power Consumption Info,  
        /// used with Data Center Power Monitoring integration
        /// </summary>
        private List<PsuInfo> GetPsuInfo()
        {
            // Create Response Collection
            List<PsuInfo> response = new List<PsuInfo>(ConfigLoaded.NumPsus);

            try
            {
                for (int psuId = 0; psuId < ConfigLoaded.NumPsus; psuId++)
                {
                    // Step 1: Create PsuInfo Response object
                    Contracts.PsuInfo psuInfo = new Contracts.PsuInfo();
                    psuInfo.id = (uint)(psuId + 1);

                    // Add object to list.
                    response.Add(psuInfo);

                    // If PSU firmware update in progress, do not read status
                    if (ChassisState.PsuFwUpdateInProgress[psuId])
                    {
                        response[psuId].completionCode = Contracts.CompletionCode.PSUFirmwareUpdateInProgress;
                        response[psuId].statusDescription = "PSU firmware update in progress";
                        continue;
                    }

                    lock (ChassisState.psuLock[psuId])
                    {
                        // subsequent commands are permitted to change upon failure.
                        response[psuId].completionCode = Contracts.CompletionCode.Success;

                        // Step 2:  Get Psu Power
                        PsuPowerPacket psuPower = ChassisState.Psu[psuId].GetPsuPower();
                        if (psuPower.CompletionCode != CompletionCode.Success)
                        {
                            Tracer.WriteWarning("GetPsuPower failed for psu: " + psuInfo.id);
                            response[psuId].powerOut = 0;
                            response[psuId].completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping((byte)psuPower.CompletionCode);
                            response[psuId].statusDescription = psuPower.CompletionCode.ToString();
                        }
                        else
                        {
                            response[psuId].powerOut = (uint)psuPower.PsuPower;
                        }

                        // Step 3: Get Psu Serial Number
                        PsuSerialNumberPacket serialNumberPacket = new PsuSerialNumberPacket();
                        serialNumberPacket = ChassisState.Psu[psuId].GetPsuSerialNumber();
                        if (serialNumberPacket.CompletionCode != CompletionCode.Success)
                        {
                            Tracer.WriteWarning("GetPsuSerialNumber failed for psu: " + psuInfo.id);
                            response[psuId].serialNumber = string.Empty;
                            response[psuId].completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping((byte)serialNumberPacket.CompletionCode);
                            response[psuId].statusDescription = serialNumberPacket.CompletionCode.ToString();
                        }
                        else
                        {
                            response[psuId].serialNumber = serialNumberPacket.SerialNumber;
                        }

                        // Step 4: Get Psu Status
                        PsuStatusPacket psuStatusPacket = new PsuStatusPacket();
                        psuStatusPacket = ChassisState.Psu[psuId].GetPsuStatus();
                        if (psuStatusPacket.CompletionCode != CompletionCode.Success)
                        {
                            Tracer.WriteWarning("GetPsuStatus failed for psu " + psuInfo.id);
                            response[psuId].state = PowerState.NA;
                            response[psuId].completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping((byte)psuStatusPacket.CompletionCode);
                            response[psuId].statusDescription = psuStatusPacket.CompletionCode.ToString();
                        }
                        else
                        {
                            if (psuStatusPacket.PsuStatus == (byte)Contracts.PowerState.OFF)
                            {
                                response[psuId].state = PowerState.OFF;
                            }
                            else if (psuStatusPacket.PsuStatus == (byte)Contracts.PowerState.ON)
                            {
                                response[psuId].state = PowerState.ON;
                            }
                            else
                            {
                                response[psuId].state = PowerState.NA;
                            }
                        }
                    } // lock...
                } // for...
            }
            catch (Exception ex)
            {
                Tracer.WriteError("GetPsuInfo failed with exception: {0}", ex);
            }

            return response;
        }
        /// <summary>
        /// Attempt to resolve Psu Faults
        /// </summary>
        private static Dictionary <byte, PsuAlertFaultStatus> PsuAlertRemediate(Dictionary <byte, PsuAlertFaultType> psuFailures)
        {
            Dictionary <byte, PsuAlertFaultStatus> failedPsu = new Dictionary <byte, PsuAlertFaultStatus>();

            foreach (KeyValuePair <byte, PsuAlertFaultType> psu in psuFailures)
            {
                // If firmware update is in progress, skip this PSU
                if (ChassisState.PsuFwUpdateInProgress[psu.Key - 1])
                {
                    continue;
                }

                lock (ChassisState.psuLock[psu.Key - 1])
                {
                    // Log PSU faults
                    ChassisState.Psu[psu.Key - 1].LogPsuFaultStatus();

                    // Clear PSU faults, which will clear PSU_ALERT
                    CompletionCode clearAlert = ClearPsuFault(psu.Key);
                    if (clearAlert != CompletionCode.Success)
                    {
                        // PSU clear faults failed. Log failure and continue to next PSU.
                        failedPsu.Add(psu.Key, PsuAlertFaultStatus.PsuClearFaultFailed);
                        Tracer.WriteError("PsuAlertRemediate: ClearPsuFault failed on PsuId: {0}", psu.Key);
                        continue;
                    }

                    if (psu.Value == PsuAlertFaultType.PsuFailure)
                    {
                        // Check that the PSU is on
                        PsuStatusPacket psuStatus = ChassisState.Psu[psu.Key - 1].GetPsuStatus();
                        if (psuStatus.CompletionCode != CompletionCode.Success)
                        {
                            failedPsu.Add(psu.Key, PsuAlertFaultStatus.PsuFault);
                            Tracer.WriteError("PsuAlertRemediate: GetPsuStatus on PSU ({0}) failed with return code {1}",
                                              psu.Key, psuStatus.CompletionCode);
                        }
                        else
                        {
                            if (psuStatus.PsuStatus == (byte)Contracts.PowerState.ON)
                            {
                                // Check PSU power output
                                PsuPowerPacket power = ChassisState.Psu[psu.Key - 1].GetPsuPower();
                                if ((power.CompletionCode == CompletionCode.Success) && (power.PsuPower != 0))
                                {
                                    Tracer.WriteInfo("PsuStatus clear faults succeeded.  Psu: {0} drawing power: {1} Watts",
                                                     psu.Key, power.PsuPower);
                                }
                                else
                                {
                                    // PSU is not outputting power.
                                    failedPsu.Add(psu.Key, PsuAlertFaultStatus.PsuNoOutputPower);
                                    Tracer.WriteError("PsuAlertRemediate failed Psu.  PsuId: {0} Psu Error State: {1}",
                                                      psu.Key, PsuAlertFaultStatus.PsuNoOutputPower.ToString());
                                }
                            }
                            else
                            {
                                // PSU is turned off.
                                failedPsu.Add(psu.Key, PsuAlertFaultStatus.PsuPowerOff);
                                Tracer.WriteError("PsuAlertRemediate failed Psu.  PsuId: {0} Psu Error State: {1}",
                                                  psu.Key, PsuAlertFaultStatus.PsuPowerOff.ToString());
                            }
                        }
                    }
                    else if ((ConfigLoaded.BatteryMonitoringEnabled) && (ChassisState.Psu[(psu.Key - 1)] is EmersonPsu))
                    {
                        // convert psu from base class object
                        EmersonPsu emersonPsu = (EmersonPsu)ChassisState.Psu[(psu.Key - 1)];

                        if (psu.Value == PsuAlertFaultType.BatteryFault)
                        {
                            // clear battery fault status
                            CompletionCode clearFault = emersonPsu.ClearBatteryFaultIndicator();

                            if (clearFault == CompletionCode.Success)
                            {
                                EmersonPsu.BatteryFaultIndicatorPacket faultIndicator = emersonPsu.GetBatteryFaultIndicator();

                                if (faultIndicator.BatteryFault == 1)
                                {
                                    if (!failedPsu.ContainsKey(emersonPsu.PsuId))
                                    {
                                        // Psu Clear faults did not succeed.
                                        failedPsu.Add(psu.Key, PsuAlertFaultStatus.BatteryFault);
                                    }
                                    Tracer.WriteError("PsuAlertRemediate failed to clear battery fault. PsuId: {0} Battery Error State: {1}",
                                                      psu.Key, PsuAlertFaultStatus.BatteryFault.ToString());
                                }
                            }
                        }
                        else if (psu.Value == PsuAlertFaultType.OnBattery && ConfigLoaded.NumBatteries > 0)
                        {
                            // Check if we need to trigger delegate to process battery status
                            if (ConfigLoaded.ProcessBatteryStatus)
                            {
                                double sumBatteryChargeLevel      = 0;
                                ChassisEnergyStorageStatus status = null;

                                // list to store battery charge levels
                                List <string> batteryStates = new List <string>();

                                // battery present or not, set to true if even one battery is present.
                                // default to false
                                bool isBatteryPresent = false;

                                // Calculate average battery charge level
                                for (int index = 1; index <= ConfigLoaded.NumBatteries; index++)
                                {
                                    status = ChassisState.GetEnergyStorageStatus((byte)index);

                                    // Add to the list battery charge levels
                                    batteryStates.Add(status.State.ToString());

                                    // If even one battery is present, set flag to true
                                    if (status.Present)
                                    {
                                        isBatteryPresent = true;
                                    }

                                    // If battery state is not unknown, add up the charge level.
                                    if (status.State != EnergyStorageState.Unknown)
                                    {
                                        sumBatteryChargeLevel += status.PercentCharge;
                                    }
                                }

                                double avgChargeLevel = (sumBatteryChargeLevel / ConfigLoaded.NumBatteries);

                                // Process battery status if battery discharge time is greater than the allowed discharge time
                                // from app.config( default 35 seconds) or Average battery charge level is below a given threshold value.
                                if (BatteryDischargeTimer.Elapsed > new System.TimeSpan(0, 0, ConfigLoaded.BatteryDischargeTimeInSecs) ||
                                    avgChargeLevel < ConfigLoaded.BatteryChargeLevelThreshold)
                                {
                                    // Invoke method to trigger NVDIMM backup for critical battery status
                                    ThreadPool.QueueUserWorkItem(new WaitCallback(ChassisManagerInternal.ProcessCriticalBatteryStatus));
                                }

                                // Calculate backup energy available per blade and per NVDIMM
                                double bladeEnergy = (ConfigLoaded.NumPsus * BATT_POUT_MAX * BATT_OP_TIME_100_LOAD * avgChargeLevel) /
                                                     ConfigLoaded.Population;
                                double nvdimmEnergy = (ConfigLoaded.NumPsus * BATT_POUT_EXTENDED * BATT_OP_TIME_75W_LOAD) /
                                                      (ConfigLoaded.Population * ConfigLoaded.NvDimmPerBlade);
                                // Scale the values
                                bladeEnergy  = bladeEnergy / ENERGY_STORAGE_SCALING_JOULES;
                                nvdimmEnergy = nvdimmEnergy / ENERGY_STORAGE_SCALING_JOULES;

                                // Send battery status to BMC, check returned completion code for success
                                Dictionary <byte, CompletionCode> results = WcsBladeFacade.BroadcastSetEnergyStorage
                                                                                (isBatteryPresent, GetBatteryStateToBroadcast(batteryStates), ENERGY_STORAGE_SCALING_JOULES, (ushort)bladeEnergy, (byte)nvdimmEnergy);

                                // Check if broadcast failed for any blade, if yes log error.
                                for (int index = 1; index <= ConfigLoaded.Population; index++)
                                {
                                    CompletionCode code;

                                    if (results.TryGetValue((byte)index, out code))
                                    {
                                        // If completion code returned is not success
                                        if (code != CompletionCode.Success)
                                        {
                                            Tracer.WriteError("PsuMonitor: ProcessBatteryStatus: " +
                                                              "Failed to update battery status to BMC for blade: " + index +
                                                              ", completion code returned: " + code);
                                        }
                                    }
                                    else
                                    {
                                        // If blade entry does not exist.
                                        Tracer.WriteError("PsuMonitor: ProcessBatteryStatus : " +
                                                          "Failed to update battery status to BMC for blade: " + index);
                                    }
                                }
                            }
                        }
                    }
                } // lock...
            }     // foreach...

            return(failedPsu);
        }
        /// <summary>
        /// Checks for faults on each PSU
        /// </summary>
        private static Dictionary <byte, PsuAlertFaultType> PsuAlertInvestigate()
        {
            Dictionary <byte, PsuAlertFaultType> failures = new Dictionary <byte, PsuAlertFaultType>();

            // Check status for all PSU
            foreach (PsuBase psu in ChassisState.Psu)
            {
                // If firmware update is in progress, skip this PSU
                if (ChassisState.PsuFwUpdateInProgress[psu.PsuId - 1])
                {
                    continue;
                }

                lock (ChassisState.psuLock[psu.PsuId - 1])
                {
                    PsuStatusPacket psuStatus = psu.GetPsuStatus();
                    if (psuStatus.CompletionCode != CompletionCode.Success)
                    {
                        Tracer.WriteError("PsuAlertInvestigate: GetPsuStatus on PSU ({0}) failed with return code {1}",
                                          psu.PsuId, psuStatus.CompletionCode);
                        failures.Add(psu.PsuId, PsuAlertFaultType.PsuFailure);
                    }
                    else
                    {
                        if (psuStatus.PsuStatus != (byte)Contracts.PowerState.ON)
                        {
                            // PSU is completely turned off
                            failures.Add(psu.PsuId, PsuAlertFaultType.PsuFailure);
                        }
                        else if ((ConfigLoaded.BatteryMonitoringEnabled) && (ChassisState.Psu[psu.PsuId - 1] is EmersonPsu))
                        {
                            // Check battery status for Emerson PSU
                            EmersonPsu emersonPsu = (EmersonPsu)psu;

                            // Get battery status and health
                            BatteryStatusPacket battStatus = emersonPsu.GetBatteryStatus();
                            EmersonPsu.BatteryHealthStatusPacket battHealth = emersonPsu.GetBatteryHealthStatus();

                            if ((battStatus.CompletionCode == CompletionCode.Success) &&
                                (battHealth.CompletionCode == CompletionCode.Success))
                            {
                                // Update chassis energy storage variables
                                bool batteryPresent          = (battStatus.Presence == 1) ? true : false;
                                bool batteryFault            = (battStatus.FaultDetected == 1) ? true : false;
                                EnergyStorageState battState = EnergyStorageState.Unknown;

                                if (batteryPresent)
                                {
                                    if (batteryFault)
                                    {
                                        // Battery Fault Detected.
                                        failures.Add(emersonPsu.PsuId, PsuAlertFaultType.BatteryFault);
                                        Tracer.WriteError("PsuAlertInvestigate Battery Fault Detected. PsuId {0}", emersonPsu.PsuId);
                                    }
                                    else // if no fault detected, check if system is on battery.
                                    {
                                        // Determine battery state
                                        if (battHealth.Discharging == 0)
                                        {
                                            battState = EnergyStorageState.Charging;

                                            // We are charging, reset the timer.
                                            if (BatteryDischargeTimer.IsRunning)
                                            {
                                                BatteryDischargeTimer.Reset();
                                            }
                                        }
                                        else
                                        {
                                            // Emerson stated that we can have discharging even when on AC since the charger will have hysteresis.
                                            // Hence we need to check Discharging and Battery Power Output to determine if we are on Battery.
                                            if (battStatus.BatteryPowerOutput != 0)
                                            {
                                                battState = EnergyStorageState.Discharging;
                                            }
                                            else
                                            {
                                                battState = EnergyStorageState.Floating;
                                            }
                                        }

                                        if (battState == EnergyStorageState.Discharging)
                                        {
                                            // Start the timer if not already running.
                                            if (!BatteryDischargeTimer.IsRunning)
                                            {
                                                BatteryDischargeTimer.Start();
                                            }

                                            // Psu Battery is Discharging. System is on battery.
                                            // Log it as a failure for processing in PsuAlertRemediate() which is called outside this method
                                            failures.Add(emersonPsu.PsuId, PsuAlertFaultType.OnBattery);
                                            Tracer.WriteInfo("PsuAlertInvestigate Psu Battery discharging.  PsuId {0}", emersonPsu.PsuId);
                                        }
                                    }
                                }
                                else
                                {
                                    Tracer.WriteInfo("PsuAlertInvestigate, no battery present for Psu: {0}", emersonPsu.PsuId);
                                }

                                // Update chassis energy storage values
                                ChassisEnergyStorageStatus chassisEnergyStatus =
                                    new ChassisEnergyStorageStatus(batteryPresent, battState,
                                                                   battStatus.BatteryChargeLevel, battStatus.BatteryPowerOutput, batteryFault);
                                if (!ChassisState.SetEnergyStorageStatus(emersonPsu.PsuId, chassisEnergyStatus))
                                {
                                    Tracer.WriteError(
                                        string.Format("PsuAlertInvestigate: SetEnergyStorageStatus failed for BatteryId {0}", emersonPsu.PsuId));
                                }
                            }
                            else
                            {
                                // Failed to get battery status or health. Log as battery fault
                                failures.Add(emersonPsu.PsuId, PsuAlertFaultType.BatteryFault);
                                Tracer.WriteError("PsuAlertInvestigate failed to get Battery Status. PsuId {0} Status Completion Code: {1}  Health Completion Code: {2}",
                                                  emersonPsu.PsuId, battStatus.CompletionCode, battHealth.CompletionCode);
                            }
                        }

                        // If PSU is on and there are no battery faults, check if other faults are present
                        // Add PSU to failure list so that we can log it in PsuAlertRemediate()
                        if ((!failures.ContainsKey(psu.PsuId)) && (psuStatus.FaultPresent))
                        {
                            failures.Add(psu.PsuId, PsuAlertFaultType.PsuFaultPresent);
                        }
                    }
                } // lock...
            }     // foreach...

            return(failures);
        }
        /// <summary>
        /// Gets the PSU status for all PSUs
        /// </summary>
        private void GetAllPsuStatus()
        {
            int countStatus = 0;
            for (int numPsus = 0; numPsus < MaxPsuCount; numPsus++)
            {
                try
                {
                    PsuStatusPacket psuStatusPacket = new PsuStatusPacket();
                    psuStatusPacket = ChassisState.Psu[numPsus].GetPsuStatus();
                    if (psuStatusPacket.CompletionCode != CompletionCode.Success)
                    {
                        Tracer.WriteWarning("PSU ({0}) get status request failed with return code {1}", numPsus + 1, psuStatusPacket.CompletionCode);
                    }
                    else
                    {
                        if (psuStatusPacket.PsuStatus == (byte)Contracts.PowerState.ON)
                        {
                            countStatus++;
                        }
                        else
                        {
                            Tracer.WriteWarning("PSU ({0}) PowerGood signal is negated - check trace log for fault information", numPsus + 1);
                            CompletionCode clearFaultCompletionCode = ChassisState.Psu[numPsus].SetPsuClearFaults();
                            if (clearFaultCompletionCode != CompletionCode.Success)
                            {
                                Tracer.WriteError("PsuStatus clear fault (invoked upon negated power good signal) command failed. Completion code({0})", clearFaultCompletionCode);
                            }
                            else
                            {
                                Tracer.WriteWarning("PsuStatus clear fault (invoked upon negated power good signal) command succeeded.");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Tracer.WriteError("PSU {0} status check failed with Exception: {1}", numPsus+1, e);
                }
            }

            // Identify whether there is a PSU failure or not
            if (countStatus != MaxPsuCount)
            {
                ChassisState.PsuFailure = true;
            }
            else
            {
                ChassisState.PsuFailure = false;
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Attempts to retrieve the Psu Status. This method
        /// calls down to the Chassis Manager with SendReceive
        /// </summary>
        private PsuStatusPacket GetPsuStatus(byte psuId)
        {
            // Initialize return packet 
            PsuStatusPacket returnPacket = new PsuStatusPacket();
            returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
            returnPacket.PsuStatus = 0;

            try
            {
                PsuStatusResponse myResponse = new PsuStatusResponse();
                myResponse = (PsuStatusResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_WORD,(byte)PmBusResponseLength.STATUS_WORD), typeof(PsuStatusResponse));

                if (myResponse.CompletionCode != 0)
                {
                    returnPacket.CompletionCode = (CompletionCode)myResponse.CompletionCode;
                    Tracer.WriteWarning("GetPsuStatus Failure: status({0})", returnPacket.PsuStatus);
                }
                else
                {
                    returnPacket.CompletionCode = CompletionCode.Success;
                    byte varStatus;
                    byte[] psuStatus = myResponse.PsuStatus;
                    
                    // If there are any other faults, print the full status word
                    if (!PmBus.ExtractPowerGoodFromPsuStatus(psuStatus, out varStatus))
                    {
                        Tracer.WriteWarning("Psu({0}) PowerGood Negated ({1} {2}) in/out curr/volt faults (See StatusWord in PmBusII Manual)", this.PsuId, System.Convert.ToString(psuStatus[0], 2).PadLeft(8, '0'), System.Convert.ToString(psuStatus[1], 2).PadLeft(8, '0'));
                    }

                    returnPacket.PsuStatus = varStatus;
                }
            }
            catch (System.Exception ex)
            {
                returnPacket.CompletionCode = CompletionCode.UnspecifiedError;
                returnPacket.PsuStatus = 0;
                Tracer.WriteError("GetPsuStatus Exception: " + ex);
            }
            return returnPacket;
        }