blob: 6e2ad2173e7536849421975931eadb85b28a2f3d [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(
24 const std::string& name, bool isDiscrete, bool logToJournal,
25 bool logToRedfish, bool updateReport,
26 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);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010033 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
34
Szymon Dompkef763c9e2021-03-12 09:19:22 +010035 if (isDiscrete)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010036 {
Cezary Zwolak4416fce2021-03-17 03:21:06 +010037 const auto& labeledDiscreteThresholdParams =
38 std::get<std::vector<discrete::LabeledThresholdParam>>(
39 labeledThresholdParams);
40 for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010041 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010042 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Cezary Zwolak4416fce2021-03-17 03:21:06 +010043
44 std::string thresholdName =
45 labeledThresholdParam.at_label<ts::UserId>();
46 discrete::Severity severity =
47 labeledThresholdParam.at_label<ts::Severity>();
48 std::chrono::milliseconds dwellTime = std::chrono::milliseconds(
49 labeledThresholdParam.at_label<ts::DwellTime>());
Szymon Dompke9f346792021-07-14 21:07:11 +020050 std::string thresholdValue =
Cezary Zwolak4416fce2021-03-17 03:21:06 +010051 labeledThresholdParam.at_label<ts::ThresholdValue>();
52
Szymon Dompkef763c9e2021-03-12 09:19:22 +010053 if (logToJournal)
54 {
55 actions.emplace_back(
56 std::make_unique<action::discrete::LogToJournal>(severity));
57 }
58 if (logToRedfish)
59 {
60 actions.emplace_back(
61 std::make_unique<action::discrete::LogToRedfish>(severity));
62 }
63 if (updateReport)
64 {
65 actions.emplace_back(std::make_unique<action::UpdateReport>(
66 reportManager, reportNames));
67 }
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010068
Szymon Dompkef763c9e2021-03-12 09:19:22 +010069 thresholds.emplace_back(std::make_shared<DiscreteThreshold>(
70 bus->get_io_context(), sensors, sensorNames, std::move(actions),
Szymon Dompke9f346792021-07-14 21:07:11 +020071 std::chrono::milliseconds(dwellTime), std::stod(thresholdValue),
Szymon Dompkef763c9e2021-03-12 09:19:22 +010072 thresholdName));
73 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +010074 if (labeledDiscreteThresholdParams.empty())
Szymon Dompkef763c9e2021-03-12 09:19:22 +010075 {
76 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
77 if (logToJournal)
78 {
79 actions.emplace_back(
80 std::make_unique<
81 action::discrete::onChange::LogToJournal>());
82 }
83 if (logToRedfish)
84 {
85 actions.emplace_back(
86 std::make_unique<
87 action::discrete::onChange::LogToRedfish>());
88 }
89 if (updateReport)
90 {
91 actions.emplace_back(std::make_unique<action::UpdateReport>(
92 reportManager, reportNames));
93 }
94
95 thresholds.emplace_back(std::make_shared<OnChangeThreshold>(
96 sensors, sensorNames, std::move(actions)));
97 }
98 }
99 else
100 {
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100101 const auto& labeledNumericThresholdParams =
102 std::get<std::vector<numeric::LabeledThresholdParam>>(
103 labeledThresholdParams);
104
105 for (const auto& labeledThresholdParam : labeledNumericThresholdParams)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100106 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100107 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100108 auto type = labeledThresholdParam.at_label<ts::Type>();
109 auto dwellTime = std::chrono::milliseconds(
110 labeledThresholdParam.at_label<ts::DwellTime>());
111 auto direction = labeledThresholdParam.at_label<ts::Direction>();
112 auto thresholdValue =
113 double{labeledThresholdParam.at_label<ts::ThresholdValue>()};
114
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100115 if (logToJournal)
116 {
117 actions.emplace_back(
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100118 std::make_unique<action::numeric::LogToJournal>(
119 type, thresholdValue));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100120 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100121
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100122 if (logToRedfish)
123 {
124 actions.emplace_back(
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100125 std::make_unique<action::numeric::LogToRedfish>(
126 type, thresholdValue));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100127 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100128
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100129 if (updateReport)
130 {
131 actions.emplace_back(std::make_unique<action::UpdateReport>(
132 reportManager, reportNames));
133 }
134
135 thresholds.emplace_back(std::make_shared<NumericThreshold>(
136 bus->get_io_context(), sensors, sensorNames, std::move(actions),
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100137 dwellTime, direction, thresholdValue));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100138 }
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100139 }
140
141 return std::make_unique<Trigger>(
142 bus->get_io_context(), objServer, name, isDiscrete, logToJournal,
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100143 logToRedfish, updateReport, reportNames, labeledSensorsInfo,
144 labeledThresholdParams, std::move(thresholds), triggerManager,
145 triggerStorage);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100146}
147
148std::pair<std::vector<std::shared_ptr<interfaces::Sensor>>,
149 std::vector<std::string>>
150 TriggerFactory::getSensors(
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100151 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100152{
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100153 std::vector<std::shared_ptr<interfaces::Sensor>> sensors;
154 std::vector<std::string> sensorNames;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100155
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100156 for (const auto& labeledSensorInfo : labeledSensorsInfo)
157 {
158 const auto& service = labeledSensorInfo.at_label<ts::Service>();
159 const auto& sensorPath = labeledSensorInfo.at_label<ts::SensorPath>();
160 const auto& metadata = labeledSensorInfo.at_label<ts::SensorMetadata>();
161
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100162 sensors.emplace_back(sensorCache.makeSensor<Sensor>(
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100163 service, sensorPath, bus->get_io_context(), bus));
164
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100165 if (metadata.empty())
166 {
167 sensorNames.emplace_back(sensorPath);
168 }
169 else
170 {
171 sensorNames.emplace_back(metadata);
172 }
173 }
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100174
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100175 return {sensors, sensorNames};
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100176}
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100177
178std::vector<LabeledSensorInfo>
179 TriggerFactory::getLabeledSensorsInfo(boost::asio::yield_context& yield,
180 const SensorsInfo& sensorsInfo) const
181{
182 auto tree = utils::getSubTreeSensors(yield, bus);
183
184 return utils::transform(sensorsInfo, [&tree](const auto& item) {
185 const auto& [sensorPath, metadata] = item;
186 auto found = std::find_if(
187 tree.begin(), tree.end(),
188 [&sensorPath](const auto& x) { return x.first == sensorPath; });
189
190 if (tree.end() != found)
191 {
192 const auto& [service, ifaces] = found->second.front();
193 return LabeledSensorInfo(service, sensorPath, metadata);
194 }
195 throw std::runtime_error("Not found");
196 });
197}