1 #include "trigger_factory.hpp" 2 3 #include "discrete_threshold.hpp" 4 #include "numeric_threshold.hpp" 5 #include "on_change_threshold.hpp" 6 #include "sensor.hpp" 7 #include "trigger.hpp" 8 #include "trigger_actions.hpp" 9 #include "utils/dbus_mapper.hpp" 10 #include "utils/transform.hpp" 11 12 namespace ts = utils::tstring; 13 14 TriggerFactory::TriggerFactory( 15 std::shared_ptr<sdbusplus::asio::connection> bus, 16 std::shared_ptr<sdbusplus::asio::object_server> objServer, 17 SensorCache& sensorCache, interfaces::ReportManager& reportManager) : 18 bus(std::move(bus)), 19 objServer(std::move(objServer)), sensorCache(sensorCache), 20 reportManager(reportManager) 21 {} 22 23 std::unique_ptr<interfaces::Trigger> TriggerFactory::make( 24 const std::string& id, const std::string& name, 25 const std::vector<std::string>& triggerActionsIn, 26 const std::vector<std::string>& reportIds, 27 interfaces::TriggerManager& triggerManager, 28 interfaces::JsonStorage& triggerStorage, 29 const LabeledTriggerThresholdParams& labeledThresholdParams, 30 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const 31 { 32 const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo); 33 std::vector<TriggerAction> triggerActions; 34 std::transform(triggerActionsIn.begin(), triggerActionsIn.end(), 35 std::back_inserter(triggerActions), 36 [](auto& triggerActionStr) { 37 return toTriggerAction(triggerActionStr); 38 }); 39 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds; 40 41 if (isTriggerThresholdDiscrete(labeledThresholdParams)) 42 { 43 const auto& labeledDiscreteThresholdParams = 44 std::get<std::vector<discrete::LabeledThresholdParam>>( 45 labeledThresholdParams); 46 for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams) 47 { 48 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 49 50 std::string thresholdName = 51 labeledThresholdParam.at_label<ts::UserId>(); 52 discrete::Severity severity = 53 labeledThresholdParam.at_label<ts::Severity>(); 54 auto dwellTime = 55 Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>()); 56 std::string thresholdValue = 57 labeledThresholdParam.at_label<ts::ThresholdValue>(); 58 59 action::discrete::fillActions(actions, triggerActions, severity, 60 reportManager, reportIds); 61 62 thresholds.emplace_back(std::make_shared<DiscreteThreshold>( 63 bus->get_io_context(), sensors, sensorNames, std::move(actions), 64 Milliseconds(dwellTime), std::stod(thresholdValue), 65 thresholdName)); 66 } 67 if (labeledDiscreteThresholdParams.empty()) 68 { 69 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 70 action::discrete::onChange::fillActions(actions, triggerActions, 71 reportManager, reportIds); 72 73 thresholds.emplace_back(std::make_shared<OnChangeThreshold>( 74 sensors, sensorNames, std::move(actions))); 75 } 76 } 77 else 78 { 79 const auto& labeledNumericThresholdParams = 80 std::get<std::vector<numeric::LabeledThresholdParam>>( 81 labeledThresholdParams); 82 83 for (const auto& labeledThresholdParam : labeledNumericThresholdParams) 84 { 85 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 86 auto type = labeledThresholdParam.at_label<ts::Type>(); 87 auto dwellTime = 88 Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>()); 89 auto direction = labeledThresholdParam.at_label<ts::Direction>(); 90 auto thresholdValue = 91 double{labeledThresholdParam.at_label<ts::ThresholdValue>()}; 92 93 action::numeric::fillActions(actions, triggerActions, type, 94 thresholdValue, reportManager, 95 reportIds); 96 97 thresholds.emplace_back(std::make_shared<NumericThreshold>( 98 bus->get_io_context(), sensors, sensorNames, std::move(actions), 99 dwellTime, direction, thresholdValue)); 100 } 101 } 102 103 return std::make_unique<Trigger>( 104 bus->get_io_context(), objServer, id, name, triggerActionsIn, reportIds, 105 labeledSensorsInfo, labeledThresholdParams, std::move(thresholds), 106 triggerManager, triggerStorage); 107 } 108 109 std::pair<Sensors, std::vector<std::string>> TriggerFactory::getSensors( 110 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const 111 { 112 Sensors sensors; 113 std::vector<std::string> sensorNames; 114 115 for (const auto& labeledSensorInfo : labeledSensorsInfo) 116 { 117 const auto& service = labeledSensorInfo.at_label<ts::Service>(); 118 const auto& sensorPath = labeledSensorInfo.at_label<ts::SensorPath>(); 119 const auto& metadata = labeledSensorInfo.at_label<ts::Metadata>(); 120 121 sensors.emplace_back(sensorCache.makeSensor<Sensor>( 122 service, sensorPath, metadata, bus->get_io_context(), bus)); 123 124 if (metadata.empty()) 125 { 126 sensorNames.emplace_back(sensorPath); 127 } 128 else 129 { 130 sensorNames.emplace_back(metadata); 131 } 132 } 133 134 return {sensors, sensorNames}; 135 } 136 137 std::vector<LabeledSensorInfo> 138 TriggerFactory::getLabeledSensorsInfo(boost::asio::yield_context& yield, 139 const SensorsInfo& sensorsInfo) const 140 { 141 auto tree = utils::getSubTreeSensors(yield, bus); 142 143 return utils::transform(sensorsInfo, [&tree](const auto& item) { 144 const auto& [sensorPath, metadata] = item; 145 auto found = std::find_if( 146 tree.begin(), tree.end(), 147 [&sensorPath](const auto& x) { return x.first == sensorPath; }); 148 149 if (tree.end() != found) 150 { 151 const auto& [service, ifaces] = found->second.front(); 152 return LabeledSensorInfo(service, sensorPath, metadata); 153 } 154 throw std::runtime_error("Not found"); 155 }); 156 } 157