xref: /openbmc/phosphor-fan-presence/control/preconditions.cpp (revision 64b5ac203518568ec8b7569d0e785352278f2472)
1 #include "preconditions.hpp"
2 
3 #include "zone.hpp"
4 
5 #include <phosphor-logging/lg2.hpp>
6 
7 #include <algorithm>
8 
9 namespace phosphor
10 {
11 namespace fan
12 {
13 namespace control
14 {
15 namespace precondition
16 {
17 
18 using namespace phosphor::fan;
19 
property_states_match(std::vector<PrecondGroup> && pg,std::vector<SetSpeedEvent> && sse)20 Action property_states_match(std::vector<PrecondGroup>&& pg,
21                              std::vector<SetSpeedEvent>&& sse)
22 {
23     return [pg = std::move(pg), sse = std::move(sse)](auto& zone, auto& group) {
24         // Compare given precondition entries
25         auto precondState =
26             std::all_of(pg.begin(), pg.end(), [&zone](const auto& entry) {
27                 try
28                 {
29                     return zone.getPropValueVariant(
30                                std::get<pcPathPos>(entry),
31                                std::get<pcIntfPos>(entry),
32                                std::get<pcPropPos>(entry)) ==
33                            std::get<pcValuePos>(entry);
34                 }
35                 catch (const std::out_of_range& oore)
36                 {
37                     // Default to property variants not equal when not found
38                     return false;
39                 }
40             });
41 
42         if (precondState)
43         {
44             lg2::debug(
45                 "Preconditions passed, init the associated events, Event_Count={EVENT_COUNT}",
46                 "EVENT_COUNT", sse.size());
47             // Init the events when all the precondition(s) are true
48             std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
49                 zone.initEvent(entry);
50             });
51         }
52         else
53         {
54             lg2::debug(
55                 "Preconditions not met for events, events removed if present, Event_Count={EVENT_COUNT}",
56                 "EVENT_COUNT", sse.size());
57             // Unsubscribe the events' signals when any precondition is false
58             std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
59                 zone.removeEvent(entry);
60             });
61             zone.setFullSpeed();
62         }
63         // Update group's fan control active allowed
64         zone.setActiveAllow(&group, precondState);
65     };
66 }
67 
services_missing_owner(std::vector<SetSpeedEvent> && sse)68 Action services_missing_owner(std::vector<SetSpeedEvent>&& sse)
69 {
70     return [sse = std::move(sse)](auto& zone, auto& group) {
71         // Set/update the services of the group
72         zone.setServices(&group);
73         const auto& services = zone.getGroupServices(&group);
74         auto precondState =
75             std::any_of(services.begin(), services.end(), [](const auto& s) {
76                 return !std::get<hasOwnerPos>(s);
77             });
78 
79         if (precondState)
80         {
81             // Init the events when all the precondition(s) are true
82             std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
83                 zone.initEvent(entry);
84             });
85         }
86         else
87         {
88             // Unsubscribe the events' signals when any precondition is false
89             std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
90                 zone.removeEvent(entry);
91             });
92         }
93     };
94 }
95 
96 } // namespace precondition
97 } // namespace control
98 } // namespace fan
99 } // namespace phosphor
100