blob: dfa6efb97783fedab8696f82f1a7de69b3a5c32d [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 Williamsdfddd642024-08-16 15:21:51 -0400244 // 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 }
261 },
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 */
Patrick Williamsdfddd642024-08-16 15:21:51 -0400507 std::vector<TimerEvent>::iterator findTimer(
508 const Group& eventGroup, const std::vector<Action>& eventActions,
509 std::vector<TimerEvent>& eventTimers);
Matthew Barth3e1bb272020-05-26 11:09:21 -0500510
511 /**
512 * @brief Add a timer to the list of timer based events
513 *
514 * @param[in] name - Event name associated with timer
515 * @param[in] group - Group associated with a timer
516 * @param[in] actions - List of actions associated with a timer
517 * @param[in] tConf - Configuration for the new timer
518 */
519 void addTimer(const std::string& name, const Group& group,
520 const std::vector<Action>& actions, const TimerConf& tConf);
521
522 /**
523 * @brief Callback function for event timers that processes the given
524 * actions for a group
525 *
526 * @param[in] eventGroup - Group to process actions on
527 * @param[in] eventActions - List of event actions to run
528 */
529 void timerExpired(const Group& eventGroup,
530 const std::vector<Action>& eventActions);
531
532 /**
533 * @brief Get the service for a given path and interface from cached
534 * dataset and add a service that's not found
535 *
536 * @param[in] path - Path to get service for
537 * @param[in] intf - Interface to get service for
538 *
539 * @return - The service name
540 */
541 const std::string& getService(const std::string& path,
542 const std::string& intf);
543
544 /**
545 * @brief Add a set of services for a path and interface
546 * by retrieving all the path subtrees to the given depth
547 * from root for the interface
548 *
549 * @param[in] path - Path to add services for
550 * @param[in] intf - Interface to add services for
551 * @param[in] depth - Depth of tree traversal from root path
552 *
553 * @return - The associated service to the given path and interface
554 * or empty string for no service found
555 */
556 const std::string& addServices(const std::string& path,
557 const std::string& intf, int32_t depth);
558
559 /**
560 * @brief Dbus signal change callback handler
561 *
562 * @param[in] msg - Expanded sdbusplus message data
563 * @param[in] eventData - The single event's data
564 */
Patrick Williamscb356d42022-07-22 19:26:53 -0500565 void handleEvent(sdbusplus::message_t& msg, const EventData* eventData);
Matthew Barth3e1bb272020-05-26 11:09:21 -0500566
567 /**
568 * @brief Add a signal to the list of signal based events
569 *
570 * @param[in] name - Event name
571 * @param[in] data - Event data for signal
572 * @param[in] match - Subscribed signal match
573 */
Patrick Williams3ea9ec22021-11-19 12:21:08 -0600574 inline void addSignal(const std::string& name,
575 std::unique_ptr<EventData>&& data,
576 std::unique_ptr<sdbusplus::bus::match_t>&& match)
Matthew Barth3e1bb272020-05-26 11:09:21 -0500577 {
578 _signalEvents[name].emplace_back(std::move(data), std::move(match));
579 }
580
581 /**
582 * @brief Set a property to be persisted
583 *
584 * @param[in] intf - Interface containing property
585 * @param[in] prop - Property to be persisted
586 */
587 inline void setPersisted(const std::string& intf, const std::string& prop)
588 {
589 _persisted[intf].emplace_back(prop);
590 }
591
592 /**
593 * @brief Get persisted property
594 *
595 * @param[in] intf - Interface containing property
596 * @param[in] prop - Property persisted
597 *
598 * @return - True if property is to be persisted, false otherwise
599 */
600 auto getPersisted(const std::string& intf, const std::string& prop);
601
602 /**
603 * @brief Get a property value from the zone object or the bus when
604 * the property requested is not on the zone object
605 *
606 * @param[in] path - Path of object
607 * @param[in] intf - Object interface
608 * @param[in] prop - Object property
609 *
610 * @return - Property's value
611 */
612 template <typename T>
613 auto getPropertyByName(const std::string& path, const std::string& intf,
614 const std::string& prop)
615 {
616 T value;
617 auto pathIter = _objects.find(path);
618 if (pathIter != _objects.end())
619 {
620 auto intfIter = pathIter->second.find(intf);
621 if (intfIter != pathIter->second.end())
Matthew Barth1499a5c2018-03-20 15:52:33 -0500622 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500623 if (intf == "xyz.openbmc_project.Control.ThermalMode")
Matthew Barth766f8542019-01-29 12:44:13 -0600624 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500625 auto var = ThermalMode::getPropertyByName(prop);
626 // Use visitor to determine if requested property
627 // type(T) is available on this interface and read it
628 std::visit(
629 [&value](auto&& val) {
Patrick Williamsdfddd642024-08-16 15:21:51 -0400630 using V = std::decay_t<decltype(val)>;
631 if constexpr (std::is_same_v<T, V>)
632 {
633 value = val;
634 }
635 },
Matthew Barth3e1bb272020-05-26 11:09:21 -0500636 var);
Matthew Barth766f8542019-01-29 12:44:13 -0600637
Matthew Barth3e1bb272020-05-26 11:09:21 -0500638 return value;
Matthew Barth766f8542019-01-29 12:44:13 -0600639 }
640 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500641 }
Matthew Barth766f8542019-01-29 12:44:13 -0600642
Matthew Barth3e1bb272020-05-26 11:09:21 -0500643 // Retrieve the property's value applying any visitors necessary
644 auto service = getService(path, intf);
645 auto variant = util::SDBusPlus::getPropertyVariant<PropertyVariantType>(
646 _bus, service, path, intf, prop);
647 value = getPropertyValueVisitor<T>(intf.c_str(), prop.c_str(), variant);
Matthew Barth766f8542019-01-29 12:44:13 -0600648
Matthew Barth3e1bb272020-05-26 11:09:21 -0500649 return value;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400650 }
Matthew Barth766f8542019-01-29 12:44:13 -0600651
Matthew Barth3e1bb272020-05-26 11:09:21 -0500652 /**
653 * @brief Overridden thermal object's set 'Current' property function
654 *
655 * @param[in] value - Value to set 'Current' to
656 *
657 * @return - The updated value of the 'Current' property
658 */
659 virtual std::string current(std::string value);
Matthew Barth6faf8942019-01-22 09:26:09 -0600660
Matthew Barth3e1bb272020-05-26 11:09:21 -0500661 private:
662 /**
663 * The dbus object
664 */
Patrick Williamscb356d42022-07-22 19:26:53 -0500665 sdbusplus::bus_t& _bus;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500666
Matthew Barth3e1bb272020-05-26 11:09:21 -0500667 /**
668 * Zone object path
669 */
670 const std::string _path;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500671
Matthew Barth3e1bb272020-05-26 11:09:21 -0500672 /**
673 * Zone supported interfaces
674 */
675 const std::vector<std::string> _ifaces;
Matthew Barth93af4192019-01-18 09:30:57 -0600676
Matthew Barth3e1bb272020-05-26 11:09:21 -0500677 /**
678 * Full speed for the zone
679 */
680 const uint64_t _fullSpeed;
Matthew Barth766f8542019-01-29 12:44:13 -0600681
Matthew Barth3e1bb272020-05-26 11:09:21 -0500682 /**
683 * The zone number
684 */
685 const size_t _zoneNum;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500686
Matthew Barth3e1bb272020-05-26 11:09:21 -0500687 /**
688 * The default floor speed for the zone
689 */
690 uint64_t _defFloorSpeed;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500691
Matthew Barth3e1bb272020-05-26 11:09:21 -0500692 /**
693 * The default ceiling speed for the zone
694 */
695 const uint64_t _defCeilingSpeed;
Matthew Barth1de66622017-06-12 13:13:02 -0500696
Matthew Barth3e1bb272020-05-26 11:09:21 -0500697 /**
698 * The floor speed to not go below
699 */
700 uint64_t _floorSpeed = _defFloorSpeed;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500701
Matthew Barth3e1bb272020-05-26 11:09:21 -0500702 /**
703 * The ceiling speed to not go above
704 */
705 uint64_t _ceilingSpeed = _defCeilingSpeed;
Matthew Barth4af419c2017-06-12 13:39:31 -0500706
Matthew Barth3e1bb272020-05-26 11:09:21 -0500707 /**
708 * The previous sensor value for calculating the ceiling
709 */
710 int64_t _ceilingKeyValue = 0;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500711
Matthew Barth3e1bb272020-05-26 11:09:21 -0500712 /**
713 * Automatic fan control active state
714 */
715 bool _isActive = true;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500716
Matthew Barth3e1bb272020-05-26 11:09:21 -0500717 /**
718 * Target speed for this zone
719 */
720 uint64_t _targetSpeed = _fullSpeed;
Matthew Barth861d77c2017-05-22 14:18:25 -0500721
Matthew Barth3e1bb272020-05-26 11:09:21 -0500722 /**
723 * Speed increase delta
724 */
725 uint64_t _incSpeedDelta = 0;
Matthew Barth240397b2017-06-22 11:23:30 -0500726
Matthew Barth3e1bb272020-05-26 11:09:21 -0500727 /**
728 * Speed decrease delta
729 */
730 uint64_t _decSpeedDelta = 0;
Matthew Barth24623522017-06-21 14:09:57 -0500731
Matthew Barth3e1bb272020-05-26 11:09:21 -0500732 /**
733 * Requested speed base
734 */
735 uint64_t _requestSpeedBase = 0;
Matthew Barth0ce99d82017-06-22 15:07:29 -0500736
Matthew Barth3e1bb272020-05-26 11:09:21 -0500737 /**
738 * Speed increase delay in seconds
739 */
740 std::chrono::seconds _incDelay;
Matthew Barth1bfdc422017-09-14 16:23:28 -0500741
Matthew Barth3e1bb272020-05-26 11:09:21 -0500742 /**
743 * Speed decrease interval in seconds
744 */
745 std::chrono::seconds _decInterval;
Matthew Bartha9561842017-06-29 11:43:45 -0500746
Matthew Barth3e1bb272020-05-26 11:09:21 -0500747 /**
748 * The increase timer object
749 */
750 Timer _incTimer;
Matthew Bartha9561842017-06-29 11:43:45 -0500751
Matthew Barth3e1bb272020-05-26 11:09:21 -0500752 /**
753 * The decrease timer object
754 */
755 Timer _decTimer;
Matthew Barth1ee48f22017-06-27 15:14:48 -0500756
Matthew Barth3e1bb272020-05-26 11:09:21 -0500757 /**
758 * Event loop used on set speed event timers
759 */
760 sdeventplus::Event _eventLoop;
Matthew Barth8600d9a2017-06-23 14:38:05 -0500761
Matthew Barth3e1bb272020-05-26 11:09:21 -0500762 /**
763 * The vector of fans in this zone
764 */
765 std::vector<std::unique_ptr<Fan>> _fans;
Matthew Barth90149802017-08-15 10:51:37 -0500766
Matthew Barth3e1bb272020-05-26 11:09:21 -0500767 /**
768 * @brief Map of object property values
769 */
770 std::map<std::string,
771 std::map<std::string, std::map<std::string, PropertyVariantType>>>
772 _properties;
Matthew Barth38a93a82017-05-11 14:12:27 -0500773
Matthew Barth3e1bb272020-05-26 11:09:21 -0500774 /**
775 * @brief Map of zone objects
776 */
777 std::map<std::string,
778 std::map<std::string, std::map<std::string, EventData*>>>
779 _objects;
Matthew Barth38a93a82017-05-11 14:12:27 -0500780
Matthew Barth3e1bb272020-05-26 11:09:21 -0500781 /**
782 * @brief Map of interfaces to persisted properties
783 */
784 std::map<std::string, std::vector<std::string>> _persisted;
Matthew Barth766f8542019-01-29 12:44:13 -0600785
Matthew Barth3e1bb272020-05-26 11:09:21 -0500786 /**
787 * @brief Map of active fan control allowed by groups
788 */
789 std::map<const Group, bool> _active;
Matthew Barth70b2e7d2019-02-18 11:03:07 -0600790
Matthew Barth3e1bb272020-05-26 11:09:21 -0500791 /**
792 * @brief Map of floor change allowed by groups
793 */
794 std::map<const Group, bool> _floorChange;
Matthew Barth861d77c2017-05-22 14:18:25 -0500795
Matthew Barth3e1bb272020-05-26 11:09:21 -0500796 /**
797 * @brief Map of groups controlling decreases allowed
798 */
799 std::map<const Group, bool> _decAllowed;
Matthew Barth98726c42017-10-17 10:35:20 -0500800
Matthew Barth3e1bb272020-05-26 11:09:21 -0500801 /**
802 * @brief Map of group service names
803 */
804 std::map<const Group, std::vector<Service>> _services;
Matthew Barthe4338cd2017-12-14 11:14:30 -0600805
Matthew Barth3e1bb272020-05-26 11:09:21 -0500806 /**
807 * @brief Map tree of paths to services of interfaces
808 */
809 std::map<std::string, std::map<std::string, std::vector<std::string>>>
810 _servTree;
Matthew Barthe59fdf72017-09-27 09:33:42 -0500811
Matthew Barth3e1bb272020-05-26 11:09:21 -0500812 /**
813 * @brief List of signal event arguments and Dbus matches
814 * for callbacks per event name
815 */
816 std::map<std::string, std::vector<SignalEvent>> _signalEvents;
Matthew Bartha603ed02018-01-19 16:56:26 -0600817
Matthew Barth3e1bb272020-05-26 11:09:21 -0500818 /**
819 * @brief List of timers per event name
820 */
821 std::map<std::string, std::vector<TimerEvent>> _timerEvents;
Matthew Barth38a93a82017-05-11 14:12:27 -0500822
Matthew Barth3e1bb272020-05-26 11:09:21 -0500823 /**
824 * @brief Save the thermal control current mode property
825 * to persisted storage
826 */
827 void saveCurrentMode();
Matthew Barth90149802017-08-15 10:51:37 -0500828
Matthew Barth3e1bb272020-05-26 11:09:21 -0500829 /**
830 * @brief Restore persisted thermal control current mode property
831 * value, setting the mode to "Default" otherwise
832 */
833 void restoreCurrentMode();
Matthew Barthcc8912e2019-01-21 11:35:27 -0600834
Matthew Barth3e1bb272020-05-26 11:09:21 -0500835 /**
836 * @brief Get the request speed base if defined, otherwise the
837 * the current target speed is returned
838 *
839 * @return - The request speed base or current target speed
840 */
841 inline auto getRequestSpeedBase() const
842 {
843 return (_requestSpeedBase != 0) ? _requestSpeedBase : _targetSpeed;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -0400844 }
Matt Spinler7f88fe62017-04-10 14:39:02 -0500845};
846
Matthew Barth3e1bb272020-05-26 11:09:21 -0500847} // namespace control
848} // namespace fan
849} // namespace phosphor