esphome 2025.9.3__py3-none-any.whl → 2025.10.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 (343) hide show
  1. esphome/__main__.py +87 -31
  2. esphome/address_cache.py +142 -0
  3. esphome/automation.py +130 -32
  4. esphome/build_gen/platformio.py +1 -3
  5. esphome/codegen.py +1 -0
  6. esphome/components/animation/animation.cpp +2 -2
  7. esphome/components/api/__init__.py +166 -3
  8. esphome/components/api/api_connection.cpp +84 -41
  9. esphome/components/api/api_connection.h +22 -16
  10. esphome/components/api/api_frame_helper.cpp +33 -19
  11. esphome/components/api/api_frame_helper.h +19 -4
  12. esphome/components/api/api_frame_helper_noise.cpp +41 -53
  13. esphome/components/api/api_frame_helper_noise.h +1 -1
  14. esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
  15. esphome/components/api/api_frame_helper_plaintext.h +1 -1
  16. esphome/components/api/api_pb2.cpp +189 -15
  17. esphome/components/api/api_pb2.h +132 -20
  18. esphome/components/api/api_pb2_dump.cpp +97 -9
  19. esphome/components/api/api_pb2_service.cpp +118 -160
  20. esphome/components/api/api_pb2_service.h +31 -3
  21. esphome/components/api/api_server.cpp +68 -10
  22. esphome/components/api/api_server.h +32 -4
  23. esphome/components/api/custom_api_device.h +8 -8
  24. esphome/components/api/homeassistant_service.h +123 -6
  25. esphome/components/api/proto.h +6 -2
  26. esphome/components/api/user_services.h +2 -2
  27. esphome/components/as7341/sensor.py +1 -1
  28. esphome/components/audio/__init__.py +1 -1
  29. esphome/components/audio/audio.cpp +1 -1
  30. esphome/components/audio/audio_decoder.cpp +9 -9
  31. esphome/components/bl0906/bl0906.cpp +2 -2
  32. esphome/components/bl0942/bl0942.cpp +2 -2
  33. esphome/components/ble_client/__init__.py +1 -1
  34. esphome/components/bluetooth_proxy/__init__.py +4 -30
  35. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
  36. esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
  37. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  38. esphome/components/camera_encoder/__init__.py +2 -4
  39. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
  40. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
  41. esphome/components/canbus/canbus.cpp +7 -5
  42. esphome/components/canbus/canbus.h +4 -4
  43. esphome/components/captive_portal/__init__.py +18 -1
  44. esphome/components/captive_portal/captive_portal.cpp +40 -46
  45. esphome/components/captive_portal/captive_portal.h +20 -22
  46. esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
  47. esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
  48. esphome/components/ccs811/ccs811.cpp +1 -1
  49. esphome/components/climate/climate.cpp +10 -7
  50. esphome/components/cm1106/cm1106.cpp +1 -1
  51. esphome/components/copy/lock/copy_lock.cpp +1 -1
  52. esphome/components/cover/cover.cpp +1 -0
  53. esphome/components/daikin_arc/daikin_arc.cpp +19 -12
  54. esphome/components/deep_sleep/__init__.py +9 -2
  55. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  56. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  57. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  58. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  59. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  60. esphome/components/epaper_spi/__init__.py +1 -0
  61. esphome/components/epaper_spi/display.py +80 -0
  62. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  63. esphome/components/epaper_spi/epaper_spi.h +93 -0
  64. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  65. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  66. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  67. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  68. esphome/components/es7210/es7210.cpp +3 -3
  69. esphome/components/esp32/__init__.py +254 -339
  70. esphome/components/esp32/boards.py +81 -0
  71. esphome/components/esp32/preferences.cpp +23 -17
  72. esphome/components/esp32_ble/__init__.py +159 -44
  73. esphome/components/esp32_ble/ble.cpp +47 -3
  74. esphome/components/esp32_ble/ble.h +18 -0
  75. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  76. esphome/components/esp32_ble/ble_advertising.h +4 -0
  77. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  78. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  79. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  80. esphome/components/esp32_ble_server/__init__.py +28 -14
  81. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  82. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  83. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  84. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  85. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  86. esphome/components/esp32_ble_server/ble_server.h +38 -20
  87. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  88. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  89. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  90. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -4
  91. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  92. esphome/components/esp32_camera/__init__.py +1 -3
  93. esphome/components/esp32_can/esp32_can.cpp +22 -4
  94. esphome/components/esp32_can/esp32_can.h +3 -0
  95. esphome/components/esp32_hosted/__init__.py +2 -1
  96. esphome/components/esp32_improv/esp32_improv_component.cpp +102 -44
  97. esphome/components/esp32_improv/esp32_improv_component.h +6 -1
  98. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  99. esphome/components/esp8266/__init__.py +3 -3
  100. esphome/components/esphome/ota/__init__.py +21 -2
  101. esphome/components/esphome/ota/ota_esphome.cpp +455 -145
  102. esphome/components/esphome/ota/ota_esphome.h +49 -2
  103. esphome/components/ethernet/__init__.py +39 -22
  104. esphome/components/ethernet/ethernet_component.cpp +28 -5
  105. esphome/components/ethernet/ethernet_component.h +5 -1
  106. esphome/components/external_components/__init__.py +8 -6
  107. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  108. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  109. esphome/components/font/__init__.py +5 -5
  110. esphome/components/graph/graph.cpp +1 -1
  111. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  112. esphome/components/haier/hon_climate.cpp +2 -2
  113. esphome/components/haier/hon_climate.h +1 -1
  114. esphome/components/hdc1080/hdc1080.cpp +42 -34
  115. esphome/components/hdc1080/hdc1080.h +1 -3
  116. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  117. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  118. esphome/components/http_request/__init__.py +3 -3
  119. esphome/components/htu21d/htu21d.cpp +13 -18
  120. esphome/components/htu21d/htu21d.h +1 -1
  121. esphome/components/i2s_audio/__init__.py +1 -2
  122. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  123. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  124. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  125. esphome/components/improv_serial/improv_serial_component.h +6 -8
  126. esphome/components/json/json_util.cpp +35 -43
  127. esphome/components/json/json_util.h +57 -0
  128. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  129. esphome/components/key_collector/key_collector.h +4 -4
  130. esphome/components/libretiny/__init__.py +6 -6
  131. esphome/components/libretiny/preferences.cpp +23 -16
  132. esphome/components/light/light_call.cpp +98 -120
  133. esphome/components/light/light_call.h +17 -7
  134. esphome/components/lm75b/__init__.py +0 -0
  135. esphome/components/lm75b/lm75b.cpp +39 -0
  136. esphome/components/lm75b/lm75b.h +19 -0
  137. esphome/components/lm75b/sensor.py +34 -0
  138. esphome/components/lock/lock.h +12 -6
  139. esphome/components/logger/__init__.py +15 -27
  140. esphome/components/logger/logger.cpp +10 -20
  141. esphome/components/logger/logger.h +105 -62
  142. esphome/components/logger/logger_esp32.cpp +0 -48
  143. esphome/components/logger/logger_zephyr.cpp +2 -3
  144. esphome/components/logger/select/logger_level_select.cpp +6 -7
  145. esphome/components/logger/select/logger_level_select.h +7 -0
  146. esphome/components/ltr501/ltr501.cpp +7 -6
  147. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  148. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  149. esphome/components/max7219digit/max7219digit.cpp +1 -1
  150. esphome/components/mcp2515/mcp2515.cpp +31 -3
  151. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  152. esphome/components/md5/md5.cpp +0 -26
  153. esphome/components/md5/md5.h +10 -20
  154. esphome/components/mdns/__init__.py +19 -6
  155. esphome/components/mdns/mdns_component.cpp +27 -59
  156. esphome/components/mdns/mdns_component.h +23 -10
  157. esphome/components/mdns/mdns_esp32.cpp +7 -7
  158. esphome/components/mdns/mdns_esp8266.cpp +6 -6
  159. esphome/components/mdns/mdns_libretiny.cpp +3 -3
  160. esphome/components/mdns/mdns_rp2040.cpp +3 -3
  161. esphome/components/mipi/__init__.py +1 -5
  162. esphome/components/mipi_spi/display.py +24 -8
  163. esphome/components/mipi_spi/mipi_spi.h +3 -3
  164. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  165. esphome/components/mmc5603/mmc5603.cpp +3 -3
  166. esphome/components/modbus/modbus.cpp +27 -13
  167. esphome/components/modbus/modbus.h +5 -3
  168. esphome/components/modbus/modbus_definitions.h +86 -0
  169. esphome/components/modbus_controller/__init__.py +29 -1
  170. esphome/components/modbus_controller/const.py +4 -0
  171. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  172. esphome/components/modbus_controller/modbus_controller.h +18 -29
  173. esphome/components/mpr121/mpr121.cpp +41 -42
  174. esphome/components/mpr121/mpr121.h +0 -1
  175. esphome/components/nau7802/nau7802.cpp +2 -2
  176. esphome/components/network/__init__.py +7 -3
  177. esphome/components/nextion/display.py +4 -4
  178. esphome/components/nextion/nextion.cpp +8 -8
  179. esphome/components/number/__init__.py +2 -0
  180. esphome/components/number/number_call.cpp +23 -12
  181. esphome/components/number/number_call.h +5 -0
  182. esphome/components/online_image/bmp_image.cpp +2 -1
  183. esphome/components/online_image/jpeg_image.cpp +4 -2
  184. esphome/components/openthread/openthread.cpp +6 -7
  185. esphome/components/openthread/openthread.h +0 -1
  186. esphome/components/ota/ota_backend.h +1 -0
  187. esphome/components/packages/__init__.py +10 -8
  188. esphome/components/packet_transport/packet_transport.cpp +2 -0
  189. esphome/components/pid/pid_controller.cpp +1 -1
  190. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  191. esphome/components/psram/__init__.py +30 -28
  192. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  193. esphome/components/qmc5883l/qmc5883l.h +3 -0
  194. esphome/components/qmc5883l/sensor.py +31 -12
  195. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  196. esphome/components/remote_receiver/__init__.py +14 -2
  197. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  198. esphome/components/remote_receiver/remote_receiver.h +4 -0
  199. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  200. esphome/components/remote_transmitter/__init__.py +2 -2
  201. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  202. esphome/components/rp2040/__init__.py +11 -11
  203. esphome/components/rtttl/rtttl.cpp +2 -2
  204. esphome/components/scd30/sensor.py +1 -1
  205. esphome/components/script/__init__.py +1 -1
  206. esphome/components/script/script.h +7 -7
  207. esphome/components/select/select.cpp +5 -4
  208. esphome/components/select/select_call.cpp +1 -1
  209. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  210. esphome/components/sensor/__init__.py +2 -0
  211. esphome/components/sha256/__init__.py +22 -0
  212. esphome/components/sha256/sha256.cpp +116 -0
  213. esphome/components/sha256/sha256.h +60 -0
  214. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  215. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  216. esphome/components/spi/__init__.py +0 -3
  217. esphome/components/split_buffer/__init__.py +5 -0
  218. esphome/components/split_buffer/split_buffer.cpp +133 -0
  219. esphome/components/split_buffer/split_buffer.h +40 -0
  220. esphome/components/sps30/sps30.cpp +14 -10
  221. esphome/components/sps30/sps30.h +2 -0
  222. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  223. esphome/components/st7789v/st7789v.cpp +3 -2
  224. esphome/components/statsd/statsd.cpp +1 -1
  225. esphome/components/substitutions/__init__.py +3 -1
  226. esphome/components/substitutions/jinja.py +13 -3
  227. esphome/components/sx126x/__init__.py +16 -0
  228. esphome/components/sx126x/sx126x.cpp +15 -1
  229. esphome/components/sx126x/sx126x.h +9 -1
  230. esphome/components/sx126x/sx126x_reg.h +2 -0
  231. esphome/components/text_sensor/text_sensor.cpp +16 -0
  232. esphome/components/text_sensor/text_sensor.h +3 -10
  233. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  234. esphome/components/tuya/select/tuya_select.cpp +1 -1
  235. esphome/components/tuya/tuya.cpp +29 -4
  236. esphome/components/uart/__init__.py +36 -26
  237. esphome/components/uart/uart.h +6 -0
  238. esphome/components/uart/uart_component.cpp +8 -0
  239. esphome/components/uart/uart_component.h +28 -0
  240. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  241. esphome/components/uart/uart_component_esp_idf.h +5 -2
  242. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  243. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  244. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  245. esphome/components/usb_host/__init__.py +2 -1
  246. esphome/components/usb_host/usb_host.h +82 -13
  247. esphome/components/usb_host/usb_host_client.cpp +180 -24
  248. esphome/components/usb_host/usb_host_component.cpp +1 -1
  249. esphome/components/usb_uart/__init__.py +0 -1
  250. esphome/components/usb_uart/ch34x.cpp +4 -4
  251. esphome/components/usb_uart/cp210x.cpp +3 -3
  252. esphome/components/usb_uart/usb_uart.cpp +88 -32
  253. esphome/components/usb_uart/usb_uart.h +30 -6
  254. esphome/components/valve/valve.cpp +1 -0
  255. esphome/components/veml7700/veml7700.cpp +7 -6
  256. esphome/components/version/version_text_sensor.cpp +2 -1
  257. esphome/components/voice_assistant/voice_assistant.cpp +3 -2
  258. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  259. esphome/components/web_server/list_entities.cpp +3 -4
  260. esphome/components/web_server/list_entities.h +8 -10
  261. esphome/components/web_server/ota/__init__.py +1 -1
  262. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  263. esphome/components/web_server/web_server.cpp +509 -404
  264. esphome/components/web_server/web_server.h +5 -6
  265. esphome/components/web_server/web_server_v1.cpp +21 -19
  266. esphome/components/web_server_base/__init__.py +5 -2
  267. esphome/components/web_server_base/web_server_base.h +27 -7
  268. esphome/components/web_server_idf/__init__.py +1 -1
  269. esphome/components/web_server_idf/multipart.cpp +2 -2
  270. esphome/components/web_server_idf/multipart.h +2 -2
  271. esphome/components/web_server_idf/utils.cpp +2 -2
  272. esphome/components/web_server_idf/utils.h +2 -2
  273. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  274. esphome/components/web_server_idf/web_server_idf.h +12 -10
  275. esphome/components/wifi/__init__.py +13 -11
  276. esphome/components/wifi/wifi_component.cpp +73 -56
  277. esphome/components/wifi/wifi_component.h +4 -4
  278. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  279. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  280. esphome/components/wireguard/__init__.py +1 -1
  281. esphome/components/wts01/__init__.py +0 -0
  282. esphome/components/wts01/sensor.py +41 -0
  283. esphome/components/wts01/wts01.cpp +91 -0
  284. esphome/components/wts01/wts01.h +27 -0
  285. esphome/components/zephyr/__init__.py +5 -5
  286. esphome/components/zwave_proxy/__init__.py +43 -0
  287. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  288. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  289. esphome/config.py +79 -24
  290. esphome/config_validation.py +13 -15
  291. esphome/const.py +9 -2
  292. esphome/core/__init__.py +31 -22
  293. esphome/core/component.cpp +28 -18
  294. esphome/core/component_iterator.h +2 -1
  295. esphome/core/config.py +15 -15
  296. esphome/core/defines.h +19 -0
  297. esphome/core/hash_base.h +56 -0
  298. esphome/core/helpers.cpp +19 -3
  299. esphome/core/helpers.h +26 -0
  300. esphome/core/scheduler.cpp +5 -21
  301. esphome/core/scheduler.h +19 -8
  302. esphome/core/string_ref.h +1 -1
  303. esphome/core/time.cpp +5 -5
  304. esphome/cpp_generator.py +4 -29
  305. esphome/dashboard/const.py +21 -4
  306. esphome/dashboard/core.py +10 -8
  307. esphome/dashboard/dns.py +15 -0
  308. esphome/dashboard/entries.py +15 -21
  309. esphome/dashboard/models.py +76 -0
  310. esphome/dashboard/settings.py +7 -7
  311. esphome/dashboard/status/mdns.py +46 -2
  312. esphome/dashboard/web_server.py +367 -93
  313. esphome/espota2.py +111 -31
  314. esphome/external_files.py +6 -7
  315. esphome/git.py +8 -0
  316. esphome/helpers.py +124 -77
  317. esphome/loader.py +8 -9
  318. esphome/platformio_api.py +25 -18
  319. esphome/storage_json.py +26 -21
  320. esphome/types.py +30 -2
  321. esphome/util.py +32 -16
  322. esphome/vscode.py +8 -8
  323. esphome/wizard.py +10 -10
  324. esphome/writer.py +50 -15
  325. esphome/yaml_util.py +37 -31
  326. esphome/zeroconf.py +12 -3
  327. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
  328. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +332 -312
  329. esphome/components/event_emitter/__init__.py +0 -5
  330. esphome/components/event_emitter/event_emitter.cpp +0 -14
  331. esphome/components/event_emitter/event_emitter.h +0 -63
  332. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  333. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  334. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  335. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  336. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  337. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  338. esphome/core/string_ref.cpp +0 -12
  339. esphome/dashboard/util/file.py +0 -63
  340. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
  341. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
  342. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
  343. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -2,11 +2,12 @@
