xref: /openbmc/phosphor-fan-presence/control/fan.cpp (revision 5d70c251cd74eb50453afe07daf5ac7e844b5d78)
1 /**
2  * Copyright © 2017 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 #include <phosphor-logging/log.hpp>
17 #include <phosphor-logging/elog.hpp>
18 #include <phosphor-logging/elog-errors.hpp>
19 #include <xyz/openbmc_project/Common/error.hpp>
20 #include <string>
21 #include "fan.hpp"
22 #include "utility.hpp"
23 
24 namespace phosphor
25 {
26 namespace fan
27 {
28 namespace control
29 {
30 
31 // For throwing exception
32 using namespace phosphor::logging;
33 using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
34                             Error::InternalFailure;
35 
36 constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
37 constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
38 constexpr auto FAN_SENSOR_CONTROL_INTF = "xyz.openbmc_project.Control.FanSpeed";
39 constexpr auto FAN_TARGET_PROPERTY = "Target";
40 
41 
42 Fan::Fan(sdbusplus::bus::bus& bus, const FanDefinition& def):
43     _bus(bus),
44     _name(std::get<fanNamePos>(def))
45 {
46     auto sensors = std::get<sensorListPos>(def);
47     for (auto& s : sensors)
48     {
49         _sensors.emplace_back(FAN_SENSOR_PATH + s);
50     }
51 }
52 
53 
54 //TODO openbmc/openbmc#1524  Can cache this value when
55 //openbmc/openbmc#1496 is resolved.
56 std::string Fan::getService(const std::string& sensor)
57 {
58     return phosphor::fan::util::getService(sensor,
59                                            FAN_SENSOR_CONTROL_INTF,
60                                            _bus);
61 }
62 
63 
64 void Fan::setSpeed(uint64_t speed)
65 {
66     sdbusplus::message::variant<uint64_t> value = speed;
67     std::string property{FAN_TARGET_PROPERTY};
68 
69     for (auto& sensor : _sensors)
70     {
71         auto service = getService(sensor);
72 
73         auto method = _bus.new_method_call(service.c_str(),
74                                                sensor.c_str(),
75                                                PROPERTY_INTERFACE,
76                                                "Set");
77         method.append(FAN_SENSOR_CONTROL_INTF, property, value);
78 
79         auto response = _bus.call(method);
80         if (response.is_method_error())
81         {
82             log<level::ERR>(
83                 "Failed call to set fan speed ", entry("SENSOR=%s", sensor));
84             elog<InternalFailure>();
85         }
86     }
87 }
88 
89 }
90 }
91 }
92