1 #include "trigger_actions.hpp"
2
3 #include "messages/update_report_ind.hpp"
4 #include "types/trigger_types.hpp"
5 #include "utils/clock.hpp"
6 #include "utils/messanger.hpp"
7 #include "utils/to_short_enum.hpp"
8
9 #include <phosphor-logging/log.hpp>
10
11 #include <ctime>
12 #include <iomanip>
13 #include <sstream>
14
15 namespace action
16 {
17
18 namespace numeric
19 {
20
getDirection(double value,double threshold)21 static const char* getDirection(double value, double threshold)
22 {
23 if (value < threshold)
24 {
25 return "decreasing";
26 }
27 if (value > threshold)
28 {
29 return "increasing";
30 }
31 throw std::runtime_error("Invalid value");
32 }
33
getRedfishMessageId(const double value) const34 const char* LogToRedfishEventLog::getRedfishMessageId(const double value) const
35 {
36 std::string direction(getDirection(value, threshold));
37
38 if (direction == "decreasing")
39 {
40 switch (type)
41 {
42 case ::numeric::Type::upperCritical:
43 return redfish_message_ids::TriggerNumericBelowUpperCritical;
44 case ::numeric::Type::lowerCritical:
45 return redfish_message_ids::TriggerNumericBelowLowerCritical;
46 case ::numeric::Type::upperWarning:
47 return redfish_message_ids::TriggerNumericReadingNormal;
48 case ::numeric::Type::lowerWarning:
49 return redfish_message_ids::TriggerNumericBelowLowerWarning;
50 }
51 }
52
53 if (direction == "increasing")
54 {
55 switch (type)
56 {
57 case ::numeric::Type::upperCritical:
58 return redfish_message_ids::TriggerNumericAboveUpperCritical;
59 case ::numeric::Type::lowerCritical:
60 return redfish_message_ids::TriggerNumericAboveLowerCritical;
61 case ::numeric::Type::upperWarning:
62 return redfish_message_ids::TriggerNumericAboveUpperWarning;
63 case ::numeric::Type::lowerWarning:
64 return redfish_message_ids::TriggerNumericReadingNormal;
65 }
66 }
67
68 throw std::runtime_error("Invalid type");
69 }
70
commit(const std::string & triggerId,const ThresholdName thresholdNameInIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)71 void LogToRedfishEventLog::commit(
72 const std::string& triggerId, const ThresholdName thresholdNameInIn,
73 const std::string& sensorName, const Milliseconds timestamp,
74 const TriggerValue triggerValue)
75 {
76 double value = std::get<double>(triggerValue);
77 auto messageId = getRedfishMessageId(value);
78
79 if (std::string_view(messageId) ==
80 redfish_message_ids::TriggerNumericReadingNormal)
81 {
82 phosphor::logging::log<phosphor::logging::level::INFO>(
83 "Logging numeric trigger action to Redfish Event Log.",
84 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
85 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%s",
86 sensorName.c_str(), value,
87 triggerId.c_str()));
88 }
89 else
90 {
91 phosphor::logging::log<phosphor::logging::level::INFO>(
92 "Logging numeric trigger action to Redfish Event Log.",
93 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
94 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%f,%s",
95 sensorName.c_str(), value, threshold,
96 triggerId.c_str()));
97 }
98 }
99
fillActions(std::vector<std::unique_ptr<interfaces::TriggerAction>> & actionsIf,const std::vector<TriggerAction> & ActionsEnum,::numeric::Type type,double thresholdValue,boost::asio::io_context & ioc,const std::shared_ptr<std::vector<std::string>> & reportIds)100 void fillActions(
101 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
102 const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
103 double thresholdValue, boost::asio::io_context& ioc,
104 const std::shared_ptr<std::vector<std::string>>& reportIds)
105 {
106 actionsIf.reserve(ActionsEnum.size());
107 for (auto actionType : ActionsEnum)
108 {
109 switch (actionType)
110 {
111 case TriggerAction::LogToRedfishEventLog:
112 {
113 actionsIf.emplace_back(std::make_unique<LogToRedfishEventLog>(
114 type, thresholdValue));
115 break;
116 }
117 case TriggerAction::UpdateReport:
118 {
119 actionsIf.emplace_back(
120 std::make_unique<UpdateReport>(ioc, reportIds));
121 break;
122 }
123 }
124 }
125 }
126
127 } // namespace numeric
128
129 namespace discrete
130 {
131
commit(const std::string & triggerId,const ThresholdName thresholdNameIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)132 void LogToRedfishEventLog::commit(
133 const std::string& triggerId, const ThresholdName thresholdNameIn,
134 const std::string& sensorName, const Milliseconds timestamp,
135 const TriggerValue triggerValue)
136 {
137 auto value = std::get<std::string>(triggerValue);
138
139 phosphor::logging::log<phosphor::logging::level::INFO>(
140 "Logging discrete trigger action to Redfish Event Log.",
141 phosphor::logging::entry(
142 "REDFISH_MESSAGE_ID=%s",
143 redfish_message_ids::TriggerDiscreteConditionMet),
144 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
145 sensorName.c_str(), value.c_str(),
146 triggerId.c_str()));
147 }
148
fillActions(std::vector<std::unique_ptr<interfaces::TriggerAction>> & actionsIf,const std::vector<TriggerAction> & ActionsEnum,::discrete::Severity severity,boost::asio::io_context & ioc,const std::shared_ptr<std::vector<std::string>> & reportIds)149 void fillActions(
150 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
151 const std::vector<TriggerAction>& ActionsEnum,
152 ::discrete::Severity severity, boost::asio::io_context& ioc,
153 const std::shared_ptr<std::vector<std::string>>& reportIds)
154 {
155 actionsIf.reserve(ActionsEnum.size());
156 for (auto actionType : ActionsEnum)
157 {
158 switch (actionType)
159 {
160 case TriggerAction::LogToRedfishEventLog:
161 {
162 actionsIf.emplace_back(
163 std::make_unique<LogToRedfishEventLog>());
164 break;
165 }
166 case TriggerAction::UpdateReport:
167 {
168 actionsIf.emplace_back(
169 std::make_unique<UpdateReport>(ioc, reportIds));
170 break;
171 }
172 }
173 }
174 }
175
176 namespace onChange
177 {
178
commit(const std::string & triggerId,const ThresholdName thresholdNameIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)179 void LogToRedfishEventLog::commit(
180 const std::string& triggerId, const ThresholdName thresholdNameIn,
181 const std::string& sensorName, const Milliseconds timestamp,
182 const TriggerValue triggerValue)
183 {
184 auto value = triggerValueToString(triggerValue);
185
186 phosphor::logging::log<phosphor::logging::level::INFO>(
187 "Logging onChange discrete trigger action to Redfish Event Log.",
188 phosphor::logging::entry(
189 "REDFISH_MESSAGE_ID=%s",
190 redfish_message_ids::TriggerDiscreteConditionMet),
191 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
192 sensorName.c_str(), value.c_str(),
193 triggerId.c_str()));
194 }
195
fillActions(std::vector<std::unique_ptr<interfaces::TriggerAction>> & actionsIf,const std::vector<TriggerAction> & ActionsEnum,boost::asio::io_context & ioc,const std::shared_ptr<std::vector<std::string>> & reportIds)196 void fillActions(
197 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
198 const std::vector<TriggerAction>& ActionsEnum, boost::asio::io_context& ioc,
199 const std::shared_ptr<std::vector<std::string>>& reportIds)
200 {
201 actionsIf.reserve(ActionsEnum.size());
202 for (auto actionType : ActionsEnum)
203 {
204 switch (actionType)
205 {
206 case TriggerAction::LogToRedfishEventLog:
207 {
208 actionsIf.emplace_back(
209 std::make_unique<LogToRedfishEventLog>());
210 break;
211 }
212 case TriggerAction::UpdateReport:
213 {
214 actionsIf.emplace_back(
215 std::make_unique<UpdateReport>(ioc, reportIds));
216 break;
217 }
218 }
219 }
220 }
221 } // namespace onChange
222 } // namespace discrete
223
commit(const std::string & triggerId,const ThresholdName thresholdNameIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)224 void UpdateReport::commit(
225 const std::string& triggerId, const ThresholdName thresholdNameIn,
226 const std::string& sensorName, const Milliseconds timestamp,
227 const TriggerValue triggerValue)
228 {
229 if (reportIds->empty())
230 {
231 return;
232 }
233
234 utils::Messanger messanger(ioc);
235 messanger.send(messages::UpdateReportInd{*reportIds});
236 }
237 } // namespace action
238