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 #pragma once 17 18 #include "../zone.hpp" 19 #include "action.hpp" 20 #include "group.hpp" 21 22 #include <nlohmann/json.hpp> 23 24 namespace phosphor::fan::control::json 25 { 26 27 using json = nlohmann::json; 28 29 /** 30 * @class OverrideFanTarget - Action to override fan targets 31 * 32 * This action locks fans at configured targets when the configured `count` 33 * amount of fans meet criterion for the particular condition. A locked fan 34 * maintains its override target until unlocked (or locked at a higher target). 35 * Upon unlocking, it will either revert to temperature control or activate the 36 * the next-highest target remaining in its list of locks. 37 * 38 * The following config will set all fans in the zone to a target of 9999 if 39 * either fan has a properties_changed event where the Functional property goes 40 * false. The count value of 1 means it only requires one fan, the state value 41 * of false means Functional should go to false to be counted. The signal is 42 * declared under the "triggers" section. 43 44 [ 45 { 46 "name": "test", 47 "groups": [ 48 { "name": "fan0 sensor inventory", "interface": 49 "xyz.openbmc_project.State.Decorator.OperationalStatus", "property": { "name": 50 "Functional" } } 51 ], 52 "triggers": [ 53 { "class": "init", "method": "get_properties" }, 54 { "class": "signal", "signal": "properties_changed" } 55 ], 56 "actions": [ { 57 "name": "override_fan_target", 58 "count": 1, 59 "state": false, 60 "fans": [ "fan0", "fan1", "fan2", "fan3" ], 61 "target": 9999 62 } ] 63 } 64 ] 65 */ 66 67 class OverrideFanTarget : 68 public ActionBase, 69 public ActionRegister<OverrideFanTarget> 70 { 71 public: 72 /* Name of this action */ 73 static constexpr auto name = "override_fan_target"; 74 75 OverrideFanTarget() = delete; 76 OverrideFanTarget(const OverrideFanTarget&) = delete; 77 OverrideFanTarget(OverrideFanTarget&&) = delete; 78 OverrideFanTarget& operator=(const OverrideFanTarget&) = delete; 79 OverrideFanTarget& operator=(OverrideFanTarget&&) = delete; 80 ~OverrideFanTarget() = default; 81 82 /** 83 * @brief Set target when a number of members are at a given state 84 * 85 * @param[in] jsonObj - JSON configuration of this action 86 * @param[in] groups - Groups of dbus objects the action uses 87 */ 88 OverrideFanTarget(const json& jsonObj, const std::vector<Group>& groups); 89 90 /** 91 * @brief Run the action 92 * 93 * Counts the number of members within a group are at or above 94 * the given state. The fans are held at the configured target 95 * until the number of members equal to the given state falls 96 * below the provided count. 97 * 98 * @param[in] zone - Zone to run the action on 99 */ 100 void run(Zone& zone) override; 101 102 private: 103 /* action will be triggered when enough group members equal this state*/ 104 PropertyVariantType _state; 105 106 /* how many group members required to be at _state to trigger action*/ 107 size_t _count; 108 109 /* target for this action */ 110 uint64_t _target; 111 112 /* store locked state to know when to unlock */ 113 bool _locked = false; 114 115 /* which fans this action applies to */ 116 std::vector<std::string> _fans; 117 118 /** 119 * @brief lock all fans in this action 120 * 121 * @param[in] Zone - zone in which _fans are found 122 * 123 */ 124 void lockFans(Zone& zone); 125 126 /** 127 * @brief unlock all fans in this action 128 * 129 * @param[in] Zone - zone which _fans are found 130 * 131 */ 132 void unlockFans(Zone& zone); 133 134 /** 135 * @brief Parse and set the count 136 * 137 * @param[in] jsonObj - JSON object for the action 138 * 139 * Sets the number of members that must equal the state 140 */ 141 void setCount(const json& jsonObj); 142 143 /** 144 * @brief Parse and set the state 145 * 146 * @param[in] jsonObj - JSON object for the action 147 * 148 * Sets the state for each member to equal to set the target 149 */ 150 void setState(const json& jsonObj); 151 152 /** 153 * @brief Parse and set the target 154 * 155 * @param[in] jsonObj - JSON object for the action 156 * 157 * Sets the target to use when running the action 158 */ 159 void setTarget(const json& jsonObj); 160 161 /** 162 * @brief Parse and set the fans 163 * 164 * @param[in] jsonObj - JSON object for the action 165 * 166 * Sets the fan list the action applies to 167 */ 168 void setFans(const json& jsonObj); 169 }; 170 171 } // namespace phosphor::fan::control::json 172