1 /** 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 23 #include <fmt/format.h> 24 #include <fmt/ranges.h> 25 26 #include <nlohmann/json.hpp> 27 28 namespace phosphor::fan::control::json 29 { 30 31 using json = nlohmann::json; 32 33 OverrideFanTarget::OverrideFanTarget(const json& jsonObj, 34 const std::vector<Group>& groups) : 35 ActionBase(jsonObj, groups) 36 { 37 setCount(jsonObj); 38 setState(jsonObj); 39 setTarget(jsonObj); 40 setFans(jsonObj); 41 } 42 43 void OverrideFanTarget::run(Zone& zone) 44 { 45 size_t numAtState = 0; 46 47 for (const auto& group : _groups) 48 { 49 for (const auto& member : group.getMembers()) 50 { 51 try 52 { 53 if (Manager::getObjValueVariant(member, group.getInterface(), 54 group.getProperty()) == _state) 55 { 56 numAtState++; 57 58 if (numAtState >= _count) 59 { 60 break; 61 } 62 } 63 } 64 catch (const std::out_of_range&) 65 {} 66 } 67 68 // lock the fans 69 if (numAtState >= _count) 70 { 71 lockFans(zone); 72 break; 73 } 74 } 75 76 if (_locked && numAtState < _count) 77 { 78 unlockFans(zone); 79 } 80 } 81 82 void OverrideFanTarget::lockFans(Zone& zone) 83 { 84 if (!_locked) 85 { 86 record(fmt::format("Adding fan target lock of {} on fans {} zone {}", 87 _target, _fans, zone.getName())); 88 89 for (auto& fan : _fans) 90 { 91 zone.lockFanTarget(fan, _target); 92 } 93 94 _locked = true; 95 } 96 } 97 98 void OverrideFanTarget::unlockFans(Zone& zone) 99 { 100 record(fmt::format("Un-locking fan target {} on fans {} zone {}", _target, 101 _fans, zone.getName())); 102 103 // unlock all fans in this instance 104 for (auto& fan : _fans) 105 { 106 zone.unlockFanTarget(fan, _target); 107 } 108 109 _locked = false; 110 } 111 112 void OverrideFanTarget::setCount(const json& jsonObj) 113 { 114 if (!jsonObj.contains("count")) 115 { 116 throw ActionParseError{ActionBase::getName(), 117 "Missing required count value"}; 118 } 119 _count = jsonObj["count"].get<size_t>(); 120 } 121 122 void OverrideFanTarget::setState(const json& jsonObj) 123 { 124 if (!jsonObj.contains("state")) 125 { 126 throw ActionParseError{ActionBase::getName(), 127 "Missing required state value"}; 128 } 129 _state = getJsonValue(jsonObj["state"]); 130 } 131 132 void OverrideFanTarget::setTarget(const json& jsonObj) 133 { 134 if (!jsonObj.contains("target")) 135 { 136 throw ActionParseError{ActionBase::getName(), 137 "Missing required target value"}; 138 } 139 _target = jsonObj["target"].get<uint64_t>(); 140 } 141 142 void OverrideFanTarget::setFans(const json& jsonObj) 143 { 144 if (!jsonObj.contains("fans")) 145 { 146 throw ActionParseError{ActionBase::getName(), 147 "Missing required fans value"}; 148 } 149 150 _fans = jsonObj["fans"].get<std::vector<std::string>>(); 151 } 152 153 } // namespace phosphor::fan::control::json 154