esphome 2024.8.2__py3-none-any.whl → 2024.9.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.
Files changed (204) hide show
  1. esphome/__main__.py +6 -2
  2. esphome/components/api/api_connection.cpp +53 -0
  3. esphome/components/api/api_connection.h +4 -0
  4. esphome/components/api/api_pb2.cpp +280 -0
  5. esphome/components/api/api_pb2.h +91 -0
  6. esphome/components/api/api_pb2_service.cpp +85 -0
  7. esphome/components/api/api_pb2_service.h +28 -0
  8. esphome/components/async_tcp/__init__.py +3 -3
  9. esphome/components/atm90e26/sensor.py +10 -10
  10. esphome/components/atm90e32/sensor.py +1 -1
  11. esphome/components/bl0906/__init__.py +1 -0
  12. esphome/components/bl0906/bl0906.cpp +238 -0
  13. esphome/components/bl0906/bl0906.h +96 -0
  14. esphome/components/bl0906/const.py +4 -0
  15. esphome/components/bl0906/constants.h +122 -0
  16. esphome/components/bl0906/sensor.py +184 -0
  17. esphome/components/bl0942/__init__.py +1 -1
  18. esphome/components/bl0942/bl0942.cpp +127 -34
  19. esphome/components/bl0942/bl0942.h +87 -3
  20. esphome/components/bl0942/sensor.py +46 -8
  21. esphome/components/ble_client/__init__.py +1 -3
  22. esphome/components/ble_presence/binary_sensor.py +2 -2
  23. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
  24. esphome/components/bmp280/sensor.py +2 -93
  25. esphome/components/bmp280_base/__init__.py +88 -0
  26. esphome/components/{bmp280/bmp280.cpp → bmp280_base/bmp280_base.cpp} +11 -4
  27. esphome/components/{bmp280/bmp280.h → bmp280_base/bmp280_base.h} +9 -5
  28. esphome/components/bmp280_i2c/__init__.py +0 -0
  29. esphome/components/bmp280_i2c/bmp280_i2c.cpp +27 -0
  30. esphome/components/bmp280_i2c/bmp280_i2c.h +22 -0
  31. esphome/components/bmp280_i2c/sensor.py +22 -0
  32. esphome/components/bmp280_spi/__init__.py +0 -0
  33. esphome/components/bmp280_spi/bmp280_spi.cpp +65 -0
  34. esphome/components/bmp280_spi/bmp280_spi.h +20 -0
  35. esphome/components/bmp280_spi/sensor.py +22 -0
  36. esphome/components/captive_portal/captive_portal.cpp +2 -0
  37. esphome/components/captive_portal/captive_portal.h +3 -1
  38. esphome/components/ch422g/__init__.py +67 -0
  39. esphome/components/ch422g/ch422g.cpp +122 -0
  40. esphome/components/ch422g/ch422g.h +70 -0
  41. esphome/components/debug/debug_esp32.cpp +3 -1
  42. esphome/components/display/__init__.py +5 -4
  43. esphome/components/dsmr/dsmr.cpp +6 -0
  44. esphome/components/dsmr/dsmr.h +6 -0
  45. esphome/components/dsmr/text_sensor.py +7 -2
  46. esphome/components/e131/e131.cpp +2 -0
  47. esphome/components/e131/e131.h +3 -1
  48. esphome/components/e131/e131_addressable_light_effect.cpp +2 -0
  49. esphome/components/e131/e131_addressable_light_effect.h +2 -1
  50. esphome/components/e131/e131_packet.cpp +2 -0
  51. esphome/components/esp32_ble/ble_uuid.cpp +7 -0
  52. esphome/components/esp32_ble/ble_uuid.h +1 -0
  53. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -9
  54. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +3 -3
  55. esphome/components/esp32_camera/__init__.py +4 -0
  56. esphome/components/esp32_camera/esp32_camera.cpp +9 -1
  57. esphome/components/esp32_camera/esp32_camera.h +3 -0
  58. esphome/components/esp32_can/canbus.py +18 -7
  59. esphome/components/esp32_can/esp32_can.cpp +8 -0
  60. esphome/components/esp32_can/esp32_can.h +4 -0
  61. esphome/components/esp32_rmt_led_strip/led_strip.cpp +14 -2
  62. esphome/components/esp32_rmt_led_strip/led_strip.h +3 -2
  63. esphome/components/esp32_rmt_led_strip/light.py +21 -4
  64. esphome/components/esphome/ota/ota_esphome.cpp +2 -1
  65. esphome/components/esphome/ota/ota_esphome.h +2 -0
  66. esphome/components/font/__init__.py +11 -22
  67. esphome/components/font/font.cpp +3 -2
  68. esphome/components/font/font.h +12 -3
  69. esphome/components/gree/climate.py +2 -1
  70. esphome/components/gree/gree.cpp +54 -3
  71. esphome/components/gree/gree.h +10 -2
  72. esphome/components/gt911/touchscreen/__init__.py +6 -4
  73. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +17 -0
  74. esphome/components/gt911/touchscreen/gt911_touchscreen.h +2 -0
  75. esphome/components/hmac_md5/__init__.py +2 -0
  76. esphome/components/hmac_md5/hmac_md5.cpp +56 -0
  77. esphome/components/hmac_md5/hmac_md5.h +48 -0
  78. esphome/components/homeassistant/__init__.py +13 -0
  79. esphome/components/homeassistant/switch/__init__.py +15 -2
  80. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  81. esphome/components/i2s_audio/__init__.py +88 -9
  82. esphome/components/i2s_audio/i2s_audio.h +20 -2
  83. esphome/components/i2s_audio/media_player/__init__.py +8 -4
  84. esphome/components/i2s_audio/media_player/i2s_audio_media_player.h +1 -1
  85. esphome/components/i2s_audio/microphone/__init__.py +19 -51
  86. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +18 -15
  87. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +0 -12
  88. esphome/components/i2s_audio/speaker/__init__.py +39 -27
  89. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +49 -37
  90. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +3 -4
  91. esphome/components/ili9xxx/display.py +16 -17
  92. esphome/components/ili9xxx/ili9xxx_display.cpp +1 -1
  93. esphome/components/ili9xxx/ili9xxx_display.h +18 -18
  94. esphome/components/ili9xxx/ili9xxx_init.h +0 -3
  95. esphome/components/improv_serial/improv_serial_component.cpp +2 -1
  96. esphome/components/improv_serial/improv_serial_component.h +2 -1
  97. esphome/components/ledc/ledc_output.cpp +11 -7
  98. esphome/components/libretiny/__init__.py +8 -13
  99. esphome/components/ltr501/__init__.py +1 -0
  100. esphome/components/ltr501/ltr501.cpp +542 -0
  101. esphome/components/ltr501/ltr501.h +184 -0
  102. esphome/components/ltr501/ltr_definitions_501.h +260 -0
  103. esphome/components/ltr501/sensor.py +274 -0
  104. esphome/components/ltr_als_ps/sensor.py +2 -2
  105. esphome/components/lvgl/__init__.py +19 -16
  106. esphome/components/lvgl/automation.py +90 -9
  107. esphome/components/lvgl/defines.py +29 -2
  108. esphome/components/lvgl/gradient.py +61 -0
  109. esphome/components/lvgl/lv_validation.py +45 -27
  110. esphome/components/lvgl/lvcode.py +8 -3
  111. esphome/components/lvgl/lvgl_esphome.cpp +54 -0
  112. esphome/components/lvgl/lvgl_esphome.h +9 -3
  113. esphome/components/lvgl/number/__init__.py +1 -0
  114. esphome/components/lvgl/number/lvgl_number.h +3 -1
  115. esphome/components/lvgl/schemas.py +16 -11
  116. esphome/components/lvgl/select/__init__.py +1 -0
  117. esphome/components/lvgl/select/lvgl_select.h +3 -1
  118. esphome/components/lvgl/switch/__init__.py +2 -1
  119. esphome/components/lvgl/switch/lvgl_switch.h +3 -1
  120. esphome/components/lvgl/text/__init__.py +1 -0
  121. esphome/components/lvgl/text/lvgl_text.h +3 -1
  122. esphome/components/lvgl/trigger.py +3 -2
  123. esphome/components/lvgl/types.py +2 -1
  124. esphome/components/lvgl/widgets/__init__.py +23 -8
  125. esphome/components/lvgl/widgets/arc.py +5 -1
  126. esphome/components/lvgl/widgets/buttonmatrix.py +5 -1
  127. esphome/components/lvgl/widgets/checkbox.py +8 -3
  128. esphome/components/lvgl/widgets/meter.py +8 -1
  129. esphome/components/lvgl/widgets/msgbox.py +26 -15
  130. esphome/components/lvgl/widgets/page.py +51 -7
  131. esphome/components/lvgl/widgets/tileview.py +2 -8
  132. esphome/components/max31856/max31856.cpp +12 -1
  133. esphome/components/max31856/max31856.h +5 -2
  134. esphome/components/max31856/sensor.py +20 -0
  135. esphome/components/mcp9600/sensor.py +2 -2
  136. esphome/components/mdns/__init__.py +6 -6
  137. esphome/components/media_player/media_player.h +16 -0
  138. esphome/components/micro_wake_word/__init__.py +2 -25
  139. esphome/components/microphone/microphone.h +1 -1
  140. esphome/components/mics_4514/mics_4514.cpp +26 -36
  141. esphome/components/modbus_controller/__init__.py +6 -0
  142. esphome/components/modbus_controller/const.py +2 -0
  143. esphome/components/modbus_controller/modbus_controller.cpp +30 -27
  144. esphome/components/modbus_controller/modbus_controller.h +22 -4
  145. esphome/components/network/__init__.py +11 -8
  146. esphome/components/pipsolar/pipsolar.cpp +3 -0
  147. esphome/components/pipsolar/pipsolar.h +1 -0
  148. esphome/components/pipsolar/switch/__init__.py +2 -0
  149. esphome/components/prometheus/prometheus_handler.cpp +2 -0
  150. esphome/components/prometheus/prometheus_handler.h +3 -1
  151. esphome/components/rp2040/__init__.py +7 -8
  152. esphome/components/rpi_dpi_rgb/display.py +20 -17
  153. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +36 -6
  154. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h +4 -0
  155. esphome/components/socket/socket.cpp +2 -0
  156. esphome/components/socket/socket.h +2 -0
  157. esphome/components/speaker/speaker.h +1 -1
  158. esphome/components/st7701s/display.py +35 -37
  159. esphome/components/st7701s/st7701s.cpp +11 -6
  160. esphome/components/st7701s/st7701s.h +1 -0
  161. esphome/components/statsd/__init__.py +65 -0
  162. esphome/components/statsd/statsd.cpp +156 -0
  163. esphome/components/statsd/statsd.h +86 -0
  164. esphome/components/tuya/__init__.py +1 -0
  165. esphome/components/tuya/number/__init__.py +39 -2
  166. esphome/components/tuya/number/tuya_number.cpp +58 -2
  167. esphome/components/tuya/number/tuya_number.h +12 -3
  168. esphome/components/udp/__init__.py +158 -0
  169. esphome/components/udp/binary_sensor.py +27 -0
  170. esphome/components/udp/sensor.py +27 -0
  171. esphome/components/udp/udp_component.cpp +616 -0
  172. esphome/components/udp/udp_component.h +158 -0
  173. esphome/components/uponor_smatrix/uponor_smatrix.cpp +4 -6
  174. esphome/components/uponor_smatrix/uponor_smatrix.h +0 -1
  175. esphome/components/veml7700/sensor.py +2 -2
  176. esphome/components/voice_assistant/__init__.py +6 -0
  177. esphome/components/voice_assistant/voice_assistant.cpp +24 -2
  178. esphome/components/voice_assistant/voice_assistant.h +20 -0
  179. esphome/components/web_server/__init__.py +11 -11
  180. esphome/components/web_server/list_entities.cpp +2 -0
  181. esphome/components/web_server/list_entities.h +3 -1
  182. esphome/components/web_server/web_server.cpp +2 -1
  183. esphome/components/web_server/web_server.h +2 -0
  184. esphome/components/web_server_base/web_server_base.cpp +2 -0
  185. esphome/components/web_server_base/web_server_base.h +3 -1
  186. esphome/components/wifi/wifi_component_libretiny.cpp +15 -1
  187. esphome/components/wireguard/__init__.py +9 -6
  188. esphome/components/wireguard/wireguard.cpp +2 -1
  189. esphome/components/wireguard/wireguard.h +3 -1
  190. esphome/config_validation.py +8 -0
  191. esphome/const.py +8 -1
  192. esphome/core/bytebuffer.cpp +117 -84
  193. esphome/core/bytebuffer.h +69 -21
  194. esphome/core/config.py +0 -3
  195. esphome/core/defines.h +2 -0
  196. esphome/core/ring_buffer.cpp +13 -2
  197. esphome/core/ring_buffer.h +56 -0
  198. esphome/external_files.py +5 -3
  199. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/METADATA +1 -1
  200. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/RECORD +204 -169
  201. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/LICENSE +0 -0
  202. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/WHEEL +0 -0
  203. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/entry_points.txt +0 -0
  204. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/top_level.txt +0 -0
