esphome 2024.12.4__py3-none-any.whl → 2025.2.0b2__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 (358) hide show
  1. esphome/__main__.py +16 -3
  2. esphome/components/adc/__init__.py +17 -11
  3. esphome/components/adc/adc_sensor.h +17 -0
  4. esphome/components/adc/adc_sensor_common.cpp +55 -0
  5. esphome/components/adc/adc_sensor_esp32.cpp +8 -5
  6. esphome/components/adc/adc_sensor_esp8266.cpp +10 -6
  7. esphome/components/adc/adc_sensor_libretiny.cpp +11 -6
  8. esphome/components/adc/adc_sensor_rp2040.cpp +13 -10
  9. esphome/components/adc/sensor.py +9 -3
  10. esphome/components/ads1115/ads1115.cpp +56 -7
  11. esphome/components/ads1115/ads1115.h +13 -1
  12. esphome/components/ads1115/sensor/__init__.py +16 -0
  13. esphome/components/ads1115/sensor/ads1115_sensor.cpp +2 -1
  14. esphome/components/ads1115/sensor/ads1115_sensor.h +2 -0
  15. esphome/components/animation/__init__.py +23 -261
  16. esphome/components/animation/animation.cpp +2 -2
  17. esphome/components/animation/animation.h +2 -1
  18. esphome/components/api/api_pb2.cpp +14 -0
  19. esphome/components/api/api_pb2.h +1 -0
  20. esphome/components/audio/__init__.py +112 -0
  21. esphome/components/audio/audio.cpp +67 -0
  22. esphome/components/audio/audio.h +125 -7
  23. esphome/components/audio/audio_decoder.cpp +361 -0
  24. esphome/components/audio/audio_decoder.h +135 -0
  25. esphome/components/audio/audio_reader.cpp +308 -0
  26. esphome/components/audio/audio_reader.h +85 -0
  27. esphome/components/audio/audio_resampler.cpp +159 -0
  28. esphome/components/audio/audio_resampler.h +101 -0
  29. esphome/components/audio/audio_transfer_buffer.cpp +165 -0
  30. esphome/components/audio/audio_transfer_buffer.h +139 -0
  31. esphome/components/audio_adc/__init__.py +41 -0
  32. esphome/components/audio_adc/audio_adc.h +17 -0
  33. esphome/components/audio_adc/automation.h +23 -0
  34. esphome/components/bk72xx/__init__.py +1 -0
  35. esphome/components/ble_client/ble_client.cpp +1 -2
  36. esphome/components/ble_client/sensor/__init__.py +1 -1
  37. esphome/components/ble_client/text_sensor/__init__.py +1 -1
  38. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -0
  39. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -0
  40. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
  41. esphome/components/ch422g/ch422g.h +2 -0
  42. esphome/components/climate/__init__.py +1 -1
  43. esphome/components/climate_ir/climate_ir.cpp +2 -1
  44. esphome/components/coolix/coolix.cpp +2 -1
  45. esphome/components/cse7766/cse7766.cpp +8 -16
  46. esphome/components/custom/__init__.py +0 -3
  47. esphome/components/custom/binary_sensor/__init__.py +2 -28
  48. esphome/components/custom/climate/__init__.py +2 -27
  49. esphome/components/custom/cover/__init__.py +2 -27
  50. esphome/components/custom/light/__init__.py +2 -27
  51. esphome/components/custom/output/__init__.py +2 -58
  52. esphome/components/custom/sensor/__init__.py +2 -24
  53. esphome/components/custom/switch/__init__.py +2 -24
  54. esphome/components/custom/text_sensor/__init__.py +2 -29
  55. esphome/components/custom_component/__init__.py +3 -27
  56. esphome/components/daly_bms/daly_bms.cpp +6 -0
  57. esphome/components/daly_bms/daly_bms.h +2 -0
  58. esphome/components/daly_bms/sensor.py +6 -0
  59. esphome/components/debug/debug_component.cpp +4 -0
  60. esphome/components/debug/debug_component.h +14 -0
  61. esphome/components/debug/debug_esp32.cpp +154 -74
  62. esphome/components/dfplayer/dfplayer.cpp +15 -2
  63. esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +2 -1
  64. esphome/components/dht/dht.cpp +2 -1
  65. esphome/components/display/__init__.py +18 -5
  66. esphome/components/display/display.cpp +2 -1
  67. esphome/components/display/rect.cpp +2 -1
  68. esphome/components/es7210/__init__.py +0 -0
  69. esphome/components/es7210/audio_adc.py +51 -0
  70. esphome/components/es7210/es7210.cpp +228 -0
  71. esphome/components/es7210/es7210.h +62 -0
  72. esphome/components/es7210/es7210_const.h +129 -0
  73. esphome/components/es7243e/__init__.py +0 -0
  74. esphome/components/es7243e/audio_adc.py +34 -0
  75. esphome/components/es7243e/es7243e.cpp +125 -0
  76. esphome/components/es7243e/es7243e.h +37 -0
  77. esphome/components/es7243e/es7243e_const.h +54 -0
  78. esphome/components/es8156/__init__.py +0 -0
  79. esphome/components/es8156/audio_dac.py +27 -0
  80. esphome/components/es8156/es8156.cpp +87 -0
  81. esphome/components/es8156/es8156.h +51 -0
  82. esphome/components/es8156/es8156_const.h +68 -0
  83. esphome/components/es8311/audio_dac.py +1 -2
  84. esphome/components/esp32/__init__.py +1 -0
  85. esphome/components/esp32/core.cpp +5 -1
  86. esphome/components/esp32/gpio.h +2 -0
  87. esphome/components/esp32_ble/__init__.py +39 -0
  88. esphome/components/esp32_ble/queue.h +4 -4
  89. esphome/components/esp32_ble_client/ble_client_base.cpp +46 -0
  90. esphome/components/esp32_ble_client/ble_client_base.h +2 -0
  91. esphome/components/esp32_ble_server/__init__.py +582 -12
  92. esphome/components/esp32_ble_server/ble_characteristic.cpp +48 -60
  93. esphome/components/esp32_ble_server/ble_characteristic.h +24 -17
  94. esphome/components/esp32_ble_server/ble_descriptor.cpp +21 -9
  95. esphome/components/esp32_ble_server/ble_descriptor.h +17 -6
  96. esphome/components/esp32_ble_server/ble_server.cpp +62 -67
  97. esphome/components/esp32_ble_server/ble_server.h +28 -32
  98. esphome/components/esp32_ble_server/ble_server_automations.cpp +77 -0
  99. esphome/components/esp32_ble_server/ble_server_automations.h +115 -0
  100. esphome/components/esp32_ble_server/ble_service.cpp +17 -15
  101. esphome/components/esp32_ble_server/ble_service.h +10 -14
  102. esphome/components/esp32_ble_tracker/__init__.py +6 -39
  103. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +33 -10
  104. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +8 -4
  105. esphome/components/esp32_improv/__init__.py +2 -8
  106. esphome/components/esp32_improv/esp32_improv_component.cpp +21 -20
  107. esphome/components/esp32_improv/esp32_improv_component.h +3 -4
  108. esphome/components/esp32_rmt/__init__.py +28 -3
  109. esphome/components/esp32_rmt_led_strip/led_strip.cpp +73 -6
  110. esphome/components/esp32_rmt_led_strip/led_strip.h +21 -3
  111. esphome/components/esp32_rmt_led_strip/light.py +72 -7
  112. esphome/components/esp32_touch/esp32_touch.cpp +5 -0
  113. esphome/components/esp8266/__init__.py +1 -0
  114. esphome/components/esp8266/gpio.h +1 -0
  115. esphome/components/ethernet/__init__.py +10 -10
  116. esphome/components/event/event.cpp +4 -2
  117. esphome/components/event/event.h +2 -0
  118. esphome/components/event_emitter/__init__.py +5 -0
  119. esphome/components/event_emitter/event_emitter.cpp +14 -0
  120. esphome/components/event_emitter/event_emitter.h +63 -0
  121. esphome/components/gcja5/gcja5.cpp +2 -1
  122. esphome/components/graph/graph.cpp +4 -9
  123. esphome/components/haier/haier_base.cpp +2 -1
  124. esphome/components/haier/hon_climate.cpp +2 -1
  125. esphome/components/heatpumpir/heatpumpir.cpp +2 -1
  126. esphome/components/host/__init__.py +1 -0
  127. esphome/components/host/gpio.h +1 -0
  128. esphome/components/http_request/http_request.h +2 -2
  129. esphome/components/http_request/http_request_arduino.cpp +1 -1
  130. esphome/components/http_request/http_request_idf.cpp +1 -1
  131. esphome/components/i2c/i2c_bus_esp_idf.cpp +4 -0
  132. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +7 -5
  133. esphome/components/i2s_audio/speaker/__init__.py +53 -6
  134. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +92 -46
  135. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -0
  136. esphome/components/ili9xxx/display.py +29 -11
  137. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -5
  138. esphome/components/ili9xxx/ili9xxx_display.h +2 -1
  139. esphome/components/image/__init__.py +443 -255
  140. esphome/components/image/image.cpp +115 -61
  141. esphome/components/image/image.h +15 -24
  142. esphome/components/json/json_util.cpp +8 -34
  143. esphome/components/libretiny/__init__.py +1 -0
  144. esphome/components/libretiny/gpio_arduino.h +1 -0
  145. esphome/components/light/light_color_values.h +1 -1
  146. esphome/components/logger/__init__.py +43 -7
  147. esphome/components/logger/logger.cpp +16 -11
  148. esphome/components/logger/logger.h +11 -7
  149. esphome/components/logger/select/__init__.py +29 -0
  150. esphome/components/logger/select/logger_level_select.cpp +27 -0
  151. esphome/components/logger/select/logger_level_select.h +15 -0
  152. esphome/components/lvgl/__init__.py +96 -73
  153. esphome/components/lvgl/automation.py +39 -7
  154. esphome/components/lvgl/defines.py +8 -2
  155. esphome/components/lvgl/lvgl_esphome.cpp +8 -15
  156. esphome/components/lvgl/lvgl_esphome.h +20 -5
  157. esphome/components/lvgl/schemas.py +25 -14
  158. esphome/components/lvgl/trigger.py +27 -3
  159. esphome/components/lvgl/widgets/dropdown.py +1 -1
  160. esphome/components/lvgl/widgets/keyboard.py +8 -1
  161. esphome/components/lvgl/widgets/meter.py +2 -1
  162. esphome/components/lvgl/widgets/msgbox.py +1 -1
  163. esphome/components/lvgl/widgets/obj.py +1 -12
  164. esphome/components/lvgl/widgets/page.py +37 -2
  165. esphome/components/lvgl/widgets/tabview.py +1 -1
  166. esphome/components/max6956/max6956.h +2 -0
  167. esphome/components/mcp23016/mcp23016.h +2 -0
  168. esphome/components/mcp23xxx_base/mcp23xxx_base.h +2 -0
  169. esphome/components/mdns/__init__.py +1 -1
  170. esphome/components/media_player/__init__.py +37 -8
  171. esphome/components/media_player/automation.h +11 -2
  172. esphome/components/media_player/media_player.cpp +8 -0
  173. esphome/components/media_player/media_player.h +8 -4
  174. esphome/components/micronova/switch/micronova_switch.cpp +4 -2
  175. esphome/components/midea/ac_automations.h +3 -1
  176. esphome/components/midea/air_conditioner.cpp +7 -5
  177. esphome/components/midea/air_conditioner.h +1 -1
  178. esphome/components/midea/climate.py +4 -2
  179. esphome/components/midea/ir_transmitter.h +36 -5
  180. esphome/components/mixer/__init__.py +0 -0
  181. esphome/components/mixer/speaker/__init__.py +172 -0
  182. esphome/components/mixer/speaker/automation.h +19 -0
  183. esphome/components/mixer/speaker/mixer_speaker.cpp +624 -0
  184. esphome/components/mixer/speaker/mixer_speaker.h +207 -0
  185. esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +7 -13
  186. esphome/components/mpr121/mpr121.h +2 -0
  187. esphome/components/mqtt/__init__.py +1 -1
  188. esphome/components/mqtt/mqtt_client.cpp +7 -1
  189. esphome/components/mqtt/mqtt_client.h +1 -1
  190. esphome/components/mqtt/mqtt_climate.cpp +2 -2
  191. esphome/components/network/ip_address.h +2 -0
  192. esphome/components/nextion/automation.h +17 -0
  193. esphome/components/nextion/display.py +42 -17
  194. esphome/components/nextion/nextion.cpp +4 -10
  195. esphome/components/nextion/nextion.h +89 -82
  196. esphome/components/nextion/nextion_commands.cpp +10 -10
  197. esphome/components/ntc/sensor.py +2 -4
  198. esphome/components/online_image/__init__.py +98 -46
  199. esphome/components/online_image/bmp_image.cpp +101 -0
  200. esphome/components/online_image/bmp_image.h +40 -0
  201. esphome/components/online_image/image_decoder.cpp +28 -2
  202. esphome/components/online_image/image_decoder.h +24 -15
  203. esphome/components/online_image/jpeg_image.cpp +90 -0
  204. esphome/components/online_image/jpeg_image.h +34 -0
  205. esphome/components/online_image/online_image.cpp +112 -53
  206. esphome/components/online_image/online_image.h +24 -7
  207. esphome/components/online_image/png_image.cpp +7 -3
  208. esphome/components/online_image/png_image.h +2 -1
  209. esphome/components/opentherm/__init__.py +73 -7
  210. esphome/components/opentherm/automation.h +25 -0
  211. esphome/components/opentherm/const.py +1 -0
  212. esphome/components/opentherm/generate.py +39 -6
  213. esphome/components/opentherm/hub.cpp +117 -79
  214. esphome/components/opentherm/hub.h +31 -15
  215. esphome/components/opentherm/opentherm.cpp +47 -23
  216. esphome/components/opentherm/opentherm.h +27 -6
  217. esphome/components/opentherm/opentherm_macros.h +11 -0
  218. esphome/components/opentherm/schema.py +78 -1
  219. esphome/components/opentherm/validate.py +7 -2
  220. esphome/components/pca6416a/pca6416a.h +2 -0
  221. esphome/components/pca9554/pca9554.h +2 -0
  222. esphome/components/pcf8574/pcf8574.h +2 -0
  223. esphome/components/preferences/__init__.py +2 -4
  224. esphome/components/preferences/syncer.h +10 -3
  225. esphome/components/prometheus/prometheus_handler.cpp +313 -0
  226. esphome/components/prometheus/prometheus_handler.h +48 -7
  227. esphome/components/psram/psram.cpp +8 -1
  228. esphome/components/pulse_counter/pulse_counter_sensor.cpp +14 -9
  229. esphome/components/pulse_counter/pulse_counter_sensor.h +4 -4
  230. esphome/components/pulse_meter/pulse_meter_sensor.cpp +2 -0
  231. esphome/components/qspi_dbi/__init__.py +3 -0
  232. esphome/components/qspi_dbi/display.py +74 -47
  233. esphome/components/qspi_dbi/models.py +245 -2
  234. esphome/components/qspi_dbi/qspi_dbi.cpp +9 -16
  235. esphome/components/qspi_dbi/qspi_dbi.h +2 -2
  236. esphome/components/remote_base/__init__.py +77 -25
  237. esphome/components/remote_base/remote_base.cpp +1 -1
  238. esphome/components/remote_base/remote_base.h +20 -2
  239. esphome/components/remote_base/toto_protocol.cpp +100 -0
  240. esphome/components/remote_base/toto_protocol.h +45 -0
  241. esphome/components/remote_receiver/__init__.py +55 -10
  242. esphome/components/remote_receiver/remote_receiver.h +36 -3
  243. esphome/components/remote_receiver/remote_receiver_esp32.cpp +145 -6
  244. esphome/components/remote_transmitter/__init__.py +62 -4
  245. esphome/components/remote_transmitter/remote_transmitter.h +21 -2
  246. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +140 -4
  247. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +3 -3
  248. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +3 -3
  249. esphome/components/resampler/__init__.py +0 -0
  250. esphome/components/resampler/speaker/__init__.py +103 -0
  251. esphome/components/resampler/speaker/resampler_speaker.cpp +318 -0
  252. esphome/components/resampler/speaker/resampler_speaker.h +107 -0
  253. esphome/components/resistance/resistance_sensor.h +2 -3
  254. esphome/components/resistance/sensor.py +2 -9
  255. esphome/components/rotary_encoder/rotary_encoder.cpp +8 -4
  256. esphome/components/rp2040/__init__.py +1 -0
  257. esphome/components/rp2040/gpio.h +1 -0
  258. esphome/components/rtl87xx/__init__.py +2 -0
  259. esphome/components/sdl/binary_sensor.py +270 -0
  260. esphome/components/sdl/sdl_esphome.cpp +16 -0
  261. esphome/components/sdl/sdl_esphome.h +9 -0
  262. esphome/components/seeed_mr60bha2/binary_sensor.py +25 -0
  263. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +26 -2
  264. esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +9 -20
  265. esphome/components/seeed_mr60bha2/sensor.py +9 -1
  266. esphome/components/sn74hc165/sn74hc165.h +3 -0
  267. esphome/components/sn74hc595/sn74hc595.h +3 -0
  268. esphome/components/speaker/__init__.py +5 -4
  269. esphome/components/speaker/media_player/__init__.py +458 -0
  270. esphome/components/speaker/media_player/audio_pipeline.cpp +568 -0
  271. esphome/components/speaker/media_player/audio_pipeline.h +159 -0
  272. esphome/components/speaker/media_player/automation.h +26 -0
  273. esphome/components/speaker/media_player/speaker_media_player.cpp +577 -0
  274. esphome/components/speaker/media_player/speaker_media_player.h +160 -0
  275. esphome/components/speaker/speaker.h +20 -0
  276. esphome/components/spi/__init__.py +1 -5
  277. esphome/components/spi/spi.cpp +7 -1
  278. esphome/components/spi/spi.h +21 -2
  279. esphome/components/spi_led_strip/light.py +3 -5
  280. esphome/components/spi_led_strip/spi_led_strip.cpp +67 -0
  281. esphome/components/spi_led_strip/spi_led_strip.h +8 -60
  282. esphome/components/sprinkler/sprinkler.cpp +3 -1
  283. esphome/components/sx1509/sx1509_gpio_pin.h +2 -0
  284. esphome/components/tca9555/tca9555.h +2 -0
  285. esphome/components/toshiba/toshiba.cpp +2 -1
  286. esphome/components/tuya/light/tuya_light.cpp +4 -2
  287. esphome/components/uart/uart_component_esp32_arduino.cpp +2 -2
  288. esphome/components/uart/uart_component_esp_idf.cpp +2 -2
  289. esphome/components/udp/__init__.py +8 -2
  290. esphome/components/udp/udp_component.cpp +25 -56
  291. esphome/components/udp/udp_component.h +3 -0
  292. esphome/components/uponor_smatrix/sensor/__init__.py +14 -4
  293. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +5 -0
  294. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.h +1 -0
  295. esphome/components/uptime/text_sensor/__init__.py +19 -0
  296. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +63 -0
  297. esphome/components/uptime/text_sensor/uptime_text_sensor.h +25 -0
  298. esphome/components/voice_assistant/voice_assistant.cpp +24 -14
  299. esphome/components/voice_assistant/voice_assistant.h +8 -0
  300. esphome/components/waveshare_epaper/display.py +22 -1
  301. esphome/components/waveshare_epaper/waveshare_213v3.cpp +9 -3
  302. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1155 -44
  303. esphome/components/waveshare_epaper/waveshare_epaper.h +208 -7
  304. esphome/components/web_server/web_server.cpp +28 -6
  305. esphome/components/weikai/weikai.h +2 -0
  306. esphome/components/wifi/__init__.py +6 -6
  307. esphome/components/wifi/wifi_component.cpp +1 -1
  308. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -1
  309. esphome/components/wireguard/__init__.py +2 -2
  310. esphome/components/xl9535/xl9535.h +2 -0
  311. esphome/components/xxtea/__init__.py +3 -0
  312. esphome/components/xxtea/xxtea.cpp +46 -0
  313. esphome/components/xxtea/xxtea.h +26 -0
  314. esphome/components/yashima/yashima.cpp +2 -1
  315. esphome/config.py +9 -5
  316. esphome/config_validation.py +55 -17
  317. esphome/const.py +7 -10
  318. esphome/core/__init__.py +6 -13
  319. esphome/core/base_automation.h +1 -0
  320. esphome/core/config.py +59 -72
  321. esphome/core/defines.h +9 -1
  322. esphome/core/gpio.h +7 -0
  323. esphome/core/helpers.cpp +19 -15
  324. esphome/core/helpers.h +57 -8
  325. esphome/core/log.h +9 -7
  326. esphome/cpp_generator.py +2 -2
  327. esphome/espota2.py +3 -2
  328. esphome/loader.py +12 -4
  329. esphome/log.py +5 -7
  330. esphome/yaml_util.py +2 -2
  331. {esphome-2024.12.4.dist-info → esphome-2025.2.0b2.dist-info}/METADATA +12 -7
  332. {esphome-2024.12.4.dist-info → esphome-2025.2.0b2.dist-info}/RECORD +341 -292
  333. esphome/components/custom/binary_sensor/custom_binary_sensor.cpp +0 -16
  334. esphome/components/custom/binary_sensor/custom_binary_sensor.h +0 -26
  335. esphome/components/custom/climate/custom_climate.h +0 -22
  336. esphome/components/custom/cover/custom_cover.h +0 -21
  337. esphome/components/custom/light/custom_light_output.h +0 -24
  338. esphome/components/custom/output/custom_output.h +0 -37
  339. esphome/components/custom/sensor/custom_sensor.cpp +0 -16
  340. esphome/components/custom/sensor/custom_sensor.h +0 -24
  341. esphome/components/custom/switch/custom_switch.cpp +0 -16
  342. esphome/components/custom/switch/custom_switch.h +0 -24
  343. esphome/components/custom/text_sensor/custom_text_sensor.cpp +0 -16
  344. esphome/components/custom/text_sensor/custom_text_sensor.h +0 -26
  345. esphome/components/custom_component/custom_component.h +0 -28
  346. esphome/components/esp32_ble_server/ble_2901.cpp +0 -18
  347. esphome/components/esp32_ble_server/ble_2901.h +0 -19
  348. esphome/components/resistance_sampler/__init__.py +0 -6
  349. esphome/components/resistance_sampler/resistance_sampler.h +0 -10
  350. esphome/components/uptime/{sensor.py → sensor/__init__.py} +3 -3
  351. /esphome/components/uptime/{uptime_seconds_sensor.cpp → sensor/uptime_seconds_sensor.cpp} +0 -0
  352. /esphome/components/uptime/{uptime_seconds_sensor.h → sensor/uptime_seconds_sensor.h} +0 -0
  353. /esphome/components/uptime/{uptime_timestamp_sensor.cpp → sensor/uptime_timestamp_sensor.cpp} +0 -0
  354. /esphome/components/uptime/{uptime_timestamp_sensor.h → sensor/uptime_timestamp_sensor.h} +0 -0
  355. {esphome-2024.12.4.dist-info → esphome-2025.2.0b2.dist-info}/LICENSE +0 -0
  356. {esphome-2024.12.4.dist-info → esphome-2025.2.0b2.dist-info}/WHEEL +0 -0
  357. {esphome-2024.12.4.dist-info → esphome-2025.2.0b2.dist-info}/entry_points.txt +0 -0
  358. {esphome-2024.12.4.dist-info → esphome-2025.2.0b2.dist-info}/top_level.txt +0 -0
