1 #include "discrete_threshold.hpp"
2
3 #include "utils/conversion_trigger.hpp"
4 #include "utils/to_short_enum.hpp"
5
6 #include <phosphor-logging/log.hpp>
7
DiscreteThreshold(boost::asio::io_context & ioc,const std::string & triggerIdIn,Sensors sensorsIn,std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,Milliseconds dwellTimeIn,const std::string & thresholdValueIn,const std::string & nameIn,const discrete::Severity severityIn,std::unique_ptr<interfaces::Clock> clockIn)8 DiscreteThreshold::DiscreteThreshold(
9 boost::asio::io_context& ioc, const std::string& triggerIdIn,
10 Sensors sensorsIn,
11 std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
12 Milliseconds dwellTimeIn, const std::string& thresholdValueIn,
13 const std::string& nameIn, const discrete::Severity severityIn,
14 std::unique_ptr<interfaces::Clock> clockIn) :
15 ioc(ioc), 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))
20 {
21 for (const auto& sensor : sensorsIn)
22 {
23 sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
24 }
25 }
26
initialize()27 void DiscreteThreshold::initialize()
28 {
29 ThresholdOperations::initialize(this);
30 }
31
updateSensors(Sensors newSensors)32 void DiscreteThreshold::updateSensors(Sensors newSensors)
33 {
34 ThresholdOperations::updateSensors(this, std::move(newSensors));
35 }
36
37 DiscreteThreshold::ThresholdDetail&
getDetails(const interfaces::Sensor & sensor)38 DiscreteThreshold::getDetails(const interfaces::Sensor& sensor)
39 {
40 return ThresholdOperations::getDetails(this, sensor);
41 }
42
43 std::shared_ptr<DiscreteThreshold::ThresholdDetail>
makeDetails(const std::string & sensorName)44 DiscreteThreshold::makeDetails(const std::string& sensorName)
45 {
46 return std::make_shared<ThresholdDetail>(sensorName, ioc);
47 }
48
sensorUpdated(interfaces::Sensor & sensor,Milliseconds timestamp,double value)49 void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
50 Milliseconds timestamp, double value)
51 {
52 auto& details = getDetails(sensor);
53 auto& dwell = details.dwell;
54 auto& timer = details.timer;
55
56 if (dwell && value != numericThresholdValue)
57 {
58 timer.cancel();
59 dwell = false;
60 }
61 else if (value == numericThresholdValue)
62 {
63 startTimer(details, value);
64 }
65 }
66
startTimer(DiscreteThreshold::ThresholdDetail & details,double value)67 void DiscreteThreshold::startTimer(DiscreteThreshold::ThresholdDetail& details,
68 double value)
69 {
70 auto& sensorName = details.getSensorName();
71 auto& dwell = details.dwell;
72 auto& timer = details.timer;
73
74 if (dwellTime == Milliseconds::zero())
75 {
76 commit(sensorName, value);
77 }
78 else
79 {
80 dwell = true;
81 timer.expires_after(dwellTime);
82 timer.async_wait([this, &sensorName, &dwell,
83 value](const boost::system::error_code ec) {
84 if (ec)
85 {
86 phosphor::logging::log<phosphor::logging::level::DEBUG>(
87 "Timer has been canceled");
88 return;
89 }
90 commit(sensorName, value);
91 dwell = false;
92 });
93 }
94 }
95
commit(const std::string & sensorName,double value)96 void DiscreteThreshold::commit(const std::string& sensorName, double value)
97 {
98 Milliseconds timestamp = clock->systemTimestamp();
99 for (const auto& action : actions)
100 {
101 action->commit(triggerId, std::cref(name), sensorName, timestamp,
102 thresholdValue);
103 }
104 }
105
getThresholdParam() const106 LabeledThresholdParam DiscreteThreshold::getThresholdParam() const
107 {
108 return discrete::LabeledThresholdParam(name, severity, dwellTime.count(),
109 thresholdValue);
110 }
111
getNonEmptyName(const std::string & nameIn) const112 std::string DiscreteThreshold::getNonEmptyName(const std::string& nameIn) const
113 {
114 if (nameIn.empty())
115 {
116 return std::string(utils::toShortEnum(utils::enumToString(severity))) +
117 " condition";
118 }
119 return nameIn;
120 }
121