esphome 2024.11.3__py3-none-any.whl → 2024.12.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 (178) hide show
  1. esphome/components/adc/adc_sensor.h +7 -8
  2. esphome/components/adc/adc_sensor_common.cpp +24 -0
  3. esphome/components/adc/{adc_sensor.cpp → adc_sensor_esp32.cpp} +10 -179
  4. esphome/components/adc/adc_sensor_esp8266.cpp +58 -0
  5. esphome/components/adc/adc_sensor_rp2040.cpp +93 -0
  6. esphome/components/alarm_control_panel/alarm_control_panel_call.cpp +3 -4
  7. esphome/components/animation/__init__.py +1 -2
  8. esphome/components/apds9306/apds9306.cpp +2 -1
  9. esphome/components/audio/audio.h +1 -1
  10. esphome/components/bk72xx/__init__.py +1 -1
  11. esphome/components/cse7766/cse7766.cpp +1 -1
  12. esphome/components/deep_sleep/deep_sleep_esp32.cpp +2 -2
  13. esphome/components/dht/dht.cpp +2 -1
  14. esphome/components/display/display.cpp +10 -6
  15. esphome/components/display/display.h +14 -0
  16. esphome/components/display_menu_base/__init__.py +0 -2
  17. esphome/components/display_menu_base/display_menu_base.cpp +1 -1
  18. esphome/components/dsmr/dsmr.cpp +1 -1
  19. esphome/components/esp32/__init__.py +94 -12
  20. esphome/components/esp32/boards.py +222 -14
  21. esphome/components/esp32_ble/__init__.py +22 -2
  22. esphome/components/esp32_ble/ble.cpp +13 -5
  23. esphome/components/esp32_ble/ble.h +2 -0
  24. esphome/components/esp32_ble/ble_advertising.cpp +1 -1
  25. esphome/components/esp32_ble/ble_uuid.cpp +9 -10
  26. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +4 -1
  27. esphome/components/esp32_camera_web_server/camera_web_server.h +1 -1
  28. esphome/components/esp32_rmt_led_strip/light.py +3 -3
  29. esphome/components/esp8266/__init__.py +5 -7
  30. esphome/components/ezo/ezo.cpp +14 -26
  31. esphome/components/font/__init__.py +5 -23
  32. esphome/components/font/font.cpp +5 -3
  33. esphome/components/graphical_display_menu/__init__.py +2 -0
  34. esphome/components/haier/hon_climate.cpp +79 -80
  35. esphome/components/hbridge/switch/__init__.py +44 -0
  36. esphome/components/hbridge/switch/hbridge_switch.cpp +95 -0
  37. esphome/components/hbridge/switch/hbridge_switch.h +50 -0
  38. esphome/components/hitachi_ac344/hitachi_ac344.cpp +4 -2
  39. esphome/components/hitachi_ac424/hitachi_ac424.cpp +4 -2
  40. esphome/components/homeassistant/number/homeassistant_number.cpp +3 -0
  41. esphome/components/hx711/hx711.cpp +1 -1
  42. esphome/components/hx711/hx711.h +1 -1
  43. esphome/components/i2c/i2c_bus_esp_idf.cpp +2 -2
  44. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +61 -59
  45. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -17
  46. esphome/components/ili9xxx/display.py +1 -2
  47. esphome/components/ili9xxx/ili9xxx_display.cpp +3 -2
  48. esphome/components/image/__init__.py +1 -2
  49. esphome/components/logger/logger.cpp +1 -1
  50. esphome/components/ltr501/ltr501.cpp +1 -1
  51. esphome/components/lvgl/defines.py +8 -1
  52. esphome/components/lvgl/lv_validation.py +8 -3
  53. esphome/components/lvgl/lvgl_esphome.cpp +1 -1
  54. esphome/components/lvgl/lvgl_esphome.h +16 -0
  55. esphome/components/lvgl/widgets/animimg.py +12 -17
  56. esphome/components/lvgl/widgets/img.py +1 -3
  57. esphome/components/matrix_keypad/__init__.py +15 -3
  58. esphome/components/matrix_keypad/matrix_keypad.cpp +4 -0
  59. esphome/components/matrix_keypad/matrix_keypad.h +5 -0
  60. esphome/components/max31865/max31865.cpp +4 -2
  61. esphome/components/modbus_controller/modbus_controller.cpp +24 -24
  62. esphome/components/modbus_controller/modbus_controller.h +22 -22
  63. esphome/components/modbus_controller/number/modbus_number.cpp +8 -8
  64. esphome/components/modbus_controller/number/modbus_number.h +4 -4
  65. esphome/components/modbus_controller/output/modbus_output.cpp +7 -6
  66. esphome/components/modbus_controller/output/modbus_output.h +5 -5
  67. esphome/components/modbus_controller/select/modbus_select.cpp +4 -3
  68. esphome/components/modbus_controller/select/modbus_select.h +4 -4
  69. esphome/components/modbus_controller/switch/modbus_switch.cpp +5 -5
  70. esphome/components/modbus_controller/switch/modbus_switch.h +2 -2
  71. esphome/components/mqtt/__init__.py +4 -0
  72. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -5
  73. esphome/components/mqtt/mqtt_backend_esp32.cpp +3 -3
  74. esphome/components/mqtt/mqtt_client.cpp +4 -0
  75. esphome/components/mqtt/mqtt_client.h +6 -0
  76. esphome/components/mqtt/mqtt_climate.cpp +13 -3
  77. esphome/components/mqtt/mqtt_sensor.cpp +2 -0
  78. esphome/components/network/ip_address.h +1 -1
  79. esphome/components/nextion/__init__.py +2 -0
  80. esphome/components/nextion/automation.h +76 -0
  81. esphome/components/nextion/base_component.py +1 -0
  82. esphome/components/nextion/binary_sensor/__init__.py +43 -2
  83. esphome/components/nextion/display.py +15 -0
  84. esphome/components/nextion/nextion.cpp +8 -5
  85. esphome/components/nextion/nextion.h +7 -0
  86. esphome/components/nextion/nextion_upload_idf.cpp +2 -2
  87. esphome/components/nextion/sensor/__init__.py +38 -5
  88. esphome/components/nextion/switch/__init__.py +38 -2
  89. esphome/components/nextion/text_sensor/__init__.py +37 -2
  90. esphome/components/nfc/ndef_record.cpp +3 -3
  91. esphome/components/online_image/__init__.py +1 -0
  92. esphome/components/opentherm/opentherm.cpp +3 -3
  93. esphome/components/opentherm/opentherm.h +1 -1
  94. esphome/components/ota/automation.h +1 -1
  95. esphome/components/output/float_output.cpp +1 -1
  96. esphome/components/pca6416a/pca6416a.cpp +5 -3
  97. esphome/components/pca9554/pca9554.cpp +4 -4
  98. esphome/components/pipsolar/pipsolar.cpp +2 -2
  99. esphome/components/pipsolar/switch/pipsolar_switch.cpp +2 -2
  100. esphome/components/pn532/pn532_mifare_ultralight.cpp +2 -2
  101. esphome/components/pn7150/pn7150_mifare_ultralight.cpp +2 -2
  102. esphome/components/pn7160/pn7160_mifare_ultralight.cpp +2 -2
  103. esphome/components/qmc5883l/qmc5883l.cpp +45 -19
  104. esphome/components/qmc5883l/qmc5883l.h +1 -1
  105. esphome/components/qspi_dbi/qspi_dbi.cpp +2 -1
  106. esphome/components/remote_base/raw_protocol.cpp +1 -1
  107. esphome/components/rotary_encoder/rotary_encoder.cpp +3 -1
  108. esphome/components/rp2040/__init__.py +1 -1
  109. esphome/components/rtl87xx/__init__.py +1 -1
  110. esphome/components/safe_mode/automation.h +1 -1
  111. esphome/components/seeed_mr60bha2/__init__.py +41 -0
  112. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +173 -0
  113. esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +61 -0
  114. esphome/components/seeed_mr60bha2/sensor.py +57 -0
  115. esphome/components/seeed_mr60fda2/__init__.py +41 -0
  116. esphome/components/seeed_mr60fda2/binary_sensor.py +33 -0
  117. esphome/components/seeed_mr60fda2/button/__init__.py +45 -0
  118. esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.cpp +9 -0
  119. esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.h +18 -0
  120. esphome/components/seeed_mr60fda2/button/reset_radar_button.cpp +9 -0
  121. esphome/components/seeed_mr60fda2/button/reset_radar_button.h +18 -0
  122. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +368 -0
  123. esphome/components/seeed_mr60fda2/seeed_mr60fda2.h +101 -0
  124. esphome/components/seeed_mr60fda2/select/__init__.py +59 -0
  125. esphome/components/seeed_mr60fda2/select/height_threshold_select.cpp +15 -0
  126. esphome/components/seeed_mr60fda2/select/height_threshold_select.h +18 -0
  127. esphome/components/seeed_mr60fda2/select/install_height_select.cpp +15 -0
  128. esphome/components/seeed_mr60fda2/select/install_height_select.h +18 -0
  129. esphome/components/seeed_mr60fda2/select/sensitivity_select.cpp +15 -0
  130. esphome/components/seeed_mr60fda2/select/sensitivity_select.h +18 -0
  131. esphome/components/sen5x/sensor.py +5 -6
  132. esphome/components/shelly_dimmer/shelly_dimmer.cpp +1 -1
  133. esphome/components/sim800l/sim800l.cpp +1 -1
  134. esphome/components/sntp/sntp_component.cpp +14 -20
  135. esphome/components/sntp/sntp_component.h +6 -9
  136. esphome/components/sntp/time.py +4 -7
  137. esphome/components/sprinkler/sprinkler.cpp +2 -2
  138. esphome/components/st7735/st7735.cpp +1 -1
  139. esphome/components/st7789v/st7789v.cpp +1 -1
  140. esphome/components/stepper/stepper.h +0 -1
  141. esphome/components/sun_gtil2/sun_gtil2.cpp +1 -1
  142. esphome/components/switch/binary_sensor/__init__.py +31 -0
  143. esphome/components/switch/binary_sensor/switch_binary_sensor.cpp +17 -0
  144. esphome/components/switch/binary_sensor/switch_binary_sensor.h +22 -0
  145. esphome/components/sx1509/sx1509_gpio_pin.cpp +2 -1
  146. esphome/components/sx1509/sx1509_gpio_pin.h +5 -5
  147. esphome/components/uart/uart.h +1 -1
  148. esphome/components/udp/udp_component.cpp +32 -16
  149. esphome/components/ufire_ec/sensor.py +4 -4
  150. esphome/components/uln2003/uln2003.cpp +4 -1
  151. esphome/components/waveshare_epaper/display.py +8 -0
  152. esphome/components/waveshare_epaper/waveshare_epaper.cpp +191 -0
  153. esphome/components/waveshare_epaper/waveshare_epaper.h +56 -0
  154. esphome/components/wiegand/__init__.py +3 -4
  155. esphome/components/wifi/__init__.py +42 -0
  156. esphome/components/wifi/wifi_component.cpp +2 -2
  157. esphome/components/wifi/wifi_component.h +82 -1
  158. esphome/components/wifi/wifi_component_esp32_arduino.cpp +1 -1
  159. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  160. esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
  161. esphome/components/wifi/wifi_component_libretiny.cpp +1 -1
  162. esphome/components/wifi/wifi_component_pico_w.cpp +1 -1
  163. esphome/components/wireguard/wireguard.cpp +2 -2
  164. esphome/components/xiaomi_ble/xiaomi_ble.cpp +1 -1
  165. esphome/config_validation.py +15 -11
  166. esphome/const.py +7 -1
  167. esphome/core/component.cpp +1 -1
  168. esphome/core/config.py +1 -2
  169. esphome/core/defines.h +3 -1
  170. esphome/core/helpers.cpp +6 -1
  171. esphome/core/helpers.h +2 -1
  172. esphome/core/optional.h +2 -2
  173. {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/METADATA +3 -3
  174. {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/RECORD +178 -149
  175. {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/LICENSE +0 -0
  176. {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/WHEEL +0 -0
  177. {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/entry_points.txt +0 -0
  178. {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/top_level.txt +0 -0
@@ -808,6 +808,90 @@ void WaveshareEPaper2P7InV2::dump_config() {
808
808
  LOG_UPDATE_INTERVAL(this);
809
809
  }
810
810
 
811
+ // ========================================================
812
+ // 1.54inch_v2_e-paper_b
813
+ // ========================================================
814
+ // Datasheet:
815
+ // - https://files.waveshare.com/upload/9/9e/1.54inch-e-paper-b-v2-specification.pdf
816
+ // - https://www.waveshare.com/wiki/1.54inch_e-Paper_Module_(B)_Manual
817
+
818
+ void WaveshareEPaper1P54InBV2::initialize() {
819
+ this->reset_();
820
+
821
+ this->wait_until_idle_();
822
+
823
+ this->command(0x12);
824
+ this->wait_until_idle_();
825
+
826
+ this->command(0x01);
827
+ this->data(0xC7);
828
+ this->data(0x00);
829
+ this->data(0x01);
830
+
831
+ this->command(0x11); // data entry mode
832
+ this->data(0x01);
833
+
834
+ this->command(0x44); // set Ram-X address start/end position
835
+ this->data(0x00);
836
+ this->data(0x18); // 0x18-->(24+1)*8=200
837
+
838
+ this->command(0x45); // set Ram-Y address start/end position
839
+ this->data(0xC7); // 0xC7-->(199+1)=200
840
+ this->data(0x00);
841
+ this->data(0x00);
842
+ this->data(0x00);
843
+
844
+ this->command(0x3C); // BorderWavefrom
845
+ this->data(0x05);
846
+
847
+ this->command(0x18); // Read built-in temperature sensor
848
+ this->data(0x80);
849
+
850
+ this->command(0x4E); // set RAM x address count to 0;
851
+ this->data(0x00);
852
+ this->command(0x4F); // set RAM y address count to 0X199;
853
+ this->data(0xC7);
854
+ this->data(0x00);
855
+
856
+ this->wait_until_idle_();
857
+ }
858
+
859
+ void HOT WaveshareEPaper1P54InBV2::display() {
860
+ uint32_t buf_len_half = this->get_buffer_length_() >> 1;
861
+ this->initialize();
862
+
863
+ // COMMAND DATA START TRANSMISSION 1 (BLACK)
864
+ this->command(0x24);
865
+ delay(2);
866
+ for (uint32_t i = 0; i < buf_len_half; i++) {
867
+ this->data(~this->buffer_[i]);
868
+ }
869
+ delay(2);
870
+
871
+ // COMMAND DATA START TRANSMISSION 2 (RED)
872
+ this->command(0x26);
873
+ delay(2);
874
+ for (uint32_t i = buf_len_half; i < buf_len_half * 2u; i++) {
875
+ this->data(this->buffer_[i]);
876
+ }
877
+ this->command(0x22);
878
+ this->data(0xf7);
879
+ this->command(0x20);
880
+ this->wait_until_idle_();
881
+
882
+ this->deep_sleep();
883
+ }
884
+ int WaveshareEPaper1P54InBV2::get_height_internal() { return 200; }
885
+ int WaveshareEPaper1P54InBV2::get_width_internal() { return 200; }
886
+ void WaveshareEPaper1P54InBV2::dump_config() {
887
+ LOG_DISPLAY("", "Waveshare E-Paper", this);
888
+ ESP_LOGCONFIG(TAG, " Model: 1.54in V2 B");
889
+ LOG_PIN(" Reset Pin: ", this->reset_pin_);
890
+ LOG_PIN(" DC Pin: ", this->dc_pin_);
891
+ LOG_PIN(" Busy Pin: ", this->busy_pin_);
892
+ LOG_UPDATE_INTERVAL(this);
893
+ }
894
+
811
895
  // ========================================================
812
896
  // 2.7inch_e-paper_b
813
897
  // ========================================================
@@ -2315,6 +2399,113 @@ void WaveshareEPaper7P5InBV3::dump_config() {
2315
2399
  LOG_UPDATE_INTERVAL(this);
2316
2400
  }
2317
2401
 
2402
+ void WaveshareEPaper7P5InBV3BWR::initialize() { this->init_display_(); }
2403
+ bool WaveshareEPaper7P5InBV3BWR::wait_until_idle_() {
2404
+ if (this->busy_pin_ == nullptr) {
2405
+ return true;
2406
+ }
2407
+
2408
+ const uint32_t start = millis();
2409
+ while (this->busy_pin_->digital_read()) {
2410
+ this->command(0x71);
2411
+ if (millis() - start > this->idle_timeout_()) {
2412
+ ESP_LOGI(TAG, "Timeout while displaying image!");
2413
+ return false;
2414
+ }
2415
+ App.feed_wdt();
2416
+ delay(10);
2417
+ }
2418
+ delay(200); // NOLINT
2419
+ return true;
2420
+ };
2421
+ void WaveshareEPaper7P5InBV3BWR::init_display_() {
2422
+ this->reset_();
2423
+
2424
+ // COMMAND POWER SETTING
2425
+ this->command(0x01);
2426
+
2427
+ // 1-0=11: internal power
2428
+ this->data(0x07);
2429
+ this->data(0x17); // VGH&VGL
2430
+ this->data(0x3F); // VSH
2431
+ this->data(0x26); // VSL
2432
+ this->data(0x11); // VSHR
2433
+
2434
+ // VCOM DC Setting
2435
+ this->command(0x82);
2436
+ this->data(0x24); // VCOM
2437
+
2438
+ // Booster Setting
2439
+ this->command(0x06);
2440
+ this->data(0x27);
2441
+ this->data(0x27);
2442
+ this->data(0x2F);
2443
+ this->data(0x17);
2444
+
2445
+ // POWER ON
2446
+ this->command(0x04);
2447
+
2448
+ delay(100); // NOLINT
2449
+ this->wait_until_idle_();
2450
+ // COMMAND PANEL SETTING
2451
+ this->command(0x00);
2452
+ this->data(0x0F); // KW-3f KWR-2F BWROTP 0f BWOTP 1f
2453
+
2454
+ // COMMAND RESOLUTION SETTING
2455
+ this->command(0x61);
2456
+ this->data(0x03); // source 800
2457
+ this->data(0x20);
2458
+ this->data(0x01); // gate 480
2459
+ this->data(0xE0);
2460
+ // COMMAND ...?
2461
+ this->command(0x15);
2462
+ this->data(0x00);
2463
+ // COMMAND VCOM AND DATA INTERVAL SETTING
2464
+ this->command(0x50);
2465
+ this->data(0x20);
2466
+ this->data(0x00);
2467
+ // COMMAND TCON SETTING
2468
+ this->command(0x60);
2469
+ this->data(0x22);
2470
+ // Resolution setting
2471
+ this->command(0x65);
2472
+ this->data(0x00);
2473
+ this->data(0x00); // 800*480
2474
+ this->data(0x00);
2475
+ this->data(0x00);
2476
+ };
2477
+ void HOT WaveshareEPaper7P5InBV3BWR::display() {
2478
+ this->init_display_();
2479
+ const uint32_t buf_len = this->get_buffer_length_() / 2u;
2480
+
2481
+ this->command(0x10); // Send BW data Transmission
2482
+ delay(2);
2483
+ for (uint32_t i = 0; i < buf_len; i++) {
2484
+ this->data(this->buffer_[i]);
2485
+ }
2486
+
2487
+ this->command(0x13); // Send red data Transmission
2488
+ delay(2);
2489
+ for (uint32_t i = 0; i < buf_len; i++) {
2490
+ this->data(this->buffer_[i + buf_len]);
2491
+ }
2492
+
2493
+ this->command(0x12); // Display Refresh
2494
+ delay(100); // NOLINT
2495
+ this->wait_until_idle_();
2496
+ this->deep_sleep();
2497
+ }
2498
+ int WaveshareEPaper7P5InBV3BWR::get_width_internal() { return 800; }
2499
+ int WaveshareEPaper7P5InBV3BWR::get_height_internal() { return 480; }
2500
+ void WaveshareEPaper7P5InBV3BWR::dump_config() {
2501
+ LOG_DISPLAY("", "Waveshare E-Paper", this);
2502
+ ESP_LOGCONFIG(TAG, " Model: 7.5in-bv3 BWR-Mode");
2503
+ LOG_PIN(" Reset Pin: ", this->reset_pin_);
2504
+ LOG_PIN(" DC Pin: ", this->dc_pin_);
2505
+ LOG_PIN(" Busy Pin: ", this->busy_pin_);
2506
+ LOG_UPDATE_INTERVAL(this);
2507
+ }
2508
+
2318
2509
  void WaveshareEPaper7P5In::initialize() {
2319
2510
  // COMMAND POWER SETTING
2320
2511
  this->command(0x01);
@@ -166,6 +166,24 @@ enum WaveshareEPaperTypeBModel {
166
166
  WAVESHARE_EPAPER_13_3_IN_K,
167
167
  };
168
168
 
169
+ class WaveshareEPaper1P54InBV2 : public WaveshareEPaperBWR {
170
+ public:
171
+ void initialize() override;
172
+
173
+ void display() override;
174
+
175
+ void dump_config() override;
176
+
177
+ void deep_sleep() override {
178
+ this->command(0x10);
179
+ this->data(0x01);
180
+ }
181
+
182
+ protected:
183
+ int get_width_internal() override;
184
+ int get_height_internal() override;
185
+ };
186
+
169
187
  class WaveshareEPaper2P7In : public WaveshareEPaper {
170
188
  public:
171
189
  void initialize() override;
@@ -619,6 +637,44 @@ class WaveshareEPaper7P5InBV3 : public WaveshareEPaper {
619
637
  void init_display_();
620
638
  };
621
639
 
640
+ class WaveshareEPaper7P5InBV3BWR : public WaveshareEPaperBWR {
641
+ public:
642
+ bool wait_until_idle_();
643
+
644
+ void initialize() override;
645
+
646
+ void display() override;
647
+
648
+ void dump_config() override;
649
+
650
+ void deep_sleep() override {
651
+ this->command(0x02); // Power off
652
+ this->wait_until_idle_();
653
+ this->command(0x07); // Deep sleep
654
+ this->data(0xA5);
655
+ }
656
+
657
+ void clear_screen();
658
+
659
+ protected:
660
+ int get_width_internal() override;
661
+
662
+ int get_height_internal() override;
663
+
664
+ void reset_() {
665
+ if (this->reset_pin_ != nullptr) {
666
+ this->reset_pin_->digital_write(true);
667
+ delay(200); // NOLINT
668
+ this->reset_pin_->digital_write(false);
669
+ delay(5);
670
+ this->reset_pin_->digital_write(true);
671
+ delay(200); // NOLINT
672
+ }
673
+ };
674
+
675
+ void init_display_();
676
+ };
677
+
622
678
  class WaveshareEPaper7P5InBC : public WaveshareEPaper {
623
679
  public:
624
680
  void initialize() override;
@@ -1,8 +1,8 @@
1
+ from esphome import automation, pins
1
2
  import esphome.codegen as cg
2
- import esphome.config_validation as cv
3
- from esphome import pins, automation
4
3
  from esphome.components import key_provider
5
- from esphome.const import CONF_ID, CONF_ON_TAG, CONF_TRIGGER_ID
4
+ import esphome.config_validation as cv
5
+ from esphome.const import CONF_ID, CONF_ON_KEY, CONF_ON_TAG, CONF_TRIGGER_ID
6
6
 
7
7
  CODEOWNERS = ["@ssieb"]
8
8
 
@@ -25,7 +25,6 @@ WiegandKeyTrigger = wiegand_ns.class_(
25
25
 
26
26
  CONF_D0 = "d0"
27
27
  CONF_D1 = "d1"
28
- CONF_ON_KEY = "on_key"
29
28
  CONF_ON_RAW = "on_raw"
30
29
 
31
30
  CONFIG_SCHEMA = cv.Schema(
@@ -27,6 +27,7 @@ from esphome.const import (
27
27
  CONF_NETWORKS,
28
28
  CONF_ON_CONNECT,
29
29
  CONF_ON_DISCONNECT,
30
+ CONF_ON_ERROR,
30
31
  CONF_PASSWORD,
31
32
  CONF_POWER_SAVE_MODE,
32
33
  CONF_PRIORITY,
@@ -34,6 +35,7 @@ from esphome.const import (
34
35
  CONF_SSID,
35
36
  CONF_STATIC_IP,
36
37
  CONF_SUBNET,
38
+ CONF_TIMEOUT,
37
39
  CONF_TTLS_PHASE_2,
38
40
  CONF_USE_ADDRESS,
39
41
  CONF_USERNAME,
@@ -46,6 +48,7 @@ from . import wpa2_eap
46
48
  AUTO_LOAD = ["network"]
47
49
 
48
50
  NO_WIFI_VARIANTS = [const.VARIANT_ESP32H2]
51
+ CONF_SAVE = "save"
49
52
 
50
53
  wifi_ns = cg.esphome_ns.namespace("wifi")
51
54
  EAPAuth = wifi_ns.struct("EAPAuth")
@@ -63,6 +66,9 @@ WiFiConnectedCondition = wifi_ns.class_("WiFiConnectedCondition", Condition)
63
66
  WiFiEnabledCondition = wifi_ns.class_("WiFiEnabledCondition", Condition)
64
67
  WiFiEnableAction = wifi_ns.class_("WiFiEnableAction", automation.Action)
65
68
  WiFiDisableAction = wifi_ns.class_("WiFiDisableAction", automation.Action)
69
+ WiFiConfigureAction = wifi_ns.class_(
70
+ "WiFiConfigureAction", automation.Action, cg.Component
71
+ )
66
72
 
67
73
 
68
74
  def validate_password(value):
@@ -483,3 +489,39 @@ async def wifi_enable_to_code(config, action_id, template_arg, args):
483
489
  @automation.register_action("wifi.disable", WiFiDisableAction, cv.Schema({}))
484
490
  async def wifi_disable_to_code(config, action_id, template_arg, args):
485
491
  return cg.new_Pvariable(action_id, template_arg)
492
+
493
+
494
+ @automation.register_action(
495
+ "wifi.configure",
496
+ WiFiConfigureAction,
497
+ cv.Schema(
498
+ {
499
+ cv.Required(CONF_SSID): cv.templatable(cv.ssid),
500
+ cv.Required(CONF_PASSWORD): cv.templatable(validate_password),
501
+ cv.Optional(CONF_SAVE, default=True): cv.templatable(cv.boolean),
502
+ cv.Optional(CONF_TIMEOUT, default="30000ms"): cv.templatable(
503
+ cv.positive_time_period_milliseconds
504
+ ),
505
+ cv.Optional(CONF_ON_CONNECT): automation.validate_automation(single=True),
506
+ cv.Optional(CONF_ON_ERROR): automation.validate_automation(single=True),
507
+ }
508
+ ),
509
+ )
510
+ async def wifi_set_sta_to_code(config, action_id, template_arg, args):
511
+ var = cg.new_Pvariable(action_id, template_arg)
512
+ ssid = await cg.templatable(config[CONF_SSID], args, cg.std_string)
513
+ password = await cg.templatable(config[CONF_PASSWORD], args, cg.std_string)
514
+ save = await cg.templatable(config[CONF_SAVE], args, cg.bool_)
515
+ timeout = await cg.templatable(config.get(CONF_TIMEOUT), args, cg.uint32)
516
+ cg.add(var.set_ssid(ssid))
517
+ cg.add(var.set_password(password))
518
+ cg.add(var.set_save(save))
519
+ cg.add(var.set_connection_timeout(timeout))
520
+ if on_connect_config := config.get(CONF_ON_CONNECT):
521
+ await automation.build_automation(
522
+ var.get_connect_trigger(), [], on_connect_config
523
+ )
524
+ if on_error_config := config.get(CONF_ON_ERROR):
525
+ await automation.build_automation(var.get_error_trigger(), [], on_error_config)
526
+ await cg.register_component(var, config)
527
+ return var
@@ -444,7 +444,7 @@ void WiFiComponent::print_connect_params_() {
444
444
  if (this->selected_ap_.get_bssid().has_value()) {
445
445
  ESP_LOGV(TAG, " Priority: %.1f", this->get_sta_priority(*this->selected_ap_.get_bssid()));
446
446
  }
447
- ESP_LOGCONFIG(TAG, " Channel: %" PRId32, wifi_channel_());
447
+ ESP_LOGCONFIG(TAG, " Channel: %" PRId32, get_wifi_channel());
448
448
  ESP_LOGCONFIG(TAG, " Subnet: %s", wifi_subnet_mask_().str().c_str());
449
449
  ESP_LOGCONFIG(TAG, " Gateway: %s", wifi_gateway_ip_().str().c_str());
450
450
  ESP_LOGCONFIG(TAG, " DNS1: %s", wifi_dns_ip_(0).str().c_str());
@@ -763,7 +763,7 @@ void WiFiComponent::load_fast_connect_settings_() {
763
763
 
764
764
  void WiFiComponent::save_fast_connect_settings_() {
765
765
  bssid_t bssid = wifi_bssid();
766
- uint8_t channel = wifi_channel_();
766
+ uint8_t channel = get_wifi_channel();
767
767
 
768
768
  if (bssid != this->selected_ap_.get_bssid() || channel != this->selected_ap_.get_channel()) {
769
769
  SavedWifiFastConnectSettings fast_connect_save{};
@@ -209,6 +209,7 @@ class WiFiComponent : public Component {
209
209
  WiFiComponent();
210
210
 
211
211
  void set_sta(const WiFiAP &ap);
212
+ WiFiAP get_sta() { return this->selected_ap_; }
212
213
  void add_sta(const WiFiAP &ap);
213
214
  void clear_sta();
214
215
 
@@ -317,6 +318,8 @@ class WiFiComponent : public Component {
317
318
  Trigger<> *get_connect_trigger() const { return this->connect_trigger_; };
318
319
  Trigger<> *get_disconnect_trigger() const { return this->disconnect_trigger_; };
319
320
 
321
+ int32_t get_wifi_channel();
322
+
320
323
  protected:
321
324
  static std::string format_mac_addr(const uint8_t mac[6]);
322
325
 
@@ -344,7 +347,7 @@ class WiFiComponent : public Component {
344
347
  #endif // USE_WIFI_AP
345
348
 
346
349
  bool wifi_disconnect_();
347
- int32_t wifi_channel_();
350
+
348
351
  network::IPAddress wifi_subnet_mask_();
349
352
  network::IPAddress wifi_gateway_ip_();
350
353
  network::IPAddress wifi_dns_ip_(int num);
@@ -441,6 +444,84 @@ template<typename... Ts> class WiFiDisableAction : public Action<Ts...> {
441
444
  void play(Ts... x) override { global_wifi_component->disable(); }
442
445
  };
443
446
 
447
+ template<typename... Ts> class WiFiConfigureAction : public Action<Ts...>, public Component {
448
+ public:
449
+ TEMPLATABLE_VALUE(std::string, ssid)
450
+ TEMPLATABLE_VALUE(std::string, password)
451
+ TEMPLATABLE_VALUE(bool, save)
452
+ TEMPLATABLE_VALUE(uint32_t, connection_timeout)
453
+
454
+ void play(Ts... x) override {
455
+ auto ssid = this->ssid_.value(x...);
456
+ auto password = this->password_.value(x...);
457
+ // Avoid multiple calls
458
+ if (this->connecting_)
459
+ return;
460
+ // If already connected to the same AP, do nothing
461
+ if (global_wifi_component->wifi_ssid() == ssid) {
462
+ // Callback to notify the user that the connection was successful
463
+ this->connect_trigger_->trigger();
464
+ return;
465
+ }
466
+ // Create a new WiFiAP object with the new SSID and password
467
+ this->new_sta_.set_ssid(ssid);
468
+ this->new_sta_.set_password(password);
469
+ // Save the current STA
470
+ this->old_sta_ = global_wifi_component->get_sta();
471
+ // Disable WiFi
472
+ global_wifi_component->disable();
473
+ // Set the state to connecting
474
+ this->connecting_ = true;
475
+ // Store the new STA so once the WiFi is enabled, it will connect to it
476
+ // This is necessary because the WiFiComponent will raise an error and fallback to the saved STA
477
+ // if trying to connect to a new STA while already connected to another one
478
+ if (this->save_.value(x...)) {
479
+ global_wifi_component->save_wifi_sta(new_sta_.get_ssid(), new_sta_.get_password());
480
+ } else {
481
+ global_wifi_component->set_sta(new_sta_);
482
+ }
483
+ // Enable WiFi
484
+ global_wifi_component->enable();
485
+ // Set timeout for the connection
486
+ this->set_timeout("wifi-connect-timeout", this->connection_timeout_.value(x...), [this]() {
487
+ this->connecting_ = false;
488
+ // If the timeout is reached, stop connecting and revert to the old AP
489
+ global_wifi_component->disable();
490
+ global_wifi_component->save_wifi_sta(old_sta_.get_ssid(), old_sta_.get_password());
491
+ global_wifi_component->enable();
492
+ // Callback to notify the user that the connection failed
493
+ this->error_trigger_->trigger();
494
+ });
495
+ }
496
+
497
+ Trigger<> *get_connect_trigger() const { return this->connect_trigger_; }
498
+ Trigger<> *get_error_trigger() const { return this->error_trigger_; }
499
+
500
+ void loop() override {
501
+ if (!this->connecting_)
502
+ return;
503
+ if (global_wifi_component->is_connected()) {
504
+ // The WiFi is connected, stop the timeout and reset the connecting flag
505
+ this->cancel_timeout("wifi-connect-timeout");
506
+ this->connecting_ = false;
507
+ if (global_wifi_component->wifi_ssid() == this->new_sta_.get_ssid()) {
508
+ // Callback to notify the user that the connection was successful
509
+ this->connect_trigger_->trigger();
510
+ } else {
511
+ // Callback to notify the user that the connection failed
512
+ this->error_trigger_->trigger();
513
+ }
514
+ }
515
+ }
516
+
517
+ protected:
518
+ bool connecting_{false};
519
+ WiFiAP new_sta_;
520
+ WiFiAP old_sta_;
521
+ Trigger<> *connect_trigger_{new Trigger<>()};
522
+ Trigger<> *error_trigger_{new Trigger<>()};
523
+ };
524
+
444
525
  } // namespace wifi
445
526
  } // namespace esphome
446
527
  #endif
@@ -815,7 +815,7 @@ bssid_t WiFiComponent::wifi_bssid() {
815
815
  }
816
816
  std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
817
817
  int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
818
- int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
818
+ int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); }
819
819
  network::IPAddress WiFiComponent::wifi_subnet_mask_() { return network::IPAddress(WiFi.subnetMask()); }
820
820
  network::IPAddress WiFiComponent::wifi_gateway_ip_() { return network::IPAddress(WiFi.gatewayIP()); }
821
821
  network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return network::IPAddress(WiFi.dnsIP(num)); }
@@ -841,7 +841,7 @@ bssid_t WiFiComponent::wifi_bssid() {
841
841
  }
842
842
  std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
843
843
  int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
844
- int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
844
+ int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); }
845
845
  network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {(const ip_addr_t *) WiFi.subnetMask()}; }
846
846
  network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {(const ip_addr_t *) WiFi.gatewayIP()}; }
847
847
  network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return {(const ip_addr_t *) WiFi.dnsIP(num)}; }
@@ -989,7 +989,7 @@ int8_t WiFiComponent::wifi_rssi() {
989
989
  }
990
990
  return info.rssi;
991
991
  }
992
- int32_t WiFiComponent::wifi_channel_() {
992
+ int32_t WiFiComponent::get_wifi_channel() {
993
993
  uint8_t primary;
994
994
  wifi_second_chan_t second;
995
995
  esp_err_t err = esp_wifi_get_channel(&primary, &second);
@@ -473,7 +473,7 @@ bssid_t WiFiComponent::wifi_bssid() {
473
473
  }
474
474
  std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
475
475
  int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
476
- int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
476
+ int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); }
477
477
  network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask()}; }
478
478
  network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {WiFi.gatewayIP()}; }
479
479
  network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return {WiFi.dnsIP(num)}; }
@@ -189,7 +189,7 @@ bssid_t WiFiComponent::wifi_bssid() {
189
189
  }
190
190
  std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
191
191
  int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
192
- int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
192
+ int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); }
193
193
 
194
194
  network::IPAddresses WiFiComponent::wifi_sta_ip_addresses() {
195
195
  network::IPAddresses addresses;
@@ -37,7 +37,7 @@ void Wireguard::setup() {
37
37
  this->wg_config_.netmask = this->netmask_.c_str();
38
38
  this->wg_config_.persistent_keepalive = this->keepalive_;
39
39
 
40
- if (this->preshared_key_.length() > 0)
40
+ if (!this->preshared_key_.empty())
41
41
  this->wg_config_.preshared_key = this->preshared_key_.c_str();
42
42
 
43
43
  this->publish_enabled_state();
@@ -137,7 +137,7 @@ void Wireguard::dump_config() {
137
137
  ESP_LOGCONFIG(TAG, " Peer Port: " LOG_SECRET("%d"), this->peer_port_);
138
138
  ESP_LOGCONFIG(TAG, " Peer Public Key: " LOG_SECRET("%s"), this->peer_public_key_.c_str());
139
139
  ESP_LOGCONFIG(TAG, " Peer Pre-shared Key: " LOG_SECRET("%s"),
140
- (this->preshared_key_.length() > 0 ? mask_key(this->preshared_key_).c_str() : "NOT IN USE"));
140
+ (!this->preshared_key_.empty() ? mask_key(this->preshared_key_).c_str() : "NOT IN USE"));
141
141
  ESP_LOGCONFIG(TAG, " Peer Allowed IPs:");
142
142
  for (auto &allowed_ip : this->allowed_ips_) {
143
143
  ESP_LOGCONFIG(TAG, " - %s/%s", std::get<0>(allowed_ip).c_str(), std::get<1>(allowed_ip).c_str());
@@ -249,7 +249,7 @@ optional<XiaomiParseResult> parse_xiaomi_header(const esp32_ble_tracker::Service
249
249
  }
250
250
 
251
251
  bool decrypt_xiaomi_payload(std::vector<uint8_t> &raw, const uint8_t *bindkey, const uint64_t &address) {
252
- if (!((raw.size() == 19) || ((raw.size() >= 22) && (raw.size() <= 24)))) {
252
+ if ((raw.size() != 19) && ((raw.size() < 22) || (raw.size() > 24))) {
253
253
  ESP_LOGVV(TAG, "decrypt_xiaomi_payload(): data packet has wrong size (%d)!", raw.size());
254
254
  ESP_LOGVV(TAG, " Packet : %s", format_hex_pretty(raw.data(), raw.size()).c_str());
255
255
  return false;
@@ -1839,8 +1839,6 @@ def validate_registry_entry(name, registry):
1839
1839
  def none(value):
1840
1840
  if value in ("none", "None"):
1841
1841
  return None
1842
- if boolean(value) is False:
1843
- return None
1844
1842
  raise Invalid("Must be none")
1845
1843
 
1846
1844
 
@@ -1912,17 +1910,23 @@ MQTT_COMMAND_COMPONENT_SCHEMA = MQTT_COMPONENT_SCHEMA.extend(
1912
1910
  }
1913
1911
  )
1914
1912
 
1913
+
1914
+ def _validate_entity_name(value):
1915
+ value = string(value)
1916
+ try:
1917
+ value = none(value) # pylint: disable=assignment-from-none
1918
+ except Invalid:
1919
+ pass
1920
+ else:
1921
+ requires_friendly_name(
1922
+ "Name cannot be None when esphome->friendly_name is not set!"
1923
+ )(value)
1924
+ return value
1925
+
1926
+
1915
1927
  ENTITY_BASE_SCHEMA = Schema(
1916
1928
  {
1917
- Optional(CONF_NAME): Any(
1918
- All(
1919
- none,
1920
- requires_friendly_name(
1921
- "Name cannot be None when esphome->friendly_name is not set!"
1922
- ),
1923
- ),
1924
- string,
1925
- ),
1929
+ Optional(CONF_NAME): _validate_entity_name,
1926
1930
  Optional(CONF_INTERNAL): boolean,
1927
1931
  Optional(CONF_DISABLED_BY_DEFAULT, default=False): boolean,
1928
1932
  Optional(CONF_ICON): icon,
esphome/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants used by esphome."""
2
2
 
3
- __version__ = "2024.11.3"
3
+ __version__ = "2024.12.0b1"
4
4
 
5
5
  ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
6
6
  VALID_SUBSTITUTIONS_CHARACTERS = (
@@ -528,6 +528,7 @@ CONF_MULTIPLE = "multiple"
528
528
  CONF_MULTIPLEXER = "multiplexer"
529
529
  CONF_MULTIPLY = "multiply"
530
530
  CONF_NAME = "name"
531
+ CONF_NAME_ADD_MAC_SUFFIX = "name_add_mac_suffix"
531
532
  CONF_NAME_FONT = "name_font"
532
533
  CONF_NBITS = "nbits"
533
534
  CONF_NEC = "nec"
@@ -574,6 +575,7 @@ CONF_ON_FINGER_SCAN_UNMATCHED = "on_finger_scan_unmatched"
574
575
  CONF_ON_FINISHED_WRITE = "on_finished_write"
575
576
  CONF_ON_IDLE = "on_idle"
576
577
  CONF_ON_JSON_MESSAGE = "on_json_message"
578
+ CONF_ON_KEY = "on_key"
577
579
  CONF_ON_LOCK = "on_lock"
578
580
  CONF_ON_LOOP = "on_loop"
579
581
  CONF_ON_MESSAGE = "on_message"
@@ -690,6 +692,7 @@ CONF_PRIORITY = "priority"
690
692
  CONF_PROJECT = "project"
691
693
  CONF_PROTOCOL = "protocol"
692
694
  CONF_PUBLISH_INITIAL_STATE = "publish_initial_state"
695
+ CONF_PUBLISH_NAN_AS_NONE = "publish_nan_as_none"
693
696
  CONF_PULL_MODE = "pull_mode"
694
697
  CONF_PULLDOWN = "pulldown"
695
698
  CONF_PULLUP = "pullup"
@@ -861,6 +864,7 @@ CONF_TARGET_TEMPERATURE_LOW_COMMAND_TOPIC = "target_temperature_low_command_topi
861
864
  CONF_TARGET_TEMPERATURE_LOW_STATE_TOPIC = "target_temperature_low_state_topic"
862
865
  CONF_TARGET_TEMPERATURE_STATE_TOPIC = "target_temperature_state_topic"
863
866
  CONF_TEMPERATURE = "temperature"
867
+ CONF_TEMPERATURE_COMPENSATION = "temperature_compensation"
864
868
  CONF_TEMPERATURE_OFFSET = "temperature_offset"
865
869
  CONF_TEMPERATURE_SOURCE = "temperature_source"
866
870
  CONF_TEMPERATURE_STEP = "temperature_step"
@@ -998,6 +1002,7 @@ ICON_GRAIN = "mdi:grain"
998
1002
  ICON_GYROSCOPE_X = "mdi:axis-x-rotate-clockwise"
999
1003
  ICON_GYROSCOPE_Y = "mdi:axis-y-rotate-clockwise"
1000
1004
  ICON_GYROSCOPE_Z = "mdi:axis-z-rotate-clockwise"
1005
+ ICON_HEART_PULSE = "mdi:heart-pulse"
1001
1006
  ICON_HEATING_COIL = "mdi:heating-coil"
1002
1007
  ICON_KEY_PLUS = "mdi:key-plus"
1003
1008
  ICON_LIGHTBULB = "mdi:lightbulb"
@@ -1037,6 +1042,7 @@ ICON_WEATHER_WINDY = "mdi:weather-windy"
1037
1042
  ICON_WIFI = "mdi:wifi"
1038
1043
 
1039
1044
  UNIT_AMPERE = "A"
1045
+ UNIT_BEATS_PER_MINUTE = "bpm"
1040
1046
  UNIT_BECQUEREL_PER_CUBIC_METER = "Bq/m³"
1041
1047
  UNIT_BYTES = "B"
1042
1048
  UNIT_CELSIUS = "°C"
@@ -67,7 +67,7 @@ bool Component::cancel_retry(const std::string &name) { // NOLINT
67
67
  }
68
68
 
69
69
  void Component::set_timeout(const std::string &name, uint32_t timeout, std::function<void()> &&f) { // NOLINT
70
- return App.scheduler.set_timeout(this, name, timeout, std::move(f));
70
+ App.scheduler.set_timeout(this, name, timeout, std::move(f));
71
71
  }
72
72
 
73
73
  bool Component::cancel_timeout(const std::string &name) { // NOLINT