blob: 3114e9af77bc7978108bbdf3d86aee04e8568b31 [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"
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010010
11TriggerFactory::TriggerFactory(
12 std::shared_ptr<sdbusplus::asio::connection> bus,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010013 std::shared_ptr<sdbusplus::asio::object_server> objServer,
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010014 SensorCache& sensorCache, interfaces::ReportManager& reportManager) :
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010015 bus(std::move(bus)),
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010016 objServer(std::move(objServer)), sensorCache(sensorCache),
17 reportManager(reportManager)
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010018{}
19
20std::unique_ptr<interfaces::Trigger> TriggerFactory::make(
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010021 boost::asio::yield_context& yield, const std::string& name, bool isDiscrete,
22 bool logToJournal, bool logToRedfish, bool updateReport,
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010023 const std::vector<std::pair<sdbusplus::message::object_path, std::string>>&
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010024 sensorPaths,
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010025 const std::vector<std::string>& reportNames,
26 const TriggerThresholdParams& thresholdParams,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010027 interfaces::TriggerManager& triggerManager) const
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010028{
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010029 auto [sensors, sensorNames] = getSensors(yield, sensorPaths);
30 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
31
Szymon Dompkef763c9e2021-03-12 09:19:22 +010032 if (isDiscrete)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010033 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010034 const auto& params =
35 std::get<std::vector<discrete::ThresholdParam>>(thresholdParams);
36 for (const auto& [thresholdName, severityStr, dwellTime,
37 thresholdValue] : params)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010038 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010039 discrete::Severity severity =
40 discrete::stringToSeverity(severityStr);
41 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
42 if (logToJournal)
43 {
44 actions.emplace_back(
45 std::make_unique<action::discrete::LogToJournal>(severity));
46 }
47 if (logToRedfish)
48 {
49 actions.emplace_back(
50 std::make_unique<action::discrete::LogToRedfish>(severity));
51 }
52 if (updateReport)
53 {
54 actions.emplace_back(std::make_unique<action::UpdateReport>(
55 reportManager, reportNames));
56 }
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010057
Szymon Dompkef763c9e2021-03-12 09:19:22 +010058 thresholds.emplace_back(std::make_shared<DiscreteThreshold>(
59 bus->get_io_context(), sensors, sensorNames, std::move(actions),
60 std::chrono::milliseconds(dwellTime), thresholdValue,
61 thresholdName));
62 }
63 if (params.empty())
64 {
65 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
66 if (logToJournal)
67 {
68 actions.emplace_back(
69 std::make_unique<
70 action::discrete::onChange::LogToJournal>());
71 }
72 if (logToRedfish)
73 {
74 actions.emplace_back(
75 std::make_unique<
76 action::discrete::onChange::LogToRedfish>());
77 }
78 if (updateReport)
79 {
80 actions.emplace_back(std::make_unique<action::UpdateReport>(
81 reportManager, reportNames));
82 }
83
84 thresholds.emplace_back(std::make_shared<OnChangeThreshold>(
85 sensors, sensorNames, std::move(actions)));
86 }
87 }
88 else
89 {
90 const auto& params =
91 std::get<std::vector<numeric::ThresholdParam>>(thresholdParams);
92 for (const auto& [typeStr, dwellTime, directionStr, value] : params)
93 {
94 numeric::Type type = numeric::stringToType(typeStr);
95 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
96 if (logToJournal)
97 {
98 actions.emplace_back(
99 std::make_unique<action::numeric::LogToJournal>(type,
100 value));
101 }
102 if (logToRedfish)
103 {
104 actions.emplace_back(
105 std::make_unique<action::numeric::LogToRedfish>(type,
106 value));
107 }
108 if (updateReport)
109 {
110 actions.emplace_back(std::make_unique<action::UpdateReport>(
111 reportManager, reportNames));
112 }
113
114 thresholds.emplace_back(std::make_shared<NumericThreshold>(
115 bus->get_io_context(), sensors, sensorNames, std::move(actions),
116 std::chrono::milliseconds(dwellTime),
117 numeric::stringToDirection(directionStr), value));
118 }
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100119 }
120
121 return std::make_unique<Trigger>(
122 bus->get_io_context(), objServer, name, isDiscrete, logToJournal,
123 logToRedfish, updateReport, sensorPaths, reportNames, thresholdParams,
124 std::move(thresholds), triggerManager);
125}
126
127std::pair<std::vector<std::shared_ptr<interfaces::Sensor>>,
128 std::vector<std::string>>
129 TriggerFactory::getSensors(
130 boost::asio::yield_context& yield,
131 const std::vector<std::pair<sdbusplus::message::object_path,
132 std::string>>& sensorPaths) const
133{
134 auto tree = utils::getSubTreeSensors(yield, bus);
135
136 std::vector<std::shared_ptr<interfaces::Sensor>> sensors;
137 std::vector<std::string> sensorNames;
138 for (const auto& [sensorPath, metadata] : sensorPaths)
139 {
140 auto found = std::find_if(
141 tree.begin(), tree.end(),
142 [&sensorPath](const auto& x) { return x.first == sensorPath; });
143 if (found == tree.end())
144 {
145 throw std::runtime_error("Not found");
146 }
147
148 const auto& service = found->second[0].first;
149 const auto& path = found->first;
150 sensors.emplace_back(sensorCache.makeSensor<Sensor>(
151 service, path, bus->get_io_context(), bus));
152 if (metadata.empty())
153 {
154 sensorNames.emplace_back(sensorPath);
155 }
156 else
157 {
158 sensorNames.emplace_back(metadata);
159 }
160 }
161 return {sensors, sensorNames};
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100162}