xref: /openbmc/phosphor-fan-presence/control/actions.cpp (revision dfddd648cb81b27492afead4e2346f5fcd1397cb)
1b280bfa4SMatthew Barth #include "actions.hpp"
2b280bfa4SMatthew Barth 
3b280bfa4SMatthew Barth namespace phosphor
4b280bfa4SMatthew Barth {
5b280bfa4SMatthew Barth namespace fan
6b280bfa4SMatthew Barth {
7b280bfa4SMatthew Barth namespace control
8b280bfa4SMatthew Barth {
9b280bfa4SMatthew Barth namespace action
10b280bfa4SMatthew Barth {
11b280bfa4SMatthew Barth 
12b280bfa4SMatthew Barth using namespace phosphor::fan;
13b280bfa4SMatthew Barth 
call_actions_based_on_timer(TimerConf && tConf,std::vector<Action> && actions)14122b843fSWilliam A. Kennington III Action call_actions_based_on_timer(TimerConf&& tConf,
15122b843fSWilliam A. Kennington III                                    std::vector<Action>&& actions)
162a646c5fSMatthew Barth {
173e1bb274SMatthew Barth     return [tConf = std::move(tConf), actions = std::move(actions)](
183e1bb274SMatthew Barth                control::Zone& zone, const Group& group) {
192a646c5fSMatthew Barth         try
202a646c5fSMatthew Barth         {
21d7b716a6SMatthew Barth             auto it = zone.getTimerEvents().find(__func__);
22d7b716a6SMatthew Barth             if (it != zone.getTimerEvents().end())
232a646c5fSMatthew Barth             {
24d7b716a6SMatthew Barth                 auto& timers = it->second;
25d7b716a6SMatthew Barth                 auto timerIter = zone.findTimer(group, actions, timers);
26e7d53896SMatthew Barth                 if (timerIter == timers.end())
27d7b716a6SMatthew Barth                 {
28d7b716a6SMatthew Barth                     // No timer exists yet for action, add timer
29d7b716a6SMatthew Barth                     zone.addTimer(__func__, group, actions, tConf);
302a646c5fSMatthew Barth                 }
31e7d53896SMatthew Barth                 else if (timerIter != timers.end())
322a646c5fSMatthew Barth                 {
33d7b716a6SMatthew Barth                     // Remove any timer for this group
34d7b716a6SMatthew Barth                     timers.erase(timerIter);
35d7b716a6SMatthew Barth                     if (timers.empty())
362a646c5fSMatthew Barth                     {
37d7b716a6SMatthew Barth                         zone.getTimerEvents().erase(it);
382a646c5fSMatthew Barth                     }
392a646c5fSMatthew Barth                 }
402a646c5fSMatthew Barth             }
41e7d53896SMatthew Barth             else
42d7b716a6SMatthew Barth             {
43d7b716a6SMatthew Barth                 // No timer exists yet for event, add timer
44d7b716a6SMatthew Barth                 zone.addTimer(__func__, group, actions, tConf);
45d7b716a6SMatthew Barth             }
46d7b716a6SMatthew Barth         }
472a646c5fSMatthew Barth         catch (const std::out_of_range& oore)
482a646c5fSMatthew Barth         {
492a646c5fSMatthew Barth             // Group not found, no timers set
502a646c5fSMatthew Barth         }
512a646c5fSMatthew Barth     };
522a646c5fSMatthew Barth }
532a646c5fSMatthew Barth 
default_floor_on_missing_owner(Zone & zone,const Group & group)5498726c45SMatthew Barth void default_floor_on_missing_owner(Zone& zone, const Group& group)
5598726c45SMatthew Barth {
56480787c1SMatthew Barth     // Set/update the services of the group
57480787c1SMatthew Barth     zone.setServices(&group);
5898726c45SMatthew Barth     auto services = zone.getGroupServices(&group);
593e1bb274SMatthew Barth     auto defFloor =
603e1bb274SMatthew Barth         std::any_of(services.begin(), services.end(),
613e1bb274SMatthew Barth                     [](const auto& s) { return !std::get<hasOwnerPos>(s); });
6298726c45SMatthew Barth     if (defFloor)
6398726c45SMatthew Barth     {
6498726c45SMatthew Barth         zone.setFloor(zone.getDefFloor());
6598726c45SMatthew Barth     }
6698726c45SMatthew Barth     // Update fan control floor change allowed
6798726c45SMatthew Barth     zone.setFloorChangeAllow(&group, !defFloor);
6898726c45SMatthew Barth }
6998726c45SMatthew Barth 
set_speed_on_missing_owner(uint64_t speed)700decd1bdSMatthew Barth Action set_speed_on_missing_owner(uint64_t speed)
710decd1bdSMatthew Barth {
723e1bb274SMatthew Barth     return [speed](control::Zone& zone, const Group& group) {
73480787c1SMatthew Barth         // Set/update the services of the group
74480787c1SMatthew Barth         zone.setServices(&group);
750decd1bdSMatthew Barth         auto services = zone.getGroupServices(&group);
76*dfddd648SPatrick Williams         auto missingOwner =
77*dfddd648SPatrick Williams             std::any_of(services.begin(), services.end(), [](const auto& s) {
78*dfddd648SPatrick Williams                 return !std::get<hasOwnerPos>(s);
79*dfddd648SPatrick Williams             });
800decd1bdSMatthew Barth         if (missingOwner)
810decd1bdSMatthew Barth         {
820decd1bdSMatthew Barth             zone.setSpeed(speed);
830decd1bdSMatthew Barth         }
840decd1bdSMatthew Barth         // Update group's fan control active allowed based on action results
850decd1bdSMatthew Barth         zone.setActiveAllow(&group, !missingOwner);
860decd1bdSMatthew Barth     };
870decd1bdSMatthew Barth }
880decd1bdSMatthew Barth 
set_request_speed_base_with_max(control::Zone & zone,const Group & group)893e1bb274SMatthew Barth void set_request_speed_base_with_max(control::Zone& zone, const Group& group)
90b280bfa4SMatthew Barth {
91b280bfa4SMatthew Barth     int64_t base = 0;
92*dfddd648SPatrick Williams     std::for_each(
93*dfddd648SPatrick Williams         group.begin(), group.end(), [&zone, &base](const auto& entry) {
94b280bfa4SMatthew Barth             try
95b280bfa4SMatthew Barth             {
96b280bfa4SMatthew Barth                 auto value = zone.template getPropertyValue<int64_t>(
973e1bb274SMatthew Barth                     std::get<pathPos>(entry), std::get<intfPos>(entry),
98146b7390SMatthew Barth                     std::get<propPos>(entry));
99b280bfa4SMatthew Barth                 base = std::max(base, value);
100b280bfa4SMatthew Barth             }
101b280bfa4SMatthew Barth             catch (const std::out_of_range& oore)
102b280bfa4SMatthew Barth             {
103b280bfa4SMatthew Barth                 // Property value not found, base request speed unchanged
104b280bfa4SMatthew Barth             }
105b280bfa4SMatthew Barth         });
106b280bfa4SMatthew Barth     // A request speed base of 0 defaults to the current target speed
107b280bfa4SMatthew Barth     zone.setRequestSpeedBase(base);
108b280bfa4SMatthew Barth }
109b280bfa4SMatthew Barth 
110b280bfa4SMatthew Barth } // namespace action
111b280bfa4SMatthew Barth } // namespace control
112b280bfa4SMatthew Barth } // namespace fan
113b280bfa4SMatthew Barth } // namespace phosphor
114