1 /** 2 * Copyright © 2017 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <algorithm> 17 #include <phosphor-logging/log.hpp> 18 #include "fan.hpp" 19 #include "types.hpp" 20 21 namespace phosphor 22 { 23 namespace fan 24 { 25 namespace monitor 26 { 27 28 using namespace phosphor::logging; 29 30 Fan::Fan(sdbusplus::bus::bus& bus, 31 std::shared_ptr<sd_event>& events, 32 const FanDefinition& def) : 33 _bus(bus), 34 _name(std::get<fanNameField>(def)), 35 _deviation(std::get<fanDeviationField>(def)), 36 _numSensorFailsForNonFunc(std::get<numSensorFailsForNonfuncField>(def)) 37 { 38 auto& sensors = std::get<sensorListField>(def); 39 40 for (auto& s : sensors) 41 { 42 _sensors.emplace_back( 43 std::make_unique<TachSensor>(bus, 44 *this, 45 std::get<sensorNameField>(s), 46 std::get<hasTargetField>(s), 47 std::get<timeoutField>(def))); 48 49 } 50 51 } 52 53 54 void Fan::tachChanged() 55 { 56 for (auto& s : _sensors) 57 { 58 tachChanged(*s); 59 } 60 } 61 62 63 void Fan::tachChanged(TachSensor& sensor) 64 { 65 //TODO 66 } 67 68 69 uint64_t Fan::getTargetSpeed(const TachSensor& sensor) 70 { 71 uint64_t target = 0; 72 73 if (sensor.hasTarget()) 74 { 75 target = sensor.getTarget(); 76 } 77 else 78 { 79 //The sensor doesn't support a target, 80 //so get it from another sensor. 81 auto s = std::find_if(_sensors.begin(), _sensors.end(), 82 [](const auto& s) 83 { 84 return s->hasTarget(); 85 }); 86 87 if (s != _sensors.end()) 88 { 89 target = (*s)->getTarget(); 90 } 91 } 92 93 return target; 94 } 95 96 97 bool Fan::tooManySensorsNonfunctional() 98 { 99 size_t numFailed = std::count_if(_sensors.begin(), _sensors.end(), 100 [](const auto& s) 101 { 102 return !s->functional(); 103 }); 104 105 return (numFailed >= _numSensorFailsForNonFunc); 106 } 107 108 109 bool Fan::outOfRange(const TachSensor& sensor) 110 { 111 auto actual = static_cast<uint64_t>(sensor.getInput()); 112 auto target = getTargetSpeed(sensor); 113 114 uint64_t min = target * (100 - _deviation) / 100; 115 uint64_t max = target * (100 + _deviation) / 100; 116 117 if ((actual < min) || (actual > max)) 118 { 119 return true; 120 } 121 122 return false; 123 } 124 125 126 } 127 } 128 } 129