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