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