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 Action call_actions_based_on_timer(TimerConf&& tConf,
15                                    std::vector<Action>&& actions)
16 {
17     return [tConf = std::move(tConf), actions = std::move(actions)](
18                control::Zone& zone, const Group& group) {
19         try
20         {
21             auto it = zone.getTimerEvents().find(__func__);
22             if (it != zone.getTimerEvents().end())
23             {
24                 auto& timers = it->second;
25                 auto timerIter = zone.findTimer(group, actions, timers);
26                 if (timerIter == timers.end())
27                 {
28                     // No timer exists yet for action, add timer
29                     zone.addTimer(__func__, group, actions, tConf);
30                 }
31                 else if (timerIter != timers.end())
32                 {
33                     // Remove any timer for this group
34                     timers.erase(timerIter);
35                     if (timers.empty())
36                     {
37                         zone.getTimerEvents().erase(it);
38                     }
39                 }
40             }
41             else
42             {
43                 // No timer exists yet for event, add timer
44                 zone.addTimer(__func__, group, actions, tConf);
45             }
46         }
47         catch (const std::out_of_range& oore)
48         {
49             // Group not found, no timers set
50         }
51     };
52 }
53 
54 void default_floor_on_missing_owner(Zone& zone, const Group& group)
55 {
56     // Set/update the services of the group
57     zone.setServices(&group);
58     auto services = zone.getGroupServices(&group);
59     auto defFloor =
60         std::any_of(services.begin(), services.end(),
61                     [](const auto& s) { return !std::get<hasOwnerPos>(s); });
62     if (defFloor)
63     {
64         zone.setFloor(zone.getDefFloor());
65     }
66     // Update fan control floor change allowed
67     zone.setFloorChangeAllow(&group, !defFloor);
68 }
69 
70 Action set_speed_on_missing_owner(uint64_t speed)
71 {
72     return [speed](control::Zone& zone, const Group& group) {
73         // Set/update the services of the group
74         zone.setServices(&group);
75         auto services = zone.getGroupServices(&group);
76         auto missingOwner = std::any_of(services.begin(), services.end(),
77                                         [](const auto& s) {
78             return !std::get<hasOwnerPos>(s);
79         });
80         if (missingOwner)
81         {
82             zone.setSpeed(speed);
83         }
84         // Update group's fan control active allowed based on action results
85         zone.setActiveAllow(&group, !missingOwner);
86     };
87 }
88 
89 void set_request_speed_base_with_max(control::Zone& zone, const Group& group)
90 {
91     int64_t base = 0;
92     std::for_each(group.begin(), group.end(),
93                   [&zone, &base](const auto& entry) {
94         try
95         {
96             auto value = zone.template getPropertyValue<int64_t>(
97                 std::get<pathPos>(entry), std::get<intfPos>(entry),
98                 std::get<propPos>(entry));
99             base = std::max(base, value);
100         }
101         catch (const std::out_of_range& oore)
102         {
103             // Property value not found, base request speed unchanged
104         }
105     });
106     // A request speed base of 0 defaults to the current target speed
107     zone.setRequestSpeedBase(base);
108 }
109 
110 } // namespace action
111 } // namespace control
112 } // namespace fan
113 } // namespace phosphor
114