esphome 2024.11.2__py3-none-any.whl → 2024.12.0__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 +1 -1
- esphome/components/adc/adc_sensor.h +7 -8
- esphome/components/adc/adc_sensor_common.cpp +24 -0
- esphome/components/adc/{adc_sensor.cpp → adc_sensor_esp32.cpp} +10 -179
- esphome/components/adc/adc_sensor_esp8266.cpp +58 -0
- esphome/components/adc/adc_sensor_libretiny.cpp +48 -0
- esphome/components/adc/adc_sensor_rp2040.cpp +93 -0
- esphome/components/alarm_control_panel/alarm_control_panel_call.cpp +3 -4
- esphome/components/animation/__init__.py +1 -2
- esphome/components/apds9306/apds9306.cpp +2 -1
- esphome/components/audio/audio.h +1 -1
- esphome/components/bk72xx/__init__.py +1 -1
- esphome/components/cse7766/cse7766.cpp +1 -1
- esphome/components/datetime/datetime_entity.cpp +1 -3
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +2 -2
- esphome/components/dht/dht.cpp +2 -1
- esphome/components/display/display.cpp +10 -6
- esphome/components/display/display.h +14 -0
- esphome/components/display_menu_base/__init__.py +0 -2
- esphome/components/display_menu_base/display_menu_base.cpp +1 -1
- esphome/components/dsmr/dsmr.cpp +1 -1
- esphome/components/esp32/__init__.py +100 -22
- esphome/components/esp32/boards.py +222 -14
- esphome/components/esp32_ble/__init__.py +22 -2
- esphome/components/esp32_ble/ble.cpp +39 -12
- esphome/components/esp32_ble/ble.h +2 -0
- esphome/components/esp32_ble/ble_advertising.cpp +1 -1
- esphome/components/esp32_ble/ble_uuid.cpp +9 -10
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +4 -1
- esphome/components/esp32_camera_web_server/camera_web_server.h +1 -1
- esphome/components/esp32_rmt_led_strip/light.py +3 -3
- esphome/components/esp8266/__init__.py +5 -7
- esphome/components/ezo/ezo.cpp +14 -26
- esphome/components/font/__init__.py +10 -25
- esphome/components/font/font.cpp +5 -3
- esphome/components/graphical_display_menu/__init__.py +2 -0
- esphome/components/haier/hon_climate.cpp +79 -80
- esphome/components/hbridge/switch/__init__.py +44 -0
- esphome/components/hbridge/switch/hbridge_switch.cpp +95 -0
- esphome/components/hbridge/switch/hbridge_switch.h +50 -0
- esphome/components/hitachi_ac344/hitachi_ac344.cpp +4 -2
- esphome/components/hitachi_ac424/hitachi_ac424.cpp +4 -2
- esphome/components/homeassistant/number/homeassistant_number.cpp +3 -0
- esphome/components/hx711/hx711.cpp +1 -1
- esphome/components/hx711/hx711.h +1 -1
- esphome/components/i2c/i2c_bus_esp_idf.cpp +2 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +61 -59
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -17
- esphome/components/ili9xxx/display.py +1 -2
- esphome/components/ili9xxx/ili9xxx_display.cpp +3 -2
- esphome/components/image/__init__.py +1 -2
- esphome/components/logger/logger.cpp +1 -1
- esphome/components/ltr501/ltr501.cpp +1 -1
- esphome/components/lvgl/defines.py +9 -2
- esphome/components/lvgl/lv_validation.py +8 -3
- esphome/components/lvgl/lvgl_esphome.cpp +1 -1
- esphome/components/lvgl/lvgl_esphome.h +19 -0
- esphome/components/lvgl/widgets/animimg.py +12 -17
- esphome/components/lvgl/widgets/img.py +1 -3
- esphome/components/lvgl/widgets/line.py +6 -0
- esphome/components/lvgl/widgets/msgbox.py +2 -1
- esphome/components/matrix_keypad/__init__.py +15 -3
- esphome/components/matrix_keypad/matrix_keypad.cpp +4 -0
- esphome/components/matrix_keypad/matrix_keypad.h +5 -0
- esphome/components/max31865/max31865.cpp +4 -2
- esphome/components/modbus_controller/modbus_controller.cpp +24 -24
- esphome/components/modbus_controller/modbus_controller.h +22 -22
- esphome/components/modbus_controller/number/modbus_number.cpp +8 -8
- esphome/components/modbus_controller/number/modbus_number.h +4 -4
- esphome/components/modbus_controller/output/modbus_output.cpp +7 -6
- esphome/components/modbus_controller/output/modbus_output.h +5 -5
- esphome/components/modbus_controller/select/modbus_select.cpp +4 -3
- esphome/components/modbus_controller/select/modbus_select.h +4 -4
- esphome/components/modbus_controller/switch/modbus_switch.cpp +5 -5
- esphome/components/modbus_controller/switch/modbus_switch.h +2 -2
- esphome/components/mqtt/__init__.py +4 -0
- esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -5
- esphome/components/mqtt/mqtt_backend_esp32.cpp +3 -3
- esphome/components/mqtt/mqtt_client.cpp +4 -0
- esphome/components/mqtt/mqtt_client.h +6 -0
- esphome/components/mqtt/mqtt_climate.cpp +13 -3
- esphome/components/mqtt/mqtt_sensor.cpp +2 -0
- esphome/components/network/ip_address.h +1 -1
- esphome/components/nextion/__init__.py +2 -0
- esphome/components/nextion/automation.h +76 -0
- esphome/components/nextion/base_component.py +1 -0
- esphome/components/nextion/binary_sensor/__init__.py +43 -2
- esphome/components/nextion/display.py +15 -0
- esphome/components/nextion/nextion.cpp +8 -5
- esphome/components/nextion/nextion.h +7 -0
- esphome/components/nextion/nextion_upload_idf.cpp +2 -2
- esphome/components/nextion/sensor/__init__.py +38 -5
- esphome/components/nextion/switch/__init__.py +38 -2
- esphome/components/nextion/text_sensor/__init__.py +37 -2
- esphome/components/nfc/ndef_record.cpp +3 -3
- esphome/components/online_image/__init__.py +1 -0
- esphome/components/online_image/png_image.cpp +4 -0
- esphome/components/opentherm/hub.cpp +6 -7
- esphome/components/opentherm/opentherm.cpp +18 -34
- esphome/components/opentherm/opentherm.h +4 -5
- esphome/components/ota/automation.h +1 -1
- esphome/components/output/float_output.cpp +1 -1
- esphome/components/pca6416a/pca6416a.cpp +5 -3
- esphome/components/pca9554/pca9554.cpp +4 -4
- esphome/components/pipsolar/pipsolar.cpp +2 -2
- esphome/components/pipsolar/switch/pipsolar_switch.cpp +2 -2
- esphome/components/pn532/pn532_mifare_ultralight.cpp +2 -2
- esphome/components/pn7150/pn7150_mifare_ultralight.cpp +2 -2
- esphome/components/pn7160/pn7160_mifare_ultralight.cpp +2 -2
- esphome/components/qmc5883l/qmc5883l.cpp +45 -19
- esphome/components/qmc5883l/qmc5883l.h +1 -1
- esphome/components/qspi_dbi/qspi_dbi.cpp +2 -1
- esphome/components/remote_base/raw_protocol.cpp +1 -1
- esphome/components/remote_receiver/__init__.py +5 -6
- esphome/components/rotary_encoder/rotary_encoder.cpp +3 -1
- esphome/components/rp2040/__init__.py +1 -1
- esphome/components/rtl87xx/__init__.py +1 -1
- esphome/components/safe_mode/automation.h +1 -1
- esphome/components/seeed_mr60bha2/__init__.py +41 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +173 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +61 -0
- esphome/components/seeed_mr60bha2/sensor.py +57 -0
- esphome/components/seeed_mr60fda2/__init__.py +41 -0
- esphome/components/seeed_mr60fda2/binary_sensor.py +33 -0
- esphome/components/seeed_mr60fda2/button/__init__.py +45 -0
- esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.cpp +9 -0
- esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.h +18 -0
- esphome/components/seeed_mr60fda2/button/reset_radar_button.cpp +9 -0
- esphome/components/seeed_mr60fda2/button/reset_radar_button.h +18 -0
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +368 -0
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.h +101 -0
- esphome/components/seeed_mr60fda2/select/__init__.py +59 -0
- esphome/components/seeed_mr60fda2/select/height_threshold_select.cpp +15 -0
- esphome/components/seeed_mr60fda2/select/height_threshold_select.h +18 -0
- esphome/components/seeed_mr60fda2/select/install_height_select.cpp +15 -0
- esphome/components/seeed_mr60fda2/select/install_height_select.h +18 -0
- esphome/components/seeed_mr60fda2/select/sensitivity_select.cpp +15 -0
- esphome/components/seeed_mr60fda2/select/sensitivity_select.h +18 -0
- esphome/components/sen5x/sensor.py +5 -6
- esphome/components/sgp30/sensor.py +8 -9
- esphome/components/sgp30/sgp30.cpp +2 -6
- esphome/components/shelly_dimmer/shelly_dimmer.cpp +1 -1
- esphome/components/sim800l/sim800l.cpp +1 -1
- esphome/components/sntp/sntp_component.cpp +14 -20
- esphome/components/sntp/sntp_component.h +6 -9
- esphome/components/sntp/time.py +4 -7
- esphome/components/sprinkler/sprinkler.cpp +2 -2
- esphome/components/st7735/st7735.cpp +1 -1
- esphome/components/st7789v/st7789v.cpp +1 -1
- esphome/components/st7920/st7920.cpp +2 -3
- esphome/components/stepper/stepper.h +0 -1
- esphome/components/sun_gtil2/sun_gtil2.cpp +1 -1
- esphome/components/switch/binary_sensor/__init__.py +31 -0
- esphome/components/switch/binary_sensor/switch_binary_sensor.cpp +17 -0
- esphome/components/switch/binary_sensor/switch_binary_sensor.h +22 -0
- esphome/components/sx1509/sx1509_gpio_pin.cpp +2 -1
- esphome/components/sx1509/sx1509_gpio_pin.h +5 -5
- esphome/components/uart/uart.h +1 -1
- esphome/components/udp/udp_component.cpp +32 -16
- esphome/components/ufire_ec/sensor.py +4 -4
- esphome/components/uln2003/uln2003.cpp +4 -1
- esphome/components/waveshare_epaper/display.py +8 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +191 -0
- esphome/components/waveshare_epaper/waveshare_epaper.h +56 -0
- esphome/components/wiegand/__init__.py +3 -4
- esphome/components/wifi/__init__.py +42 -0
- esphome/components/wifi/wifi_component.cpp +2 -2
- esphome/components/wifi/wifi_component.h +82 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +1 -1
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
- esphome/components/wifi/wifi_component_libretiny.cpp +1 -1
- esphome/components/wifi/wifi_component_pico_w.cpp +1 -1
- esphome/components/wireguard/wireguard.cpp +2 -2
- esphome/components/xiaomi_ble/xiaomi_ble.cpp +1 -1
- esphome/config_validation.py +15 -11
- esphome/const.py +11 -1
- esphome/core/component.cpp +1 -1
- esphome/core/config.py +1 -2
- esphome/core/defines.h +3 -1
- esphome/core/helpers.cpp +20 -2
- esphome/core/helpers.h +10 -1
- esphome/core/optional.h +2 -2
- esphome/core/time.cpp +19 -15
- esphome/core/time.h +1 -3
- esphome/dashboard/web_server.py +6 -0
- {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/METADATA +4 -4
- {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/RECORD +192 -162
- {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/LICENSE +0 -0
- {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/WHEEL +0 -0
- {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
from esphome import pins
|
2
|
+
import esphome.codegen as cg
|
3
|
+
from esphome.components import switch
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
from esphome.const import CONF_OPTIMISTIC, CONF_PULSE_LENGTH, CONF_WAIT_TIME
|
6
|
+
|
7
|
+
from .. import hbridge_ns
|
8
|
+
|
9
|
+
HBridgeSwitch = hbridge_ns.class_("HBridgeSwitch", switch.Switch, cg.Component)
|
10
|
+
|
11
|
+
CODEOWNERS = ["@dwmw2"]
|
12
|
+
|
13
|
+
CONF_OFF_PIN = "off_pin"
|
14
|
+
CONF_ON_PIN = "on_pin"
|
15
|
+
|
16
|
+
CONFIG_SCHEMA = (
|
17
|
+
switch.switch_schema(HBridgeSwitch)
|
18
|
+
.extend(
|
19
|
+
{
|
20
|
+
cv.Required(CONF_ON_PIN): pins.gpio_output_pin_schema,
|
21
|
+
cv.Required(CONF_OFF_PIN): pins.gpio_output_pin_schema,
|
22
|
+
cv.Optional(
|
23
|
+
CONF_PULSE_LENGTH, default="100ms"
|
24
|
+
): cv.positive_time_period_milliseconds,
|
25
|
+
cv.Optional(CONF_WAIT_TIME): cv.positive_time_period_milliseconds,
|
26
|
+
cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
|
27
|
+
}
|
28
|
+
)
|
29
|
+
.extend(cv.COMPONENT_SCHEMA)
|
30
|
+
)
|
31
|
+
|
32
|
+
|
33
|
+
async def to_code(config):
|
34
|
+
var = await switch.new_switch(config)
|
35
|
+
await cg.register_component(var, config)
|
36
|
+
|
37
|
+
on_pin = await cg.gpio_pin_expression(config[CONF_ON_PIN])
|
38
|
+
cg.add(var.set_on_pin(on_pin))
|
39
|
+
off_pin = await cg.gpio_pin_expression(config[CONF_OFF_PIN])
|
40
|
+
cg.add(var.set_off_pin(off_pin))
|
41
|
+
cg.add(var.set_pulse_length(config[CONF_PULSE_LENGTH]))
|
42
|
+
cg.add(var.set_optimistic(config[CONF_OPTIMISTIC]))
|
43
|
+
if wait_time := config.get(CONF_WAIT_TIME):
|
44
|
+
cg.add(var.set_wait_time(wait_time))
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#include "hbridge_switch.h"
|
2
|
+
#include "esphome/core/log.h"
|
3
|
+
|
4
|
+
#include <cinttypes>
|
5
|
+
|
6
|
+
namespace esphome {
|
7
|
+
namespace hbridge {
|
8
|
+
|
9
|
+
static const char *const TAG = "switch.hbridge";
|
10
|
+
|
11
|
+
float HBridgeSwitch::get_setup_priority() const { return setup_priority::HARDWARE; }
|
12
|
+
void HBridgeSwitch::setup() {
|
13
|
+
ESP_LOGCONFIG(TAG, "Setting up H-Bridge Switch '%s'...", this->name_.c_str());
|
14
|
+
|
15
|
+
optional<bool> initial_state = this->get_initial_state_with_restore_mode().value_or(false);
|
16
|
+
|
17
|
+
// Like GPIOSwitch does, set the pin state both before and after pin setup()
|
18
|
+
this->on_pin_->digital_write(false);
|
19
|
+
this->on_pin_->setup();
|
20
|
+
this->on_pin_->digital_write(false);
|
21
|
+
|
22
|
+
this->off_pin_->digital_write(false);
|
23
|
+
this->off_pin_->setup();
|
24
|
+
this->off_pin_->digital_write(false);
|
25
|
+
|
26
|
+
if (initial_state.has_value())
|
27
|
+
this->write_state(initial_state);
|
28
|
+
}
|
29
|
+
|
30
|
+
void HBridgeSwitch::dump_config() {
|
31
|
+
LOG_SWITCH("", "H-Bridge Switch", this);
|
32
|
+
LOG_PIN(" On Pin: ", this->on_pin_);
|
33
|
+
LOG_PIN(" Off Pin: ", this->off_pin_);
|
34
|
+
ESP_LOGCONFIG(TAG, " Pulse length: %" PRId32 " ms", this->pulse_length_);
|
35
|
+
if (this->wait_time_)
|
36
|
+
ESP_LOGCONFIG(TAG, " Wait time %" PRId32 " ms", this->wait_time_);
|
37
|
+
}
|
38
|
+
|
39
|
+
void HBridgeSwitch::write_state(bool state) {
|
40
|
+
this->desired_state_ = state;
|
41
|
+
if (!this->timer_running_)
|
42
|
+
this->timer_fn_();
|
43
|
+
}
|
44
|
+
|
45
|
+
void HBridgeSwitch::timer_fn_() {
|
46
|
+
uint32_t next_timeout = 0;
|
47
|
+
|
48
|
+
while ((uint8_t) this->desired_state_ != this->relay_state_) {
|
49
|
+
switch (this->relay_state_) {
|
50
|
+
case RELAY_STATE_ON:
|
51
|
+
case RELAY_STATE_OFF:
|
52
|
+
case RELAY_STATE_UNKNOWN:
|
53
|
+
if (this->desired_state_) {
|
54
|
+
this->on_pin_->digital_write(true);
|
55
|
+
this->relay_state_ = RELAY_STATE_SWITCHING_ON;
|
56
|
+
} else {
|
57
|
+
this->off_pin_->digital_write(true);
|
58
|
+
this->relay_state_ = RELAY_STATE_SWITCHING_OFF;
|
59
|
+
}
|
60
|
+
next_timeout = this->pulse_length_;
|
61
|
+
if (!this->optimistic_)
|
62
|
+
this->publish_state(this->desired_state_);
|
63
|
+
break;
|
64
|
+
|
65
|
+
case RELAY_STATE_SWITCHING_ON:
|
66
|
+
this->on_pin_->digital_write(false);
|
67
|
+
this->relay_state_ = RELAY_STATE_ON;
|
68
|
+
if (this->optimistic_)
|
69
|
+
this->publish_state(true);
|
70
|
+
next_timeout = this->wait_time_;
|
71
|
+
break;
|
72
|
+
|
73
|
+
case RELAY_STATE_SWITCHING_OFF:
|
74
|
+
this->off_pin_->digital_write(false);
|
75
|
+
this->relay_state_ = RELAY_STATE_OFF;
|
76
|
+
if (this->optimistic_)
|
77
|
+
this->publish_state(false);
|
78
|
+
next_timeout = this->wait_time_;
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
|
82
|
+
if (next_timeout) {
|
83
|
+
this->timer_running_ = true;
|
84
|
+
this->set_timeout(next_timeout, [this]() { this->timer_fn_(); });
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
|
88
|
+
// In the case where ON/OFF state has been reached but we need to
|
89
|
+
// immediately change back again to reach desired_state_, we loop.
|
90
|
+
}
|
91
|
+
this->timer_running_ = false;
|
92
|
+
}
|
93
|
+
|
94
|
+
} // namespace hbridge
|
95
|
+
} // namespace esphome
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/core/component.h"
|
4
|
+
#include "esphome/core/hal.h"
|
5
|
+
#include "esphome/components/switch/switch.h"
|
6
|
+
|
7
|
+
#include <vector>
|
8
|
+
|
9
|
+
namespace esphome {
|
10
|
+
namespace hbridge {
|
11
|
+
|
12
|
+
enum RelayState : uint8_t {
|
13
|
+
RELAY_STATE_OFF = 0,
|
14
|
+
RELAY_STATE_ON = 1,
|
15
|
+
RELAY_STATE_SWITCHING_ON = 2,
|
16
|
+
RELAY_STATE_SWITCHING_OFF = 3,
|
17
|
+
RELAY_STATE_UNKNOWN = 4,
|
18
|
+
};
|
19
|
+
|
20
|
+
class HBridgeSwitch : public switch_::Switch, public Component {
|
21
|
+
public:
|
22
|
+
void set_on_pin(GPIOPin *pin) { this->on_pin_ = pin; }
|
23
|
+
void set_off_pin(GPIOPin *pin) { this->off_pin_ = pin; }
|
24
|
+
void set_pulse_length(uint32_t pulse_length) { this->pulse_length_ = pulse_length; }
|
25
|
+
void set_wait_time(uint32_t wait_time) { this->wait_time_ = wait_time; }
|
26
|
+
void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
|
27
|
+
|
28
|
+
// ========== INTERNAL METHODS ==========
|
29
|
+
// (In most use cases you won't need these)
|
30
|
+
float get_setup_priority() const override;
|
31
|
+
|
32
|
+
void setup() override;
|
33
|
+
void dump_config() override;
|
34
|
+
|
35
|
+
protected:
|
36
|
+
void write_state(bool state) override;
|
37
|
+
void timer_fn_();
|
38
|
+
|
39
|
+
bool timer_running_{false};
|
40
|
+
bool desired_state_{false};
|
41
|
+
RelayState relay_state_{RELAY_STATE_UNKNOWN};
|
42
|
+
GPIOPin *on_pin_{nullptr};
|
43
|
+
GPIOPin *off_pin_{nullptr};
|
44
|
+
uint32_t pulse_length_{0};
|
45
|
+
uint32_t wait_time_{0};
|
46
|
+
bool optimistic_{false};
|
47
|
+
};
|
48
|
+
|
49
|
+
} // namespace hbridge
|
50
|
+
} // namespace esphome
|
@@ -133,8 +133,10 @@ bool HitachiClimate::get_swing_v_() {
|
|
133
133
|
}
|
134
134
|
|
135
135
|
void HitachiClimate::set_swing_h_(uint8_t position) {
|
136
|
-
if (position > HITACHI_AC344_SWINGH_LEFT_MAX)
|
137
|
-
|
136
|
+
if (position > HITACHI_AC344_SWINGH_LEFT_MAX) {
|
137
|
+
set_swing_h_(HITACHI_AC344_SWINGH_MIDDLE);
|
138
|
+
return;
|
139
|
+
}
|
138
140
|
set_bits(&remote_state_[HITACHI_AC344_SWINGH_BYTE], HITACHI_AC344_SWINGH_OFFSET, HITACHI_AC344_SWINGH_SIZE, position);
|
139
141
|
set_button_(HITACHI_AC344_BUTTON_SWINGH);
|
140
142
|
}
|
@@ -133,8 +133,10 @@ bool HitachiClimate::get_swing_v_() {
|
|
133
133
|
}
|
134
134
|
|
135
135
|
void HitachiClimate::set_swing_h_(uint8_t position) {
|
136
|
-
if (position > HITACHI_AC424_SWINGH_LEFT_MAX)
|
137
|
-
|
136
|
+
if (position > HITACHI_AC424_SWINGH_LEFT_MAX) {
|
137
|
+
set_swing_h_(HITACHI_AC424_SWINGH_MIDDLE);
|
138
|
+
return;
|
139
|
+
}
|
138
140
|
set_bits(&remote_state_[HITACHI_AC424_SWINGH_BYTE], HITACHI_AC424_SWINGH_OFFSET, HITACHI_AC424_SWINGH_SIZE, position);
|
139
141
|
set_button_(HITACHI_AC424_BUTTON_SWINGH);
|
140
142
|
}
|
@@ -27,6 +27,7 @@ void HomeassistantNumber::min_retrieved_(const std::string &min) {
|
|
27
27
|
auto min_value = parse_number<float>(min);
|
28
28
|
if (!min_value.has_value()) {
|
29
29
|
ESP_LOGE(TAG, "'%s': Can't convert 'min' value '%s' to number!", this->entity_id_.c_str(), min.c_str());
|
30
|
+
return;
|
30
31
|
}
|
31
32
|
ESP_LOGD(TAG, "'%s': Min retrieved: %s", get_name().c_str(), min.c_str());
|
32
33
|
this->traits.set_min_value(min_value.value());
|
@@ -36,6 +37,7 @@ void HomeassistantNumber::max_retrieved_(const std::string &max) {
|
|
36
37
|
auto max_value = parse_number<float>(max);
|
37
38
|
if (!max_value.has_value()) {
|
38
39
|
ESP_LOGE(TAG, "'%s': Can't convert 'max' value '%s' to number!", this->entity_id_.c_str(), max.c_str());
|
40
|
+
return;
|
39
41
|
}
|
40
42
|
ESP_LOGD(TAG, "'%s': Max retrieved: %s", get_name().c_str(), max.c_str());
|
41
43
|
this->traits.set_max_value(max_value.value());
|
@@ -45,6 +47,7 @@ void HomeassistantNumber::step_retrieved_(const std::string &step) {
|
|
45
47
|
auto step_value = parse_number<float>(step);
|
46
48
|
if (!step_value.has_value()) {
|
47
49
|
ESP_LOGE(TAG, "'%s': Can't convert 'step' value '%s' to number!", this->entity_id_.c_str(), step.c_str());
|
50
|
+
return;
|
48
51
|
}
|
49
52
|
ESP_LOGD(TAG, "'%s': Step Retrieved %s", get_name().c_str(), step.c_str());
|
50
53
|
this->traits.set_step(step_value.value());
|
@@ -53,7 +53,7 @@ bool HX711Sensor::read_sensor_(uint32_t *result) {
|
|
53
53
|
}
|
54
54
|
|
55
55
|
// Cycle clock pin for gain setting
|
56
|
-
for (uint8_t i = 0; i < this->gain_; i++) {
|
56
|
+
for (uint8_t i = 0; i < static_cast<uint8_t>(this->gain_); i++) {
|
57
57
|
this->sck_pin_->digital_write(true);
|
58
58
|
delayMicroseconds(1);
|
59
59
|
this->sck_pin_->digital_write(false);
|
esphome/components/hx711/hx711.h
CHANGED
@@ -17,14 +17,14 @@ void IDFI2CBus::setup() {
|
|
17
17
|
ESP_LOGCONFIG(TAG, "Setting up I2C bus...");
|
18
18
|
static i2c_port_t next_port = I2C_NUM_0;
|
19
19
|
port_ = next_port;
|
20
|
-
#if
|
20
|
+
#if SOC_I2C_NUM > 1
|
21
21
|
next_port = (next_port == I2C_NUM_0) ? I2C_NUM_1 : I2C_NUM_MAX;
|
22
22
|
#else
|
23
23
|
next_port = I2C_NUM_MAX;
|
24
24
|
#endif
|
25
25
|
|
26
26
|
if (port_ == I2C_NUM_MAX) {
|
27
|
-
ESP_LOGE(TAG, "Too many I2C buses configured");
|
27
|
+
ESP_LOGE(TAG, "Too many I2C buses configured. Max %u supported.", SOC_I2C_NUM);
|
28
28
|
this->mark_failed();
|
29
29
|
return;
|
30
30
|
}
|
@@ -33,14 +33,15 @@ enum SpeakerEventGroupBits : uint32_t {
|
|
33
33
|
STATE_RUNNING = (1 << 11),
|
34
34
|
STATE_STOPPING = (1 << 12),
|
35
35
|
STATE_STOPPED = (1 << 13),
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
ERR_TASK_FAILED_TO_START = (1 << 14),
|
37
|
+
ERR_ESP_INVALID_STATE = (1 << 15),
|
38
|
+
ERR_ESP_NOT_SUPPORTED = (1 << 16),
|
39
39
|
ERR_ESP_INVALID_ARG = (1 << 17),
|
40
40
|
ERR_ESP_INVALID_SIZE = (1 << 18),
|
41
41
|
ERR_ESP_NO_MEM = (1 << 19),
|
42
42
|
ERR_ESP_FAIL = (1 << 20),
|
43
|
-
ALL_ERR_ESP_BITS = ERR_ESP_INVALID_STATE |
|
43
|
+
ALL_ERR_ESP_BITS = ERR_ESP_INVALID_STATE | ERR_ESP_NOT_SUPPORTED | ERR_ESP_INVALID_ARG | ERR_ESP_INVALID_SIZE |
|
44
|
+
ERR_ESP_NO_MEM | ERR_ESP_FAIL,
|
44
45
|
ALL_BITS = 0x00FFFFFF, // All valid FreeRTOS event group bits
|
45
46
|
};
|
46
47
|
|
@@ -55,6 +56,8 @@ static esp_err_t err_bit_to_esp_err(uint32_t bit) {
|
|
55
56
|
return ESP_ERR_INVALID_SIZE;
|
56
57
|
case SpeakerEventGroupBits::ERR_ESP_NO_MEM:
|
57
58
|
return ESP_ERR_NO_MEM;
|
59
|
+
case SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED:
|
60
|
+
return ESP_ERR_NOT_SUPPORTED;
|
58
61
|
default:
|
59
62
|
return ESP_FAIL;
|
60
63
|
}
|
@@ -135,19 +138,19 @@ void I2SAudioSpeaker::loop() {
|
|
135
138
|
xEventGroupClearBits(this->event_group_, SpeakerEventGroupBits::ERR_TASK_FAILED_TO_START);
|
136
139
|
}
|
137
140
|
|
138
|
-
if (event_group_bits & SpeakerEventGroupBits::
|
141
|
+
if (event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS) {
|
142
|
+
uint32_t error_bits = event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS;
|
143
|
+
ESP_LOGW(TAG, "Error writing to I2S: %s", esp_err_to_name(err_bit_to_esp_err(error_bits)));
|
144
|
+
this->status_set_warning();
|
145
|
+
}
|
146
|
+
|
147
|
+
if (event_group_bits & SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED) {
|
139
148
|
this->status_set_error("Failed to adjust I2S bus to match the incoming audio");
|
140
149
|
ESP_LOGE(TAG,
|
141
150
|
"Incompatible audio format: sample rate = %" PRIu32 ", channels = %" PRIu8 ", bits per sample = %" PRIu8,
|
142
151
|
this->audio_stream_info_.sample_rate, this->audio_stream_info_.channels,
|
143
152
|
this->audio_stream_info_.bits_per_sample);
|
144
153
|
}
|
145
|
-
|
146
|
-
if (event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS) {
|
147
|
-
uint32_t error_bits = event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS;
|
148
|
-
ESP_LOGW(TAG, "Error writing to I2S: %s", esp_err_to_name(err_bit_to_esp_err(error_bits)));
|
149
|
-
this->status_set_warning();
|
150
|
-
}
|
151
154
|
}
|
152
155
|
|
153
156
|
void I2SAudioSpeaker::set_volume(float volume) {
|
@@ -236,13 +239,15 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
236
239
|
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_STARTING);
|
237
240
|
|
238
241
|
audio::AudioStreamInfo audio_stream_info = this_speaker->audio_stream_info_;
|
239
|
-
const ssize_t bytes_per_sample = audio_stream_info.get_bytes_per_sample();
|
240
|
-
const uint8_t number_of_channels = audio_stream_info.channels;
|
241
242
|
|
242
|
-
const
|
243
|
-
|
243
|
+
const uint32_t bytes_per_ms =
|
244
|
+
audio_stream_info.channels * audio_stream_info.get_bytes_per_sample() * audio_stream_info.sample_rate / 1000;
|
245
|
+
|
246
|
+
const size_t dma_buffers_size = DMA_BUFFERS_COUNT * DMA_BUFFER_DURATION_MS * bytes_per_ms;
|
247
|
+
|
248
|
+
// Ensure ring buffer is at least as large as the total size of the DMA buffers
|
244
249
|
const size_t ring_buffer_size =
|
245
|
-
|
250
|
+
std::max((uint32_t) dma_buffers_size, this_speaker->buffer_duration_ms_ * bytes_per_ms);
|
246
251
|
|
247
252
|
if (this_speaker->send_esp_err_to_event_group_(this_speaker->allocate_buffers_(dma_buffers_size, ring_buffer_size))) {
|
248
253
|
// Failed to allocate buffers
|
@@ -250,14 +255,7 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
250
255
|
this_speaker->delete_task_(dma_buffers_size);
|
251
256
|
}
|
252
257
|
|
253
|
-
if (this_speaker->send_esp_err_to_event_group_(this_speaker->start_i2s_driver_())) {
|
254
|
-
// Failed to start I2S driver
|
255
|
-
this_speaker->delete_task_(dma_buffers_size);
|
256
|
-
}
|
257
|
-
|
258
|
-
if (!this_speaker->send_esp_err_to_event_group_(this_speaker->reconfigure_i2s_stream_info_(audio_stream_info))) {
|
259
|
-
// Successfully set the I2S stream info, ready to write audio data to the I2S port
|
260
|
-
|
258
|
+
if (!this_speaker->send_esp_err_to_event_group_(this_speaker->start_i2s_driver_(audio_stream_info))) {
|
261
259
|
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_RUNNING);
|
262
260
|
|
263
261
|
bool stop_gracefully = false;
|
@@ -275,6 +273,12 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
275
273
|
stop_gracefully = true;
|
276
274
|
}
|
277
275
|
|
276
|
+
if (this_speaker->audio_stream_info_ != audio_stream_info) {
|
277
|
+
// Audio stream info has changed, stop the speaker task so it will restart with the proper settings.
|
278
|
+
|
279
|
+
break;
|
280
|
+
}
|
281
|
+
|
278
282
|
i2s_event_t i2s_event;
|
279
283
|
while (xQueueReceive(this_speaker->i2s_event_queue_, &i2s_event, 0)) {
|
280
284
|
if (i2s_event.type == I2S_EVENT_TX_Q_OVF) {
|
@@ -316,17 +320,14 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
316
320
|
}
|
317
321
|
}
|
318
322
|
}
|
319
|
-
} else {
|
320
|
-
// Couldn't configure the I2S port to be compatible with the incoming audio
|
321
|
-
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::ERR_INVALID_FORMAT);
|
322
|
-
}
|
323
|
-
i2s_zero_dma_buffer(this_speaker->parent_->get_port());
|
324
323
|
|
325
|
-
|
324
|
+
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_STOPPING);
|
325
|
+
|
326
|
+
i2s_driver_uninstall(this_speaker->parent_->get_port());
|
326
327
|
|
327
|
-
|
328
|
+
this_speaker->parent_->unlock();
|
329
|
+
}
|
328
330
|
|
329
|
-
this_speaker->parent_->unlock();
|
330
331
|
this_speaker->delete_task_(dma_buffers_size);
|
331
332
|
}
|
332
333
|
|
@@ -382,6 +383,9 @@ bool I2SAudioSpeaker::send_esp_err_to_event_group_(esp_err_t err) {
|
|
382
383
|
case ESP_ERR_NO_MEM:
|
383
384
|
xEventGroupSetBits(this->event_group_, SpeakerEventGroupBits::ERR_ESP_NO_MEM);
|
384
385
|
return true;
|
386
|
+
case ESP_ERR_NOT_SUPPORTED:
|
387
|
+
xEventGroupSetBits(this->event_group_, SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED);
|
388
|
+
return true;
|
385
389
|
default:
|
386
390
|
xEventGroupSetBits(this->event_group_, SpeakerEventGroupBits::ERR_ESP_FAIL);
|
387
391
|
return true;
|
@@ -411,18 +415,40 @@ esp_err_t I2SAudioSpeaker::allocate_buffers_(size_t data_buffer_size, size_t rin
|
|
411
415
|
return ESP_OK;
|
412
416
|
}
|
413
417
|
|
414
|
-
esp_err_t I2SAudioSpeaker::start_i2s_driver_() {
|
418
|
+
esp_err_t I2SAudioSpeaker::start_i2s_driver_(audio::AudioStreamInfo &audio_stream_info) {
|
419
|
+
if ((this->i2s_mode_ & I2S_MODE_SLAVE) && (this->sample_rate_ != audio_stream_info.sample_rate)) { // NOLINT
|
420
|
+
// Can't reconfigure I2S bus, so the sample rate must match the configured value
|
421
|
+
return ESP_ERR_NOT_SUPPORTED;
|
422
|
+
}
|
423
|
+
|
424
|
+
if ((i2s_bits_per_sample_t) audio_stream_info.bits_per_sample > this->bits_per_sample_) {
|
425
|
+
// Currently can't handle the case when the incoming audio has more bits per sample than the configured value
|
426
|
+
return ESP_ERR_NOT_SUPPORTED;
|
427
|
+
}
|
428
|
+
|
415
429
|
if (!this->parent_->try_lock()) {
|
416
430
|
return ESP_ERR_INVALID_STATE;
|
417
431
|
}
|
418
432
|
|
433
|
+
i2s_channel_fmt_t channel = this->channel_;
|
434
|
+
|
435
|
+
if (audio_stream_info.channels == 1) {
|
436
|
+
if (this->channel_ == I2S_CHANNEL_FMT_ONLY_LEFT) {
|
437
|
+
channel = I2S_CHANNEL_FMT_ONLY_LEFT;
|
438
|
+
} else {
|
439
|
+
channel = I2S_CHANNEL_FMT_ONLY_RIGHT;
|
440
|
+
}
|
441
|
+
} else if (audio_stream_info.channels == 2) {
|
442
|
+
channel = I2S_CHANNEL_FMT_RIGHT_LEFT;
|
443
|
+
}
|
444
|
+
|
419
445
|
int dma_buffer_length = DMA_BUFFER_DURATION_MS * this->sample_rate_ / 1000;
|
420
446
|
|
421
447
|
i2s_driver_config_t config = {
|
422
448
|
.mode = (i2s_mode_t) (this->i2s_mode_ | I2S_MODE_TX),
|
423
|
-
.sample_rate =
|
449
|
+
.sample_rate = audio_stream_info.sample_rate,
|
424
450
|
.bits_per_sample = this->bits_per_sample_,
|
425
|
-
.channel_format =
|
451
|
+
.channel_format = channel,
|
426
452
|
.communication_format = this->i2s_comm_fmt_,
|
427
453
|
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
|
428
454
|
.dma_buf_count = DMA_BUFFERS_COUNT,
|
@@ -477,30 +503,6 @@ esp_err_t I2SAudioSpeaker::start_i2s_driver_() {
|
|
477
503
|
return err;
|
478
504
|
}
|
479
505
|
|
480
|
-
esp_err_t I2SAudioSpeaker::reconfigure_i2s_stream_info_(audio::AudioStreamInfo &audio_stream_info) {
|
481
|
-
if (this->i2s_mode_ & I2S_MODE_MASTER) {
|
482
|
-
// ESP controls for the the I2S bus, so adjust the sample rate and bits per sample to match the incoming audio
|
483
|
-
this->sample_rate_ = audio_stream_info.sample_rate;
|
484
|
-
this->bits_per_sample_ = (i2s_bits_per_sample_t) audio_stream_info.bits_per_sample;
|
485
|
-
} else if (this->sample_rate_ != audio_stream_info.sample_rate) {
|
486
|
-
// Can't reconfigure I2S bus, so the sample rate must match the configured value
|
487
|
-
return ESP_ERR_INVALID_ARG;
|
488
|
-
}
|
489
|
-
|
490
|
-
if ((i2s_bits_per_sample_t) audio_stream_info.bits_per_sample > this->bits_per_sample_) {
|
491
|
-
// Currently can't handle the case when the incoming audio has more bits per sample than the configured value
|
492
|
-
return ESP_ERR_INVALID_ARG;
|
493
|
-
}
|
494
|
-
|
495
|
-
if (audio_stream_info.channels == 1) {
|
496
|
-
return i2s_set_clk(this->parent_->get_port(), this->sample_rate_, this->bits_per_sample_, I2S_CHANNEL_MONO);
|
497
|
-
} else if (audio_stream_info.channels == 2) {
|
498
|
-
return i2s_set_clk(this->parent_->get_port(), this->sample_rate_, this->bits_per_sample_, I2S_CHANNEL_STEREO);
|
499
|
-
}
|
500
|
-
|
501
|
-
return ESP_ERR_INVALID_ARG;
|
502
|
-
}
|
503
|
-
|
504
506
|
void I2SAudioSpeaker::delete_task_(size_t buffer_size) {
|
505
507
|
this->audio_ring_buffer_.reset(); // Releases onwership of the shared_ptr
|
506
508
|
|
@@ -91,24 +91,15 @@ class I2SAudioSpeaker : public I2SAudioOut, public speaker::Speaker, public Comp
|
|
91
91
|
esp_err_t allocate_buffers_(size_t data_buffer_size, size_t ring_buffer_size);
|
92
92
|
|
93
93
|
/// @brief Starts the ESP32 I2S driver.
|
94
|
-
/// Attempts to lock the I2S port, starts the I2S driver
|
95
|
-
/// the I2S port and uninstall the driver, if necessary.
|
96
|
-
/// @
|
97
|
-
///
|
94
|
+
/// Attempts to lock the I2S port, starts the I2S driver using the passed in stream information, and sets the data out
|
95
|
+
/// pin. If it fails, it will unlock the I2S port and uninstall the driver, if necessary.
|
96
|
+
/// @param audio_stream_info Stream information for the I2S driver.
|
97
|
+
/// @return ESP_ERR_NOT_ALLOWED if the I2S port can't play the incoming audio stream.
|
98
|
+
/// ESP_ERR_INVALID_STATE if the I2S port is already locked.
|
99
|
+
/// ESP_ERR_INVALID_ARG if nstalling the driver or setting the data outpin fails due to a parameter error.
|
98
100
|
/// ESP_ERR_NO_MEM if the driver fails to install due to a memory allocation error.
|
99
|
-
/// ESP_FAIL if setting the data out pin fails due to an IO error
|
100
|
-
|
101
|
-
esp_err_t start_i2s_driver_();
|
102
|
-
|
103
|
-
/// @brief Adjusts the I2S driver configuration to match the incoming audio stream.
|
104
|
-
/// Modifies I2S driver's sample rate, bits per sample, and number of channel settings. If the I2S is in secondary
|
105
|
-
/// mode, it only modifies the number of channels.
|
106
|
-
/// @param audio_stream_info Describes the incoming audio stream
|
107
|
-
/// @return ESP_ERR_INVALID_ARG if there is a parameter error, if there is more than 2 channels in the stream, or if
|
108
|
-
/// the audio settings are incompatible with the configuration.
|
109
|
-
/// ESP_ERR_NO_MEM if the driver fails to reconfigure due to a memory allocation error.
|
110
|
-
/// ESP_OK if successful.
|
111
|
-
esp_err_t reconfigure_i2s_stream_info_(audio::AudioStreamInfo &audio_stream_info);
|
101
|
+
/// ESP_FAIL if setting the data out pin fails due to an IO error ESP_OK if successful
|
102
|
+
esp_err_t start_i2s_driver_(audio::AudioStreamInfo &audio_stream_info);
|
112
103
|
|
113
104
|
/// @brief Deletes the speaker's task.
|
114
105
|
/// Deallocates the data_buffer_ and audio_ring_buffer_, if necessary, and deletes the task. Should only be called by
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from esphome import core, pins
|
2
2
|
import esphome.codegen as cg
|
3
|
-
from esphome.components import display,
|
3
|
+
from esphome.components import display, spi
|
4
4
|
from esphome.components.display import validate_rotation
|
5
5
|
import esphome.config_validation as cv
|
6
6
|
from esphome.const import (
|
@@ -147,7 +147,6 @@ def _validate(config):
|
|
147
147
|
|
148
148
|
|
149
149
|
CONFIG_SCHEMA = cv.All(
|
150
|
-
font.validate_pillow_installed,
|
151
150
|
display.FULL_DISPLAY_SCHEMA.extend(
|
152
151
|
{
|
153
152
|
cv.GenerateID(): cv.declare_id(ILI9XXXDisplay),
|
@@ -313,8 +313,9 @@ void ILI9XXXDisplay::draw_pixels_at(int x_start, int y_start, int w, int h, cons
|
|
313
313
|
// do color conversion pixel-by-pixel into the buffer and draw it later. If this is happening the user has not
|
314
314
|
// configured the renderer well.
|
315
315
|
if (this->rotation_ != display::DISPLAY_ROTATION_0_DEGREES || bitness != display::COLOR_BITNESS_565 || !big_endian) {
|
316
|
-
|
317
|
-
|
316
|
+
display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset,
|
317
|
+
x_pad);
|
318
|
+
return;
|
318
319
|
}
|
319
320
|
this->set_addr_window_(x_start, y_start, x_start + w - 1, y_start + h - 1);
|
320
321
|
// x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display.
|
@@ -10,7 +10,6 @@ import puremagic
|
|
10
10
|
|
11
11
|
from esphome import core, external_files
|
12
12
|
import esphome.codegen as cg
|
13
|
-
from esphome.components import font
|
14
13
|
import esphome.config_validation as cv
|
15
14
|
from esphome.const import (
|
16
15
|
CONF_DITHER,
|
@@ -233,7 +232,7 @@ IMAGE_SCHEMA = cv.Schema(
|
|
233
232
|
)
|
234
233
|
)
|
235
234
|
|
236
|
-
CONFIG_SCHEMA =
|
235
|
+
CONFIG_SCHEMA = IMAGE_SCHEMA
|
237
236
|
|
238
237
|
|
239
238
|
def load_svg_image(file: bytes, resize: tuple[int, int]):
|
@@ -47,7 +47,7 @@ void Logger::write_header_(int level, const char *tag, int line) {
|
|
47
47
|
if (current_task == main_task_) {
|
48
48
|
this->printf_to_buffer_("%s[%s][%s:%03u]: ", color, letter, tag, line);
|
49
49
|
} else {
|
50
|
-
const char *thread_name = "";
|
50
|
+
const char *thread_name = ""; // NOLINT(clang-analyzer-deadcode.DeadStores)
|
51
51
|
#if defined(USE_ESP32)
|
52
52
|
thread_name = pcTaskGetName(current_task);
|
53
53
|
#elif defined(USE_LIBRETINY)
|
@@ -23,7 +23,7 @@ bool operator==(const GainTimePair &lhs, const GainTimePair &rhs) {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
bool operator!=(const GainTimePair &lhs, const GainTimePair &rhs) {
|
26
|
-
return
|
26
|
+
return lhs.gain != rhs.gain || lhs.time != rhs.time;
|
27
27
|
}
|
28
28
|
|
29
29
|
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
@@ -8,7 +8,7 @@ import logging
|
|
8
8
|
|
9
9
|
from esphome import codegen as cg, config_validation as cv
|
10
10
|
from esphome.const import CONF_ITEMS
|
11
|
-
from esphome.core import Lambda
|
11
|
+
from esphome.core import ID, Lambda
|
12
12
|
from esphome.cpp_generator import LambdaExpression, MockObj
|
13
13
|
from esphome.cpp_types import uint32
|
14
14
|
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
@@ -38,7 +38,7 @@ def literal(arg):
|
|
38
38
|
def call_lambda(lamb: LambdaExpression):
|
39
39
|
expr = lamb.content.strip()
|
40
40
|
if expr.startswith("return") and expr.endswith(";"):
|
41
|
-
return expr[
|
41
|
+
return expr[6:][:-1].strip()
|
42
42
|
return f"{lamb}()"
|
43
43
|
|
44
44
|
|
@@ -72,6 +72,12 @@ class LValidator:
|
|
72
72
|
)
|
73
73
|
if self.retmapper is not None:
|
74
74
|
return self.retmapper(value)
|
75
|
+
if isinstance(value, ID):
|
76
|
+
return await cg.get_variable(value)
|
77
|
+
if isinstance(value, list):
|
78
|
+
value = [
|
79
|
+
await cg.get_variable(x) if isinstance(x, ID) else x for x in value
|
80
|
+
]
|
75
81
|
return cg.safe_exp(value)
|
76
82
|
|
77
83
|
|
@@ -162,6 +168,7 @@ LV_EVENT_MAP = {
|
|
162
168
|
"READY": "READY",
|
163
169
|
"CANCEL": "CANCEL",
|
164
170
|
"ALL_EVENTS": "ALL",
|
171
|
+
"CHANGE": "VALUE_CHANGED",
|
165
172
|
}
|
166
173
|
|
167
174
|
LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Union
|
2
2
|
|
3
3
|
import esphome.codegen as cg
|
4
|
+
from esphome.components import image
|
4
5
|
from esphome.components.color import CONF_HEX, ColorStruct, from_rgbw
|
5
6
|
from esphome.components.font import Font
|
6
7
|
from esphome.components.image import Image_
|
@@ -31,7 +32,7 @@ from .defines import (
|
|
31
32
|
literal,
|
32
33
|
)
|
33
34
|
from .helpers import add_lv_use, esphome_fonts_used, lv_fonts_used, requires_component
|
34
|
-
from .types import lv_font_t, lv_gradient_t
|
35
|
+
from .types import lv_font_t, lv_gradient_t
|
35
36
|
|
36
37
|
opacity_consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
|
37
38
|
|
@@ -332,8 +333,12 @@ def image_validator(value):
|
|
332
333
|
|
333
334
|
lv_image = LValidator(
|
334
335
|
image_validator,
|
335
|
-
|
336
|
-
|
336
|
+
image.Image_.operator("ptr"),
|
337
|
+
requires="image",
|
338
|
+
)
|
339
|
+
lv_image_list = LValidator(
|
340
|
+
cv.ensure_list(image_validator),
|
341
|
+
cg.std_vector.template(image.Image_.operator("ptr")),
|
337
342
|
requires="image",
|
338
343
|
)
|
339
344
|
lv_bool = LValidator(cv.boolean, cg.bool_, retmapper=literal)
|