summaryrefslogtreecommitdiffstats
path: root/control/preconditions.hpp
blob: f989f0d4ab2d75b49d1568e6119852eae7f275f4 (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
#pragma once

#include <algorithm>

namespace phosphor
{
namespace fan
{
namespace control
{
namespace precondition
{

/**
 * @brief A precondition to compare a group of property values and
 * subscribe/unsubscribe a set speed event group
 * @details Compares each entry within the precondition group to a given value
 * that when each entry's property value matches the given value, the set speed
 * event is then initialized. At any point a precondition entry's value no
 * longer matches, the set speed event is removed from being active and fans
 * are set to full speed.
 *
 * @param[in] pg - Precondition property group of property values
 * @param[in] sse - Set speed event definition
 *
 * @return Lambda function
 *     A lambda function to compare precondition property value states
 *     and either subscribe or unsubscribe a set speed event group.
 */
auto property_states_match(std::vector<PrecondGroup>&& pg,
                           std::vector<SetSpeedEvent>&& sse)
{
    return [pg = std::move(pg),
            sse = std::move(sse)](auto& zone, auto& group)
    {
        // Compare given precondition entries
        size_t precondState = std::count_if(
            pg.begin(),
            pg.end(),
            [&zone](auto const& entry)
            {
                try
                {
                    return zone.getPropValueVariant(
                        std::get<pcPathPos>(entry),
                        std::get<pcIntfPos>(entry),
                        std::get<pcPropPos>(entry)) ==
                                std::get<pcValuePos>(entry);
                }
                catch (const std::out_of_range& oore)
                {
                    // Default to property variants not equal when not found
                    return false;
                }
            });

        if (precondState == pg.size())
        {
            // Init the events when all the precondition(s) are true
            std::for_each(
                sse.begin(),
                sse.end(),
                [&zone](auto const& entry)
                {
                    zone.initEvent(entry);
                });
        }
        else
        {
            // Unsubscribe the events' signals when any precondition is false
            std::for_each(
                sse.begin(),
                sse.end(),
                [&zone](auto const& entry)
                {
                    zone.removeEvent(entry);
                });
            zone.setFullSpeed();
        }
        // Update group's fan control active allowed
        zone.setActiveAllow(&group, (precondState == pg.size()));
    };
}

} // namespace precondition
} // namespace control
} // namespace fan
} // namespace phosphor
OpenPOWER on IntegriCloud