blob: 33fbd3442c099f42a9aae1dd16b55b8dd89dd682 [file] [log] [blame]
Mike Capps59af8ca2021-10-07 15:42:28 -04001/**
2 * Copyright © 2022 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 "override_fan_target.hpp"
17
18#include "../manager.hpp"
19#include "../zone.hpp"
20#include "action.hpp"
21#include "group.hpp"
22
Mike Capps59af8ca2021-10-07 15:42:28 -040023#include <nlohmann/json.hpp>
24
Matt Spinler2e22b232023-08-24 16:08:46 -050025#include <format>
26
Mike Capps59af8ca2021-10-07 15:42:28 -040027namespace phosphor::fan::control::json
28{
29
30using json = nlohmann::json;
31
32OverrideFanTarget::OverrideFanTarget(const json& jsonObj,
33 const std::vector<Group>& groups) :
34 ActionBase(jsonObj, groups)
35{
36 setCount(jsonObj);
37 setState(jsonObj);
38 setTarget(jsonObj);
39 setFans(jsonObj);
40}
41
42void OverrideFanTarget::run(Zone& zone)
43{
44 size_t numAtState = 0;
45
46 for (const auto& group : _groups)
47 {
48 for (const auto& member : group.getMembers())
49 {
50 try
51 {
52 if (Manager::getObjValueVariant(member, group.getInterface(),
53 group.getProperty()) == _state)
54 {
55 numAtState++;
56
57 if (numAtState >= _count)
58 {
59 break;
60 }
61 }
62 }
63 catch (const std::out_of_range&)
64 {}
65 }
66
67 // lock the fans
68 if (numAtState >= _count)
69 {
70 lockFans(zone);
71 break;
72 }
73 }
74
75 if (_locked && numAtState < _count)
76 {
77 unlockFans(zone);
78 }
79}
80
81void OverrideFanTarget::lockFans(Zone& zone)
82{
83 if (!_locked)
84 {
Matt Spinler2e22b232023-08-24 16:08:46 -050085 std::string fanList;
86 if (!_fans.empty())
87 {
88 fanList = std::accumulate(std::next(_fans.begin()), _fans.end(),
89 _fans[0], [](auto list, auto fan) {
Patrick Williamsdfddd642024-08-16 15:21:51 -040090 return std::move(list) + ", " + fan;
91 });
Matt Spinler2e22b232023-08-24 16:08:46 -050092 }
93
94 record(std::format("Adding fan target lock of {} on fans [{}] zone {}",
95 _target, fanList, zone.getName()));
Mike Capps59af8ca2021-10-07 15:42:28 -040096
97 for (auto& fan : _fans)
98 {
99 zone.lockFanTarget(fan, _target);
100 }
101
102 _locked = true;
103 }
104}
105
106void OverrideFanTarget::unlockFans(Zone& zone)
107{
Matt Spinler2e22b232023-08-24 16:08:46 -0500108 std::string fanList;
109 if (!_fans.empty())
110 {
111 fanList = std::accumulate(
112 std::next(_fans.begin()), _fans.end(), _fans[0],
113 [](auto list, auto fan) { return std::move(list) + ", " + fan; });
114 }
115
116 record(std::format("Un-locking fan target {} on fans [{}] zone {}", _target,
117 fanList, zone.getName()));
Mike Capps59af8ca2021-10-07 15:42:28 -0400118
119 // unlock all fans in this instance
120 for (auto& fan : _fans)
121 {
122 zone.unlockFanTarget(fan, _target);
123 }
124
125 _locked = false;
126}
127
128void OverrideFanTarget::setCount(const json& jsonObj)
129{
130 if (!jsonObj.contains("count"))
131 {
132 throw ActionParseError{ActionBase::getName(),
133 "Missing required count value"};
134 }
135 _count = jsonObj["count"].get<size_t>();
136}
137
138void OverrideFanTarget::setState(const json& jsonObj)
139{
140 if (!jsonObj.contains("state"))
141 {
142 throw ActionParseError{ActionBase::getName(),
143 "Missing required state value"};
144 }
145 _state = getJsonValue(jsonObj["state"]);
146}
147
148void OverrideFanTarget::setTarget(const json& jsonObj)
149{
150 if (!jsonObj.contains("target"))
151 {
152 throw ActionParseError{ActionBase::getName(),
153 "Missing required target value"};
154 }
155 _target = jsonObj["target"].get<uint64_t>();
156}
157
158void OverrideFanTarget::setFans(const json& jsonObj)
159{
160 if (!jsonObj.contains("fans"))
161 {
162 throw ActionParseError{ActionBase::getName(),
163 "Missing required fans value"};
164 }
165
166 _fans = jsonObj["fans"].get<std::vector<std::string>>();
167}
168
169} // namespace phosphor::fan::control::json