diff options
Diffstat (limited to 'presence/tach.cpp')
-rw-r--r-- | presence/tach.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/presence/tach.cpp b/presence/tach.cpp new file mode 100644 index 0000000..deed040 --- /dev/null +++ b/presence/tach.cpp @@ -0,0 +1,148 @@ +/** + * Copyright © 2017 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string> +#include <tuple> +#include <vector> +#include "tach.hpp" +#include "rpolicy.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +using namespace std::literals::string_literals; + +static const auto tachNamespace = "/xyz/openbmc_project/sensors/fan_tach/"s; +static const auto tachIface = "xyz.openbmc_project.Sensor.Value"s; +static const auto tachProperty = "Value"s; + +Tach::Tach( + const std::vector<std::string>& sensors) : currentState(false) +{ + // Initialize state. + for (const auto& s : sensors) + { + state.emplace_back(s, nullptr, 0); + } +} + +bool Tach::start() +{ + for (size_t i = 0; i < state.size(); ++i) + { + auto& s = state[i]; + auto tachPath = tachNamespace + std::get<std::string>(s); + + // Register for signal callbacks. + std::get<1>(s) = std::make_unique<sdbusplus::bus::match::match>( + util::SDBusPlus::getBus(), + sdbusplus::bus::match::rules::propertiesChanged( + tachPath, tachIface), + [this, i](auto& msg){ this->propertiesChanged(i, msg);}); + + // Get an initial tach speed. + std::get<int64_t>(s) = util::SDBusPlus::getProperty<int64_t>( + tachPath, + tachIface, + tachProperty); + } + + // Set the initial state of the sensor. + currentState = std::any_of( + state.begin(), + state.end(), + [](const auto & s) + { + return std::get<int64_t>(s) != 0; + }); + + return currentState; +} + +void Tach::stop() +{ + for (auto& s : state) + { + // De-register signal callbacks. + std::get<1>(s) = nullptr; + } +} + +bool Tach::present() +{ + // Live query the tach readings. + std::vector<int64_t> values; + for (const auto& s : state) + { + values.push_back( + util::SDBusPlus::getProperty<int64_t>( + tachNamespace + std::get<std::string>(s), + tachIface, + tachProperty)); + } + + return std::any_of( + values.begin(), + values.end(), + [](const auto & v) {return v != 0;}); +} + +void Tach::propertiesChanged( + size_t sensor, + sdbusplus::message::message& msg) +{ + std::string iface; + util::Properties<int64_t> properties; + msg.read(iface, properties); + + propertiesChanged(sensor, properties); +} + +void Tach::propertiesChanged( + size_t sensor, + const util::Properties<int64_t>& props) +{ + auto& s = state[sensor]; + + // Find the Value property containing the speed. + auto it = props.find(tachProperty); + if (it != props.end()) + { + std::get<int64_t>(s) = + sdbusplus::message::variant_ns::get<int64_t>(it->second); + + auto newState = std::any_of( + state.begin(), + state.end(), + [](const auto & s) + { + return std::get<int64_t>(s) != 0; + }); + + if (currentState != newState) + { + getPolicy().stateChanged(newState); + currentState = newState; + } + } +} + +} // namespace presence +} // namespace fan +} // namespace phosphor |