#pragma once #include "interfaces/clock.hpp" #include "interfaces/sensor.hpp" #include "interfaces/sensor_listener.hpp" #include "interfaces/threshold.hpp" #include "interfaces/trigger_action.hpp" #include "types/duration_types.hpp" #include "types/trigger_types.hpp" #include "utils/threshold_operations.hpp" #include #include #include #include #include class DiscreteThreshold : public interfaces::Threshold, public interfaces::SensorListener, public std::enable_shared_from_this { public: DiscreteThreshold( boost::asio::io_context& ioc, const std::string& triggerId, Sensors sensors, std::vector> actions, Milliseconds dwellTime, const std::string& thresholdValue, const std::string& name, const discrete::Severity severity, std::unique_ptr clock); DiscreteThreshold(const DiscreteThreshold&) = delete; DiscreteThreshold(DiscreteThreshold&&) = delete; void initialize() override; void sensorUpdated(interfaces::Sensor&, Milliseconds, double) override; LabeledThresholdParam getThresholdParam() const override; void updateSensors(Sensors newSensors) override; private: boost::asio::io_context& ioc; const std::string& triggerId; const std::vector> actions; const Milliseconds dwellTime; const std::string thresholdValue; const double numericThresholdValue; const discrete::Severity severity; const std::string name; bool initialized = false; std::unique_ptr clock; struct ThresholdDetail { bool dwell = false; boost::asio::steady_timer timer; ThresholdDetail(const std::string& sensorNameIn, boost::asio::io_context& ioc) : timer(ioc), sensorName(sensorNameIn) {} ThresholdDetail(const ThresholdDetail&) = delete; ThresholdDetail(ThresholdDetail&&) = delete; const std::string& getSensorName() { return sensorName; } private: std::string sensorName; }; using SensorDetails = std::unordered_map, std::shared_ptr>; SensorDetails sensorDetails; friend ThresholdOperations; void startTimer(ThresholdDetail&, double); void commit(const std::string&, double); ThresholdDetail& getDetails(const interfaces::Sensor& sensor); std::shared_ptr makeDetails(const std::string& sensorName); std::string getNonEmptyName(const std::string& nameIn) const; };