blob: 706d9c2a37cedd5048000f892dd104d37a6e03b7 [file] [log] [blame]
Matt Spinler7f88fe62017-04-10 14:39:02 -05001#pragma once
Matthew Bartha9561842017-06-29 11:43:45 -05002#include <chrono>
Matt Spinler7f88fe62017-04-10 14:39:02 -05003#include <vector>
Matthew Barthe0ca13e2017-06-13 16:29:09 -05004#include <algorithm>
Matt Spinler7f88fe62017-04-10 14:39:02 -05005#include <sdbusplus/bus.hpp>
Matthew Barth38a93a82017-05-11 14:12:27 -05006#include <sdbusplus/server.hpp>
Matt Spinler7f88fe62017-04-10 14:39:02 -05007#include "fan.hpp"
8#include "types.hpp"
Matthew Barth8600d9a2017-06-23 14:38:05 -05009#include "timer.hpp"
Matt Spinler7f88fe62017-04-10 14:39:02 -050010
11namespace phosphor
12{
13namespace fan
14{
15namespace control
16{
17
18/**
Matthew Barth14184132017-05-19 14:37:30 -050019 * The mode fan control will run in:
20 * - init - only do the initialization steps
21 * - control - run normal control algorithms
22 */
23enum class Mode
24{
25 init,
26 control
27};
28
29/**
Matt Spinler7f88fe62017-04-10 14:39:02 -050030 * @class Represents a fan control zone, which is a group of fans
31 * that behave the same.
32 */
33class Zone
34{
35 public:
36
37 Zone() = delete;
38 Zone(const Zone&) = delete;
39 Zone(Zone&&) = default;
40 Zone& operator=(const Zone&) = delete;
41 Zone& operator=(Zone&&) = delete;
42 ~Zone() = default;
43
44 /**
45 * Constructor
46 * Creates the appropriate fan objects based on
47 * the zone definition data passed in.
48 *
Matthew Barth14184132017-05-19 14:37:30 -050049 * @param[in] mode - mode of fan control
Matt Spinler7f88fe62017-04-10 14:39:02 -050050 * @param[in] bus - the dbus object
Matthew Barth8600d9a2017-06-23 14:38:05 -050051 * @param[in] events - sd_event pointer
Matt Spinler7f88fe62017-04-10 14:39:02 -050052 * @param[in] def - the fan zone definition data
53 */
Matthew Barth14184132017-05-19 14:37:30 -050054 Zone(Mode mode,
55 sdbusplus::bus::bus& bus,
Matthew Barth8600d9a2017-06-23 14:38:05 -050056 phosphor::fan::event::EventPtr& events,
Matt Spinler7f88fe62017-04-10 14:39:02 -050057 const ZoneDefinition& def);
58
59 /**
60 * Sets all fans in the zone to the speed
61 * passed in
62 *
63 * @param[in] speed - the fan speed
64 */
65 void setSpeed(uint64_t speed);
66
67 /**
68 * Sets the zone to full speed
69 */
70 inline void setFullSpeed()
71 {
72 if (_fullSpeed != 0)
73 {
74 setSpeed(_fullSpeed);
75 }
76 }
77
Matthew Barth38a93a82017-05-11 14:12:27 -050078 /**
Matthew Barth861d77c2017-05-22 14:18:25 -050079 * @brief Sets the automatic fan control allowed active state
80 *
81 * @param[in] group - A group that affects the active state
82 * @param[in] isActiveAllow - Active state according to group
83 */
84 void setActiveAllow(const Group* group, bool isActiveAllow);
85
86 /**
Matthew Barth38a93a82017-05-11 14:12:27 -050087 * @brief Sets a given object's property value
88 *
89 * @param[in] object - Name of the object containing the property
Matthew Barthcec5ab72017-06-02 15:20:56 -050090 * @param[in] interface - Interface name containing the property
Matthew Barth38a93a82017-05-11 14:12:27 -050091 * @param[in] property - Property name
92 * @param[in] value - Property value
93 */
Matthew Barth9e741ed2017-06-02 16:29:09 -050094 template <typename T>
Matthew Barth38a93a82017-05-11 14:12:27 -050095 void setPropertyValue(const char* object,
Matthew Barthcec5ab72017-06-02 15:20:56 -050096 const char* interface,
Matthew Barth38a93a82017-05-11 14:12:27 -050097 const char* property,
Matthew Barth9e741ed2017-06-02 16:29:09 -050098 T value)
Matthew Barth38a93a82017-05-11 14:12:27 -050099 {
Matthew Barthcec5ab72017-06-02 15:20:56 -0500100 _properties[object][interface][property] = value;
Matthew Barth38a93a82017-05-11 14:12:27 -0500101 };
102
Matthew Barth17d1fe22017-05-11 15:00:36 -0500103 /**
104 * @brief Get the value of an object's property
105 *
106 * @param[in] object - Name of the object containing the property
Matthew Barthcec5ab72017-06-02 15:20:56 -0500107 * @param[in] interface - Interface name containing the property
Matthew Barth17d1fe22017-05-11 15:00:36 -0500108 * @param[in] property - Property name
109 *
110 * @return - The property value
111 */
Matthew Barth9e741ed2017-06-02 16:29:09 -0500112 template <typename T>
Matthew Barth17d1fe22017-05-11 15:00:36 -0500113 inline auto getPropertyValue(const std::string& object,
Matthew Barthcec5ab72017-06-02 15:20:56 -0500114 const std::string& interface,
Matthew Barth17d1fe22017-05-11 15:00:36 -0500115 const std::string& property)
116 {
Matthew Barth9e741ed2017-06-02 16:29:09 -0500117 return sdbusplus::message::variant_ns::get<T>(
118 _properties[object][interface][property]);
Matthew Barth17d1fe22017-05-11 15:00:36 -0500119 };
120
Matthew Barth1de66622017-06-12 13:13:02 -0500121 /**
122 * @brief Get the default floor speed
123 *
124 * @return - The defined default floor speed
125 */
126 inline auto getDefFloor()
127 {
128 return _defFloorSpeed;
129 };
130
Matthew Barth4af419c2017-06-12 13:39:31 -0500131 /**
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500132 * @brief Get the ceiling speed
133 *
134 * @return - The current ceiling speed
135 */
136 inline auto& getCeiling() const
137 {
138 return _ceilingSpeed;
139 };
140
141 /**
142 * @brief Set the ceiling speed to the given speed
143 *
144 * @param[in] speed - Speed to set the ceiling to
145 */
146 inline void setCeiling(uint64_t speed)
147 {
148 _ceilingSpeed = speed;
149 };
150
151 /**
152 * @brief Swaps the ceiling key value with what's given and
153 * returns the value that was swapped.
154 *
155 * @param[in] keyValue - New ceiling key value
156 *
157 * @return - Ceiling key value prior to swapping
158 */
159 inline auto swapCeilingKeyValue(int64_t keyValue)
160 {
161 std::swap(_ceilingKeyValue, keyValue);
162 return keyValue;
163 };
164
Matthew Barth24623522017-06-21 14:09:57 -0500165 /**
166 * @brief Get the increase speed delta
167 *
168 * @return - The current increase speed delta
169 */
170 inline auto& getIncSpeedDelta() const
171 {
172 return _incSpeedDelta;
173 };
174
Matthew Barth240397b2017-06-22 11:23:30 -0500175 /**
Matthew Barth0ce99d82017-06-22 15:07:29 -0500176 * @brief Get the decrease speed delta
177 *
178 * @return - The current decrease speed delta
179 */
180 inline auto& getDecSpeedDelta() const
181 {
182 return _decSpeedDelta;
183 };
184
185 /**
Matthew Barthb4a7cb92017-06-28 15:29:50 -0500186 * @brief Set the floor speed to the given speed and increase target
187 * speed to the floor when target is below floor.
188 *
189 * @param[in] speed - Speed to set the floor to
190 */
191 void setFloor(uint64_t speed);
192
193 /**
Matthew Barth240397b2017-06-22 11:23:30 -0500194 * @brief Calculate the requested target speed from the given delta
195 * and increase the fan speeds, not going above the ceiling.
196 *
197 * @param[in] targetDelta - The delta to increase the target speed by
198 */
199 void requestSpeedIncrease(uint64_t targetDelta);
200
Matthew Barth0ce99d82017-06-22 15:07:29 -0500201 /**
202 * @brief Calculate the requested target speed from the given delta
203 * and increase the fan speeds, not going above the ceiling.
204 *
205 * @param[in] targetDelta - The delta to increase the target speed by
206 */
207 void requestSpeedDecrease(uint64_t targetDelta);
208
Matthew Barth8600d9a2017-06-23 14:38:05 -0500209 /**
Matthew Barth1ee48f22017-06-27 15:14:48 -0500210 * @brief Callback function for the increase timer that delays
211 * processing of requested speed increases while fans are increasing
212 */
213 void incTimerExpired();
214
215 /**
Matthew Barth8600d9a2017-06-23 14:38:05 -0500216 * @brief Callback function for the decrease timer that processes any
217 * requested speed decreases if allowed
218 */
219 void decTimerExpired();
220
Matt Spinler7f88fe62017-04-10 14:39:02 -0500221 private:
222
223 /**
224 * The dbus object
225 */
226 sdbusplus::bus::bus& _bus;
227
228 /**
229 * Full speed for the zone
230 */
231 const uint64_t _fullSpeed;
232
233 /**
234 * The zone number
235 */
236 const size_t _zoneNum;
237
238 /**
Matthew Barth1de66622017-06-12 13:13:02 -0500239 * The default floor speed for the zone
240 */
241 const uint64_t _defFloorSpeed;
242
243 /**
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500244 * The default ceiling speed for the zone
245 */
246 const uint64_t _defCeilingSpeed;
247
248 /**
Matthew Barth4af419c2017-06-12 13:39:31 -0500249 * The floor speed to not go below
250 */
251 uint64_t _floorSpeed = _defFloorSpeed;
252
253 /**
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500254 * The ceiling speed to not go above
255 */
256 uint64_t _ceilingSpeed = _defCeilingSpeed;
257
258 /**
259 * The previous sensor value for calculating the ceiling
260 */
261 int64_t _ceilingKeyValue = 0;
262
263 /**
Matthew Barth861d77c2017-05-22 14:18:25 -0500264 * Automatic fan control active state
265 */
266 bool _isActive = true;
267
268 /**
Matthew Barth240397b2017-06-22 11:23:30 -0500269 * Target speed for this zone
270 */
271 uint64_t _targetSpeed = _fullSpeed;
272
273 /**
Matthew Barth24623522017-06-21 14:09:57 -0500274 * Speed increase delta
275 */
276 uint64_t _incSpeedDelta = 0;
277
278 /**
Matthew Barth0ce99d82017-06-22 15:07:29 -0500279 * Speed decrease delta
280 */
281 uint64_t _decSpeedDelta = 0;
282
283 /**
Matthew Bartha9561842017-06-29 11:43:45 -0500284 * Speed increase delay in seconds
285 */
286 std::chrono::seconds _incDelay;
287
288 /**
289 * Speed decrease interval in seconds
290 */
291 std::chrono::seconds _decInterval;
292
293 /**
Matthew Barth1ee48f22017-06-27 15:14:48 -0500294 * The increase timer object
295 */
296 phosphor::fan::util::Timer _incTimer;
297
298 /**
Matthew Barth8600d9a2017-06-23 14:38:05 -0500299 * The decrease timer object
300 */
301 phosphor::fan::util::Timer _decTimer;
302
303 /**
Matt Spinler7f88fe62017-04-10 14:39:02 -0500304 * The vector of fans in this zone
305 */
306 std::vector<std::unique_ptr<Fan>> _fans;
Matthew Barth38a93a82017-05-11 14:12:27 -0500307
308 /**
309 * @brief Map of object property values
310 */
Matthew Barthcec5ab72017-06-02 15:20:56 -0500311 std::map<std::string,
312 std::map<std::string,
313 std::map<std::string,
Matthew Barth9e741ed2017-06-02 16:29:09 -0500314 PropertyVariantType>>> _properties;
Matthew Barth38a93a82017-05-11 14:12:27 -0500315
316 /**
Matthew Barth861d77c2017-05-22 14:18:25 -0500317 * @brief Map of active fan control allowed by groups
318 */
319 std::map<const Group*, bool> _active;
320
321 /**
Matthew Barth38a93a82017-05-11 14:12:27 -0500322 * @brief List of signal event arguments
323 */
Matthew Barth34f1bda2017-05-31 13:45:36 -0500324 std::vector<std::unique_ptr<EventData>> _signalEvents;
Matthew Barth38a93a82017-05-11 14:12:27 -0500325
326 /**
327 * @brief list of Dbus matches for callbacks
328 */
329 std::vector<sdbusplus::server::match::match> _matches;
330
331 /**
Matthew Barth1bf0ce42017-06-23 16:16:30 -0500332 * @brief Initialize all the set speed event properties and actions
333 *
334 * @param[in] def - zone definition containing set speed events
335 */
336 void initEvents(const ZoneDefinition& def);
337
338 /**
339 * @brief Refresh the given property's cached value
340 *
341 * @param[in] bus - the bus to use
342 * @param[in] path - the dbus path name
343 * @param[in] iface - the dbus interface name
344 * @param[in] prop - the property name
345 */
346 void refreshProperty(sdbusplus::bus::bus& bus,
347 const std::string& path,
348 const std::string& iface,
349 const std::string& prop);
350
351 /**
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500352 * @brief Get a property value from the path/interface given
353 *
354 * @param[in] bus - the bus to use
355 * @param[in] path - the dbus path name
356 * @param[in] iface - the dbus interface name
357 * @param[in] prop - the property name
358 * @param[out] value - the value of the property
359 */
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500360 static void getProperty(sdbusplus::bus::bus& bus,
361 const std::string& path,
362 const std::string& iface,
363 const std::string& prop,
Matthew Barth9e741ed2017-06-02 16:29:09 -0500364 PropertyVariantType& value);
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500365
366 /**
Matthew Barth34f1bda2017-05-31 13:45:36 -0500367 * @brief Dbus signal change callback handler
Matthew Barth38a93a82017-05-11 14:12:27 -0500368 *
Matthew Barth34f1bda2017-05-31 13:45:36 -0500369 * @param[in] msg - Expanded sdbusplus message data
370 * @param[in] eventData - The single event's data
Matthew Barth38a93a82017-05-11 14:12:27 -0500371 */
Matthew Barth34f1bda2017-05-31 13:45:36 -0500372 void handleEvent(sdbusplus::message::message& msg,
373 const EventData* eventData);
Matt Spinler7f88fe62017-04-10 14:39:02 -0500374};
375
376}
377}
378}