| #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; |
| } |
| |
| } // namespace dbus |
| } // namespace occ |
| } // namespace open_power |