blob: aaaf1c614eb56eb5e0431433a947ed216a9c060f [file] [log] [blame]
#include "occ_dbus.hpp"
#include "utils.hpp"
#include <fmt/core.h>
#include <phosphor-logging/log.hpp>
#include <iostream>
namespace open_power
{
namespace occ
{
namespace dbus
{
using namespace phosphor::logging;
using namespace std::string_literals;
const auto defaultChassisPath =
"/xyz/openbmc_project/inventory/system/chassis"s;
const auto chassisInterface = "xyz.openbmc_project.Inventory.Item.Chassis"s;
bool OccDBusSensors::setMaxValue(const std::string& path, double value)
{
if (path.empty())
{
return false;
}
if (sensors.find(path) == sensors.end())
{
sensors.emplace(
path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
}
sensors.at(path)->maxValue(value);
return true;
}
double OccDBusSensors::getMaxValue(const std::string& path) const
{
if (sensors.find(path) != sensors.end())
{
return sensors.at(path)->maxValue();
}
throw std::invalid_argument("Failed to get MaxValue property.");
}
bool OccDBusSensors::setMinValue(const std::string& path, double value)
{
if (path.empty())
{
return false;
}
if (sensors.find(path) == sensors.end())
{
sensors.emplace(
path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
}
sensors.at(path)->minValue(value);
return true;
}
double OccDBusSensors::getMinValue(const std::string& path) const
{
if (sensors.find(path) != sensors.end())
{
return sensors.at(path)->minValue();
}
throw std::invalid_argument("Failed to get MinValue property.");
}
bool OccDBusSensors::setValue(const std::string& path, double value)
{
if (path.empty())
{
return false;
}
if (sensors.find(path) == sensors.end())
{
sensors.emplace(
path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
}
sensors.at(path)->value(value);
return true;
}
double OccDBusSensors::getValue(const std::string& path) const
{
if (sensors.find(path) != sensors.end())
{
return sensors.at(path)->value();
}
throw std::invalid_argument("Failed to get Value property.");
}
bool OccDBusSensors::setUnit(const std::string& path, const std::string& value)
{
if (path.empty())
{
return false;
}
if (sensors.find(path) == sensors.end())
{
sensors.emplace(
path, std::make_unique<SensorIntf>(utils::getBus(), path.c_str()));
}
try
{
sensors.at(path)->unit(SensorIntf::convertUnitFromString(value));
}
catch (const std::exception& e)
{
log<level::ERR>("set Unit propety failed", entry("ERROR=%s", e.what()));
return false;
}
return true;
}
std::string OccDBusSensors::getUnit(const std::string& path) const
{
if (sensors.find(path) != sensors.end())
{
try
{
return SensorIntf::convertUnitToString(sensors.at(path)->unit());
}
catch (const std::exception& e)
{
log<level::ERR>("get Unit propety failed",
entry("ERROR=%s", e.what()));
}
}
throw std::invalid_argument("Failed to get Unit property.");
}
bool OccDBusSensors::setOperationalStatus(const std::string& path, bool value)
{
if (path.empty())
{
return false;
}
if (operationalStatus.find(path) == operationalStatus.end())
{
operationalStatus.emplace(path, std::make_unique<OperationalStatusIntf>(
utils::getBus(), path.c_str()));
}
operationalStatus.at(path)->functional(value);
return true;
}
bool OccDBusSensors::getOperationalStatus(const std::string& path) const
{
if (operationalStatus.find(path) != operationalStatus.end())
{
return operationalStatus.at(path)->functional();
}
throw std::invalid_argument("Failed to get OperationalStatus property.");
}
void OccDBusSensors::setChassisAssociation(const std::string& path)
{
using AssociationsEntry = std::tuple<std::string, std::string, std::string>;
using AssociationsProperty = std::vector<AssociationsEntry>;
using PropVariant = sdbusplus::xyz::openbmc_project::Association::server::
Definitions::PropertiesVariant;
if (chassisPath.empty())
{
chassisPath = getChassisPath();
}
AssociationsProperty associations{
AssociationsEntry{"chassis", "all_sensors", chassisPath}};
PropVariant value{std::move(associations)};
std::map<std::string, PropVariant> properties;
properties.emplace("Associations", std::move(value));
chassisAssociations.emplace(
path, std::make_unique<AssociationIntf>(utils::getBus(), path.c_str(),
properties));
}
std::string OccDBusSensors::getChassisPath()
{
try
{
auto paths = utils::getSubtreePaths(std::vector{chassisInterface});
// For now, support either 1 chassis, or multiple as long as one
// of them has the standard name, which we will use. If this ever
// fails, then someone would have to figure out how to identify the
// chassis the OCCs are on.
if (paths.size() == 1)
{
return paths[0];
}
else if (std::find(paths.begin(), paths.end(), defaultChassisPath) ==
paths.end())
{
log<level::ERR>(
fmt::format(
"Could not find a chassis out of {} chassis objects",
paths.size())
.c_str());
// Can't throw an exception here, the sdeventplus timer
// just catches it.
abort();
}
}
catch (const std::exception& e)
{
log<level::ERR>(
fmt::format("Error looking up chassis objects: {}", e.what())
.c_str());
abort();
}
return defaultChassisPath;
}
bool OccDBusSensors::hasDvfsTemp(const std::string& path) const
{
return dvfsTemps.find(path) != dvfsTemps.end();
}
void OccDBusSensors::setDvfsTemp(const std::string& path, double value)
{
dvfsTemps[path] =
std::make_unique<SensorIntf>(utils::getBus(), path.c_str());
dvfsTemps[path]->value(value);
}
} // namespace dbus
} // namespace occ
} // namespace open_power