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