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
property_states_match(std::vector<PrecondGroup> && pg,std::vector<SetSpeedEvent> && sse)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 =
27 std::all_of(pg.begin(), pg.end(), [&zone](const auto& entry) {
28 try
29 {
30 return zone.getPropValueVariant(
31 std::get<pcPathPos>(entry),
32 std::get<pcIntfPos>(entry),
33 std::get<pcPropPos>(entry)) ==
34 std::get<pcValuePos>(entry);
35 }
36 catch (const std::out_of_range& oore)
37 {
38 // Default to property variants not equal when not found
39 return false;
40 }
41 });
42
43 if (precondState)
44 {
45 log<level::DEBUG>(
46 "Preconditions passed, init the associated events",
47 entry("EVENT_COUNT=%u", sse.size()));
48 // Init the events when all the precondition(s) are true
49 std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
50 zone.initEvent(entry);
51 });
52 }
53 else
54 {
55 log<level::DEBUG>(
56 "Preconditions not met for events, events removed if present",
57 entry("EVENT_COUNT=%u", sse.size()));
58 // Unsubscribe the events' signals when any precondition is false
59 std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
60 zone.removeEvent(entry);
61 });
62 zone.setFullSpeed();
63 }
64 // Update group's fan control active allowed
65 zone.setActiveAllow(&group, precondState);
66 };
67 }
68
services_missing_owner(std::vector<SetSpeedEvent> && sse)69 Action services_missing_owner(std::vector<SetSpeedEvent>&& sse)
70 {
71 return [sse = std::move(sse)](auto& zone, auto& group) {
72 // Set/update the services of the group
73 zone.setServices(&group);
74 const auto& services = zone.getGroupServices(&group);
75 auto precondState =
76 std::any_of(services.begin(), services.end(), [](const auto& s) {
77 return !std::get<hasOwnerPos>(s);
78 });
79
80 if (precondState)
81 {
82 // Init the events when all the precondition(s) are true
83 std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
84 zone.initEvent(entry);
85 });
86 }
87 else
88 {
89 // Unsubscribe the events' signals when any precondition is false
90 std::for_each(sse.begin(), sse.end(), [&zone](const auto& entry) {
91 zone.removeEvent(entry);
92 });
93 }
94 };
95 }
96
97 } // namespace precondition
98 } // namespace control
99 } // namespace fan
100 } // namespace phosphor
101