esphome 2025.2.2__py3-none-any.whl → 2025.3.0b1__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.
Files changed (135) hide show
  1. esphome/__main__.py +9 -1
  2. esphome/components/api/api_connection.cpp +426 -70
  3. esphome/components/api/api_connection.h +117 -25
  4. esphome/components/api/api_pb2.cpp +9 -0
  5. esphome/components/api/api_pb2.h +1 -0
  6. esphome/components/api/api_server.cpp +2 -2
  7. esphome/components/api/list_entities.cpp +76 -22
  8. esphome/components/api/list_entities.h +1 -0
  9. esphome/components/api/subscribe_state.h +2 -0
  10. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -0
  11. esphome/components/bmp085/bmp085.cpp +1 -1
  12. esphome/components/chsc6x/__init__.py +2 -0
  13. esphome/components/chsc6x/chsc6x_touchscreen.cpp +47 -0
  14. esphome/components/chsc6x/chsc6x_touchscreen.h +34 -0
  15. esphome/components/chsc6x/touchscreen.py +33 -0
  16. esphome/components/climate/__init__.py +0 -1
  17. esphome/components/cst816/binary_sensor/__init__.py +2 -25
  18. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +3 -14
  19. esphome/components/cst816/touchscreen/cst816_touchscreen.h +0 -4
  20. esphome/components/esp32_ble_beacon/__init__.py +3 -1
  21. esphome/components/esp8266/gpio.py +1 -2
  22. esphome/components/font/__init__.py +185 -185
  23. esphome/components/font/font.cpp +4 -4
  24. esphome/components/font/font.h +1 -0
  25. esphome/components/haier/climate.py +11 -10
  26. esphome/components/hbridge/switch/hbridge_switch.cpp +2 -2
  27. esphome/components/heatpumpir/climate.py +2 -1
  28. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  29. esphome/components/heatpumpir/heatpumpir.h +1 -0
  30. esphome/components/i2c/__init__.py +6 -6
  31. esphome/components/i2c/i2c_bus_esp_idf.cpp +6 -2
  32. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  33. esphome/components/ili9xxx/display.py +1 -0
  34. esphome/components/ili9xxx/ili9xxx_display.h +5 -0
  35. esphome/components/ili9xxx/ili9xxx_init.h +59 -0
  36. esphome/components/ld2450/__init__.py +51 -0
  37. esphome/components/ld2450/binary_sensor.py +47 -0
  38. esphome/components/ld2450/button/__init__.py +45 -0
  39. esphome/components/ld2450/button/reset_button.cpp +9 -0
  40. esphome/components/ld2450/button/reset_button.h +18 -0
  41. esphome/components/ld2450/button/restart_button.cpp +9 -0
  42. esphome/components/ld2450/button/restart_button.h +18 -0
  43. esphome/components/ld2450/ld2450.cpp +876 -0
  44. esphome/components/ld2450/ld2450.h +234 -0
  45. esphome/components/ld2450/number/__init__.py +121 -0
  46. esphome/components/ld2450/number/presence_timeout_number.cpp +12 -0
  47. esphome/components/ld2450/number/presence_timeout_number.h +18 -0
  48. esphome/components/ld2450/number/zone_coordinate_number.cpp +14 -0
  49. esphome/components/ld2450/number/zone_coordinate_number.h +19 -0
  50. esphome/components/ld2450/select/__init__.py +56 -0
  51. esphome/components/ld2450/select/baud_rate_select.cpp +12 -0
  52. esphome/components/ld2450/select/baud_rate_select.h +18 -0
  53. esphome/components/ld2450/select/zone_type_select.cpp +12 -0
  54. esphome/components/ld2450/select/zone_type_select.h +18 -0
  55. esphome/components/ld2450/sensor.py +156 -0
  56. esphome/components/ld2450/switch/__init__.py +45 -0
  57. esphome/components/ld2450/switch/bluetooth_switch.cpp +12 -0
  58. esphome/components/ld2450/switch/bluetooth_switch.h +18 -0
  59. esphome/components/ld2450/switch/multi_target_switch.cpp +12 -0
  60. esphome/components/ld2450/switch/multi_target_switch.h +18 -0
  61. esphome/components/ld2450/text_sensor.py +62 -0
  62. esphome/components/lvgl/defines.py +0 -2
  63. esphome/components/lvgl/font.cpp +1 -1
  64. esphome/components/lvgl/lvgl_esphome.cpp +27 -19
  65. esphome/components/lvgl/widgets/img.py +1 -3
  66. esphome/components/mcp2515/mcp2515.cpp +1 -0
  67. esphome/components/mlx90393/sensor.py +53 -33
  68. esphome/components/mlx90393/sensor_mlx90393.cpp +4 -0
  69. esphome/components/mlx90393/sensor_mlx90393.h +8 -3
  70. esphome/components/mqtt/__init__.py +2 -2
  71. esphome/components/msa3xx/__init__.py +189 -0
  72. esphome/components/msa3xx/binary_sensor.py +40 -0
  73. esphome/components/msa3xx/msa3xx.cpp +417 -0
  74. esphome/components/msa3xx/msa3xx.h +311 -0
  75. esphome/components/msa3xx/sensor.py +42 -0
  76. esphome/components/msa3xx/text_sensor.py +38 -0
  77. esphome/components/nfc/binary_sensor/__init__.py +4 -4
  78. esphome/components/opentherm/binary_sensor/__init__.py +4 -4
  79. esphome/components/opentherm/generate.py +6 -6
  80. esphome/components/opentherm/sensor/__init__.py +5 -6
  81. esphome/components/packages/__init__.py +35 -11
  82. esphome/components/pn532/binary_sensor.py +4 -4
  83. esphome/components/rc522/binary_sensor.py +4 -4
  84. esphome/components/socket/bsd_sockets_impl.cpp +1 -0
  85. esphome/components/socket/lwip_sockets_impl.cpp +1 -0
  86. esphome/components/socket/socket.h +3 -1
  87. esphome/components/ssd1306_base/__init__.py +7 -7
  88. esphome/components/thermostat/climate.py +1 -1
  89. esphome/components/tmp1075/tmp1075.cpp +7 -11
  90. esphome/components/tmp1075/tmp1075.h +1 -2
  91. esphome/components/tormatic/__init__.py +1 -0
  92. esphome/components/tormatic/cover.py +47 -0
  93. esphome/components/tormatic/tormatic_cover.cpp +355 -0
  94. esphome/components/tormatic/tormatic_cover.h +60 -0
  95. esphome/components/tormatic/tormatic_protocol.h +211 -0
  96. esphome/components/touchscreen/binary_sensor/__init__.py +3 -0
  97. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.cpp +7 -1
  98. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.h +3 -1
  99. esphome/components/touchscreen/touchscreen.cpp +3 -4
  100. esphome/components/udp/udp_component.h +4 -1
  101. esphome/components/web_server/list_entities.cpp +70 -66
  102. esphome/components/web_server/list_entities.h +43 -22
  103. esphome/components/web_server/web_server.cpp +345 -68
  104. esphome/components/web_server/web_server.h +138 -6
  105. esphome/components/web_server_base/__init__.py +1 -1
  106. esphome/components/web_server_idf/__init__.py +2 -0
  107. esphome/components/web_server_idf/web_server_idf.cpp +177 -30
  108. esphome/components/web_server_idf/web_server_idf.h +53 -4
  109. esphome/config_validation.py +23 -125
  110. esphome/const.py +5 -1
  111. esphome/core/config.py +12 -4
  112. esphome/core/defines.h +1 -1
  113. esphome/core/helpers.h +5 -3
  114. esphome/core/time.cpp +1 -0
  115. esphome/cpp_generator.py +3 -3
  116. esphome/dashboard/core.py +30 -21
  117. esphome/dashboard/dns.py +7 -1
  118. esphome/dashboard/entries.py +83 -16
  119. esphome/dashboard/settings.py +0 -4
  120. esphome/dashboard/status/mdns.py +43 -14
  121. esphome/dashboard/status/mqtt.py +22 -9
  122. esphome/dashboard/status/ping.py +54 -10
  123. esphome/dashboard/web_server.py +56 -24
  124. esphome/storage_json.py +4 -0
  125. esphome/wizard.py +13 -17
  126. esphome/writer.py +1 -3
  127. esphome/yaml_util.py +36 -33
  128. esphome/zeroconf.py +9 -21
  129. {esphome-2025.2.2.dist-info → esphome-2025.3.0b1.dist-info}/METADATA +5 -5
  130. {esphome-2025.2.2.dist-info → esphome-2025.3.0b1.dist-info}/RECORD +134 -94
  131. esphome/components/cst816/binary_sensor/cst816_button.h +0 -27
  132. {esphome-2025.2.2.dist-info → esphome-2025.3.0b1.dist-info}/LICENSE +0 -0
  133. {esphome-2025.2.2.dist-info → esphome-2025.3.0b1.dist-info}/WHEEL +0 -0
  134. {esphome-2025.2.2.dist-info → esphome-2025.3.0b1.dist-info}/entry_points.txt +0 -0
  135. {esphome-2025.2.2.dist-info → esphome-2025.3.0b1.dist-info}/top_level.txt +0 -0
