in fboss/platform/fan_service/ControlLogic.cpp [245:387]
void ControlLogic::getSensorUpdate() {
std::string sensorItemName;
float rawValue = 0.0, adjustedValue, targetPwm;
uint64_t calculatedTime = 0;
for (auto configSensorItem = pConfig_->sensors.begin();
configSensorItem != pConfig_->sensors.end();
++configSensorItem) {
XLOG(INFO) << "Control :: Sensor Name : " << configSensorItem->sensorName;
bool sensorAccessFail = false;
sensorItemName = configSensorItem->sensorName;
if (pSensor_->checkIfEntryExists(sensorItemName)) {
XLOG(INFO) << "Control :: Sensor Exists. Getting the entry type";
// 1.a Get the reading
SensorEntryType entryType = pSensor_->getSensorEntryType(sensorItemName);
switch (entryType) {
case SensorEntryType::kSensorEntryInt:
rawValue = pSensor_->getSensorDataInt(sensorItemName);
rawValue = rawValue / configSensorItem->scale;
break;
case SensorEntryType::kSensorEntryFloat:
rawValue = pSensor_->getSensorDataFloat(sensorItemName);
rawValue = rawValue / configSensorItem->scale;
break;
default:
facebook::fboss::FbossError(
"Invalid Sensor Entry Type in entry name : ", sensorItemName);
break;
}
} else {
XLOG(ERR) << "Control :: Sensor Read Fail : " << sensorItemName;
sensorAccessFail = true;
}
XLOG(INFO) << "Control :: Done raw sensor reading";
if (sensorAccessFail) {
// If the sensor data cache is stale for a while, we consider it as the
// failure of such sensor
uint64_t timeDiffInSec = pBsp_->getCurrentTime() -
configSensorItem->processedData.lastUpdatedTime;
if (timeDiffInSec >= configSensorItem->sensorFailThresholdInSec) {
configSensorItem->processedData.sensorFailed == true;
numSensorFailed_++;
}
} else {
calculatedTime = pSensor_->getLastUpdated(sensorItemName);
configSensorItem->processedData.lastUpdatedTime = calculatedTime;
configSensorItem->processedData.sensorFailed = false;
}
// 1.b If adjustment table exists, adjust the raw value
if (configSensorItem->offsetTable.size() == 0) {
adjustedValue = rawValue;
} else {
float offset = 0;
for (auto tableEntry = configSensorItem->offsetTable.begin();
tableEntry != configSensorItem->offsetTable.end();
++tableEntry) {
if (rawValue >= tableEntry->first) {
offset = tableEntry->second;
}
adjustedValue = rawValue + offset;
}
}
configSensorItem->processedData.adjustedReadCache = adjustedValue;
XLOG(INFO) << "Control :: Adjusted Value : " << adjustedValue;
// 1.c Check and trigger alarm
bool prevMajorAlarm = configSensorItem->processedData.majorAlarmTriggered;
configSensorItem->processedData.majorAlarmTriggered =
(adjustedValue >= configSensorItem->alarm.high_major);
// If major alarm was triggered, write it as a ERR log
if (!prevMajorAlarm &&
configSensorItem->processedData.majorAlarmTriggered) {
XLOG(ERR) << "Major Alarm Triggered on " << configSensorItem->sensorName
<< " at value " << adjustedValue;
} else if (
prevMajorAlarm &&
!configSensorItem->processedData.majorAlarmTriggered) {
XLOG(WARN) << "Major Alarm Cleared on " << configSensorItem->sensorName
<< " at value " << adjustedValue;
}
bool prevMinorAlarm = configSensorItem->processedData.minorAlarmTriggered;
if (adjustedValue >= configSensorItem->alarm.high_minor) {
if (configSensorItem->processedData.soakStarted) {
uint64_t timeDiffInSec = pBsp_->getCurrentTime() -
configSensorItem->processedData.soakStartedAt;
if (timeDiffInSec >= configSensorItem->alarm.high_minor_soak) {
configSensorItem->processedData.minorAlarmTriggered = true;
configSensorItem->processedData.soakStarted = false;
}
} else {
configSensorItem->processedData.soakStarted = true;
configSensorItem->processedData.soakStartedAt = calculatedTime;
}
} else {
configSensorItem->processedData.minorAlarmTriggered = false;
configSensorItem->processedData.soakStarted = false;
}
// If minor alarm was triggered, write it as a WARN log
if (!prevMinorAlarm &&
configSensorItem->processedData.minorAlarmTriggered) {
XLOG(WARN) << "Minor Alarm Triggered on " << configSensorItem->sensorName
<< " at value " << adjustedValue;
}
if (prevMinorAlarm &&
!configSensorItem->processedData.minorAlarmTriggered) {
XLOG(WARN) << "Minor Alarm Cleared on " << configSensorItem->sensorName
<< " at value " << adjustedValue;
}
// 1.d Check the range (if required), and do emergency
// shutdown, if the value is out of range for more than
// the "tolerance" times
if (configSensorItem->rangeCheck.enabled) {
if ((adjustedValue > configSensorItem->rangeCheck.rangeHigh) ||
(adjustedValue < configSensorItem->rangeCheck.rangeLow)) {
configSensorItem->rangeCheck.invalidCount += 1;
if (configSensorItem->rangeCheck.invalidCount >=
configSensorItem->rangeCheck.tolerance) {
// ERR log only once.
if (configSensorItem->rangeCheck.invalidCount ==
configSensorItem->rangeCheck.tolerance) {
XLOG(ERR) << "Sensor " << configSensorItem->sensorName
<< " out of range for too long!";
}
// If we are not yet in emergency state, do the emergency shutdown.
if ((configSensorItem->rangeCheck.action ==
kRangeCheckActionShutdown) &&
(pBsp_->getEmergencyState() == false)) {
pBsp_->emergencyShutdown(pConfig_, true);
}
}
} else {
configSensorItem->rangeCheck.invalidCount = 0;
}
}
// 1.e Calculate the target pwm in percent
// (the table or incremental pid should produce
// percent as its output)
updateTargetPwm(&(*configSensorItem));
XLOG(INFO) << configSensorItem->sensorName << " has the target PWM of "
<< configSensorItem->processedData.targetPwmCache;
}
return;
}