blob: aaaf1c614eb56eb5e0431433a947ed216a9c060f [file] [log] [blame]
George Liu6f777cd2021-06-10 09:16:28 +08001#include "occ_dbus.hpp"
2
3#include "utils.hpp"
4
Matt Spinler5901abd2021-09-23 13:50:03 -05005#include <fmt/core.h>
6
George Liu6f777cd2021-06-10 09:16:28 +08007#include <phosphor-logging/log.hpp>
8
George Liub5ca1012021-09-10 12:53:11 +08009#include <iostream>
10
George Liu6f777cd2021-06-10 09:16:28 +080011namespace open_power
12{
13namespace occ
14{
15namespace dbus
16{
17
18using namespace phosphor::logging;
Matt Spinler5901abd2021-09-23 13:50:03 -050019using namespace std::string_literals;
20const auto defaultChassisPath =
21 "/xyz/openbmc_project/inventory/system/chassis"s;
22const auto chassisInterface = "xyz.openbmc_project.Inventory.Item.Chassis"s;
23
George Liu0ad9dd82021-06-22 14:46:14 +080024bool OccDBusSensors::setMaxValue(const std::string& path, double value)
George Liu6f777cd2021-06-10 09:16:28 +080025{
George Liu0ad9dd82021-06-22 14:46:14 +080026 if (path.empty())
27 {
28 return false;
29 }
30
George Liu6f777cd2021-06-10 09:16:28 +080031 if (sensors.find(path) == sensors.end())
32 {
33 sensors.emplace(
34 path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
35 }
36
37 sensors.at(path)->maxValue(value);
George Liu0ad9dd82021-06-22 14:46:14 +080038 return true;
George Liu6f777cd2021-06-10 09:16:28 +080039}
40
41double OccDBusSensors::getMaxValue(const std::string& path) const
42{
43 if (sensors.find(path) != sensors.end())
44 {
45 return sensors.at(path)->maxValue();
46 }
47
48 throw std::invalid_argument("Failed to get MaxValue property.");
49}
50
George Liu0ad9dd82021-06-22 14:46:14 +080051bool OccDBusSensors::setMinValue(const std::string& path, double value)
George Liu6f777cd2021-06-10 09:16:28 +080052{
George Liu0ad9dd82021-06-22 14:46:14 +080053 if (path.empty())
54 {
55 return false;
56 }
57
George Liu6f777cd2021-06-10 09:16:28 +080058 if (sensors.find(path) == sensors.end())
59 {
60 sensors.emplace(
61 path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
62 }
63
64 sensors.at(path)->minValue(value);
George Liu0ad9dd82021-06-22 14:46:14 +080065 return true;
George Liu6f777cd2021-06-10 09:16:28 +080066}
67
68double OccDBusSensors::getMinValue(const std::string& path) const
69{
70 if (sensors.find(path) != sensors.end())
71 {
72 return sensors.at(path)->minValue();
73 }
74
75 throw std::invalid_argument("Failed to get MinValue property.");
76}
77
George Liu0ad9dd82021-06-22 14:46:14 +080078bool OccDBusSensors::setValue(const std::string& path, double value)
George Liu6f777cd2021-06-10 09:16:28 +080079{
George Liu0ad9dd82021-06-22 14:46:14 +080080 if (path.empty())
81 {
82 return false;
83 }
84
George Liu6f777cd2021-06-10 09:16:28 +080085 if (sensors.find(path) == sensors.end())
86 {
87 sensors.emplace(
88 path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
89 }
90
91 sensors.at(path)->value(value);
George Liu0ad9dd82021-06-22 14:46:14 +080092 return true;
George Liu6f777cd2021-06-10 09:16:28 +080093}
94
95double OccDBusSensors::getValue(const std::string& path) const
96{
97 if (sensors.find(path) != sensors.end())
98 {
99 return sensors.at(path)->value();
100 }
101
102 throw std::invalid_argument("Failed to get Value property.");
103}
104
George Liu0ad9dd82021-06-22 14:46:14 +0800105bool OccDBusSensors::setUnit(const std::string& path, const std::string& value)
George Liu6f777cd2021-06-10 09:16:28 +0800106{
George Liu0ad9dd82021-06-22 14:46:14 +0800107 if (path.empty())
108 {
109 return false;
110 }
111
George Liu6f777cd2021-06-10 09:16:28 +0800112 if (sensors.find(path) == sensors.end())
113 {
114 sensors.emplace(
115 path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
116 }
117
118 try
119 {
120 sensors.at(path)->unit(SensorIntf::convertUnitFromString(value));
121 }
122 catch (const std::exception& e)
123 {
124 log<level::ERR>("set Unit propety failed", entry("ERROR=%s", e.what()));
George Liu0ad9dd82021-06-22 14:46:14 +0800125 return false;
George Liu6f777cd2021-06-10 09:16:28 +0800126 }
George Liu0ad9dd82021-06-22 14:46:14 +0800127
128 return true;
George Liu6f777cd2021-06-10 09:16:28 +0800129}
130
131std::string OccDBusSensors::getUnit(const std::string& path) const
132{
133 if (sensors.find(path) != sensors.end())
134 {
135 try
136 {
137 return SensorIntf::convertUnitToString(sensors.at(path)->unit());
138 }
139 catch (const std::exception& e)
140 {
141 log<level::ERR>("get Unit propety failed",
142 entry("ERROR=%s", e.what()));
143 }
144 }
145
146 throw std::invalid_argument("Failed to get Unit property.");
147}
148
George Liu0ad9dd82021-06-22 14:46:14 +0800149bool OccDBusSensors::setOperationalStatus(const std::string& path, bool value)
George Liu6f777cd2021-06-10 09:16:28 +0800150{
George Liu0ad9dd82021-06-22 14:46:14 +0800151 if (path.empty())
152 {
153 return false;
154 }
155
George Liu6f777cd2021-06-10 09:16:28 +0800156 if (operationalStatus.find(path) == operationalStatus.end())
157 {
158 operationalStatus.emplace(path, std::make_unique<OperationalStatusIntf>(
159 utils::getBus(), path.c_str()));
160 }
161
162 operationalStatus.at(path)->functional(value);
George Liu0ad9dd82021-06-22 14:46:14 +0800163 return true;
George Liu6f777cd2021-06-10 09:16:28 +0800164}
165
166bool OccDBusSensors::getOperationalStatus(const std::string& path) const
167{
168 if (operationalStatus.find(path) != operationalStatus.end())
169 {
170 return operationalStatus.at(path)->functional();
171 }
172
173 throw std::invalid_argument("Failed to get OperationalStatus property.");
174}
175
Matt Spinler5901abd2021-09-23 13:50:03 -0500176void OccDBusSensors::setChassisAssociation(const std::string& path)
177{
178 using AssociationsEntry = std::tuple<std::string, std::string, std::string>;
179 using AssociationsProperty = std::vector<AssociationsEntry>;
180 using PropVariant = sdbusplus::xyz::openbmc_project::Association::server::
181 Definitions::PropertiesVariant;
182
183 if (chassisPath.empty())
184 {
185 chassisPath = getChassisPath();
186 }
187
188 AssociationsProperty associations{
189 AssociationsEntry{"chassis", "all_sensors", chassisPath}};
190 PropVariant value{std::move(associations)};
191
192 std::map<std::string, PropVariant> properties;
193 properties.emplace("Associations", std::move(value));
194
195 chassisAssociations.emplace(
196 path, std::make_unique<AssociationIntf>(utils::getBus(), path.c_str(),
197 properties));
198}
199
200std::string OccDBusSensors::getChassisPath()
201{
202 try
203 {
204 auto paths = utils::getSubtreePaths(std::vector{chassisInterface});
205
206 // For now, support either 1 chassis, or multiple as long as one
207 // of them has the standard name, which we will use. If this ever
208 // fails, then someone would have to figure out how to identify the
209 // chassis the OCCs are on.
210 if (paths.size() == 1)
211 {
212 return paths[0];
213 }
214 else if (std::find(paths.begin(), paths.end(), defaultChassisPath) ==
215 paths.end())
216 {
217 log<level::ERR>(
218 fmt::format(
219 "Could not find a chassis out of {} chassis objects",
220 paths.size())
221 .c_str());
222 // Can't throw an exception here, the sdeventplus timer
223 // just catches it.
224 abort();
225 }
226 }
227 catch (const std::exception& e)
228 {
229 log<level::ERR>(
230 fmt::format("Error looking up chassis objects: {}", e.what())
231 .c_str());
232 abort();
233 }
234
235 return defaultChassisPath;
236}
237
Matt Spinlerace67d82021-10-18 13:41:57 -0500238bool OccDBusSensors::hasDvfsTemp(const std::string& path) const
239{
240 return dvfsTemps.find(path) != dvfsTemps.end();
241}
242
243void OccDBusSensors::setDvfsTemp(const std::string& path, double value)
244{
245 dvfsTemps[path] =
246 std::make_unique<SensorIntf>(utils::getBus(), path.c_str());
247 dvfsTemps[path]->value(value);
248}
249
George Liu6f777cd2021-06-10 09:16:28 +0800250} // namespace dbus
251} // namespace occ
252} // namespace open_power