esphome 2025.4.0b2__py3-none-any.whl → 2025.4.1__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/__main__.py +5 -3
- esphome/components/am2315c/am2315c.cpp +4 -4
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +6 -0
- esphome/components/ens160_base/ens160_base.cpp +1 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -0
- esphome/components/lvgl/lvgl_esphome.cpp +1 -0
- esphome/components/online_image/online_image.cpp +5 -5
- esphome/components/psram/psram.cpp +3 -2
- esphome/components/sml/sml.cpp +8 -6
- esphome/components/sml/sml.h +1 -1
- esphome/components/sml/sml_parser.cpp +16 -18
- esphome/components/sml/sml_parser.h +42 -12
- esphome/components/watchdog/watchdog.cpp +2 -1
- esphome/config_validation.py +0 -42
- esphome/const.py +1 -1
- esphome/core/__init__.py +0 -1
- esphome/log.py +5 -4
- esphome/vscode.py +27 -8
- esphome/yaml_util.py +75 -39
- {esphome-2025.4.0b2.dist-info → esphome-2025.4.1.dist-info}/METADATA +2 -2
- {esphome-2025.4.0b2.dist-info → esphome-2025.4.1.dist-info}/RECORD +25 -25
- {esphome-2025.4.0b2.dist-info → esphome-2025.4.1.dist-info}/WHEEL +0 -0
- {esphome-2025.4.0b2.dist-info → esphome-2025.4.1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.0b2.dist-info → esphome-2025.4.1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.0b2.dist-info → esphome-2025.4.1.dist-info}/top_level.txt +0 -0
esphome/__main__.py
CHANGED
@@ -375,10 +375,12 @@ def upload_program(config, args, host):
|
|
375
375
|
password = ota_conf.get(CONF_PASSWORD, "")
|
376
376
|
|
377
377
|
if (
|
378
|
-
|
379
|
-
and (get_port_type(host) == "MQTT" or config[CONF_MDNS][CONF_DISABLED])
|
380
|
-
and CONF_MQTT in config
|
378
|
+
CONF_MQTT in config # pylint: disable=too-many-boolean-expressions
|
381
379
|
and (not args.device or args.device in ("MQTT", "OTA"))
|
380
|
+
and (
|
381
|
+
((config[CONF_MDNS][CONF_DISABLED]) and not is_ip_address(CORE.address))
|
382
|
+
or get_port_type(host) == "MQTT"
|
383
|
+
)
|
382
384
|
):
|
383
385
|
from esphome import mqtt
|
384
386
|
|
@@ -128,7 +128,7 @@ void AM2315C::update() {
|
|
128
128
|
data[2] = 0x00;
|
129
129
|
if (this->write(data, 3) != i2c::ERROR_OK) {
|
130
130
|
ESP_LOGE(TAG, "Write failed!");
|
131
|
-
this->
|
131
|
+
this->status_set_warning();
|
132
132
|
return;
|
133
133
|
}
|
134
134
|
|
@@ -138,12 +138,12 @@ void AM2315C::update() {
|
|
138
138
|
uint8_t status = 0;
|
139
139
|
if (this->read(&status, 1) != i2c::ERROR_OK) {
|
140
140
|
ESP_LOGE(TAG, "Read failed!");
|
141
|
-
this->
|
141
|
+
this->status_set_warning();
|
142
142
|
return;
|
143
143
|
}
|
144
144
|
if ((status & 0x80) == 0x80) {
|
145
145
|
ESP_LOGE(TAG, "HW still busy!");
|
146
|
-
this->
|
146
|
+
this->status_set_warning();
|
147
147
|
return;
|
148
148
|
}
|
149
149
|
|
@@ -151,7 +151,7 @@ void AM2315C::update() {
|
|
151
151
|
uint8_t data[7];
|
152
152
|
if (this->read(data, 7) != i2c::ERROR_OK) {
|
153
153
|
ESP_LOGE(TAG, "Read failed!");
|
154
|
-
this->
|
154
|
+
this->status_set_warning();
|
155
155
|
return;
|
156
156
|
}
|
157
157
|
|
@@ -265,6 +265,12 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
|
|
265
265
|
connection->get_connection_index(), connection->address_str().c_str());
|
266
266
|
return;
|
267
267
|
} else if (connection->state() == espbt::ClientState::CONNECTING) {
|
268
|
+
if (connection->disconnect_pending()) {
|
269
|
+
ESP_LOGW(TAG, "[%d] [%s] Connection request while pending disconnect, cancelling pending disconnect",
|
270
|
+
connection->get_connection_index(), connection->address_str().c_str());
|
271
|
+
connection->cancel_pending_disconnect();
|
272
|
+
return;
|
273
|
+
}
|
268
274
|
ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, already connecting", connection->get_connection_index(),
|
269
275
|
connection->address_str().c_str());
|
270
276
|
return;
|
@@ -173,6 +173,8 @@ class ESPBTClient : public ESPBTDeviceListener {
|
|
173
173
|
virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) = 0;
|
174
174
|
virtual void connect() = 0;
|
175
175
|
virtual void disconnect() = 0;
|
176
|
+
bool disconnect_pending() const { return this->want_disconnect_; }
|
177
|
+
void cancel_pending_disconnect() { this->want_disconnect_ = false; }
|
176
178
|
virtual void set_state(ClientState st) {
|
177
179
|
this->state_ = st;
|
178
180
|
if (st == ClientState::IDLE) {
|
@@ -120,6 +120,7 @@ void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_ev
|
|
120
120
|
void LvglComponent::add_page(LvPageType *page) {
|
121
121
|
this->pages_.push_back(page);
|
122
122
|
page->set_parent(this);
|
123
|
+
lv_disp_set_default(this->disp_);
|
123
124
|
page->setup(this->pages_.size() - 1);
|
124
125
|
}
|
125
126
|
void LvglComponent::show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time) {
|
@@ -111,7 +111,7 @@ void OnlineImage::update() {
|
|
111
111
|
case ImageFormat::BMP:
|
112
112
|
accept_mime_type = "image/bmp";
|
113
113
|
break;
|
114
|
-
#endif //
|
114
|
+
#endif // USE_ONLINE_IMAGE_BMP_SUPPORT
|
115
115
|
#ifdef USE_ONLINE_IMAGE_JPEG_SUPPORT
|
116
116
|
case ImageFormat::JPEG:
|
117
117
|
accept_mime_type = "image/jpeg";
|
@@ -121,7 +121,7 @@ void OnlineImage::update() {
|
|
121
121
|
case ImageFormat::PNG:
|
122
122
|
accept_mime_type = "image/png";
|
123
123
|
break;
|
124
|
-
#endif //
|
124
|
+
#endif // USE_ONLINE_IMAGE_PNG_SUPPORT
|
125
125
|
default:
|
126
126
|
accept_mime_type = "image/*";
|
127
127
|
}
|
@@ -159,7 +159,7 @@ void OnlineImage::update() {
|
|
159
159
|
ESP_LOGD(TAG, "Allocating BMP decoder");
|
160
160
|
this->decoder_ = make_unique<BmpDecoder>(this);
|
161
161
|
}
|
162
|
-
#endif //
|
162
|
+
#endif // USE_ONLINE_IMAGE_BMP_SUPPORT
|
163
163
|
#ifdef USE_ONLINE_IMAGE_JPEG_SUPPORT
|
164
164
|
if (this->format_ == ImageFormat::JPEG) {
|
165
165
|
ESP_LOGD(TAG, "Allocating JPEG decoder");
|
@@ -171,7 +171,7 @@ void OnlineImage::update() {
|
|
171
171
|
ESP_LOGD(TAG, "Allocating PNG decoder");
|
172
172
|
this->decoder_ = make_unique<PngDecoder>(this);
|
173
173
|
}
|
174
|
-
#endif //
|
174
|
+
#endif // USE_ONLINE_IMAGE_PNG_SUPPORT
|
175
175
|
|
176
176
|
if (!this->decoder_) {
|
177
177
|
ESP_LOGE(TAG, "Could not instantiate decoder. Image format unsupported: %d", this->format_);
|
@@ -185,7 +185,7 @@ void OnlineImage::update() {
|
|
185
185
|
this->download_error_callback_.call();
|
186
186
|
return;
|
187
187
|
}
|
188
|
-
ESP_LOGI(TAG, "Downloading image (Size: %
|
188
|
+
ESP_LOGI(TAG, "Downloading image (Size: %zu)", total_size);
|
189
189
|
this->start_time_ = ::time(nullptr);
|
190
190
|
}
|
191
191
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
|
2
2
|
#ifdef USE_ESP32
|
3
3
|
#include "psram.h"
|
4
|
-
#
|
4
|
+
#include <esp_idf_version.h>
|
5
|
+
#if defined(USE_ESP_IDF) && ESP_IDF_VERSION_MAJOR >= 5
|
5
6
|
#include <esp_psram.h>
|
6
7
|
#endif // USE_ESP_IDF
|
7
8
|
|
@@ -15,7 +16,7 @@ static const char *const TAG = "psram";
|
|
15
16
|
|
16
17
|
void PsramComponent::dump_config() {
|
17
18
|
ESP_LOGCONFIG(TAG, "PSRAM:");
|
18
|
-
#
|
19
|
+
#if defined(USE_ESP_IDF) && ESP_IDF_VERSION_MAJOR >= 5
|
19
20
|
bool available = esp_psram_is_initialized();
|
20
21
|
|
21
22
|
ESP_LOGCONFIG(TAG, " Available: %s", YESNO(available));
|
esphome/components/sml/sml.cpp
CHANGED
@@ -52,9 +52,8 @@ void Sml::loop() {
|
|
52
52
|
break;
|
53
53
|
|
54
54
|
// remove start/end sequence
|
55
|
-
this->
|
56
|
-
|
57
|
-
this->process_sml_file_(this->sml_data_);
|
55
|
+
this->process_sml_file_(
|
56
|
+
BytesView(this->sml_data_).subview(START_SEQ.size(), this->sml_data_.size() - START_SEQ.size() - 8));
|
58
57
|
}
|
59
58
|
break;
|
60
59
|
};
|
@@ -66,8 +65,8 @@ void Sml::add_on_data_callback(std::function<void(std::vector<uint8_t>, bool)> &
|
|
66
65
|
this->data_callbacks_.add(std::move(callback));
|
67
66
|
}
|
68
67
|
|
69
|
-
void Sml::process_sml_file_(const
|
70
|
-
SmlFile sml_file
|
68
|
+
void Sml::process_sml_file_(const BytesView &sml_data) {
|
69
|
+
SmlFile sml_file(sml_data);
|
71
70
|
std::vector<ObisInfo> obis_info = sml_file.get_obis_info();
|
72
71
|
this->publish_obis_info_(obis_info);
|
73
72
|
|
@@ -75,6 +74,7 @@ void Sml::process_sml_file_(const bytes &sml_data) {
|
|
75
74
|
}
|
76
75
|
|
77
76
|
void Sml::log_obis_info_(const std::vector<ObisInfo> &obis_info_vec) {
|
77
|
+
#ifdef ESPHOME_LOG_HAS_DEBUG
|
78
78
|
ESP_LOGD(TAG, "OBIS info:");
|
79
79
|
for (auto const &obis_info : obis_info_vec) {
|
80
80
|
std::string info;
|
@@ -83,6 +83,7 @@ void Sml::log_obis_info_(const std::vector<ObisInfo> &obis_info_vec) {
|
|
83
83
|
info += " [0x" + bytes_repr(obis_info.value) + "]";
|
84
84
|
ESP_LOGD(TAG, "%s", info.c_str());
|
85
85
|
}
|
86
|
+
#endif
|
86
87
|
}
|
87
88
|
|
88
89
|
void Sml::publish_obis_info_(const std::vector<ObisInfo> &obis_info_vec) {
|
@@ -92,10 +93,11 @@ void Sml::publish_obis_info_(const std::vector<ObisInfo> &obis_info_vec) {
|
|
92
93
|
}
|
93
94
|
|
94
95
|
void Sml::publish_value_(const ObisInfo &obis_info) {
|
96
|
+
const auto obis_code = obis_info.code_repr();
|
95
97
|
for (auto const &sml_listener : sml_listeners_) {
|
96
98
|
if ((!sml_listener->server_id.empty()) && (bytes_repr(obis_info.server_id) != sml_listener->server_id))
|
97
99
|
continue;
|
98
|
-
if (
|
100
|
+
if (obis_code != sml_listener->obis_code)
|
99
101
|
continue;
|
100
102
|
sml_listener->publish_val(obis_info);
|
101
103
|
}
|
esphome/components/sml/sml.h
CHANGED
@@ -27,7 +27,7 @@ class Sml : public Component, public uart::UARTDevice {
|
|
27
27
|
void add_on_data_callback(std::function<void(std::vector<uint8_t>, bool)> &&callback);
|
28
28
|
|
29
29
|
protected:
|
30
|
-
void process_sml_file_(const
|
30
|
+
void process_sml_file_(const BytesView &sml_data);
|
31
31
|
void log_obis_info_(const std::vector<ObisInfo> &obis_info_vec);
|
32
32
|
void publish_obis_info_(const std::vector<ObisInfo> &obis_info_vec);
|
33
33
|
char check_start_end_bytes_(uint8_t byte);
|
@@ -5,17 +5,17 @@
|
|
5
5
|
namespace esphome {
|
6
6
|
namespace sml {
|
7
7
|
|
8
|
-
SmlFile::SmlFile(
|
8
|
+
SmlFile::SmlFile(const BytesView &buffer) : buffer_(buffer) {
|
9
9
|
// extract messages
|
10
10
|
this->pos_ = 0;
|
11
11
|
while (this->pos_ < this->buffer_.size()) {
|
12
12
|
if (this->buffer_[this->pos_] == 0x00)
|
13
13
|
break; // EndOfSmlMsg
|
14
14
|
|
15
|
-
SmlNode message
|
15
|
+
SmlNode message;
|
16
16
|
if (!this->setup_node(&message))
|
17
17
|
break;
|
18
|
-
this->messages.emplace_back(message);
|
18
|
+
this->messages.emplace_back(std::move(message));
|
19
19
|
}
|
20
20
|
}
|
21
21
|
|
@@ -62,22 +62,20 @@ bool SmlFile::setup_node(SmlNode *node) {
|
|
62
62
|
return false;
|
63
63
|
|
64
64
|
node->type = type;
|
65
|
-
node->nodes.clear();
|
66
|
-
node->value_bytes.clear();
|
67
65
|
|
68
66
|
if (type == SML_LIST) {
|
69
67
|
node->nodes.reserve(length);
|
70
68
|
for (size_t i = 0; i != length; i++) {
|
71
|
-
SmlNode child_node
|
69
|
+
SmlNode child_node;
|
72
70
|
if (!this->setup_node(&child_node))
|
73
71
|
return false;
|
74
|
-
node->nodes.emplace_back(child_node);
|
72
|
+
node->nodes.emplace_back(std::move(child_node));
|
75
73
|
}
|
76
74
|
} else {
|
77
75
|
// Value starts at the current position
|
78
76
|
// Value ends "length" bytes later,
|
79
77
|
// (since the TL field is counted but already subtracted from length)
|
80
|
-
node->value_bytes =
|
78
|
+
node->value_bytes = buffer_.subview(this->pos_, length);
|
81
79
|
// Increment the pointer past all consumed bytes
|
82
80
|
this->pos_ += length;
|
83
81
|
}
|
@@ -87,14 +85,14 @@ bool SmlFile::setup_node(SmlNode *node) {
|
|
87
85
|
std::vector<ObisInfo> SmlFile::get_obis_info() {
|
88
86
|
std::vector<ObisInfo> obis_info;
|
89
87
|
for (auto const &message : messages) {
|
90
|
-
|
88
|
+
const auto &message_body = message.nodes[3];
|
91
89
|
uint16_t message_type = bytes_to_uint(message_body.nodes[0].value_bytes);
|
92
90
|
if (message_type != SML_GET_LIST_RES)
|
93
91
|
continue;
|
94
92
|
|
95
|
-
|
96
|
-
|
97
|
-
|
93
|
+
const auto &get_list_response = message_body.nodes[1];
|
94
|
+
const auto &server_id = get_list_response.nodes[1].value_bytes;
|
95
|
+
const auto &val_list = get_list_response.nodes[4];
|
98
96
|
|
99
97
|
for (auto const &val_list_entry : val_list.nodes) {
|
100
98
|
obis_info.emplace_back(server_id, val_list_entry);
|
@@ -103,7 +101,7 @@ std::vector<ObisInfo> SmlFile::get_obis_info() {
|
|
103
101
|
return obis_info;
|
104
102
|
}
|
105
103
|
|
106
|
-
std::string bytes_repr(const
|
104
|
+
std::string bytes_repr(const BytesView &buffer) {
|
107
105
|
std::string repr;
|
108
106
|
for (auto const value : buffer) {
|
109
107
|
repr += str_sprintf("%02x", value & 0xff);
|
@@ -111,7 +109,7 @@ std::string bytes_repr(const bytes &buffer) {
|
|
111
109
|
return repr;
|
112
110
|
}
|
113
111
|
|
114
|
-
uint64_t bytes_to_uint(const
|
112
|
+
uint64_t bytes_to_uint(const BytesView &buffer) {
|
115
113
|
uint64_t val = 0;
|
116
114
|
for (auto const value : buffer) {
|
117
115
|
val = (val << 8) + value;
|
@@ -119,7 +117,7 @@ uint64_t bytes_to_uint(const bytes &buffer) {
|
|
119
117
|
return val;
|
120
118
|
}
|
121
119
|
|
122
|
-
int64_t bytes_to_int(const
|
120
|
+
int64_t bytes_to_int(const BytesView &buffer) {
|
123
121
|
uint64_t tmp = bytes_to_uint(buffer);
|
124
122
|
int64_t val;
|
125
123
|
|
@@ -135,14 +133,14 @@ int64_t bytes_to_int(const bytes &buffer) {
|
|
135
133
|
return val;
|
136
134
|
}
|
137
135
|
|
138
|
-
std::string bytes_to_string(const
|
136
|
+
std::string bytes_to_string(const BytesView &buffer) { return std::string(buffer.begin(), buffer.end()); }
|
139
137
|
|
140
|
-
ObisInfo::ObisInfo(
|
138
|
+
ObisInfo::ObisInfo(const BytesView &server_id, const SmlNode &val_list_entry) : server_id(server_id) {
|
141
139
|
this->code = val_list_entry.nodes[0].value_bytes;
|
142
140
|
this->status = val_list_entry.nodes[1].value_bytes;
|
143
141
|
this->unit = bytes_to_uint(val_list_entry.nodes[3].value_bytes);
|
144
142
|
this->scaler = bytes_to_int(val_list_entry.nodes[4].value_bytes);
|
145
|
-
|
143
|
+
const auto &value_node = val_list_entry.nodes[5];
|
146
144
|
this->value = value_node.value_bytes;
|
147
145
|
this->value_type = value_node.type;
|
148
146
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
+
#include <cassert>
|
3
4
|
#include <cstdint>
|
4
5
|
#include <cstdio>
|
5
6
|
#include <string>
|
@@ -11,44 +12,73 @@ namespace sml {
|
|
11
12
|
|
12
13
|
using bytes = std::vector<uint8_t>;
|
13
14
|
|
15
|
+
class BytesView {
|
16
|
+
public:
|
17
|
+
BytesView() noexcept = default;
|
18
|
+
|
19
|
+
explicit BytesView(const uint8_t *first, size_t count) noexcept : data_{first}, count_{count} {}
|
20
|
+
|
21
|
+
explicit BytesView(const bytes &bytes) noexcept : data_{bytes.data()}, count_{bytes.size()} {}
|
22
|
+
|
23
|
+
size_t size() const noexcept { return count_; }
|
24
|
+
|
25
|
+
uint8_t operator[](size_t index) const noexcept {
|
26
|
+
assert(index < count_);
|
27
|
+
return data_[index];
|
28
|
+
}
|
29
|
+
|
30
|
+
BytesView subview(size_t offset, size_t count) const noexcept {
|
31
|
+
assert(offset + count <= count_);
|
32
|
+
return BytesView{data_ + offset, count};
|
33
|
+
}
|
34
|
+
|
35
|
+
const uint8_t *begin() const noexcept { return data_; }
|
36
|
+
|
37
|
+
const uint8_t *end() const noexcept { return data_ + count_; }
|
38
|
+
|
39
|
+
private:
|
40
|
+
const uint8_t *data_ = nullptr;
|
41
|
+
size_t count_ = 0;
|
42
|
+
};
|
43
|
+
|
14
44
|
class SmlNode {
|
15
45
|
public:
|
16
46
|
uint8_t type;
|
17
|
-
|
47
|
+
BytesView value_bytes;
|
18
48
|
std::vector<SmlNode> nodes;
|
19
49
|
};
|
20
50
|
|
21
51
|
class ObisInfo {
|
22
52
|
public:
|
23
|
-
ObisInfo(
|
24
|
-
|
25
|
-
|
26
|
-
|
53
|
+
ObisInfo(const BytesView &server_id, const SmlNode &val_list_entry);
|
54
|
+
BytesView server_id;
|
55
|
+
BytesView code;
|
56
|
+
BytesView status;
|
27
57
|
char unit;
|
28
58
|
char scaler;
|
29
|
-
|
59
|
+
BytesView value;
|
30
60
|
uint16_t value_type;
|
31
61
|
std::string code_repr() const;
|
32
62
|
};
|
33
63
|
|
34
64
|
class SmlFile {
|
35
65
|
public:
|
36
|
-
SmlFile(
|
66
|
+
SmlFile(const BytesView &buffer);
|
37
67
|
bool setup_node(SmlNode *node);
|
38
68
|
std::vector<SmlNode> messages;
|
39
69
|
std::vector<ObisInfo> get_obis_info();
|
40
70
|
|
41
71
|
protected:
|
42
|
-
const
|
72
|
+
const BytesView buffer_;
|
43
73
|
size_t pos_;
|
44
74
|
};
|
45
75
|
|
46
|
-
std::string bytes_repr(const
|
76
|
+
std::string bytes_repr(const BytesView &buffer);
|
47
77
|
|
48
|
-
uint64_t bytes_to_uint(const
|
78
|
+
uint64_t bytes_to_uint(const BytesView &buffer);
|
49
79
|
|
50
|
-
int64_t bytes_to_int(const
|
80
|
+
int64_t bytes_to_int(const BytesView &buffer);
|
51
81
|
|
52
|
-
std::string bytes_to_string(const
|
82
|
+
std::string bytes_to_string(const BytesView &buffer);
|
53
83
|
} // namespace sml
|
54
84
|
} // namespace esphome
|
@@ -6,6 +6,7 @@
|
|
6
6
|
#include <cinttypes>
|
7
7
|
#include <cstdint>
|
8
8
|
#ifdef USE_ESP32
|
9
|
+
#include <soc/soc_caps.h>
|
9
10
|
#include "esp_idf_version.h"
|
10
11
|
#include "esp_task_wdt.h"
|
11
12
|
#endif
|
@@ -40,7 +41,7 @@ void WatchdogManager::set_timeout_(uint32_t timeout_ms) {
|
|
40
41
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
41
42
|
esp_task_wdt_config_t wdt_config = {
|
42
43
|
.timeout_ms = timeout_ms,
|
43
|
-
.idle_core_mask =
|
44
|
+
.idle_core_mask = (1 << SOC_CPU_CORES_NUM) - 1,
|
44
45
|
.trigger_panic = true,
|
45
46
|
};
|
46
47
|
esp_task_wdt_reconfigure(&wdt_config);
|
esphome/config_validation.py
CHANGED
@@ -1499,30 +1499,9 @@ def dimensions(value):
|
|
1499
1499
|
|
1500
1500
|
|
1501
1501
|
def directory(value):
|
1502
|
-
import json
|
1503
|
-
|
1504
1502
|
value = string(value)
|
1505
1503
|
path = CORE.relative_config_path(value)
|
1506
1504
|
|
1507
|
-
if CORE.vscode and (
|
1508
|
-
not CORE.ace or os.path.abspath(path) == os.path.abspath(CORE.config_path)
|
1509
|
-
):
|
1510
|
-
print(
|
1511
|
-
json.dumps(
|
1512
|
-
{
|
1513
|
-
"type": "check_directory_exists",
|
1514
|
-
"path": path,
|
1515
|
-
}
|
1516
|
-
)
|
1517
|
-
)
|
1518
|
-
data = json.loads(input())
|
1519
|
-
assert data["type"] == "directory_exists_response"
|
1520
|
-
if data["content"]:
|
1521
|
-
return value
|
1522
|
-
raise Invalid(
|
1523
|
-
f"Could not find directory '{path}'. Please make sure it exists (full path: {os.path.abspath(path)})."
|
1524
|
-
)
|
1525
|
-
|
1526
1505
|
if not os.path.exists(path):
|
1527
1506
|
raise Invalid(
|
1528
1507
|
f"Could not find directory '{path}'. Please make sure it exists (full path: {os.path.abspath(path)})."
|
@@ -1535,30 +1514,9 @@ def directory(value):
|
|
1535
1514
|
|
1536
1515
|
|
1537
1516
|
def file_(value):
|
1538
|
-
import json
|
1539
|
-
|
1540
1517
|
value = string(value)
|
1541
1518
|
path = CORE.relative_config_path(value)
|
1542
1519
|
|
1543
|
-
if CORE.vscode and (
|
1544
|
-
not CORE.ace or os.path.abspath(path) == os.path.abspath(CORE.config_path)
|
1545
|
-
):
|
1546
|
-
print(
|
1547
|
-
json.dumps(
|
1548
|
-
{
|
1549
|
-
"type": "check_file_exists",
|
1550
|
-
"path": path,
|
1551
|
-
}
|
1552
|
-
)
|
1553
|
-
)
|
1554
|
-
data = json.loads(input())
|
1555
|
-
assert data["type"] == "file_exists_response"
|
1556
|
-
if data["content"]:
|
1557
|
-
return value
|
1558
|
-
raise Invalid(
|
1559
|
-
f"Could not find file '{path}'. Please make sure it exists (full path: {os.path.abspath(path)})."
|
1560
|
-
)
|
1561
|
-
|
1562
1520
|
if not os.path.exists(path):
|
1563
1521
|
raise Invalid(
|
1564
1522
|
f"Could not find file '{path}'. Please make sure it exists (full path: {os.path.abspath(path)})."
|
esphome/const.py
CHANGED
esphome/core/__init__.py
CHANGED
esphome/log.py
CHANGED
@@ -74,13 +74,14 @@ def setup_log(
|
|
74
74
|
|
75
75
|
colorama.init()
|
76
76
|
|
77
|
-
|
77
|
+
# Setup logging - will map log level from string to constant
|
78
|
+
logging.basicConfig(level=log_level)
|
79
|
+
|
80
|
+
if logging.root.level == logging.DEBUG:
|
78
81
|
CORE.verbose = True
|
79
|
-
elif
|
82
|
+
elif logging.root.level == logging.CRITICAL:
|
80
83
|
CORE.quiet = True
|
81
84
|
|
82
|
-
logging.basicConfig(level=log_level)
|
83
|
-
|
84
85
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
85
86
|
|
86
87
|
logging.getLogger().handlers[0].setFormatter(
|
esphome/vscode.py
CHANGED
@@ -78,28 +78,47 @@ def _print_file_read_event(path: str) -> None:
|
|
78
78
|
)
|
79
79
|
|
80
80
|
|
81
|
+
def _request_and_get_stream_on_stdin(fname: str) -> StringIO:
|
82
|
+
_print_file_read_event(fname)
|
83
|
+
raw_yaml_stream = StringIO(_read_file_content_from_json_on_stdin())
|
84
|
+
return raw_yaml_stream
|
85
|
+
|
86
|
+
|
87
|
+
def _vscode_loader(fname: str) -> dict[str, Any]:
|
88
|
+
raw_yaml_stream = _request_and_get_stream_on_stdin(fname)
|
89
|
+
# it is required to set the name on StringIO so document on start_mark
|
90
|
+
# is set properly. Otherwise it is initialized with "<file>"
|
91
|
+
raw_yaml_stream.name = fname
|
92
|
+
return parse_yaml(fname, raw_yaml_stream, _vscode_loader)
|
93
|
+
|
94
|
+
|
95
|
+
def _ace_loader(fname: str) -> dict[str, Any]:
|
96
|
+
raw_yaml_stream = _request_and_get_stream_on_stdin(fname)
|
97
|
+
return parse_yaml(fname, raw_yaml_stream)
|
98
|
+
|
99
|
+
|
81
100
|
def read_config(args):
|
82
101
|
while True:
|
83
102
|
CORE.reset()
|
84
103
|
data = json.loads(input())
|
85
|
-
assert data["type"] == "validate"
|
104
|
+
assert data["type"] == "validate" or data["type"] == "exit"
|
105
|
+
if data["type"] == "exit":
|
106
|
+
return
|
86
107
|
CORE.vscode = True
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
CORE.config_path = os.path.join(args.configuration, f)
|
108
|
+
if args.ace: # Running from ESPHome Compiler dashboard, not vscode
|
109
|
+
CORE.config_path = os.path.join(args.configuration, data["file"])
|
110
|
+
loader = _ace_loader
|
91
111
|
else:
|
92
112
|
CORE.config_path = data["file"]
|
113
|
+
loader = _vscode_loader
|
93
114
|
|
94
115
|
file_name = CORE.config_path
|
95
|
-
_print_file_read_event(file_name)
|
96
|
-
raw_yaml = _read_file_content_from_json_on_stdin()
|
97
116
|
command_line_substitutions: dict[str, Any] = (
|
98
117
|
dict(args.substitution) if args.substitution else {}
|
99
118
|
)
|
100
119
|
vs = VSCodeResult()
|
101
120
|
try:
|
102
|
-
config =
|
121
|
+
config = loader(file_name)
|
103
122
|
res = validate_config(config, command_line_substitutions)
|
104
123
|
except Exception as err: # pylint: disable=broad-except
|
105
124
|
vs.add_yaml_error(str(err))
|
esphome/yaml_util.py
CHANGED
@@ -3,12 +3,12 @@ from __future__ import annotations
|
|
3
3
|
import fnmatch
|
4
4
|
import functools
|
5
5
|
import inspect
|
6
|
-
from io import TextIOWrapper
|
6
|
+
from io import BytesIO, TextIOBase, TextIOWrapper
|
7
7
|
from ipaddress import _BaseAddress
|
8
8
|
import logging
|
9
9
|
import math
|
10
10
|
import os
|
11
|
-
from typing import Any
|
11
|
+
from typing import Any, Callable
|
12
12
|
import uuid
|
13
13
|
|
14
14
|
import yaml
|
@@ -69,7 +69,10 @@ class ESPForceValue:
|
|
69
69
|
pass
|
70
70
|
|
71
71
|
|
72
|
-
def make_data_base(
|
72
|
+
def make_data_base(
|
73
|
+
value, from_database: ESPHomeDataBase = None
|
74
|
+
) -> ESPHomeDataBase | Any:
|
75
|
+
"""Wrap a value in a ESPHomeDataBase object."""
|
73
76
|
try:
|
74
77
|
value = add_class_to_obj(value, ESPHomeDataBase)
|
75
78
|
if from_database is not None:
|
@@ -102,6 +105,11 @@ def _add_data_ref(fn):
|
|
102
105
|
class ESPHomeLoaderMixin:
|
103
106
|
"""Loader class that keeps track of line numbers."""
|
104
107
|
|
108
|
+
def __init__(self, name: str, yaml_loader: Callable[[str], dict[str, Any]]) -> None:
|
109
|
+
"""Initialize the loader."""
|
110
|
+
self.name = name
|
111
|
+
self.yaml_loader = yaml_loader
|
112
|
+
|
105
113
|
@_add_data_ref
|
106
114
|
def construct_yaml_int(self, node):
|
107
115
|
return super().construct_yaml_int(node)
|
@@ -127,7 +135,7 @@ class ESPHomeLoaderMixin:
|
|
127
135
|
return super().construct_yaml_seq(node)
|
128
136
|
|
129
137
|
@_add_data_ref
|
130
|
-
def construct_yaml_map(self, node):
|
138
|
+
def construct_yaml_map(self, node: yaml.MappingNode) -> OrderedDict[str, Any]:
|
131
139
|
"""Traverses the given mapping node and returns a list of constructed key-value pairs."""
|
132
140
|
assert isinstance(node, yaml.MappingNode)
|
133
141
|
# A list of key-value pairs we find in the current mapping
|
@@ -231,7 +239,7 @@ class ESPHomeLoaderMixin:
|
|
231
239
|
return OrderedDict(pairs)
|
232
240
|
|
233
241
|
@_add_data_ref
|
234
|
-
def construct_env_var(self, node):
|
242
|
+
def construct_env_var(self, node: yaml.Node) -> str:
|
235
243
|
args = node.value.split()
|
236
244
|
# Check for a default value
|
237
245
|
if len(args) > 1:
|
@@ -243,23 +251,23 @@ class ESPHomeLoaderMixin:
|
|
243
251
|
)
|
244
252
|
|
245
253
|
@property
|
246
|
-
def _directory(self):
|
254
|
+
def _directory(self) -> str:
|
247
255
|
return os.path.dirname(self.name)
|
248
256
|
|
249
|
-
def _rel_path(self, *args):
|
257
|
+
def _rel_path(self, *args: str) -> str:
|
250
258
|
return os.path.join(self._directory, *args)
|
251
259
|
|
252
260
|
@_add_data_ref
|
253
|
-
def construct_secret(self, node):
|
261
|
+
def construct_secret(self, node: yaml.Node) -> str:
|
254
262
|
try:
|
255
|
-
secrets =
|
263
|
+
secrets = self.yaml_loader(self._rel_path(SECRET_YAML))
|
256
264
|
except EsphomeError as e:
|
257
265
|
if self.name == CORE.config_path:
|
258
266
|
raise e
|
259
267
|
try:
|
260
268
|
main_config_dir = os.path.dirname(CORE.config_path)
|
261
269
|
main_secret_yml = os.path.join(main_config_dir, SECRET_YAML)
|
262
|
-
secrets =
|
270
|
+
secrets = self.yaml_loader(main_secret_yml)
|
263
271
|
except EsphomeError as er:
|
264
272
|
raise EsphomeError(f"{e}\n{er}") from er
|
265
273
|
|
@@ -272,7 +280,9 @@ class ESPHomeLoaderMixin:
|
|
272
280
|
return val
|
273
281
|
|
274
282
|
@_add_data_ref
|
275
|
-
def construct_include(
|
283
|
+
def construct_include(
|
284
|
+
self, node: yaml.Node
|
285
|
+
) -> dict[str, Any] | OrderedDict[str, Any]:
|
276
286
|
from esphome.const import CONF_VARS
|
277
287
|
|
278
288
|
def extract_file_vars(node):
|
@@ -290,71 +300,93 @@ class ESPHomeLoaderMixin:
|
|
290
300
|
else:
|
291
301
|
file, vars = node.value, None
|
292
302
|
|
293
|
-
result =
|
303
|
+
result = self.yaml_loader(self._rel_path(file))
|
294
304
|
if not vars:
|
295
305
|
vars = {}
|
296
306
|
result = substitute_vars(result, vars)
|
297
307
|
return result
|
298
308
|
|
299
309
|
@_add_data_ref
|
300
|
-
def construct_include_dir_list(self, node):
|
310
|
+
def construct_include_dir_list(self, node: yaml.Node) -> list[dict[str, Any]]:
|
301
311
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
302
|
-
return [
|
312
|
+
return [self.yaml_loader(f) for f in files]
|
303
313
|
|
304
314
|
@_add_data_ref
|
305
|
-
def construct_include_dir_merge_list(self, node):
|
315
|
+
def construct_include_dir_merge_list(self, node: yaml.Node) -> list[dict[str, Any]]:
|
306
316
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
307
317
|
merged_list = []
|
308
318
|
for fname in files:
|
309
|
-
loaded_yaml =
|
319
|
+
loaded_yaml = self.yaml_loader(fname)
|
310
320
|
if isinstance(loaded_yaml, list):
|
311
321
|
merged_list.extend(loaded_yaml)
|
312
322
|
return merged_list
|
313
323
|
|
314
324
|
@_add_data_ref
|
315
|
-
def construct_include_dir_named(
|
325
|
+
def construct_include_dir_named(
|
326
|
+
self, node: yaml.Node
|
327
|
+
) -> OrderedDict[str, dict[str, Any]]:
|
316
328
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
317
329
|
mapping = OrderedDict()
|
318
330
|
for fname in files:
|
319
331
|
filename = os.path.splitext(os.path.basename(fname))[0]
|
320
|
-
mapping[filename] =
|
332
|
+
mapping[filename] = self.yaml_loader(fname)
|
321
333
|
return mapping
|
322
334
|
|
323
335
|
@_add_data_ref
|
324
|
-
def construct_include_dir_merge_named(
|
336
|
+
def construct_include_dir_merge_named(
|
337
|
+
self, node: yaml.Node
|
338
|
+
) -> OrderedDict[str, dict[str, Any]]:
|
325
339
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
326
340
|
mapping = OrderedDict()
|
327
341
|
for fname in files:
|
328
|
-
loaded_yaml =
|
342
|
+
loaded_yaml = self.yaml_loader(fname)
|
329
343
|
if isinstance(loaded_yaml, dict):
|
330
344
|
mapping.update(loaded_yaml)
|
331
345
|
return mapping
|
332
346
|
|
333
347
|
@_add_data_ref
|
334
|
-
def construct_lambda(self, node):
|
348
|
+
def construct_lambda(self, node: yaml.Node) -> Lambda:
|
335
349
|
return Lambda(str(node.value))
|
336
350
|
|
337
351
|
@_add_data_ref
|
338
|
-
def construct_force(self, node):
|
352
|
+
def construct_force(self, node: yaml.Node) -> ESPForceValue:
|
339
353
|
obj = self.construct_scalar(node)
|
340
354
|
return add_class_to_obj(obj, ESPForceValue)
|
341
355
|
|
342
356
|
@_add_data_ref
|
343
|
-
def construct_extend(self, node):
|
357
|
+
def construct_extend(self, node: yaml.Node) -> Extend:
|
344
358
|
return Extend(str(node.value))
|
345
359
|
|
346
360
|
@_add_data_ref
|
347
|
-
def construct_remove(self, node):
|
361
|
+
def construct_remove(self, node: yaml.Node) -> Remove:
|
348
362
|
return Remove(str(node.value))
|
349
363
|
|
350
364
|
|
351
365
|
class ESPHomeLoader(ESPHomeLoaderMixin, FastestAvailableSafeLoader):
|
352
366
|
"""Loader class that keeps track of line numbers."""
|
353
367
|
|
368
|
+
def __init__(
|
369
|
+
self,
|
370
|
+
stream: TextIOBase | BytesIO,
|
371
|
+
name: str,
|
372
|
+
yaml_loader: Callable[[str], dict[str, Any]],
|
373
|
+
) -> None:
|
374
|
+
FastestAvailableSafeLoader.__init__(self, stream)
|
375
|
+
ESPHomeLoaderMixin.__init__(self, name, yaml_loader)
|
376
|
+
|
354
377
|
|
355
378
|
class ESPHomePurePythonLoader(ESPHomeLoaderMixin, PurePythonLoader):
|
356
379
|
"""Loader class that keeps track of line numbers."""
|
357
380
|
|
381
|
+
def __init__(
|
382
|
+
self,
|
383
|
+
stream: TextIOBase | BytesIO,
|
384
|
+
name: str,
|
385
|
+
yaml_loader: Callable[[str], dict[str, Any]],
|
386
|
+
) -> None:
|
387
|
+
PurePythonLoader.__init__(self, stream)
|
388
|
+
ESPHomeLoaderMixin.__init__(self, name, yaml_loader)
|
389
|
+
|
358
390
|
|
359
391
|
for _loader in (ESPHomeLoader, ESPHomePurePythonLoader):
|
360
392
|
_loader.add_constructor("tag:yaml.org,2002:int", _loader.construct_yaml_int)
|
@@ -388,17 +420,30 @@ def load_yaml(fname: str, clear_secrets: bool = True) -> Any:
|
|
388
420
|
return _load_yaml_internal(fname)
|
389
421
|
|
390
422
|
|
391
|
-
def
|
423
|
+
def _load_yaml_internal(fname: str) -> Any:
|
424
|
+
"""Load a YAML file."""
|
425
|
+
try:
|
426
|
+
with open(fname, encoding="utf-8") as f_handle:
|
427
|
+
return parse_yaml(fname, f_handle)
|
428
|
+
except (UnicodeDecodeError, OSError) as err:
|
429
|
+
raise EsphomeError(f"Error reading file {fname}: {err}") from err
|
430
|
+
|
431
|
+
|
432
|
+
def parse_yaml(
|
433
|
+
file_name: str, file_handle: TextIOWrapper, yaml_loader=_load_yaml_internal
|
434
|
+
) -> Any:
|
392
435
|
"""Parse a YAML file."""
|
393
436
|
try:
|
394
|
-
return _load_yaml_internal_with_type(
|
437
|
+
return _load_yaml_internal_with_type(
|
438
|
+
ESPHomeLoader, file_name, file_handle, yaml_loader
|
439
|
+
)
|
395
440
|
except EsphomeError:
|
396
441
|
# Loading failed, so we now load with the Python loader which has more
|
397
442
|
# readable exceptions
|
398
443
|
# Rewind the stream so we can try again
|
399
444
|
file_handle.seek(0, 0)
|
400
445
|
return _load_yaml_internal_with_type(
|
401
|
-
ESPHomePurePythonLoader, file_name, file_handle
|
446
|
+
ESPHomePurePythonLoader, file_name, file_handle, yaml_loader
|
402
447
|
)
|
403
448
|
|
404
449
|
|
@@ -435,23 +480,14 @@ def substitute_vars(config, vars):
|
|
435
480
|
return result
|
436
481
|
|
437
482
|
|
438
|
-
def _load_yaml_internal(fname: str) -> Any:
|
439
|
-
"""Load a YAML file."""
|
440
|
-
try:
|
441
|
-
with open(fname, encoding="utf-8") as f_handle:
|
442
|
-
return parse_yaml(fname, f_handle)
|
443
|
-
except (UnicodeDecodeError, OSError) as err:
|
444
|
-
raise EsphomeError(f"Error reading file {fname}: {err}") from err
|
445
|
-
|
446
|
-
|
447
483
|
def _load_yaml_internal_with_type(
|
448
484
|
loader_type: type[ESPHomeLoader] | type[ESPHomePurePythonLoader],
|
449
485
|
fname: str,
|
450
486
|
content: TextIOWrapper,
|
487
|
+
yaml_loader: Any,
|
451
488
|
) -> Any:
|
452
489
|
"""Load a YAML file."""
|
453
|
-
loader = loader_type(content)
|
454
|
-
loader.name = fname
|
490
|
+
loader = loader_type(content, fname, yaml_loader)
|
455
491
|
try:
|
456
492
|
return loader.get_single_data() or OrderedDict()
|
457
493
|
except yaml.YAMLError as exc:
|
@@ -470,7 +506,7 @@ def dump(dict_, show_secrets=False):
|
|
470
506
|
)
|
471
507
|
|
472
508
|
|
473
|
-
def _is_file_valid(name):
|
509
|
+
def _is_file_valid(name: str) -> bool:
|
474
510
|
"""Decide if a file is valid."""
|
475
511
|
return not name.startswith(".")
|
476
512
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: esphome
|
3
|
-
Version: 2025.4.
|
3
|
+
Version: 2025.4.1
|
4
4
|
Summary: ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems.
|
5
5
|
Author-email: The ESPHome Authors <esphome@openhomefoundation.org>
|
6
6
|
License: MIT
|
@@ -39,7 +39,7 @@ Requires-Dist: esptool==4.8.1
|
|
39
39
|
Requires-Dist: click==8.1.7
|
40
40
|
Requires-Dist: esphome-dashboard==20250415.0
|
41
41
|
Requires-Dist: aioesphomeapi==29.10.0
|
42
|
-
Requires-Dist: zeroconf==0.146.
|
42
|
+
Requires-Dist: zeroconf==0.146.5
|
43
43
|
Requires-Dist: puremagic==1.28
|
44
44
|
Requires-Dist: ruamel.yaml==0.18.10
|
45
45
|
Requires-Dist: esphome-glyphsets==0.2.0
|
@@ -1,11 +1,11 @@
|
|
1
1
|
esphome/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
esphome/__main__.py,sha256=
|
2
|
+
esphome/__main__.py,sha256=u8FUFrXqmO17I_HIFz_t8N-O7Cma7QiHzCnW4ARp_VQ,32617
|
3
3
|
esphome/automation.py,sha256=9xmW3AmWDd2oKB7zF-UITYIiSci8ys8qiylK-rcU7Rg,15689
|
4
4
|
esphome/codegen.py,sha256=GePHUM7xdXb_Pil59SHVsXg2F4VBPgkH-Fz2PDX8Z54,1873
|
5
5
|
esphome/config.py,sha256=fFrDYbhWY1xn_onAl_0jwlg9D8NkK_FdKULTlnjZtxs,39832
|
6
6
|
esphome/config_helpers.py,sha256=MKf_wzO35nn41FvigXE0iYKDslPgL2ruf8R-EPtTT2I,3256
|
7
|
-
esphome/config_validation.py,sha256=
|
8
|
-
esphome/const.py,sha256=
|
7
|
+
esphome/config_validation.py,sha256=cjOlphJs-ybsA2VlXXPY-lYq80Vm2uPJ8oIXtWhiPU4,62490
|
8
|
+
esphome/const.py,sha256=UC1S6lqRz-unu1Uod0Ml5ej8ZG7qAToiFVU2iLZBNbc,40828
|
9
9
|
esphome/coroutine.py,sha256=j_14z8dIIzIBeuNO30D4c1RJvMMt1xZFZ58Evd-EvJA,9344
|
10
10
|
esphome/cpp_generator.py,sha256=1g-y3fxWSrd5Kpbz6DrJXaQajjuwQiTIaTRIz9n7svI,31237
|
11
11
|
esphome/cpp_helpers.py,sha256=6C2vNbOIhZKi43xRVlk5hp9GfshfBn-rc5D_ZFUEYaE,4801
|
@@ -16,7 +16,7 @@ esphome/final_validate.py,sha256=EPhbU4xyEL3POdSY7oygyAIVvkeYM7qH-6eZWb76DFE,189
|
|
16
16
|
esphome/git.py,sha256=rKb5JUc05nbRlvR4tRWGL851ANZUYuS7YZp5Tm5wHjE,6296
|
17
17
|
esphome/helpers.py,sha256=2mQ0eyOLjdjaLRL6jdcJfg4UMnqEFY8ORrmEGc5yNHc,12435
|
18
18
|
esphome/loader.py,sha256=5C-agEUY5AnES6Tdn8KTfot89HIQPeGYu8W1s4ZqT9M,6821
|
19
|
-
esphome/log.py,sha256=
|
19
|
+
esphome/log.py,sha256=XqVmsRvi4hHUkjcjwTSFBYbbXonNeoRKPE9bx9kfWf0,2181
|
20
20
|
esphome/mqtt.py,sha256=jjmdEk-_ov_pAuy-FqNPQlPB1VOJEs8iFi4pe2gdiTM,9223
|
21
21
|
esphome/pins.py,sha256=wO0d-2qn0fhT6WEN0H0AmYRSH90jW154hZT7RewMGYI,10713
|
22
22
|
esphome/platformio_api.py,sha256=OEWhPZ2NQnTrZ3Vtm0IqW0E-xE7EyVhs5w3OtT2xfDY,11905
|
@@ -25,10 +25,10 @@ esphome/storage_json.py,sha256=VyIQDo7hHTIYEeLJTO5cq6I_nOWTlvFVvxqvXd6cgg4,10124
|
|
25
25
|
esphome/types.py,sha256=xJaCRRyYuJiRo32mns9v-YeYB6w12NAT8vMSk9ZmJl8,430
|
26
26
|
esphome/util.py,sha256=sKW1kNMRle3bOGrw9Rga32ZfSDXYMbQeQeVKxFEumJs,9329
|
27
27
|
esphome/voluptuous_schema.py,sha256=Z5nhm8lM4H4D-RB7hi4aCKgPiVLuIZ5EULkC0X4QUjY,9345
|
28
|
-
esphome/vscode.py,sha256=
|
28
|
+
esphome/vscode.py,sha256=NtCZkDwckoHrM9ZPmyMBE0q29nqd899VjvISkojsLMw,3991
|
29
29
|
esphome/wizard.py,sha256=BO89_Y9Z6T8kvC5ZrQGPZzT5Rl9vXpte9L2hqr6CeOk,15349
|
30
30
|
esphome/writer.py,sha256=nJSeC5kZesf9EL4nbsWwhMRq7wPnZPjhP0gLZbVTkvI,10999
|
31
|
-
esphome/yaml_util.py,sha256=
|
31
|
+
esphome/yaml_util.py,sha256=pHw9fJzU0sr180ntmdLZh7k7HQ5giSHkCJzdIgTi_jg,22919
|
32
32
|
esphome/zeroconf.py,sha256=IuAKqtvDCi4uvLKCbLxrP-DFrXVm1I9icbryrCkenAA,6383
|
33
33
|
esphome/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
34
|
esphome/components/a01nyub/__init__.py,sha256=d_xNluCS0T63CxdXJGuw7raK7G9vAEwXNJpnA9GthzA,34
|
@@ -143,7 +143,7 @@ esphome/components/alpha3/alpha3.cpp,sha256=1zSC6RmxRxmLFFwRq-pY1BbUWqNiB6ZMOkzf
|
|
143
143
|
esphome/components/alpha3/alpha3.h,sha256=tiCloEGqw9rHdIOocRskj50Z32DiWo6aVUjUk-tRAb8,3405
|
144
144
|
esphome/components/alpha3/sensor.py,sha256=6qSx-_JzQ0wK8aml1LLHqm-u0L0ABX3o8dgqqwdpNvQ,2749
|
145
145
|
esphome/components/am2315c/__init__.py,sha256=_LBsZwU4Hpwdgs3o5uioFVeClSE5fK8k_FZB2MWSADE,30
|
146
|
-
esphome/components/am2315c/am2315c.cpp,sha256=
|
146
|
+
esphome/components/am2315c/am2315c.cpp,sha256=azPE7NUg2saRKmzz5p7hpIu6eMcyglu4OqnV7BMLj4w,5529
|
147
147
|
esphome/components/am2315c/am2315c.h,sha256=xJyLj_vUnDACJ0LehomCzXKWnqWYUmmr9OvjpfdrteQ,2047
|
148
148
|
esphome/components/am2315c/sensor.py,sha256=Y3tt7aOi12IsrfbS9fAHec9BkV0hz3PfmviT-nDyfX0,1702
|
149
149
|
esphome/components/am2320/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -380,7 +380,7 @@ esphome/components/ble_scanner/text_sensor.py,sha256=yOB-AMBbNwJ0K9zYXh3ZedA42Os
|
|
380
380
|
esphome/components/bluetooth_proxy/__init__.py,sha256=yBpHNPhRuw7B_LKUvGFZLnrqItID31kQG-DTT679uu8,3282
|
381
381
|
esphome/components/bluetooth_proxy/bluetooth_connection.cpp,sha256=KBSjOMljcqOsJ0hDSuJjhi8A9GK0_JnL9CPMfs1CDkc,11223
|
382
382
|
esphome/components/bluetooth_proxy/bluetooth_connection.h,sha256=oR0r7QAUNABFMKB_anI_l7lI-iOE6RbyBPkDozoC14Y,1171
|
383
|
-
esphome/components/bluetooth_proxy/bluetooth_proxy.cpp,sha256=
|
383
|
+
esphome/components/bluetooth_proxy/bluetooth_proxy.cpp,sha256=J5365iSzQ6C61hAAHqnd1jBhjPqp0dsmiat0mDLWv_Q,22466
|
384
384
|
esphome/components/bluetooth_proxy/bluetooth_proxy.h,sha256=lEx8Qx2fcjkBU24vT39VUUuwkVJdQ2cB0lG9hTp0lM8,5144
|
385
385
|
esphome/components/bme280_base/__init__.py,sha256=KQhkrj8Ny2lMRUdJXaem5z3-fiR2J82b9AGe58xnZgE,3688
|
386
386
|
esphome/components/bme280_base/bme280_base.cpp,sha256=st3cMKvdG49rHF-pRfplpqhcFAfLZ_YxNmGouiPUQH4,12989
|
@@ -754,7 +754,7 @@ esphome/components/endstop/endstop_cover.h,sha256=RRAAHaZRkRjH9Q2KMLDCoGnQ44Z_lC
|
|
754
754
|
esphome/components/ens160/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
755
755
|
esphome/components/ens160/sensor.py,sha256=JmqJW89ItAMvLqzpgrwWuLsNJctyV-_6i18t4rb-KcA,164
|
756
756
|
esphome/components/ens160_base/__init__.py,sha256=VGWuu4IdB7GWLOns49nmj1dWQAUD3FmTYyyxYRRqMAI,2473
|
757
|
-
esphome/components/ens160_base/ens160_base.cpp,sha256=
|
757
|
+
esphome/components/ens160_base/ens160_base.cpp,sha256=PRgqcB07kwVCQuquMFx5SjtT8j5ON3ZB-a6x2m2yn0M,9982
|
758
758
|
esphome/components/ens160_base/ens160_base.h,sha256=u8rmUObUBj9JtxNJLjGS_Mv4ZhSmd0R9NwJeNX4D-yo,1732
|
759
759
|
esphome/components/ens160_i2c/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
760
760
|
esphome/components/ens160_i2c/ens160_i2c.cpp,sha256=qXi0VlzYvveeoNPMJh6DmGM_QG-Zc15aKL7T9HS76-0,932
|
@@ -842,7 +842,7 @@ esphome/components/esp32_ble_server/ble_service.h,sha256=BvKpr2fsUlNnviH9gdokI7I
|
|
842
842
|
esphome/components/esp32_ble_tracker/__init__.py,sha256=mfStrLvJxJcTc1koz1grSqbslqG0SxCpQfi1899vRZk,14649
|
843
843
|
esphome/components/esp32_ble_tracker/automation.h,sha256=0pDA6EX__f14sT0KJwcnqg7UOsueKjjegHPznQj9biw,3795
|
844
844
|
esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp,sha256=-h-yvcDYOCk9zKLmMo45aroEg5vguELxJ3YiW8X-mYA,27960
|
845
|
-
esphome/components/esp32_ble_tracker/esp32_ble_tracker.h,sha256=
|
845
|
+
esphome/components/esp32_ble_tracker/esp32_ble_tracker.h,sha256=D5YTrA5WROUkupXP5uW5y_xqAmfAoT3xxuHHsQ0-Dso,9488
|
846
846
|
esphome/components/esp32_camera/__init__.py,sha256=JL1umjoPo8qLDUaFYQWI34j-ItCshy8COQgn2sa3csM,12630
|
847
847
|
esphome/components/esp32_camera/esp32_camera.cpp,sha256=Ba2nu453rF4FDSlIJwD5sLnzE8ru4kKK4xVCvMdoyac,16960
|
848
848
|
esphome/components/esp32_camera/esp32_camera.h,sha256=3-MKRSBcjDgI3I0uKmt0bGSfp2t6B85Zsjr06tmpa9Q,7590
|
@@ -1524,7 +1524,7 @@ esphome/components/lvgl/helpers.py,sha256=XI3C5IHwoSVlgR32kMxeXTZWK6iW112nmWv5wB
|
|
1524
1524
|
esphome/components/lvgl/keypads.py,sha256=jtQjAG4vbTzI5Pr1IBfrEEPzV_0k4wkKfCMfsef6VT4,2124
|
1525
1525
|
esphome/components/lvgl/lv_validation.py,sha256=8FoODFSzpxWUzRcwk7zOmv6TIpN9yXaHDIJjoCifOiA,13843
|
1526
1526
|
esphome/components/lvgl/lvcode.py,sha256=pTpwXB0ZehgHVMF1y-fAvaTZPTbWfwA-iZwTbl2W9hI,10118
|
1527
|
-
esphome/components/lvgl/lvgl_esphome.cpp,sha256=
|
1527
|
+
esphome/components/lvgl/lvgl_esphome.cpp,sha256=ffClk2SbGPxafbMZRshkkO-4MESBih4ADsfVpbj7cAg,19289
|
1528
1528
|
esphome/components/lvgl/lvgl_esphome.h,sha256=8a5DaKfK0jWa1dQsA0bC0aw_RoPrLXC5vcBzVi4CCXU,13927
|
1529
1529
|
esphome/components/lvgl/lvgl_hal.h,sha256=aZqWpSmKKAB-ZfNxxgxjgASTtLpAZjXJKuoTiPB0qqU,431
|
1530
1530
|
esphome/components/lvgl/lvgl_proxy.h,sha256=JPmVBVh5zD5nraJCN7PqXVmQQlc4CPJe_X9tA6IAtXQ,547
|
@@ -2028,7 +2028,7 @@ esphome/components/online_image/image_decoder.cpp,sha256=p_693Ac8F-vs2n_1AZ7E57H
|
|
2028
2028
|
esphome/components/online_image/image_decoder.h,sha256=A8sU-3m5dkyR8S2wXbeR7v7C5mRSLxrvfvsBPYz3a90,3798
|
2029
2029
|
esphome/components/online_image/jpeg_image.cpp,sha256=1qDTfzp7H6oxuRVBVXXgglourmlcBO4uvxQK6YLDFl4,2867
|
2030
2030
|
esphome/components/online_image/jpeg_image.h,sha256=RxlXrSxgd_j7tXYMGdkU1gVmkWB6Jc0YHuq13NrY9fc,741
|
2031
|
-
esphome/components/online_image/online_image.cpp,sha256=
|
2031
|
+
esphome/components/online_image/online_image.cpp,sha256=NpXUoKdbIJRdPcY5tQ-fxa6WLpTYeRs8sHJnNP2M2pA,10585
|
2032
2032
|
esphome/components/online_image/online_image.h,sha256=40F0zWRI0p6A8pFfQdQ1eD5tnwgCxBDbeNcpCHgeUzk,7177
|
2033
2033
|
esphome/components/online_image/png_image.cpp,sha256=ysXfjX05YPuZaG0wxHg0EiPlj3HlddQqUdDG25W1jpY,2432
|
2034
2034
|
esphome/components/online_image/png_image.h,sha256=oDyTIkyOB2MiKxZ9YmctwN7sbc_E7Qz0PvFxWg9Lip8,783
|
@@ -2197,7 +2197,7 @@ esphome/components/prometheus/__init__.py,sha256=V3QD6_RZk7tY7PDuKNbQzzimbgRJ0hk
|
|
2197
2197
|
esphome/components/prometheus/prometheus_handler.cpp,sha256=CYECmgJoD3rXlcBN5GPrDStNuIT34JAAOmpjLL27F64,30420
|
2198
2198
|
esphome/components/prometheus/prometheus_handler.h,sha256=iw1ecV2tnDMA1H6kk59P0I-fE-P8bOrHkRnURi3epRg,6773
|
2199
2199
|
esphome/components/psram/__init__.py,sha256=fmi0xiOuhBdYMt5Wab9PetwRLCbPEz7PtmZHf0CEXzo,3983
|
2200
|
-
esphome/components/psram/psram.cpp,sha256=
|
2200
|
+
esphome/components/psram/psram.cpp,sha256=ryng74NZ0ok4miBDb21vgwDjl2IWFirZXeh3S4tNfNY,1509
|
2201
2201
|
esphome/components/psram/psram.h,sha256=LdElwxbKK68o4J9sdmMX8RZn5D94lXhCCSDm83Ge2jc,239
|
2202
2202
|
esphome/components/pulse_counter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2203
2203
|
esphome/components/pulse_counter/automation.h,sha256=y-QRATOjByPNkmMaTlaIwvO3q1hpJyifb39GV85CS7c,644
|
@@ -2655,10 +2655,10 @@ esphome/components/sm300d2/sm300d2.h,sha256=YDd_1VQ0Bq0KhWgtvsJLmuXdIRG8purGyxmU
|
|
2655
2655
|
esphome/components/sml/__init__.py,sha256=ibRZmFRQFxOAJ9-YC_00_FYUGQSn2UcFy_9mAKfEg3g,1795
|
2656
2656
|
esphome/components/sml/automation.h,sha256=lY2a8F41GCJB03oPWj4fBJ_3VlXgSc7HKwkVzVmPLqc,411
|
2657
2657
|
esphome/components/sml/constants.h,sha256=bBhl2KSbp7c44Ah4qcVxGwVGMq5na8JgSLwu-Zk-uUE,639
|
2658
|
-
esphome/components/sml/sml.cpp,sha256=
|
2659
|
-
esphome/components/sml/sml.h,sha256=
|
2660
|
-
esphome/components/sml/sml_parser.cpp,sha256=
|
2661
|
-
esphome/components/sml/sml_parser.h,sha256=
|
2658
|
+
esphome/components/sml/sml.cpp,sha256=G0AYjyk8VvP1V_BEKgsXe_eH-P-MouyZENciorrUAHg,4210
|
2659
|
+
esphome/components/sml/sml.h,sha256=5xTtlwcoKVfvBN3IXoB6gKIvni85edLL6z_865SqNaE,1330
|
2660
|
+
esphome/components/sml/sml_parser.cpp,sha256=oNOcV2mPUzXNY0oYRfOxHM9i51ODw3vWNdxeyhH9N7M,5051
|
2661
|
+
esphome/components/sml/sml_parser.h,sha256=bZk5KCQnIjlRUEjnIR2SfpSCe835BqJAlTVGvFkJ3i0,1812
|
2662
2662
|
esphome/components/sml/sensor/__init__.py,sha256=jlZBTGgveDgAtiLdpJzyumU4DiKyZgvTOY6m3q09arg,910
|
2663
2663
|
esphome/components/sml/sensor/sml_sensor.cpp,sha256=onWh6gi584Qy8TaYgnRi5K4nMUkS39P8_liCTTKW5JM,1106
|
2664
2664
|
esphome/components/sml/sensor/sml_sensor.h,sha256=QypjAdqlNPIVLP77YuxASVRJVwjITCuoc5q0MvzUjNY,420
|
@@ -3220,7 +3220,7 @@ esphome/components/wake_on_lan/button.py,sha256=QQwzh-kUVI8RJVxCP_JpQUk0A9lDDf-c
|
|
3220
3220
|
esphome/components/wake_on_lan/wake_on_lan.cpp,sha256=6rxv_zyBNuYUn-DoahTna0qusEkw4KuU9ccvWU3ZZTY,3114
|
3221
3221
|
esphome/components/wake_on_lan/wake_on_lan.h,sha256=46_1RmAkbCIzHZc0m4ZuJgdO2QHkiWjGuB7hw7MgKZM,984
|
3222
3222
|
esphome/components/watchdog/__init__.py,sha256=phrvkU9sRMp2iVLKx5pNCG11R1HtrJChggVbad-OVWA,26
|
3223
|
-
esphome/components/watchdog/watchdog.cpp,sha256=
|
3223
|
+
esphome/components/watchdog/watchdog.cpp,sha256=A8--WFI3ccw62n7A-MZSmwtO_I2g2rC4bpEUB-kbEWo,1683
|
3224
3224
|
esphome/components/watchdog/watchdog.h,sha256=8Ro3Kgi9C1bYFBkNEeKc188EK63uI48VuzhF5yHPuCk,400
|
3225
3225
|
esphome/components/waveshare_epaper/__init__.py,sha256=4Nn7UhpMJ9oSbuLdyVEW7G9PlIey2v33SWRNVizt9Oc,30
|
3226
3226
|
esphome/components/waveshare_epaper/display.py,sha256=DBEN5glBcXQBvv0bwLcddNzP-fkeyk-yKeHsfPXw1nM,9794
|
@@ -3423,7 +3423,7 @@ esphome/components/zyaura/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
3423
3423
|
esphome/components/zyaura/sensor.py,sha256=cSmO4ozYdi4ZD7NK4lmYjswWVmJoDvEruU1HhGrZSE0,2476
|
3424
3424
|
esphome/components/zyaura/zyaura.cpp,sha256=F7WM8XAZ5MYuCD3eERm2_IA-O7sP1i-A-yF5TV4PqX8,3679
|
3425
3425
|
esphome/components/zyaura/zyaura.h,sha256=yWrcYj_CnLDyopkuIVySJy5dB-R5X9zwm5fWjBDTSts,2384
|
3426
|
-
esphome/core/__init__.py,sha256=
|
3426
|
+
esphome/core/__init__.py,sha256=RCYQQQLlJxABwGyhSQJ9-kCwMOZL-uSVhBEnHUfEeOU,26735
|
3427
3427
|
esphome/core/application.cpp,sha256=DOhq0rTYu_dNcUCavHYVYASQZ5QzVOXMWVTaO7YTdnM,4680
|
3428
3428
|
esphome/core/application.h,sha256=jepd6I9BBa48ByAXoLnUE7ddtlHiUS5uuKaMaJOD0x0,17721
|
3429
3429
|
esphome/core/automation.h,sha256=UQQD9De3eiaopvzYQG89SxkBfnL5QaiR6bvkk2RxV8k,7332
|
@@ -3481,9 +3481,9 @@ esphome/dashboard/util/itertools.py,sha256=8eLrWEWmICLtXNxkKdYPQV0c_N4GEz8m9Npnb
|
|
3481
3481
|
esphome/dashboard/util/password.py,sha256=cQz3b9B-ijTe7zS6BeCW0hc3pWv6JjC78jmnycYYAh8,321
|
3482
3482
|
esphome/dashboard/util/subprocess.py,sha256=T8EW6dbU4LPd2DG1dRrdh8li71tt6J1isn411poMhkk,1022
|
3483
3483
|
esphome/dashboard/util/text.py,sha256=ENDnfN4O0NdA3CKVJjQYabFbwbrsIhVKrAMQe53qYu4,534
|
3484
|
-
esphome-2025.4.
|
3485
|
-
esphome-2025.4.
|
3486
|
-
esphome-2025.4.
|
3487
|
-
esphome-2025.4.
|
3488
|
-
esphome-2025.4.
|
3489
|
-
esphome-2025.4.
|
3484
|
+
esphome-2025.4.1.dist-info/licenses/LICENSE,sha256=HzEjkBInJe44L4WvAOPfhPJJDNj6YbnqFyvGWRzArGM,36664
|
3485
|
+
esphome-2025.4.1.dist-info/METADATA,sha256=jj3WZGaXL8BXOWuytPx-HxMTDPq2ycMg7c89WNWW0EM,3671
|
3486
|
+
esphome-2025.4.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
3487
|
+
esphome-2025.4.1.dist-info/entry_points.txt,sha256=mIxVNuWtbYzeEcaWCl-AQ-97aBOWbnYBAK8nbF6P4M0,50
|
3488
|
+
esphome-2025.4.1.dist-info/top_level.txt,sha256=0GSXEW3cnITpgG3qnsSMz0qoqJHAFyfw7Y8MVtEf1Yk,8
|
3489
|
+
esphome-2025.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|