esphome 2025.8.4__py3-none-any.whl → 2025.9.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 (344) hide show
  1. esphome/__main__.py +36 -42
  2. esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
  3. esphome/components/adc/adc_sensor_esp32.cpp +29 -6
  4. esphome/components/ags10/ags10.cpp +3 -18
  5. esphome/components/ags10/ags10.h +2 -12
  6. esphome/components/aht10/aht10.cpp +3 -3
  7. esphome/components/airthings_ble/__init__.py +2 -2
  8. esphome/components/alarm_control_panel/__init__.py +2 -2
  9. esphome/components/am2315c/am2315c.cpp +1 -17
  10. esphome/components/am2315c/am2315c.h +2 -3
  11. esphome/components/api/__init__.py +2 -2
  12. esphome/components/api/api_connection.cpp +34 -23
  13. esphome/components/api/api_connection.h +20 -39
  14. esphome/components/api/api_frame_helper.cpp +25 -25
  15. esphome/components/api/api_frame_helper.h +3 -3
  16. esphome/components/api/api_frame_helper_noise.cpp +75 -40
  17. esphome/components/api/api_frame_helper_noise.h +3 -7
  18. esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
  19. esphome/components/api/api_frame_helper_plaintext.h +1 -4
  20. esphome/components/api/api_pb2.cpp +20 -2
  21. esphome/components/api/api_pb2.h +146 -141
  22. esphome/components/api/api_pb2_dump.cpp +12 -1
  23. esphome/components/api/proto.cpp +33 -37
  24. esphome/components/async_tcp/__init__.py +2 -2
  25. esphome/components/atm90e26/sensor.py +2 -0
  26. esphome/components/atm90e32/sensor.py +4 -2
  27. esphome/components/audio_adc/__init__.py +2 -2
  28. esphome/components/audio_dac/__init__.py +2 -2
  29. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
  30. esphome/components/bedjet/bedjet_hub.cpp +1 -1
  31. esphome/components/binary_sensor/__init__.py +2 -2
  32. esphome/components/binary_sensor/binary_sensor.cpp +13 -0
  33. esphome/components/binary_sensor/binary_sensor.h +4 -7
  34. esphome/components/bl0940/__init__.py +6 -1
  35. esphome/components/bl0940/bl0940.cpp +178 -41
  36. esphome/components/bl0940/bl0940.h +121 -76
  37. esphome/components/bl0940/button/__init__.py +27 -0
  38. esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
  39. esphome/components/bl0940/button/calibration_reset_button.h +19 -0
  40. esphome/components/bl0940/number/__init__.py +94 -0
  41. esphome/components/bl0940/number/calibration_number.cpp +29 -0
  42. esphome/components/bl0940/number/calibration_number.h +26 -0
  43. esphome/components/bl0940/sensor.py +151 -2
  44. esphome/components/bl0942/bl0942.cpp +1 -1
  45. esphome/components/ble_client/output/__init__.py +4 -4
  46. esphome/components/bluetooth_proxy/__init__.py +1 -1
  47. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
  48. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
  49. esphome/components/bluetooth_proxy/bluetooth_proxy.h +3 -2
  50. esphome/components/button/__init__.py +2 -2
  51. esphome/components/button/button.cpp +13 -0
  52. esphome/components/button/button.h +4 -7
  53. esphome/components/camera/buffer.h +18 -0
  54. esphome/components/camera/buffer_impl.cpp +20 -0
  55. esphome/components/camera/buffer_impl.h +26 -0
  56. esphome/components/camera/camera.h +43 -0
  57. esphome/components/camera/encoder.h +69 -0
  58. esphome/components/camera_encoder/__init__.py +62 -0
  59. esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
  60. esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
  61. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
  62. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
  63. esphome/components/captive_portal/__init__.py +2 -2
  64. esphome/components/captive_portal/captive_portal.cpp +35 -12
  65. esphome/components/captive_portal/captive_portal.h +3 -3
  66. esphome/components/ccs811/ccs811.cpp +3 -3
  67. esphome/components/climate/__init__.py +2 -2
  68. esphome/components/climate/climate.cpp +1 -1
  69. esphome/components/cover/__init__.py +5 -5
  70. esphome/components/cover/cover.cpp +1 -1
  71. esphome/components/cover/cover.h +2 -2
  72. esphome/components/dallas_temp/dallas_temp.cpp +2 -2
  73. esphome/components/datetime/__init__.py +2 -2
  74. esphome/components/datetime/date_entity.h +2 -2
  75. esphome/components/datetime/datetime_entity.h +2 -2
  76. esphome/components/datetime/time_entity.h +2 -2
  77. esphome/components/debug/debug_esp32.cpp +1 -1
  78. esphome/components/display/__init__.py +4 -4
  79. esphome/components/duty_time/duty_time_sensor.cpp +1 -1
  80. esphome/components/esp32/__init__.py +0 -5
  81. esphome/components/esp32/gpio.cpp +27 -23
  82. esphome/components/esp32/gpio.h +26 -11
  83. esphome/components/esp32/preferences.cpp +8 -4
  84. esphome/components/esp32_ble/__init__.py +7 -2
  85. esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
  86. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  87. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +9 -44
  88. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
  89. esphome/components/esp8266/__init__.py +2 -2
  90. esphome/components/esp8266/core.cpp +2 -2
  91. esphome/components/esp8266/gpio.py +4 -4
  92. esphome/components/esp8266/preferences.cpp +30 -28
  93. esphome/components/esphome/ota/__init__.py +2 -2
  94. esphome/components/esphome/ota/ota_esphome.cpp +21 -19
  95. esphome/components/esphome/ota/ota_esphome.h +6 -5
  96. esphome/components/ethernet/__init__.py +7 -2
  97. esphome/components/ethernet/ethernet_component.cpp +1 -1
  98. esphome/components/event/__init__.py +2 -2
  99. esphome/components/event/event.h +4 -4
  100. esphome/components/fan/__init__.py +2 -2
  101. esphome/components/fan/fan.cpp +2 -1
  102. esphome/components/gdk101/gdk101.cpp +4 -4
  103. esphome/components/globals/__init__.py +2 -2
  104. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
  105. esphome/components/gpio_expander/cached_gpio.h +36 -16
  106. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
  107. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  108. esphome/components/haier/haier_base.cpp +1 -1
  109. esphome/components/haier/hon_climate.cpp +1 -1
  110. esphome/components/hlw8012/hlw8012.cpp +5 -5
  111. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
  112. esphome/components/host/preferences.h +3 -2
  113. esphome/components/hte501/hte501.cpp +3 -21
  114. esphome/components/hte501/hte501.h +2 -3
  115. esphome/components/http_request/ota/__init__.py +2 -2
  116. esphome/components/i2c/__init__.py +2 -2
  117. esphome/components/i2c/i2c.cpp +13 -9
  118. esphome/components/i2c/i2c_bus.h +36 -6
  119. esphome/components/i2s_audio/__init__.py +8 -2
  120. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  121. esphome/components/i2s_audio/microphone/__init__.py +1 -1
  122. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  123. esphome/components/inkplate/__init__.py +1 -0
  124. esphome/components/inkplate/const.py +105 -0
  125. esphome/components/inkplate/display.py +238 -0
  126. esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
  127. esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
  128. esphome/components/inkplate6/__init__.py +0 -1
  129. esphome/components/inkplate6/display.py +2 -211
  130. esphome/components/integration/integration_sensor.cpp +1 -1
  131. esphome/components/json/__init__.py +2 -2
  132. esphome/components/lc709203f/lc709203f.cpp +4 -17
  133. esphome/components/lc709203f/lc709203f.h +2 -3
  134. esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
  135. esphome/components/ld2450/ld2450.cpp +1 -1
  136. esphome/components/libretiny/preferences.cpp +13 -5
  137. esphome/components/light/__init__.py +2 -2
  138. esphome/components/light/addressable_light_effect.h +7 -0
  139. esphome/components/light/base_light_effects.h +8 -0
  140. esphome/components/light/light_call.cpp +22 -20
  141. esphome/components/light/light_effect.cpp +36 -0
  142. esphome/components/light/light_effect.h +14 -0
  143. esphome/components/light/light_json_schema.cpp +9 -1
  144. esphome/components/light/light_state.cpp +2 -2
  145. esphome/components/light/light_state.h +38 -0
  146. esphome/components/lock/__init__.py +2 -2
  147. esphome/components/lock/lock.h +2 -2
  148. esphome/components/logger/__init__.py +2 -2
  149. esphome/components/logger/logger.cpp +25 -4
  150. esphome/components/logger/logger.h +1 -1
  151. esphome/components/logger/logger_esp32.cpp +16 -8
  152. esphome/components/logger/logger_esp8266.cpp +11 -3
  153. esphome/components/logger/logger_libretiny.cpp +13 -3
  154. esphome/components/logger/logger_rp2040.cpp +14 -3
  155. esphome/components/logger/logger_zephyr.cpp +15 -4
  156. esphome/components/lvgl/defines.py +1 -0
  157. esphome/components/lvgl/hello_world.py +96 -33
  158. esphome/components/lvgl/number/lvgl_number.h +1 -1
  159. esphome/components/lvgl/select/lvgl_select.h +1 -1
  160. esphome/components/lvgl/widgets/__init__.py +0 -1
  161. esphome/components/lvgl/widgets/spinbox.py +20 -11
  162. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
  163. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
  164. esphome/components/mapping/__init__.py +13 -5
  165. esphome/components/mapping/mapping.h +69 -0
  166. esphome/components/max17043/max17043.cpp +2 -2
  167. esphome/components/mcp23016/__init__.py +1 -0
  168. esphome/components/mcp23016/mcp23016.cpp +20 -5
  169. esphome/components/mcp23016/mcp23016.h +10 -4
  170. esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
  171. esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
  172. esphome/components/mdns/__init__.py +2 -2
  173. esphome/components/mdns/mdns_component.cpp +145 -54
  174. esphome/components/media_player/__init__.py +2 -2
  175. esphome/components/micro_wake_word/__init__.py +2 -2
  176. esphome/components/microphone/__init__.py +2 -2
  177. esphome/components/mipi/__init__.py +77 -33
  178. esphome/components/mipi_rgb/__init__.py +2 -0
  179. esphome/components/mipi_rgb/display.py +321 -0
  180. esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
  181. esphome/components/mipi_rgb/mipi_rgb.h +127 -0
  182. esphome/components/mipi_rgb/models/guition.py +24 -0
  183. esphome/components/mipi_rgb/models/lilygo.py +228 -0
  184. esphome/components/mipi_rgb/models/rpi.py +9 -0
  185. esphome/components/mipi_rgb/models/st7701s.py +214 -0
  186. esphome/components/mipi_rgb/models/waveshare.py +64 -0
  187. esphome/components/mipi_spi/models/jc.py +229 -0
  188. esphome/components/mlx90614/mlx90614.cpp +1 -16
  189. esphome/components/mlx90614/mlx90614.h +0 -1
  190. esphome/components/mqtt/__init__.py +2 -2
  191. esphome/components/mqtt/mqtt_sensor.cpp +7 -2
  192. esphome/components/ms5611/ms5611.cpp +7 -6
  193. esphome/components/network/__init__.py +2 -2
  194. esphome/components/nextion/nextion_upload.cpp +4 -1
  195. esphome/components/nrf52/__init__.py +49 -6
  196. esphome/components/nrf52/const.py +1 -0
  197. esphome/components/nrf52/dfu.cpp +51 -0
  198. esphome/components/nrf52/dfu.h +24 -0
  199. esphome/components/ntc/ntc.cpp +1 -1
  200. esphome/components/number/__init__.py +2 -2
  201. esphome/components/number/automation.cpp +1 -1
  202. esphome/components/number/number.cpp +21 -0
  203. esphome/components/number/number.h +4 -13
  204. esphome/components/opentherm/hub.h +6 -6
  205. esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
  206. esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
  207. esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
  208. esphome/components/ota/__init__.py +2 -2
  209. esphome/components/pca6416a/__init__.py +1 -0
  210. esphome/components/pca6416a/pca6416a.cpp +20 -5
  211. esphome/components/pca6416a/pca6416a.h +12 -5
  212. esphome/components/pca9554/__init__.py +2 -1
  213. esphome/components/pca9554/pca9554.cpp +12 -18
  214. esphome/components/pca9554/pca9554.h +10 -9
  215. esphome/components/pcf8574/__init__.py +1 -0
  216. esphome/components/pcf8574/pcf8574.cpp +14 -5
  217. esphome/components/pcf8574/pcf8574.h +13 -6
  218. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
  219. esphome/components/pipsolar/__init__.py +3 -3
  220. esphome/components/pipsolar/output/__init__.py +4 -4
  221. esphome/components/pulse_width/pulse_width.cpp +2 -2
  222. esphome/components/qmp6988/qmp6988.cpp +81 -126
  223. esphome/components/qmp6988/qmp6988.h +31 -37
  224. esphome/components/radon_eye_ble/__init__.py +2 -2
  225. esphome/components/remote_base/__init__.py +6 -8
  226. esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
  227. esphome/components/rp2040/__init__.py +2 -2
  228. esphome/components/runtime_stats/runtime_stats.cpp +10 -23
  229. esphome/components/runtime_stats/runtime_stats.h +4 -10
  230. esphome/components/safe_mode/__init__.py +2 -2
  231. esphome/components/safe_mode/safe_mode.cpp +33 -31
  232. esphome/components/script/script.cpp +6 -0
  233. esphome/components/script/script.h +19 -5
  234. esphome/components/sdm_meter/sensor.py +3 -1
  235. esphome/components/select/__init__.py +2 -2
  236. esphome/components/select/select.h +2 -2
  237. esphome/components/sen5x/sen5x.cpp +57 -55
  238. esphome/components/sen5x/sen5x.h +21 -15
  239. esphome/components/sen5x/sensor.py +67 -44
  240. esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
  241. esphome/components/sensirion_common/i2c_sensirion.h +39 -55
  242. esphome/components/sensor/__init__.py +2 -2
  243. esphome/components/sensor/automation.h +1 -1
  244. esphome/components/sensor/sensor.cpp +34 -6
  245. esphome/components/sensor/sensor.h +4 -21
  246. esphome/components/sgp30/sgp30.cpp +34 -35
  247. esphome/components/sgp30/sgp30.h +11 -10
  248. esphome/components/sgp4x/sgp4x.cpp +2 -2
  249. esphome/components/shelly_dimmer/light.py +7 -7
  250. esphome/components/sht4x/sht4x.cpp +1 -1
  251. esphome/components/sntp/sntp_component.cpp +36 -9
  252. esphome/components/sntp/sntp_component.h +7 -0
  253. esphome/components/sound_level/sound_level.cpp +1 -1
  254. esphome/components/speaker/__init__.py +2 -2
  255. esphome/components/speaker/media_player/__init__.py +2 -2
  256. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
  257. esphome/components/spi/__init__.py +2 -2
  258. esphome/components/sprinkler/sprinkler.cpp +1 -1
  259. esphome/components/sps30/sps30.cpp +18 -23
  260. esphome/components/sps30/sps30.h +3 -3
  261. esphome/components/status_led/__init__.py +2 -2
  262. esphome/components/stepper/__init__.py +2 -2
  263. esphome/components/switch/__init__.py +2 -2
  264. esphome/components/switch/switch.cpp +5 -5
  265. esphome/components/sx1509/__init__.py +1 -1
  266. esphome/components/sx1509/sx1509.cpp +12 -7
  267. esphome/components/sx1509/sx1509.h +11 -4
  268. esphome/components/tca9555/tca9555.cpp +5 -5
  269. esphome/components/tee501/tee501.cpp +2 -21
  270. esphome/components/tee501/tee501.h +2 -4
  271. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
  272. esphome/components/template/datetime/template_date.cpp +1 -1
  273. esphome/components/template/datetime/template_datetime.cpp +2 -2
  274. esphome/components/template/datetime/template_time.cpp +1 -1
  275. esphome/components/template/number/template_number.cpp +1 -1
  276. esphome/components/template/select/template_select.cpp +1 -1
  277. esphome/components/template/text/template_text.cpp +1 -1
  278. esphome/components/text/__init__.py +2 -2
  279. esphome/components/text/text.h +2 -2
  280. esphome/components/text_sensor/__init__.py +2 -2
  281. esphome/components/text_sensor/text_sensor.h +4 -4
  282. esphome/components/thermostat/climate.py +11 -7
  283. esphome/components/thermostat/thermostat_climate.cpp +237 -206
  284. esphome/components/thermostat/thermostat_climate.h +52 -41
  285. esphome/components/time/__init__.py +2 -2
  286. esphome/components/tmp1075/tmp1075.cpp +1 -1
  287. esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
  288. esphome/components/touchscreen/__init__.py +2 -2
  289. esphome/components/tuya/number/tuya_number.cpp +1 -1
  290. esphome/components/udp/udp_component.cpp +3 -3
  291. esphome/components/ufire_ec/ufire_ec.cpp +4 -4
  292. esphome/components/ufire_ise/ufire_ise.cpp +4 -4
  293. esphome/components/update/__init__.py +2 -2
  294. esphome/components/usb_uart/usb_uart.cpp +1 -1
  295. esphome/components/valve/__init__.py +5 -5
  296. esphome/components/valve/valve.cpp +1 -1
  297. esphome/components/valve/valve.h +2 -2
  298. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
  299. esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
  300. esphome/components/web_server/__init__.py +2 -2
  301. esphome/components/web_server/ota/__init__.py +2 -2
  302. esphome/components/web_server/ota/ota_web_server.cpp +11 -0
  303. esphome/components/web_server/web_server.cpp +58 -12
  304. esphome/components/web_server_base/__init__.py +2 -2
  305. esphome/components/wifi/__init__.py +5 -5
  306. esphome/components/wifi/wifi_component.cpp +3 -3
  307. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
  308. esphome/config_validation.py +2 -2
  309. esphome/const.py +2 -1
  310. esphome/core/__init__.py +1 -0
  311. esphome/core/application.cpp +89 -51
  312. esphome/core/application.h +1 -0
  313. esphome/core/component.cpp +41 -19
  314. esphome/core/component.h +17 -13
  315. esphome/core/config.py +7 -7
  316. esphome/core/defines.h +4 -0
  317. esphome/core/entity_base.cpp +22 -8
  318. esphome/core/entity_base.h +43 -0
  319. esphome/core/helpers.cpp +26 -13
  320. esphome/core/helpers.h +4 -3
  321. esphome/core/ring_buffer.cpp +6 -2
  322. esphome/core/ring_buffer.h +2 -1
  323. esphome/core/scheduler.cpp +175 -94
  324. esphome/core/scheduler.h +66 -35
  325. esphome/core/time.cpp +6 -20
  326. esphome/coroutine.py +80 -3
  327. esphome/cpp_generator.py +13 -0
  328. esphome/cpp_helpers.py +2 -2
  329. esphome/dashboard/web_server.py +67 -10
  330. esphome/espota2.py +13 -6
  331. esphome/helpers.py +68 -83
  332. esphome/resolver.py +67 -0
  333. esphome/util.py +9 -6
  334. esphome/wizard.py +39 -26
  335. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/METADATA +9 -9
  336. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/RECORD +344 -313
  337. /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
  338. /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
  339. /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
  340. /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
  341. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/WHEEL +0 -0
  342. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/entry_points.txt +0 -0
  343. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/licenses/LICENSE +0 -0
  344. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,30 @@
