145c44ea0SMatthew Barth /**
245c44ea0SMatthew Barth * Copyright © 2021 IBM Corporation
345c44ea0SMatthew Barth *
445c44ea0SMatthew Barth * Licensed under the Apache License, Version 2.0 (the "License");
545c44ea0SMatthew Barth * you may not use this file except in compliance with the License.
645c44ea0SMatthew Barth * You may obtain a copy of the License at
745c44ea0SMatthew Barth *
845c44ea0SMatthew Barth * http://www.apache.org/licenses/LICENSE-2.0
945c44ea0SMatthew Barth *
1045c44ea0SMatthew Barth * Unless required by applicable law or agreed to in writing, software
1145c44ea0SMatthew Barth * distributed under the License is distributed on an "AS IS" BASIS,
1245c44ea0SMatthew Barth * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1345c44ea0SMatthew Barth * See the License for the specific language governing permissions and
1445c44ea0SMatthew Barth * limitations under the License.
1545c44ea0SMatthew Barth */
1645c44ea0SMatthew Barth #include "net_target_decrease.hpp"
1745c44ea0SMatthew Barth
1845c44ea0SMatthew Barth #include "../manager.hpp"
1945c44ea0SMatthew Barth #include "../zone.hpp"
2045c44ea0SMatthew Barth #include "action.hpp"
2145c44ea0SMatthew Barth #include "group.hpp"
2245c44ea0SMatthew Barth
2345c44ea0SMatthew Barth #include <nlohmann/json.hpp>
24*64b5ac20SAnwaar Hadi #include <phosphor-logging/lg2.hpp>
2545c44ea0SMatthew Barth
2645c44ea0SMatthew Barth #include <algorithm>
2745c44ea0SMatthew Barth #include <variant>
2845c44ea0SMatthew Barth
2945c44ea0SMatthew Barth namespace phosphor::fan::control::json
3045c44ea0SMatthew Barth {
3145c44ea0SMatthew Barth
3245c44ea0SMatthew Barth using json = nlohmann::json;
3345c44ea0SMatthew Barth
NetTargetDecrease(const json & jsonObj,const std::vector<Group> & groups)3419c77494SMatthew Barth NetTargetDecrease::NetTargetDecrease(const json& jsonObj,
3519c77494SMatthew Barth const std::vector<Group>& groups) :
3619c77494SMatthew Barth ActionBase(jsonObj, groups)
3745c44ea0SMatthew Barth {
3845c44ea0SMatthew Barth setState(jsonObj);
3945c44ea0SMatthew Barth setDelta(jsonObj);
4045c44ea0SMatthew Barth }
4145c44ea0SMatthew Barth
run(Zone & zone)426d2476c9SMatthew Barth void NetTargetDecrease::run(Zone& zone)
4345c44ea0SMatthew Barth {
4420afdda3SMatthew Barth if (!_stateParameter.empty())
4520afdda3SMatthew Barth {
4620afdda3SMatthew Barth auto s = Manager::getParameter(_stateParameter);
4720afdda3SMatthew Barth if (!s)
4820afdda3SMatthew Barth {
4920afdda3SMatthew Barth return;
5020afdda3SMatthew Barth }
5120afdda3SMatthew Barth _state = *s;
5220afdda3SMatthew Barth }
5320afdda3SMatthew Barth
5445c44ea0SMatthew Barth auto netDelta = zone.getDecDelta();
556d2476c9SMatthew Barth for (const auto& group : _groups)
566d2476c9SMatthew Barth {
5745c44ea0SMatthew Barth for (const auto& member : group.getMembers())
5845c44ea0SMatthew Barth {
5945c44ea0SMatthew Barth try
6045c44ea0SMatthew Barth {
6145c44ea0SMatthew Barth auto value = Manager::getObjValueVariant(
6245c44ea0SMatthew Barth member, group.getInterface(), group.getProperty());
6345c44ea0SMatthew Barth if (std::holds_alternative<int64_t>(value) ||
6445c44ea0SMatthew Barth std::holds_alternative<double>(value))
6545c44ea0SMatthew Barth {
6645c44ea0SMatthew Barth if (value >= _state)
6745c44ea0SMatthew Barth {
6845c44ea0SMatthew Barth // No decrease allowed for this group
6945c44ea0SMatthew Barth netDelta = 0;
7045c44ea0SMatthew Barth break;
7145c44ea0SMatthew Barth }
7245c44ea0SMatthew Barth else
7345c44ea0SMatthew Barth {
746d2476c9SMatthew Barth // Decrease factor is the difference in configured state
756d2476c9SMatthew Barth // to the current value's state
7645c44ea0SMatthew Barth uint64_t deltaFactor = 0;
7745c44ea0SMatthew Barth if (auto dblPtr = std::get_if<double>(&value))
7845c44ea0SMatthew Barth {
7945c44ea0SMatthew Barth deltaFactor = static_cast<uint64_t>(
8045c44ea0SMatthew Barth std::get<double>(_state) - *dblPtr);
8145c44ea0SMatthew Barth }
8245c44ea0SMatthew Barth else
8345c44ea0SMatthew Barth {
846d2476c9SMatthew Barth deltaFactor = static_cast<uint64_t>(
856d2476c9SMatthew Barth std::get<int64_t>(_state) -
8645c44ea0SMatthew Barth std::get<int64_t>(value));
8745c44ea0SMatthew Barth }
8845c44ea0SMatthew Barth
896d2476c9SMatthew Barth // Multiply the decrease factor by the configured delta
906d2476c9SMatthew Barth // to get the net decrease delta for the given group
916d2476c9SMatthew Barth // member. The lowest net decrease delta of the entire
926d2476c9SMatthew Barth // group is the decrease requested.
9345c44ea0SMatthew Barth if (netDelta == 0)
9445c44ea0SMatthew Barth {
9545c44ea0SMatthew Barth netDelta = deltaFactor * _delta;
9645c44ea0SMatthew Barth }
9745c44ea0SMatthew Barth else
9845c44ea0SMatthew Barth {
9945c44ea0SMatthew Barth netDelta = std::min(netDelta, deltaFactor * _delta);
10045c44ea0SMatthew Barth }
10145c44ea0SMatthew Barth }
10245c44ea0SMatthew Barth }
10345c44ea0SMatthew Barth else if (std::holds_alternative<bool>(value) ||
10445c44ea0SMatthew Barth std::holds_alternative<std::string>(value))
10545c44ea0SMatthew Barth {
10645c44ea0SMatthew Barth // Where a group of booleans or strings equal the state
10745c44ea0SMatthew Barth // provided, request a decrease of the configured delta
10845c44ea0SMatthew Barth if (_state == value)
10945c44ea0SMatthew Barth {
11045c44ea0SMatthew Barth if (netDelta == 0)
11145c44ea0SMatthew Barth {
11245c44ea0SMatthew Barth netDelta = _delta;
11345c44ea0SMatthew Barth }
11445c44ea0SMatthew Barth else
11545c44ea0SMatthew Barth {
11645c44ea0SMatthew Barth netDelta = std::min(netDelta, _delta);
11745c44ea0SMatthew Barth }
11845c44ea0SMatthew Barth }
11945c44ea0SMatthew Barth }
12045c44ea0SMatthew Barth else
12145c44ea0SMatthew Barth {
12245c44ea0SMatthew Barth // Unsupported group member type for this action
123*64b5ac20SAnwaar Hadi lg2::error(
124*64b5ac20SAnwaar Hadi "Action {ACTION_NAME}: Unsupported group member type "
125*64b5ac20SAnwaar Hadi "given. [object = {MEMBER} : {GROUP_INTERFACE} : {GROUP_PROPERTY}]",
126*64b5ac20SAnwaar Hadi "ACTION_NAME", ActionBase::getName(), "MEMBER", member,
127*64b5ac20SAnwaar Hadi "GROUP_INTERFACE", group.getInterface(),
128*64b5ac20SAnwaar Hadi "GROUP_PROPERTY", group.getProperty());
12945c44ea0SMatthew Barth }
13045c44ea0SMatthew Barth }
13145c44ea0SMatthew Barth catch (const std::out_of_range& oore)
13245c44ea0SMatthew Barth {
13345c44ea0SMatthew Barth // Property value not found, netDelta unchanged
13445c44ea0SMatthew Barth }
13545c44ea0SMatthew Barth }
13645c44ea0SMatthew Barth // Update group's decrease allowed state
13745c44ea0SMatthew Barth zone.setDecreaseAllow(group.getName(), !(netDelta == 0));
1386d2476c9SMatthew Barth }
13945c44ea0SMatthew Barth // Request target decrease to occur on decrease interval
14045c44ea0SMatthew Barth zone.requestDecrease(netDelta);
14145c44ea0SMatthew Barth }
14245c44ea0SMatthew Barth
setState(const json & jsonObj)14345c44ea0SMatthew Barth void NetTargetDecrease::setState(const json& jsonObj)
14445c44ea0SMatthew Barth {
14520afdda3SMatthew Barth if (jsonObj.contains("state"))
14645c44ea0SMatthew Barth {
14745c44ea0SMatthew Barth _state = getJsonValue(jsonObj["state"]);
14845c44ea0SMatthew Barth }
14920afdda3SMatthew Barth else if (jsonObj.contains("state_parameter_name"))
15020afdda3SMatthew Barth {
15120afdda3SMatthew Barth _stateParameter = jsonObj["state_parameter_name"].get<std::string>();
15220afdda3SMatthew Barth }
15320afdda3SMatthew Barth else
15420afdda3SMatthew Barth {
15520afdda3SMatthew Barth throw ActionParseError{
15620afdda3SMatthew Barth ActionBase::getName(),
15720afdda3SMatthew Barth "Missing required state or state_parameter_name value"};
15820afdda3SMatthew Barth }
15920afdda3SMatthew Barth }
16045c44ea0SMatthew Barth
setDelta(const json & jsonObj)16145c44ea0SMatthew Barth void NetTargetDecrease::setDelta(const json& jsonObj)
16245c44ea0SMatthew Barth {
16345c44ea0SMatthew Barth if (!jsonObj.contains("delta"))
16445c44ea0SMatthew Barth {
16545c44ea0SMatthew Barth throw ActionParseError{ActionBase::getName(),
16645c44ea0SMatthew Barth "Missing required delta value"};
16745c44ea0SMatthew Barth }
16845c44ea0SMatthew Barth _delta = jsonObj["delta"].get<uint64_t>();
16945c44ea0SMatthew Barth }
17045c44ea0SMatthew Barth
17145c44ea0SMatthew Barth } // namespace phosphor::fan::control::json
172