1 /**
2  * Copyright © 2020 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 "config_base.hpp"
19 #include "types.hpp"
20 
21 #include <nlohmann/json.hpp>
22 #include <sdbusplus/bus.hpp>
23 
24 #include <any>
25 #include <functional>
26 #include <map>
27 #include <tuple>
28 
29 namespace phosphor::fan::control::json
30 {
31 
32 using json = nlohmann::json;
33 
34 /* Interface property handler function */
35 using propHandler = std::function<ZoneHandler(const json&, bool)>;
36 
37 /**
38  * @class Zone - Represents a configured fan control zone
39  *
40  * A zone object contains the configured attributes for a zone that groups
41  * a number of fans together to be under the same speed control. These
42  * configuration attributes include, but are not limited to, the full speed
43  * of the fans within the zone, a default floor speed, the delay between speed
44  * increases, a decrease interval, and any profiles(OPTIONAL) the zone should
45  * be included in.
46  *
47  * (When no profile for a zone is given, the zone defaults to always exist)
48  *
49  */
50 class Zone : public ConfigBase
51 {
52   public:
53     /* JSON file name for zones */
54     static constexpr auto confFileName = "zones.json";
55     static constexpr auto thermModeIntf =
56         "xyz.openbmc_project.Control.ThermalMode";
57     static constexpr auto supportedProp = "Supported";
58     static constexpr auto currentProp = "Current";
59 
60     Zone() = delete;
61     Zone(const Zone&) = delete;
62     Zone(Zone&&) = delete;
63     Zone& operator=(const Zone&) = delete;
64     Zone& operator=(Zone&&) = delete;
65     ~Zone() = default;
66 
67     /**
68      * Constructor
69      * Parses and populates a zone from JSON object data
70      *
71      * @param[in] bus - sdbusplus bus object
72      * @param[in] jsonObj - JSON object
73      */
74     Zone(sdbusplus::bus::bus& bus, const json& jsonObj);
75 
76     /**
77      * @brief Get the full speed
78      *
79      * Full speed is the speed set to the fans within this zone unless there
80      * are events configured that alter the fan speeds.
81      *
82      * @return Full speed of this zone
83      */
84     inline const auto& getFullSpeed() const
85     {
86         return _fullSpeed;
87     }
88 
89     /**
90      * @brief Get the default floor speed
91      *
92      * The default floor speed is the lowest speed the fans within this zone
93      * are allowed to decrease to. The zone's floor speed defaults to this
94      * unless changed by some configured event.
95      *
96      * @return Default floor speed
97      */
98     inline const auto& getDefaultFloor() const
99     {
100         return _defaultFloor;
101     }
102 
103     /**
104      * @brief Get the speed increase delay(OPTIONAL)
105      *
106      * The speed increase delay is the amount of time(in seconds) increases
107      * to a target speed are delayed before being made. The default is 0, which
108      * results in immediate speed increase requests when any events result in
109      * a change to the target speed.
110      *
111      * It is recommend a value other than 0 is configured, but that inherently
112      * depends on the fan controller and configured speed increases.
113      *
114      * @return Speed increase delay(in seconds)
115      */
116     inline const auto& getIncDelay() const
117     {
118         return _incDelay;
119     }
120 
121     /**
122      * @brief Get the speed decrease interval
123      *
124      * Speed decreases happen on a set interval when no requests for an increase
125      * in fan speeds exists. This is the interval(in seconds) at which the fans
126      * within the zone are decreased if events exist that result in a target
127      * speed decrease.
128      *
129      * @return Speed decrease interval(in seconds)
130      */
131     inline const auto& getDecInterval() const
132     {
133         return _decInterval;
134     }
135 
136     /**
137      * @brief Get the configuration of zone interface handlers
138      *
139      * Interfaces hosted by a zone can optionally be configured to set their
140      * property values and/or persistency. These interfaces must be supported
141      * by the zone object they are configured for.
142      *
143      * @return List of zone interface handler functions that set an interface's
144      * property values and persistency states
145      */
146     inline const auto& getZoneHandlers() const
147     {
148         return _zoneHandlers;
149     }
150 
151   private:
152     /* The zone's full speed value for fans */
153     uint64_t _fullSpeed;
154 
155     /* The zone's default floor speed value for fans */
156     uint64_t _defaultFloor;
157 
158     /* Zone's speed increase delay(in seconds) (OPTIONAL) */
159     uint64_t _incDelay;
160 
161     /* Zone's speed decrease interval(in seconds) */
162     uint64_t _decInterval;
163 
164     /**
165      * Zone interface handler functions for its
166      * configured interfaces (OPTIONAL)
167      */
168     std::vector<ZoneHandler> _zoneHandlers;
169 
170     /* Interface to property mapping of their associated handler function */
171     static const std::map<std::string, std::map<std::string, propHandler>>
172         _intfPropHandlers;
173 
174     /**
175      * @brief Parse and set the zone's full speed value
176      *
177      * @param[in] jsonObj - JSON object for the zone
178      *
179      * Sets the full speed value for the zone from the JSON configuration object
180      */
181     void setFullSpeed(const json& jsonObj);
182 
183     /**
184      * @brief Parse and set the zone's default floor speed value
185      *
186      * @param[in] jsonObj - JSON object for the zone
187      *
188      * Sets the default floor speed value for the zone from the JSON
189      * configuration object
190      */
191     void setDefaultFloor(const json& jsonObj);
192 
193     /**
194      * @brief Parse and set the zone's decrease interval(in seconds)
195      *
196      * @param[in] jsonObj - JSON object for the zone
197      *
198      * Sets the speed decrease interval(in seconds) for the zone from the JSON
199      * configuration object
200      */
201     void setDecInterval(const json& jsonObj);
202 
203     /**
204      * @brief Parse and set the interfaces served by the zone(OPTIONAL)
205      *
206      * @param[in] jsonObj - JSON object for the zone
207      *
208      * Constructs any zone interface handler functions for interfaces that the
209      * zone serves which contains the interface's property's value and
210      * persistency state (OPTIONAL). A property's "persist" state is defaulted
211      * to not be persisted when not given.
212      */
213     void setInterfaces(const json& jsonObj);
214 };
215 
216 /**
217  * Properties of interfaces supported by the zone configuration
218  */
219 namespace zone::property
220 {
221 
222 /**
223  * @brief "Supported" property on the "xyz.openbmc_project.Control.ThermalMode"
224  * interface
225  *
226  * @param[in] jsonObj - JSON object for the "Supported" property
227  * @param[in] persist - Whether to persist the value or not
228  *
229  * @return Zone interface handler function for the property
230  */
231 ZoneHandler supported(const json& jsonObj, bool persist);
232 
233 /**
234  * @brief "Current" property on the "xyz.openbmc_project.Control.ThermalMode"
235  * interface
236  *
237  * @param[in] jsonObj - JSON object for the "Current" property
238  * @param[in] persist - Whether to persist the value or not
239  *
240  * @return Zone interface handler function for the property
241  */
242 ZoneHandler current(const json& jsonObj, bool persist);
243 
244 } // namespace zone::property
245 
246 } // namespace phosphor::fan::control::json
247