@@ -81,7 +81,7 @@ void Font::measure(const char *str, int *width, int *x_offset, int *baseline, in
81
81
  if (glyph_n < 0) {
82
82
  // Unknown char, skip
83
83
  if (!this->get_glyphs().empty())
84
- x += this->get_glyphs()[0].glyph_data_->width;
84
+ x += this->get_glyphs()[0].glyph_data_->advance;
85
85
  i++;
86
86
  continue;
87
87
  }
@@ -92,7 +92,7 @@ void Font::measure(const char *str, int *width, int *x_offset, int *baseline, in
92
92
  } else {
93
93
  min_x = std::min(min_x, x + glyph.glyph_data_->offset_x);
94
94
  }
95
- x += glyph.glyph_data_->width + glyph.glyph_data_->offset_x;
95
+ x += glyph.glyph_data_->advance;
96
96
 
97
97
  i += match_length;
98
98
  has_char = true;
@@ -111,7 +111,7 @@ void Font::print(int x_start, int y_start, display::Display *display, Color colo
111
111
  // Unknown char, skip
112
112
  ESP_LOGW(TAG, "Encountered character without representation in font: '%c'", text[i]);
113
113
  if (!this->get_glyphs().empty()) {
114
- uint8_t glyph_width = this->get_glyphs()[0].glyph_data_->width;
114
+ uint8_t glyph_width = this->get_glyphs()[0].glyph_data_->advance;
115
115
  display->filled_rectangle(x_at, y_start, glyph_width, this->height_, color);
116
116
  x_at += glyph_width;
117
117
  }
@@ -161,7 +161,7 @@ void Font::print(int x_start, int y_start, display::Display *display, Color colo
161
161
  }
162
162
  }
163
163
  }
