esphome 2025.6.0b1__py3-none-any.whl → 2025.6.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/components/api/api_connection.cpp +53 -33
- esphome/components/api/api_connection.h +24 -25
- esphome/components/api/api_pb2.cpp +1 -0
- esphome/components/api/api_pb2.h +65 -226
- esphome/components/api/client.py +1 -3
- esphome/components/api/proto.h +1 -1
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +1 -1
- esphome/components/bme280_base/bme280_base.cpp +2 -3
- esphome/components/datetime/date_entity.cpp +5 -5
- esphome/components/datetime/datetime_base.h +0 -5
- esphome/components/datetime/datetime_entity.cpp +8 -8
- esphome/components/datetime/time_entity.cpp +4 -4
- esphome/components/esp32/__init__.py +30 -3
- esphome/components/esp32_ble/ble.cpp +90 -45
- esphome/components/esp32_ble/ble.h +24 -5
- esphome/components/esp32_ble/ble_event.h +172 -32
- esphome/components/esp32_ble/ble_scan_result.h +24 -0
- esphome/components/esp32_ble/queue.h +53 -27
- esphome/components/esp32_ble_tracker/__init__.py +1 -0
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +95 -66
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +16 -16
- esphome/components/esp32_camera/esp32_camera.cpp +1 -1
- esphome/components/fan/fan.cpp +26 -17
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +12 -9
- esphome/components/kmeteriso/kmeteriso.cpp +2 -3
- esphome/components/logger/logger.cpp +2 -15
- esphome/components/logger/logger.h +1 -2
- esphome/components/mqtt/mqtt_component.cpp +1 -1
- esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
- esphome/components/nextion/nextion_upload_arduino.cpp +12 -9
- esphome/components/nextion/nextion_upload_idf.cpp +11 -9
- esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
- esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
- esphome/components/number/number.cpp +1 -1
- esphome/components/number/number.h +0 -4
- esphome/components/prometheus/__init__.py +0 -1
- esphome/components/select/select.cpp +1 -1
- esphome/components/select/select.h +0 -4
- esphome/components/sensor/sensor.cpp +8 -4
- esphome/components/sensor/sensor.h +3 -6
- esphome/components/status_led/light/status_led_light.cpp +2 -2
- esphome/components/status_led/light/status_led_light.h +1 -1
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +14 -9
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +1 -0
- esphome/components/text/text.cpp +1 -1
- esphome/components/text/text.h +0 -4
- esphome/components/text_sensor/text_sensor.cpp +8 -4
- esphome/components/text_sensor/text_sensor.h +6 -6
- esphome/components/update/update_entity.cpp +1 -1
- esphome/components/update/update_entity.h +0 -3
- esphome/components/uptime/sensor/uptime_timestamp_sensor.cpp +1 -1
- esphome/components/web_server_idf/__init__.py +0 -2
- esphome/components/web_server_idf/web_server_idf.cpp +6 -2
- esphome/components/web_server_idf/web_server_idf.h +7 -0
- esphome/components/weikai/weikai.cpp +1 -1
- esphome/const.py +1 -1
- esphome/core/application.cpp +14 -8
- esphome/core/application.h +7 -7
- esphome/core/component.cpp +36 -15
- esphome/core/component.h +30 -13
- esphome/core/entity_base.cpp +4 -16
- esphome/core/entity_base.h +27 -13
- esphome/core/helpers.h +1 -1
- esphome/wizard.py +0 -16
- {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b2.dist-info}/METADATA +2 -2
- {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b2.dist-info}/RECORD +71 -70
- {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b2.dist-info}/top_level.txt +0 -0
@@ -6,6 +6,7 @@
|
|
6
6
|
#include "esphome/core/helpers.h"
|
7
7
|
|
8
8
|
#include <array>
|
9
|
+
#include <atomic>
|
9
10
|
#include <string>
|
10
11
|
#include <vector>
|
11
12
|
|
@@ -62,7 +63,7 @@ class ESPBLEiBeacon {
|
|
62
63
|
|
63
64
|
class ESPBTDevice {
|
64
65
|
public:
|
65
|
-
void parse_scan_rst(const
|
66
|
+
void parse_scan_rst(const BLEScanResult &scan_result);
|
66
67
|
|
67
68
|
std::string address_str() const;
|
68
69
|
|
@@ -84,8 +85,6 @@ class ESPBTDevice {
|
|
84
85
|
|
85
86
|
const std::vector<ServiceData> &get_service_datas() const { return service_datas_; }
|
86
87
|
|
87
|
-
const esp_ble_gap_cb_param_t::ble_scan_result_evt_param &get_scan_result() const { return scan_result_; }
|
88
|
-
|
89
88
|
bool resolve_irk(const uint8_t *irk) const;
|
90
89
|
|
91
90
|
optional<ESPBLEiBeacon> get_ibeacon() const {
|
@@ -98,7 +97,7 @@ class ESPBTDevice {
|
|
98
97
|
}
|
99
98
|
|
100
99
|
protected:
|
101
|
-
void parse_adv_(const
|
100
|
+
void parse_adv_(const uint8_t *payload, uint8_t len);
|
102
101
|
|
103
102
|
esp_bd_addr_t address_{
|
104
103
|
0,
|
@@ -112,7 +111,6 @@ class ESPBTDevice {
|
|
112
111
|
std::vector<ESPBTUUID> service_uuids_{};
|
113
112
|
std::vector<ServiceData> manufacturer_datas_{};
|
114
113
|
std::vector<ServiceData> service_datas_{};
|
115
|
-
esp_ble_gap_cb_param_t::ble_scan_result_evt_param scan_result_{};
|
116
114
|
};
|
117
115
|
|
118
116
|
class ESP32BLETracker;
|
@@ -121,9 +119,7 @@ class ESPBTDeviceListener {
|
|
121
119
|
public:
|
122
120
|
virtual void on_scan_end() {}
|
123
121
|
virtual bool parse_device(const ESPBTDevice &device) = 0;
|
124
|
-
virtual bool parse_devices(
|
125
|
-
return false;
|
126
|
-
};
|
122
|
+
virtual bool parse_devices(const BLEScanResult *scan_results, size_t count) { return false; };
|
127
123
|
virtual AdvertisementParserType get_advertisement_parser_type() {
|
128
124
|
return AdvertisementParserType::PARSED_ADVERTISEMENTS;
|
129
125
|
};
|
@@ -210,6 +206,7 @@ class ESPBTClient : public ESPBTDeviceListener {
|
|
210
206
|
|
211
207
|
class ESP32BLETracker : public Component,
|
212
208
|
public GAPEventHandler,
|
209
|
+
public GAPScanEventHandler,
|
213
210
|
public GATTcEventHandler,
|
214
211
|
public BLEStatusEventHandler,
|
215
212
|
public Parented<ESP32BLE> {
|
@@ -240,6 +237,7 @@ class ESP32BLETracker : public Component,
|
|
240
237
|
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
241
238
|
esp_ble_gattc_cb_param_t *param) override;
|
242
239
|
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
240
|
+
void gap_scan_event_handler(const BLEScanResult &scan_result) override;
|
243
241
|
void ble_before_disabled_event_handler() override;
|
244
242
|
|
245
243
|
void add_scanner_state_callback(std::function<void(ScannerState)> &&callback) {
|
@@ -285,14 +283,16 @@ class ESP32BLETracker : public Component,
|
|
285
283
|
bool ble_was_disabled_{true};
|
286
284
|
bool raw_advertisements_{false};
|
287
285
|
bool parse_advertisements_{false};
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
286
|
+
|
287
|
+
// Lock-free Single-Producer Single-Consumer (SPSC) ring buffer for scan results
|
288
|
+
// Producer: ESP-IDF Bluetooth stack callback (gap_scan_event_handler)
|
289
|
+
// Consumer: ESPHome main loop (loop() method)
|
290
|
+
// This design ensures zero blocking in the BT callback and prevents scan result loss
|
291
|
+
BLEScanResult *scan_ring_buffer_;
|
292
|
+
std::atomic<size_t> ring_write_index_{0}; // Written only by BT callback (producer)
|
293
|
+
std::atomic<size_t> ring_read_index_{0}; // Written only by main loop (consumer)
|
294
|
+
std::atomic<size_t> scan_results_dropped_{0}; // Tracks buffer overflow events
|
295
|
+
|
296
296
|
esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS};
|
297
297
|
esp_bt_status_t scan_set_param_failed_{ESP_BT_STATUS_SUCCESS};
|
298
298
|
int connecting_{0};
|
@@ -57,7 +57,7 @@ void ESP32Camera::dump_config() {
|
|
57
57
|
" External Clock: Pin:%d Frequency:%u\n"
|
58
58
|
" I2C Pins: SDA:%d SCL:%d\n"
|
59
59
|
" Reset Pin: %d",
|
60
|
-
this->name_.c_str(), YESNO(this->
|
60
|
+
this->name_.c_str(), YESNO(this->is_internal()), conf.pin_d0, conf.pin_d1, conf.pin_d2, conf.pin_d3,
|
61
61
|
conf.pin_d4, conf.pin_d5, conf.pin_d6, conf.pin_d7, conf.pin_vsync, conf.pin_href, conf.pin_pclk,
|
62
62
|
conf.pin_xclk, conf.xclk_freq_hz, conf.pin_sccb_sda, conf.pin_sccb_scl, conf.pin_reset);
|
63
63
|
switch (this->config_.frame_size) {
|
esphome/components/fan/fan.cpp
CHANGED
@@ -41,39 +41,48 @@ void FanCall::perform() {
|
|
41
41
|
void FanCall::validate_() {
|
42
42
|
auto traits = this->parent_.get_traits();
|
43
43
|
|
44
|
-
if (this->speed_.has_value())
|
44
|
+
if (this->speed_.has_value()) {
|
45
45
|
this->speed_ = clamp(*this->speed_, 1, traits.supported_speed_count());
|
46
46
|
|
47
|
-
|
48
|
-
//
|
49
|
-
|
50
|
-
|
47
|
+
// https://developers.home-assistant.io/docs/core/entity/fan/#preset-modes
|
48
|
+
// "Manually setting a speed must disable any set preset mode"
|
49
|
+
this->preset_mode_.clear();
|
50
|
+
}
|
51
|
+
|
52
|
+
if (!this->preset_mode_.empty()) {
|
53
|
+
const auto &preset_modes = traits.supported_preset_modes();
|
54
|
+
if (preset_modes.find(this->preset_mode_) == preset_modes.end()) {
|
55
|
+
ESP_LOGW(TAG, "%s: Preset mode '%s' not supported", this->parent_.get_name().c_str(), this->preset_mode_.c_str());
|
56
|
+
this->preset_mode_.clear();
|
51
57
|
}
|
52
58
|
}
|
53
59
|
|
60
|
+
// when turning on...
|
61
|
+
if (!this->parent_.state && this->binary_state_.has_value() &&
|
62
|
+
*this->binary_state_
|
63
|
+
// ..,and no preset mode will be active...
|
64
|
+
&& this->preset_mode_.empty() &&
|
65
|
+
this->parent_.preset_mode.empty()
|
66
|
+
// ...and neither current nor new speed is available...
|
67
|
+
&& traits.supports_speed() && this->parent_.speed == 0 && !this->speed_.has_value()) {
|
68
|
+
// ...set speed to 100%
|
69
|
+
this->speed_ = traits.supported_speed_count();
|
70
|
+
}
|
71
|
+
|
54
72
|
if (this->oscillating_.has_value() && !traits.supports_oscillation()) {
|
55
|
-
ESP_LOGW(TAG, "
|
73
|
+
ESP_LOGW(TAG, "%s: Oscillation not supported", this->parent_.get_name().c_str());
|
56
74
|
this->oscillating_.reset();
|
57
75
|
}
|
58
76
|
|
59
77
|
if (this->speed_.has_value() && !traits.supports_speed()) {
|
60
|
-
ESP_LOGW(TAG, "
|
78
|
+
ESP_LOGW(TAG, "%s: Speed control not supported", this->parent_.get_name().c_str());
|
61
79
|
this->speed_.reset();
|
62
80
|
}
|
63
81
|
|
64
82
|
if (this->direction_.has_value() && !traits.supports_direction()) {
|
65
|
-
ESP_LOGW(TAG, "
|
83
|
+
ESP_LOGW(TAG, "%s: Direction control not supported", this->parent_.get_name().c_str());
|
66
84
|
this->direction_.reset();
|
67
85
|
}
|
68
|
-
|
69
|
-
if (!this->preset_mode_.empty()) {
|
70
|
-
const auto &preset_modes = traits.supported_preset_modes();
|
71
|
-
if (preset_modes.find(this->preset_mode_) == preset_modes.end()) {
|
72
|
-
ESP_LOGW(TAG, "'%s' - This fan does not support preset mode '%s'!", this->parent_.get_name().c_str(),
|
73
|
-
this->preset_mode_.c_str());
|
74
|
-
this->preset_mode_.clear();
|
75
|
-
}
|
76
|
-
}
|
77
86
|
}
|
78
87
|
|
79
88
|
FanCall FanRestoreState::to_call(Fan &fan) {
|
@@ -317,15 +317,18 @@ void I2SAudioMicrophone::stop_driver_() {
|
|
317
317
|
ESP_LOGW(TAG, "Error uninstalling I2S driver - it may not have started: %s", esp_err_to_name(err));
|
318
318
|
}
|
319
319
|
#else
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
320
|
+
if (this->rx_handle_ != nullptr) {
|
321
|
+
/* Have to stop the channel before deleting it */
|
322
|
+
err = i2s_channel_disable(this->rx_handle_);
|
323
|
+
if (err != ESP_OK) {
|
324
|
+
ESP_LOGW(TAG, "Error stopping I2S microphone - it may not have started: %s", esp_err_to_name(err));
|
325
|
+
}
|
326
|
+
/* If the handle is not needed any more, delete it to release the channel resources */
|
327
|
+
err = i2s_del_channel(this->rx_handle_);
|
328
|
+
if (err != ESP_OK) {
|
329
|
+
ESP_LOGW(TAG, "Error deleting I2S channel - it may not have started: %s", esp_err_to_name(err));
|
330
|
+
}
|
331
|
+
this->rx_handle_ = nullptr;
|
329
332
|
}
|
330
333
|
#endif
|
331
334
|
this->parent_->unlock();
|
@@ -19,9 +19,8 @@ void KMeterISOComponent::setup() {
|
|
19
19
|
|
20
20
|
// Mark as not failed before initializing. Some devices will turn off sensors to save on batteries
|
21
21
|
// and when they come back on, the COMPONENT_STATE_FAILED bit must be unset on the component.
|
22
|
-
if (
|
23
|
-
this->
|
24
|
-
this->component_state_ |= COMPONENT_STATE_CONSTRUCTION;
|
22
|
+
if (this->is_failed()) {
|
23
|
+
this->reset_to_construction_state();
|
25
24
|
}
|
26
25
|
|
27
26
|
auto err = this->bus_->writev(this->address_, nullptr, 0);
|
@@ -116,7 +116,7 @@ void Logger::log_vprintf_(int level, const char *tag, int line, const __FlashStr
|
|
116
116
|
if (this->baud_rate_ > 0) {
|
117
117
|
this->write_msg_(this->tx_buffer_ + msg_start);
|
118
118
|
}
|
119
|
-
this->
|
119
|
+
this->log_callback_.call(level, tag, this->tx_buffer_ + msg_start);
|
120
120
|
|
121
121
|
global_recursion_guard_ = false;
|
122
122
|
}
|
@@ -129,19 +129,6 @@ inline int Logger::level_for(const char *tag) {
|
|
129
129
|
return this->current_level_;
|
130
130
|
}
|
131
131
|
|
132
|
-
void HOT Logger::call_log_callbacks_(int level, const char *tag, const char *msg) {
|
133
|
-
#ifdef USE_ESP32
|
134
|
-
// Suppress network-logging if memory constrained
|
135
|
-
// In some configurations (eg BLE enabled) there may be some transient
|
136
|
-
// memory exhaustion, and trying to log when OOM can lead to a crash. Skipping
|
137
|
-
// here usually allows the stack to recover instead.
|
138
|
-
// See issue #1234 for analysis.
|
139
|
-
if (xPortGetFreeHeapSize() < 2048)
|
140
|
-
return;
|
141
|
-
#endif
|
142
|
-
this->log_callback_.call(level, tag, msg);
|
143
|
-
}
|
144
|
-
|
145
132
|
Logger::Logger(uint32_t baud_rate, size_t tx_buffer_size) : baud_rate_(baud_rate), tx_buffer_size_(tx_buffer_size) {
|
146
133
|
// add 1 to buffer size for null terminator
|
147
134
|
this->tx_buffer_ = new char[this->tx_buffer_size_ + 1]; // NOLINT
|
@@ -189,7 +176,7 @@ void Logger::loop() {
|
|
189
176
|
this->tx_buffer_size_);
|
190
177
|
this->write_footer_to_buffer_(this->tx_buffer_, &this->tx_buffer_at_, this->tx_buffer_size_);
|
191
178
|
this->tx_buffer_[this->tx_buffer_at_] = '\0';
|
192
|
-
this->
|
179
|
+
this->log_callback_.call(message->level, message->tag, this->tx_buffer_);
|
193
180
|
// At this point all the data we need from message has been transferred to the tx_buffer
|
194
181
|
// so we can release the message to allow other tasks to use it as soon as possible.
|
195
182
|
this->log_buffer_->release_message_main_loop(received_token);
|
@@ -156,7 +156,6 @@ class Logger : public Component {
|
|
156
156
|
#endif
|
157
157
|
|
158
158
|
protected:
|
159
|
-
void call_log_callbacks_(int level, const char *tag, const char *msg);
|
160
159
|
void write_msg_(const char *msg);
|
161
160
|
|
162
161
|
// Format a log message with printf-style arguments and write it to a buffer with header, footer, and null terminator
|
@@ -191,7 +190,7 @@ class Logger : public Component {
|
|
191
190
|
if (this->baud_rate_ > 0) {
|
192
191
|
this->write_msg_(this->tx_buffer_); // If logging is enabled, write to console
|
193
192
|
}
|
194
|
-
this->
|
193
|
+
this->log_callback_.call(level, tag, this->tx_buffer_);
|
195
194
|
}
|
196
195
|
|
197
196
|
// Write the body of the log message to the buffer
|
@@ -153,7 +153,7 @@ bool MQTTComponent::send_discovery_() {
|
|
153
153
|
if (node_friendly_name.empty()) {
|
154
154
|
node_friendly_name = node_name;
|
155
155
|
}
|
156
|
-
|
156
|
+
std::string node_area = App.get_area();
|
157
157
|
|
158
158
|
JsonObject device_info = root.createNestedObject(MQTT_DEVICE);
|
159
159
|
const auto mac = get_mac_address();
|
@@ -337,23 +337,26 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
|
|
337
337
|
|
338
338
|
bool Nextion::upload_end_(bool successful) {
|
339
339
|
ESP_LOGD(TAG, "TFT upload done: %s", YESNO(successful));
|
340
|
-
this->is_updating_ = false;
|
341
|
-
this->ignore_is_setup_ = false;
|
342
|
-
|
343
|
-
uint32_t baud_rate = this->parent_->get_baud_rate();
|
344
|
-
if (baud_rate != this->original_baud_rate_) {
|
345
|
-
ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
|
346
|
-
this->parent_->set_baud_rate(this->original_baud_rate_);
|
347
|
-
this->parent_->load_settings();
|
348
|
-
}
|
349
340
|
|
350
341
|
if (successful) {
|
351
342
|
ESP_LOGD(TAG, "Restart");
|
352
343
|
delay(1500); // NOLINT
|
353
344
|
App.safe_reboot();
|
345
|
+
delay(1500); // NOLINT
|
354
346
|
} else {
|
355
347
|
ESP_LOGE(TAG, "TFT upload failed");
|
348
|
+
|
349
|
+
this->is_updating_ = false;
|
350
|
+
this->ignore_is_setup_ = false;
|
351
|
+
|
352
|
+
uint32_t baud_rate = this->parent_->get_baud_rate();
|
353
|
+
if (baud_rate != this->original_baud_rate_) {
|
354
|
+
ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
|
355
|
+
this->parent_->set_baud_rate(this->original_baud_rate_);
|
356
|
+
this->parent_->load_settings();
|
357
|
+
}
|
356
358
|
}
|
359
|
+
|
357
360
|
return successful;
|
358
361
|
}
|
359
362
|
|
@@ -337,15 +337,6 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
|
|
337
337
|
|
338
338
|
bool Nextion::upload_end_(bool successful) {
|
339
339
|
ESP_LOGD(TAG, "TFT upload done: %s", YESNO(successful));
|
340
|
-
this->is_updating_ = false;
|
341
|
-
this->ignore_is_setup_ = false;
|
342
|
-
|
343
|
-
uint32_t baud_rate = this->parent_->get_baud_rate();
|
344
|
-
if (baud_rate != this->original_baud_rate_) {
|
345
|
-
ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
|
346
|
-
this->parent_->set_baud_rate(this->original_baud_rate_);
|
347
|
-
this->parent_->load_settings();
|
348
|
-
}
|
349
340
|
|
350
341
|
if (successful) {
|
351
342
|
ESP_LOGD(TAG, "Restart");
|
@@ -353,7 +344,18 @@ bool Nextion::upload_end_(bool successful) {
|
|
353
344
|
App.safe_reboot();
|
354
345
|
} else {
|
355
346
|
ESP_LOGE(TAG, "TFT upload failed");
|
347
|
+
|
348
|
+
this->is_updating_ = false;
|
349
|
+
this->ignore_is_setup_ = false;
|
350
|
+
|
351
|
+
uint32_t baud_rate = this->parent_->get_baud_rate();
|
352
|
+
if (baud_rate != this->original_baud_rate_) {
|
353
|
+
ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
|
354
|
+
this->parent_->set_baud_rate(this->original_baud_rate_);
|
355
|
+
this->parent_->load_settings();
|
356
|
+
}
|
356
357
|
}
|
358
|
+
|
357
359
|
return successful;
|
358
360
|
}
|
359
361
|
|
@@ -7,7 +7,7 @@ namespace number {
|
|
7
7
|
static const char *const TAG = "number";
|
8
8
|
|
9
9
|
void Number::publish_state(float state) {
|
10
|
-
this->
|
10
|
+
this->set_has_state(true);
|
11
11
|
this->state = state;
|
12
12
|
ESP_LOGD(TAG, "'%s': Sending state %f", this->get_name().c_str(), state);
|
13
13
|
this->state_callback_.call(state);
|
@@ -48,9 +48,6 @@ class Number : public EntityBase {
|
|
48
48
|
|
49
49
|
NumberTraits traits;
|
50
50
|
|
51
|
-
/// Return whether this number has gotten a full state yet.
|
52
|
-
bool has_state() const { return has_state_; }
|
53
|
-
|
54
51
|
protected:
|
55
52
|
friend class NumberCall;
|
56
53
|
|
@@ -63,7 +60,6 @@ class Number : public EntityBase {
|
|
63
60
|
virtual void control(float value) = 0;
|
64
61
|
|
65
62
|
CallbackManager<void(float)> state_callback_;
|
66
|
-
bool has_state_{false};
|
67
63
|
};
|
68
64
|
|
69
65
|
} // namespace number
|
@@ -10,7 +10,7 @@ void Select::publish_state(const std::string &state) {
|
|
10
10
|
auto index = this->index_of(state);
|
11
11
|
const auto *name = this->get_name().c_str();
|
12
12
|
if (index.has_value()) {
|
13
|
-
this->
|
13
|
+
this->set_has_state(true);
|
14
14
|
this->state = state;
|
15
15
|
ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", name, state.c_str(), index.value());
|
16
16
|
this->state_callback_.call(state, index.value());
|
@@ -35,9 +35,6 @@ class Select : public EntityBase {
|
|
35
35
|
|
36
36
|
void publish_state(const std::string &state);
|
37
37
|
|
38
|
-
/// Return whether this select component has gotten a full state yet.
|
39
|
-
bool has_state() const { return has_state_; }
|
40
|
-
|
41
38
|
/// Instantiate a SelectCall object to modify this select component's state.
|
42
39
|
SelectCall make_call() { return SelectCall(this); }
|
43
40
|
|
@@ -73,7 +70,6 @@ class Select : public EntityBase {
|
|
73
70
|
virtual void control(const std::string &value) = 0;
|
74
71
|
|
75
72
|
CallbackManager<void(std::string, size_t)> state_callback_;
|
76
|
-
bool has_state_{false};
|
77
73
|
};
|
78
74
|
|
79
75
|
} // namespace select
|
@@ -38,7 +38,9 @@ StateClass Sensor::get_state_class() {
|
|
38
38
|
|
39
39
|
void Sensor::publish_state(float state) {
|
40
40
|
this->raw_state = state;
|
41
|
-
this->raw_callback_
|
41
|
+
if (this->raw_callback_) {
|
42
|
+
this->raw_callback_->call(state);
|
43
|
+
}
|
42
44
|
|
43
45
|
ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
|
44
46
|
|
@@ -51,7 +53,10 @@ void Sensor::publish_state(float state) {
|
|
51
53
|
|
52
54
|
void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); }
|
53
55
|
void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) {
|
54
|
-
this->raw_callback_
|
56
|
+
if (!this->raw_callback_) {
|
57
|
+
this->raw_callback_ = make_unique<CallbackManager<void(float)>>();
|
58
|
+
}
|
59
|
+
this->raw_callback_->add(std::move(callback));
|
55
60
|
}
|
56
61
|
|
57
62
|
void Sensor::add_filter(Filter *filter) {
|
@@ -88,13 +93,12 @@ float Sensor::get_raw_state() const { return this->raw_state; }
|
|
88
93
|
std::string Sensor::unique_id() { return ""; }
|
89
94
|
|
90
95
|
void Sensor::internal_send_state_to_frontend(float state) {
|
91
|
-
this->
|
96
|
+
this->set_has_state(true);
|
92
97
|
this->state = state;
|
93
98
|
ESP_LOGD(TAG, "'%s': Sending state %.5f %s with %d decimals of accuracy", this->get_name().c_str(), state,
|
94
99
|
this->get_unit_of_measurement().c_str(), this->get_accuracy_decimals());
|
95
100
|
this->callback_.call(state);
|
96
101
|
}
|
97
|
-
bool Sensor::has_state() const { return this->has_state_; }
|
98
102
|
|
99
103
|
} // namespace sensor
|
100
104
|
} // namespace esphome
|
@@ -7,6 +7,7 @@
|
|
7
7
|
#include "esphome/components/sensor/filter.h"
|
8
8
|
|
9
9
|
#include <vector>
|
10
|
+
#include <memory>
|
10
11
|
|
11
12
|
namespace esphome {
|
12
13
|
namespace sensor {
|
@@ -140,9 +141,6 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
|
|
140
141
|
*/
|
141
142
|
float raw_state;
|
142
143
|
|
143
|
-
/// Return whether this sensor has gotten a full state (that passed through all filters) yet.
|
144
|
-
bool has_state() const;
|
145
|
-
|
146
144
|
/** Override this method to set the unique ID of this sensor.
|
147
145
|
*
|
148
146
|
* @deprecated Do not use for new sensors, a suitable unique ID is automatically generated (2023.4).
|
@@ -152,15 +150,14 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
|
|
152
150
|
void internal_send_state_to_frontend(float state);
|
153
151
|
|
154
152
|
protected:
|
155
|
-
CallbackManager<void(float)
|
156
|
-
CallbackManager<void(float)> callback_;
|
153
|
+
std::unique_ptr<CallbackManager<void(float)>> raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
|
154
|
+
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
|
157
155
|
|
158
156
|
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
159
157
|
|
160
158
|
optional<int8_t> accuracy_decimals_; ///< Accuracy in decimals override
|
161
159
|
optional<StateClass> state_class_{STATE_CLASS_NONE}; ///< State class override
|
162
160
|
bool force_update_{false}; ///< Force update mode
|
163
|
-
bool has_state_{false};
|
164
161
|
};
|
165
162
|
|
166
163
|
} // namespace sensor
|
@@ -9,10 +9,10 @@ namespace status_led {
|
|
9
9
|
static const char *const TAG = "status_led";
|
10
10
|
|
11
11
|
void StatusLEDLightOutput::loop() {
|
12
|
-
|
12
|
+
uint8_t new_state = App.get_app_state() & STATUS_LED_MASK;
|
13
13
|
|
14
14
|
if (new_state != this->last_app_state_) {
|
15
|
-
ESP_LOGV(TAG, "New app state 0x%
|
15
|
+
ESP_LOGV(TAG, "New app state 0x%02X", new_state);
|
16
16
|
}
|
17
17
|
|
18
18
|
if ((new_state & STATUS_LED_ERROR) != 0u) {
|
@@ -36,7 +36,7 @@ class StatusLEDLightOutput : public light::LightOutput, public Component {
|
|
36
36
|
GPIOPin *pin_{nullptr};
|
37
37
|
output::BinaryOutput *output_{nullptr};
|
38
38
|
light::LightState *lightstate_{};
|
39
|
-
|
39
|
+
uint8_t last_app_state_{0xFF};
|
40
40
|
void output_state_(bool state);
|
41
41
|
};
|
42
42
|
|
@@ -110,15 +110,7 @@ void TemplateAlarmControlPanel::loop() {
|
|
110
110
|
delay = this->arming_night_time_;
|
111
111
|
}
|
112
112
|
if ((millis() - this->last_update_) > delay) {
|
113
|
-
|
114
|
-
for (auto sensor_info : this->sensor_map_) {
|
115
|
-
// Check for sensors left on and set to bypass automatically and remove them from monitoring
|
116
|
-
if ((sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor_info.first->state)) {
|
117
|
-
ESP_LOGW(TAG, "%s is left on and will be automatically bypassed", sensor_info.first->get_name().c_str());
|
118
|
-
this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index);
|
119
|
-
}
|
120
|
-
}
|
121
|
-
#endif
|
113
|
+
this->bypass_before_arming();
|
122
114
|
this->publish_state(this->desired_state_);
|
123
115
|
}
|
124
116
|
return;
|
@@ -259,10 +251,23 @@ void TemplateAlarmControlPanel::arm_(optional<std::string> code, alarm_control_p
|
|
259
251
|
if (delay > 0) {
|
260
252
|
this->publish_state(ACP_STATE_ARMING);
|
261
253
|
} else {
|
254
|
+
this->bypass_before_arming();
|
262
255
|
this->publish_state(state);
|
263
256
|
}
|
264
257
|
}
|
265
258
|
|
259
|
+
void TemplateAlarmControlPanel::bypass_before_arming() {
|
260
|
+
#ifdef USE_BINARY_SENSOR
|
261
|
+
for (auto sensor_info : this->sensor_map_) {
|
262
|
+
// Check for sensors left on and set to bypass automatically and remove them from monitoring
|
263
|
+
if ((sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor_info.first->state)) {
|
264
|
+
ESP_LOGW(TAG, "'%s' is left on and will be automatically bypassed", sensor_info.first->get_name().c_str());
|
265
|
+
this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index);
|
266
|
+
}
|
267
|
+
}
|
268
|
+
#endif
|
269
|
+
}
|
270
|
+
|
266
271
|
void TemplateAlarmControlPanel::control(const AlarmControlPanelCall &call) {
|
267
272
|
if (call.get_state()) {
|
268
273
|
if (call.get_state() == ACP_STATE_ARMED_AWAY) {
|
@@ -60,6 +60,7 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel,
|
|
60
60
|
bool get_requires_code_to_arm() const override { return this->requires_code_to_arm_; }
|
61
61
|
bool get_all_sensors_ready() { return this->sensors_ready_; };
|
62
62
|
void set_restore_mode(TemplateAlarmControlPanelRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
|
63
|
+
void bypass_before_arming();
|
63
64
|
|
64
65
|
#ifdef USE_BINARY_SENSOR
|
65
66
|
/** Add a binary_sensor to the alarm_panel.
|
esphome/components/text/text.cpp
CHANGED
@@ -7,7 +7,7 @@ namespace text {
|
|
7
7
|
static const char *const TAG = "text";
|
8
8
|
|
9
9
|
void Text::publish_state(const std::string &state) {
|
10
|
-
this->
|
10
|
+
this->set_has_state(true);
|
11
11
|
this->state = state;
|
12
12
|
if (this->traits.get_mode() == TEXT_MODE_PASSWORD) {
|
13
13
|
ESP_LOGD(TAG, "'%s': Sending state " LOG_SECRET("'%s'"), this->get_name().c_str(), state.c_str());
|
esphome/components/text/text.h
CHANGED
@@ -28,9 +28,6 @@ class Text : public EntityBase {
|
|
28
28
|
|
29
29
|
void publish_state(const std::string &state);
|
30
30
|
|
31
|
-
/// Return whether this text input has gotten a full state yet.
|
32
|
-
bool has_state() const { return has_state_; }
|
33
|
-
|
34
31
|
/// Instantiate a TextCall object to modify this text component's state.
|
35
32
|
TextCall make_call() { return TextCall(this); }
|
36
33
|
|
@@ -48,7 +45,6 @@ class Text : public EntityBase {
|
|
48
45
|
virtual void control(const std::string &value) = 0;
|
49
46
|
|
50
47
|
CallbackManager<void(std::string)> state_callback_;
|
51
|
-
bool has_state_{false};
|
52
48
|
};
|
53
49
|
|
54
50
|
} // namespace text
|