blob: 852d2baf1622a8376a6455385e0642afab6ac0f1 [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
Matt Spinlerebaae612017-04-27 14:21:48 -050054void Fan::tachChanged()
55{
56 for (auto& s : _sensors)
57 {
58 tachChanged(*s);
59 }
60}
61
62
63void Fan::tachChanged(TachSensor& sensor)
64{
65 //TODO
66}
67
68
Matt Spinlerabf8da32017-04-27 14:08:45 -050069uint64_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
97bool 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
109bool 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}