1 #include "actions.hpp" 2 3 namespace phosphor 4 { 5 namespace fan 6 { 7 namespace control 8 { 9 namespace action 10 { 11 12 using namespace phosphor::fan; 13 14 void set_request_speed_base_with_max(control::Zone& zone, 15 const Group& group) 16 { 17 int64_t base = 0; 18 std::for_each( 19 group.begin(), 20 group.end(), 21 [&zone, &base](auto const& entry) 22 { 23 try 24 { 25 auto value = zone.template getPropertyValue<int64_t>( 26 entry.first, 27 std::get<intfPos>(entry.second), 28 std::get<propPos>(entry.second)); 29 base = std::max(base, value); 30 } 31 catch (const std::out_of_range& oore) 32 { 33 // Property value not found, base request speed unchanged 34 } 35 }); 36 // A request speed base of 0 defaults to the current target speed 37 zone.setRequestSpeedBase(base); 38 } 39 40 Action set_floor_from_average_sensor_value( 41 std::map<int64_t, uint64_t>&& val_to_speed) 42 { 43 return [val_to_speed = std::move(val_to_speed)](control::Zone& zone, 44 const Group& group) 45 { 46 auto speed = zone.getDefFloor(); 47 if (group.size() != 0) 48 { 49 auto count = 0; 50 auto sumValue = std::accumulate( 51 group.begin(), 52 group.end(), 53 0, 54 [&zone, &count](int64_t sum, auto const& entry) 55 { 56 try 57 { 58 return sum + 59 zone.template getPropertyValue<int64_t>( 60 entry.first, 61 std::get<intfPos>(entry.second), 62 std::get<propPos>(entry.second)); 63 } 64 catch (const std::out_of_range& oore) 65 { 66 count++; 67 return sum; 68 } 69 }); 70 if ((group.size() - count) > 0) 71 { 72 auto groupSize = static_cast<int64_t>(group.size()); 73 auto avgValue = sumValue / (groupSize - count); 74 auto it = std::find_if( 75 val_to_speed.begin(), 76 val_to_speed.end(), 77 [&avgValue](auto const& entry) 78 { 79 return avgValue < entry.first; 80 } 81 ); 82 if (it != std::end(val_to_speed)) 83 { 84 speed = (*it).second; 85 } 86 } 87 } 88 zone.setFloor(speed); 89 }; 90 } 91 92 Action set_ceiling_from_average_sensor_value( 93 std::map<int64_t, uint64_t>&& val_to_speed) 94 { 95 return [val_to_speed = std::move(val_to_speed)](Zone& zone, 96 const Group& group) 97 { 98 auto speed = zone.getCeiling(); 99 if (group.size() != 0) 100 { 101 auto count = 0; 102 auto sumValue = std::accumulate( 103 group.begin(), 104 group.end(), 105 0, 106 [&zone, &count](int64_t sum, auto const& entry) 107 { 108 try 109 { 110 return sum + 111 zone.template getPropertyValue<int64_t>( 112 entry.first, 113 std::get<intfPos>(entry.second), 114 std::get<propPos>(entry.second)); 115 } 116 catch (const std::out_of_range& oore) 117 { 118 count++; 119 return sum; 120 } 121 }); 122 if ((group.size() - count) > 0) 123 { 124 auto groupSize = static_cast<int64_t>(group.size()); 125 auto avgValue = sumValue / (groupSize - count); 126 auto prevValue = zone.swapCeilingKeyValue(avgValue); 127 if (avgValue != prevValue) 128 {// Only check if previous and new values differ 129 if (avgValue < prevValue) 130 {// Value is decreasing from previous 131 for (auto it = val_to_speed.rbegin(); 132 it != val_to_speed.rend(); 133 ++it) 134 { 135 if (it == val_to_speed.rbegin() && 136 avgValue >= it->first) 137 { 138 // Value is at/above last map key, set 139 // ceiling speed to the last map key's value 140 speed = it->second; 141 break; 142 } 143 else if (std::next(it, 1) == val_to_speed.rend() && 144 avgValue <= it->first) 145 { 146 // Value is at/below first map key, set 147 // ceiling speed to the first map key's value 148 speed = it->second; 149 break; 150 } 151 if (avgValue < it->first && 152 it->first <= prevValue) 153 { 154 // Value decreased & transitioned across 155 // a map key, update ceiling speed to this 156 // map key's value when new value is below 157 // map's key and the key is at/below the 158 // previous value 159 speed = it->second; 160 } 161 } 162 } 163 else 164 {// Value is increasing from previous 165 for (auto it = val_to_speed.begin(); 166 it != val_to_speed.end(); 167 ++it) 168 { 169 if (it == val_to_speed.begin() && 170 avgValue <= it->first) 171 { 172 // Value is at/below first map key, set 173 // ceiling speed to the first map key's value 174 speed = it->second; 175 break; 176 } 177 else if (std::next(it, 1) == val_to_speed.end() && 178 avgValue >= it->first) 179 { 180 // Value is at/above last map key, set 181 // ceiling speed to the last map key's value 182 speed = it->second; 183 break; 184 } 185 if (avgValue > it->first && 186 it->first >= prevValue) 187 { 188 // Value increased & transitioned across 189 // a map key, update ceiling speed to this 190 // map key's value when new value is above 191 // map's key and the key is at/above the 192 // previous value 193 speed = it->second; 194 } 195 } 196 } 197 } 198 } 199 } 200 zone.setCeiling(speed); 201 }; 202 } 203 204 } // namespace action 205 } // namespace control 206 } // namespace fan 207 } // namespace phosphor 208