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