xref: /openbmc/phosphor-fan-presence/control/json/actions/target_from_group_max.hpp (revision bb29bb7c6560946505160b0a03d2653bf67c38ee)
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