5
5
  #include "esphome/core/version.h"
6
6
  #include "mdns_component.h"
7
7
 
8
+ #ifdef USE_ESP8266
9
+ #include <pgmspace.h>
10
+ // Macro to define strings in PROGMEM on ESP8266, regular memory on other platforms
11
+ #define MDNS_STATIC_CONST_CHAR(name, value) static const char name[] PROGMEM = value
12
+ // Helper to get string from PROGMEM - returns a temporary std::string
13
+ // Only define this function if we have services that will use it
14
+ #if defined(USE_API) || defined(USE_PROMETHEUS) || defined(USE_WEBSERVER) || defined(USE_MDNS_EXTRA_SERVICES)
15
+ static std::string mdns_string_p(const char *src) {
16
+ char buf[64];
17
+ strncpy_P(buf, src, sizeof(buf) - 1);
18
+ buf[sizeof(buf) - 1] = '\0';
19
+ return std::string(buf);
20
+ }
21
+ #define MDNS_STR(name) mdns_string_p(name)
22
+ #else
23
+ // If no services are configured, we still need the fallback service but it uses string literals
24
+ #define MDNS_STR(name) std::string(name)
25
+ #endif
26
+ #else
27
+ // On non-ESP8266 platforms, use regular const char*
28
+ #define MDNS_STATIC_CONST_CHAR(name, value) static constexpr const char *name = value
29
+ #define MDNS_STR(name) name
30
+ #endif
31
+
8
32
  #ifdef USE_API
