diff options
-rw-r--r-- | control/actions.hpp | 50 | ||||
-rw-r--r-- | control/functor.hpp | 13 | ||||
-rw-r--r-- | control/types.hpp | 18 | ||||
-rw-r--r-- | control/zone.cpp | 42 | ||||
-rw-r--r-- | control/zone.hpp | 16 |
5 files changed, 118 insertions, 21 deletions
diff --git a/control/actions.hpp b/control/actions.hpp new file mode 100644 index 0000000..eb857b6 --- /dev/null +++ b/control/actions.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include <algorithm> + +namespace phosphor +{ +namespace fan +{ +namespace control +{ +namespace action +{ + +/** + * @brief An action to set the speed on a zone + * @details The zone is set to the given speed when a defined number of + * properties in the group are set to the given state + * + * @param[in] count - Number of properties + * @param[in] state - Value the property(s) needed to be set at + * @param[in] speed - Speed to set the zone to + * + * @return Lambda function + * A lambda function to set the zone speed when the number of properties + * within the group are at a certain value + */ +auto count_state_before_speed(size_t count, bool state, uint64_t speed) +{ + return [=](auto& zone, auto& group) + { + size_t numAtState = std::count_if( + group.begin(), + group.end(), + [&zone, &state](auto const& entry) + { + return zone.getPropertyValue( + entry.first, + std::get<propPos>(entry.second)) == state; + }); + if (numAtState >= count) + { + zone.setSpeed(speed); + } + }; +} + +} // namespace action +} // namespace control +} // namespace fan +} // namespace phosphor diff --git a/control/functor.hpp b/control/functor.hpp index f2f3a78..2b36445 100644 --- a/control/functor.hpp +++ b/control/functor.hpp @@ -27,6 +27,19 @@ auto make_handler(T&& handler) } /** + * @brief Create an action function object + * + * @param[in] action - The action being created + * + * @return - The created action function object + */ +template <typename T> +auto make_action(T&& action) +{ + return Action(std::forward<T>(action)); +} + +/** * @struct Property Changed * @brief A match filter functor for Dbus property value changed signals * diff --git a/control/types.hpp b/control/types.hpp index bbbac61..c610ed9 100644 --- a/control/types.hpp +++ b/control/types.hpp @@ -19,17 +19,31 @@ constexpr auto fanNamePos = 0; constexpr auto sensorListPos = 1; using FanDefinition = std::tuple<std::string, std::vector<std::string>>; +constexpr auto intfPos = 0; +constexpr auto propPos = 1; +using Group = std::map<std::string, std::tuple<std::string, std::string>>; using Handler = std::function<void(sdbusplus::bus::bus&, sdbusplus::message::message&, Zone&)>; +using Action = std::function<void(Zone&, const Group&)>; constexpr auto signaturePos = 0; constexpr auto handlerObjPos = 1; using PropertyChange = std::tuple<std::string, Handler>; -using SetSpeedEvent = std::vector<PropertyChange>; + +constexpr auto groupPos = 0; +constexpr auto actionPos = 1; +constexpr auto propChangeListPos = 2; +using SetSpeedEvent = std::tuple<Group, Action, std::vector<PropertyChange>>; + +constexpr auto eventGroupPos = 0; +constexpr auto eventHandlerPos = 1; +constexpr auto eventActionPos = 2; +using EventData = std::tuple<Group, Handler, Action>; constexpr auto zoneObjPos = 0; -using SignalEvent = std::tuple<Zone*, Handler>; +constexpr auto eventDataPos = 1; +using SignalEvent = std::tuple<Zone*, EventData>; constexpr auto zoneNumPos = 0; constexpr auto fullSpeedPos = 1; diff --git a/control/zone.cpp b/control/zone.cpp index 28b81f9..3a35b24 100644 --- a/control/zone.cpp +++ b/control/zone.cpp @@ -36,20 +36,24 @@ Zone::Zone(sdbusplus::bus::bus& bus, _fans.emplace_back(std::make_unique<Fan>(bus, def)); } - // Setup signal trigger for property changes
- for (auto& event : std::get<setSpeedEventsPos>(def))
- {
- for (auto& prop : event)
- {
- _signalEvents.emplace_back(
- std::make_unique<SignalEvent>(this,
- std::get<handlerObjPos>(prop)
- ));
- _matches.emplace_back(bus,
- std::get<signaturePos>(prop).c_str(),
- signalHandler,
- _signalEvents.back().get());
- }
+ // Setup signal trigger for set speed events + for (auto& event : std::get<setSpeedEventsPos>(def)) + { + for (auto& prop : std::get<propChangeListPos>(event)) + { + _signalEvents.emplace_back( + std::make_unique<SignalEvent>(this, + EventData + { + std::get<groupPos>(event), + std::get<handlerObjPos>(prop), + std::get<actionPos>(event) + })); + _matches.emplace_back(bus, + std::get<signaturePos>(prop).c_str(), + signalHandler, + _signalEvents.back().get()); + } } } @@ -70,18 +74,20 @@ int Zone::signalHandler(sd_bus_message* msg, auto& signalEvent = *static_cast<SignalEvent*>(data); std::get<zoneObjPos>(signalEvent)->handleEvent( sdbpMsg, - std::get<handlerObjPos>(signalEvent)); + std::get<eventDataPos>(signalEvent)); return 0; } void Zone::handleEvent(sdbusplus::message::message& msg, - const Handler& handler) + const EventData& eventData) { // Handle the callback - handler(_bus, msg, *this); + std::get<eventHandlerPos>(eventData)(_bus, msg, *this); + // Perform the action + std::get<eventActionPos>(eventData)(*this, + std::get<eventGroupPos>(eventData)); } - } } } diff --git a/control/zone.hpp b/control/zone.hpp index 601c002..d8f3fe4 100644 --- a/control/zone.hpp +++ b/control/zone.hpp @@ -71,6 +71,20 @@ class Zone _properties[object][property] = value; }; + /** + * @brief Get the value of an object's property + * + * @param[in] object - Name of the object containing the property + * @param[in] property - Property name + * + * @return - The property value + */ + inline auto getPropertyValue(const std::string& object, + const std::string& property) + { + return _properties[object][property]; + }; + private: /** @@ -126,7 +140,7 @@ class Zone * @param[in] eventData - The event's data */ void handleEvent(sdbusplus::message::message& msg, - const Handler& handler); + const EventData& eventData); }; } |