summaryrefslogtreecommitdiffstats
path: root/presence/tach.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'presence/tach.cpp')
-rw-r--r--presence/tach.cpp148
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
OpenPOWER on IntegriCloud