9
33
  #include "esphome/components/api/api_server.h"
10
34
  #endif
@@ -21,103 +45,168 @@ static const char *const TAG = "mdns";
21
45
  #define USE_WEBSERVER_PORT 80 // NOLINT
22
46
  #endif
23
47
 
48
+ // Define all constant strings using the macro
49
+ MDNS_STATIC_CONST_CHAR(SERVICE_ESPHOMELIB, "_esphomelib");
50
+ MDNS_STATIC_CONST_CHAR(SERVICE_TCP, "_tcp");
51
+ MDNS_STATIC_CONST_CHAR(SERVICE_PROMETHEUS, "_prometheus-http");
52
+ MDNS_STATIC_CONST_CHAR(SERVICE_HTTP, "_http");
53
+
54
+ MDNS_STATIC_CONST_CHAR(TXT_FRIENDLY_NAME, "friendly_name");
55
+ MDNS_STATIC_CONST_CHAR(TXT_VERSION, "version");
56
+ MDNS_STATIC_CONST_CHAR(TXT_MAC, "mac");
57
+ MDNS_STATIC_CONST_CHAR(TXT_PLATFORM, "platform");
58
+ MDNS_STATIC_CONST_CHAR(TXT_BOARD, "board");
59
+ MDNS_STATIC_CONST_CHAR(TXT_NETWORK, "network");
60
+ MDNS_STATIC_CONST_CHAR(TXT_API_ENCRYPTION, "api_encryption");
61
+ MDNS_STATIC_CONST_CHAR(TXT_API_ENCRYPTION_SUPPORTED, "api_encryption_supported");
62
+ MDNS_STATIC_CONST_CHAR(TXT_PROJECT_NAME, "project_name");
63
+ MDNS_STATIC_CONST_CHAR(TXT_PROJECT_VERSION, "project_version");
64
+ MDNS_STATIC_CONST_CHAR(TXT_PACKAGE_IMPORT_URL, "package_import_url");
65
+
66
+ MDNS_STATIC_CONST_CHAR(PLATFORM_ESP8266, "ESP8266");
67
+ MDNS_STATIC_CONST_CHAR(PLATFORM_ESP32, "ESP32");
68
+ MDNS_STATIC_CONST_CHAR(PLATFORM_RP2040, "RP2040");
69
+
70
+ MDNS_STATIC_CONST_CHAR(NETWORK_WIFI, "wifi");
71
+ MDNS_STATIC_CONST_CHAR(NETWORK_ETHERNET, "ethernet");
72
+ MDNS_STATIC_CONST_CHAR(NETWORK_THREAD, "thread");
73
+
24
74
  void MDNSComponent::compile_records_() {
25
75
  this->hostname_ = App.get_name();
26
76
 
27
- this->services_.clear();
77
+ // Calculate exact capacity needed for services vector
78
+ size_t services_count = 0;
79
+ #ifdef USE_API
80
+ if (api::global_api_server != nullptr) {
81
+ services_count++;
82
+ }
83
+ #endif
84
+ #ifdef USE_PROMETHEUS
85
+ services_count++;
86
+ #endif
87
+ #ifdef USE_WEBSERVER
88
+ services_count++;
89
+ #endif
90
+ #ifdef USE_MDNS_EXTRA_SERVICES
91
+ services_count += this->services_extra_.size();
92
+ #endif
93
+ // Reserve for fallback service if needed
94
+ if (services_count == 0) {
95
+ services_count = 1;
96
+ }
97
+ this->services_.reserve(services_count);
98
+
28
99
  #ifdef USE_API
29
100
  if (api::global_api_server != nullptr) {
30
- MDNSService service{};
31
- service.service_type = "_esphomelib";
32
- service.proto = "_tcp";
101
+ this->services_.emplace_back();
102
+ auto &service = this->services_.back();
103
+ service.service_type = MDNS_STR(SERVICE_ESPHOMELIB);
104
+ service.proto = MDNS_STR(SERVICE_TCP);
33
105
  service.port = api::global_api_server->get_port();
34
- if (!App.get_friendly_name().empty()) {
35
- service.txt_records.push_back({"friendly_name", App.get_friendly_name()});
106
+
107
+ const std::string &friendly_name = App.get_friendly_name();
108
+ bool friendly_name_empty = friendly_name.empty();
109
+
110
+ // Calculate exact capacity for txt_records
111
+ size_t txt_count = 3; // version, mac, board (always present)
112
+ if (!friendly_name_empty) {
113
+ txt_count++; // friendly_name
36
114
  }
37
- service.txt_records.push_back({"version", ESPHOME_VERSION});
38
- service.txt_records.push_back({"mac", get_mac_address()});
39
- const char *platform = nullptr;
40
- #ifdef USE_ESP8266
41
- platform = "ESP8266";
115
+ #if defined(USE_ESP8266) || defined(USE_ESP32) || defined(USE_RP2040) || defined(USE_LIBRETINY)
116
+ txt_count++; // platform
42
117
  #endif
43
- #ifdef USE_ESP32
44
- platform = "ESP32";
118
+ #if defined(USE_WIFI) || defined(USE_ETHERNET) || defined(USE_OPENTHREAD)
119
+ txt_count++; // network
45
120
  #endif
46
- #ifdef USE_RP2040
47
- platform = "RP2040";
121
+ #ifdef USE_API_NOISE
122
+ txt_count++; // api_encryption or api_encryption_supported
48
123
  #endif
49
- #ifdef USE_LIBRETINY
50
- platform = lt_cpu_get_model_name();
124
+ #ifdef ESPHOME_PROJECT_NAME
125
+ txt_count += 2; // project_name and project_version
51
126
  #endif
52
- if (platform != nullptr) {
53
- service.txt_records.push_back({"platform", platform});
127
+ #ifdef USE_DASHBOARD_IMPORT
128
+ txt_count++; // package_import_url
129
+ #endif
130
+
131
+ auto &txt_records = service.txt_records;
132
+ txt_records.reserve(txt_count);
133
+
134
+ if (!friendly_name_empty) {
135
+ txt_records.push_back({MDNS_STR(TXT_FRIENDLY_NAME), friendly_name});
54
136
  }
137
+ txt_records.push_back({MDNS_STR(TXT_VERSION), ESPHOME_VERSION});
138
+ txt_records.push_back({MDNS_STR(TXT_MAC), get_mac_address()});
55
139
 
56
- service.txt_records.push_back({"board", ESPHOME_BOARD});
140
+ #ifdef USE_ESP8266
141
+ txt_records.push_back({MDNS_STR(TXT_PLATFORM), MDNS_STR(PLATFORM_ESP8266)});
142
+ #elif defined(USE_ESP32)
143
+ txt_records.push_back({MDNS_STR(TXT_PLATFORM), MDNS_STR(PLATFORM_ESP32)});
144
+ #elif defined(USE_RP2040)
145
+ txt_records.push_back({MDNS_STR(TXT_PLATFORM), MDNS_STR(PLATFORM_RP2040)});
146
+ #elif defined(USE_LIBRETINY)
147
+ txt_records.emplace_back(MDNSTXTRecord{"platform", lt_cpu_get_model_name()});
148
+ #endif
149
+
150
+ txt_records.push_back({MDNS_STR(TXT_BOARD), ESPHOME_BOARD});
57
151
 
58
152
  #if defined(USE_WIFI)
59
- service.txt_records.push_back({"network", "wifi"});
153
+ txt_records.push_back({MDNS_STR(TXT_NETWORK), MDNS_STR(NETWORK_WIFI)});
60
154
  #elif defined(USE_ETHERNET)
61
- service.txt_records.push_back({"network", "ethernet"});
155
+ txt_records.push_back({MDNS_STR(TXT_NETWORK), MDNS_STR(NETWORK_ETHERNET)});
62
156
  #elif defined(USE_OPENTHREAD)
63
- service.txt_records.push_back({"network", "thread"});
157
+ txt_records.push_back({MDNS_STR(TXT_NETWORK), MDNS_STR(NETWORK_THREAD)});
64
158
  #endif
65
159
 
66
160
  #ifdef USE_API_NOISE
161
+ MDNS_STATIC_CONST_CHAR(NOISE_ENCRYPTION, "Noise_NNpsk0_25519_ChaChaPoly_SHA256");
67
162
  if (api::global_api_server->get_noise_ctx()->has_psk()) {
68
- service.txt_records.push_back({"api_encryption", "Noise_NNpsk0_25519_ChaChaPoly_SHA256"});
163
+ txt_records.push_back({MDNS_STR(TXT_API_ENCRYPTION), MDNS_STR(NOISE_ENCRYPTION)});
69
164
  } else {
70
- service.txt_records.push_back({"api_encryption_supported", "Noise_NNpsk0_25519_ChaChaPoly_SHA256"});
165
+ txt_records.push_back({MDNS_STR(TXT_API_ENCRYPTION_SUPPORTED), MDNS_STR(NOISE_ENCRYPTION)});
71
166
  }
72
167
  #endif
73
168
 
74
169
  #ifdef ESPHOME_PROJECT_NAME
75
- service.txt_records.push_back({"project_name", ESPHOME_PROJECT_NAME});
76
- service.txt_records.push_back({"project_version", ESPHOME_PROJECT_VERSION});
170
+ txt_records.push_back({MDNS_STR(TXT_PROJECT_NAME), ESPHOME_PROJECT_NAME});
171
+ txt_records.push_back({MDNS_STR(TXT_PROJECT_VERSION), ESPHOME_PROJECT_VERSION});
77
172
  #endif // ESPHOME_PROJECT_NAME
78
173
 
79
174
  #ifdef USE_DASHBOARD_IMPORT
80
- service.txt_records.push_back({"package_import_url", dashboard_import::get_package_import_url()});
175
+ txt_records.push_back({MDNS_STR(TXT_PACKAGE_IMPORT_URL), dashboard_import::get_package_import_url()});
81
176
  #endif
82
-
83
- this->services_.push_back(service);
84
177
  }
85
178
  #endif // USE_API
86
179
 
87
180
  #ifdef USE_PROMETHEUS
88
- {
89
- MDNSService service{};
90
- service.service_type = "_prometheus-http";
91
- service.proto = "_tcp";
92
- service.port = USE_WEBSERVER_PORT;
93
- this->services_.push_back(service);
94
- }
181
+ this->services_.emplace_back();
182
+ auto &prom_service = this->services_.back();
183
+ prom_service.service_type = MDNS_STR(SERVICE_PROMETHEUS);
184
+ prom_service.proto = MDNS_STR(SERVICE_TCP);
185
+ prom_service.port = USE_WEBSERVER_PORT;
95
186
  #endif
96
187
 
97
188
  #ifdef USE_WEBSERVER
98
- {
99
- MDNSService service{};
100
- service.service_type = "_http";
101
- service.proto = "_tcp";
102
- service.port = USE_WEBSERVER_PORT;
103
- this->services_.push_back(service);
104
- }
189
+ this->services_.emplace_back();
190
+ auto &web_service = this->services_.back();
191
+ web_service.service_type = MDNS_STR(SERVICE_HTTP);
192
+ web_service.proto = MDNS_STR(SERVICE_TCP);
193
+ web_service.port = USE_WEBSERVER_PORT;
105
194
  #endif
106
195
 
107
196
  #ifdef USE_MDNS_EXTRA_SERVICES
108
197
  this->services_.insert(this->services_.end(), this->services_extra_.begin(), this->services_extra_.end());
109
198
  #endif
110
199
 
111
- if (this->services_.empty()) {
112
- // Publish "http" service if not using native API
113
- // This is just to have *some* mDNS service so that .local resolution works
114
- MDNSService service{};
115
- service.service_type = "_http";
116
- service.proto = "_tcp";
117
- service.port = USE_WEBSERVER_PORT;
118
- service.txt_records.push_back({"version", ESPHOME_VERSION});
119
- this->services_.push_back(service);
120
- }
200
+ #if !defined(USE_API) && !defined(USE_PROMETHEUS) && !defined(USE_WEBSERVER) && !defined(USE_MDNS_EXTRA_SERVICES)
201
+ // Publish "http" service if not using native API or any other services
202
+ // This is just to have *some* mDNS service so that .local resolution works
203
+ this->services_.emplace_back();
204
+ auto &fallback_service = this->services_.back();
205
+ fallback_service.service_type = "_http";
206
+ fallback_service.proto = "_tcp";
207
+ fallback_service.port = USE_WEBSERVER_PORT;
208
+ fallback_service.txt_records.emplace_back(MDNSTXTRecord{"version", ESPHOME_VERSION});
209
+ #endif
121
210
  }
122
211
 
123
212
  void MDNSComponent::dump_config() {
@@ -125,6 +214,7 @@ void MDNSComponent::dump_config() {
125
214
  "mDNS:\n"
126
215
  " Hostname: %s",
127
216
  this->hostname_.c_str());
217
+ #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
128
218
  ESP_LOGV(TAG, " Services:");
129
219
  for (const auto &service : this->services_) {
130
220
  ESP_LOGV(TAG, " - %s, %s, %d", service.service_type.c_str(), service.proto.c_str(),
@@ -134,6 +224,7 @@ void MDNSComponent::dump_config() {
134
224
  const_cast<TemplatableValue<std::string> &>(record.value).value().c_str());
135
225
  }
136
226
  }
227
+ #endif
137
228
  }
138
229
 
139
230
  std::vector<MDNSService> MDNSComponent::get_services() { return this->services_; }
@@ -14,7 +14,7 @@ from esphome.const import (
14
14
  )
15
15
  from esphome.core import CORE
16
16
  from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
17
- from esphome.coroutine import coroutine_with_priority
17
+ from esphome.coroutine import CoroPriority, coroutine_with_priority
18
18
  from esphome.cpp_generator import MockObjClass
19
19
 
20
20
  CODEOWNERS = ["@jesserockz"]
@@ -303,7 +303,7 @@ async def media_player_volume_set_action(config, action_id, template_arg, args):
303
303
  return var
304
304
 
305
305
 
306
- @coroutine_with_priority(100.0)
306
+ @coroutine_with_priority(CoroPriority.CORE)
307
307
  async def to_code(config):
308
308
  cg.add_global(media_player_ns.using)
309
309
  cg.add_define("USE_MEDIA_PLAYER")
@@ -201,7 +201,7 @@ def _validate_manifest_version(manifest_data):
201
201
  else:
202
202
  raise cv.Invalid("Invalid manifest version")
203
203
  else:
204
- raise cv.Invalid("Invalid manifest file, missing 'version' key.")
204
+ raise cv.Invalid("Invalid manifest file, missing 'version' key")
205
205
 
206
206
 
207
207
  def _process_http_source(config):
@@ -421,7 +421,7 @@ def _feature_step_size_validate(config):
421
421
  if features_step_size is None:
422
422
  features_step_size = model_step_size
423
423
  elif features_step_size != model_step_size:
424
- raise cv.Invalid("Cannot load models with different features step sizes.")
424
+ raise cv.Invalid("Cannot load models with different features step sizes")
425
425
 
426
426
 
427
427
  FINAL_VALIDATE_SCHEMA = cv.All(
@@ -12,7 +12,7 @@ from esphome.const import (
12
12
  CONF_TRIGGER_ID,
13
13
  )
14
14
  from esphome.core import CORE
15
- from esphome.coroutine import coroutine_with_priority
15
+ from esphome.coroutine import CoroPriority, coroutine_with_priority
16
16
 
17
17
  AUTO_LOAD = ["audio"]
18
18
  CODEOWNERS = ["@jesserockz", "@kahrendt"]
@@ -213,7 +213,7 @@ automation.register_condition(
213
213
  )(microphone_action)
214
214
 
215
215
 
216
- @coroutine_with_priority(100.0)
216
+ @coroutine_with_priority(CoroPriority.CORE)
217
217
  async def to_code(config):
218
218
  cg.add_global(microphone_ns.using)
219
219
  cg.add_define("USE_MICROPHONE")
@@ -2,7 +2,7 @@
2
2
  # Various configuration constants for MIPI displays
3
3
  # Various utility functions for MIPI DBI configuration
4
4
 
5
- from typing import Any
5
+ from typing import Any, Self
6
6
 
7
7
  from esphome.components.const import CONF_COLOR_DEPTH
8
8
  from esphome.components.display import CONF_SHOW_TEST_CARD, display_ns
@@ -222,7 +222,13 @@ def delay(ms):
222
222
 
223
223
 
224
224
  class DriverChip:
225
- models = {}
225
+ """
226
+ A class representing a MIPI DBI driver chip model.
227
+ The parameters supplied as defaults will be used to provide default values for the display configuration.
228
+ Setting swap_xy to cv.UNDEFINED will indicate that the model does not support swapping X and Y axes.
229
+ """
230
+
231
+ models: dict[str, Self] = {}
226
232
 
227
233
  def __init__(
228
234
  self,
@@ -232,7 +238,7 @@ class DriverChip:
232
238
  ):
233
239
  name = name.upper()
234
240
  self.name = name
235
- self.initsequence = initsequence or defaults.get("init_sequence")
241
+ self.initsequence = initsequence
236
242
  self.defaults = defaults
237
243
  DriverChip.models[name] = self
238
244
 
@@ -246,6 +252,17 @@ class DriverChip:
246
252
  return models
247
253
 
248
254
  def extend(self, name, **kwargs) -> "DriverChip":
255
+ """
256
+ Extend the current model with additional parameters or a modified init sequence.
257
+ Parameters supplied here will override the defaults of the current model.
258
+ if the initsequence is not provided, the current model's initsequence will be used.
259
+ If add_init_sequence is provided, it will be appended to the current initsequence.
260
+ :param name:
261
+ :param kwargs:
262
+ :return:
263
+ """
264
+ initsequence = list(kwargs.pop("initsequence", self.initsequence))
265
+ initsequence.extend(kwargs.pop("add_init_sequence", ()))
249
266
  defaults = self.defaults.copy()
250
267
  if (
251
268
  CONF_WIDTH in defaults
@@ -260,23 +277,39 @@ class DriverChip:
260
277
  ):
261
278
  defaults[CONF_NATIVE_HEIGHT] = defaults[CONF_HEIGHT]
262
279
  defaults.update(kwargs)
263
- return DriverChip(name, initsequence=self.initsequence, **defaults)
280
+ return self.__class__(name, initsequence=tuple(initsequence), **defaults)
264
281
 
265
282
  def get_default(self, key, fallback: Any = False) -> Any:
266
283
  return self.defaults.get(key, fallback)
267
284
 
285
+ @property
286
+ def transforms(self) -> set[str]:
287
+ """
288
+ Return the available transforms for this model.
289
+ """
290
+ if self.get_default("no_transform", False):
291
+ return set()
292
+ if self.get_default(CONF_SWAP_XY) != cv.UNDEFINED:
293
+ return {CONF_MIRROR_X, CONF_MIRROR_Y, CONF_SWAP_XY}
294
+ return {CONF_MIRROR_X, CONF_MIRROR_Y}
295
+
268
296
  def option(self, name, fallback=False) -> cv.Optional:
269
297
  return cv.Optional(name, default=self.get_default(name, fallback))
270
298
 
271
299
  def rotation_as_transform(self, config) -> bool:
272
300
  """
273
301
  Check if a rotation can be implemented in hardware using the MADCTL register.
274
- A rotation of 180 is always possible, 90 and 270 are possible if the model supports swapping X and Y.
302
+ A rotation of 180 is always possible if x and y mirroring are supported, 90 and 270 are possible if the model supports swapping X and Y.
275
303
  """
304
+ transforms = self.transforms
276
305
  rotation = config.get(CONF_ROTATION, 0)
277
- return rotation and (
278
- self.get_default(CONF_SWAP_XY) != cv.UNDEFINED or rotation == 180
279
- )
306
+ if rotation == 0 or not transforms:
307
+ return False
308
+ if rotation == 180:
309
+ return CONF_MIRROR_X in transforms and CONF_MIRROR_Y in transforms
310
+ if rotation == 90:
311
+ return CONF_SWAP_XY in transforms and CONF_MIRROR_X in transforms
312
+ return CONF_SWAP_XY in transforms and CONF_MIRROR_Y in transforms
280
313
 
281
314
  def get_dimensions(self, config) -> tuple[int, int, int, int]:
282
315
  if CONF_DIMENSIONS in config:
@@ -301,10 +334,10 @@ class DriverChip:
301
334
 
302
335
  # if mirroring axes and there are offsets, also mirror the offsets to cater for situations where
303
336
  # the offset is asymmetric
304
- if transform[CONF_MIRROR_X]:
337
+ if transform.get(CONF_MIRROR_X):
305
338
  native_width = self.get_default(CONF_NATIVE_WIDTH, width + offset_width * 2)
306
339
  offset_width = native_width - width - offset_width
307
- if transform[CONF_MIRROR_Y]:
340
+ if transform.get(CONF_MIRROR_Y):
308
341
  native_height = self.get_default(
309
342
  CONF_NATIVE_HEIGHT, height + offset_height * 2
310
343
  )
@@ -314,7 +347,7 @@ class DriverChip:
314
347
  90,
315
348
  270,
316
349
  )
317
- if transform[CONF_SWAP_XY] is True or rotated:
350
+ if transform.get(CONF_SWAP_XY) is True or rotated:
318
351
  width, height = height, width
319
352
  offset_height, offset_width = offset_width, offset_height
320
353
  return width, height, offset_width, offset_height
@@ -324,27 +357,50 @@ class DriverChip:
324
357
  transform = config.get(
325
358
  CONF_TRANSFORM,
326
359
  {
327
- CONF_MIRROR_X: self.get_default(CONF_MIRROR_X, False),
328
- CONF_MIRROR_Y: self.get_default(CONF_MIRROR_Y, False),
329
- CONF_SWAP_XY: self.get_default(CONF_SWAP_XY, False),
360
+ CONF_MIRROR_X: self.get_default(CONF_MIRROR_X),
361
+ CONF_MIRROR_Y: self.get_default(CONF_MIRROR_Y),
362
+ CONF_SWAP_XY: self.get_default(CONF_SWAP_XY),
330
363
  },
331
364
  )
365
+ # fill in defaults if not provided
366
+ mirror_x = transform.get(CONF_MIRROR_X, self.get_default(CONF_MIRROR_X))
367
+ mirror_y = transform.get(CONF_MIRROR_Y, self.get_default(CONF_MIRROR_Y))
368
+ swap_xy = transform.get(CONF_SWAP_XY, self.get_default(CONF_SWAP_XY))
369
+ transform[CONF_MIRROR_X] = mirror_x
370
+ transform[CONF_MIRROR_Y] = mirror_y
371
+ transform[CONF_SWAP_XY] = swap_xy
332
372
 
333
373
  # Can we use the MADCTL register to set the rotation?
334
374
  if can_transform and CONF_TRANSFORM not in config:
335
375
  rotation = config[CONF_ROTATION]
336
376
  if rotation == 180:
337
- transform[CONF_MIRROR_X] = not transform[CONF_MIRROR_X]
338
- transform[CONF_MIRROR_Y] = not transform[CONF_MIRROR_Y]
377
+ transform[CONF_MIRROR_X] = not mirror_x
378
+ transform[CONF_MIRROR_Y] = not mirror_y
339
379
  elif rotation == 90:
340
- transform[CONF_SWAP_XY] = not transform[CONF_SWAP_XY]
341
- transform[CONF_MIRROR_X] = not transform[CONF_MIRROR_X]
380
+ transform[CONF_SWAP_XY] = not swap_xy
381
+ transform[CONF_MIRROR_X] = not mirror_x
342
382
  else:
343
- transform[CONF_SWAP_XY] = not transform[CONF_SWAP_XY]
344
- transform[CONF_MIRROR_Y] = not transform[CONF_MIRROR_Y]
383
+ transform[CONF_SWAP_XY] = not swap_xy
384
+ transform[CONF_MIRROR_Y] = not mirror_y
345
385
  transform[CONF_TRANSFORM] = True
346
386
  return transform
347
387
 
388
+ def add_madctl(self, sequence: list, config: dict):
389
+ # Add the MADCTL command to the sequence based on the configuration.
390
+ use_flip = config.get(CONF_USE_AXIS_FLIPS)
391
+ madctl = 0
392
+ transform = self.get_transform(config)
393
+ if transform[CONF_MIRROR_X]:
394
+ madctl |= MADCTL_XFLIP if use_flip else MADCTL_MX
395
+ if transform[CONF_MIRROR_Y]:
396
+ madctl |= MADCTL_YFLIP if use_flip else MADCTL_MY
397
+ if transform.get(CONF_SWAP_XY) is True: # Exclude Undefined
398
+ madctl |= MADCTL_MV
399
+ if config[CONF_COLOR_ORDER] == MODE_BGR:
400
+ madctl |= MADCTL_BGR
401
+ sequence.append((MADCTL, madctl))
402
+ return madctl
403
+
348
404
  def get_sequence(self, config) -> tuple[tuple[int, ...], int]:
349
405
  """
350
406
  Create the init sequence for the display.
@@ -367,21 +423,9 @@ class DriverChip:
367
423
  pixel_mode = PIXEL_MODES[pixel_mode]
368
424
  sequence.append((PIXFMT, pixel_mode))
369
425
 
370
- # Does the chip use the flipping bits for mirroring rather than the reverse order bits?
371
- use_flip = config.get(CONF_USE_AXIS_FLIPS)
372
- madctl = 0
373
- transform = self.get_transform(config)
374
426
  if self.rotation_as_transform(config):
375
427
  LOGGER.info("Using hardware transform to implement rotation")
376
- if transform.get(CONF_MIRROR_X):
377
- madctl |= MADCTL_XFLIP if use_flip else MADCTL_MX
378
- if transform.get(CONF_MIRROR_Y):
379
- madctl |= MADCTL_YFLIP if use_flip else MADCTL_MY
380
- if transform.get(CONF_SWAP_XY) is True: # Exclude Undefined
381
- madctl |= MADCTL_MV
382
- if config[CONF_COLOR_ORDER] == MODE_BGR:
383
- madctl |= MADCTL_BGR
384
- sequence.append((MADCTL, madctl))
428
+ madctl = self.add_madctl(sequence, config)
385
429
  if config[CONF_INVERT_COLORS]:
386
430
  sequence.append((INVON,))
387
431
  else:
@@ -0,0 +1,2 @@
1
+ CODEOWNERS = ["@clydebarrow"]
2
+ DOMAIN = "mipi_rgb"