#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 bus, std::shared_ptr objServer, SensorCache& sensorCache, interfaces::ReportManager& reportManager) : bus(std::move(bus)), objServer(std::move(objServer)), sensorCache(sensorCache), reportManager(reportManager) {} std::unique_ptr TriggerFactory::make( const std::string& id, const std::string& name, const std::vector& triggerActionsIn, const std::vector& reportIds, interfaces::TriggerManager& triggerManager, interfaces::JsonStorage& triggerStorage, const LabeledTriggerThresholdParams& labeledThresholdParams, const std::vector& labeledSensorsInfo) const { const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo); std::vector triggerActions; std::transform(triggerActionsIn.begin(), triggerActionsIn.end(), std::back_inserter(triggerActions), [](const auto& triggerActionStr) { return toTriggerAction(triggerActionStr); }); std::vector> thresholds; if (isTriggerThresholdDiscrete(labeledThresholdParams)) { const auto& labeledDiscreteThresholdParams = std::get>( labeledThresholdParams); for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams) { std::vector> actions; std::string thresholdName = labeledThresholdParam.at_label(); discrete::Severity severity = labeledThresholdParam.at_label(); auto dwellTime = Milliseconds(labeledThresholdParam.at_label()); std::string thresholdValue = labeledThresholdParam.at_label(); action::discrete::fillActions(actions, triggerActions, severity, reportManager, reportIds); thresholds.emplace_back(std::make_shared( bus->get_io_context(), sensors, sensorNames, std::move(actions), Milliseconds(dwellTime), std::stod(thresholdValue), thresholdName)); } if (labeledDiscreteThresholdParams.empty()) { std::vector> actions; action::discrete::onChange::fillActions(actions, triggerActions, reportManager, reportIds); thresholds.emplace_back(std::make_shared( sensors, sensorNames, std::move(actions))); } } else { const auto& labeledNumericThresholdParams = std::get>( labeledThresholdParams); for (const auto& labeledThresholdParam : labeledNumericThresholdParams) { std::vector> actions; auto type = labeledThresholdParam.at_label(); auto dwellTime = Milliseconds(labeledThresholdParam.at_label()); auto direction = labeledThresholdParam.at_label(); auto thresholdValue = double{labeledThresholdParam.at_label()}; action::numeric::fillActions(actions, triggerActions, type, thresholdValue, reportManager, reportIds); thresholds.emplace_back(std::make_shared( bus->get_io_context(), sensors, sensorNames, std::move(actions), dwellTime, direction, thresholdValue)); } } return std::make_unique( bus->get_io_context(), objServer, id, name, triggerActionsIn, reportIds, labeledSensorsInfo, labeledThresholdParams, std::move(thresholds), triggerManager, triggerStorage); } std::pair> TriggerFactory::getSensors( const std::vector& labeledSensorsInfo) const { Sensors sensors; std::vector sensorNames; for (const auto& labeledSensorInfo : labeledSensorsInfo) { const auto& service = labeledSensorInfo.at_label(); const auto& sensorPath = labeledSensorInfo.at_label(); const auto& metadata = labeledSensorInfo.at_label(); sensors.emplace_back(sensorCache.makeSensor( 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 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"); }); }