blob: c82f0a8da5f4f0fcc07e3abdac17ff695a4d006b [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
Matthew Barth93af4192019-01-18 09:30:57 -060024using ThermalObject = sdbusplus::server::object::object<
25 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 */
63 Zone(Mode mode, sdbusplus::bus::bus& bus, const std::string& path,
64 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;
167 };
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;
183 };
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));
200 };
201
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);
216 };
217
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) {
Matthew Barth7f4c5482020-02-07 16:14:46 -0600244 // 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)>;
Matthew Barth3e1bb272020-05-26 11:09:21 -0500248 if constexpr (std::is_same_v<T, int64_t> &&
249 std::is_same_v<V, double>)
Matthew Barth7f4c5482020-02-07 16:14:46 -0600250 {
251 val = val * 1000;
Patrick Williamsed7b0342020-02-12 10:29:46 -0600252 value = std::lround(val);
Matthew Barth7f4c5482020-02-07 16:14:46 -0600253 }
254 // If the type configured matches the sensor value
255 // property's type, just return the value as its
256 // given type.
Matthew Barth3e1bb272020-05-26 11:09:21 -0500257 else if constexpr (std::is_same_v<T, V>)
Matthew Barth7f4c5482020-02-07 16:14:46 -0600258 {
259 value = val;
260 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500261 },
262 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);
274 };
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;
350 };
351
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;
360 };
361
362 /**
363 * @brief Get the ceiling speed
364 *
365 * @return - The current ceiling speed
366 */
367 inline auto& getCeiling() const
368 {
369 return _ceilingSpeed;
370 };
371
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;
380 };
381
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;
394 };
395
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;
404 };
405
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;
414 };
415
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;
434 };
435
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 */
566 void handleEvent(sdbusplus::message::message& msg,
567 const EventData* eventData);
568
569 /**
570 * @brief Add a signal to the list of signal based events
571 *
572 * @param[in] name - Event name
573 * @param[in] data - Event data for signal
574 * @param[in] match - Subscribed signal match
575 */
Patrick Williams3ea9ec22021-11-19 12:21:08 -0600576 inline void addSignal(const std::string& name,
577 std::unique_ptr<EventData>&& data,
578 std::unique_ptr<sdbusplus::bus::match_t>&& match)
Matthew Barth3e1bb272020-05-26 11:09:21 -0500579 {
580 _signalEvents[name].emplace_back(std::move(data), std::move(match));
581 }
582
583 /**
584 * @brief Set a property to be persisted
585 *
586 * @param[in] intf - Interface containing property
587 * @param[in] prop - Property to be persisted
588 */
589 inline void setPersisted(const std::string& intf, const std::string& prop)
590 {
591 _persisted[intf].emplace_back(prop);
592 }
593
594 /**
595 * @brief Get persisted property
596 *
597 * @param[in] intf - Interface containing property
598 * @param[in] prop - Property persisted
599 *
600 * @return - True if property is to be persisted, false otherwise
601 */
602 auto getPersisted(const std::string& intf, const std::string& prop);
603
604 /**
605 * @brief Get a property value from the zone object or the bus when
606 * the property requested is not on the zone object
607 *
608 * @param[in] path - Path of object
609 * @param[in] intf - Object interface
610 * @param[in] prop - Object property
611 *
612 * @return - Property's value
613 */
614 template <typename T>
615 auto getPropertyByName(const std::string& path, const std::string& intf,
616 const std::string& prop)
617 {
618 T value;
619 auto pathIter = _objects.find(path);
620 if (pathIter != _objects.end())
621 {
622 auto intfIter = pathIter->second.find(intf);
623 if (intfIter != pathIter->second.end())
Matthew Barth1499a5c2018-03-20 15:52:33 -0500624 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500625 if (intf == "xyz.openbmc_project.Control.ThermalMode")
Matthew Barth766f8542019-01-29 12:44:13 -0600626 {
Matthew Barth3e1bb272020-05-26 11:09:21 -0500627 auto var = ThermalMode::getPropertyByName(prop);
628 // Use visitor to determine if requested property
629 // type(T) is available on this interface and read it
630 std::visit(
631 [&value](auto&& val) {
Matthew Barth766f8542019-01-29 12:44:13 -0600632 using V = std::decay_t<decltype(val)>;
Matthew Barth3e1bb272020-05-26 11:09:21 -0500633 if constexpr (std::is_same_v<T, V>)
Matthew Barth766f8542019-01-29 12:44:13 -0600634 {
635 value = val;
636 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500637 },
638 var);
Matthew Barth766f8542019-01-29 12:44:13 -0600639
Matthew Barth3e1bb272020-05-26 11:09:21 -0500640 return value;
Matthew Barth766f8542019-01-29 12:44:13 -0600641 }
642 }
Matthew Barth3e1bb272020-05-26 11:09:21 -0500643 }
Matthew Barth766f8542019-01-29 12:44:13 -0600644
Matthew Barth3e1bb272020-05-26 11:09:21 -0500645 // Retrieve the property's value applying any visitors necessary
646 auto service = getService(path, intf);
647 auto variant = util::SDBusPlus::getPropertyVariant<PropertyVariantType>(
648 _bus, service, path, intf, prop);
649 value = getPropertyValueVisitor<T>(intf.c_str(), prop.c_str(), variant);
Matthew Barth766f8542019-01-29 12:44:13 -0600650
Matthew Barth3e1bb272020-05-26 11:09:21 -0500651 return value;
652 };
Matthew Barth766f8542019-01-29 12:44:13 -0600653
Matthew Barth3e1bb272020-05-26 11:09:21 -0500654 /**
655 * @brief Overridden thermal object's set 'Current' property function
656 *
657 * @param[in] value - Value to set 'Current' to
658 *
659 * @return - The updated value of the 'Current' property
660 */
661 virtual std::string current(std::string value);
Matthew Barth6faf8942019-01-22 09:26:09 -0600662
Matthew Barth3e1bb272020-05-26 11:09:21 -0500663 private:
664 /**
665 * The dbus object
666 */
667 sdbusplus::bus::bus& _bus;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500668
Matthew Barth3e1bb272020-05-26 11:09:21 -0500669 /**
670 * Zone object path
671 */
672 const std::string _path;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500673
Matthew Barth3e1bb272020-05-26 11:09:21 -0500674 /**
675 * Zone supported interfaces
676 */
677 const std::vector<std::string> _ifaces;
Matthew Barth93af4192019-01-18 09:30:57 -0600678
Matthew Barth3e1bb272020-05-26 11:09:21 -0500679 /**
680 * Full speed for the zone
681 */
682 const uint64_t _fullSpeed;
Matthew Barth766f8542019-01-29 12:44:13 -0600683
Matthew Barth3e1bb272020-05-26 11:09:21 -0500684 /**
685 * The zone number
686 */
687 const size_t _zoneNum;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500688
Matthew Barth3e1bb272020-05-26 11:09:21 -0500689 /**
690 * The default floor speed for the zone
691 */
692 uint64_t _defFloorSpeed;
Matt Spinler7f88fe62017-04-10 14:39:02 -0500693
Matthew Barth3e1bb272020-05-26 11:09:21 -0500694 /**
695 * The default ceiling speed for the zone
696 */
697 const uint64_t _defCeilingSpeed;
Matthew Barth1de66622017-06-12 13:13:02 -0500698
Matthew Barth3e1bb272020-05-26 11:09:21 -0500699 /**
700 * The floor speed to not go below
701 */
702 uint64_t _floorSpeed = _defFloorSpeed;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500703
Matthew Barth3e1bb272020-05-26 11:09:21 -0500704 /**
705 * The ceiling speed to not go above
706 */
707 uint64_t _ceilingSpeed = _defCeilingSpeed;
Matthew Barth4af419c2017-06-12 13:39:31 -0500708
Matthew Barth3e1bb272020-05-26 11:09:21 -0500709 /**
710 * The previous sensor value for calculating the ceiling
711 */
712 int64_t _ceilingKeyValue = 0;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500713
Matthew Barth3e1bb272020-05-26 11:09:21 -0500714 /**
715 * Automatic fan control active state
716 */
717 bool _isActive = true;
Matthew Barthe0ca13e2017-06-13 16:29:09 -0500718
Matthew Barth3e1bb272020-05-26 11:09:21 -0500719 /**
720 * Target speed for this zone
721 */
722 uint64_t _targetSpeed = _fullSpeed;
Matthew Barth861d77c2017-05-22 14:18:25 -0500723
Matthew Barth3e1bb272020-05-26 11:09:21 -0500724 /**
725 * Speed increase delta
726 */
727 uint64_t _incSpeedDelta = 0;
Matthew Barth240397b2017-06-22 11:23:30 -0500728
Matthew Barth3e1bb272020-05-26 11:09:21 -0500729 /**
730 * Speed decrease delta
731 */
732 uint64_t _decSpeedDelta = 0;
Matthew Barth24623522017-06-21 14:09:57 -0500733
Matthew Barth3e1bb272020-05-26 11:09:21 -0500734 /**
735 * Requested speed base
736 */
737 uint64_t _requestSpeedBase = 0;
Matthew Barth0ce99d82017-06-22 15:07:29 -0500738
Matthew Barth3e1bb272020-05-26 11:09:21 -0500739 /**
740 * Speed increase delay in seconds
741 */
742 std::chrono::seconds _incDelay;
Matthew Barth1bfdc422017-09-14 16:23:28 -0500743
Matthew Barth3e1bb272020-05-26 11:09:21 -0500744 /**
745 * Speed decrease interval in seconds
746 */
747 std::chrono::seconds _decInterval;
Matthew Bartha9561842017-06-29 11:43:45 -0500748
Matthew Barth3e1bb272020-05-26 11:09:21 -0500749 /**
750 * The increase timer object
751 */
752 Timer _incTimer;
Matthew Bartha9561842017-06-29 11:43:45 -0500753
Matthew Barth3e1bb272020-05-26 11:09:21 -0500754 /**
755 * The decrease timer object
756 */
757 Timer _decTimer;
Matthew Barth1ee48f22017-06-27 15:14:48 -0500758
Matthew Barth3e1bb272020-05-26 11:09:21 -0500759 /**
760 * Event loop used on set speed event timers
761 */
762 sdeventplus::Event _eventLoop;
Matthew Barth8600d9a2017-06-23 14:38:05 -0500763
Matthew Barth3e1bb272020-05-26 11:09:21 -0500764 /**
765 * The vector of fans in this zone
766 */
767 std::vector<std::unique_ptr<Fan>> _fans;
Matthew Barth90149802017-08-15 10:51:37 -0500768
Matthew Barth3e1bb272020-05-26 11:09:21 -0500769 /**
770 * @brief Map of object property values
771 */
772 std::map<std::string,
773 std::map<std::string, std::map<std::string, PropertyVariantType>>>
774 _properties;
Matthew Barth38a93a82017-05-11 14:12:27 -0500775
Matthew Barth3e1bb272020-05-26 11:09:21 -0500776 /**
777 * @brief Map of zone objects
778 */
779 std::map<std::string,
780 std::map<std::string, std::map<std::string, EventData*>>>
781 _objects;
Matthew Barth38a93a82017-05-11 14:12:27 -0500782
Matthew Barth3e1bb272020-05-26 11:09:21 -0500783 /**
784 * @brief Map of interfaces to persisted properties
785 */
786 std::map<std::string, std::vector<std::string>> _persisted;
Matthew Barth766f8542019-01-29 12:44:13 -0600787
Matthew Barth3e1bb272020-05-26 11:09:21 -0500788 /**
789 * @brief Map of active fan control allowed by groups
790 */
791 std::map<const Group, bool> _active;
Matthew Barth70b2e7d2019-02-18 11:03:07 -0600792
Matthew Barth3e1bb272020-05-26 11:09:21 -0500793 /**
794 * @brief Map of floor change allowed by groups
795 */
796 std::map<const Group, bool> _floorChange;
Matthew Barth861d77c2017-05-22 14:18:25 -0500797
Matthew Barth3e1bb272020-05-26 11:09:21 -0500798 /**
799 * @brief Map of groups controlling decreases allowed
800 */
801 std::map<const Group, bool> _decAllowed;
Matthew Barth98726c42017-10-17 10:35:20 -0500802
Matthew Barth3e1bb272020-05-26 11:09:21 -0500803 /**
804 * @brief Map of group service names
805 */
806 std::map<const Group, std::vector<Service>> _services;
Matthew Barthe4338cd2017-12-14 11:14:30 -0600807
Matthew Barth3e1bb272020-05-26 11:09:21 -0500808 /**
809 * @brief Map tree of paths to services of interfaces
810 */
811 std::map<std::string, std::map<std::string, std::vector<std::string>>>
812 _servTree;
Matthew Barthe59fdf72017-09-27 09:33:42 -0500813
Matthew Barth3e1bb272020-05-26 11:09:21 -0500814 /**
815 * @brief List of signal event arguments and Dbus matches
816 * for callbacks per event name
817 */
818 std::map<std::string, std::vector<SignalEvent>> _signalEvents;
Matthew Bartha603ed02018-01-19 16:56:26 -0600819
Matthew Barth3e1bb272020-05-26 11:09:21 -0500820 /**
821 * @brief List of timers per event name
822 */
823 std::map<std::string, std::vector<TimerEvent>> _timerEvents;
Matthew Barth38a93a82017-05-11 14:12:27 -0500824
Matthew Barth3e1bb272020-05-26 11:09:21 -0500825 /**
826 * @brief Save the thermal control current mode property
827 * to persisted storage
828 */
829 void saveCurrentMode();
Matthew Barth90149802017-08-15 10:51:37 -0500830
Matthew Barth3e1bb272020-05-26 11:09:21 -0500831 /**
832 * @brief Restore persisted thermal control current mode property
833 * value, setting the mode to "Default" otherwise
834 */
835 void restoreCurrentMode();
Matthew Barthcc8912e2019-01-21 11:35:27 -0600836
Matthew Barth3e1bb272020-05-26 11:09:21 -0500837 /**
838 * @brief Get the request speed base if defined, otherwise the
839 * the current target speed is returned
840 *
841 * @return - The request speed base or current target speed
842 */
843 inline auto getRequestSpeedBase() const
844 {
845 return (_requestSpeedBase != 0) ? _requestSpeedBase : _targetSpeed;
846 };
Matt Spinler7f88fe62017-04-10 14:39:02 -0500847};
848
Matthew Barth3e1bb272020-05-26 11:09:21 -0500849} // namespace control
850} // namespace fan
851} // namespace phosphor