@@ -856,76 +856,6 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
856
856
  */
857
857
  void set_backlight_brightness(float brightness);
858
858
 
859
- /**
860
- * Set the touch sleep timeout of the display.
861
- * @param timeout Timeout in seconds.
862
- *
863
- * Example:
864
- * ```cpp
865
- * it.set_touch_sleep_timeout(30);
866
- * ```
867
- *
868
- * After 30 seconds the display will go to sleep. Note: the display will only wakeup by a restart or by setting up
869
- * `thup`.
870
- */
871
- void set_touch_sleep_timeout(uint16_t timeout);
872
-
873
- /**
874
- * Sets which page Nextion loads when exiting sleep mode. Note this can be set even when Nextion is in sleep mode.
875
- * @param page_id The page id, from 0 to the lage page in Nextion. Set 255 (not set to any existing page) to
876
- * wakes up to current page.
877
- *
878
- * Example:
879
- * ```cpp
880
- * it.set_wake_up_page(2);
881
- * ```
882
- *
883
- * The display will wake up to page 2.
884
- */
885
- void set_wake_up_page(uint8_t page_id = 255);
886
-
887
- /**
888
- * Sets which page Nextion loads when connecting to ESPHome.
889
- * @param page_id The page id, from 0 to the lage page in Nextion. Set 255 (not set to any existing page) to
890
- * wakes up to current page.
891
- *
892
- * Example:
893
- * ```cpp
894
- * it.set_start_up_page(2);
895
- * ```
896
- *
897
- * The display will go to page 2 when it establishes a connection to ESPHome.
898
- */
899
- void set_start_up_page(uint8_t page_id = 255);
900
-
901
- /**
902
- * Sets if Nextion should auto-wake from sleep when touch press occurs.
903
- * @param auto_wake True or false. When auto_wake is true and Nextion is in sleep mode,
904
- * the first touch will only trigger the auto wake mode and not trigger a Touch Event.
905
- *
906
- * Example:
907
- * ```cpp
908
- * it.set_auto_wake_on_touch(true);
909
- * ```
910
- *
911
- * The display will wake up by touch.
912
- */
913
- void set_auto_wake_on_touch(bool auto_wake);
914
-
915
- /**
916
- * Sets if Nextion should exit the active reparse mode before the "connect" command is sent
917
- * @param exit_reparse True or false. When exit_reparse is true, the exit reparse command
918
- * will be sent before requesting the connection from Nextion.
919
- *
920
- * Example:
921
- * ```cpp
922
- * it.set_exit_reparse_on_start(true);
923
- * ```
924
- *
925
- * The display will be requested to leave active reparse mode before setup.
926
- */
927
- void set_exit_reparse_on_start(bool exit_reparse);
928
-
929
859
  /**
930
860
  * Sets whether the Nextion display should skip the connection handshake process.
931
861
  * @param skip_handshake True or false. When skip_connection_handshake is true,
@@ -1172,15 +1102,75 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
1172
1102
 
1173
1103
  void update_components_by_prefix(const std::string &prefix);
1174
1104
 
1175
- void set_touch_sleep_timeout_internal(uint32_t touch_sleep_timeout) {
1176
- this->touch_sleep_timeout_ = touch_sleep_timeout;
1177
- }
1178
- void set_wake_up_page_internal(uint8_t wake_up_page) { this->wake_up_page_ = wake_up_page; }
1179
- void set_start_up_page_internal(uint8_t start_up_page) { this->start_up_page_ = start_up_page; }
1180
- void set_auto_wake_on_touch_internal(bool auto_wake_on_touch) { this->auto_wake_on_touch_ = auto_wake_on_touch; }
1181
- void set_exit_reparse_on_start_internal(bool exit_reparse_on_start) {
1182
- this->exit_reparse_on_start_ = exit_reparse_on_start;
1183
- }
1105
+ /**
1106
+ * Set the touch sleep timeout of the display.
1107
+ * @param timeout Timeout in seconds.
1108
+ *
1109
+ * Example:
1110
+ * ```cpp
1111
+ * it.set_touch_sleep_timeout(30);
1112
+ * ```
1113
+ *
1114
+ * After 30 seconds the display will go to sleep. Note: the display will only wakeup by a restart or by setting up
1115
+ * `thup`.
1116
+ */
1117
+ void set_touch_sleep_timeout(uint32_t touch_sleep_timeout);
1118
+
1119
+ /**
1120
+ * Sets which page Nextion loads when exiting sleep mode. Note this can be set even when Nextion is in sleep mode.
1121
+ * @param wake_up_page The page id, from 0 to the lage page in Nextion. Set 255 (not set to any existing page) to
1122
+ * wakes up to current page.
1123
+ *
1124
+ * Example:
1125
+ * ```cpp
1126
+ * it.set_wake_up_page(2);
1127
+ * ```
1128
+ *
1129
+ * The display will wake up to page 2.
1130
+ */
1131
+ void set_wake_up_page(uint8_t wake_up_page = 255);
1132
+
1133
+ /**
1134
+ * Sets which page Nextion loads when connecting to ESPHome.
1135
+ * @param start_up_page The page id, from 0 to the lage page in Nextion. Set 255 (not set to any existing page) to
1136
+ * wakes up to current page.
1137
+ *
1138
+ * Example:
1139
+ * ```cpp
1140
+ * it.set_start_up_page(2);
1141
+ * ```
1142
+ *
1143
+ * The display will go to page 2 when it establishes a connection to ESPHome.
1144
+ */
1145
+ void set_start_up_page(uint8_t start_up_page = 255) { this->start_up_page_ = start_up_page; }
1146
+
1147
+ /**
1148
+ * Sets if Nextion should auto-wake from sleep when touch press occurs.
1149
+ * @param auto_wake_on_touch True or false. When auto_wake is true and Nextion is in sleep mode,
1150
+ * the first touch will only trigger the auto wake mode and not trigger a Touch Event.
1151
+ *
1152
+ * Example:
1153
+ * ```cpp
1154
+ * it.set_auto_wake_on_touch(true);
1155
+ * ```
1156
+ *
1157
+ * The display will wake up by touch.
1158
+ */
1159
+ void set_auto_wake_on_touch(bool auto_wake_on_touch);
1160
+
1161
+ /**
1162
+ * Sets if Nextion should exit the active reparse mode before the "connect" command is sent
1163
+ * @param exit_reparse_on_start True or false. When exit_reparse_on_start is true, the exit reparse command
1164
+ * will be sent before requesting the connection from Nextion.
1165
+ *
1166
+ * Example:
1167
+ * ```cpp
1168
+ * it.set_exit_reparse_on_start(true);
1169
+ * ```
1170
+ *
1171
+ * The display will be requested to leave active reparse mode before setup.
1172
+ */
1173
+ void set_exit_reparse_on_start(bool exit_reparse_on_start) { this->exit_reparse_on_start_ = exit_reparse_on_start; }
1184
1174
 