2
2
 
3
3
  #include "ble_descriptor.h"
4
4
  #include "esphome/components/esp32_ble/ble_uuid.h"
5
- #include "esphome/components/event_emitter/event_emitter.h"
6
5
  #include "esphome/components/bytebuffer/bytebuffer.h"
7
6
 
8
7
  #include <vector>
9
- #include <unordered_map>
8
+ #include <span>
9
+ #include <functional>
10
+ #include <memory>
10
11
 
11
12
  #ifdef USE_ESP32
12
13
 
@@ -23,22 +24,10 @@ namespace esp32_ble_server {
23
24
 
24
25
  using namespace esp32_ble;
25
26
  using namespace bytebuffer;
26
- using namespace event_emitter;
27
27
 
28
28
  class BLEService;
29
29
 
30
- namespace BLECharacteristicEvt {
31
- enum VectorEvt {
32
- ON_WRITE,
33
- };
34
-
35
- enum EmptyEvt {
36
- ON_READ,
37
- };
38
- } // namespace BLECharacteristicEvt
39
-
40
- class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>,
41
- public EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t> {
30
+ class BLECharacteristic {
42
31
  public:
43
32
  BLECharacteristic(ESPBTUUID uuid, uint32_t properties);
44
33
  ~BLECharacteristic();
@@ -77,6 +66,15 @@ class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, s
77
66
  bool is_created();
78
67
  bool is_failed();
79
68
 
69
+ // Direct callback registration - only allocates when callback is set
70
+ void on_write(std::function<void(std::span<const uint8_t>, uint16_t)> &&callback) {
71
+ this->on_write_callback_ =
72
+ std::make_unique<std::function<void(std::span<const uint8_t>, uint16_t)>>(std::move(callback));
73
+ }
74
+ void on_read(std::function<void(uint16_t)> &&callback) {
75
+ this->on_read_callback_ = std::make_unique<std::function<void(uint16_t)>>(std::move(callback));
76
+ }
77
+
80
78
  protected:
81
79
  bool write_event_{false};
82
80
  BLEService *service_{};
@@ -89,7 +87,20 @@ class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, s
89
87
  SemaphoreHandle_t set_value_lock_;
90
88
 
91
89
  std::vector<BLEDescriptor *> descriptors_;
92
- std::unordered_map<uint16_t, bool> clients_to_notify_;
90
+
91
+ struct ClientNotificationEntry {
92
+ uint16_t conn_id;
93
+ bool indicate; // true = indicate, false = notify
94
+ };
95
+ std::vector<ClientNotificationEntry> clients_to_notify_;
96
+
97
+ void remove_client_from_notify_list_(uint16_t conn_id);
98
+ ClientNotificationEntry *find_client_in_notify_list_(uint16_t conn_id);
99
+
100
+ void set_property_bit_(esp_gatt_char_prop_t bit, bool value);
101
+
102
+ std::unique_ptr<std::function<void(std::span<const uint8_t>, uint16_t)>> on_write_callback_;
103
+ std::unique_ptr<std::function<void(uint16_t)>> on_read_callback_;
93
104
 
94
105
  esp_gatt_perm_t permissions_ = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
95
106
 
@@ -74,9 +74,10 @@ void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
74
74
  break;
75
75
  this->value_.attr_len = param->write.len;
76
76
  memcpy(this->value_.attr_value, param->write.value, param->write.len);
77
- this->emit_(BLEDescriptorEvt::VectorEvt::ON_WRITE,
78
- std::vector<uint8_t>(param->write.value, param->write.value + param->write.len),
79
- param->write.conn_id);
77
+ if (this->on_write_callback_) {
78
+ (*this->on_write_callback_)(std::span<const uint8_t>(param->write.value, param->write.len),
79
+ param->write.conn_id);
80
+ }
80
81
  break;
81
82
  }
82
83
  default:
@@ -1,30 +1,26 @@
1
1
  #pragma once
2
2
 
3
3
  #include "esphome/components/esp32_ble/ble_uuid.h"
4
- #include "esphome/components/event_emitter/event_emitter.h"
5
4
  #include "esphome/components/bytebuffer/bytebuffer.h"
6
5
 
7
6
  #ifdef USE_ESP32
8
7
 
9
8
  #include <esp_gatt_defs.h>
10
9
  #include <esp_gatts_api.h>
10
+ #include <span>
11
+ #include <functional>
12
+ #include <memory>
11
13
 
12
14
  namespace esphome {
13
15
  namespace esp32_ble_server {
14
16
 
15
17
  using namespace esp32_ble;
16
18
  using namespace bytebuffer;
17
- using namespace event_emitter;
18
19
 
19
20
  class BLECharacteristic;
20
21
 
21
- namespace BLEDescriptorEvt {
22
- enum VectorEvt {
23
- ON_WRITE,
24
- };
25
- } // namespace BLEDescriptorEvt
26
-
27
- class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vector<uint8_t>, uint16_t> {
22
+ // Base class for BLE descriptors
23
+ class BLEDescriptor {
28
24
  public:
29
25
  BLEDescriptor(ESPBTUUID uuid, uint16_t max_len = 100, bool read = true, bool write = true);
30
26
  virtual ~BLEDescriptor();
@@ -39,6 +35,12 @@ class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vect
39
35
  bool is_created() { return this->state_ == CREATED; }
40
36
  bool is_failed() { return this->state_ == FAILED; }
41
37
 
38
+ // Direct callback registration - only allocates when callback is set
39
+ void on_write(std::function<void(std::span<const uint8_t>, uint16_t)> &&callback) {
40
+ this->on_write_callback_ =
41
+ std::make_unique<std::function<void(std::span<const uint8_t>, uint16_t)>>(std::move(callback));
42
+ }
43
+
42
44
  protected:
43
45
  BLECharacteristic *characteristic_{nullptr};
44
46
  ESPBTUUID uuid_;
@@ -46,6 +48,8 @@ class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vect
46
48
 
47
49
  esp_attr_value_t value_{};
48
50
 
51
+ std::unique_ptr<std::function<void(std::span<const uint8_t>, uint16_t)>> on_write_callback_;
52
+
49
53
  esp_gatt_perm_t permissions_{};
50
54
 
51
55
  enum State : uint8_t {
@@ -70,11 +70,11 @@ void BLEServer::loop() {
70
70
  // it is at the top of the GATT table
71
71
  this->device_information_service_->do_create(this);
72
72
  // Create all services previously created
73
- for (auto &pair : this->services_) {
74
- if (pair.second == this->device_information_service_) {
73
+ for (auto &entry : this->services_) {
74
+ if (entry.service == this->device_information_service_) {
75
75
  continue;
76
76
  }
77
- pair.second->do_create(this);
77
+ entry.service->do_create(this);
78
78
  }
79
79
  this->state_ = STARTING_SERVICE;
80
80
  }
@@ -118,7 +118,7 @@ BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t n
118
118
  }
119
119
  BLEService *service = // NOLINT(cppcoreguidelines-owning-memory)
120
120
  new BLEService(uuid, num_handles, inst_id, advertise);
121
- this->services_.emplace(BLEServer::get_service_key(uuid, inst_id), service);
121
+ this->services_.push_back({uuid, inst_id, service});
122
122
  if (this->parent_->is_active() && this->registered_) {
123
123
  service->do_create(this);
124
124
  }
@@ -127,26 +127,32 @@ BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t n
127
127
 
128
128
  void BLEServer::remove_service(ESPBTUUID uuid, uint8_t inst_id) {
129
129
  ESP_LOGV(TAG, "Removing BLE service - %s %d", uuid.to_string().c_str(), inst_id);
130
- BLEService *service = this->get_service(uuid, inst_id);
131
- if (service == nullptr) {
132
- ESP_LOGW(TAG, "BLE service %s %d does not exist", uuid.to_string().c_str(), inst_id);
133
- return;
130
+ for (auto it = this->services_.begin(); it != this->services_.end(); ++it) {
131
+ if (it->uuid == uuid && it->inst_id == inst_id) {
132
+ it->service->do_delete();
133
+ delete it->service; // NOLINT(cppcoreguidelines-owning-memory)
134
+ this->services_.erase(it);
135
+ return;
136
+ }
134
137
  }
135
- service->do_delete();
136
- delete service; // NOLINT(cppcoreguidelines-owning-memory)
137
- this->services_.erase(BLEServer::get_service_key(uuid, inst_id));
138
+ ESP_LOGW(TAG, "BLE service %s %d does not exist", uuid.to_string().c_str(), inst_id);
138
139
  }
139
140
 
140
141
  BLEService *BLEServer::get_service(ESPBTUUID uuid, uint8_t inst_id) {
141
- BLEService *service = nullptr;
142
- if (this->services_.count(BLEServer::get_service_key(uuid, inst_id)) > 0) {
143
- service = this->services_.at(BLEServer::get_service_key(uuid, inst_id));
142
+ for (auto &entry : this->services_) {
143
+ if (entry.uuid == uuid && entry.inst_id == inst_id) {
144
+ return entry.service;
145
+ }
144
146
  }
145
- return service;
147
+ return nullptr;
146
148
  }
147
149
 
148
- std::string BLEServer::get_service_key(ESPBTUUID uuid, uint8_t inst_id) {
149
- return uuid.to_string() + std::to_string(inst_id);
150
+ void BLEServer::dispatch_callbacks_(CallbackType type, uint16_t conn_id) {
151
+ for (auto &entry : this->callbacks_) {
152
+ if (entry.type == type) {
153
+ entry.callback(conn_id);
154
+ }
155
+ }
150
156
  }
151
157
 
152
158
  void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
@@ -155,14 +161,14 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga
155
161
  case ESP_GATTS_CONNECT_EVT: {
156
162
  ESP_LOGD(TAG, "BLE Client connected");
157
163
  this->add_client_(param->connect.conn_id);
158
- this->emit_(BLEServerEvt::EmptyEvt::ON_CONNECT, param->connect.conn_id);
164
+ this->dispatch_callbacks_(CallbackType::ON_CONNECT, param->connect.conn_id);
159
165
  break;
160
166
  }
161
167
  case ESP_GATTS_DISCONNECT_EVT: {
162
168
  ESP_LOGD(TAG, "BLE Client disconnected");
163
169
  this->remove_client_(param->disconnect.conn_id);
164
170
  this->parent_->advertising_start();
165
- this->emit_(BLEServerEvt::EmptyEvt::ON_DISCONNECT, param->disconnect.conn_id);
171
+ this->dispatch_callbacks_(CallbackType::ON_DISCONNECT, param->disconnect.conn_id);
166
172
  break;
167
173
  }
168
174
  case ESP_GATTS_REG_EVT: {
@@ -174,17 +180,46 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga
174
180
  break;
175
181
  }
176
182
 
177
- for (const auto &pair : this->services_) {
178
- pair.second->gatts_event_handler(event, gatts_if, param);
183
+ for (auto &entry : this->services_) {
184
+ entry.service->gatts_event_handler(event, gatts_if, param);
185
+ }
186
+ }
187
+
188
+ int8_t BLEServer::find_client_index_(uint16_t conn_id) const {
189
+ for (uint8_t i = 0; i < this->client_count_; i++) {
190
+ if (this->clients_[i] == conn_id)
191
+ return i;
192
+ }
193
+ return -1;
194
+ }
195
+
196
+ void BLEServer::add_client_(uint16_t conn_id) {
197
+ // Check if already in list
198
+ if (this->find_client_index_(conn_id) >= 0)
199
+ return;
200
+ // Add if there's space
201
+ if (this->client_count_ < USE_ESP32_BLE_MAX_CONNECTIONS) {
202
+ this->clients_[this->client_count_++] = conn_id;
203
+ } else {
204
+ // This should never happen since max clients is known at compile time
205
+ ESP_LOGE(TAG, "Client array full");
206
+ }
207
+ }
208
+
209
+ void BLEServer::remove_client_(uint16_t conn_id) {
210
+ int8_t index = this->find_client_index_(conn_id);
211
+ if (index >= 0) {
212
+ // Replace with last element and decrement count (client order not preserved)
213
+ this->clients_[index] = this->clients_[--this->client_count_];
179
214
  }
180
215
  }
181
216
 
182
217
  void BLEServer::ble_before_disabled_event_handler() {
183
218
  // Delete all clients
184
- this->clients_.clear();
219
+ this->client_count_ = 0;
185
220
  // Delete all services
186
- for (auto &pair : this->services_) {
187
- pair.second->do_delete();
221
+ for (auto &entry : this->services_) {
222
+ entry.service->do_delete();
188
223
  }
189
224
  this->registered_ = false;
190
225
  this->state_ = INIT;
@@ -12,7 +12,7 @@
12
12
  #include <memory>
13
13
  #include <vector>
14
14
  #include <unordered_map>
15
- #include <unordered_set>
15
+ #include <functional>
16
16
 
17
17
  #ifdef USE_ESP32
18
18
 
@@ -24,18 +24,7 @@ namespace esp32_ble_server {
24
24
  using namespace esp32_ble;
25
25
  using namespace bytebuffer;
26
26
 
27
- namespace BLEServerEvt {
28
- enum EmptyEvt {
29
- ON_CONNECT,
30
- ON_DISCONNECT,
31
- };
32
- } // namespace BLEServerEvt
33
-
34
- class BLEServer : public Component,
35
- public GATTsEventHandler,
36
- public BLEStatusEventHandler,
37
- public Parented<ESP32BLE>,
38
- public EventEmitter<BLEServerEvt::EmptyEvt, uint16_t> {
27
+ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEventHandler, public Parented<ESP32BLE> {
39
28
  public:
40
29
  void setup() override;
41
30
  void loop() override;
@@ -57,27 +46,56 @@ class BLEServer : public Component,
57
46
  void set_device_information_service(BLEService *service) { this->device_information_service_ = service; }
58
47
 
59
48
  esp_gatt_if_t get_gatts_if() { return this->gatts_if_; }
60
- uint32_t get_connected_client_count() { return this->clients_.size(); }
61
- const std::unordered_set<uint16_t> &get_clients() { return this->clients_; }
49
+ uint32_t get_connected_client_count() { return this->client_count_; }
50
+ const uint16_t *get_clients() const { return this->clients_; }
51
+ uint8_t get_client_count() const { return this->client_count_; }
62
52
 
63
53
  void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
64
54
  esp_ble_gatts_cb_param_t *param) override;
65
55
 
66
56
  void ble_before_disabled_event_handler() override;
67
57
 
58
+ // Direct callback registration - supports multiple callbacks
59
+ void on_connect(std::function<void(uint16_t)> &&callback) {
60
+ this->callbacks_.push_back({CallbackType::ON_CONNECT, std::move(callback)});
61
+ }
62
+ void on_disconnect(std::function<void(uint16_t)> &&callback) {
63
+ this->callbacks_.push_back({CallbackType::ON_DISCONNECT, std::move(callback)});
64
+ }
65
+
68
66
  protected:
69
- static std::string get_service_key(ESPBTUUID uuid, uint8_t inst_id);
67
+ enum class CallbackType : uint8_t {
68
+ ON_CONNECT,
69
+ ON_DISCONNECT,
70
+ };
71
+
72
+ struct CallbackEntry {
73
+ CallbackType type;
74
+ std::function<void(uint16_t)> callback;
75
+ };
76
+
77
+ struct ServiceEntry {
78
+ ESPBTUUID uuid;
79
+ uint8_t inst_id;
80
+ BLEService *service;
81
+ };
82
+
70
83
  void restart_advertising_();
71
84
 
72
- void add_client_(uint16_t conn_id) { this->clients_.insert(conn_id); }
73
- void remove_client_(uint16_t conn_id) { this->clients_.erase(conn_id); }
85
+ int8_t find_client_index_(uint16_t conn_id) const;
86
+ void add_client_(uint16_t conn_id);
87
+ void remove_client_(uint16_t conn_id);
88
+ void dispatch_callbacks_(CallbackType type, uint16_t conn_id);
89
+
90
+ std::vector<CallbackEntry> callbacks_;
74
91
 
75
92
  std::vector<uint8_t> manufacturer_data_{};
76
93
  esp_gatt_if_t gatts_if_{0};
77
94
  bool registered_{false};
78
95
 
79
- std::unordered_set<uint16_t> clients_;
80
- std::unordered_map<std::string, BLEService *> services_{};
96
+ uint16_t clients_[USE_ESP32_BLE_MAX_CONNECTIONS]{};
97
+ uint8_t client_count_{0};
98
+ std::vector<ServiceEntry> services_{};
81
99
  std::vector<BLEService *> services_to_start_{};
82
100
  BLEService *device_information_service_{};
83
101
 
@@ -9,66 +9,82 @@ namespace esp32_ble_server_automations {
9
9
 
10
10
  using namespace esp32_ble;
11
11
 
12
+ #ifdef USE_ESP32_BLE_SERVER_CHARACTERISTIC_ON_WRITE
12
13
  Trigger<std::vector<uint8_t>, uint16_t> *BLETriggers::create_characteristic_on_write_trigger(
13
14
  BLECharacteristic *characteristic) {
14
15
  Trigger<std::vector<uint8_t>, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory)
15
16
  new Trigger<std::vector<uint8_t>, uint16_t>();
16
- characteristic->EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>::on(
17
- BLECharacteristicEvt::VectorEvt::ON_WRITE,
18
- [on_write_trigger](const std::vector<uint8_t> &data, uint16_t id) { on_write_trigger->trigger(data, id); });
17
+ characteristic->on_write([on_write_trigger](std::span<const uint8_t> data, uint16_t id) {
18
+ // Convert span to vector for trigger
19
+ on_write_trigger->trigger(std::vector<uint8_t>(data.begin(), data.end()), id);
20
+ });
19
21
  return on_write_trigger;
20
22
  }
23
+ #endif
21
24
 
25
+ #ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_ON_WRITE
22
26
  Trigger<std::vector<uint8_t>, uint16_t> *BLETriggers::create_descriptor_on_write_trigger(BLEDescriptor *descriptor) {
23
27
  Trigger<std::vector<uint8_t>, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory)
24
28
  new Trigger<std::vector<uint8_t>, uint16_t>();
25
- descriptor->on(
26
- BLEDescriptorEvt::VectorEvt::ON_WRITE,
27
- [on_write_trigger](const std::vector<uint8_t> &data, uint16_t id) { on_write_trigger->trigger(data, id); });
29
+ descriptor->on_write([on_write_trigger](std::span<const uint8_t> data, uint16_t id) {
30
+ // Convert span to vector for trigger
31
+ on_write_trigger->trigger(std::vector<uint8_t>(data.begin(), data.end()), id);
32
+ });
28
33
  return on_write_trigger;
29
34
  }
35
+ #endif
30
36
 
37
+ #ifdef USE_ESP32_BLE_SERVER_ON_CONNECT
31
38
  Trigger<uint16_t> *BLETriggers::create_server_on_connect_trigger(BLEServer *server) {
32
39
  Trigger<uint16_t> *on_connect_trigger = new Trigger<uint16_t>(); // NOLINT(cppcoreguidelines-owning-memory)
33
- server->on(BLEServerEvt::EmptyEvt::ON_CONNECT,
34
- [on_connect_trigger](uint16_t conn_id) { on_connect_trigger->trigger(conn_id); });
40
+ server->on_connect([on_connect_trigger](uint16_t conn_id) { on_connect_trigger->trigger(conn_id); });
35
41
  return on_connect_trigger;
36
42
  }
43
+ #endif
37
44
 
45
+ #ifdef USE_ESP32_BLE_SERVER_ON_DISCONNECT
38
46
  Trigger<uint16_t> *BLETriggers::create_server_on_disconnect_trigger(BLEServer *server) {
39
47
  Trigger<uint16_t> *on_disconnect_trigger = new Trigger<uint16_t>(); // NOLINT(cppcoreguidelines-owning-memory)
40
- server->on(BLEServerEvt::EmptyEvt::ON_DISCONNECT,
41
- [on_disconnect_trigger](uint16_t conn_id) { on_disconnect_trigger->trigger(conn_id); });
48
+ server->on_disconnect([on_disconnect_trigger](uint16_t conn_id) { on_disconnect_trigger->trigger(conn_id); });
42
49
  return on_disconnect_trigger;
43
50
  }
51
+ #endif
44
52
 
53
+ #ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
45
54
  void BLECharacteristicSetValueActionManager::set_listener(BLECharacteristic *characteristic,
46
- EventEmitterListenerID listener_id,
47
55
  const std::function<void()> &pre_notify_listener) {
48
- // Check if there is already a listener for this characteristic
49
- if (this->listeners_.count(characteristic) > 0) {
50
- // Unpack the pair listener_id, pre_notify_listener_id
51
- auto listener_pairs = this->listeners_[characteristic];
52
- EventEmitterListenerID old_listener_id = listener_pairs.first;
53
- EventEmitterListenerID old_pre_notify_listener_id = listener_pairs.second;
54
- // Remove the previous listener
55
- characteristic->EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t>::off(BLECharacteristicEvt::EmptyEvt::ON_READ,
56
- old_listener_id);
57
- // Remove the pre-notify listener
58
- this->off(BLECharacteristicSetValueActionEvt::PRE_NOTIFY, old_pre_notify_listener_id);
56
+ // Find and remove existing listener for this characteristic
57
+ auto *existing = this->find_listener_(characteristic);
58
+ if (existing != nullptr) {
59
+ // Remove from vector
60
+ this->remove_listener_(characteristic);
61
+ }
62
+ // Save the entry to the vector
63
+ this->listeners_.push_back({characteristic, pre_notify_listener});
64
+ }
65
+
66
+ BLECharacteristicSetValueActionManager::ListenerEntry *BLECharacteristicSetValueActionManager::find_listener_(
67
+ BLECharacteristic *characteristic) {
68
+ for (auto &entry : this->listeners_) {
69
+ if (entry.characteristic == characteristic) {
70
+ return &entry;
71
+ }
72
+ }
73
+ return nullptr;
74
+ }
75
+
76
+ void BLECharacteristicSetValueActionManager::remove_listener_(BLECharacteristic *characteristic) {
77
+ // Since we typically have very few listeners, optimize by swapping with back and popping
78
+ for (size_t i = 0; i < this->listeners_.size(); i++) {
79
+ if (this->listeners_[i].characteristic == characteristic) {
80
+ // Swap with last element and pop (safe even when i is the last element)
81
+ this->listeners_[i] = this->listeners_.back();
82
+ this->listeners_.pop_back();
83
+ return;
84
+ }
59
85
  }
60
- // Create a new listener for the pre-notify event
61
- EventEmitterListenerID pre_notify_listener_id =
62
- this->on(BLECharacteristicSetValueActionEvt::PRE_NOTIFY,
63
- [pre_notify_listener, characteristic](const BLECharacteristic *evt_characteristic) {
64
- // Only call the pre-notify listener if the characteristic is the one we are interested in
65
- if (characteristic == evt_characteristic) {
66
- pre_notify_listener();
67
- }
68
- });
69
- // Save the pair listener_id, pre_notify_listener_id to the map
70
- this->listeners_[characteristic] = std::make_pair(listener_id, pre_notify_listener_id);
71
86
  }
87
+ #endif
72
88
 
73
89
  } // namespace esp32_ble_server_automations
74
90
  } // namespace esp32_ble_server
@@ -4,11 +4,9 @@
4
4
  #include "ble_characteristic.h"
5
5
  #include "ble_descriptor.h"
6
6
 
7
- #include "esphome/components/event_emitter/event_emitter.h"
8
7
  #include "esphome/core/automation.h"
9
8
 
10
9
  #include <vector>
11
- #include <unordered_map>
12
10
  #include <functional>
13
11
 
14
12
  #ifdef USE_ESP32
@@ -19,41 +17,53 @@ namespace esp32_ble_server {
19
17
  namespace esp32_ble_server_automations {
20
18
 
21
19
  using namespace esp32_ble;
22
- using namespace event_emitter;
23
20
 
24
21
  class BLETriggers {
25
22
  public:
23
+ #ifdef USE_ESP32_BLE_SERVER_CHARACTERISTIC_ON_WRITE
26
24
  static Trigger<std::vector<uint8_t>, uint16_t> *create_characteristic_on_write_trigger(
27
25
  BLECharacteristic *characteristic);
26
+ #endif
27
+ #ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_ON_WRITE
28
28
  static Trigger<std::vector<uint8_t>, uint16_t> *create_descriptor_on_write_trigger(BLEDescriptor *descriptor);
29
+ #endif
30
+ #ifdef USE_ESP32_BLE_SERVER_ON_CONNECT
29
31
  static Trigger<uint16_t> *create_server_on_connect_trigger(BLEServer *server);
32
+ #endif
33
+ #ifdef USE_ESP32_BLE_SERVER_ON_DISCONNECT
30
34
  static Trigger<uint16_t> *create_server_on_disconnect_trigger(BLEServer *server);
35
+ #endif
31
36
  };
32
37
 
33
- enum BLECharacteristicSetValueActionEvt {
34
- PRE_NOTIFY,
35
- };
36
-
38
+ #ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
37
39
  // Class to make sure only one BLECharacteristicSetValueAction is active at a time for each characteristic
38
- class BLECharacteristicSetValueActionManager
39
- : public EventEmitter<BLECharacteristicSetValueActionEvt, BLECharacteristic *> {
40
+ class BLECharacteristicSetValueActionManager {
40
41
  public:
41
42
  // Singleton pattern
42
43
  static BLECharacteristicSetValueActionManager *get_instance() {
43
44
  static BLECharacteristicSetValueActionManager instance;
44
45
  return &instance;
45
46
  }
46
- void set_listener(BLECharacteristic *characteristic, EventEmitterListenerID listener_id,
47
- const std::function<void()> &pre_notify_listener);
48
- EventEmitterListenerID get_listener(BLECharacteristic *characteristic) {
49
- return this->listeners_[characteristic].first;
50
- }
47
+ void set_listener(BLECharacteristic *characteristic, const std::function<void()> &pre_notify_listener);
48
+ bool has_listener(BLECharacteristic *characteristic) { return this->find_listener_(characteristic) != nullptr; }
51
49
  void emit_pre_notify(BLECharacteristic *characteristic) {
52
- this->emit_(BLECharacteristicSetValueActionEvt::PRE_NOTIFY, characteristic);
50
+ for (const auto &entry : this->listeners_) {
51
+ if (entry.characteristic == characteristic) {
52
+ entry.pre_notify_listener();
53
+ break;
54
+ }
55
+ }
53
56
  }
54
57
 
55
58
  private:
56
- std::unordered_map<BLECharacteristic *, std::pair<EventEmitterListenerID, EventEmitterListenerID>> listeners_;
59
+ struct ListenerEntry {
60
+ BLECharacteristic *characteristic;
61
+ std::function<void()> pre_notify_listener;
62
+ };
63
+ std::vector<ListenerEntry> listeners_;
64
+
65
+ ListenerEntry *find_listener_(BLECharacteristic *characteristic);
66
+ void remove_listener_(BLECharacteristic *characteristic);
57
67
  };
58
68
 
59
69
  template<typename... Ts> class BLECharacteristicSetValueAction : public Action<Ts...> {
@@ -63,32 +73,34 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
63
73
  void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); }
64
74
  void play(Ts... x) override {
65
75
  // If the listener is already set, do nothing
66
- if (BLECharacteristicSetValueActionManager::get_instance()->get_listener(this->parent_) == this->listener_id_)
76
+ if (BLECharacteristicSetValueActionManager::get_instance()->has_listener(this->parent_))
67
77
  return;
68
78
  // Set initial value
69
79
  this->parent_->set_value(this->buffer_.value(x...));
70
80
  // Set the listener for read events
71
- this->listener_id_ = this->parent_->EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t>::on(
72
- BLECharacteristicEvt::EmptyEvt::ON_READ, [this, x...](uint16_t id) {
73
- // Set the value of the characteristic every time it is read
74
- this->parent_->set_value(this->buffer_.value(x...));
75
- });
81
+ this->parent_->on_read([this, x...](uint16_t id) {
82
+ // Set the value of the characteristic every time it is read
83
+ this->parent_->set_value(this->buffer_.value(x...));
84
+ });
76
85
  // Set the listener in the global manager so only one BLECharacteristicSetValueAction is set for each characteristic
77
86
  BLECharacteristicSetValueActionManager::get_instance()->set_listener(
78
- this->parent_, this->listener_id_, [this, x...]() { this->parent_->set_value(this->buffer_.value(x...)); });
87
+ this->parent_, [this, x...]() { this->parent_->set_value(this->buffer_.value(x...)); });
79
88
  }
80
89
 
81
90
  protected:
82
91
  BLECharacteristic *parent_;
83
- EventEmitterListenerID listener_id_;
84
92
  };
93
+ #endif // USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
85
94
 
95
+ #ifdef USE_ESP32_BLE_SERVER_NOTIFY_ACTION
86
96
  template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts...> {
87
97
  public:
88
98
  BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
89
99
  void play(Ts... x) override {
100
+ #ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
90
101
  // Call the pre-notify event
91
102
  BLECharacteristicSetValueActionManager::get_instance()->emit_pre_notify(this->parent_);
103
+ #endif
92
104
  // Notify the characteristic
93
105
  this->parent_->notify();
94
106
  }
@@ -96,7 +108,9 @@ template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts.
96
108
  protected:
97
109
  BLECharacteristic *parent_;
98
110
  };
111
+ #endif // USE_ESP32_BLE_SERVER_NOTIFY_ACTION
99
112
 
113
+ #ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
100
114
  template<typename... Ts> class BLEDescriptorSetValueAction : public Action<Ts...> {
101
115
  public:
102
116
  BLEDescriptorSetValueAction(BLEDescriptor *descriptor) : parent_(descriptor) {}
@@ -107,6 +121,7 @@ template<typename... Ts> class BLEDescriptorSetValueAction : public Action<Ts...
107
121
  protected:
108
122
  BLEDescriptor *parent_;
109
123
  };
124
+ #endif // USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
110
125
 
111
126
  } // namespace esp32_ble_server_automations
112
127
  } // namespace esp32_ble_server