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     /**
114      * @brief Returns the fan's locked targets.
115      *
116      * @return - vector of locked targets
117      */
118     const std::vector<uint64_t>& getLockedTargets() const
119     {
120         return _lockedTargets;
121     }
122 
123   private:
124     /**
125      * Forces all contained sensors to the target (if this target is the
126      * highest. May be overridden by existing or subsequent higher values),
127      * ignoring subsequent setTarget() commands
128      *
129      * @param[in] target - The target lock to set/add
130      */
131     void lockTarget(uint64_t target);
132 
133     /**
134      * Removes the provided target lock from the list of locks. Fan will unlock
135      * (become eligible for setTarget()) when all locks are removed from the
136      * list.
137      */
138     void unlockTarget(uint64_t target);
139 
140     /* The sdbusplus bus object */
141     sdbusplus::bus_t& _bus;
142 
143     /**
144      * Interface containing the `Target` property
145      * to use in controlling the fan's target
146      */
147     std::string _interface;
148 
149     /* Target for this fan */
150     uint64_t _target;
151 
152     /* list of locked targets active on this fan */
153     std::vector<uint64_t> _lockedTargets;
154 
155     /**
156      * Map of sensors containing the `Target` property on
157      * dbus to the service providing them that make up the fan
158      */
159     std::map<std::string, std::string> _sensors;
160 
161     /* The zone this fan belongs to */
162     std::string _zone;
163 
164     /**
165      * @brief Parse and set the fan's sensor interface
166      *
167      * @param[in] jsonObj - JSON object for the fan
168      *
169      * Sets the sensor interface to use when setting the `Target` property
170      */
171     void setInterface(const json& jsonObj);
172 
173     /**
174      * @brief Parse and set the fan's sensor list
175      *
176      * @param[in] jsonObj - JSON object for the fan
177      *
178      * Sets the list of sensors that contain a `Target` property on dbus
179      * that make up this fan.
180      */
181     void setSensors(const json& jsonObj);
182 
183     /**
184      * @brief Parse and set the fan's zone
185      *
186      * @param[in] jsonObj - JSON object for the fan
187      *
188      * Sets the zone this fan is included in.
189      */
190     void setZone(const json& jsonObj);
191 };
192 
193 } // namespace phosphor::fan::control::json
194