blob: b29eaab225833d4dd8ed06139b22375aad7cd17d [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001/**
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
21namespace phosphor
22{
23namespace fan
24{
25namespace monitor
26{
27
28using namespace phosphor::logging;
29
30Fan::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
54uint64_t Fan::getTargetSpeed(const TachSensor& sensor)
55{
56 uint64_t target = 0;
57
58 if (sensor.hasTarget())
59 {
60 target = sensor.getTarget();
61 }
62 else
63 {
64 //The sensor doesn't support a target,
65 //so get it from another sensor.
66 auto s = std::find_if(_sensors.begin(), _sensors.end(),
67 [](const auto& s)
68 {
69 return s->hasTarget();
70 });
71
72 if (s != _sensors.end())
73 {
74 target = (*s)->getTarget();
75 }
76 }
77
78 return target;
79}
80
81
82bool Fan::tooManySensorsNonfunctional()
83{
84 size_t numFailed = std::count_if(_sensors.begin(), _sensors.end(),
85 [](const auto& s)
86 {
87 return !s->functional();
88 });
89
90 return (numFailed >= _numSensorFailsForNonFunc);
91}
92
93
94bool Fan::outOfRange(const TachSensor& sensor)
95{
96 auto actual = static_cast<uint64_t>(sensor.getInput());
97 auto target = getTargetSpeed(sensor);
98
99 uint64_t min = target * (100 - _deviation) / 100;
100 uint64_t max = target * (100 + _deviation) / 100;
101
102 if ((actual < min) || (actual > max))
103 {
104 return true;
105 }
106
107 return false;
108}
109
110
111}
112}
113}