esphome 2024.10.3__py3-none-any.whl → 2024.11.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 (234) hide show
  1. esphome/__main__.py +22 -4
  2. esphome/automation.py +29 -2
  3. esphome/components/animation/__init__.py +5 -8
  4. esphome/components/animation/animation.cpp +1 -1
  5. esphome/components/audio/__init__.py +9 -0
  6. esphome/components/audio/audio.h +21 -0
  7. esphome/components/axs15231/__init__.py +6 -0
  8. esphome/components/axs15231/touchscreen/__init__.py +36 -0
  9. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +64 -0
  10. esphome/components/axs15231/touchscreen/axs15231_touchscreen.h +27 -0
  11. esphome/components/bme68x_bsec2/__init__.py +1 -1
  12. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +50 -47
  13. esphome/components/bme68x_bsec2/bme68x_bsec2.h +0 -2
  14. esphome/components/bytebuffer/__init__.py +5 -0
  15. esphome/components/bytebuffer/bytebuffer.h +421 -0
  16. esphome/components/climate/__init__.py +14 -13
  17. esphome/components/datetime/__init__.py +3 -3
  18. esphome/components/debug/debug_esp32.cpp +16 -8
  19. esphome/components/dfplayer/dfplayer.cpp +132 -6
  20. esphome/components/dfplayer/dfplayer.h +19 -53
  21. esphome/components/display/display.cpp +142 -0
  22. esphome/components/display/display.h +7 -0
  23. esphome/components/es8311/__init__.py +0 -0
  24. esphome/components/es8311/audio_dac.py +70 -0
  25. esphome/components/es8311/es8311.cpp +227 -0
  26. esphome/components/es8311/es8311.h +135 -0
  27. esphome/components/es8311/es8311_const.h +195 -0
  28. esphome/components/esp32/boards.py +199 -1
  29. esphome/components/esp32/gpio.py +3 -1
  30. esphome/components/esp32_ble/const_esp32c6.h +7 -0
  31. esphome/components/esp32_ble_client/ble_client_base.h +1 -1
  32. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +3 -0
  33. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -1
  34. esphome/components/esp32_rmt_led_strip/led_strip.cpp +2 -2
  35. esphome/components/esp32_rmt_led_strip/led_strip.h +2 -0
  36. esphome/components/esp32_rmt_led_strip/light.py +3 -1
  37. esphome/components/esp8266/gpio.py +7 -5
  38. esphome/components/ethernet/__init__.py +55 -1
  39. esphome/components/ethernet/ethernet_component.cpp +14 -1
  40. esphome/components/ethernet/ethernet_component.h +7 -1
  41. esphome/components/font/__init__.py +213 -108
  42. esphome/components/gp8403/output/__init__.py +1 -1
  43. esphome/components/host/gpio.py +6 -4
  44. esphome/components/http_request/__init__.py +12 -0
  45. esphome/components/http_request/http_request.h +65 -3
  46. esphome/components/http_request/http_request_arduino.cpp +4 -3
  47. esphome/components/http_request/http_request_idf.cpp +12 -14
  48. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  49. esphome/components/http_request/update/http_request_update.cpp +1 -1
  50. esphome/components/i2c_device/__init__.py +26 -0
  51. esphome/components/i2c_device/i2c_device.cpp +17 -0
  52. esphome/components/i2c_device/i2c_device.h +18 -0
  53. esphome/components/i2s_audio/__init__.py +1 -3
  54. esphome/components/i2s_audio/speaker/__init__.py +12 -4
  55. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +426 -200
  56. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +92 -33
  57. esphome/components/ili9xxx/display.py +5 -1
  58. esphome/components/image/__init__.py +5 -8
  59. esphome/components/image/image.cpp +14 -14
  60. esphome/components/image/image.h +20 -24
  61. esphome/components/internal_temperature/internal_temperature.cpp +51 -2
  62. esphome/components/internal_temperature/internal_temperature.h +1 -0
  63. esphome/components/ld2420/ld2420.cpp +1 -1
  64. esphome/components/libretiny/gpio.py +4 -2
  65. esphome/components/light/__init__.py +32 -1
  66. esphome/components/light/automation.py +39 -32
  67. esphome/components/light/effects.py +36 -36
  68. esphome/components/light/light_state.cpp +6 -16
  69. esphome/components/light/light_state.h +34 -0
  70. esphome/components/light/types.py +3 -1
  71. esphome/components/logger/logger_esp32.cpp +15 -0
  72. esphome/components/lvgl/__init__.py +202 -95
  73. esphome/components/lvgl/automation.py +42 -40
  74. esphome/components/lvgl/binary_sensor/__init__.py +8 -15
  75. esphome/components/lvgl/defines.py +14 -8
  76. esphome/components/lvgl/encoders.py +11 -8
  77. esphome/components/lvgl/keypads.py +77 -0
  78. esphome/components/lvgl/light/__init__.py +6 -8
  79. esphome/components/lvgl/lv_validation.py +2 -4
  80. esphome/components/lvgl/lvcode.py +3 -9
  81. esphome/components/lvgl/lvgl_esphome.cpp +210 -89
  82. esphome/components/lvgl/lvgl_esphome.h +113 -30
  83. esphome/components/lvgl/lvgl_proxy.h +17 -0
  84. esphome/components/lvgl/number/__init__.py +10 -15
  85. esphome/components/lvgl/schemas.py +4 -2
  86. esphome/components/lvgl/select/__init__.py +12 -37
  87. esphome/components/lvgl/select/lvgl_select.h +27 -33
  88. esphome/components/lvgl/sensor/__init__.py +8 -14
  89. esphome/components/lvgl/styles.py +3 -4
  90. esphome/components/lvgl/switch/__init__.py +8 -13
  91. esphome/components/lvgl/text/__init__.py +5 -6
  92. esphome/components/lvgl/text_sensor/__init__.py +15 -15
  93. esphome/components/lvgl/touchscreens.py +2 -3
  94. esphome/components/lvgl/trigger.py +7 -9
  95. esphome/components/lvgl/types.py +9 -3
  96. esphome/components/lvgl/widgets/__init__.py +32 -21
  97. esphome/components/lvgl/widgets/dropdown.py +22 -10
  98. esphome/components/lvgl/widgets/msgbox.py +6 -5
  99. esphome/components/lvgl/widgets/obj.py +4 -2
  100. esphome/components/lvgl/widgets/page.py +3 -2
  101. esphome/components/lvgl/widgets/qrcode.py +54 -0
  102. esphome/components/lvgl/widgets/roller.py +21 -14
  103. esphome/components/lvgl/widgets/tileview.py +2 -1
  104. esphome/components/max17043/__init__.py +1 -0
  105. esphome/components/max17043/automation.h +20 -0
  106. esphome/components/max17043/max17043.cpp +98 -0
  107. esphome/components/max17043/max17043.h +29 -0
  108. esphome/components/max17043/sensor.py +77 -0
  109. esphome/components/media_player/__init__.py +11 -0
  110. esphome/components/media_player/automation.h +10 -0
  111. esphome/components/media_player/media_player.cpp +4 -0
  112. esphome/components/midea/air_conditioner.cpp +17 -1
  113. esphome/components/mlx90393/sensor.py +1 -1
  114. esphome/components/modbus_controller/__init__.py +31 -1
  115. esphome/components/modbus_controller/automation.h +16 -0
  116. esphome/components/modbus_controller/const.py +2 -0
  117. esphome/components/modbus_controller/modbus_controller.cpp +14 -2
  118. esphome/components/modbus_controller/modbus_controller.h +9 -0
  119. esphome/components/mopeka_pro_check/mopeka_pro_check.cpp +40 -21
  120. esphome/components/mopeka_pro_check/mopeka_pro_check.h +9 -2
  121. esphome/components/mopeka_pro_check/sensor.py +41 -0
  122. esphome/components/mqtt/__init__.py +36 -0
  123. esphome/components/mqtt/mqtt_client.cpp +27 -3
  124. esphome/components/mqtt/mqtt_client.h +27 -2
  125. esphome/components/mqtt/mqtt_climate.cpp +4 -2
  126. esphome/components/mqtt/mqtt_component.cpp +6 -0
  127. esphome/components/mqtt/mqtt_component.h +4 -0
  128. esphome/components/mqtt/mqtt_const.h +6 -0
  129. esphome/components/online_image/online_image.cpp +2 -8
  130. esphome/components/online_image/online_image.h +2 -6
  131. esphome/components/opentherm/__init__.py +35 -9
  132. esphome/components/opentherm/binary_sensor/__init__.py +33 -0
  133. esphome/components/opentherm/const.py +11 -0
  134. esphome/components/opentherm/generate.py +142 -0
  135. esphome/components/opentherm/hub.cpp +130 -24
  136. esphome/components/opentherm/hub.h +62 -9
  137. esphome/components/opentherm/input.h +18 -0
  138. esphome/components/opentherm/input.py +51 -0
  139. esphome/components/opentherm/number/__init__.py +74 -0
  140. esphome/components/opentherm/number/number.cpp +40 -0
  141. esphome/components/opentherm/number/number.h +31 -0
  142. esphome/components/opentherm/opentherm.cpp +30 -0
  143. esphome/components/opentherm/opentherm.h +34 -2
  144. esphome/components/opentherm/opentherm_macros.h +151 -0
  145. esphome/components/opentherm/output/__init__.py +47 -0
  146. esphome/components/opentherm/output/output.cpp +18 -0
  147. esphome/components/opentherm/output/output.h +33 -0
  148. esphome/components/opentherm/schema.py +814 -0
  149. esphome/components/opentherm/sensor/__init__.py +51 -0
  150. esphome/components/opentherm/switch/__init__.py +43 -0
  151. esphome/components/opentherm/switch/switch.cpp +28 -0
  152. esphome/components/opentherm/switch/switch.h +20 -0
  153. esphome/components/opentherm/validate.py +31 -0
  154. esphome/components/pcd8544/display.py +8 -4
  155. esphome/components/prometheus/prometheus_handler.cpp +176 -14
  156. esphome/components/prometheus/prometheus_handler.h +25 -7
  157. esphome/components/qspi_amoled/display.py +1 -141
  158. esphome/components/qspi_dbi/display.py +185 -0
  159. esphome/components/qspi_dbi/models.py +64 -0
  160. esphome/components/{qspi_amoled/qspi_amoled.cpp → qspi_dbi/qspi_dbi.cpp} +95 -46
  161. esphome/components/{qspi_amoled/qspi_amoled.h → qspi_dbi/qspi_dbi.h} +26 -15
  162. esphome/components/rp2040/__init__.py +6 -3
  163. esphome/components/rp2040/gpio.py +5 -3
  164. esphome/components/rtttl/rtttl.cpp +4 -1
  165. esphome/components/rtttl/rtttl.h +1 -0
  166. esphome/components/sdl/sdl_esphome.cpp +22 -5
  167. esphome/components/sdl/sdl_esphome.h +1 -0
  168. esphome/components/sdm_meter/sdm_meter.cpp +1 -1
  169. esphome/components/sensor/__init__.py +18 -8
  170. esphome/components/sensor/filter.cpp +19 -18
  171. esphome/components/sensor/filter.h +9 -10
  172. esphome/components/sgp4x/sgp4x.cpp +40 -74
  173. esphome/components/sgp4x/sgp4x.h +5 -3
  174. esphome/components/speaker/__init__.py +51 -5
  175. esphome/components/speaker/automation.h +25 -0
  176. esphome/components/speaker/speaker.h +72 -1
  177. esphome/components/spi/__init__.py +15 -14
  178. esphome/components/spi_device/__init__.py +4 -15
  179. esphome/components/ssd1306_spi/display.py +6 -2
  180. esphome/components/ssd1322_spi/display.py +6 -2
  181. esphome/components/ssd1325_spi/display.py +6 -2
  182. esphome/components/ssd1327_spi/display.py +6 -2
  183. esphome/components/ssd1331_spi/display.py +6 -2
  184. esphome/components/ssd1351_spi/display.py +6 -2
  185. esphome/components/st7567_spi/display.py +6 -2
  186. esphome/components/st7701s/display.py +5 -1
  187. esphome/components/st7735/display.py +10 -5
  188. esphome/components/st7789v/display.py +12 -7
  189. esphome/components/statsd/statsd.cpp +2 -0
  190. esphome/components/statsd/statsd.h +2 -0
  191. esphome/components/sun/sun.h +3 -0
  192. esphome/components/tc74/__init__.py +1 -0
  193. esphome/components/tc74/sensor.py +32 -0
  194. esphome/components/tc74/tc74.cpp +68 -0
  195. esphome/components/tc74/tc74.h +28 -0
  196. esphome/components/touchscreen/__init__.py +41 -50
  197. esphome/components/touchscreen/touchscreen.h +4 -8
  198. esphome/components/tuya/fan/tuya_fan.cpp +1 -1
  199. esphome/components/udp/udp_component.cpp +6 -3
  200. esphome/components/udp/udp_component.h +4 -2
  201. esphome/components/waveshare_epaper/display.py +6 -2
  202. esphome/components/web_server/web_server.cpp +22 -0
  203. esphome/components/web_server/web_server.h +3 -0
  204. esphome/components/weikai/weikai.h +2 -2
  205. esphome/components/wifi/wifi_component.cpp +2 -2
  206. esphome/components/wifi/wifi_component_esp32_arduino.cpp +4 -4
  207. esphome/components/wifi/wifi_component_esp8266.cpp +4 -4
  208. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -2
  209. esphome/components/xpt2046/touchscreen/__init__.py +7 -32
  210. esphome/config_validation.py +3 -1
  211. esphome/const.py +9 -2
  212. esphome/core/defines.h +8 -2
  213. esphome/core/helpers.cpp +32 -17
  214. esphome/core/helpers.h +32 -16
  215. esphome/core/ring_buffer.cpp +2 -2
  216. esphome/core/ring_buffer.h +2 -2
  217. esphome/dashboard/core.py +25 -0
  218. esphome/dashboard/status/mdns.py +3 -4
  219. esphome/dashboard/web_server.py +54 -19
  220. esphome/espota2.py +36 -35
  221. esphome/helpers.py +68 -16
  222. esphome/mqtt.py +9 -2
  223. esphome/storage_json.py +4 -0
  224. esphome/writer.py +7 -18
  225. esphome/zeroconf.py +8 -6
  226. {esphome-2024.10.3.dist-info → esphome-2024.11.0.dist-info}/METADATA +7 -5
  227. {esphome-2024.10.3.dist-info → esphome-2024.11.0.dist-info}/RECORD +232 -186
  228. esphome/core/bytebuffer.cpp +0 -167
  229. esphome/core/bytebuffer.h +0 -144
  230. /esphome/components/{qspi_amoled → qspi_dbi}/__init__.py +0 -0
  231. {esphome-2024.10.3.dist-info → esphome-2024.11.0.dist-info}/LICENSE +0 -0
  232. {esphome-2024.10.3.dist-info → esphome-2024.11.0.dist-info}/WHEEL +0 -0
  233. {esphome-2024.10.3.dist-info → esphome-2024.11.0.dist-info}/entry_points.txt +0 -0
  234. {esphome-2024.10.3.dist-info → esphome-2024.11.0.dist-info}/top_level.txt +0 -0
