blob: 8980cc948a13be546a7a1a028203e26cda83d098 [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 Dompkee28aa532021-10-27 12:33:12 +020024 const std::string& id, const std::string& name,
25 const std::vector<std::string>& triggerActionsIn,
Cezary Zwolak4416fce2021-03-17 03:21:06 +010026 const std::vector<std::string>& reportNames,
27 interfaces::TriggerManager& triggerManager,
28 interfaces::JsonStorage& triggerStorage,
29 const LabeledTriggerThresholdParams& labeledThresholdParams,
30 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010031{
Cezary Zwolak4416fce2021-03-17 03:21:06 +010032 const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo);
Szymon Dompke20013012021-07-23 09:54:20 +020033 std::vector<TriggerAction> triggerActions;
34 std::transform(triggerActionsIn.begin(), triggerActionsIn.end(),
35 std::back_inserter(triggerActions),
36 [](auto& triggerActionStr) {
37 return stringToTriggerAction(triggerActionStr);
38 });
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010039 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
40
Szymon Dompke20013012021-07-23 09:54:20 +020041 if (isTriggerThresholdDiscrete(labeledThresholdParams))
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010042 {
Cezary Zwolak4416fce2021-03-17 03:21:06 +010043 const auto& labeledDiscreteThresholdParams =
44 std::get<std::vector<discrete::LabeledThresholdParam>>(
45 labeledThresholdParams);
46 for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010047 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010048 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Cezary Zwolak4416fce2021-03-17 03:21:06 +010049
50 std::string thresholdName =
51 labeledThresholdParam.at_label<ts::UserId>();
52 discrete::Severity severity =
53 labeledThresholdParam.at_label<ts::Severity>();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000054 auto dwellTime =
55 Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>());
Szymon Dompke9f346792021-07-14 21:07:11 +020056 std::string thresholdValue =
Cezary Zwolak4416fce2021-03-17 03:21:06 +010057 labeledThresholdParam.at_label<ts::ThresholdValue>();
58
Szymon Dompke20013012021-07-23 09:54:20 +020059 action::discrete::fillActions(actions, triggerActions, severity,
60 reportManager, reportNames);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010061
Szymon Dompkef763c9e2021-03-12 09:19:22 +010062 thresholds.emplace_back(std::make_shared<DiscreteThreshold>(
63 bus->get_io_context(), sensors, sensorNames, std::move(actions),
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000064 Milliseconds(dwellTime), std::stod(thresholdValue),
Szymon Dompkef763c9e2021-03-12 09:19:22 +010065 thresholdName));
66 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +010067 if (labeledDiscreteThresholdParams.empty())
Szymon Dompkef763c9e2021-03-12 09:19:22 +010068 {
69 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Szymon Dompke20013012021-07-23 09:54:20 +020070 action::discrete::onChange::fillActions(actions, triggerActions,
71 reportManager, reportNames);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010072
73 thresholds.emplace_back(std::make_shared<OnChangeThreshold>(
74 sensors, sensorNames, std::move(actions)));
75 }
76 }
77 else
78 {
Cezary Zwolak4416fce2021-03-17 03:21:06 +010079 const auto& labeledNumericThresholdParams =
80 std::get<std::vector<numeric::LabeledThresholdParam>>(
81 labeledThresholdParams);
82
83 for (const auto& labeledThresholdParam : labeledNumericThresholdParams)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010084 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010085 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Cezary Zwolak4416fce2021-03-17 03:21:06 +010086 auto type = labeledThresholdParam.at_label<ts::Type>();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000087 auto dwellTime =
88 Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>());
Cezary Zwolak4416fce2021-03-17 03:21:06 +010089 auto direction = labeledThresholdParam.at_label<ts::Direction>();
90 auto thresholdValue =
91 double{labeledThresholdParam.at_label<ts::ThresholdValue>()};
92
Szymon Dompke20013012021-07-23 09:54:20 +020093 action::numeric::fillActions(actions, triggerActions, type,
94 thresholdValue, reportManager,
95 reportNames);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010096
97 thresholds.emplace_back(std::make_shared<NumericThreshold>(
98 bus->get_io_context(), sensors, sensorNames, std::move(actions),
Cezary Zwolak4416fce2021-03-17 03:21:06 +010099 dwellTime, direction, thresholdValue));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100100 }
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100101 }
102
103 return std::make_unique<Trigger>(
Szymon Dompkee28aa532021-10-27 12:33:12 +0200104 bus->get_io_context(), objServer, id, name, triggerActionsIn,
105 reportNames, labeledSensorsInfo, labeledThresholdParams,
106 std::move(thresholds), triggerManager, triggerStorage);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100107}
108
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000109std::pair<Sensors, std::vector<std::string>> TriggerFactory::getSensors(
110 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100111{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000112 Sensors sensors;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100113 std::vector<std::string> sensorNames;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100114
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100115 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::SensorMetadata>();
120
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100121 sensors.emplace_back(sensorCache.makeSensor<Sensor>(
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100122 service, sensorPath, bus->get_io_context(), bus));
123
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100124 if (metadata.empty())
125 {
126 sensorNames.emplace_back(sensorPath);
127 }
128 else
129 {
130 sensorNames.emplace_back(metadata);
131 }
132 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100133
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100134 return {sensors, sensorNames};
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100135}
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100136
137std::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}