blob: 2acb2bff739027dd8b71f32a305dd77ac1baa301 [file] [log] [blame]
Szymon Dompkef763c9e2021-03-12 09:19:22 +01001#include "discrete_threshold.hpp"
2
Szymon Dompkeaa572362022-03-23 16:31:24 +01003#include "utils/conversion_trigger.hpp"
4
Szymon Dompkef763c9e2021-03-12 09:19:22 +01005#include <phosphor-logging/log.hpp>
6
7DiscreteThreshold::DiscreteThreshold(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +02008 boost::asio::io_context& ioc, const std::string& triggerIdIn,
9 Sensors sensorsIn,
Szymon Dompkef763c9e2021-03-12 09:19:22 +010010 std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
Szymon Dompkeaa572362022-03-23 16:31:24 +010011 Milliseconds dwellTimeIn, const std::string& thresholdValueIn,
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020012 const std::string& nameIn, const discrete::Severity severityIn,
13 std::unique_ptr<interfaces::Clock> clockIn) :
Szymon Dompkef763c9e2021-03-12 09:19:22 +010014 ioc(ioc),
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020015 triggerId(triggerIdIn), actions(std::move(actionsIn)),
16 dwellTime(dwellTimeIn), thresholdValue(thresholdValueIn),
17 numericThresholdValue(utils::stodStrict(thresholdValue)),
18 severity(severityIn), name(getNonEmptyName(nameIn)),
19 clock(std::move(clockIn))
Szymon Dompkef763c9e2021-03-12 09:19:22 +010020{
Szymon Dompke94f71c52021-12-10 07:16:33 +010021 for (const auto& sensor : sensorsIn)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010022 {
Szymon Dompke94f71c52021-12-10 07:16:33 +010023 sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +010024 }
25}
26
27void DiscreteThreshold::initialize()
28{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020029 ThresholdOperations::initialize(this);
Szymon Dompke94f71c52021-12-10 07:16:33 +010030}
31
32void DiscreteThreshold::updateSensors(Sensors newSensors)
33{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020034 ThresholdOperations::updateSensors(this, std::move(newSensors));
Szymon Dompkef763c9e2021-03-12 09:19:22 +010035}
36
37DiscreteThreshold::ThresholdDetail&
Szymon Dompke94f71c52021-12-10 07:16:33 +010038 DiscreteThreshold::getDetails(const interfaces::Sensor& sensor)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010039{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020040 return ThresholdOperations::getDetails(this, sensor);
Szymon Dompke94f71c52021-12-10 07:16:33 +010041}
42
43std::shared_ptr<DiscreteThreshold::ThresholdDetail>
44 DiscreteThreshold::makeDetails(const std::string& sensorName)
45{
46 return std::make_shared<ThresholdDetail>(sensorName, false, ioc);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010047}
48
49void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010050 Milliseconds timestamp, double value)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010051{
Szymon Dompke94f71c52021-12-10 07:16:33 +010052 auto& details = getDetails(sensor);
53 auto& [sensorName, dwell, timer] = details;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010054
Szymon Dompkeaa572362022-03-23 16:31:24 +010055 if (dwell && value != numericThresholdValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010056 {
Szymon Dompkeaa572362022-03-23 16:31:24 +010057 timer.cancel();
58 dwell = false;
59 }
60 else if (value == numericThresholdValue)
61 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020062 startTimer(details, value);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010063 }
64}
65
Szymon Dompke94f71c52021-12-10 07:16:33 +010066void DiscreteThreshold::startTimer(DiscreteThreshold::ThresholdDetail& details,
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020067 double value)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010068{
Szymon Dompke94f71c52021-12-10 07:16:33 +010069 const auto& sensorName = details.sensorName;
70 auto& dwell = details.dwell;
71 auto& timer = details.timer;
72
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000073 if (dwellTime == Milliseconds::zero())
Szymon Dompkef763c9e2021-03-12 09:19:22 +010074 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020075 commit(sensorName, value);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010076 }
77 else
78 {
79 dwell = true;
80 timer.expires_after(dwellTime);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020081 timer.async_wait([this, &sensorName, &dwell,
Szymon Dompkef763c9e2021-03-12 09:19:22 +010082 value](const boost::system::error_code ec) {
83 if (ec)
84 {
85 phosphor::logging::log<phosphor::logging::level::DEBUG>(
86 "Timer has been canceled");
87 return;
88 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020089 commit(sensorName, value);
Szymon Dompkef763c9e2021-03-12 09:19:22 +010090 dwell = false;
91 });
92 }
93}
94
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020095void DiscreteThreshold::commit(const std::string& sensorName, double value)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010096{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020097 Milliseconds timestamp = clock->systemTimestamp();
Szymon Dompkef763c9e2021-03-12 09:19:22 +010098 for (const auto& action : actions)
99 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200100 action->commit(triggerId, std::cref(name), sensorName, timestamp,
101 thresholdValue);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100102 }
103}
Szymon Dompke94f71c52021-12-10 07:16:33 +0100104
105LabeledThresholdParam DiscreteThreshold::getThresholdParam() const
106{
107 return discrete::LabeledThresholdParam(name, severity, dwellTime.count(),
Szymon Dompkeaa572362022-03-23 16:31:24 +0100108 thresholdValue);
Szymon Dompke94f71c52021-12-10 07:16:33 +0100109}
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200110
111std::string DiscreteThreshold::getNonEmptyName(const std::string& nameIn) const
112{
113 if (nameIn.empty())
114 {
115 return discrete::severityToString(severity) + " condition";
116 }
117 return nameIn;
118}