1 #pragma once
2 
3 #include "interfaces/clock.hpp"
4 #include "interfaces/sensor.hpp"
5 #include "interfaces/sensor_listener.hpp"
6 #include "interfaces/threshold.hpp"
7 #include "interfaces/trigger_action.hpp"
8 #include "types/duration_types.hpp"
9 #include "types/trigger_types.hpp"
10 #include "utils/threshold_operations.hpp"
11 
12 #include <boost/asio/steady_timer.hpp>
13 
14 #include <chrono>
15 #include <map>
16 #include <memory>
17 #include <vector>
18 
19 class NumericThreshold :
20     public interfaces::Threshold,
21     public interfaces::SensorListener,
22     public std::enable_shared_from_this<NumericThreshold>
23 {
24   public:
25     NumericThreshold(
26         boost::asio::io_context& ioc, const std::string& triggerId,
27         Sensors sensors,
28         std::vector<std::unique_ptr<interfaces::TriggerAction>> actions,
29         Milliseconds dwellTime, numeric::Direction direction,
30         double thresholdValue, numeric::Type type,
31         std::unique_ptr<interfaces::Clock> clock);
32     NumericThreshold(const NumericThreshold&) = delete;
33     NumericThreshold(NumericThreshold&&) = delete;
34 
35     void initialize() override;
36     void sensorUpdated(interfaces::Sensor&, Milliseconds, double) override;
37     LabeledThresholdParam getThresholdParam() const override;
38     void updateSensors(Sensors newSensors) override;
39 
40   private:
41     boost::asio::io_context& ioc;
42     const std::string& triggerId;
43     const std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
44     const Milliseconds dwellTime;
45     const numeric::Direction direction;
46     const double thresholdValue;
47     const numeric::Type type;
48     bool initialized = false;
49     std::unique_ptr<interfaces::Clock> clock;
50 
51     struct ThresholdDetail
52     {
53         std::optional<double> prevValue = std::nullopt;
54         numeric::Direction prevDirection = numeric::Direction::either;
55         bool dwell = false;
56         boost::asio::steady_timer timer;
57 
58         ThresholdDetail(const std::string& sensorNameIn,
59                         boost::asio::io_context& ioc) :
60             timer(ioc),
61             sensorName(sensorNameIn)
62         {}
63         ThresholdDetail(const ThresholdDetail&) = delete;
64         ThresholdDetail(ThresholdDetail&&) = delete;
65 
66         const std::string& getSensorName()
67         {
68             return sensorName;
69         }
70 
71       private:
72         std::string sensorName;
73     };
74     using SensorDetails =
75         std::unordered_map<std::shared_ptr<interfaces::Sensor>,
76                            std::shared_ptr<ThresholdDetail>>;
77     SensorDetails sensorDetails;
78 
79     friend ThresholdOperations;
80 
81     void startTimer(ThresholdDetail&, double);
82     void commit(const std::string&, double);
83     ThresholdDetail& getDetails(const interfaces::Sensor& sensor);
84     std::shared_ptr<ThresholdDetail> makeDetails(const std::string& sensorName);
85 };
86