@@ -43,13 +43,16 @@ class LEDStripTimings:
43
43
  bit0_low: int
44
44
  bit1_high: int
45
45
  bit1_low: int
46
+ reset_high: int
47
+ reset_low: int
46
48
 
47
49
 
48
50
  CHIPSETS = {
49
- "WS2812": LEDStripTimings(400, 1000, 1000, 400),
50
- "SK6812": LEDStripTimings(300, 900, 600, 600),
51
- "APA106": LEDStripTimings(350, 1360, 1360, 350),
52
- "SM16703": LEDStripTimings(300, 900, 900, 300),
51
+ "WS2811": LEDStripTimings(300, 1090, 1090, 320, 0, 300000),
52
+ "WS2812": LEDStripTimings(400, 1000, 1000, 400, 0, 0),
53
+ "SK6812": LEDStripTimings(300, 900, 600, 600, 0, 0),
54
+ "APA106": LEDStripTimings(350, 1360, 1360, 350, 0, 0),
55
+ "SM16703": LEDStripTimings(300, 900, 900, 300, 0, 0),
53
56
  }
54
57
 
55
58
 
@@ -58,6 +61,8 @@ CONF_BIT0_HIGH = "bit0_high"
58
61
  CONF_BIT0_LOW = "bit0_low"
