xref: /openbmc/phosphor-fan-presence/control/preconditions.cpp (revision f724c16b42abe061752f0d78f0bdb5e2c85de4b6)
1  #include "preconditions.hpp"
2  
3  #include "zone.hpp"
4  
5  #include <phosphor-logging/log.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  using namespace phosphor::logging;
20  
21  Action property_states_match(std::vector<PrecondGroup>&& pg,
22                               std::vector<SetSpeedEvent>&& sse)
23  {
24      return [pg = std::move(pg), sse = std::move(sse)](auto& zone, auto& group) {
25          // Compare given precondition entries
26          auto precondState = std::all_of(pg.begin(), pg.end(),
27                                          [&zone](auto const& entry) {
28              try
29              {
30                  return zone.getPropValueVariant(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              log<level::DEBUG>(
45                  "Preconditions passed, init the associated events",
46                  entry("EVENT_COUNT=%u", sse.size()));
47              // Init the events when all the precondition(s) are true
48              std::for_each(sse.begin(), sse.end(), [&zone](auto const& entry) {
49                  zone.initEvent(entry);
50              });
51          }
52          else
53          {
54              log<level::DEBUG>(
55                  "Preconditions not met for events, events removed if present",
56                  entry("EVENT_COUNT=%u", sse.size()));
57              // Unsubscribe the events' signals when any precondition is false
58              std::for_each(sse.begin(), sse.end(), [&zone](auto const& 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  
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 = std::any_of(services.begin(), services.end(),
75                                          [](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](auto const& 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](auto const& entry) {
90                  zone.removeEvent(entry);
91              });
92          }
93      };
94  }
95  
96  } // namespace precondition
97  } // namespace control
98  } // namespace fan
99  } // namespace phosphor
100