1*bb29bb7cSchaul.ampere /** 2*bb29bb7cSchaul.ampere * Copyright © 2022 Ampere Computing 3*bb29bb7cSchaul.ampere * 4*bb29bb7cSchaul.ampere * Licensed under the Apache License, Version 2.0 (the "License"); 5*bb29bb7cSchaul.ampere * you may not use this file except in compliance with the License. 6*bb29bb7cSchaul.ampere * You may obtain a copy of the License at 7*bb29bb7cSchaul.ampere * 8*bb29bb7cSchaul.ampere * http://www.apache.org/licenses/LICENSE-2.0 9*bb29bb7cSchaul.ampere * 10*bb29bb7cSchaul.ampere * Unless required by applicable law or agreed to in writing, software 11*bb29bb7cSchaul.ampere * distributed under the License is distributed on an "AS IS" BASIS, 12*bb29bb7cSchaul.ampere * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*bb29bb7cSchaul.ampere * See the License for the specific language governing permissions and 14*bb29bb7cSchaul.ampere * limitations under the License. 15*bb29bb7cSchaul.ampere */ 16*bb29bb7cSchaul.ampere #pragma once 17*bb29bb7cSchaul.ampere 18*bb29bb7cSchaul.ampere #include "../utils/modifier.hpp" 19*bb29bb7cSchaul.ampere #include "../zone.hpp" 20*bb29bb7cSchaul.ampere #include "action.hpp" 21*bb29bb7cSchaul.ampere #include "group.hpp" 22*bb29bb7cSchaul.ampere 23*bb29bb7cSchaul.ampere #include <nlohmann/json.hpp> 24*bb29bb7cSchaul.ampere 25*bb29bb7cSchaul.ampere namespace phosphor::fan::control::json 26*bb29bb7cSchaul.ampere { 27*bb29bb7cSchaul.ampere 28*bb29bb7cSchaul.ampere using json = nlohmann::json; 29*bb29bb7cSchaul.ampere 30*bb29bb7cSchaul.ampere /** 31*bb29bb7cSchaul.ampere * @class class TargetFromGroupMax : - Action to set target of Zone 32*bb29bb7cSchaul.ampere * to a value corresponding to the maximum value from group's member 33*bb29bb7cSchaul.ampere * properties. The mapping is according to the configurable map. 34*bb29bb7cSchaul.ampere * 35*bb29bb7cSchaul.ampere * If there are more than one group using this action, the maximum 36*bb29bb7cSchaul.ampere * speed derived from the mapping of all groups will be set to target. 37*bb29bb7cSchaul.ampere * 38*bb29bb7cSchaul.ampere * For example: 39*bb29bb7cSchaul.ampere * 40*bb29bb7cSchaul.ampere * { 41*bb29bb7cSchaul.ampere "name": "target_from_group_max", 42*bb29bb7cSchaul.ampere "groups": [ 43*bb29bb7cSchaul.ampere { 44*bb29bb7cSchaul.ampere "name": "zone0_ambient", 45*bb29bb7cSchaul.ampere "interface": "xyz.openbmc_project.Sensor.Value", 46*bb29bb7cSchaul.ampere "property": { "name": "Value" } 47*bb29bb7cSchaul.ampere } 48*bb29bb7cSchaul.ampere ], 49*bb29bb7cSchaul.ampere "neg_hysteresis": 1, 50*bb29bb7cSchaul.ampere "pos_hysteresis": 0, 51*bb29bb7cSchaul.ampere "map": [ 52*bb29bb7cSchaul.ampere { "value": 10.0, "target": 38.0 } 53*bb29bb7cSchaul.ampere ] 54*bb29bb7cSchaul.ampere } 55*bb29bb7cSchaul.ampere 56*bb29bb7cSchaul.ampere * 57*bb29bb7cSchaul.ampere * The above JSON will cause the action to read the property specified 58*bb29bb7cSchaul.ampere * in the group "zone0_ambient" from all members of the group, the change 59*bb29bb7cSchaul.ampere * in the group's members value will be checked against "neg_hysteresis" 60*bb29bb7cSchaul.ampere * and "pos_hysteresis" to decide if it is worth taking action. 61*bb29bb7cSchaul.ampere * "neg_hysteresis" is for the increasing case and "pos_hysteresis" is 62*bb29bb7cSchaul.ampere * for the decreasing case. The maximum property value in a group will be 63*bb29bb7cSchaul.ampere * mapped to the "map" to get the output "target". The updated "target" 64*bb29bb7cSchaul.ampere * value of each group will be stored in a static map with a key. The 65*bb29bb7cSchaul.ampere * maximum value from the static map will be used to set to the Zone's target. 66*bb29bb7cSchaul.ampere * 67*bb29bb7cSchaul.ampere */ 68*bb29bb7cSchaul.ampere class TargetFromGroupMax : 69*bb29bb7cSchaul.ampere public ActionBase, 70*bb29bb7cSchaul.ampere public ActionRegister<TargetFromGroupMax> 71*bb29bb7cSchaul.ampere { 72*bb29bb7cSchaul.ampere public: 73*bb29bb7cSchaul.ampere /* Name of this action */ 74*bb29bb7cSchaul.ampere static constexpr auto name = "target_from_group_max"; 75*bb29bb7cSchaul.ampere 76*bb29bb7cSchaul.ampere TargetFromGroupMax() = delete; 77*bb29bb7cSchaul.ampere TargetFromGroupMax(const TargetFromGroupMax&) = delete; 78*bb29bb7cSchaul.ampere TargetFromGroupMax(TargetFromGroupMax&&) = delete; 79*bb29bb7cSchaul.ampere TargetFromGroupMax& operator=(const TargetFromGroupMax&) = delete; 80*bb29bb7cSchaul.ampere TargetFromGroupMax& operator=(TargetFromGroupMax&&) = delete; 81*bb29bb7cSchaul.ampere ~TargetFromGroupMax() = default; 82*bb29bb7cSchaul.ampere 83*bb29bb7cSchaul.ampere /** 84*bb29bb7cSchaul.ampere * @brief Constructor 85*bb29bb7cSchaul.ampere * 86*bb29bb7cSchaul.ampere * @param[in] jsonObj - JSON configuration of this action 87*bb29bb7cSchaul.ampere * @param[in] groups - Groups of dbus objects the action uses 88*bb29bb7cSchaul.ampere */ 89*bb29bb7cSchaul.ampere TargetFromGroupMax(const json& jsonObj, const std::vector<Group>& groups); 90*bb29bb7cSchaul.ampere 91*bb29bb7cSchaul.ampere /** 92*bb29bb7cSchaul.ampere * @brief Reads a property value from the configured group, 93*bb29bb7cSchaul.ampere * get the max, do mapping and get the target. 94*bb29bb7cSchaul.ampere * 95*bb29bb7cSchaul.ampere * @param[in] zone - Zone to run the action on 96*bb29bb7cSchaul.ampere */ 97*bb29bb7cSchaul.ampere void run(Zone& zone) override; 98*bb29bb7cSchaul.ampere 99*bb29bb7cSchaul.ampere private: 100*bb29bb7cSchaul.ampere /*The previous maximum property value from group used for checking against 101*bb29bb7cSchaul.ampere * hysteresis*/ 102*bb29bb7cSchaul.ampere uint64_t _prevGroupValue = 0; 103*bb29bb7cSchaul.ampere 104*bb29bb7cSchaul.ampere /*The table of maximum speed derived from each group using this action*/ 105*bb29bb7cSchaul.ampere static std::map<size_t, uint64_t> _speedFromGroupsMap; 106*bb29bb7cSchaul.ampere 107*bb29bb7cSchaul.ampere /*The group index counter*/ 108*bb29bb7cSchaul.ampere static size_t _groupIndexCounter; 109*bb29bb7cSchaul.ampere 110*bb29bb7cSchaul.ampere /*The Hysteresis parameters from config*/ 111*bb29bb7cSchaul.ampere uint64_t _negHysteresis = 0; 112*bb29bb7cSchaul.ampere uint64_t _posHysteresis = 0; 113*bb29bb7cSchaul.ampere 114*bb29bb7cSchaul.ampere /*The group index from config*/ 115*bb29bb7cSchaul.ampere size_t _groupIndex = 0; 116*bb29bb7cSchaul.ampere 117*bb29bb7cSchaul.ampere /*The mapping table from config*/ 118*bb29bb7cSchaul.ampere std::map<uint64_t, uint64_t> _valueToSpeedMap; 119*bb29bb7cSchaul.ampere 120*bb29bb7cSchaul.ampere /** 121*bb29bb7cSchaul.ampere * @brief Read the hysteresis parameters from the JSON 122*bb29bb7cSchaul.ampere * 123*bb29bb7cSchaul.ampere * @param[in] jsonObj - JSON configuration of this action 124*bb29bb7cSchaul.ampere */ 125*bb29bb7cSchaul.ampere void setHysteresis(const json& jsonObj); 126*bb29bb7cSchaul.ampere 127*bb29bb7cSchaul.ampere /** 128*bb29bb7cSchaul.ampere * @brief Set index for the group 129*bb29bb7cSchaul.ampere * 130*bb29bb7cSchaul.ampere * @param[in] jsonObj - JSON configuration of this action 131*bb29bb7cSchaul.ampere */ 132*bb29bb7cSchaul.ampere void setIndex(); 133*bb29bb7cSchaul.ampere 134*bb29bb7cSchaul.ampere /** 135*bb29bb7cSchaul.ampere * @brief Read the map from the JSON 136*bb29bb7cSchaul.ampere * 137*bb29bb7cSchaul.ampere * @param[in] jsonObj - JSON configuration of this action 138*bb29bb7cSchaul.ampere */ 139*bb29bb7cSchaul.ampere void setMap(const json& jsonObj); 140*bb29bb7cSchaul.ampere 141*bb29bb7cSchaul.ampere /** 142*bb29bb7cSchaul.ampere * @brief Process through all groups of the event and return the maximum 143*bb29bb7cSchaul.ampere * property value 144*bb29bb7cSchaul.ampere * 145*bb29bb7cSchaul.ampere * @param[in] jsonObj - JSON configuration of this action 146*bb29bb7cSchaul.ampere */ 147*bb29bb7cSchaul.ampere std::optional<PropertyVariantType> processGroups(); 148*bb29bb7cSchaul.ampere }; 149*bb29bb7cSchaul.ampere 150*bb29bb7cSchaul.ampere } // namespace phosphor::fan::control::json 151