esphome/__main__.py CHANGED
@@ -20,6 +20,8 @@ from esphome.const import (
20
20
  CONF_DEASSERT_RTS_DTR,
21
21
  CONF_DISABLED,
22
22
  CONF_ESPHOME,
23
+ CONF_LEVEL,
24
+ CONF_LOG_TOPIC,
23
25
  CONF_LOGGER,
24
26
  CONF_MDNS,
25
27
  CONF_MQTT,
@@ -30,6 +32,7 @@ from esphome.const import (
30
32
  CONF_PLATFORMIO_OPTIONS,
31
33
  CONF_PORT,
32
34
  CONF_SUBSTITUTIONS,
35
+ CONF_TOPIC,
33
36
  PLATFORM_BK72XX,
34
37
  PLATFORM_ESP32,
35
38
  PLATFORM_ESP8266,
@@ -38,7 +41,7 @@ from esphome.const import (
38
41
  SECRETS_FILES,
39
42
  )
40
43
  from esphome.core import CORE, EsphomeError, coroutine
41
- from esphome.helpers import indent, is_ip_address, get_bool_env
44
+ from esphome.helpers import get_bool_env, indent, is_ip_address
42
45
  from esphome.log import Fore, color, setup_log
43
46
  from esphome.util import (
44
47
  get_serial_ports,
@@ -95,8 +98,12 @@ def choose_upload_log_host(
95
98
  options.append((f"Over The Air ({CORE.address})", CORE.address))
96
99
  if default == "OTA":
97
100
  return CORE.address
98
- if show_mqtt and CONF_MQTT in CORE.config:
99
- options.append((f"MQTT ({CORE.config['mqtt'][CONF_BROKER]})", "MQTT"))
101
+ if (
102
+ show_mqtt
103
+ and (mqtt_config := CORE.config.get(CONF_MQTT))
104
+ and mqtt_logging_enabled(mqtt_config)
105
+ ):
106
+ options.append((f"MQTT ({mqtt_config[CONF_BROKER]})", "MQTT"))
100
107
  if default == "OTA":
101
108
  return "MQTT"
102
109
  if default is not None:
@@ -106,6 +113,17 @@ def choose_upload_log_host(
106
113
  return choose_prompt(options, purpose=purpose)
107
114
 
108
115
 
116
+ def mqtt_logging_enabled(mqtt_config):
117
+ log_topic = mqtt_config[CONF_LOG_TOPIC]
118
+ if log_topic is None:
119
+ return False
120
+ if CONF_TOPIC not in log_topic:
121
+ return False
122
+ if log_topic.get(CONF_LEVEL, None) == "NONE":
123
+ return False
124
+ return True
125
+
126
+
109
127
  def get_port_type(port):
110
128
  if port.startswith("/") or port.startswith("COM"):
111
129
  return "SERIAL"
@@ -378,7 +396,7 @@ def show_logs(config, args, port):
378
396
 
379
397
  port = mqtt.get_esphome_device_ip(
380
398
  config, args.username, args.password, args.client_id
381
- )
399
+ )[0]
382
400
 
383
401
  from esphome.components.api.client import run_logs
384
402
 
esphome/automation.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import esphome.codegen as cg
2
2
  import esphome.config_validation as cv
3
3
  from esphome.const import (
4
+ CONF_ALL,
5
+ CONF_ANY,
4
6
  CONF_AUTOMATION_ID,
5
7
  CONF_CONDITION,
6
8
  CONF_COUNT,
@@ -73,6 +75,13 @@ def validate_potentially_and_condition(value):
73
75
  return validate_condition(value)
74
76
 
75
77
 
78
+ def validate_potentially_or_condition(value):
79
+ if isinstance(value, list):
80
+ with cv.remove_prepend_path(["or"]):
81
+ return validate_condition({"or": value})
82
+ return validate_condition(value)
83
+
84
+
76
85
  DelayAction = cg.esphome_ns.class_("DelayAction", Action, cg.Component)
77
86
  LambdaAction = cg.esphome_ns.class_("LambdaAction", Action)
78
87
  IfAction = cg.esphome_ns.class_("IfAction", Action)
@@ -166,6 +175,18 @@ async def or_condition_to_code(config, condition_id, template_arg, args):
166
175
  return cg.new_Pvariable(condition_id, template_arg, conditions)
167
176
 
168
177
 
178
+ @register_condition("all", AndCondition, validate_condition_list)
179
+ async def all_condition_to_code(config, condition_id, template_arg, args):
180
+ conditions = await build_condition_list(config, template_arg, args)
181
+ return cg.new_Pvariable(condition_id, template_arg, conditions)
182
+
183
+
184
+ @register_condition("any", OrCondition, validate_condition_list)
185
+ async def any_condition_to_code(config, condition_id, template_arg, args):
186
+ conditions = await build_condition_list(config, template_arg, args)
187
+ return cg.new_Pvariable(condition_id, template_arg, conditions)
188
+
189
+
169
190
  @register_condition("not", NotCondition, validate_potentially_and_condition)
170
191
  async def not_condition_to_code(config, condition_id, template_arg, args):
171
192
  condition = await build_condition(config, template_arg, args)
@@ -223,15 +244,21 @@ async def delay_action_to_code(config, action_id, template_arg, args):
223
244
  IfAction,
224
245
  cv.All(
225
246
  {
226
- cv.Required(CONF_CONDITION): validate_potentially_and_condition,
247
+ cv.Exclusive(
248
+ CONF_CONDITION, CONF_CONDITION
249
+ ): validate_potentially_and_condition,
250
+ cv.Exclusive(CONF_ANY, CONF_CONDITION): validate_potentially_or_condition,
251
+ cv.Exclusive(CONF_ALL, CONF_CONDITION): validate_potentially_and_condition,
227
252
  cv.Optional(CONF_THEN): validate_action_list,
228
253
  cv.Optional(CONF_ELSE): validate_action_list,
229
254
  },
230
255
  cv.has_at_least_one_key(CONF_THEN, CONF_ELSE),
256
+ cv.has_at_least_one_key(CONF_CONDITION, CONF_ANY, CONF_ALL),
231
257
  ),
232
258
  )
233
259
  async def if_action_to_code(config, action_id, template_arg, args):
234
- conditions = await build_condition(config[CONF_CONDITION], template_arg, args)
260
+ cond_conf = next(el for el in config if el in (CONF_ANY, CONF_ALL, CONF_CONDITION))
261
+ conditions = await build_condition(config[cond_conf], template_arg, args)
235
262
  var = cg.new_Pvariable(action_id, template_arg, conditions)
236
263
  if CONF_THEN in config:
237
264
  actions = await build_action_list(config[CONF_THEN], template_arg, args)
@@ -271,7 +271,8 @@ async def to_code(config):
271
271
  pos += 1
272
272
 
273
273
  elif config[CONF_TYPE] in ["RGB565", "TRANSPARENT_IMAGE"]:
274
- data = [0 for _ in range(height * width * 2 * frames)]
274
+ bytes_per_pixel = 3 if transparent else 2
275
+ data = [0 for _ in range(height * width * bytes_per_pixel * frames)]
275
276
  pos = 0
276
277
  for frameIndex in range(frames):
277
278
  image.seek(frameIndex)
@@ -288,17 +289,13 @@ async def to_code(config):
288
289
  G = g >> 2
289
290
  B = b >> 3
290
291
  rgb = (R << 11) | (G << 5) | B
291
-
292
- if transparent:
293
- if rgb == 0x0020:
294
- rgb = 0
295
- if a < 0x80:
296
- rgb = 0x0020
297
-
298
292
  data[pos] = rgb >> 8
299
293
  pos += 1
300
294
  data[pos] = rgb & 0xFF
301
295
  pos += 1
296
+ if transparent:
297
+ data[pos] = a
298
+ pos += 1
302
299
 
303
300
  elif config[CONF_TYPE] in ["BINARY", "TRANSPARENT_BINARY"]:
304
301
  width8 = ((width + 7) // 8) * 8
@@ -62,7 +62,7 @@ void Animation::set_frame(int frame) {
62
62
  }
63
63
 
64
64
  void Animation::update_data_start_() {
65
- const uint32_t image_size = image_type_to_width_stride(this->width_, this->type_) * this->height_;
65
+ const uint32_t image_size = this->get_width_stride() * this->height_;
66
66
  this->data_start_ = this->animation_data_start_ + image_size * this->current_frame_;
67
67
  }
68
68
 
@@ -0,0 +1,9 @@
1
+ import esphome.codegen as cg
2
+ import esphome.config_validation as cv
3
+
4
+ CODEOWNERS = ["@kahrendt"]
5
+ audio_ns = cg.esphome_ns.namespace("audio")
6
+
7
+ CONFIG_SCHEMA = cv.All(
8
+ cv.Schema({}),
9
+ )
@@ -0,0 +1,21 @@
1
+ #pragma once
2
+
3
+ #include <cstdint>
4
+ #include <stddef.h>
5
+
6
+ namespace esphome {
7
+ namespace audio {
8
+
9
+ struct AudioStreamInfo {
10
+ bool operator==(const AudioStreamInfo &rhs) const {
11
+ return (channels == rhs.channels) && (bits_per_sample == rhs.bits_per_sample) && (sample_rate == rhs.sample_rate);
12
+ }
13
+ bool operator!=(const AudioStreamInfo &rhs) const { return !operator==(rhs); }
14
+ size_t get_bytes_per_sample() const { return bits_per_sample / 8; }
15
+ uint8_t channels = 1;
16
+ uint8_t bits_per_sample = 16;
17
+ uint32_t sample_rate = 16000;
18
+ };
19
+
20
+ } // namespace audio
21
+ } // namespace esphome
@@ -0,0 +1,6 @@
1
+ import esphome.codegen as cg
2
+
3
+ CODEOWNERS = ["@clydebarrow"]
4
+ DEPENDENCIES = ["i2c"]
5
+
6
+ axs15231_ns = cg.esphome_ns.namespace("axs15231")
@@ -0,0 +1,36 @@
1
+ from esphome import pins
2
+ import esphome.codegen as cg
3
+ from esphome.components import i2c, touchscreen
4
+ import esphome.config_validation as cv
5
+ from esphome.const import CONF_ID, CONF_INTERRUPT_PIN, CONF_RESET_PIN
6
+
7
+ from .. import axs15231_ns
8
+
9
+ AXS15231Touchscreen = axs15231_ns.class_(
10
+ "AXS15231Touchscreen",
11
+ touchscreen.Touchscreen,
12
+ i2c.I2CDevice,
13
+ )
14
+
15
+ CONFIG_SCHEMA = (
16
+ touchscreen.touchscreen_schema("50ms")
17
+ .extend(
18
+ {
19
+ cv.GenerateID(): cv.declare_id(AXS15231Touchscreen),
20
+ cv.Optional(CONF_INTERRUPT_PIN): pins.internal_gpio_input_pin_schema,
21
+ cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
22
+ }
23
+ )
24
+ .extend(i2c.i2c_device_schema(0x3B))
25
+ )
26
+
27
+
28
+ async def to_code(config):
29
+ var = cg.new_Pvariable(config[CONF_ID])
30
+ await touchscreen.register_touchscreen(var, config)
31
+ await i2c.register_i2c_device(var, config)
32
+
33
+ if interrupt_pin := config.get(CONF_INTERRUPT_PIN):
34
+ cg.add(var.set_interrupt_pin(await cg.gpio_pin_expression(interrupt_pin)))
35
+ if reset_pin := config.get(CONF_RESET_PIN):
36
+ cg.add(var.set_reset_pin(await cg.gpio_pin_expression(reset_pin)))
@@ -0,0 +1,64 @@
1
+ #include "axs15231_touchscreen.h"
2
+
3
+ #include "esphome/core/helpers.h"
4
+ #include "esphome/core/log.h"
5
+
6
+ namespace esphome {
7
+ namespace axs15231 {
8
+
9
+ static const char *const TAG = "ax15231.touchscreen";
10
+
11
+ constexpr static const uint8_t AXS_READ_TOUCHPAD[11] = {0xb5, 0xab, 0xa5, 0x5a, 0x0, 0x0, 0x0, 0x8};
12
+
13
+ #define ERROR_CHECK(err) \
14
+ if ((err) != i2c::ERROR_OK) { \
15
+ this->status_set_warning("Failed to communicate"); \
16
+ return; \
17
+ }
18
+
19
+ void AXS15231Touchscreen::setup() {
20
+ ESP_LOGCONFIG(TAG, "Setting up AXS15231 Touchscreen...");
21
+ if (this->reset_pin_ != nullptr) {
22
+ this->reset_pin_->setup();
23
+ this->reset_pin_->digital_write(false);
24
+ delay(5);
25
+ this->reset_pin_->digital_write(true);
26
+ delay(10);
27
+ }
28
+ if (this->interrupt_pin_ != nullptr) {
29
+ this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT);
30
+ this->interrupt_pin_->setup();
31
+ this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
32
+ }
33
+ this->x_raw_max_ = this->display_->get_native_width();
34
+ this->y_raw_max_ = this->display_->get_native_height();
35
+ ESP_LOGCONFIG(TAG, "AXS15231 Touchscreen setup complete");
36
+ }
37
+
38
+ void AXS15231Touchscreen::update_touches() {
39
+ i2c::ErrorCode err;
40
+ uint8_t data[8]{};
41
+
42
+ err = this->write(AXS_READ_TOUCHPAD, sizeof(AXS_READ_TOUCHPAD), false);
43
+ ERROR_CHECK(err);
44
+ err = this->read(data, sizeof(data));
45
+ ERROR_CHECK(err);
46
+ this->status_clear_warning();
47
+ if (data[0] != 0) // no touches
48
+ return;
49
+ uint16_t x = encode_uint16(data[2] & 0xF, data[3]);
50
+ uint16_t y = encode_uint16(data[4] & 0xF, data[5]);
51
+ this->add_raw_touch_position_(0, x, y);
52
+ }
53
+
54
+ void AXS15231Touchscreen::dump_config() {
55
+ ESP_LOGCONFIG(TAG, "AXS15231 Touchscreen:");
56
+ LOG_I2C_DEVICE(this);
57
+ LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
58
+ LOG_PIN(" Reset Pin: ", this->reset_pin_);
59
+ ESP_LOGCONFIG(TAG, " Width: %d", this->x_raw_max_);
60
+ ESP_LOGCONFIG(TAG, " Height: %d", this->y_raw_max_);
61
+ }
62
+
63
+ } // namespace axs15231
64
+ } // namespace esphome
@@ -0,0 +1,27 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/i2c/i2c.h"
4
+ #include "esphome/components/touchscreen/touchscreen.h"
5
+ #include "esphome/core/component.h"
6
+ #include "esphome/core/hal.h"
7
+
8
+ namespace esphome {
9
+ namespace axs15231 {
10
+
11
+ class AXS15231Touchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice {
12
+ public:
13
+ void setup() override;
14
+ void dump_config() override;
15
+
16
+ void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
17
+ void set_reset_pin(GPIOPin *pin) { this->reset_pin_ = pin; }
18
+
19
+ protected:
20
+ void update_touches() override;
21
+
22
+ InternalGPIOPin *interrupt_pin_{};
23
+ GPIOPin *reset_pin_{};
24
+ };
25
+
26
+ } // namespace axs15231
27
+ } // namespace esphome
@@ -16,7 +16,7 @@ CODEOWNERS = ["@neffs", "@kbx81"]
16
16
 
17
17
  DOMAIN = "bme68x_bsec2"
18
18
 
19
- BSEC2_LIBRARY_VERSION = "v1.7.2502"
19
+ BSEC2_LIBRARY_VERSION = "v1.8.2610"
20
20
 
21
21
  CONF_ALGORITHM_OUTPUT = "algorithm_output"
22
22
  CONF_BME68X_BSEC2_ID = "bme68x_bsec2_id"
@@ -204,11 +204,11 @@ void BME68xBSEC2Component::update_subscription_() {
204
204
  }
205
205
 
206
206
  void BME68xBSEC2Component::run_() {
207
+ this->op_mode_ = this->bsec_settings_.op_mode;
207
208
  int64_t curr_time_ns = this->get_time_ns_();
208
- if (curr_time_ns < this->next_call_ns_) {
209
+ if (curr_time_ns < this->bsec_settings_.next_call) {
209
210
  return;
210
211
  }
211
- this->op_mode_ = this->bsec_settings_.op_mode;
212
212
  uint8_t status;
213
213
 
214
214
  ESP_LOGV(TAG, "Performing sensor run");
@@ -219,57 +219,60 @@ void BME68xBSEC2Component::run_() {
219
219
  ESP_LOGW(TAG, "Failed to fetch sensor control settings (BSEC2 error code %d)", this->bsec_status_);
220
220
  return;
221
221
  }
222
- this->next_call_ns_ = this->bsec_settings_.next_call;
223
222
 
224
- if (this->bsec_settings_.trigger_measurement) {
225
- bme68x_get_conf(&bme68x_conf, &this->bme68x_);
223
+ switch (this->bsec_settings_.op_mode) {
224
+ case BME68X_FORCED_MODE:
225
+ bme68x_get_conf(&bme68x_conf, &this->bme68x_);
226
226
 
227
- bme68x_conf.os_hum = this->bsec_settings_.humidity_oversampling;
228
- bme68x_conf.os_temp = this->bsec_settings_.temperature_oversampling;
229
- bme68x_conf.os_pres = this->bsec_settings_.pressure_oversampling;
230
- bme68x_set_conf(&bme68x_conf, &this->bme68x_);
227
+ bme68x_conf.os_hum = this->bsec_settings_.humidity_oversampling;
228
+ bme68x_conf.os_temp = this->bsec_settings_.temperature_oversampling;
229
+ bme68x_conf.os_pres = this->bsec_settings_.pressure_oversampling;
230
+ bme68x_set_conf(&bme68x_conf, &this->bme68x_);
231
+ this->bme68x_heatr_conf_.enable = BME68X_ENABLE;
232
+ this->bme68x_heatr_conf_.heatr_temp = this->bsec_settings_.heater_temperature;
233
+ this->bme68x_heatr_conf_.heatr_dur = this->bsec_settings_.heater_duration;
231
234
 
232
- switch (this->bsec_settings_.op_mode) {
233
- case BME68X_FORCED_MODE:
234
- this->bme68x_heatr_conf_.enable = BME68X_ENABLE;
235
- this->bme68x_heatr_conf_.heatr_temp = this->bsec_settings_.heater_temperature;
236
- this->bme68x_heatr_conf_.heatr_dur = this->bsec_settings_.heater_duration;
235
+ // status = bme68x_set_op_mode(this->bsec_settings_.op_mode, &this->bme68x_);
236
+ status = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &this->bme68x_heatr_conf_, &this->bme68x_);
237
+ status = bme68x_set_op_mode(BME68X_FORCED_MODE, &this->bme68x_);
238
+ this->op_mode_ = BME68X_FORCED_MODE;
239
+ ESP_LOGV(TAG, "Using forced mode");
237
240
 
238
- status = bme68x_set_op_mode(this->bsec_settings_.op_mode, &this->bme68x_);
239
- status = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &this->bme68x_heatr_conf_, &this->bme68x_);
240
- status = bme68x_set_op_mode(BME68X_FORCED_MODE, &this->bme68x_);
241
- this->op_mode_ = BME68X_FORCED_MODE;
242
- this->sleep_mode_ = false;
243
- ESP_LOGV(TAG, "Using forced mode");
241
+ break;
242
+ case BME68X_PARALLEL_MODE:
243
+ if (this->op_mode_ != this->bsec_settings_.op_mode) {
244
+ bme68x_get_conf(&bme68x_conf, &this->bme68x_);
244
245
 
245
- break;
246
- case BME68X_PARALLEL_MODE:
247
- if (this->op_mode_ != this->bsec_settings_.op_mode) {
248
- this->bme68x_heatr_conf_.enable = BME68X_ENABLE;
249
- this->bme68x_heatr_conf_.heatr_temp_prof = this->bsec_settings_.heater_temperature_profile;
250
- this->bme68x_heatr_conf_.heatr_dur_prof = this->bsec_settings_.heater_duration_profile;
251
- this->bme68x_heatr_conf_.profile_len = this->bsec_settings_.heater_profile_len;
252
- this->bme68x_heatr_conf_.shared_heatr_dur =
253
- BSEC_TOTAL_HEAT_DUR -
254
- (bme68x_get_meas_dur(BME68X_PARALLEL_MODE, &bme68x_conf, &this->bme68x_) / INT64_C(1000));
255
-
256
- status = bme68x_set_heatr_conf(BME68X_PARALLEL_MODE, &this->bme68x_heatr_conf_, &this->bme68x_);
257
-
258
- status = bme68x_set_op_mode(BME68X_PARALLEL_MODE, &this->bme68x_);
259
- this->op_mode_ = BME68X_PARALLEL_MODE;
260
- this->sleep_mode_ = false;
261
- ESP_LOGV(TAG, "Using parallel mode");
262
- }
263
- break;
264
- case BME68X_SLEEP_MODE:
265
- if (!this->sleep_mode_) {
266
- bme68x_set_op_mode(BME68X_SLEEP_MODE, &this->bme68x_);
267
- this->sleep_mode_ = true;
268
- ESP_LOGV(TAG, "Using sleep mode");
269
- }
270
- break;
271
- }
246
+ bme68x_conf.os_hum = this->bsec_settings_.humidity_oversampling;
247
+ bme68x_conf.os_temp = this->bsec_settings_.temperature_oversampling;
248
+ bme68x_conf.os_pres = this->bsec_settings_.pressure_oversampling;
249
+ bme68x_set_conf(&bme68x_conf, &this->bme68x_);
250
+
251
+ this->bme68x_heatr_conf_.enable = BME68X_ENABLE;
252
+ this->bme68x_heatr_conf_.heatr_temp_prof = this->bsec_settings_.heater_temperature_profile;
253
+ this->bme68x_heatr_conf_.heatr_dur_prof = this->bsec_settings_.heater_duration_profile;
254
+ this->bme68x_heatr_conf_.profile_len = this->bsec_settings_.heater_profile_len;
255
+ this->bme68x_heatr_conf_.shared_heatr_dur =
256
+ BSEC_TOTAL_HEAT_DUR -
257
+ (bme68x_get_meas_dur(BME68X_PARALLEL_MODE, &bme68x_conf, &this->bme68x_) / INT64_C(1000));
258
+
259
+ status = bme68x_set_heatr_conf(BME68X_PARALLEL_MODE, &this->bme68x_heatr_conf_, &this->bme68x_);
260
+
261
+ status = bme68x_set_op_mode(BME68X_PARALLEL_MODE, &this->bme68x_);
262
+ this->op_mode_ = BME68X_PARALLEL_MODE;
263
+ ESP_LOGV(TAG, "Using parallel mode");
264
+ }
265
+ break;
266
+ case BME68X_SLEEP_MODE:
267
+ if (this->op_mode_ != this->bsec_settings_.op_mode) {
268
+ bme68x_set_op_mode(BME68X_SLEEP_MODE, &this->bme68x_);
269
+ this->op_mode_ = BME68X_SLEEP_MODE;
270
+ ESP_LOGV(TAG, "Using sleep mode");
271
+ }
272
+ break;
273
+ }
272
274
 
275
+ if (this->bsec_settings_.trigger_measurement && this->bsec_settings_.op_mode != BME68X_SLEEP_MODE) {
273
276
  uint32_t meas_dur = 0;
274
277
  meas_dur = bme68x_get_meas_dur(this->op_mode_, &bme68x_conf, &this->bme68x_);
275
278
  ESP_LOGV(TAG, "Queueing read in %uus", meas_dur);
@@ -113,13 +113,11 @@ class BME68xBSEC2Component : public Component {
113
113
 
114
114
  struct bme68x_heatr_conf bme68x_heatr_conf_;
115
115
  uint8_t op_mode_; // operating mode of sensor
116
- bool sleep_mode_;
117
116
  bsec_library_return_t bsec_status_{BSEC_OK};
118
117
  int8_t bme68x_status_{BME68X_OK};
119
118
 
120
119
  int64_t last_time_ms_{0};
121
120
  uint32_t millis_overflow_counter_{0};
122
- int64_t next_call_ns_{0};
123
121
 
124
122
  std::queue<std::function<void()>> queue_;
125
123
 
@@ -0,0 +1,5 @@
1
+ CODEOWNERS = ["@clydebarrow"]
2
+
3
+ # Allows bytebuffer to be configured in yaml, to allow use of the C++ api.
4
+
5
+ CONFIG_SCHEMA = {}