1 #pragma once
2 
3 #include <algorithm>
4 
5 namespace phosphor
6 {
7 namespace fan
8 {
9 namespace control
10 {
11 namespace precondition
12 {
13 
14 /**
15  * @brief A precondition to compare a group of property values and
16  * subscribe/unsubscribe a set speed event group
17  * @details Compares each entry within the precondition group to a given value
18  * that when each entry's property value matches the given value, the set speed
19  * event is then initialized. At any point a precondition entry's value no
20  * longer matches, the set speed event is removed from being active and fans
21  * are set to full speed.
22  *
23  * @param[in] pg - Precondition property group of property values
24  * @param[in] sse - Set speed event definition
25  *
26  * @return Lambda function
27  *     A lambda function to compare precondition property value states
28  *     and either subscribe or unsubscribe a set speed event group.
29  */
30 auto property_states_match(std::vector<PrecondGroup>&& pg,
31                            SetSpeedEvent&& sse)
32 {
33     return [pg = std::move(pg),
34             sse = std::move(sse)](auto& zone, auto& group)
35     {
36         // Compare given precondition entries
37         size_t precondState = std::count_if(
38             pg.begin(),
39             pg.end(),
40             [&zone](auto const& entry)
41             {
42                 try
43                 {
44                     return zone.getPropValueVariant(
45                         std::get<pcPathPos>(entry),
46                         std::get<pcIntfPos>(entry),
47                         std::get<pcPropPos>(entry)) ==
48                                 std::get<pcValuePos>(entry);
49                 }
50                 catch (const std::out_of_range& oore)
51                 {
52                     // Default to property variants not equal when not found
53                     return false;
54                 }
55             });
56 
57         // Update group's fan control active allowed
58         zone.setActiveAllow(&group, (precondState == pg.size()));
59         if (precondState == pg.size())
60         {
61             // Init the event when all the precondition(s) are true
62             zone.initEvent(sse);
63         }
64         else
65         {
66             zone.setFullSpeed();
67             // Unsubscribe the event signals when any precondition is false
68             zone.removeEvent(sse);
69         }
70     };
71 }
72 
73 } // namespace precondition
74 } // namespace control
75 } // namespace fan
76 } // namespace phosphor
77