164
- x_at += glyph.glyph_data_->width + glyph.glyph_data_->offset_x;
164
+ x_at += glyph.glyph_data_->advance;
165
165
 
166
166
  i += match_length;
167
167
  }
@@ -15,6 +15,7 @@ class Font;
15
15
  struct GlyphData {
16
16
  const uint8_t *a_char;
17
17
  const uint8_t *data;
18
+ int advance;
18
19
  int offset_x;
19
20
  int offset_y;
20
21
  int width;
@@ -1,9 +1,15 @@
1
- import logging
1
+ import logging
2
+
3
+ from esphome import automation
2
4
  import esphome.codegen as cg
5
+ from esphome.components import climate, logger, uart
6
+ from esphome.components.climate import (
7
+ CONF_CURRENT_TEMPERATURE,
8
+ ClimateMode,
9
+ ClimatePreset,
10
+ ClimateSwingMode,
11
+ )
3
12
  import esphome.config_validation as cv
4
- import esphome.final_validate as fv
5
- from esphome.components import uart, climate, logger
6
- from esphome import automation
7
13
  from esphome.const import (
8
14
  CONF_BEEPER,
9
15
  CONF_DISPLAY,
@@ -24,12 +30,7 @@ from esphome.const import (
24
30
  CONF_VISUAL,
25
31
  CONF_WIFI,
26
32
  )
27
- from esphome.components.climate import (
28
- ClimateMode,
29
- ClimatePreset,
30
- ClimateSwingMode,
31
- CONF_CURRENT_TEMPERATURE,
32
- )
33
+ import esphome.final_validate as fv
33
34
 
34
35
  _LOGGER = logging.getLogger(__name__)
35
36
 
@@ -12,7 +12,7 @@ float HBridgeSwitch::get_setup_priority() const { return setup_priority::HARDWAR
12
12
  void HBridgeSwitch::setup() {
13
13
  ESP_LOGCONFIG(TAG, "Setting up H-Bridge Switch '%s'...", this->name_.c_str());
14
14
 
15
- optional<bool> initial_state = this->get_initial_state_with_restore_mode().value_or(false);
15
+ optional<bool> initial_state = this->get_initial_state_with_restore_mode();
16
16
 
17
17
  // Like GPIOSwitch does, set the pin state both before and after pin setup()
18
18
  this->on_pin_->digital_write(false);
@@ -24,7 +24,7 @@ void HBridgeSwitch::setup() {
24
24
  this->off_pin_->digital_write(false);
25
25
 
26
26
  if (initial_state.has_value())
27
- this->write_state(initial_state);
27
+ this->write_state(initial_state.value());
28
28
  }
29
29
 
30
30
  void HBridgeSwitch::dump_config() {
@@ -53,6 +53,7 @@ PROTOCOLS = {
53
53
  "mitsubishi_sez": Protocol.PROTOCOL_MITSUBISHI_SEZ,
54
54
  "panasonic_ckp": Protocol.PROTOCOL_PANASONIC_CKP,
55
55
  "panasonic_dke": Protocol.PROTOCOL_PANASONIC_DKE,
56
+ "panasonic_eke": Protocol.PROTOCOL_PANASONIC_EKE,
56
57
  "panasonic_jke": Protocol.PROTOCOL_PANASONIC_JKE,
57
58
  "panasonic_lke": Protocol.PROTOCOL_PANASONIC_LKE,
58
59
  "panasonic_nke": Protocol.PROTOCOL_PANASONIC_NKE,
@@ -127,6 +128,6 @@ def to_code(config):
127
128
  cg.add(var.set_max_temperature(config[CONF_MAX_TEMPERATURE]))
128
129
  cg.add(var.set_min_temperature(config[CONF_MIN_TEMPERATURE]))
129
130
 
130
- cg.add_library("tonia/HeatpumpIR", "1.0.27")
131
+ cg.add_library("tonia/HeatpumpIR", "1.0.32")
131
132
  if CORE.is_libretiny:
132
133
  CORE.add_platformio_option("lib_ignore", "IRremoteESP8266")
@@ -47,6 +47,7 @@ const std::map<Protocol, std::function<HeatpumpIR *()>> PROTOCOL_CONSTRUCTOR_MAP
47
47
  {PROTOCOL_MITSUBISHI_SEZ, []() { return new MitsubishiSEZKDXXHeatpumpIR(); }}, // NOLINT
48
48
  {PROTOCOL_PANASONIC_CKP, []() { return new PanasonicCKPHeatpumpIR(); }}, // NOLINT
49
49
  {PROTOCOL_PANASONIC_DKE, []() { return new PanasonicDKEHeatpumpIR(); }}, // NOLINT
50
+ {PROTOCOL_PANASONIC_EKE, []() { return new PanasonicEKEHeatpumpIR(); }}, // NOLINT
50
51
  {PROTOCOL_PANASONIC_JKE, []() { return new PanasonicJKEHeatpumpIR(); }}, // NOLINT
51
52
  {PROTOCOL_PANASONIC_LKE, []() { return new PanasonicLKEHeatpumpIR(); }}, // NOLINT
52
53
  {PROTOCOL_PANASONIC_NKE, []() { return new PanasonicNKEHeatpumpIR(); }}, // NOLINT
@@ -47,6 +47,7 @@ enum Protocol {
47
47
  PROTOCOL_MITSUBISHI_SEZ,
48
48
  PROTOCOL_PANASONIC_CKP,
49
49
  PROTOCOL_PANASONIC_DKE,
50
+ PROTOCOL_PANASONIC_EKE,
50
51
  PROTOCOL_PANASONIC_JKE,
51
52
  PROTOCOL_PANASONIC_LKE,
52
53
  PROTOCOL_PANASONIC_NKE,
@@ -1,23 +1,23 @@
1
+ from esphome import pins
1
2
  import esphome.codegen as cg
2
3
  import esphome.config_validation as cv
3
- import esphome.final_validate as fv
4
- from esphome import pins
5
4
  from esphome.const import (
5
+ CONF_ADDRESS,
6
6
  CONF_FREQUENCY,
7
- CONF_TIMEOUT,
7
+ CONF_I2C_ID,
8
8
  CONF_ID,
9
9
  CONF_INPUT,
10
10
  CONF_OUTPUT,
11
11
  CONF_SCAN,
12
12
  CONF_SCL,
13
13
  CONF_SDA,
14
- CONF_ADDRESS,
15
- CONF_I2C_ID,
14
+ CONF_TIMEOUT,
16
15
  PLATFORM_ESP32,
17
16
  PLATFORM_ESP8266,
18
17
  PLATFORM_RP2040,
19
18
  )
20
- from esphome.core import coroutine_with_priority, CORE
19
+ from esphome.core import CORE, coroutine_with_priority
20
+ import esphome.final_validate as fv
21
21
 
22
22
  CODEOWNERS = ["@esphome/core"]
23
23
  i2c_ns = cg.esphome_ns.namespace("i2c")
@@ -8,6 +8,10 @@
8
8
  #include "esphome/core/helpers.h"
9
9
  #include "esphome/core/log.h"
10
10
 
11
+ #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
12
+ #define SOC_HP_I2C_NUM SOC_I2C_NUM
13
+ #endif
14
+
11
15
  namespace esphome {
12
16
  namespace i2c {
13
17
 
@@ -17,14 +21,14 @@ void IDFI2CBus::setup() {
17
21
  ESP_LOGCONFIG(TAG, "Setting up I2C bus...");
18
22
  static i2c_port_t next_port = I2C_NUM_0;
19
23
  port_ = next_port;
20
- #if SOC_I2C_NUM > 1
24
+ #if SOC_HP_I2C_NUM > 1
21
25
  next_port = (next_port == I2C_NUM_0) ? I2C_NUM_1 : I2C_NUM_MAX;
22
26
  #else
23
27
  next_port = I2C_NUM_MAX;
24
28
  #endif
25
29
 
26
30
  if (port_ == I2C_NUM_MAX) {
27
- ESP_LOGE(TAG, "Too many I2C buses configured. Max %u supported.", SOC_I2C_NUM);
31
+ ESP_LOGE(TAG, "Too many I2C buses configured. Max %u supported.", SOC_HP_I2C_NUM);
28
32
  this->mark_failed();
29
33
  return;
30
34
  }
@@ -203,7 +203,7 @@ size_t I2SAudioSpeaker::play(const uint8_t *data, size_t length, TickType_t tick
203
203
  this->start();
204
204
  }
205
205
 
206
- if ((this->state_ != speaker::STATE_RUNNING) || (this->audio_ring_buffer_.use_count() == 1)) {
206
+ if ((this->state_ != speaker::STATE_RUNNING) || (this->audio_ring_buffer_.use_count() != 1)) {
207
207
  // Unable to write data to a running speaker, so delay the max amount of time so it can get ready
208
208
  vTaskDelay(ticks_to_wait);
209
209
  ticks_to_wait = 0;
@@ -57,6 +57,7 @@ ColorOrder = display.display_ns.enum("ColorMode")
57
57
 
58
58
  MODELS = {
59
59
  "GC9A01A": ili9xxx_ns.class_("ILI9XXXGC9A01A", ILI9XXXDisplay),
60
+ "GC9D01N": ili9xxx_ns.class_("ILI9XXXGC9D01N", ILI9XXXDisplay),
60
61
  "M5STACK": ili9xxx_ns.class_("ILI9XXXM5Stack", ILI9XXXDisplay),
61
62
  "M5CORE": ili9xxx_ns.class_("ILI9XXXM5CORE", ILI9XXXDisplay),
62
63
  "TFT_2.4": ili9xxx_ns.class_("ILI9XXXILI9341", ILI9XXXDisplay),
@@ -272,6 +272,11 @@ class ILI9XXXGC9A01A : public ILI9XXXDisplay {
272
272
  ILI9XXXGC9A01A() : ILI9XXXDisplay(INITCMD_GC9A01A, 240, 240) {}
273
273
  };
274
274
 
275
+ class ILI9XXXGC9D01N : public ILI9XXXDisplay {
276
+ public:
277
+ ILI9XXXGC9D01N() : ILI9XXXDisplay(INITCMD_GC9D01N, 160, 160) {}
278
+ };
279
+
275
280
  //----------- ILI9XXX_24_TFT display --------------
276
281
  class ILI9XXXST7735 : public ILI9XXXDisplay {
277
282
  public:
@@ -367,6 +367,65 @@ static const uint8_t PROGMEM INITCMD_GC9A01A[] = {
367
367
  0x00 // End of list
368
368
  };
369
369
 
370
+ static const uint8_t PROGMEM INITCMD_GC9D01N[] = {
371
+ // Enable Inter_command
372
+ 0xFE, 0, // Inter Register Enable 1 (FEh)
373
+ 0xEF, 0, // Inter Register Enable 2 (EFh)
374
+ // Inter_command is now enabled
375
+ 0x80, 1, 0xFF,
376
+ 0x81, 1, 0xFF,
377
+ 0x82, 1, 0xFF,
378
+ 0x83, 1, 0xFF,
379
+ 0x84, 1, 0xFF,
380
+ 0x85, 1, 0xFF,
381
+ 0x86, 1, 0xFF,
382
+ 0x87, 1, 0xFF,
383
+ 0x88, 1, 0xFF,
384
+ 0x89, 1, 0xFF,
385
+ 0x8A, 1, 0xFF,
386
+ 0x8B, 1, 0xFF,
387
+ 0x8C, 1, 0xFF,
388
+ 0x8D, 1, 0xFF,
389
+ 0x8E, 1, 0xFF,
390
+ 0x8F, 1, 0xFF,
391
+ 0X3A, 1, 0x05, // COLMOD: Pixel Format Set (3Ah) MCU interface, 16 bits / pixel
392
+ 0xEC, 1, 0x01, // Inversion (ECh) DINV=1+2H1V column for Dual Gate (BFh=0)
393
+ // According to datasheet Inversion (ECh) value 0x01 isn't valid, but Lilygo uses it everywhere
394
+ 0x74, 7, 0x02, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
395
+ 0x98, 1, 0x3e,
396
+ 0x99, 1, 0x3e,
397
+ 0xB5, 2, 0x0D, 0x0D, // Blanking Porch Control (B5h) VFP=14 VBP=14 HBP=Off
398
+ 0x60, 4, 0x38, 0x0F, 0x79, 0x67,
399
+ 0x61, 4, 0x38, 0x11, 0x79, 0x67,
400
+ 0x64, 6, 0x38, 0x17, 0x71, 0x5F, 0x79, 0x67,
401
+ 0x65, 6, 0x38, 0x13, 0x71, 0x5B, 0x79, 0x67,
402
+ 0x6A, 2, 0x00, 0x00,
403
+ 0x6C, 7, 0x22, 0x02, 0x22, 0x02, 0x22, 0x22, 0x50,
404
+ 0x6E, 32, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x0F, 0x0F,
405
+ 0x0D, 0x0D, 0x0B, 0x0B, 0x09, 0x09, 0x00, 0x00,
406
+ 0x00, 0x00, 0x0A, 0x0A, 0x0C, 0x0C, 0x0E, 0x0E,
407
+ 0x10, 0x10, 0x00, 0x00, 0x02, 0x02, 0x04, 0x04,
408
+ 0xBF, 1, 0x01, // Dual-Single gate select (BFh) 01h = dual gate mode
409
+ 0xF9, 1, 0x40,
410
+ 0x9B, 5, 0x3B, 0x93, 0x33, 0x7F, 0x00,
411
+ 0x7E, 1, 0x30,
412
+ 0x70, 6, 0x0D, 0x02, 0x08, 0x0D, 0x02, 0x08,
413
+ 0x71, 3, 0x0D, 0x02, 0x08,
414
+ 0x91, 2, 0x0E, 0x09,
415
+ // Set VREG1A, VREG1B, VREG2A, VREG2B voltage
416
+ // According to datasheet set either 0xC3/0xC4 or 0xC9 only, but Lilygo sets both of them
417
+ 0xC3, 5, 0x19, 0xC4, 0x19, 0xC9, 0x3C,
418
+ 0xF0, 6, 0x53, 0x15, 0x0A, 0x04, 0x00, 0x3E, // SET_GAMMA1 (F0h)
419
+ 0xF1, 6, 0x56, 0xA8, 0x7F, 0x33, 0x34, 0x5F, // SET_GAMMA2 (F1h)
420
+ 0xF2, 6, 0x53, 0x15, 0x0A, 0x04, 0x00, 0x3A, // SET_GAMMA3 (F2h)
421
+ 0xF3, 6, 0x52, 0xA4, 0x7F, 0x33, 0x34, 0xDF, // SET_GAMMA4 (F3h)
422
+ ILI9XXX_SLPOUT, 0, // Sleep Out Mode (11h)
423
+ ILI9XXX_DELAY(10),
424
+ ILI9XXX_DISPON, 0, // Display ON (29h)
425
+ ILI9XXX_DELAY(20),
426
+ 0x00 // End of list
427
+ };
428
+
370
429
  static const uint8_t PROGMEM INITCMD_ST7735[] = {
371
430
  ILI9XXX_SWRESET, 0, // Soft reset, then delay 10ms
372
431
  ILI9XXX_DELAY(10),
@@ -0,0 +1,51 @@
1
+ import esphome.codegen as cg
2
+ import esphome.config_validation as cv
3
+ from esphome.components import uart
4
+ from esphome.const import (
5
+ CONF_ID,
6
+ CONF_THROTTLE,
7
+ )
8
+
9
+ DEPENDENCIES = ["uart"]
10
+ CODEOWNERS = ["@hareeshmu"]
11
+ MULTI_CONF = True
12
+
13
+ ld2450_ns = cg.esphome_ns.namespace("ld2450")
14
+ LD2450Component = ld2450_ns.class_("LD2450Component", cg.Component, uart.UARTDevice)
15
+
16
+ CONF_LD2450_ID = "ld2450_id"
17
+
18
+ CONFIG_SCHEMA = cv.All(
19
+ cv.Schema(
20
+ {
21
+ cv.GenerateID(): cv.declare_id(LD2450Component),
22
+ cv.Optional(CONF_THROTTLE, default="1000ms"): cv.All(
23
+ cv.positive_time_period_milliseconds,
24
+ cv.Range(min=cv.TimePeriod(milliseconds=1)),
25
+ ),
26
+ }
27
+ )
28
+ .extend(uart.UART_DEVICE_SCHEMA)
29
+ .extend(cv.COMPONENT_SCHEMA)
30
+ )
31
+
32
+ LD2450BaseSchema = cv.Schema(
33
+ {
34
+ cv.GenerateID(CONF_LD2450_ID): cv.use_id(LD2450Component),
35
+ },
36
+ )
37
+
38
+ FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
39
+ "ld2450",
40
+ require_tx=True,
41
+ require_rx=True,
42
+ parity="NONE",
43
+ stop_bits=1,
44
+ )
45
+
46
+
47
+ async def to_code(config):
48
+ var = cg.new_Pvariable(config[CONF_ID])
49
+ await cg.register_component(var, config)
50
+ await uart.register_uart_device(var, config)
51
+ cg.add(var.set_throttle(config[CONF_THROTTLE]))
@@ -0,0 +1,47 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import binary_sensor
3
+ import esphome.config_validation as cv
4
+ from esphome.const import (
5
+ CONF_HAS_MOVING_TARGET,
6
+ CONF_HAS_STILL_TARGET,
7
+ CONF_HAS_TARGET,
8
+ DEVICE_CLASS_MOTION,
9
+ DEVICE_CLASS_OCCUPANCY,
10
+ )
11
+
12
+ from . import CONF_LD2450_ID, LD2450Component
13
+
14
+ DEPENDENCIES = ["ld2450"]
15
+
16
+ ICON_MEDITATION = "mdi:meditation"
17
+ ICON_SHIELD_ACCOUNT = "mdi:shield-account"
18
+ ICON_TARGET_ACCOUNT = "mdi:target-account"
19
+
20
+ CONFIG_SCHEMA = {
21
+ cv.GenerateID(CONF_LD2450_ID): cv.use_id(LD2450Component),
22
+ cv.Optional(CONF_HAS_TARGET): binary_sensor.binary_sensor_schema(
23
+ device_class=DEVICE_CLASS_OCCUPANCY,
24
+ icon=ICON_SHIELD_ACCOUNT,
25
+ ),
26
+ cv.Optional(CONF_HAS_MOVING_TARGET): binary_sensor.binary_sensor_schema(
27
+ device_class=DEVICE_CLASS_MOTION,
28
+ icon=ICON_TARGET_ACCOUNT,
29
+ ),
30
+ cv.Optional(CONF_HAS_STILL_TARGET): binary_sensor.binary_sensor_schema(
31
+ device_class=DEVICE_CLASS_OCCUPANCY,
32
+ icon=ICON_MEDITATION,
33
+ ),
34
+ }
35
+
36
+
37
+ async def to_code(config):
38
+ ld2450_component = await cg.get_variable(config[CONF_LD2450_ID])
39
+ if has_target_config := config.get(CONF_HAS_TARGET):
40
+ sens = await binary_sensor.new_binary_sensor(has_target_config)
41
+ cg.add(ld2450_component.set_target_binary_sensor(sens))
42
+ if has_moving_target_config := config.get(CONF_HAS_MOVING_TARGET):
43
+ sens = await binary_sensor.new_binary_sensor(has_moving_target_config)
44
+ cg.add(ld2450_component.set_moving_target_binary_sensor(sens))
45
+ if has_still_target_config := config.get(CONF_HAS_STILL_TARGET):
46
+ sens = await binary_sensor.new_binary_sensor(has_still_target_config)
47
+ cg.add(ld2450_component.set_still_target_binary_sensor(sens))
@@ -0,0 +1,45 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import button
3
+ import esphome.config_validation as cv
4
+ from esphome.const import (
5
+ CONF_FACTORY_RESET,
6
+ CONF_RESTART,
7
+ DEVICE_CLASS_RESTART,
8
+ ENTITY_CATEGORY_CONFIG,
9
+ ENTITY_CATEGORY_DIAGNOSTIC,
10
+ ICON_RESTART,
11
+ ICON_RESTART_ALERT,
12
+ )
13
+
14
+ from .. import CONF_LD2450_ID, LD2450Component, ld2450_ns
15
+
16
+ ResetButton = ld2450_ns.class_("ResetButton", button.Button)
17
+ RestartButton = ld2450_ns.class_("RestartButton", button.Button)
18
+
19
+ CONFIG_SCHEMA = {
20
+ cv.GenerateID(CONF_LD2450_ID): cv.use_id(LD2450Component),
21
+ cv.Optional(CONF_FACTORY_RESET): button.button_schema(
22
+ ResetButton,
23
+ device_class=DEVICE_CLASS_RESTART,
24
+ entity_category=ENTITY_CATEGORY_CONFIG,
25
+ icon=ICON_RESTART_ALERT,
26
+ ),
27
+ cv.Optional(CONF_RESTART): button.button_schema(
28
+ RestartButton,
29
+ device_class=DEVICE_CLASS_RESTART,
30
+ entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
31
+ icon=ICON_RESTART,
32
+ ),
33
+ }
34
+
35
+
36
+ async def to_code(config):
37
+ ld2450_component = await cg.get_variable(config[CONF_LD2450_ID])
38
+ if factory_reset_config := config.get(CONF_FACTORY_RESET):
39
+ b = await button.new_button(factory_reset_config)
40
+ await cg.register_parented(b, config[CONF_LD2450_ID])
41
+ cg.add(ld2450_component.set_reset_button(b))
42
+ if restart_config := config.get(CONF_RESTART):
43
+ b = await button.new_button(restart_config)
44
+ await cg.register_parented(b, config[CONF_LD2450_ID])
45
+ cg.add(ld2450_component.set_restart_button(b))
@@ -0,0 +1,9 @@
1
+ #include "reset_button.h"
2
+
3
+ namespace esphome {
4
+ namespace ld2450 {
5
+
6
+ void ResetButton::press_action() { this->parent_->factory_reset(); }
7
+
8
+ } // namespace ld2450
9
+ } // namespace esphome
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/button/button.h"
4
+ #include "../ld2450.h"
5
+
6
+ namespace esphome {
7
+ namespace ld2450 {
8
+
9
+ class ResetButton : public button::Button, public Parented<LD2450Component> {
10
+ public:
11
+ ResetButton() = default;
12
+
13
+ protected:
14
+ void press_action() override;
15
+ };
16
+
17
+ } // namespace ld2450
18
+ } // namespace esphome
@@ -0,0 +1,9 @@
1
+ #include "restart_button.h"
2
+
3
+ namespace esphome {
4
+ namespace ld2450 {
5
+
6
+ void RestartButton::press_action() { this->parent_->restart_and_read_all_info(); }
7
+
8
+ } // namespace ld2450
9
+ } // namespace esphome
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/button/button.h"
4
+ #include "../ld2450.h"
5
+
6
+ namespace esphome {
7
+ namespace ld2450 {
8
+
9
+ class RestartButton : public button::Button, public Parented<LD2450Component> {
10
+ public:
11
+ RestartButton() = default;
12
+
13
+ protected:
14
+ void press_action() override;
15
+ };
16
+
17
+ } // namespace ld2450
18
+ } // namespace esphome