| #include "trigger_factory.hpp" |
| |
| #include "discrete_threshold.hpp" |
| #include "numeric_threshold.hpp" |
| #include "on_change_threshold.hpp" |
| #include "sensor.hpp" |
| #include "trigger.hpp" |
| #include "trigger_actions.hpp" |
| #include "utils/dbus_mapper.hpp" |
| #include "utils/transform.hpp" |
| |
| namespace ts = utils::tstring; |
| |
| TriggerFactory::TriggerFactory( |
| std::shared_ptr<sdbusplus::asio::connection> bus, |
| std::shared_ptr<sdbusplus::asio::object_server> objServer, |
| SensorCache& sensorCache, interfaces::ReportManager& reportManager) : |
| bus(std::move(bus)), |
| objServer(std::move(objServer)), sensorCache(sensorCache), |
| reportManager(reportManager) |
| {} |
| |
| std::unique_ptr<interfaces::Trigger> TriggerFactory::make( |
| const std::string& id, const std::string& name, |
| const std::vector<std::string>& triggerActionsIn, |
| const std::vector<std::string>& reportIds, |
| interfaces::TriggerManager& triggerManager, |
| interfaces::JsonStorage& triggerStorage, |
| const LabeledTriggerThresholdParams& labeledThresholdParams, |
| const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const |
| { |
| const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo); |
| std::vector<TriggerAction> triggerActions; |
| std::transform(triggerActionsIn.begin(), triggerActionsIn.end(), |
| std::back_inserter(triggerActions), |
| [](const auto& triggerActionStr) { |
| return toTriggerAction(triggerActionStr); |
| }); |
| std::vector<std::shared_ptr<interfaces::Threshold>> thresholds; |
| |
| if (isTriggerThresholdDiscrete(labeledThresholdParams)) |
| { |
| const auto& labeledDiscreteThresholdParams = |
| std::get<std::vector<discrete::LabeledThresholdParam>>( |
| labeledThresholdParams); |
| for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams) |
| { |
| std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; |
| |
| std::string thresholdName = |
| labeledThresholdParam.at_label<ts::UserId>(); |
| discrete::Severity severity = |
| labeledThresholdParam.at_label<ts::Severity>(); |
| auto dwellTime = |
| Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>()); |
| std::string thresholdValue = |
| labeledThresholdParam.at_label<ts::ThresholdValue>(); |
| |
| action::discrete::fillActions(actions, triggerActions, severity, |
| reportManager, reportIds); |
| |
| thresholds.emplace_back(std::make_shared<DiscreteThreshold>( |
| bus->get_io_context(), sensors, sensorNames, std::move(actions), |
| Milliseconds(dwellTime), std::stod(thresholdValue), |
| thresholdName)); |
| } |
| if (labeledDiscreteThresholdParams.empty()) |
| { |
| std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; |
| action::discrete::onChange::fillActions(actions, triggerActions, |
| reportManager, reportIds); |
| |
| thresholds.emplace_back(std::make_shared<OnChangeThreshold>( |
| sensors, sensorNames, std::move(actions))); |
| } |
| } |
| else |
| { |
| const auto& labeledNumericThresholdParams = |
| std::get<std::vector<numeric::LabeledThresholdParam>>( |
| labeledThresholdParams); |
| |
| for (const auto& labeledThresholdParam : labeledNumericThresholdParams) |
| { |
| std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; |
| auto type = labeledThresholdParam.at_label<ts::Type>(); |
| auto dwellTime = |
| Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>()); |
| auto direction = labeledThresholdParam.at_label<ts::Direction>(); |
| auto thresholdValue = |
| double{labeledThresholdParam.at_label<ts::ThresholdValue>()}; |
| |
| action::numeric::fillActions(actions, triggerActions, type, |
| thresholdValue, reportManager, |
| reportIds); |
| |
| thresholds.emplace_back(std::make_shared<NumericThreshold>( |
| bus->get_io_context(), sensors, sensorNames, std::move(actions), |
| dwellTime, direction, thresholdValue)); |
| } |
| } |
| |
| return std::make_unique<Trigger>( |
| bus->get_io_context(), objServer, id, name, triggerActionsIn, reportIds, |
| labeledSensorsInfo, labeledThresholdParams, std::move(thresholds), |
| triggerManager, triggerStorage); |
| } |
| |
| std::pair<Sensors, std::vector<std::string>> TriggerFactory::getSensors( |
| const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const |
| { |
| Sensors sensors; |
| std::vector<std::string> sensorNames; |
| |
| for (const auto& labeledSensorInfo : labeledSensorsInfo) |
| { |
| const auto& service = labeledSensorInfo.at_label<ts::Service>(); |
| const auto& sensorPath = labeledSensorInfo.at_label<ts::SensorPath>(); |
| const auto& metadata = labeledSensorInfo.at_label<ts::Metadata>(); |
| |
| sensors.emplace_back(sensorCache.makeSensor<Sensor>( |
| service, sensorPath, metadata, bus->get_io_context(), bus)); |
| |
| if (metadata.empty()) |
| { |
| sensorNames.emplace_back(sensorPath); |
| } |
| else |
| { |
| sensorNames.emplace_back(metadata); |
| } |
| } |
| |
| return {sensors, sensorNames}; |
| } |
| |
| std::vector<LabeledSensorInfo> |
| TriggerFactory::getLabeledSensorsInfo(boost::asio::yield_context& yield, |
| const SensorsInfo& sensorsInfo) const |
| { |
| auto tree = utils::getSubTreeSensors(yield, bus); |
| |
| return utils::transform(sensorsInfo, [&tree](const auto& item) { |
| const auto& [sensorPath, metadata] = item; |
| auto found = std::find_if( |
| tree.begin(), tree.end(), |
| [path = sensorPath](const auto& x) { return x.first == path; }); |
| |
| if (tree.end() != found) |
| { |
| const auto& [service, ifaces] = found->second.front(); |
| return LabeledSensorInfo(service, sensorPath, metadata); |
| } |
| throw std::runtime_error("Not found"); |
| }); |
| } |