ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
switch.cpp
Go to the documentation of this file.
1#include "switch.h"
4#include "esphome/core/log.h"
5
6namespace esphome::switch_ {
7
8ESPHOME_LOG_TAG(TAG, "switch");
9
10Switch::Switch() : state(false) {}
11
12void Switch::control(bool target_state) {
13 if (target_state) {
14 this->turn_on();
15 } else {
16 this->turn_off();
17 }
18}
20 ESP_LOGV(TAG, "'%s' Turning ON.", LOG_STR_ARG(this->get_log_name()));
21 this->write_state(!this->inverted_);
22}
24 ESP_LOGV(TAG, "'%s' Turning OFF.", LOG_STR_ARG(this->get_log_name()));
25 this->write_state(this->inverted_);
26}
28 ESP_LOGV(TAG, "'%s' Toggling %s.", LOG_STR_ARG(this->get_log_name()),
29 this->state ? LOG_STR_LITERAL("OFF") : LOG_STR_LITERAL("ON"));
30 this->write_state(this->inverted_ == this->state);
31}
32optional<bool> Switch::get_initial_state() {
34 return {};
35
36#ifdef USE_SWITCH_STORAGE
39 } else
40#endif
41 {
42 this->rtc_ = this->make_entity_preference<bool>();
43 }
44 bool initial_state;
45 if (!this->rtc_.load(&initial_state))
46 return {};
47 return initial_state;
48}
51 return {};
52 }
53 bool initial_state = restore_mode & RESTORE_MODE_ON_MASK; // default value *_OFF or *_ON
54 if (restore_mode & RESTORE_MODE_PERSISTENT_MASK) { // For RESTORE_*
55 optional<bool> restored_state = this->get_initial_state();
56 if (restored_state.has_value()) {
57 // Invert value if any of the *_INVERTED_* modes
58 initial_state = restore_mode & RESTORE_MODE_INVERTED_MASK ? !restored_state.value() : restored_state.value();
59 }
60 }
61 return initial_state;
62}
64 if (auto initial = this->get_initial_state_with_restore_mode())
65 this->control(*initial);
66}
67void Switch::restore(bool when_disabled) {
68 this->control(this->get_initial_state_with_restore_mode().value_or(when_disabled));
69}
71 if (!this->publish_dedup_.next(state))
72 return;
73 this->state = state != this->inverted_;
74 this->set_has_state(true);
75
77 this->rtc_.save(&this->state);
78
79 ESP_LOGV(TAG, "'%s' >> %s", LOG_STR_ARG(this->get_log_name()), ONOFF(this->state));
80 this->state_callback_.call(this->state);
81#if defined(USE_SWITCH) && defined(USE_CONTROLLER_REGISTRY)
82 ControllerRegistry::notify_switch_update(this);
83#endif
84}
85bool Switch::assumed_state() { return false; }
86
87void log_switch(const char *tag, const char *prefix, const char *type, Switch *obj) {
88 if (obj != nullptr) {
89 // Prepare restore mode string
90 const LogString *onoff = LOG_STR(""), *inverted = onoff, *restore;
92 restore = LOG_STR("disabled");
93 } else {
94 onoff = obj->restore_mode & RESTORE_MODE_ON_MASK ? LOG_STR("ON") : LOG_STR("OFF");
95 inverted = obj->restore_mode & RESTORE_MODE_INVERTED_MASK ? LOG_STR("inverted ") : LOG_STR("");
96 restore = obj->restore_mode & RESTORE_MODE_PERSISTENT_MASK ? LOG_STR("restore defaults to") : LOG_STR("always");
97 }
98
99 // Build the base message with mandatory fields
100 ESP_LOGCONFIG(tag,
101 "%s%s '%s'\n"
102 "%s Restore Mode: %s%s %s",
103 prefix, type, LOG_STR_ARG(obj->get_log_name()), prefix, LOG_STR_ARG(inverted), LOG_STR_ARG(restore),
104 LOG_STR_ARG(onoff));
105
106 // Add optional fields separately
107 LOG_ENTITY_ICON(tag, prefix, *obj);
108 if (obj->assumed_state()) {
109 ESP_LOGCONFIG(tag, "%s Assumed State: YES", prefix);
110 }
111 if (obj->is_inverted()) {
112 ESP_LOGCONFIG(tag, "%s Inverted: YES", prefix);
113 }
114 LOG_ENTITY_DEVICE_CLASS(tag, prefix, *obj);
115 }
116}
117
118} // namespace esphome::switch_
bool next(T value)
Feeds the next item in the series to the deduplicator and returns false if this is a duplicate.
Definition helpers.h:2048
const LogString * get_log_name() const
Get the name for a "%s" log argument (LOG_STR_ARG).
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
void set_has_state(bool state)
Base class for all switches.
Definition switch.h:43
void toggle()
Toggle this switch.
Definition switch.cpp:27
LazyCallbackManager< void(bool)> state_callback_
Definition switch.h:149
optional< bool > get_initial_state()
Returns the initial state of the switch, as persisted previously, or empty if never persisted.
Definition switch.cpp:32
void turn_on()
Turn this switch on.
Definition switch.cpp:19
void turn_off()
Turn this switch off.
Definition switch.cpp:23
bool state
The current reported state of the binary sensor.
Definition switch.h:60
virtual void write_state(bool state)=0
Write the given state to hardware.
SwitchRestoreMode restore_mode
Indicates whether or not state is to be retrieved from flash and how.
Definition switch.h:57
void restore()
Drive the switch to the state its restore mode yields, through control(), so inversion and write_stat...
Definition switch.cpp:63
void publish_state(bool state)
Publish a state to the front-end from the back-end.
Definition switch.cpp:70
virtual bool assumed_state()
Return whether this switch uses an assumed state - i.e.
Definition switch.cpp:85
optional< bool > get_initial_state_with_restore_mode()
Returns the initial state of the switch, after applying restore mode rules.
Definition switch.cpp:49
Deduplicator< bool > publish_dedup_
Definition switch.h:152
bool is_inverted() const
Definition switch.h:130
void control(bool target_state)
Control this switch using a boolean state value.
Definition switch.cpp:12
ESPPreferenceObject rtc_
Definition switch.h:146
uint8_t type
bool state
Definition fan.h:2
constexpr int RESTORE_MODE_ON_MASK
Definition switch.h:20
constexpr int RESTORE_MODE_STORAGE_MASK
Definition switch.h:26
constexpr int RESTORE_MODE_INVERTED_MASK
Definition switch.h:22
void log_switch(const char *tag, const char *prefix, const char *type, Switch *obj)
Definition switch.cpp:87
constexpr int RESTORE_MODE_STORAGE_FLASH_MASK
Definition switch.h:24
ESPHOME_LOG_TAG(TAG, "switch.binary_sensor")
constexpr int RESTORE_MODE_PERSISTENT_MASK
Definition switch.h:21
constexpr int RESTORE_MODE_DISABLED_MASK
Definition switch.h:23