1 /**
2  * Copyright © 2022 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "config_base.hpp"
19 
20 #include <nlohmann/json.hpp>
21 #include <sdbusplus/bus.hpp>
22 
23 #include <map>
24 
25 namespace phosphor::fan::control::json
26 {
27 
28 using json = nlohmann::json;
29 
30 /**
31  * @class Fan - Represents a configured fan control fan object
32  *
33  * A fan object contains the configured attributes for a fan within the system
34  * that will be controlled by the fan control application. These configuration
35  * attributes include, but are not limited to, the cooling zone in which the
36  * fan is included, what sensors make up the fan, the target interface to be
37  * used in setting a target, and any profiles(OPTIONAL) the fan should be
38  * included in.
39  *
40  * (When no profile for a fan is given, the fan defaults to always be included)
41  *
42  */
43 class Fan : public ConfigBase
44 {
45     friend class Zone;
46 
47   public:
48     /* JSON file name for fans */
49     static constexpr auto confFileName = "fans.json";
50 
51     Fan() = delete;
52     Fan(const Fan&) = delete;
53     Fan(Fan&&) = delete;
54     Fan& operator=(const Fan&) = delete;
55     Fan& operator=(Fan&&) = delete;
56     ~Fan() = default;
57 
58     /**
59      * Constructor
60      * Parses and populates a zone fan from JSON object data
61      *
62      * @param[in] jsonObj - JSON object
63      */
64     Fan(const json& jsonObj);
65 
66     /**
67      * @brief Get the zone
68      *
69      * @return Zone this fan belongs in
70      */
71     inline const auto& getZone() const
72     {
73         return _zone;
74     }
75 
76     /**
77      * @brief Get the list of sensors
78      *
79      * @return List of sensors with `Target` property
80      */
81     inline const auto& getSensors() const
82     {
83         return _sensors;
84     }
85 
86     /**
87      * @brief Get the sensors' interface
88      *
89      * @return Interface containing `Target` to use on sensors
90      */
91     inline const auto& getInterface() const
92     {
93         return _interface;
94     }
95 
96     /**
97      * @brief Get the current fan target
98      *
99      * @return - The current target of the fan
100      */
101     inline auto getTarget() const
102     {
103         return _target;
104     }
105 
106     /**
107      * Sets the target value on all contained sensors
108      *
109      * @param[in] target - The value to set
110      */
111     void setTarget(uint64_t target);
112 
113   private:
114     /**
115      * Forces all contained sensors to the target (if this target is the
116      * highest. May be overridden by existing or subsequent higher values),
117      * ignoring subsequent setTarget() commands
118      *
119      * @param[in] target - The target lock to set/add
120      */
121     void lockTarget(uint64_t target);
122 
123     /**
124      * Removes the provided target lock from the list of locks. Fan will unlock
125      * (become eligible for setTarget()) when all locks are removed from the
126      * list.
127      */
128     void unlockTarget(uint64_t target);
129 
130     /* The sdbusplus bus object */
131     sdbusplus::bus_t& _bus;
132 
133     /**
134      * Interface containing the `Target` property
135      * to use in controlling the fan's target
136      */
137     std::string _interface;
138 
139     /* Target for this fan */
140     uint64_t _target;
141 
142     /* list of locked targets active on this fan */
143     std::vector<uint64_t> _lockedTargets;
144 
145     /**
146      * Map of sensors containing the `Target` property on
147      * dbus to the service providing them that make up the fan
148      */
149     std::map<std::string, std::string> _sensors;
150 
151     /* The zone this fan belongs to */
152     std::string _zone;
153 
154     /**
155      * @brief Parse and set the fan's sensor interface
156      *
157      * @param[in] jsonObj - JSON object for the fan
158      *
159      * Sets the sensor interface to use when setting the `Target` property
160      */
161     void setInterface(const json& jsonObj);
162 
163     /**
164      * @brief Parse and set the fan's sensor list
165      *
166      * @param[in] jsonObj - JSON object for the fan
167      *
168      * Sets the list of sensors that contain a `Target` property on dbus
169      * that make up this fan.
170      */
171     void setSensors(const json& jsonObj);
172 
173     /**
174      * @brief Parse and set the fan's zone
175      *
176      * @param[in] jsonObj - JSON object for the fan
177      *
178      * Sets the zone this fan is included in.
179      */
180     void setZone(const json& jsonObj);
181 };
182 
183 } // namespace phosphor::fan::control::json
184