59
62
  CONF_BIT1_HIGH = "bit1_high"
60
63
  CONF_BIT1_LOW = "bit1_low"
64
+ CONF_RESET_HIGH = "reset_high"
65
+ CONF_RESET_LOW = "reset_low"
61
66
 
62
67
 
63
68
  CONFIG_SCHEMA = cv.All(
@@ -88,6 +93,14 @@ CONFIG_SCHEMA = cv.All(
88
93
  CONF_BIT1_LOW,
89
94
  "custom",
90
95
  ): cv.positive_time_period_nanoseconds,
96
+ cv.Optional(
97
+ CONF_RESET_HIGH,
98
+ default="0 us",
99
+ ): cv.positive_time_period_nanoseconds,
100
+ cv.Optional(
101
+ CONF_RESET_LOW,
102
+ default="0 us",
103
+ ): cv.positive_time_period_nanoseconds,
91
104
  }
92
105
  ),
93
106
  cv.has_exactly_one_key(CONF_CHIPSET, CONF_BIT0_HIGH),
@@ -113,6 +126,8 @@ async def to_code(config):
113
126
  chipset.bit0_low,
114
127
  chipset.bit1_high,
115
128
  chipset.bit1_low,
129
+ chipset.reset_high,
130
+ chipset.reset_low,
116
131
  )
