| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #pragma once
- #include <string>
- #include <functional>
- #include "Arduino.h"
- #include "esphome/core/optional.h"
- namespace esphome {
- /** Default setup priorities for components of different types.
- *
- * Components should return one of these setup priorities in get_setup_priority.
- */
- namespace setup_priority {
- /// For communication buses like i2c/spi
- extern const float BUS;
- /// For components that represent GPIO pins like PCF8573
- extern const float IO;
- /// For components that deal with hardware and are very important like GPIO switch
- extern const float HARDWARE;
- /// For components that import data from directly connected sensors like DHT.
- extern const float DATA;
- /// Alias for DATA (here for compatability reasons)
- extern const float HARDWARE_LATE;
- /// For components that use data from sensors like displays
- extern const float PROCESSOR;
- extern const float WIFI;
- /// For components that should be initialized after WiFi is connected.
- extern const float AFTER_WIFI;
- /// For components that should be initialized after a data connection (API/MQTT) is connected.
- extern const float AFTER_CONNECTION;
- /// For components that should be initialized at the very end of the setup process.
- extern const float LATE;
- } // namespace setup_priority
- #define LOG_UPDATE_INTERVAL(this) \
- if (this->get_update_interval() < 100) { \
- ESP_LOGCONFIG(TAG, " Update Interval: %.3fs", this->get_update_interval() / 1000.0f); \
- } else { \
- ESP_LOGCONFIG(TAG, " Update Interval: %.1fs", this->get_update_interval() / 1000.0f); \
- }
- extern const uint32_t COMPONENT_STATE_MASK;
- extern const uint32_t COMPONENT_STATE_CONSTRUCTION;
- extern const uint32_t COMPONENT_STATE_SETUP;
- extern const uint32_t COMPONENT_STATE_LOOP;
- extern const uint32_t COMPONENT_STATE_FAILED;
- extern const uint32_t STATUS_LED_MASK;
- extern const uint32_t STATUS_LED_OK;
- extern const uint32_t STATUS_LED_WARNING;
- extern const uint32_t STATUS_LED_ERROR;
- class Component {
- public:
- /** Where the component's initialization should happen.
- *
- * Analogous to Arduino's setup(). This method is guaranteed to only be called once.
- * Defaults to doing nothing.
- */
- virtual void setup();
- /** This method will be called repeatedly.
- *
- * Analogous to Arduino's loop(). setup() is guaranteed to be called before this.
- * Defaults to doing nothing.
- */
- virtual void loop();
- virtual void dump_config();
- /** priority of setup(). higher -> executed earlier
- *
- * Defaults to 0.
- *
- * @return The setup priority of this component
- */
- virtual float get_setup_priority() const;
- float get_actual_setup_priority() const;
- void set_setup_priority(float priority);
- /** priority of loop(). higher -> executed earlier
- *
- * Defaults to 0.
- *
- * @return The loop priority of this component
- */
- virtual float get_loop_priority() const;
- void call();
- virtual void on_shutdown() {}
- virtual void on_safe_shutdown() {}
- uint32_t get_component_state() const;
- /** Mark this component as failed. Any future timeouts/intervals/setup/loop will no longer be called.
- *
- * This might be useful if a component wants to indicate that a connection to its peripheral failed.
- * For example, i2c based components can check if the remote device is responding and otherwise
- * mark the component as failed. Eventually this will also enable smart status LEDs.
- */
- virtual void mark_failed();
- bool is_failed();
- virtual bool can_proceed();
- bool status_has_warning();
- bool status_has_error();
- void status_set_warning();
- void status_set_error();
- void status_clear_warning();
- void status_clear_error();
- void status_momentary_warning(const std::string &name, uint32_t length = 5000);
- void status_momentary_error(const std::string &name, uint32_t length = 5000);
- bool has_overridden_loop() const;
- protected:
- virtual void call_loop();
- virtual void call_setup();
- /** Set an interval function with a unique name. Empty name means no cancelling possible.
- *
- * This will call f every interval ms. Can be cancelled via CancelInterval().
- * Similar to javascript's setInterval().
- *
- * IMPORTANT: Do not rely on this having correct timing. This is only called from
- * loop() and therefore can be significantly delay. If you need exact timing please
- * use hardware timers.
- *
- * @param name The identifier for this interval function.
- * @param interval The interval in ms.
- * @param f The function (or lambda) that should be called
- *
- * @see cancel_interval()
- */
- void set_interval(const std::string &name, uint32_t interval, std::function<void()> &&f); // NOLINT
- void set_interval(uint32_t interval, std::function<void()> &&f); // NOLINT
- /** Cancel an interval function.
- *
- * @param name The identifier for this interval function.
- * @return Whether an interval functions was deleted.
- */
- bool cancel_interval(const std::string &name); // NOLINT
- void set_timeout(uint32_t timeout, std::function<void()> &&f); // NOLINT
- /** Set a timeout function with a unique name.
- *
- * Similar to javascript's setTimeout(). Empty name means no cancelling possible.
- *
- * IMPORTANT: Do not rely on this having correct timing. This is only called from
- * loop() and therefore can be significantly delay. If you need exact timing please
- * use hardware timers.
- *
- * @param name The identifier for this timeout function.
- * @param timeout The timeout in ms.
- * @param f The function (or lambda) that should be called
- *
- * @see cancel_timeout()
- */
- void set_timeout(const std::string &name, uint32_t timeout, std::function<void()> &&f); // NOLINT
- /** Cancel a timeout function.
- *
- * @param name The identifier for this timeout function.
- * @return Whether a timeout functions was deleted.
- */
- bool cancel_timeout(const std::string &name); // NOLINT
- /** Defer a callback to the next loop() call.
- *
- * If name is specified and a defer() object with the same name exists, the old one is first removed.
- *
- * @param name The name of the defer function.
- * @param f The callback.
- */
- void defer(const std::string &name, std::function<void()> &&f); // NOLINT
- /// Defer a callback to the next loop() call.
- void defer(std::function<void()> &&f); // NOLINT
- /// Cancel a defer callback using the specified name, name must not be empty.
- bool cancel_defer(const std::string &name); // NOLINT
- uint32_t component_state_{0x0000}; ///< State of this component.
- float setup_priority_override_{NAN};
- };
- /** This class simplifies creating components that periodically check a state.
- *
- * You basically just need to implement the update() function, it will be called every update_interval ms
- * after startup. Note that this class cannot guarantee a correct timing, as it's not using timers, just
- * a software polling feature with set_interval() from Component.
- */
- class PollingComponent : public Component {
- public:
- PollingComponent() : PollingComponent(0) {}
- /** Initialize this polling component with the given update interval in ms.
- *
- * @param update_interval The update interval in ms.
- */
- explicit PollingComponent(uint32_t update_interval);
- /** Manually set the update interval in ms for this polling object.
- *
- * Override this if you want to do some validation for the update interval.
- *
- * @param update_interval The update interval in ms.
- */
- virtual void set_update_interval(uint32_t update_interval);
- // ========== OVERRIDE METHODS ==========
- // (You'll only need this when creating your own custom sensor)
- virtual void update() = 0;
- // ========== INTERNAL METHODS ==========
- // (In most use cases you won't need these)
- void call_setup() override;
- /// Get the update interval in ms of this sensor
- virtual uint32_t get_update_interval() const;
- protected:
- uint32_t update_interval_;
- };
- /// Helper class that enables naming of objects so that it doesn't have to be re-implement every time.
- class Nameable {
- public:
- Nameable() : Nameable("") {}
- explicit Nameable(const std::string &name);
- const std::string &get_name() const;
- void set_name(const std::string &name);
- /// Get the sanitized name of this nameable as an ID. Caching it internally.
- const std::string &get_object_id();
- uint32_t get_object_id_hash();
- bool is_internal() const;
- void set_internal(bool internal);
- protected:
- virtual uint32_t hash_base() = 0;
- void calc_object_id_();
- std::string name_;
- std::string object_id_;
- uint32_t object_id_hash_;
- bool internal_{false};
- };
- } // namespace esphome
|