blob: 98cfefeae598dc2637d1dee75eedcd812da11b2e [file] [log] [blame]
Wludzik, Jozef76833cb2020-12-21 14:42:41 +01001#include "trigger_factory.hpp"
2
Szymon Dompkef763c9e2021-03-12 09:19:22 +01003#include "discrete_threshold.hpp"
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01004#include "numeric_threshold.hpp"
Szymon Dompkef763c9e2021-03-12 09:19:22 +01005#include "on_change_threshold.hpp"
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01006#include "sensor.hpp"
Wludzik, Jozef76833cb2020-12-21 14:42:41 +01007#include "trigger.hpp"
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +01008#include "trigger_actions.hpp"
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01009#include "utils/dbus_mapper.hpp"
Cezary Zwolak4416fce2021-03-17 03:21:06 +010010#include "utils/transform.hpp"
11
12namespace ts = utils::tstring;
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010013
14TriggerFactory::TriggerFactory(
15 std::shared_ptr<sdbusplus::asio::connection> bus,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010016 std::shared_ptr<sdbusplus::asio::object_server> objServer,
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010017 SensorCache& sensorCache, interfaces::ReportManager& reportManager) :
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010018 bus(std::move(bus)),
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010019 objServer(std::move(objServer)), sensorCache(sensorCache),
20 reportManager(reportManager)
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010021{}
22
Cezary Zwolak4416fce2021-03-17 03:21:06 +010023std::unique_ptr<interfaces::Trigger> TriggerFactory::make(
Szymon Dompke20013012021-07-23 09:54:20 +020024 const std::string& name, const std::vector<std::string>& triggerActionsIn,
Cezary Zwolak4416fce2021-03-17 03:21:06 +010025 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
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010030{
Cezary Zwolak4416fce2021-03-17 03:21:06 +010031 const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo);
Szymon Dompke20013012021-07-23 09:54:20 +020032 std::vector<TriggerAction> triggerActions;
33 std::transform(triggerActionsIn.begin(), triggerActionsIn.end(),
34 std::back_inserter(triggerActions),
35 [](auto& triggerActionStr) {
36 return stringToTriggerAction(triggerActionStr);
37 });
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010038 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
39
Szymon Dompke20013012021-07-23 09:54:20 +020040 if (isTriggerThresholdDiscrete(labeledThresholdParams))
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010041 {
Cezary Zwolak4416fce2021-03-17 03:21:06 +010042 const auto& labeledDiscreteThresholdParams =
43 std::get<std::vector<discrete::LabeledThresholdParam>>(
44 labeledThresholdParams);
45 for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010046 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010047 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Cezary Zwolak4416fce2021-03-17 03:21:06 +010048
49 std::string thresholdName =
50 labeledThresholdParam.at_label<ts::UserId>();
51 discrete::Severity severity =
52 labeledThresholdParam.at_label<ts::Severity>();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000053 auto dwellTime =
54 Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>());
Szymon Dompke9f346792021-07-14 21:07:11 +020055 std::string thresholdValue =
Cezary Zwolak4416fce2021-03-17 03:21:06 +010056 labeledThresholdParam.at_label<ts::ThresholdValue>();
57
Szymon Dompke20013012021-07-23 09:54:20 +020058 action::discrete::fillActions(actions, triggerActions, severity,
59 reportManager, reportNames);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010060
Szymon Dompkef763c9e2021-03-12 09:19:22 +010061 thresholds.emplace_back(std::make_shared<DiscreteThreshold>(
62 bus->get_io_context(), sensors, sensorNames, std::move(actions),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000063 Milliseconds(dwellTime), std::stod(thresholdValue),
Szymon Dompkef763c9e2021-03-12 09:19:22 +010064 thresholdName));
65 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +010066 if (labeledDiscreteThresholdParams.empty())
Szymon Dompkef763c9e2021-03-12 09:19:22 +010067 {
68 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Szymon Dompke20013012021-07-23 09:54:20 +020069 action::discrete::onChange::fillActions(actions, triggerActions,
70 reportManager, reportNames);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010071
72 thresholds.emplace_back(std::make_shared<OnChangeThreshold>(
73 sensors, sensorNames, std::move(actions)));
74 }
75 }
76 else
77 {
Cezary Zwolak4416fce2021-03-17 03:21:06 +010078 const auto& labeledNumericThresholdParams =
79 std::get<std::vector<numeric::LabeledThresholdParam>>(
80 labeledThresholdParams);
81
82 for (const auto& labeledThresholdParam : labeledNumericThresholdParams)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010083 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010084 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Cezary Zwolak4416fce2021-03-17 03:21:06 +010085 auto type = labeledThresholdParam.at_label<ts::Type>();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000086 auto dwellTime =
87 Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>());
Cezary Zwolak4416fce2021-03-17 03:21:06 +010088 auto direction = labeledThresholdParam.at_label<ts::Direction>();
89 auto thresholdValue =
90 double{labeledThresholdParam.at_label<ts::ThresholdValue>()};
91
Szymon Dompke20013012021-07-23 09:54:20 +020092 action::numeric::fillActions(actions, triggerActions, type,
93 thresholdValue, reportManager,
94 reportNames);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010095
96 thresholds.emplace_back(std::make_shared<NumericThreshold>(
97 bus->get_io_context(), sensors, sensorNames, std::move(actions),
Cezary Zwolak4416fce2021-03-17 03:21:06 +010098 dwellTime, direction, thresholdValue));
Szymon Dompkef763c9e2021-03-12 09:19:22 +010099 }
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100100 }
101
102 return std::make_unique<Trigger>(
Szymon Dompke20013012021-07-23 09:54:20 +0200103 bus->get_io_context(), objServer, name, triggerActionsIn, reportNames,
104 labeledSensorsInfo, labeledThresholdParams, std::move(thresholds),
105 triggerManager, triggerStorage);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100106}
107
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000108std::pair<Sensors, std::vector<std::string>> TriggerFactory::getSensors(
109 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100110{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000111 Sensors sensors;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100112 std::vector<std::string> sensorNames;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100113
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100114 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
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100120 sensors.emplace_back(sensorCache.makeSensor<Sensor>(
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100121 service, sensorPath, bus->get_io_context(), bus));
122
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100123 if (metadata.empty())
124 {
125 sensorNames.emplace_back(sensorPath);
126 }
127 else
128 {
129 sensorNames.emplace_back(metadata);
130 }
131 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100132
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100133 return {sensors, sensorNames};
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100134}
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100135
136std::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}