1185
1175
  /**
1186
1176
  * @brief Retrieves the number of commands pending in the Nextion command queue.
@@ -1217,6 +1207,25 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
1217
1207
  */
1218
1208
  bool is_updating() override;
1219
1209
 
1210
+ /**
1211
+ * @brief Check if the Nextion display is successfully connected.
1212
+ *
1213
+ * This method returns whether a successful connection has been established with
1214
+ * the Nextion display. A connection is considered established when:
1215
+ *
1216
+ * - The initial handshake with the display is completed successfully, or
1217
+ * - The handshake is skipped via skip_connection_handshake_ flag
1218
+ *
1219
+ * The connection status is particularly useful when:
1220
+ * - Troubleshooting communication issues
1221
+ * - Ensuring the display is ready before sending commands
1222
+ * - Implementing connection-dependent behaviors
1223
+ *
1224
+ * @return true if the Nextion display is connected and ready to receive commands
1225
+ * @return false if the display is not yet connected or connection was lost
1226
+ */
1227
+ bool is_connected() { return this->is_connected_; }
1228
+
1220
1229
  protected:
1221
1230
  std::deque<NextionQueue *> nextion_queue_;
1222
1231
  std::deque<NextionQueue *> waveform_queue_;
@@ -1315,8 +1324,6 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
1315
1324
 
