summaryrefslogtreecommitdiffstats
path: root/monitor/fan.cpp
blob: b29eaab225833d4dd8ed06139b22375aad7cd17d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * Copyright © 2017 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <algorithm>
#include <phosphor-logging/log.hpp>
#include "fan.hpp"
#include "types.hpp"

namespace phosphor
{
namespace fan
{
namespace monitor
{

using namespace phosphor::logging;

Fan::Fan(sdbusplus::bus::bus& bus,
         std::shared_ptr<sd_event>&  events,
         const FanDefinition& def) :
    _bus(bus),
    _name(std::get<fanNameField>(def)),
    _deviation(std::get<fanDeviationField>(def)),
    _numSensorFailsForNonFunc(std::get<numSensorFailsForNonfuncField>(def))
{
    auto& sensors = std::get<sensorListField>(def);

    for (auto& s : sensors)
    {
        _sensors.emplace_back(
            std::make_unique<TachSensor>(bus,
                                         *this,
                                         std::get<sensorNameField>(s),
                                         std::get<hasTargetField>(s),
                                         std::get<timeoutField>(def)));

    }

}


uint64_t Fan::getTargetSpeed(const TachSensor& sensor)
{
    uint64_t target = 0;

    if (sensor.hasTarget())
    {
        target = sensor.getTarget();
    }
    else
    {
        //The sensor doesn't support a target,
        //so get it from another sensor.
        auto s = std::find_if(_sensors.begin(), _sensors.end(),
                              [](const auto& s)
                              {
                                  return s->hasTarget();
                              });

        if (s != _sensors.end())
        {
            target = (*s)->getTarget();
        }
    }

    return target;
}


bool Fan::tooManySensorsNonfunctional()
{
    size_t numFailed =  std::count_if(_sensors.begin(), _sensors.end(),
                                      [](const auto& s)
                                      {
                                          return !s->functional();
                                      });

    return (numFailed >= _numSensorFailsForNonFunc);
}


bool Fan::outOfRange(const TachSensor& sensor)
{
    auto actual = static_cast<uint64_t>(sensor.getInput());
    auto target = getTargetSpeed(sensor);

    uint64_t min = target * (100 - _deviation) / 100;
    uint64_t max = target * (100 + _deviation) / 100;

    if ((actual < min) || (actual > max))
    {
        return true;
    }

    return false;
}


}
}
}
OpenPOWER on IntegriCloud