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 "count_state_target.hpp"
17 
18 #include "../manager.hpp"
19 #include "../zone.hpp"
20 #include "action.hpp"
21 #include "group.hpp"
22 
23 #include <fmt/format.h>
24 
25 #include <nlohmann/json.hpp>
26 
27 namespace phosphor::fan::control::json
28 {
29 
30 using json = nlohmann::json;
31 
32 // Instance id for setting the unique id of each instance of this action
33 size_t CountStateTarget::instanceId = 0;
34 
35 CountStateTarget::CountStateTarget(const json& jsonObj,
36                                    const std::vector<Group>& groups) :
37     ActionBase(jsonObj, groups)
38 {
39     setCount(jsonObj);
40     setState(jsonObj);
41     setTarget(jsonObj);
42 
43     _id = instanceId++;
44 }
45 
46 void CountStateTarget::run(Zone& zone)
47 {
48     size_t numAtState = 0;
49     for (const auto& group : _groups)
50     {
51         for (const auto& member : group.getMembers())
52         {
53             try
54             {
55                 if (Manager::getObjValueVariant(member, group.getInterface(),
56                                                 group.getProperty()) == _state)
57                 {
58                     numAtState++;
59                 }
60             }
61             catch (const std::out_of_range& oore)
62             {
63                 // Default to property not equal when not found
64             }
65             if (numAtState >= _count)
66             {
67                 break;
68             }
69         }
70         if (numAtState >= _count)
71         {
72             break;
73         }
74     }
75 
76     // Update zone's target hold based on action results
77     zone.setTargetHold(ActionBase::getName() + std::to_string(_id), _target,
78                        (numAtState >= _count));
79 }
80 
81 void CountStateTarget::setCount(const json& jsonObj)
82 {
83     if (!jsonObj.contains("count"))
84     {
85         throw ActionParseError{ActionBase::getName(),
86                                "Missing required count value"};
87     }
88     _count = jsonObj["count"].get<size_t>();
89 }
90 
91 void CountStateTarget::setState(const json& jsonObj)
92 {
93     if (!jsonObj.contains("state"))
94     {
95         throw ActionParseError{ActionBase::getName(),
96                                "Missing required state value"};
97     }
98     _state = getJsonValue(jsonObj["state"]);
99 }
100 
101 void CountStateTarget::setTarget(const json& jsonObj)
102 {
103     if (!jsonObj.contains("target"))
104     {
105         throw ActionParseError{ActionBase::getName(),
106                                "Missing required target value"};
107     }
108     _target = jsonObj["target"].get<uint64_t>();
109 }
110 
111 } // namespace phosphor::fan::control::json
112