1316
1325
  #endif // USE_NEXTION_TFT_UPLOAD
1317
1326
 
1318
- bool get_is_connected_() { return this->is_connected_; }
1319
-
1320
1327
  bool check_connect_();
1321
1328
 
1322
1329
  std::vector<NextionComponentBase *> touch_;
@@ -1332,7 +1339,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
1332
1339
  CallbackManager<void()> buffer_overflow_callback_{};
1333
1340
 
1334
1341
  optional<nextion_writer_t> writer_;
1335
- float brightness_{1.0};
1342
+ optional<float> brightness_;
1336
1343
 
1337
1344
  std::string device_model_;
1338
1345
  std::string firmware_version_;
@@ -10,19 +10,19 @@ static const char *const TAG = "nextion";
10
10
  // Sleep safe commands
11
11
  void Nextion::soft_reset() { this->send_command_("rest"); }
12
12
 
13
- void Nextion::set_wake_up_page(uint8_t page_id) {
14
- this->add_no_result_to_queue_with_set_internal_("wake_up_page", "wup", page_id, true);
13
+ void Nextion::set_wake_up_page(uint8_t wake_up_page) {
14
+ this->wake_up_page_ = wake_up_page;
15
+ this->add_no_result_to_queue_with_set_internal_("wake_up_page", "wup", wake_up_page, true);
15
16
  }
16
17
 
17
- void Nextion::set_start_up_page(uint8_t page_id) { this->start_up_page_ = page_id; }
18
-
19
- void Nextion::set_touch_sleep_timeout(uint16_t timeout) {
20
- if (timeout < 3) {
18
+ void Nextion::set_touch_sleep_timeout(uint32_t touch_sleep_timeout) {
19
+ if (touch_sleep_timeout < 3) {
21
20
  ESP_LOGD(TAG, "Sleep timeout out of bounds, range 3-65535");
22
21
  return;
23
22
  }
24
23
 
25
- this->add_no_result_to_queue_with_set_internal_("touch_sleep_timeout", "thsp", timeout, true);
24
+ this->touch_sleep_timeout_ = touch_sleep_timeout;
25
+ this->add_no_result_to_queue_with_set_internal_("touch_sleep_timeout", "thsp", touch_sleep_timeout, true);
26
26
  }
27
27
 
28
28
  void Nextion::sleep(bool sleep) {
@@ -54,7 +54,6 @@ bool Nextion::set_protocol_reparse_mode(bool active_mode) {
54
54
  this->ignore_is_setup_ = false;
55
55
  return all_commands_sent;
56
56
  }
57
- void Nextion::set_exit_reparse_on_start(bool exit_reparse) { this->exit_reparse_on_start_ = exit_reparse; }
58
57
 
59
58
  // Set Colors - Background
60
59
  void Nextion::set_component_background_color(const char *component, uint16_t color) {
@@ -191,8 +190,9 @@ void Nextion::set_backlight_brightness(float brightness) {
191
190
  this->add_no_result_to_queue_with_printf_("backlight_brightness", "dim=%d", static_cast<int>(brightness * 100));
192
191
  }
193
192
 
194
- void Nextion::set_auto_wake_on_touch(bool auto_wake) {
195
- this->add_no_result_to_queue_with_set("auto_wake_on_touch", "thup", auto_wake ? 1 : 0);
193
+ void Nextion::set_auto_wake_on_touch(bool auto_wake_on_touch) {
194
+ this->auto_wake_on_touch_ = auto_wake_on_touch;
195
+ this->add_no_result_to_queue_with_set("auto_wake_on_touch", "thup", auto_wake_on_touch ? 1 : 0);
196
196
  }
197
197
 
198
198
  // General Component
@@ -2,7 +2,7 @@ from math import log
2
2
 
3
3
  import esphome.config_validation as cv
4
4
  import esphome.codegen as cg
5
- from esphome.components import sensor, resistance_sampler
5
+ from esphome.components import sensor
6
6
  from esphome.const import (
7
7
  CONF_CALIBRATION,
8
8
  CONF_REFERENCE_RESISTANCE,
@@ -15,8 +15,6 @@ from esphome.const import (
15
15
  UNIT_CELSIUS,
16
16
  )
17
17
 
18
- AUTO_LOAD = ["resistance_sampler"]
19
-
20
18
  ntc_ns = cg.esphome_ns.namespace("ntc")
21
19
  NTC = ntc_ns.class_("NTC", cg.Component, sensor.Sensor)
22
20
 
@@ -126,7 +124,7 @@ CONFIG_SCHEMA = (
126
124
  )
127
125
  .extend(
128
126
  {
129
- cv.Required(CONF_SENSOR): cv.use_id(resistance_sampler.ResistanceSampler),
127
+ cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
130
128
  cv.Required(CONF_CALIBRATION): process_calibration,
131
129
  }
132
130
  )
@@ -4,14 +4,18 @@ from esphome import automation
4
4
  import esphome.codegen as cg
5
5
  from esphome.components.http_request import CONF_HTTP_REQUEST_ID, HttpRequestComponent
6
6
  from esphome.components.image import (
7
- CONF_USE_TRANSPARENCY,
8
- IMAGE_TYPE,
7
+ CONF_INVERT_ALPHA,
8
+ CONF_TRANSPARENCY,
9
+ IMAGE_SCHEMA,
9
10
  Image_,
10
- validate_cross_dependencies,
11
+ get_image_type_enum,
12
+ get_transparency_enum,
11
13
  )
12
14
  import esphome.config_validation as cv
13
15
  from esphome.const import (
14
16
  CONF_BUFFER_SIZE,
17
+ CONF_DITHER,
18
+ CONF_FILE,
15
19
  CONF_FORMAT,
16
20
  CONF_ID,
17
21
  CONF_ON_ERROR,
@@ -23,7 +27,7 @@ from esphome.const import (
23
27
 
24
28
  AUTO_LOAD = ["image"]
25
29
  DEPENDENCIES = ["display", "http_request"]
26
- CODEOWNERS = ["@guillempages"]
30
+ CODEOWNERS = ["@guillempages", "@clydebarrow"]
27
31
  MULTI_CONF = True
28
32
 
29
33
  CONF_ON_DOWNLOAD_FINISHED = "on_download_finished"
@@ -35,9 +39,54 @@ online_image_ns = cg.esphome_ns.namespace("online_image")
35
39
 
36
40
  ImageFormat = online_image_ns.enum("ImageFormat")
37
41
 
38
- FORMAT_PNG = "PNG"
39
42
 
40
- IMAGE_FORMAT = {FORMAT_PNG: ImageFormat.PNG} # Add new supported formats here
43
+ class Format:
44
+ def __init__(self, image_type):
45
+ self.image_type = image_type
46
+
47
+ @property
48
+ def enum(self):
49
+ return getattr(ImageFormat, self.image_type)
50
+
51
+ def actions(self):
52
+ pass
53
+
54
+
55
+ class BMPFormat(Format):
56
+ def __init__(self):
57
+ super().__init__("BMP")
58
+
59
+ def actions(self):
60
+ cg.add_define("USE_ONLINE_IMAGE_BMP_SUPPORT")
61
+
62
+
63
+ class JPEGFormat(Format):
64
+ def __init__(self):
65
+ super().__init__("JPEG")
66
+
67
+ def actions(self):
68
+ cg.add_define("USE_ONLINE_IMAGE_JPEG_SUPPORT")
69
+ cg.add_library("JPEGDEC", None, "https://github.com/bitbank2/JPEGDEC#ca1e0f2")
70
+
71
+
72
+ class PNGFormat(Format):
73
+ def __init__(self):
74
+ super().__init__("PNG")
75
+
76
+ def actions(self):
77
+ cg.add_define("USE_ONLINE_IMAGE_PNG_SUPPORT")
78
+ cg.add_library("pngle", "1.0.2")
79
+
80
+
81
+ IMAGE_FORMATS = {
82
+ x.image_type: x
83
+ for x in (
84
+ BMPFormat(),
85
+ JPEGFormat(),
86
+ PNGFormat(),
87
+ )
88
+ }
89
+ IMAGE_FORMATS.update({"JPG": IMAGE_FORMATS["JPEG"]})
41
90
 
42
91
  OnlineImage = online_image_ns.class_("OnlineImage", cg.PollingComponent, Image_)
43
92
 
@@ -57,48 +106,54 @@ DownloadErrorTrigger = online_image_ns.class_(
57
106
  "DownloadErrorTrigger", automation.Trigger.template()
58
107
  )
59
108
 
60
- ONLINE_IMAGE_SCHEMA = cv.Schema(
61
- {
62
- cv.Required(CONF_ID): cv.declare_id(OnlineImage),
63
- cv.GenerateID(CONF_HTTP_REQUEST_ID): cv.use_id(HttpRequestComponent),
64
- #
65
- # Common image options
66
- #
67
- cv.Optional(CONF_RESIZE): cv.dimensions,
68
- cv.Optional(CONF_TYPE, default="BINARY"): cv.enum(IMAGE_TYPE, upper=True),
69
- # Not setting default here on purpose; the default depends on the image type,
70
- # and thus will be set in the "validate_cross_dependencies" validator.
71
- cv.Optional(CONF_USE_TRANSPARENCY): cv.boolean,
72
- #
73
- # Online Image specific options
74
- #
75
- cv.Required(CONF_URL): cv.url,
76
- cv.Required(CONF_FORMAT): cv.enum(IMAGE_FORMAT, upper=True),
77
- cv.Optional(CONF_PLACEHOLDER): cv.use_id(Image_),
78
- cv.Optional(CONF_BUFFER_SIZE, default=2048): cv.int_range(256, 65536),
79
- cv.Optional(CONF_ON_DOWNLOAD_FINISHED): automation.validate_automation(
80
- {
81
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DownloadFinishedTrigger),
82
- }
83
- ),
84
- cv.Optional(CONF_ON_ERROR): automation.validate_automation(
85
- {
86
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DownloadErrorTrigger),
87
- }
88
- ),
109
+
110
+ def remove_options(*options):
111
+ return {
112
+ cv.Optional(option): cv.invalid(
113
+ f"{option} is an invalid option for online_image"
114
+ )
115
+ for option in options
89
116
  }
90
- ).extend(cv.polling_component_schema("never"))
117
+
118
+
119
+ ONLINE_IMAGE_SCHEMA = (
120
+ IMAGE_SCHEMA.extend(remove_options(CONF_FILE, CONF_INVERT_ALPHA, CONF_DITHER))
121
+ .extend(
122
+ {
123
+ cv.Required(CONF_ID): cv.declare_id(OnlineImage),
124
+ cv.GenerateID(CONF_HTTP_REQUEST_ID): cv.use_id(HttpRequestComponent),
125
+ # Online Image specific options
126
+ cv.Required(CONF_URL): cv.url,
127
+ cv.Required(CONF_FORMAT): cv.one_of(*IMAGE_FORMATS, upper=True),
128
+ cv.Optional(CONF_PLACEHOLDER): cv.use_id(Image_),
129
+ cv.Optional(CONF_BUFFER_SIZE, default=65536): cv.int_range(256, 65536),
130
+ cv.Optional(CONF_ON_DOWNLOAD_FINISHED): automation.validate_automation(
131
+ {
132
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
133
+ DownloadFinishedTrigger
134
+ ),
135
+ }
136
+ ),
137
+ cv.Optional(CONF_ON_ERROR): automation.validate_automation(
138
+ {
139
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DownloadErrorTrigger),
140
+ }
141
+ ),
142
+ }
143
+ )
144
+ .extend(cv.polling_component_schema("never"))
145
+ )
91
146
 
92
147
  CONFIG_SCHEMA = cv.Schema(
93
148
  cv.All(
94
149
  ONLINE_IMAGE_SCHEMA,
95
- validate_cross_dependencies,
96
150
  cv.require_framework_version(
97
151
  # esp8266 not supported yet; if enabled in the future, minimum version of 2.7.0 is needed
98
152
  # esp8266_arduino=cv.Version(2, 7, 0),
99
153
  esp32_arduino=cv.Version(0, 0, 0),
100
154
  esp_idf=cv.Version(4, 0, 0),
101
155
  rp2040_arduino=cv.Version(0, 0, 0),
156
+ host=cv.Version(0, 0, 0),
102
157
  ),
103
158
  )
104
159
  )
@@ -132,29 +187,26 @@ async def online_image_action_to_code(config, action_id, template_arg, args):
132
187
 
133
188
 
134
189
  async def to_code(config):
135
- format = config[CONF_FORMAT]
136
- if format in [FORMAT_PNG]:
137
- cg.add_define("USE_ONLINE_IMAGE_PNG_SUPPORT")
138
- cg.add_library("pngle", "1.0.2")
190
+ image_format = IMAGE_FORMATS[config[CONF_FORMAT]]
191
+ image_format.actions()
139
192
 
140
193
  url = config[CONF_URL]
141
194
  width, height = config.get(CONF_RESIZE, (0, 0))
142
- transparent = config[CONF_USE_TRANSPARENCY]
195
+ transparent = get_transparency_enum(config[CONF_TRANSPARENCY])
143
196
 
144
197
  var = cg.new_Pvariable(
145
198
  config[CONF_ID],
146
199
  url,
147
200
  width,
148
201
  height,
149
- format,
150
- config[CONF_TYPE],
202
+ image_format.enum,
203
+ get_image_type_enum(config[CONF_TYPE]),
204
+ transparent,
151
205
  config[CONF_BUFFER_SIZE],
152
206
  )
153
207
  await cg.register_component(var, config)
154
208
  await cg.register_parented(var, config[CONF_HTTP_REQUEST_ID])
155
209
 
156
- cg.add(var.set_transparency(transparent))
157
-
158
210
  if placeholder_id := config.get(CONF_PLACEHOLDER):
159
211
  placeholder = await cg.get_variable(placeholder_id)
160
212
  cg.add(var.set_placeholder(placeholder))
@@ -0,0 +1,101 @@
1
+ #include "bmp_image.h"
2
+
3
+ #ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
4
+
5
+ #include "esphome/components/display/display.h"
6
+ #include "esphome/core/helpers.h"
7
+ #include "esphome/core/log.h"
8
+
9
+ namespace esphome {
10
+ namespace online_image {
11
+
12
+ static const char *const TAG = "online_image.bmp";
13
+
14
+ int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) {
15
+ size_t index = 0;
16
+ if (this->current_index_ == 0 && index == 0 && size > 14) {
17
+ /**
18
+ * BMP file format:
19
+ * 0-1: Signature (BM)
20
+ * 2-5: File size
21
+ * 6-9: Reserved
22
+ * 10-13: Pixel data offset
23
+ *
24
+ * Integer values are stored in little-endian format.
25
+ */
26
+
27
+ // Check if the file is a BMP image
28
+ if (buffer[0] != 'B' || buffer[1] != 'M') {
29
+ ESP_LOGE(TAG, "Not a BMP file");
30
+ return DECODE_ERROR_INVALID_TYPE;
31
+ }
32
+
33
+ this->download_size_ = encode_uint32(buffer[5], buffer[4], buffer[3], buffer[2]);
34
+ this->data_offset_ = encode_uint32(buffer[13], buffer[12], buffer[11], buffer[10]);
35
+
36
+ this->current_index_ = 14;
37
+ index = 14;
38
+ }
39
+ if (this->current_index_ == 14 && index == 14 && size > this->data_offset_) {
40
+ /**
41
+ * BMP DIB header:
42
+ * 14-17: DIB header size
43
+ * 18-21: Image width
44
+ * 22-25: Image height
45
+ * 26-27: Number of color planes
46
+ * 28-29: Bits per pixel
47
+ * 30-33: Compression method
48
+ * 34-37: Image data size
49
+ * 38-41: Horizontal resolution
50
+ * 42-45: Vertical resolution
51
+ * 46-49: Number of colors in the color table
52
+ */
53
+
54
+ this->width_ = encode_uint32(buffer[21], buffer[20], buffer[19], buffer[18]);
55
+ this->height_ = encode_uint32(buffer[25], buffer[24], buffer[23], buffer[22]);
56
+ this->bits_per_pixel_ = encode_uint16(buffer[29], buffer[28]);
57
+ this->compression_method_ = encode_uint32(buffer[33], buffer[32], buffer[31], buffer[30]);
58
+ this->image_data_size_ = encode_uint32(buffer[37], buffer[36], buffer[35], buffer[34]);
59
+ this->color_table_entries_ = encode_uint32(buffer[49], buffer[48], buffer[47], buffer[46]);
60
+
61
+ switch (this->bits_per_pixel_) {
62
+ case 1:
63
+ this->width_bytes_ = (this->width_ % 8 == 0) ? (this->width_ / 8) : (this->width_ / 8 + 1);
64
+ break;
65
+ default:
66
+ ESP_LOGE(TAG, "Unsupported bits per pixel: %d", this->bits_per_pixel_);
67
+ return DECODE_ERROR_UNSUPPORTED_FORMAT;
68
+ }
69
+
70
+ if (this->compression_method_ != 0) {
71
+ ESP_LOGE(TAG, "Unsupported compression method: %d", this->compression_method_);
72
+ return DECODE_ERROR_UNSUPPORTED_FORMAT;
73
+ }
74
+
75
+ if (!this->set_size(this->width_, this->height_)) {
76
+ return DECODE_ERROR_OUT_OF_MEMORY;
77
+ }
78
+ this->current_index_ = this->data_offset_;
79
+ index = this->data_offset_;
80
+ }
81
+ while (index < size) {
82
+ size_t paint_index = this->current_index_ - this->data_offset_;
83
+
84
+ uint8_t current_byte = buffer[index];
85
+ for (uint8_t i = 0; i < 8; i++) {
86
+ size_t x = (paint_index * 8) % this->width_ + i;
87
+ size_t y = (this->height_ - 1) - (paint_index / this->width_bytes_);
88
+ Color c = (current_byte & (1 << (7 - i))) ? display::COLOR_ON : display::COLOR_OFF;
89
+ this->draw(x, y, 1, 1, c);
90
+ }
91
+ this->current_index_++;
92
+ index++;
93
+ }
94
+ this->decoded_bytes_ += size;
95
+ return size;
96
+ };
97
+
98
+ } // namespace online_image
99
+ } // namespace esphome
100
+
101
+ #endif // USE_ONLINE_IMAGE_BMP_SUPPORT
@@ -0,0 +1,40 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/defines.h"
4
+ #ifdef USE_ONLINE_IMAGE_BMP_SUPPORT
5
+
6
+ #include "image_decoder.h"
7
+
8
+ namespace esphome {
9
+ namespace online_image {
10
+
11
+ /**
12
+ * @brief Image decoder specialization for PNG images.
13
+ */
14
+ class BmpDecoder : public ImageDecoder {
15
+ public:
16
+ /**
17
+ * @brief Construct a new BMP Decoder object.
18
+ *
19
+ * @param display The image to decode the stream into.
20
+ */
21
+ BmpDecoder(OnlineImage *image) : ImageDecoder(image) {}
22
+
23
+ int HOT decode(uint8_t *buffer, size_t size) override;
24
+
25
+ protected:
26
+ size_t current_index_{0};
27
+ ssize_t width_{0};
28
+ ssize_t height_{0};
29
+ uint16_t bits_per_pixel_{0};
30
+ uint32_t compression_method_{0};
31
+ uint32_t image_data_size_{0};
32
+ uint32_t color_table_entries_{0};
33
+ size_t width_bytes_{0};
34
+ size_t data_offset_{0};
35
+ };
36
+
37
+ } // namespace online_image
38
+ } // namespace esphome
39
+
40
+ #endif // USE_ONLINE_IMAGE_BMP_SUPPORT
@@ -8,10 +8,11 @@ namespace online_image {
8
8
 
9
9
  static const char *const TAG = "online_image.decoder";
10
10
 
11
- void ImageDecoder::set_size(int width, int height) {
12
- this->image_->resize_(width, height);
11
+ bool ImageDecoder::set_size(int width, int height) {
12
+ bool resized = this->image_->resize_(width, height);
13
13
  this->x_scale_ = static_cast<double>(this->image_->buffer_width_) / width;
14
14
  this->y_scale_ = static_cast<double>(this->image_->buffer_height_) / height;
15
+ return resized;
15
16
  }
16
17
 
17
18
  void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
@@ -24,6 +25,15 @@ void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
24
25
  }
25
26
  }
26
27
 
28
+ DownloadBuffer::DownloadBuffer(size_t size) : size_(size) {
29
+ this->buffer_ = this->allocator_.allocate(size);
30
+ this->reset();
31
+ if (!this->buffer_) {
32
+ ESP_LOGE(TAG, "Initial allocation of download buffer failed!");
33
+ this->size_ = 0;
34
+ }
35
+ }
36
+
27
37
  uint8_t *DownloadBuffer::data(size_t offset) {
28
38
  if (offset > this->size_) {
29
39
  ESP_LOGE(TAG, "Tried to access beyond download buffer bounds!!!");
@@ -40,5 +50,21 @@ size_t DownloadBuffer::read(size_t len) {
40
50
  return this->unread_;
41
51
  }
42
52
 
53
+ size_t DownloadBuffer::resize(size_t size) {
54
+ if (this->size_ == size) {
55
+ return size;
56
+ }
57
+ this->allocator_.deallocate(this->buffer_, this->size_);
58
+ this->buffer_ = this->allocator_.allocate(size);
59
+ this->reset();
60
+ if (this->buffer_) {
61
+ this->size_ = size;
62
+ return size;
63
+ } else {
64
+ this->size_ = 0;
65
+ return 0;
66
+ }
67
+ }
68
+
43
69
  } // namespace online_image
44
70
  } // namespace esphome