1 /**
2  * Copyright © 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "request_target_base.hpp"
17 
18 #include "../manager.hpp"
19 #include "../zone.hpp"
20 #include "group.hpp"
21 
22 #include <fmt/format.h>
23 
24 #include <nlohmann/json.hpp>
25 #include <phosphor-logging/log.hpp>
26 
27 #include <algorithm>
28 
29 namespace phosphor::fan::control::json
30 {
31 
32 using json = nlohmann::json;
33 using namespace phosphor::logging;
34 
35 RequestTargetBase::RequestTargetBase(const json& jsonObj,
36                                      const std::vector<Group>& groups) :
37     ActionBase(jsonObj, groups)
38 {
39     // There are no JSON configuration parameters for this action
40 }
41 
42 void RequestTargetBase::run(Zone& zone)
43 {
44     uint64_t base = 0;
45     for (const auto& group : _groups)
46     {
47         for (const auto& member : group.getMembers())
48         {
49             try
50             {
51                 auto value = Manager::getObjValueVariant(
52                     member, group.getInterface(), group.getProperty());
53                 if (auto intPtr = std::get_if<int64_t>(&value))
54                 {
55                     // Throw out any negative values as those are not valid
56                     // to use as a fan target base
57                     if (*intPtr < 0)
58                     {
59                         continue;
60                     }
61                     base = std::max(base, static_cast<uint64_t>(*intPtr));
62                 }
63                 else if (auto dblPtr = std::get_if<double>(&value))
64                 {
65                     // Throw out any negative values as those are not valid
66                     // to use as a fan target base
67                     if (*dblPtr < 0)
68                     {
69                         continue;
70                     }
71                     // Precision of a double not a concern with fan targets
72                     base = std::max(base, static_cast<uint64_t>(*dblPtr));
73                 }
74                 else
75                 {
76                     // Unsupported group member type for this action
77                     log<level::ERR>(
78                         fmt::format("Action {}: Unsupported group member type "
79                                     "given. [object = {} : {} : {}]",
80                                     getName(), member, group.getInterface(),
81                                     group.getProperty())
82                             .c_str());
83                 }
84             }
85             catch (const std::out_of_range& oore)
86             {
87                 // Property value not found, base request target unchanged
88             }
89         }
90     }
91 
92     // A request target base of 0 defaults to the current target
93     zone.setRequestTargetBase(base);
94 }
95 
96 } // namespace phosphor::fan::control::json
97