117
132
  )
118
133
  else:
@@ -122,6 +137,8 @@ async def to_code(config):
122
137
  config[CONF_BIT0_LOW],
123
138
  config[CONF_BIT1_HIGH],
124
139
  config[CONF_BIT1_LOW],
140
+ config[CONF_RESET_HIGH],
141
+ config[CONF_RESET_LOW],
125
142
  )
126
143
  )
127
144
 
@@ -1,5 +1,5 @@
1
1
  #include "ota_esphome.h"
2
-
2
+ #ifdef USE_OTA
3
3
  #include "esphome/components/md5/md5.h"
4
4
  #include "esphome/components/network/util.h"
5
5
  #include "esphome/components/ota/ota_backend.h"
@@ -410,3 +410,4 @@ float ESPHomeOTAComponent::get_setup_priority() const { return setup_priority::A
410
410
  uint16_t ESPHomeOTAComponent::get_port() const { return this->port_; }
411
411
  void ESPHomeOTAComponent::set_port(uint16_t port) { this->port_ = port; }
412
412
  } // namespace esphome
413
+ #endif
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  #include "esphome/core/defines.h"
4
+ #ifdef USE_OTA
4
5
  #include "esphome/core/helpers.h"
5
6
  #include "esphome/core/preferences.h"
6
7
  #include "esphome/components/ota/ota_backend.h"
@@ -41,3 +42,4 @@ class ESPHomeOTAComponent : public ota::OTAComponent {
41
42
  };
42
43
 
43
44
  } // namespace esphome
45
+ #endif
@@ -1,43 +1,35 @@
1
+ import functools
1
2
  import hashlib
2
3
  import logging
3
-
4
- import functools
5
- from pathlib import Path
6
4
  import os
5
+ from pathlib import Path
7
6
  import re
7
+
8
8
  from packaging import version
9
9
  import requests
10
10
 
11
- from esphome import core
12
- from esphome import external_files
13
- import esphome.config_validation as cv
11
+ from esphome import core, external_files
14
12
  import esphome.codegen as cg
15
- from esphome.helpers import (
16
- copy_file_if_changed,
17
- cpp_string_escape,
18
- )
13
+ import esphome.config_validation as cv
19
14
  from esphome.const import (
20
15
  CONF_FAMILY,
21
16
  CONF_FILE,
22
17
  CONF_GLYPHS,
23
18
  CONF_ID,
19
+ CONF_PATH,
24
20
  CONF_RAW_DATA_ID,
25
- CONF_TYPE,
26
21
  CONF_REFRESH,
27
22
  CONF_SIZE,
28
- CONF_PATH,
29
- CONF_WEIGHT,
23
+ CONF_TYPE,
30
24
  CONF_URL,
25
+ CONF_WEIGHT,
31
26
  )
32
- from esphome.core import (
33
- CORE,
34
- HexInt,
35
- )
27
+ from esphome.core import CORE, HexInt
28
+ from esphome.helpers import copy_file_if_changed, cpp_string_escape
36
29
 
37
30
  _LOGGER = logging.getLogger(__name__)
38
31
 
39
32
  DOMAIN = "font"
40
- DEPENDENCIES = ["display"]
41
33
  MULTI_CONF = True
42
34
 
43
35
  CODEOWNERS = ["@esphome/core", "@clydebarrow"]
@@ -400,10 +392,7 @@ class EFont:
400
392
 
401
393
 
402
394
  def convert_bitmap_to_pillow_font(filepath):
403
- from PIL import (
404
- PcfFontFile,
405
- BdfFontFile,
406
- )
395
+ from PIL import BdfFontFile, PcfFontFile
407
396
 
