blob: 1423ac06e09e378987d1f607e5eb5f7edc385a25 [file] [log] [blame]
Matthew Barthccc77702017-07-28 13:43:04 -05001#pragma once
2
Matthew Barth604329e2017-08-04 11:18:28 -05003#include <algorithm>
Matthew Barth572d4062018-05-08 14:16:04 -05004#include <phosphor-logging/log.hpp>
Matthew Barth604329e2017-08-04 11:18:28 -05005
Matthew Barthccc77702017-07-28 13:43:04 -05006namespace phosphor
7{
8namespace fan
9{
10namespace control
11{
12namespace precondition
13{
14
Matthew Barth572d4062018-05-08 14:16:04 -050015using namespace phosphor::logging;
16
Matthew Barthccc77702017-07-28 13:43:04 -050017/**
18 * @brief A precondition to compare a group of property values and
19 * subscribe/unsubscribe a set speed event group
20 * @details Compares each entry within the precondition group to a given value
21 * that when each entry's property value matches the given value, the set speed
22 * event is then initialized. At any point a precondition entry's value no
23 * longer matches, the set speed event is removed from being active and fans
24 * are set to full speed.
25 *
26 * @param[in] pg - Precondition property group of property values
27 * @param[in] sse - Set speed event definition
28 *
29 * @return Lambda function
30 * A lambda function to compare precondition property value states
31 * and either subscribe or unsubscribe a set speed event group.
32 */
33auto property_states_match(std::vector<PrecondGroup>&& pg,
Matthew Barthf9201ab2017-09-11 16:07:58 -050034 std::vector<SetSpeedEvent>&& sse)
Matthew Barthccc77702017-07-28 13:43:04 -050035{
36 return [pg = std::move(pg),
37 sse = std::move(sse)](auto& zone, auto& group)
38 {
Matthew Barth604329e2017-08-04 11:18:28 -050039 // Compare given precondition entries
Matthew Barth572d4062018-05-08 14:16:04 -050040 auto precondState = std::all_of(
Matthew Barth604329e2017-08-04 11:18:28 -050041 pg.begin(),
42 pg.end(),
43 [&zone](auto const& entry)
44 {
45 try
46 {
47 return zone.getPropValueVariant(
48 std::get<pcPathPos>(entry),
49 std::get<pcIntfPos>(entry),
50 std::get<pcPropPos>(entry)) ==
51 std::get<pcValuePos>(entry);
52 }
53 catch (const std::out_of_range& oore)
54 {
55 // Default to property variants not equal when not found
56 return false;
57 }
58 });
59
Matthew Barth572d4062018-05-08 14:16:04 -050060 if (precondState)
Matthew Barth604329e2017-08-04 11:18:28 -050061 {
Matthew Barth572d4062018-05-08 14:16:04 -050062 log<level::DEBUG>(
63 "Preconditions passed, init the associated events",
64 entry("EVENT_COUNT=%u", sse.size()));
Matthew Barthf9201ab2017-09-11 16:07:58 -050065 // Init the events when all the precondition(s) are true
66 std::for_each(
67 sse.begin(),
68 sse.end(),
69 [&zone](auto const& entry)
70 {
71 zone.initEvent(entry);
72 });
Matthew Barth604329e2017-08-04 11:18:28 -050073 }
74 else
75 {
Matthew Barth572d4062018-05-08 14:16:04 -050076 log<level::DEBUG>(
77 "Preconditions not met for events, events removed if present",
78 entry("EVENT_COUNT=%u", sse.size()));
Matthew Barthf9201ab2017-09-11 16:07:58 -050079 // Unsubscribe the events' signals when any precondition is false
80 std::for_each(
81 sse.begin(),
82 sse.end(),
83 [&zone](auto const& entry)
84 {
85 zone.removeEvent(entry);
86 });
Matthew Barth60b00762017-08-15 13:39:06 -050087 zone.setFullSpeed();
Matthew Barth604329e2017-08-04 11:18:28 -050088 }
Matthew Barth60b00762017-08-15 13:39:06 -050089 // Update group's fan control active allowed
Matthew Barth572d4062018-05-08 14:16:04 -050090 zone.setActiveAllow(&group, precondState);
Matthew Barthccc77702017-07-28 13:43:04 -050091 };
92}
93
94} // namespace precondition
95} // namespace control
96} // namespace fan
97} // namespace phosphor