blob: ce9c6bf7313b6924229941babb1f526bf1c5ecdc [file] [log] [blame]
Matt Spinler7f88fe62017-04-10 14:39:02 -05001#pragma once
Matthew Barth3e1bb272020-05-26 11:09:21 -05002#include "fan.hpp"
3#include "sdbusplus.hpp"
4#include "types.hpp"
5#include "xyz/openbmc_project/Control/ThermalMode/server.hpp"
6
7#include <sdbusplus/bus.hpp>
8#include <sdeventplus/event.hpp>
9
William A. Kennington III8fd879f2018-10-30 19:49:29 -070010#include <algorithm>
William A. Kennington III2c8e1982018-11-12 08:37:07 -080011#include <cassert>
Matthew Bartha9561842017-06-29 11:43:45 -050012#include <chrono>
Patrick Williamsed7b0342020-02-12 10:29:46 -060013#include <cmath>
Matthew Barth5a80f3a2020-03-13 11:28:18 -050014#include <optional>
Matthew Barth3e1bb272020-05-26 11:09:21 -050015#include <vector>
Matt Spinler7f88fe62017-04-10 14:39:02 -050016
17namespace phosphor
18{
19namespace fan
20{
21namespace control
22{
23
Patrick Williamscb356d42022-07-22 19:26:53 -050024using ThermalObject = sdbusplus::server::object_t<
Matthew Barth93af4192019-01-18 09:30:57 -060025 sdbusplus::xyz::openbmc_project::Control::server::ThermalMode>;
26
Matt Spinler7f88fe62017-04-10 14:39:02 -050027/**
Matthew Barth14184132017-05-19 14:37:30 -050028 * The mode fan control will run in:
29 * - init - only do the initialization steps
30 * - control - run normal control algorithms
31 */
32enum class Mode
33{
34 init,
35 control
36};
37
38/**
Matt Spinler7f88fe62017-04-10 14:39:02 -050039 * @class Represents a fan control zone, which is a group of fans
40 * that behave the same.
41 */
Matthew Barth93af4192019-01-18 09:30:57 -060042class Zone : public ThermalObject
Matt Spinler7f88fe62017-04-10 14:39:02 -050043{
Matthew Barth3e1bb272020-05-26 11:09:21 -050044 public:
45 Zone() = delete;
46 Zone(const Zone&) = delete;
47 Zone(Zone&&) = delete;
48 Zone& operator=(const Zone&) = delete;
49 Zone& operator=(Zone&&) = delete;
50 ~Zone() = default;
Matt Spinler7f88fe62017-04-10 14:39:02 -050051
Matthew Barth3e1bb272020-05-26 11:09:21 -050052 /**
53 * Constructor
54 * Creates the appropriate fan objects based on
55 * the zone definition data passed in.
56 *
57 * @param[in] mode - mode of fan control
58 * @param[in] bus - the dbus object
59 * @param[in] path - object instance path
60 * @param[in] event - Event loop reference
61 * @param[in] def - the fan zone definition data
62 */
Patrick Williamscb356d42022-07-22 19:26:53 -050063 Zone(Mode mode, sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth3e1bb272020-05-26 11:09:21 -050064 const sdeventplus::Event& event, const ZoneDefinition& def);
Matt Spinler7f88fe62017-04-10 14:39:02 -050065
Matthew Barth3e1bb272020-05-26 11:09:21 -050066 /**
67 * @brief Get the zone's bus
68 *
69 * @return The bus used by the zone
70 */
71 inline auto& getBus()
72 {
73 return _bus;
74 }
Matt Spinler7f88fe62017-04-10 14:39:02 -050075
Matthew Barth3e1bb272020-05-26 11:09:21 -050076 /**
77 * @brief Get the zone's path
78 *
79 * @return The path of this zone
80 */
81 inline auto& getPath()
82 {
83 return _path;
84 }
Matthew Barth016bd242018-03-07 16:06:06 -060085
Matthew Barth3e1bb272020-05-26 11:09:21 -050086 /**
87 * @brief Get the zone's hosted interfaces
88 *
89 * @return The interfaces hosted by this zone
90 */
91 inline auto& getIfaces()
92 {
93 return _ifaces;
94 }
Matthew Barth016bd242018-03-07 16:06:06 -060095
Matthew Barth3e1bb272020-05-26 11:09:21 -050096 /**
97 * Sets all fans in the zone to the speed
98 * passed in when the zone is active
99 *
100 * @param[in] speed - the fan speed
101 */
102 void setSpeed(uint64_t speed);
Matthew Barth016bd242018-03-07 16:06:06 -0600103
Matthew Barth3e1bb272020-05-26 11:09:21 -0500104 /**
105 * Sets the zone to full speed regardless of zone's active state
106 */
107 void setFullSpeed();
Matt Spinler7f88fe62017-04-10 14:39:02 -0500108
Matthew Barth3e1bb272020-05-26 11:09:21 -0500109 /**
110 * @brief Sets the automatic fan control allowed active state
111 *
112 * @param[in] group - A group that affects the active state
113 * @param[in] isActiveAllow - Active state according to group
114 */
115 void setActiveAllow(const Group* group, bool isActiveAllow);
Matt Spinler7f88fe62017-04-10 14:39:02 -0500116
Matthew Barth3e1bb272020-05-26 11:09:21 -0500117 /**
118 * @brief Sets the floor change allowed state
119 *
120 * @param[in] group - A group that affects floor changes
121 * @param[in] isAllow - Allow state according to group
122 */
123 inline void setFloorChangeAllow(const Group* group, bool isAllow)
124 {
125 _floorChange[*(group)] = isAllow;
126 }
Matthew Barth861d77c2017-05-22 14:18:25 -0500127
Matthew Barth3e1bb272020-05-26 11:09:21 -0500128 /**
129 * @brief Sets the decrease allowed state of a group
130 *
131 * @param[in] group - A group that affects speed decreases
132 * @param[in] isAllow - Allow state according to group
133 */
134 inline void setDecreaseAllow(const Group* group, bool isAllow)
135 {
136 _decAllowed[*(group)] = isAllow;
137 }
Matthew Barth98726c42017-10-17 10:35:20 -0500138
Matthew Barth3e1bb272020-05-26 11:09:21 -0500139 /**
140 * @brief Sets a given object's event data for a property on this zone
141 *
142 * @param[in] object - Name of the object containing the property
143 * @param[in] interface - Interface name containing the property
144 * @param[in] property - Property name
145 * @param[in] data - Property value
146 */
147 inline void setObjectData(const std::string& object,
Matthew Barth016bd242018-03-07 16:06:06 -0600148 const std::string& interface,
Matthew Barth3e1bb272020-05-26 11:09:21 -0500149 const std::string& property, EventData* data)
150 {
151 _objects[object][interface][property] = data;
152 }
Matthew Barth016bd242018-03-07 16:06:06 -0600153
Matthew Barth3e1bb272020-05-26 11:09:21 -0500154 /**
155 * @brief Sets a given object's property value
156 *
157 * @param[in] object - Name of the object containing the property
158 * @param[in] interface - Interface name containing the property
159 * @param[in] property - Property name
160 * @param[in] value - Property value
161 */
162 template <typename T>
163 void setPropertyValue(const char* object, const char* interface,
164 const char* property, T value)
165 {
166 _properties[object][interface][property] = value;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400167 }
Matthew Barth17d1fe22017-05-11 15:00:36 -0500168
Matthew Barth3e1bb272020-05-26 11:09:21 -0500169 /**
170 * @brief Sets a given object's property value
171 *
172 * @param[in] object - Name of the object containing the property
173 * @param[in] interface - Interface name containing the property
174 * @param[in] property - Property name
175 * @param[in] value - Property value
176 */
177 template <typename T>
178 void setPropertyValue(const std::string& object,
179 const std::string& interface,
180 const std::string& property, T value)
181 {
182 _properties[object][interface][property] = value;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400183 }
Matthew Barth604329e2017-08-04 11:18:28 -0500184
Matthew Barth3e1bb272020-05-26 11:09:21 -0500185 /**
186 * @brief Get the value of an object's property
187 *
188 * @param[in] object - Name of the object containing the property
189 * @param[in] interface - Interface name containing the property
190 * @param[in] property - Property name
191 *
192 * @return - The property value
193 */
194 template <typename T>
195 inline auto getPropertyValue(const std::string& object,
196 const std::string& interface,
197 const std::string& property)
198 {
199 return std::get<T>(_properties.at(object).at(interface).at(property));
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400200 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500201
202 /**
203 * @brief Get the object's property variant
204 *
205 * @param[in] object - Name of the object containing the property
206 * @param[in] interface - Interface name containing the property
207 * @param[in] property - Property name
208 *
209 * @return - The property variant
210 */
211 inline auto getPropValueVariant(const std::string& object,
212 const std::string& interface,
213 const std::string& property)
214 {
215 return _properties.at(object).at(interface).at(property);
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400216 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500217
218 /**
219 * @brief Get a property's value after applying a set of visitors
220 * to translate the property value's type change to keep from
221 * affecting the configured use of the property.
222 *
223 * @param[in] intf = Interface name containing the property
224 * @param[in] prop = Property name
225 * @param[in] variant = Variant containing the property's value from
226 * the supported property types.
227 */
228 template <typename T>
229 inline auto getPropertyValueVisitor(const char* intf, const char* prop,
230 PropertyVariantType& variant)
231 {
232 // Handle the transition of the dbus sensor value type from
233 // int64 to double which also removed the scale property.
234 // https://gerrit.openbmc-project.xyz/11739
235 if (strcmp(intf, "xyz.openbmc_project.Sensor.Value") == 0 &&
236 strcmp(prop, "Value") == 0)
Matthew Barth7f4c5482020-02-07 16:14:46 -0600237 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500238 // Use 'optional' variable to determine if the sensor value
239 // is set within the visitor based on the supported types.
240 // A non-supported type configured will assert.
241 std::optional<T> value;
242 std::visit(
243 [&value](auto&& val) {
Patrick Williams61b73292023-05-10 07:50:12 -0500244 // If the type configured is int64, but the sensor value
245 // property's type is double, scale it by 1000 and return
246 // the value as an int64 as configured.
247 using V = std::decay_t<decltype(val)>;
248 if constexpr (std::is_same_v<T, int64_t> &&
249 std::is_same_v<V, double>)
250 {
251 val = val * 1000;
252 value = std::lround(val);
253 }
254 // If the type configured matches the sensor value
255 // property's type, just return the value as its
256 // given type.
257 else if constexpr (std::is_same_v<T, V>)
258 {
259 value = val;
260 }
Patrick Williams5e15c3b2023-10-20 11:18:11 -0500261 },
Matthew Barth3e1bb272020-05-26 11:09:21 -0500262 variant);
Matthew Barth7f4c5482020-02-07 16:14:46 -0600263
Matthew Barth3e1bb272020-05-26 11:09:21 -0500264 // Unable to return Sensor Value property
265 // as given type configured.
266 assert(value);
Matthew Barth5a80f3a2020-03-13 11:28:18 -0500267
Matthew Barth3e1bb272020-05-26 11:09:21 -0500268 return value.value();
269 }
Matthew Barth7f4c5482020-02-07 16:14:46 -0600270
Matthew Barth3e1bb272020-05-26 11:09:21 -0500271 // Default to return the property's value by the data type
272 // configured, applying no visitors to the variant.
273 return std::get<T>(variant);
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400274 }
Matthew Barth7f4c5482020-02-07 16:14:46 -0600275
Matthew Barth3e1bb272020-05-26 11:09:21 -0500276 /**
277 * @brief Remove an object's interface
278 *
279 * @param[in] object - Name of the object with the interface
280 * @param[in] interface - Interface name to remove
281 */
282 inline void removeObjectInterface(const char* object, const char* interface)
283 {
284 auto it = _properties.find(object);
285 if (it != std::end(_properties))
Matthew Barth1499a5c2018-03-20 15:52:33 -0500286 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500287 _properties[object].erase(interface);
288 }
289 }
290
291 /**
292 * @brief Remove a service associated to a group
293 *
294 * @param[in] group - Group associated with service
295 * @param[in] name - Service name to remove
296 */
297 void removeService(const Group* group, const std::string& name);
298
299 /**
300 * @brief Set or update a service name owner in use
301 *
302 * @param[in] group - Group associated with service
303 * @param[in] name - Service name
304 * @param[in] hasOwner - Whether the service is owned or not
305 */
306 void setServiceOwner(const Group* group, const std::string& name,
307 const bool hasOwner);
308
309 /**
310 * @brief Set or update all services for a group
311 *
312 * @param[in] group - Group to get service names for
313 */
314 void setServices(const Group* group);
315
316 /**
317 * @brief Get the group's list of service names
318 *
319 * @param[in] group - Group to get service names for
320 *
321 * @return - The list of service names
322 */
323 inline auto getGroupServices(const Group* group)
324 {
325 return _services.at(*group);
326 }
327
328 /**
329 * @brief Initialize a set speed event properties and actions
330 *
331 * @param[in] event - Set speed event
332 */
333 void initEvent(const SetSpeedEvent& event);
334
335 /**
336 * @brief Removes all the set speed event properties and actions
337 *
338 * @param[in] event - Set speed event
339 */
340 void removeEvent(const SetSpeedEvent& event);
341
342 /**
343 * @brief Get the default floor speed
344 *
345 * @return - The defined default floor speed
346 */
347 inline auto getDefFloor()
348 {
349 return _defFloorSpeed;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400350 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500351
352 /**
353 * @brief Set the default floor
354 *
355 * @param[in] speed - Speed to set the default floor to
356 */
357 inline void setDefFloor(uint64_t speed)
358 {
359 _defFloorSpeed = speed;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400360 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500361
362 /**
363 * @brief Get the ceiling speed
364 *
365 * @return - The current ceiling speed
366 */
367 inline auto& getCeiling() const
368 {
369 return _ceilingSpeed;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400370 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500371
372 /**
373 * @brief Set the ceiling speed to the given speed
374 *
375 * @param[in] speed - Speed to set the ceiling to
376 */
377 inline void setCeiling(uint64_t speed)
378 {
379 _ceilingSpeed = speed;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400380 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500381
382 /**
383 * @brief Swaps the ceiling key value with what's given and
384 * returns the value that was swapped.
385 *
386 * @param[in] keyValue - New ceiling key value
387 *
388 * @return - Ceiling key value prior to swapping
389 */
390 inline auto swapCeilingKeyValue(int64_t keyValue)
391 {
392 std::swap(_ceilingKeyValue, keyValue);
393 return keyValue;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400394 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500395
396 /**
397 * @brief Get the increase speed delta
398 *
399 * @return - The current increase speed delta
400 */
401 inline auto& getIncSpeedDelta() const
402 {
403 return _incSpeedDelta;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400404 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500405
406 /**
407 * @brief Get the decrease speed delta
408 *
409 * @return - The current decrease speed delta
410 */
411 inline auto& getDecSpeedDelta() const
412 {
413 return _decSpeedDelta;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400414 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500415
416 /**
417 * @brief Set the floor speed to the given speed and increase target
418 * speed to the floor when target is below floor where floor changes
419 * are allowed.
420 *
421 * @param[in] speed - Speed to set the floor to
422 */
423 void setFloor(uint64_t speed);
424
425 /**
426 * @brief Set the requested speed base to be used as the speed to
427 * base a new requested speed target from
428 *
429 * @param[in] speedBase - Base speed value to use
430 */
431 inline void setRequestSpeedBase(uint64_t speedBase)
432 {
433 _requestSpeedBase = speedBase;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400434 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500435
436 /**
437 * @brief Calculate the requested target speed from the given delta
438 * and increase the fan speeds, not going above the ceiling.
439 *
440 * @param[in] targetDelta - The delta to increase the target speed by
441 */
442 void requestSpeedIncrease(uint64_t targetDelta);
443
444 /**
445 * @brief Calculate the requested target speed from the given delta
446 * and increase the fan speeds, not going above the ceiling.
447 *
448 * @param[in] targetDelta - The delta to increase the target speed by
449 */
450 void requestSpeedDecrease(uint64_t targetDelta);
451
452 /**
453 * @brief Callback function for the increase timer that delays
454 * processing of requested speed increases while fans are increasing
455 */
456 void incTimerExpired();
457
458 /**
459 * @brief Callback function for the decrease timer that processes any
460 * requested speed decreases if allowed
461 */
462 void decTimerExpired();
463
464 /**
465 * @brief Get the event loop used with this zone's timers
466 *
467 * @return - The event loop for timers
468 */
469 inline auto& getEventLoop()
470 {
471 return _eventLoop;
472 }
473
474 /**
475 * @brief Remove the given signal event
476 *
477 * @param[in] seIter - Iterator pointing to the signal event to remove
478 */
479 inline void removeSignal(std::vector<SignalEvent>::iterator& seIter)
480 {
481 std::get<signalEventDataPos>(*seIter).reset();
482 if (std::get<signalMatchPos>(*seIter) != nullptr)
483 {
484 std::get<signalMatchPos>(*seIter).reset();
485 }
486 }
487
488 /**
489 * @brief Get the list of timer events
490 *
491 * @return - List of timer events
492 */
493 inline auto& getTimerEvents()
494 {
495 return _timerEvents;
496 }
497
498 /**
499 * @brief Find the first instance of a timer event
500 *
501 * @param[in] eventGroup - Group associated with a timer
502 * @param[in] eventActions - List of actions associated with a timer
503 * @param[in] eventTimers - List of timers to find the timer in
504 *
505 * @return - Iterator to the timer event
506 */
507 std::vector<TimerEvent>::iterator
508 findTimer(const Group& eventGroup,
509 const std::vector<Action>& eventActions,
510 std::vector<TimerEvent>& eventTimers);
511
512 /**
513 * @brief Add a timer to the list of timer based events
514 *
515 * @param[in] name - Event name associated with timer
516 * @param[in] group - Group associated with a timer
517 * @param[in] actions - List of actions associated with a timer
518 * @param[in] tConf - Configuration for the new timer
519 */
520 void addTimer(const std::string& name, const Group& group,
521 const std::vector<Action>& actions, const TimerConf& tConf);
522
523 /**
524 * @brief Callback function for event timers that processes the given
525 * actions for a group
526 *
527 * @param[in] eventGroup - Group to process actions on
528 * @param[in] eventActions - List of event actions to run
529 */
530 void timerExpired(const Group& eventGroup,
531 const std::vector<Action>& eventActions);
532
533 /**
534 * @brief Get the service for a given path and interface from cached
535 * dataset and add a service that's not found
536 *
537 * @param[in] path - Path to get service for
538 * @param[in] intf - Interface to get service for
539 *
540 * @return - The service name
541 */
542 const std::string& getService(const std::string& path,
543 const std::string& intf);
544
545 /**
546 * @brief Add a set of services for a path and interface
547 * by retrieving all the path subtrees to the given depth
548 * from root for the interface
549 *
550 * @param[in] path - Path to add services for
551 * @param[in] intf - Interface to add services for
552 * @param[in] depth - Depth of tree traversal from root path
553 *
554 * @return - The associated service to the given path and interface
555 * or empty string for no service found
556 */
557 const std::string& addServices(const std::string& path,
558 const std::string& intf, int32_t depth);
559
560 /**
561 * @brief Dbus signal change callback handler
562 *
563 * @param[in] msg - Expanded sdbusplus message data
564 * @param[in] eventData - The single event's data
565 */
Patrick Williamscb356d42022-07-22 19:26:53 -0500566 void handleEvent(sdbusplus::message_t& msg, const EventData* eventData);
Matthew Barth3e1bb272020-05-26 11:09:21 -0500567
568 /**
569 * @brief Add a signal to the list of signal based events
570 *
571 * @param[in] name - Event name
572 * @param[in] data - Event data for signal
573 * @param[in] match - Subscribed signal match
574 */
Patrick Williams3ea9ec22021-11-19 12:21:08 -0600575 inline void addSignal(const std::string& name,
576 std::unique_ptr<EventData>&& data,
577 std::unique_ptr<sdbusplus::bus::match_t>&& match)
Matthew Barth3e1bb272020-05-26 11:09:21 -0500578 {
579 _signalEvents[name].emplace_back(std::move(data), std::move(match));
580 }
581
582 /**
583 * @brief Set a property to be persisted
584 *
585 * @param[in] intf - Interface containing property
586 * @param[in] prop - Property to be persisted
587 */
588 inline void setPersisted(const std::string& intf, const std::string& prop)
589 {
590 _persisted[intf].emplace_back(prop);
591 }
592
593 /**
594 * @brief Get persisted property
595 *
596 * @param[in] intf - Interface containing property
597 * @param[in] prop - Property persisted
598 *
599 * @return - True if property is to be persisted, false otherwise
600 */
601 auto getPersisted(const std::string& intf, const std::string& prop);
602
603 /**
604 * @brief Get a property value from the zone object or the bus when
605 * the property requested is not on the zone object
606 *
607 * @param[in] path - Path of object
608 * @param[in] intf - Object interface
609 * @param[in] prop - Object property
610 *
611 * @return - Property's value
612 */
613 template <typename T>
614 auto getPropertyByName(const std::string& path, const std::string& intf,
615 const std::string& prop)
616 {
617 T value;
618 auto pathIter = _objects.find(path);
619 if (pathIter != _objects.end())
620 {
621 auto intfIter = pathIter->second.find(intf);
622 if (intfIter != pathIter->second.end())
Matthew Barth1499a5c2018-03-20 15:52:33 -0500623 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500624 if (intf == "xyz.openbmc_project.Control.ThermalMode")
Matthew Barth766f8542019-01-29 12:44:13 -0600625 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500626 auto var = ThermalMode::getPropertyByName(prop);
627 // Use visitor to determine if requested property
628 // type(T) is available on this interface and read it
629 std::visit(
630 [&value](auto&& val) {
Patrick Williams61b73292023-05-10 07:50:12 -0500631 using V = std::decay_t<decltype(val)>;
632 if constexpr (std::is_same_v<T, V>)
633 {
634 value = val;
635 }
Patrick Williams5e15c3b2023-10-20 11:18:11 -0500636 },
Matthew Barth3e1bb272020-05-26 11:09:21 -0500637 var);
Matthew Barth766f8542019-01-29 12:44:13 -0600638
Matthew Barth3e1bb272020-05-26 11:09:21 -0500639 return value;
Matthew Barth766f8542019-01-29 12:44:13 -0600640 }
641 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500642 }
Matthew Barth766f8542019-01-29 12:44:13 -0600643
Matthew Barth3e1bb272020-05-26 11:09:21 -0500644 // Retrieve the property's value applying any visitors necessary
645 auto service = getService(path, intf);
646 auto variant = util::SDBusPlus::getPropertyVariant<PropertyVariantType>(
647 _bus, service, path, intf, prop);
648 value = getPropertyValueVisitor<T>(intf.c_str(), prop.c_str(), variant);
Matthew Barth766f8542019-01-29 12:44:13 -0600649
Matthew Barth3e1bb272020-05-26 11:09:21 -0500650 return value;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400651 }
Matthew Barth766f8542019-01-29 12:44:13 -0600652
Matthew Barth3e1bb272020-05-26 11:09:21 -0500653 /**
654 * @brief Overridden thermal object's set 'Current' property function
655 *
656 * @param[in] value - Value to set 'Current' to
657 *
658 * @return - The updated value of the 'Current' property
659 */
660 virtual std::string current(std::string value);
Matthew Barth6faf8942019-01-22 09:26:09 -0600661
Matthew Barth3e1bb272020-05-26 11:09:21 -0500662 private:
663 /**
664 * The dbus object
665 */
Patrick Williamscb356d42022-07-22 19:26:53 -0500666 sdbusplus::bus_t& _bus;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500667
Matthew Barth3e1bb272020-05-26 11:09:21 -0500668 /**
669 * Zone object path
670 */
671 const std::string _path;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500672
Matthew Barth3e1bb272020-05-26 11:09:21 -0500673 /**
674 * Zone supported interfaces
675 */
676 const std::vector<std::string> _ifaces;
Matthew Barth93af4192019-01-18 09:30:57 -0600677
Matthew Barth3e1bb272020-05-26 11:09:21 -0500678 /**
679 * Full speed for the zone
680 */
681 const uint64_t _fullSpeed;
Matthew Barth766f8542019-01-29 12:44:13 -0600682
Matthew Barth3e1bb272020-05-26 11:09:21 -0500683 /**
684 * The zone number
685 */
686 const size_t _zoneNum;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500687
Matthew Barth3e1bb272020-05-26 11:09:21 -0500688 /**
689 * The default floor speed for the zone
690 */
691 uint64_t _defFloorSpeed;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500692
Matthew Barth3e1bb272020-05-26 11:09:21 -0500693 /**
694 * The default ceiling speed for the zone
695 */
696 const uint64_t _defCeilingSpeed;
Matthew Barth1de66622017-06-12 13:13:02 -0500697
Matthew Barth3e1bb272020-05-26 11:09:21 -0500698 /**
699 * The floor speed to not go below
700 */
701 uint64_t _floorSpeed = _defFloorSpeed;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500702
Matthew Barth3e1bb272020-05-26 11:09:21 -0500703 /**
704 * The ceiling speed to not go above
705 */
706 uint64_t _ceilingSpeed = _defCeilingSpeed;
Matthew Barth4af419c2017-06-12 13:39:31 -0500707
Matthew Barth3e1bb272020-05-26 11:09:21 -0500708 /**
709 * The previous sensor value for calculating the ceiling
710 */
711 int64_t _ceilingKeyValue = 0;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500712
Matthew Barth3e1bb272020-05-26 11:09:21 -0500713 /**
714 * Automatic fan control active state
715 */
716 bool _isActive = true;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500717
Matthew Barth3e1bb272020-05-26 11:09:21 -0500718 /**
719 * Target speed for this zone
720 */
721 uint64_t _targetSpeed = _fullSpeed;
Matthew Barth861d77c2017-05-22 14:18:25 -0500722
Matthew Barth3e1bb272020-05-26 11:09:21 -0500723 /**
724 * Speed increase delta
725 */
726 uint64_t _incSpeedDelta = 0;
Matthew Barth240397b2017-06-22 11:23:30 -0500727
Matthew Barth3e1bb272020-05-26 11:09:21 -0500728 /**
729 * Speed decrease delta
730 */
731 uint64_t _decSpeedDelta = 0;
Matthew Barth24623522017-06-21 14:09:57 -0500732
Matthew Barth3e1bb272020-05-26 11:09:21 -0500733 /**
734 * Requested speed base
735 */
736 uint64_t _requestSpeedBase = 0;
Matthew Barth0ce99d82017-06-22 15:07:29 -0500737
Matthew Barth3e1bb272020-05-26 11:09:21 -0500738 /**
739 * Speed increase delay in seconds
740 */
741 std::chrono::seconds _incDelay;
Matthew Barth1bfdc422017-09-14 16:23:28 -0500742
Matthew Barth3e1bb272020-05-26 11:09:21 -0500743 /**
744 * Speed decrease interval in seconds
745 */
746 std::chrono::seconds _decInterval;
Matthew Bartha9561842017-06-29 11:43:45 -0500747
Matthew Barth3e1bb272020-05-26 11:09:21 -0500748 /**
749 * The increase timer object
750 */
751 Timer _incTimer;
Matthew Bartha9561842017-06-29 11:43:45 -0500752
Matthew Barth3e1bb272020-05-26 11:09:21 -0500753 /**
754 * The decrease timer object
755 */
756 Timer _decTimer;
Matthew Barth1ee48f22017-06-27 15:14:48 -0500757
Matthew Barth3e1bb272020-05-26 11:09:21 -0500758 /**
759 * Event loop used on set speed event timers
760 */
761 sdeventplus::Event _eventLoop;
Matthew Barth8600d9a2017-06-23 14:38:05 -0500762
Matthew Barth3e1bb272020-05-26 11:09:21 -0500763 /**
764 * The vector of fans in this zone
765 */
766 std::vector<std::unique_ptr<Fan>> _fans;
Matthew Barth90149802017-08-15 10:51:37 -0500767
Matthew Barth3e1bb272020-05-26 11:09:21 -0500768 /**
769 * @brief Map of object property values
770 */
771 std::map<std::string,
772 std::map<std::string, std::map<std::string, PropertyVariantType>>>
773 _properties;
Matthew Barth38a93a82017-05-11 14:12:27 -0500774
Matthew Barth3e1bb272020-05-26 11:09:21 -0500775 /**
776 * @brief Map of zone objects
777 */
778 std::map<std::string,
779 std::map<std::string, std::map<std::string, EventData*>>>
780 _objects;
Matthew Barth38a93a82017-05-11 14:12:27 -0500781
Matthew Barth3e1bb272020-05-26 11:09:21 -0500782 /**
783 * @brief Map of interfaces to persisted properties
784 */
785 std::map<std::string, std::vector<std::string>> _persisted;
Matthew Barth766f8542019-01-29 12:44:13 -0600786
Matthew Barth3e1bb272020-05-26 11:09:21 -0500787 /**
788 * @brief Map of active fan control allowed by groups
789 */
790 std::map<const Group, bool> _active;
Matthew Barth70b2e7d2019-02-18 11:03:07 -0600791
Matthew Barth3e1bb272020-05-26 11:09:21 -0500792 /**
793 * @brief Map of floor change allowed by groups
794 */
795 std::map<const Group, bool> _floorChange;
Matthew Barth861d77c2017-05-22 14:18:25 -0500796
Matthew Barth3e1bb272020-05-26 11:09:21 -0500797 /**
798 * @brief Map of groups controlling decreases allowed
799 */
800 std::map<const Group, bool> _decAllowed;
Matthew Barth98726c42017-10-17 10:35:20 -0500801
Matthew Barth3e1bb272020-05-26 11:09:21 -0500802 /**
803 * @brief Map of group service names
804 */
805 std::map<const Group, std::vector<Service>> _services;
Matthew Barthe4338cd2017-12-14 11:14:30 -0600806
Matthew Barth3e1bb272020-05-26 11:09:21 -0500807 /**
808 * @brief Map tree of paths to services of interfaces
809 */
810 std::map<std::string, std::map<std::string, std::vector<std::string>>>
811 _servTree;
Matthew Barthe59fdf72017-09-27 09:33:42 -0500812
Matthew Barth3e1bb272020-05-26 11:09:21 -0500813 /**
814 * @brief List of signal event arguments and Dbus matches
815 * for callbacks per event name
816 */
817 std::map<std::string, std::vector<SignalEvent>> _signalEvents;
Matthew Bartha603ed02018-01-19 16:56:26 -0600818
Matthew Barth3e1bb272020-05-26 11:09:21 -0500819 /**
820 * @brief List of timers per event name
821 */
822 std::map<std::string, std::vector<TimerEvent>> _timerEvents;
Matthew Barth38a93a82017-05-11 14:12:27 -0500823
Matthew Barth3e1bb272020-05-26 11:09:21 -0500824 /**
825 * @brief Save the thermal control current mode property
826 * to persisted storage
827 */
828 void saveCurrentMode();
Matthew Barth90149802017-08-15 10:51:37 -0500829
Matthew Barth3e1bb272020-05-26 11:09:21 -0500830 /**
831 * @brief Restore persisted thermal control current mode property
832 * value, setting the mode to "Default" otherwise
833 */
834 void restoreCurrentMode();
Matthew Barthcc8912e2019-01-21 11:35:27 -0600835
Matthew Barth3e1bb272020-05-26 11:09:21 -0500836 /**
837 * @brief Get the request speed base if defined, otherwise the
838 * the current target speed is returned
839 *
840 * @return - The request speed base or current target speed
841 */
842 inline auto getRequestSpeedBase() const
843 {
844 return (_requestSpeedBase != 0) ? _requestSpeedBase : _targetSpeed;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400845 }
Matt Spinler7f88fe62017-04-10 14:39:02 -0500846};
847
Matthew Barth3e1bb272020-05-26 11:09:21 -0500848} // namespace control
849} // namespace fan
850} // namespace phosphor