408
397
  local_bitmap_font_file = external_files.compute_local_file_dir(
409
398
  DOMAIN,
@@ -1,9 +1,8 @@
1
1
  #include "font.h"
2
2
 
3
+ #include "esphome/core/color.h"
3
4
  #include "esphome/core/hal.h"
4
5
  #include "esphome/core/log.h"
5
- #include "esphome/core/color.h"
6
- #include "esphome/components/display/display_buffer.h"
7
6
 
8
7
  namespace esphome {
9
8
  namespace font {
@@ -68,6 +67,7 @@ int Font::match_next_glyph(const uint8_t *str, int *match_length) {
68
67
  return -1;
69
68
  return lo;
70
69
  }
70
+ #ifdef USE_DISPLAY
71
71
  void Font::measure(const char *str, int *width, int *x_offset, int *baseline, int *height) {
72
72
  *baseline = this->baseline_;
73
73
  *height = this->height_;
@@ -164,6 +164,7 @@ void Font::print(int x_start, int y_start, display::Display *display, Color colo
164
164
  i += match_length;
165
165
  }
166
166
  }
167
+ #endif
167
168
 
168
169
  } // namespace font
169
170
  } // namespace esphome
@@ -1,8 +1,11 @@
1
1
  #pragma once
2
2
 
3
- #include "esphome/core/datatypes.h"
4
3
  #include "esphome/core/color.h"
5
- #include "esphome/components/display/display_buffer.h"
4
+ #include "esphome/core/datatypes.h"
5
+ #include "esphome/core/defines.h"
6
+ #ifdef USE_DISPLAY
7
+ #include "esphome/components/display/display.h"
8
+ #endif
6
9
 
7
10
  namespace esphome {
8
11
  namespace font {
@@ -38,7 +41,11 @@ class Glyph {
38
41
  const GlyphData *glyph_data_;
39
42
  };
40
43
 
41
- class Font : public display::BaseFont {
44
+ class Font
45
+ #ifdef USE_DISPLAY
46
+ : public display::BaseFont
47
+ #endif
48
+ {
42
49
  public:
43
50
  /** Construct the font with the given glyphs.
44
51
  *
@@ -50,9 +57,11 @@ class Font : public display::BaseFont {
50
57
 
51
58
  int match_next_glyph(const uint8_t *str, int *match_length);
52
59
 
60
+ #ifdef USE_DISPLAY
53
61
  void print(int x_start, int y_start, display::Display *display, Color color, const char *text,
54
62
  Color background) override;
55
63
  void measure(const char *str, int *width, int *x_offset, int *baseline, int *height) override;
64
+ #endif
56
65
  inline int get_baseline() { return this->baseline_; }
57
66
  inline int get_height() { return this->height_; }
58
67
  inline int get_bpp() { return this->bpp_; }
@@ -1,6 +1,6 @@
1
1
  import esphome.codegen as cg
2
- import esphome.config_validation as cv
3
2
  from esphome.components import climate_ir
3
+ import esphome.config_validation as cv
4
4
  from esphome.const import CONF_ID, CONF_MODEL
5
5
 
6
6
  CODEOWNERS = ["@orestismers"]
@@ -17,6 +17,7 @@ MODELS = {
17
17
  "yaa": Model.GREE_YAA,
18
18
  "yac": Model.GREE_YAC,
19
19
  "yac1fb9": Model.GREE_YAC1FB9,
20
+ "yx1ff": Model.GREE_YX1FF,
20
21
  }
21
22
 
22
23
  CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
@@ -6,7 +6,15 @@ namespace gree {
6
6
 
7
7
  static const char *const TAG = "gree.climate";
8
8
 
9
- void GreeClimate::set_model(Model model) { this->model_ = model; }
9
+ void GreeClimate::set_model(Model model) {
10
+ if (model == GREE_YX1FF) {
11
+ this->fan_modes_.insert(climate::CLIMATE_FAN_QUIET); // YX1FF 4 speed
12
+ this->presets_.insert(climate::CLIMATE_PRESET_NONE); // YX1FF sleep mode
13
+ this->presets_.insert(climate::CLIMATE_PRESET_SLEEP); // YX1FF sleep mode
14
+ }
15
+
16
+ this->model_ = model;
17
+ }
10
18
 
11
19
  void GreeClimate::transmit_state() {
12
20
  uint8_t remote_state[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00};
@@ -14,7 +22,7 @@ void GreeClimate::transmit_state() {
14
22
  remote_state[0] = this->fan_speed_() | this->operation_mode_();
15
23
  remote_state[1] = this->temperature_();
16
24
 
17
- if (this->model_ == GREE_YAN) {
25
+ if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF) {
18
26
  remote_state[2] = 0x60;
19
27
  remote_state[3] = 0x50;
20
28
  remote_state[4] = this->vertical_swing_();
@@ -36,8 +44,18 @@ void GreeClimate::transmit_state() {
36
44
  }
37
45
  }
38
46
 
47
+ if (this->model_ == GREE_YX1FF) {
48
+ if (this->fan_speed_() == GREE_FAN_TURBO) {
49
+ remote_state[2] |= GREE_FAN_TURBO_BIT;
50
+ }
51
+
52
+ if (this->preset_() == GREE_PRESET_SLEEP) {
53
+ remote_state[0] |= GREE_PRESET_SLEEP_BIT;
54
+ }
55
+ }
56
+
39
57
  // Calculate the checksum
40
- if (this->model_ == GREE_YAN) {
58
+ if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF) {
41
59
  remote_state[7] = ((remote_state[0] << 4) + (remote_state[1] << 4) + 0xC0);
42
60
  } else {
43
61
  remote_state[7] =
@@ -124,6 +142,23 @@ uint8_t GreeClimate::operation_mode_() {
124
142
  }
125
143
 
126
144
  uint8_t GreeClimate::fan_speed_() {
145
+ // YX1FF has 4 fan speeds -- we treat low as quiet and turbo as high
146
+ if (this->model_ == GREE_YX1FF) {
147
+ switch (this->fan_mode.value()) {
148
+ case climate::CLIMATE_FAN_QUIET:
149
+ return GREE_FAN_1;
150
+ case climate::CLIMATE_FAN_LOW:
151
+ return GREE_FAN_2;
152
+ case climate::CLIMATE_FAN_MEDIUM:
153
+ return GREE_FAN_3;
154
+ case climate::CLIMATE_FAN_HIGH:
155
+ return GREE_FAN_TURBO;
156
+ case climate::CLIMATE_FAN_AUTO:
157
+ default:
158
+ return GREE_FAN_AUTO;
159
+ }
160
+ }
161
+
127
162
  switch (this->fan_mode.value()) {
128
163
  case climate::CLIMATE_FAN_LOW:
129
164
  return GREE_FAN_1;
@@ -161,5 +196,21 @@ uint8_t GreeClimate::temperature_() {
161
196
  return (uint8_t) roundf(clamp<float>(this->target_temperature, GREE_TEMP_MIN, GREE_TEMP_MAX));
162
197
  }
163
198
 
199
+ uint8_t GreeClimate::preset_() {
200
+ // YX1FF has sleep preset
201
+ if (this->model_ == GREE_YX1FF) {
202
+ switch (this->preset.value()) {
203
+ case climate::CLIMATE_PRESET_NONE:
204
+ return GREE_PRESET_NONE;
205
+ case climate::CLIMATE_PRESET_SLEEP:
206
+ return GREE_PRESET_SLEEP;
207
+ default:
208
+ return GREE_PRESET_NONE;
209
+ }
210
+ }
211
+
212
+ return GREE_PRESET_NONE;
213
+ }
214
+
164
215
  } // namespace gree
165
216
  } // namespace esphome
@@ -25,7 +25,6 @@ const uint8_t GREE_FAN_AUTO = 0x00;
25
25
  const uint8_t GREE_FAN_1 = 0x10;
26
26
  const uint8_t GREE_FAN_2 = 0x20;
27
27
  const uint8_t GREE_FAN_3 = 0x30;
28
- const uint8_t GREE_FAN_TURBO = 0x80;
29
28
 
30
29
  // IR Transmission
31
30
  const uint32_t GREE_IR_FREQUENCY = 38000;
@@ -70,8 +69,16 @@ const uint8_t GREE_HDIR_MIDDLE = 0x04;
70
69
  const uint8_t GREE_HDIR_MRIGHT = 0x05;
71
70
  const uint8_t GREE_HDIR_RIGHT = 0x06;
72
71
 
72
+ // Only available on YX1FF
73
+ // Turbo (high) fan mode + sleep preset mode
74
+ const uint8_t GREE_FAN_TURBO = 0x80;
75
+ const uint8_t GREE_FAN_TURBO_BIT = 0x10;
76
+ const uint8_t GREE_PRESET_NONE = 0x00;
77
+ const uint8_t GREE_PRESET_SLEEP = 0x01;
78
+ const uint8_t GREE_PRESET_SLEEP_BIT = 0x80;
79
+
73
80
  // Model codes
74
- enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC, GREE_YAC1FB9 };
81
+ enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC, GREE_YAC1FB9, GREE_YX1FF };
75
82
 
76
83
  class GreeClimate : public climate_ir::ClimateIR {
77
84
  public:
@@ -93,6 +100,7 @@ class GreeClimate : public climate_ir::ClimateIR {
93
100
  uint8_t horizontal_swing_();
94
101
  uint8_t vertical_swing_();
95
102
  uint8_t temperature_();
103
+ uint8_t preset_();
96
104
 
97
105
  Model model_{};
98
106
  };
@@ -1,12 +1,11 @@
1
+ from esphome import pins
1
2
  import esphome.codegen as cg
3
+ from esphome.components import i2c, touchscreen
2
4
  import esphome.config_validation as cv
5
+ from esphome.const import CONF_ID, CONF_INTERRUPT_PIN, CONF_RESET_PIN
3
6
 
4
- from esphome import pins
5
- from esphome.components import i2c, touchscreen
6
- from esphome.const import CONF_INTERRUPT_PIN, CONF_ID
7
7
  from .. import gt911_ns
8
8
 
9
-
10
9
  GT911ButtonListener = gt911_ns.class_("GT911ButtonListener")
11
10
  GT911Touchscreen = gt911_ns.class_(
12
11
  "GT911Touchscreen",
@@ -18,6 +17,7 @@ CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
18
17
  {
19
18
  cv.GenerateID(): cv.declare_id(GT911Touchscreen),
20
19
  cv.Optional(CONF_INTERRUPT_PIN): pins.internal_gpio_input_pin_schema,
20
+ cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
21
21
  }
22
22
  ).extend(i2c.i2c_device_schema(0x5D))
23
23
 
@@ -29,3 +29,5 @@ async def to_code(config):
29
29
 
30
30
  if interrupt_pin := config.get(CONF_INTERRUPT_PIN):
31
31
  cg.add(var.set_interrupt_pin(await cg.gpio_pin_expression(interrupt_pin)))
32
+ if reset_pin := config.get(CONF_RESET_PIN):
33
+ cg.add(var.set_reset_pin(await cg.gpio_pin_expression(reset_pin)))
@@ -26,6 +26,23 @@ static const size_t MAX_BUTTONS = 4; // max number of buttons scanned
26
26
  void GT911Touchscreen::setup() {
27
27
  i2c::ErrorCode err;
28
28
  ESP_LOGCONFIG(TAG, "Setting up GT911 Touchscreen...");
29
+ if (this->reset_pin_ != nullptr) {
30
+ this->reset_pin_->setup();
31
+ this->reset_pin_->digital_write(false);
32
+ if (this->interrupt_pin_ != nullptr) {
33
+ // The interrupt pin is used as an input during reset to select the I2C address.
34
+ this->interrupt_pin_->pin_mode(gpio::FLAG_OUTPUT);
35
+ this->interrupt_pin_->setup();
36
+ this->interrupt_pin_->digital_write(false);
37
+ }
38
+ delay(2);
39
+ this->reset_pin_->digital_write(true);
40
+ delay(50); // NOLINT
41
+ if (this->interrupt_pin_ != nullptr) {
42
+ this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT);
43
+ this->interrupt_pin_->setup();
44
+ }
45
+ }
29
46
 
30
47
  // check the configuration of the int line.
31
48
  uint8_t data[4];
@@ -19,12 +19,14 @@ class GT911Touchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice
19
19
  void dump_config() override;
20
20
 
21
21
  void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
22
+ void set_reset_pin(GPIOPin *pin) { this->reset_pin_ = pin; }
22
23
  void register_button_listener(GT911ButtonListener *listener) { this->button_listeners_.push_back(listener); }
23
24
 
24
25
  protected:
25
26
  void update_touches() override;
26
27
 
27
28
  InternalGPIOPin *interrupt_pin_{};
29
+ GPIOPin *reset_pin_{};
28
30
  std::vector<GT911ButtonListener *> button_listeners_;
29
31
  uint8_t button_state_{0xFF}; // last button state. Initial FF guarantees first update.
30
32
  };
@@ -0,0 +1,2 @@
1
+ AUTO_LOAD = ["md5"]
2
+ CODEOWNERS = ["@dwmw2"]
@@ -0,0 +1,56 @@
1
+ #include <cstdio>
2
+ #include <cstring>
3
+ #include "hmac_md5.h"
4
+ #include "esphome/core/helpers.h"
5
+
6
+ namespace esphome {
7
+ namespace hmac_md5 {
8
+ void HmacMD5::init(const uint8_t *key, size_t len) {
9
+ uint8_t ipad[64], opad[64];
10
+
11
+ memset(ipad, 0, sizeof(ipad));
12
+ if (len > 64) {
13
+ md5::MD5Digest keymd5;
14
+ keymd5.init();
15
+ keymd5.add(key, len);
16
+ keymd5.calculate();
17
+ keymd5.get_bytes(ipad);
18
+ } else {
19
+ memcpy(ipad, key, len);
20
+ }
21
+ memcpy(opad, ipad, sizeof(opad));
22
+
23
+ for (int i = 0; i < 64; i++) {
24
+ ipad[i] ^= 0x36;
25
+ opad[i] ^= 0x5c;
26
+ }
27
+
28
+ this->ihash_.init();
29
+ this->ihash_.add(ipad, sizeof(ipad));
30
+
31
+ this->ohash_.init();
32
+ this->ohash_.add(opad, sizeof(opad));
33
+ }
34
+
35
+ void HmacMD5::add(const uint8_t *data, size_t len) { this->ihash_.add(data, len); }
36
+
37
+ void HmacMD5::calculate() {
38
+ uint8_t ibytes[16];
39
+
40
+ this->ihash_.calculate();
41
+ this->ihash_.get_bytes(ibytes);
42
+
43
+ this->ohash_.add(ibytes, sizeof(ibytes));
44
+ this->ohash_.calculate();
45
+ }
46
+
47
+ void HmacMD5::get_bytes(uint8_t *output) { this->ohash_.get_bytes(output); }
48
+
49
+ void HmacMD5::get_hex(char *output) { this->ohash_.get_hex(output); }
50
+
51
+ bool HmacMD5::equals_bytes(const uint8_t *expected) { return this->ohash_.equals_bytes(expected); }
52
+
53
+ bool HmacMD5::equals_hex(const char *expected) { return this->ohash_.equals_hex(expected); }
54
+
55
+ } // namespace hmac_md5
56
+ } // namespace esphome
@@ -0,0 +1,48 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/defines.h"
4
+ #include "esphome/components/md5/md5.h"
5
+
6
+ #include <string>
7
+
8
+ namespace esphome {
9
+ namespace hmac_md5 {
10
+
11
+ class HmacMD5 {
12
+ public:
13
+ HmacMD5() = default;
14
+ ~HmacMD5() = default;
15
+
16
+ /// Initialize a new MD5 digest computation.
17
+ void init(const uint8_t *key, size_t len);
18
+ void init(const char *key, size_t len) { this->init((const uint8_t *) key, len); }
19
+ void init(const std::string &key) { this->init(key.c_str(), key.length()); }
20
+
21
+ /// Add bytes of data for the digest.
22
+ void add(const uint8_t *data, size_t len);
23
+ void add(const char *data, size_t len) { this->add((const uint8_t *) data, len); }
24
+
25
+ /// Compute the digest, based on the provided data.
26
+ void calculate();
27
+
28
+ /// Retrieve the HMAC-MD5 digest as bytes.
29
+ /// The output must be able to hold 16 bytes or more.
30
+ void get_bytes(uint8_t *output);
31
+
32
+ /// Retrieve the HMAC-MD5 digest as hex characters.
33
+ /// The output must be able to hold 32 bytes or more.
34
+ void get_hex(char *output);
35
+
36
+ /// Compare the digest against a provided byte-encoded digest (16 bytes).
37
+ bool equals_bytes(const uint8_t *expected);
38
+
39
+ /// Compare the digest against a provided hex-encoded digest (32 bytes).
40
+ bool equals_hex(const char *expected);
41
+
42
+ protected:
43
+ md5::MD5Digest ihash_;
44
+ md5::MD5Digest ohash_;
45
+ };
46
+
47
+ } // namespace hmac_md5
48
+ } // namespace esphome
@@ -5,6 +5,19 @@ from esphome.const import CONF_ATTRIBUTE, CONF_ENTITY_ID, CONF_INTERNAL
5
5
  CODEOWNERS = ["@OttoWinter", "@esphome/core"]
6
6
  homeassistant_ns = cg.esphome_ns.namespace("homeassistant")
7
7
 
8
+
9
+ def validate_entity_domain(platform, supported_domains):
10
+ def validator(config):
11
+ domain = config[CONF_ENTITY_ID].split(".", 1)[0]
12
+ if domain not in supported_domains:
13
+ raise cv.Invalid(
14
+ f"Entity ID {config[CONF_ENTITY_ID]} is not supported by the {platform} platform."
15
+ )
16
+ return config
17
+
18
+ return validator
19
+
20
+
8
21
  HOME_ASSISTANT_IMPORT_SCHEMA = cv.Schema(
9
22
  {
10
23
  cv.Required(CONF_ENTITY_ID): cv.entity_id,
@@ -7,19 +7,32 @@ from .. import (
7
7
  HOME_ASSISTANT_IMPORT_CONTROL_SCHEMA,
8
8
  homeassistant_ns,
9
9
  setup_home_assistant_entity,
10
+ validate_entity_domain,
10
11
  )
11
12
 
12
13
  CODEOWNERS = ["@Links2004"]
13
14
  DEPENDENCIES = ["api"]
14
15
 
16
+ SUPPORTED_DOMAINS = [
17
+ "automation",
18
+ "fan",
19
+ "humidifier",
20
+ "input_boolean",
21
+ "light",
22
+ "remote",
23
+ "siren",
24
+ "switch",
25
+ ]
26
+
15
27
  HomeassistantSwitch = homeassistant_ns.class_(
16
28
  "HomeassistantSwitch", switch.Switch, cg.Component
17
29
  )
18
30
 
19
- CONFIG_SCHEMA = (
31
+ CONFIG_SCHEMA = cv.All(
20
32
  switch.switch_schema(HomeassistantSwitch)
21
- .extend(cv.COMPONENT_SCHEMA)
22
33
  .extend(HOME_ASSISTANT_IMPORT_CONTROL_SCHEMA)
34
+ .extend(cv.COMPONENT_SCHEMA),
35
+ validate_entity_domain("switch", SUPPORTED_DOMAINS),
23
36
  )
24
37
 
25
38
 
@@ -42,9 +42,9 @@ void HomeassistantSwitch::write_state(bool state) {
42
42
 
43
43
  api::HomeassistantServiceResponse resp;
44
44
  if (state) {
45
- resp.service = "switch.turn_on";
45
+ resp.service = "homeassistant.turn_on";
46
46
  } else {
47
- resp.service = "switch.turn_off";
47
+ resp.service = "homeassistant.turn_off";
48
48
  }
49
49
 
50
50
  api::HomeassistantServiceMap entity_id_kv;