esphome 2025.4.0b1__py3-none-any.whl → 2025.4.0b3__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/api/api_frame_helper.cpp +4 -0
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +7 -3
- esphome/components/lvgl/automation.py +14 -2
- esphome/components/lvgl/encoders.py +3 -2
- esphome/components/lvgl/lvcode.py +2 -1
- esphome/components/lvgl/lvgl_esphome.h +2 -0
- esphome/components/lvgl/number/__init__.py +23 -20
- esphome/components/lvgl/number/lvgl_number.h +27 -14
- esphome/components/lvgl/schemas.py +3 -1
- esphome/components/lvgl/select/__init__.py +11 -13
- esphome/components/lvgl/select/lvgl_select.h +25 -18
- esphome/components/lvgl/widgets/buttonmatrix.py +2 -2
- esphome/components/lvgl/widgets/canvas.py +7 -3
- esphome/components/lvgl/widgets/meter.py +3 -1
- 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/speaker/media_player/audio_pipeline.cpp +3 -2
- esphome/config_validation.py +0 -42
- esphome/const.py +1 -1
- esphome/core/__init__.py +0 -1
- esphome/vscode.py +27 -8
- esphome/yaml_util.py +75 -39
- {esphome-2025.4.0b1.dist-info → esphome-2025.4.0b3.dist-info}/METADATA +4 -4
- {esphome-2025.4.0b1.dist-info → esphome-2025.4.0b3.dist-info}/RECORD +32 -32
- {esphome-2025.4.0b1.dist-info → esphome-2025.4.0b3.dist-info}/WHEEL +0 -0
- {esphome-2025.4.0b1.dist-info → esphome-2025.4.0b3.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.0b1.dist-info → esphome-2025.4.0b3.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.0b1.dist-info → esphome-2025.4.0b3.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
|
|
@@ -311,6 +311,10 @@ APIError APINoiseFrameHelper::state_action_() {
|
|
311
311
|
const std::string &name = App.get_name();
|
312
312
|
const uint8_t *name_ptr = reinterpret_cast<const uint8_t *>(name.c_str());
|
313
313
|
msg.insert(msg.end(), name_ptr, name_ptr + name.size() + 1);
|
314
|
+
// node mac, terminated by null byte
|
315
|
+
const std::string &mac = get_mac_address();
|
316
|
+
const uint8_t *mac_ptr = reinterpret_cast<const uint8_t *>(mac.c_str());
|
317
|
+
msg.insert(msg.end(), mac_ptr, mac_ptr + mac.size() + 1);
|
314
318
|
|
315
319
|
aerr = write_frame_(msg.data(), msg.size());
|
316
320
|
if (aerr != APIError::OK)
|
@@ -30,8 +30,12 @@ void AXS15231Touchscreen::setup() {
|
|
30
30
|
this->interrupt_pin_->setup();
|
31
31
|
this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
|
32
32
|
}
|
33
|
-
this->x_raw_max_
|
34
|
-
|
33
|
+
if (this->x_raw_max_ == 0) {
|
34
|
+
this->x_raw_max_ = this->display_->get_native_width();
|
35
|
+
}
|
36
|
+
if (this->y_raw_max_ == 0) {
|
37
|
+
this->y_raw_max_ = this->display_->get_native_height();
|
38
|
+
}
|
35
39
|
ESP_LOGCONFIG(TAG, "AXS15231 Touchscreen setup complete");
|
36
40
|
}
|
37
41
|
|
@@ -44,7 +48,7 @@ void AXS15231Touchscreen::update_touches() {
|
|
44
48
|
err = this->read(data, sizeof(data));
|
45
49
|
ERROR_CHECK(err);
|
46
50
|
this->status_clear_warning();
|
47
|
-
if (data[0] != 0) // no touches
|
51
|
+
if (data[0] != 0 || data[1] == 0) // no touches
|
48
52
|
return;
|
49
53
|
uint16_t x = encode_uint16(data[2] & 0xF, data[3]);
|
50
54
|
uint16_t y = encode_uint16(data[4] & 0xF, data[5]);
|
@@ -4,6 +4,7 @@ from esphome import automation
|
|
4
4
|
import esphome.codegen as cg
|
5
5
|
import esphome.config_validation as cv
|
6
6
|
from esphome.const import CONF_ACTION, CONF_GROUP, CONF_ID, CONF_TIMEOUT
|
7
|
+
from esphome.core import Lambda
|
7
8
|
from esphome.cpp_generator import TemplateArguments, get_variable
|
8
9
|
from esphome.cpp_types import nullptr
|
9
10
|
|
@@ -64,7 +65,14 @@ async def action_to_code(
|
|
64
65
|
action_id,
|
65
66
|
template_arg,
|
66
67
|
args,
|
68
|
+
config=None,
|
67
69
|
):
|
70
|
+
# Ensure all required ids have been processed, so our LambdaContext doesn't get context-switched.
|
71
|
+
if config:
|
72
|
+
for lamb in config.values():
|
73
|
+
if isinstance(lamb, Lambda):
|
74
|
+
for id_ in lamb.requires_ids:
|
75
|
+
await get_variable(id_)
|
68
76
|
await wait_for_widgets()
|
69
77
|
async with LambdaContext(parameters=args, where=action_id) as context:
|
70
78
|
for widget in widgets:
|
@@ -84,7 +92,9 @@ async def update_to_code(config, action_id, template_arg, args):
|
|
84
92
|
lv.event_send(widget.obj, UPDATE_EVENT, nullptr)
|
85
93
|
|
86
94
|
widgets = await get_widgets(config[CONF_ID])
|
87
|
-
return await action_to_code(
|
95
|
+
return await action_to_code(
|
96
|
+
widgets, do_update, action_id, template_arg, args, config
|
97
|
+
)
|
88
98
|
|
89
99
|
|
90
100
|
@automation.register_condition(
|
@@ -348,4 +358,6 @@ async def obj_update_to_code(config, action_id, template_arg, args):
|
|
348
358
|
await set_obj_properties(widget, config)
|
349
359
|
|
350
360
|
widgets = await get_widgets(config[CONF_ID])
|
351
|
-
return await action_to_code(
|
361
|
+
return await action_to_code(
|
362
|
+
widgets, do_update, action_id, template_arg, args, config
|
363
|
+
)
|
@@ -18,6 +18,7 @@ from .helpers import lvgl_components_required, requires_component
|
|
18
18
|
from .lvcode import lv, lv_add, lv_assign, lv_expr, lv_Pvariable
|
19
19
|
from .schemas import ENCODER_SCHEMA
|
20
20
|
from .types import lv_group_t, lv_indev_type_t, lv_key_t
|
21
|
+
from .widgets import get_widgets
|
21
22
|
|
22
23
|
ENCODERS_CONFIG = cv.ensure_list(
|
23
24
|
ENCODER_SCHEMA.extend(
|
@@ -76,5 +77,5 @@ async def encoders_to_code(var, config, default_group):
|
|
76
77
|
async def initial_focus_to_code(config):
|
77
78
|
for enc_conf in config[CONF_ENCODERS]:
|
78
79
|
if default_focus := enc_conf.get(CONF_INITIAL_FOCUS):
|
79
|
-
|
80
|
-
lv.group_focus_obj(obj)
|
80
|
+
widget = await get_widgets(default_focus)
|
81
|
+
lv.group_focus_obj(widget[0].obj)
|
@@ -173,7 +173,8 @@ class LambdaContext(CodeContext):
|
|
173
173
|
|
174
174
|
class LvContext(LambdaContext):
|
175
175
|
"""
|
176
|
-
Code generation into the LVGL initialisation code
|
176
|
+
Code generation into the LVGL initialisation code, called before setup() and loop()
|
177
|
+
Basically just does cg.add, so now fairly redundant.
|
177
178
|
"""
|
178
179
|
|
179
180
|
added_lambda_count = 0
|
@@ -63,10 +63,12 @@ inline void lv_disp_set_bg_image(lv_disp_t *disp, esphome::image::Image *image)
|
|
63
63
|
inline void lv_obj_set_style_bg_img_src(lv_obj_t *obj, esphome::image::Image *image, lv_style_selector_t selector) {
|
64
64
|
lv_obj_set_style_bg_img_src(obj, image->get_lv_img_dsc(), selector);
|
65
65
|
}
|
66
|
+
#ifdef USE_LVGL_CANVAS
|
66
67
|
inline void lv_canvas_draw_img(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, image::Image *image,
|
67
68
|
lv_draw_img_dsc_t *dsc) {
|
68
69
|
lv_canvas_draw_img(canvas, x, y, image->get_lv_img_dsc(), dsc);
|
69
70
|
}
|
71
|
+
#endif
|
70
72
|
|
71
73
|
#ifdef USE_LVGL_METER
|
72
74
|
inline lv_meter_indicator_t *lv_meter_add_needle_img(lv_obj_t *obj, lv_meter_scale_t *scale, esphome::image::Image *src,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import number
|
3
3
|
import esphome.config_validation as cv
|
4
|
+
from esphome.const import CONF_RESTORE_VALUE
|
4
5
|
from esphome.cpp_generator import MockObj
|
5
6
|
|
6
7
|
from ..defines import CONF_ANIMATED, CONF_UPDATE_ON_RELEASE, CONF_WIDGET
|
@@ -10,21 +11,21 @@ from ..lvcode import (
|
|
10
11
|
EVENT_ARG,
|
11
12
|
UPDATE_EVENT,
|
12
13
|
LambdaContext,
|
13
|
-
|
14
|
+
ReturnStatement,
|
14
15
|
lv,
|
15
|
-
lv_add,
|
16
16
|
lvgl_static,
|
17
17
|
)
|
18
18
|
from ..types import LV_EVENT, LvNumber, lvgl_ns
|
19
19
|
from ..widgets import get_widgets, wait_for_widgets
|
20
20
|
|
21
|
-
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number)
|
21
|
+
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number, cg.Component)
|
22
22
|
|
23
23
|
CONFIG_SCHEMA = number.number_schema(LVGLNumber).extend(
|
24
24
|
{
|
25
25
|
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
26
26
|
cv.Optional(CONF_ANIMATED, default=True): animated,
|
27
27
|
cv.Optional(CONF_UPDATE_ON_RELEASE, default=False): cv.boolean,
|
28
|
+
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
|
28
29
|
}
|
29
30
|
)
|
30
31
|
|
@@ -32,32 +33,34 @@ CONFIG_SCHEMA = number.number_schema(LVGLNumber).extend(
|
|
32
33
|
async def to_code(config):
|
33
34
|
widget = await get_widgets(config, CONF_WIDGET)
|
34
35
|
widget = widget[0]
|
35
|
-
var = await number.new_number(
|
36
|
-
config,
|
37
|
-
max_value=widget.get_max(),
|
38
|
-
min_value=widget.get_min(),
|
39
|
-
step=widget.get_step(),
|
40
|
-
)
|
41
|
-
|
42
36
|
await wait_for_widgets()
|
37
|
+
async with LambdaContext([], return_type=cg.float_) as value:
|
38
|
+
value.add(ReturnStatement(widget.get_value()))
|
43
39
|
async with LambdaContext([(cg.float_, "v")]) as control:
|
44
40
|
await widget.set_property(
|
45
41
|
"value", MockObj("v") * MockObj(widget.get_scale()), config[CONF_ANIMATED]
|
46
42
|
)
|
47
43
|
lv.event_send(widget.obj, API_EVENT, cg.nullptr)
|
48
|
-
control.add(var.publish_state(widget.get_value()))
|
49
|
-
async with LambdaContext(EVENT_ARG) as event:
|
50
|
-
event.add(var.publish_state(widget.get_value()))
|
51
44
|
event_code = (
|
52
45
|
LV_EVENT.VALUE_CHANGED
|
53
46
|
if not config[CONF_UPDATE_ON_RELEASE]
|
54
47
|
else LV_EVENT.RELEASED
|
55
48
|
)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
49
|
+
var = await number.new_number(
|
50
|
+
config,
|
51
|
+
await control.get_lambda(),
|
52
|
+
await value.get_lambda(),
|
53
|
+
event_code,
|
54
|
+
config[CONF_RESTORE_VALUE],
|
55
|
+
max_value=widget.get_max(),
|
56
|
+
min_value=widget.get_min(),
|
57
|
+
step=widget.get_step(),
|
58
|
+
)
|
59
|
+
async with LambdaContext(EVENT_ARG) as event:
|
60
|
+
event.add(var.on_value())
|
61
|
+
await cg.register_component(var, config)
|
62
|
+
cg.add(
|
63
|
+
lvgl_static.add_event_cb(
|
64
|
+
widget.obj, await event.get_lambda(), UPDATE_EVENT, event_code
|
62
65
|
)
|
63
|
-
|
66
|
+
)
|
@@ -3,33 +3,46 @@
|
|
3
3
|
#include <utility>
|
4
4
|
|
5
5
|
#include "esphome/components/number/number.h"
|
6
|
-
#include "esphome/core/automation.h"
|
7
6
|
#include "esphome/core/component.h"
|
8
7
|
#include "esphome/core/preferences.h"
|
9
8
|
|
10
9
|
namespace esphome {
|
11
10
|
namespace lvgl {
|
12
11
|
|
13
|
-
class LVGLNumber : public number::Number {
|
12
|
+
class LVGLNumber : public number::Number, public Component {
|
14
13
|
public:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
LVGLNumber(std::function<void(float)> control_lambda, std::function<float()> value_lambda, lv_event_code_t event,
|
15
|
+
bool restore)
|
16
|
+
: control_lambda_(std::move(control_lambda)),
|
17
|
+
value_lambda_(std::move(value_lambda)),
|
18
|
+
event_(event),
|
19
|
+
restore_(restore) {}
|
20
|
+
|
21
|
+
void setup() override {
|
22
|
+
float value = this->value_lambda_();
|
23
|
+
if (this->restore_) {
|
24
|
+
this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
|
25
|
+
if (this->pref_.load(&value)) {
|
26
|
+
this->control_lambda_(value);
|
27
|
+
}
|
20
28
|
}
|
29
|
+
this->publish_state(value);
|
21
30
|
}
|
22
31
|
|
32
|
+
void on_value() { this->publish_state(this->value_lambda_()); }
|
33
|
+
|
23
34
|
protected:
|
24
35
|
void control(float value) override {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
this->
|
29
|
-
}
|
36
|
+
this->control_lambda_(value);
|
37
|
+
this->publish_state(value);
|
38
|
+
if (this->restore_)
|
39
|
+
this->pref_.save(&value);
|
30
40
|
}
|
31
|
-
std::function<void(float)> control_lambda_
|
32
|
-
|
41
|
+
std::function<void(float)> control_lambda_;
|
42
|
+
std::function<float()> value_lambda_;
|
43
|
+
lv_event_code_t event_;
|
44
|
+
bool restore_;
|
45
|
+
ESPPreferenceObject pref_{};
|
33
46
|
};
|
34
47
|
|
35
48
|
} // namespace lvgl
|
@@ -81,7 +81,9 @@ ENCODER_SCHEMA = cv.Schema(
|
|
81
81
|
cv.declare_id(LVEncoderListener), requires_component("binary_sensor")
|
82
82
|
),
|
83
83
|
cv.Optional(CONF_GROUP): cv.declare_id(lv_group_t),
|
84
|
-
cv.Optional(df.CONF_INITIAL_FOCUS): cv.
|
84
|
+
cv.Optional(df.CONF_INITIAL_FOCUS): cv.All(
|
85
|
+
LIST_ACTION_SCHEMA, cv.Length(min=1, max=1)
|
86
|
+
),
|
85
87
|
cv.Optional(df.CONF_LONG_PRESS_TIME, default="400ms"): PRESS_TIME,
|
86
88
|
cv.Optional(df.CONF_LONG_PRESS_REPEAT_TIME, default="100ms"): PRESS_TIME,
|
87
89
|
}
|
@@ -1,18 +1,19 @@
|
|
1
|
+
import esphome.codegen as cg
|
1
2
|
from esphome.components import select
|
2
3
|
import esphome.config_validation as cv
|
3
|
-
from esphome.const import CONF_OPTIONS
|
4
|
+
from esphome.const import CONF_ID, CONF_OPTIONS, CONF_RESTORE_VALUE
|
4
5
|
|
5
6
|
from ..defines import CONF_ANIMATED, CONF_WIDGET, literal
|
6
|
-
from ..lvcode import LvContext
|
7
7
|
from ..types import LvSelect, lvgl_ns
|
8
|
-
from ..widgets import get_widgets
|
8
|
+
from ..widgets import get_widgets
|
9
9
|
|
10
|
-
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select)
|
10
|
+
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select, cg.Component)
|
11
11
|
|
12
12
|
CONFIG_SCHEMA = select.select_schema(LVGLSelect).extend(
|
13
13
|
{
|
14
14
|
cv.Required(CONF_WIDGET): cv.use_id(LvSelect),
|
15
15
|
cv.Optional(CONF_ANIMATED, default=False): cv.boolean,
|
16
|
+
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
|
16
17
|
}
|
17
18
|
)
|
18
19
|
|
@@ -21,12 +22,9 @@ async def to_code(config):
|
|
21
22
|
widget = await get_widgets(config, CONF_WIDGET)
|
22
23
|
widget = widget[0]
|
23
24
|
options = widget.config.get(CONF_OPTIONS, [])
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
literal("LV_ANIM_ON" if config[CONF_ANIMATED] else "LV_ANIM_OFF"),
|
31
|
-
)
|
32
|
-
)
|
25
|
+
animated = literal("LV_ANIM_ON" if config[CONF_ANIMATED] else "LV_ANIM_OFF")
|
26
|
+
selector = cg.new_Pvariable(
|
27
|
+
config[CONF_ID], widget.var, animated, config[CONF_RESTORE_VALUE]
|
28
|
+
)
|
29
|
+
await select.register_select(selector, config, options=options)
|
30
|
+
await cg.register_component(selector, config)
|
@@ -11,12 +11,20 @@
|
|
11
11
|
namespace esphome {
|
12
12
|
namespace lvgl {
|
13
13
|
|
14
|
-
class LVGLSelect : public select::Select {
|
14
|
+
class LVGLSelect : public select::Select, public Component {
|
15
15
|
public:
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
LVGLSelect(LvSelectable *widget, lv_anim_enable_t anim, bool restore)
|
17
|
+
: widget_(widget), anim_(anim), restore_(restore) {}
|
18
|
+
|
19
|
+
void setup() override {
|
19
20
|
this->set_options_();
|
21
|
+
if (this->restore_) {
|
22
|
+
size_t index;
|
23
|
+
this->pref_ = global_preferences->make_preference<size_t>(this->get_object_id_hash());
|
24
|
+
if (this->pref_.load(&index))
|
25
|
+
this->widget_->set_selected_index(index, LV_ANIM_OFF);
|
26
|
+
}
|
27
|
+
this->publish();
|
20
28
|
lv_obj_add_event_cb(
|
21
29
|
this->widget_->obj,
|
22
30
|
[](lv_event_t *e) {
|
@@ -24,11 +32,6 @@ class LVGLSelect : public select::Select {
|
|
24
32
|
it->set_options_();
|
25
33
|
},
|
26
34
|
LV_EVENT_REFRESH, this);
|
27
|
-
if (this->initial_state_.has_value()) {
|
28
|
-
this->control(this->initial_state_.value());
|
29
|
-
this->initial_state_.reset();
|
30
|
-
}
|
31
|
-
this->publish();
|
32
35
|
auto lamb = [](lv_event_t *e) {
|
33
36
|
auto *self = static_cast<LVGLSelect *>(e->user_data);
|
34
37
|
self->publish();
|
@@ -37,21 +40,25 @@ class LVGLSelect : public select::Select {
|
|
37
40
|
lv_obj_add_event_cb(this->widget_->obj, lamb, lv_update_event, this);
|
38
41
|
}
|
39
42
|
|
40
|
-
void publish() {
|
43
|
+
void publish() {
|
44
|
+
this->publish_state(this->widget_->get_selected_text());
|
45
|
+
if (this->restore_) {
|
46
|
+
auto index = this->widget_->get_selected_index();
|
47
|
+
this->pref_.save(&index);
|
48
|
+
}
|
49
|
+
}
|
41
50
|
|
42
51
|
protected:
|
43
52
|
void control(const std::string &value) override {
|
44
|
-
|
45
|
-
|
46
|
-
} else {
|
47
|
-
this->initial_state_ = value;
|
48
|
-
}
|
53
|
+
this->widget_->set_selected_text(value, this->anim_);
|
54
|
+
this->publish();
|
49
55
|
}
|
50
56
|
void set_options_() { this->traits.set_options(this->widget_->get_options()); }
|
51
57
|
|
52
|
-
LvSelectable *widget_
|
53
|
-
|
54
|
-
|
58
|
+
LvSelectable *widget_;
|
59
|
+
lv_anim_enable_t anim_;
|
60
|
+
bool restore_;
|
61
|
+
ESPPreferenceObject pref_{};
|
55
62
|
};
|
56
63
|
|
57
64
|
} // namespace lvgl
|
@@ -250,7 +250,7 @@ async def button_update_to_code(config, action_id, template_arg, args):
|
|
250
250
|
widgets = await get_widgets(config[CONF_ID])
|
251
251
|
assert all(isinstance(w, MatrixButton) for w in widgets)
|
252
252
|
|
253
|
-
async def do_button_update(w
|
253
|
+
async def do_button_update(w):
|
254
254
|
if (width := config.get(CONF_WIDTH)) is not None:
|
255
255
|
lv.btnmatrix_set_btn_width(w.obj, w.index, width)
|
256
256
|
if config.get(CONF_SELECTED):
|
@@ -275,5 +275,5 @@ async def button_update_to_code(config, action_id, template_arg, args):
|
|
275
275
|
)
|
276
276
|
|
277
277
|
return await action_to_code(
|
278
|
-
widgets, do_button_update, action_id, template_arg, args
|
278
|
+
widgets, do_button_update, action_id, template_arg, args, config
|
279
279
|
)
|
@@ -97,7 +97,7 @@ async def canvas_fill(config, action_id, template_arg, args):
|
|
97
97
|
async def do_fill(w: Widget):
|
98
98
|
lv.canvas_fill_bg(w.obj, color, opa)
|
99
99
|
|
100
|
-
return await action_to_code(widget, do_fill, action_id, template_arg, args)
|
100
|
+
return await action_to_code(widget, do_fill, action_id, template_arg, args, config)
|
101
101
|
|
102
102
|
|
103
103
|
@automation.register_action(
|
@@ -145,7 +145,9 @@ async def canvas_set_pixel(config, action_id, template_arg, args):
|
|
145
145
|
x, y = point
|
146
146
|
lv.canvas_set_px_opa(w.obj, x, y, opa_var)
|
147
147
|
|
148
|
-
return await action_to_code(
|
148
|
+
return await action_to_code(
|
149
|
+
widget, do_set_pixels, action_id, template_arg, args, config
|
150
|
+
)
|
149
151
|
|
150
152
|
|
151
153
|
DRAW_SCHEMA = cv.Schema(
|
@@ -181,7 +183,9 @@ async def draw_to_code(config, dsc_type, props, do_draw, action_id, template_arg
|
|
181
183
|
lv_assign(getattr(dsc, mapped_prop), value)
|
182
184
|
await do_draw(w, x, y, dsc_addr)
|
183
185
|
|
184
|
-
return await action_to_code(
|
186
|
+
return await action_to_code(
|
187
|
+
widget, action_func, action_id, template_arg, args, config
|
188
|
+
)
|
185
189
|
|
186
190
|
|
187
191
|
RECT_PROPS = {
|
@@ -297,7 +297,9 @@ async def indicator_update_to_code(config, action_id, template_arg, args):
|
|
297
297
|
async def set_value(w: Widget):
|
298
298
|
await set_indicator_values(w.var, w.obj, config)
|
299
299
|
|
300
|
-
return await action_to_code(
|
300
|
+
return await action_to_code(
|
301
|
+
widget, set_value, action_id, template_arg, args, config
|
302
|
+
)
|
301
303
|
|
302
304
|
|
303
305
|
async def set_indicator_values(meter, indicator, config):
|
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);
|