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                 zone.setTarget(_target);
68                 break;
69             }
70         }
71         if (numAtState >= _count)
72         {
73             break;
74         }
75     }
76 
77     // Update zone's active fan control allowed based on action results
78     zone.setActiveAllow(ActionBase::getName() + std::to_string(_id),
79                         !(numAtState >= _count));
80 }
81 
82 void CountStateTarget::setCount(const json& jsonObj)
83 {
84     if (!jsonObj.contains("count"))
85     {
86         throw ActionParseError{ActionBase::getName(),
87                                "Missing required count value"};
88     }
89     _count = jsonObj["count"].get<size_t>();
90 }
91 
92 void CountStateTarget::setState(const json& jsonObj)
93 {
94     if (!jsonObj.contains("state"))
95     {
96         throw ActionParseError{ActionBase::getName(),
97                                "Missing required state value"};
98     }
99     _state = getJsonValue(jsonObj["state"]);
100 }
101 
102 void CountStateTarget::setTarget(const json& jsonObj)
103 {
104     if (!jsonObj.contains("target"))
105     {
106         throw ActionParseError{ActionBase::getName(),
107                                "Missing required target value"};
108     }
109     _target = jsonObj["target"].get<uint64_t>();
110 }
111 
112 } // namespace phosphor::fan::control::json
113