esphome 2024.7.3__py3-none-any.whl → 2024.8.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 (341) hide show
  1. esphome/__main__.py +15 -81
  2. esphome/automation.py +1 -1
  3. esphome/codegen.py +53 -53
  4. esphome/components/ade7953/sensor.py +1 -1
  5. esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
  6. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +5 -2
  7. esphome/components/airthings_wave_plus/airthings_wave_plus.h +2 -0
  8. esphome/components/airthings_wave_plus/sensor.py +12 -0
  9. esphome/components/alarm_control_panel/__init__.py +75 -66
  10. esphome/components/apds9306/__init__.py +4 -0
  11. esphome/components/apds9306/apds9306.cpp +151 -0
  12. esphome/components/apds9306/apds9306.h +66 -0
  13. esphome/components/apds9306/sensor.py +95 -0
  14. esphome/components/api/__init__.py +79 -51
  15. esphome/components/api/api_connection.cpp +14 -1
  16. esphome/components/api/api_pb2.cpp +33 -4
  17. esphome/components/api/api_pb2.h +8 -1
  18. esphome/components/api/api_server.cpp +10 -0
  19. esphome/components/api/api_server.h +3 -0
  20. esphome/components/atm90e32/__init__.py +7 -0
  21. esphome/components/atm90e32/atm90e32.cpp +68 -16
  22. esphome/components/atm90e32/atm90e32.h +20 -7
  23. esphome/components/atm90e32/atm90e32_reg.h +2 -0
  24. esphome/components/atm90e32/button/__init__.py +43 -0
  25. esphome/components/atm90e32/button/atm90e32_button.cpp +20 -0
  26. esphome/components/atm90e32/button/atm90e32_button.h +27 -0
  27. esphome/components/atm90e32/sensor.py +15 -11
  28. esphome/components/bedjet/bedjet_codec.h +1 -1
  29. esphome/components/binary/light/binary_light_output.h +3 -2
  30. esphome/components/binary_sensor/__init__.py +5 -5
  31. esphome/components/ble_client/__init__.py +3 -3
  32. esphome/components/ble_client/output/__init__.py +1 -1
  33. esphome/components/ble_client/sensor/__init__.py +4 -3
  34. esphome/components/ble_client/switch/__init__.py +2 -1
  35. esphome/components/ble_client/text_sensor/__init__.py +4 -3
  36. esphome/components/ble_presence/binary_sensor.py +3 -3
  37. esphome/components/ble_rssi/sensor.py +2 -2
  38. esphome/components/ble_scanner/text_sensor.py +1 -1
  39. esphome/components/bluetooth_proxy/__init__.py +3 -3
  40. esphome/components/bme68x_bsec2/__init__.py +196 -0
  41. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +523 -0
  42. esphome/components/bme68x_bsec2/bme68x_bsec2.h +163 -0
  43. esphome/components/bme68x_bsec2/sensor.py +130 -0
  44. esphome/components/bme68x_bsec2/text_sensor.py +33 -0
  45. esphome/components/bme68x_bsec2_i2c/__init__.py +28 -0
  46. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +53 -0
  47. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.h +28 -0
  48. esphome/components/bmp3xx/sensor.py +1 -1
  49. esphome/components/button/__init__.py +4 -4
  50. esphome/components/climate/__init__.py +5 -5
  51. esphome/components/climate/climate.h +1 -1
  52. esphome/components/cover/__init__.py +8 -8
  53. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +11 -7
  54. esphome/components/cst226/touchscreen/cst226_touchscreen.h +1 -1
  55. esphome/components/datetime/__init__.py +11 -13
  56. esphome/components/demo/demo_sensor.h +3 -2
  57. esphome/components/display/display.cpp +31 -0
  58. esphome/components/display/display.h +3 -0
  59. esphome/components/display_menu_base/__init__.py +14 -13
  60. esphome/components/ens160/sensor.py +1 -1
  61. esphome/components/esp32/__init__.py +9 -10
  62. esphome/components/esp32/boards.py +1 -1
  63. esphome/components/esp32/gpio.py +12 -13
  64. esphome/components/esp32/gpio_esp32.py +1 -2
  65. esphome/components/esp32/gpio_esp32_c2.py +1 -2
  66. esphome/components/esp32/gpio_esp32_c3.py +1 -5
  67. esphome/components/esp32/gpio_esp32_c6.py +1 -2
  68. esphome/components/esp32/gpio_esp32_h2.py +1 -2
  69. esphome/components/esp32/gpio_esp32_s2.py +1 -2
  70. esphome/components/esp32/gpio_esp32_s3.py +1 -6
  71. esphome/components/esp32_ble/__init__.py +20 -3
  72. esphome/components/esp32_ble/ble.cpp +9 -1
  73. esphome/components/esp32_ble/ble.h +9 -0
  74. esphome/components/esp32_ble/ble_advertising.cpp +42 -9
  75. esphome/components/esp32_ble/ble_advertising.h +21 -1
  76. esphome/components/esp32_ble_beacon/__init__.py +17 -7
  77. esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +45 -113
  78. esphome/components/esp32_ble_beacon/esp32_ble_beacon.h +17 -19
  79. esphome/components/esp32_ble_client/__init__.py +0 -1
  80. esphome/components/esp32_ble_server/__init__.py +2 -3
  81. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  82. esphome/components/esp32_improv/__init__.py +2 -4
  83. esphome/components/ethernet/__init__.py +17 -17
  84. esphome/components/ethernet_info/text_sensor.py +2 -2
  85. esphome/components/event/__init__.py +5 -5
  86. esphome/components/fan/__init__.py +14 -14
  87. esphome/components/fan/fan.cpp +2 -2
  88. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  89. esphome/components/fingerprint_grow/fingerprint_grow.h +1 -1
  90. esphome/components/graphical_display_menu/__init__.py +11 -8
  91. esphome/components/haier/haier_base.h +2 -2
  92. esphome/components/homeassistant/__init__.py +8 -1
  93. esphome/components/homeassistant/number/__init__.py +33 -0
  94. esphome/components/homeassistant/number/homeassistant_number.cpp +100 -0
  95. esphome/components/homeassistant/number/homeassistant_number.h +31 -0
  96. esphome/components/homeassistant/switch/__init__.py +30 -0
  97. esphome/components/homeassistant/switch/homeassistant_switch.cpp +59 -0
  98. esphome/components/homeassistant/switch/homeassistant_switch.h +22 -0
  99. esphome/components/http_request/__init__.py +12 -1
  100. esphome/components/http_request/http_request_arduino.cpp +2 -2
  101. esphome/components/http_request/http_request_idf.cpp +11 -2
  102. esphome/components/http_request/http_request_idf.h +10 -0
  103. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  104. esphome/components/http_request/update/http_request_update.cpp +2 -2
  105. esphome/components/http_request/update/http_request_update.h +2 -1
  106. esphome/components/hx711/hx711.cpp +10 -1
  107. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +1 -1
  108. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +11 -2
  109. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +2 -0
  110. esphome/components/ili9xxx/ili9xxx_defines.h +3 -1
  111. esphome/components/ili9xxx/ili9xxx_display.cpp +9 -22
  112. esphome/components/ili9xxx/ili9xxx_display.h +5 -7
  113. esphome/components/ili9xxx/ili9xxx_init.h +4 -4
  114. esphome/components/improv_base/__init__.py +2 -3
  115. esphome/components/improv_serial/__init__.py +4 -10
  116. esphome/components/improv_serial/improv_serial_component.cpp +4 -0
  117. esphome/components/jsn_sr04t/jsn_sr04t.cpp +18 -1
  118. esphome/components/jsn_sr04t/jsn_sr04t.h +7 -1
  119. esphome/components/jsn_sr04t/sensor.py +13 -0
  120. esphome/components/kalman_combinator/sensor.py +1 -1
  121. esphome/components/light/__init__.py +16 -15
  122. esphome/components/light/addressable_light_effect.h +12 -8
  123. esphome/components/light/automation.h +16 -1
  124. esphome/components/light/automation.py +21 -0
  125. esphome/components/light/base_light_effects.h +5 -5
  126. esphome/components/light/types.py +7 -0
  127. esphome/components/lock/__init__.py +3 -3
  128. esphome/components/logger/__init__.py +15 -18
  129. esphome/components/lvgl/__init__.py +346 -0
  130. esphome/components/lvgl/automation.py +226 -0
  131. esphome/components/lvgl/binary_sensor/__init__.py +43 -0
  132. esphome/components/lvgl/defines.py +504 -0
  133. esphome/components/lvgl/encoders.py +77 -0
  134. esphome/components/lvgl/font.cpp +76 -0
  135. esphome/components/lvgl/helpers.py +49 -0
  136. esphome/components/lvgl/light/__init__.py +32 -0
  137. esphome/components/lvgl/light/lvgl_light.h +48 -0
  138. esphome/components/lvgl/lv_validation.py +279 -0
  139. esphome/components/lvgl/lvcode.py +349 -0
  140. esphome/components/lvgl/lvgl_esphome.cpp +407 -0
  141. esphome/components/lvgl/lvgl_esphome.h +274 -0
  142. esphome/components/lvgl/lvgl_hal.h +21 -0
  143. esphome/components/lvgl/number/__init__.py +66 -0
  144. esphome/components/lvgl/number/lvgl_number.h +34 -0
  145. esphome/components/lvgl/schemas.py +426 -0
  146. esphome/components/lvgl/select/__init__.py +55 -0
  147. esphome/components/lvgl/select/lvgl_select.h +62 -0
  148. esphome/components/lvgl/sensor/__init__.py +47 -0
  149. esphome/components/lvgl/styles.py +58 -0
  150. esphome/components/lvgl/switch/__init__.py +56 -0
  151. esphome/components/lvgl/switch/lvgl_switch.h +34 -0
  152. esphome/components/lvgl/text/__init__.py +50 -0
  153. esphome/components/lvgl/text/lvgl_text.h +34 -0
  154. esphome/components/lvgl/text_sensor/__init__.py +42 -0
  155. esphome/components/lvgl/touchscreens.py +45 -0
  156. esphome/components/lvgl/trigger.py +74 -0
  157. esphome/components/lvgl/types.py +191 -0
  158. esphome/components/lvgl/widgets/__init__.py +400 -0
  159. esphome/components/lvgl/widgets/animimg.py +117 -0
  160. esphome/components/lvgl/widgets/arc.py +78 -0
  161. esphome/components/lvgl/widgets/button.py +20 -0
  162. esphome/components/lvgl/widgets/buttonmatrix.py +275 -0
  163. esphome/components/lvgl/widgets/checkbox.py +27 -0
  164. esphome/components/lvgl/widgets/dropdown.py +76 -0
  165. esphome/components/lvgl/widgets/img.py +85 -0
  166. esphome/components/lvgl/widgets/keyboard.py +49 -0
  167. esphome/components/lvgl/widgets/label.py +42 -0
  168. esphome/components/lvgl/widgets/led.py +29 -0
  169. esphome/components/lvgl/widgets/line.py +50 -0
  170. esphome/components/lvgl/widgets/lv_bar.py +55 -0
  171. esphome/components/lvgl/widgets/meter.py +302 -0
  172. esphome/components/lvgl/widgets/msgbox.py +134 -0
  173. esphome/components/lvgl/widgets/obj.py +28 -0
  174. esphome/components/lvgl/widgets/page.py +113 -0
  175. esphome/components/lvgl/widgets/roller.py +77 -0
  176. esphome/components/lvgl/widgets/slider.py +63 -0
  177. esphome/components/lvgl/widgets/spinbox.py +178 -0
  178. esphome/components/lvgl/widgets/spinner.py +43 -0
  179. esphome/components/lvgl/widgets/switch.py +20 -0
  180. esphome/components/lvgl/widgets/tabview.py +114 -0
  181. esphome/components/lvgl/widgets/textarea.py +66 -0
  182. esphome/components/lvgl/widgets/tileview.py +128 -0
  183. esphome/components/m5stack_8angle/__init__.py +33 -0
  184. esphome/components/m5stack_8angle/binary_sensor/__init__.py +30 -0
  185. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +17 -0
  186. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.h +19 -0
  187. esphome/components/m5stack_8angle/light/__init__.py +31 -0
  188. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +45 -0
  189. esphome/components/m5stack_8angle/light/m5stack_8angle_light.h +37 -0
  190. esphome/components/m5stack_8angle/m5stack_8angle.cpp +74 -0
  191. esphome/components/m5stack_8angle/m5stack_8angle.h +34 -0
  192. esphome/components/m5stack_8angle/sensor/__init__.py +66 -0
  193. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +24 -0
  194. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.h +27 -0
  195. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -0
  196. esphome/components/max31856/sensor.py +5 -5
  197. esphome/components/media_player/__init__.py +3 -5
  198. esphome/components/media_player/automation.h +31 -27
  199. esphome/components/micro_wake_word/__init__.py +20 -25
  200. esphome/components/modbus_controller/__init__.py +26 -2
  201. esphome/components/modbus_controller/automation.h +19 -0
  202. esphome/components/modbus_controller/const.py +1 -0
  203. esphome/components/modbus_controller/modbus_controller.cpp +8 -0
  204. esphome/components/modbus_controller/modbus_controller.h +3 -0
  205. esphome/components/mqtt/__init__.py +20 -9
  206. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +128 -0
  207. esphome/components/mqtt/mqtt_alarm_control_panel.h +39 -0
  208. esphome/components/mqtt/mqtt_backend.h +3 -1
  209. esphome/components/mqtt/mqtt_backend_esp32.cpp +4 -1
  210. esphome/components/mqtt/mqtt_backend_esp32.h +3 -1
  211. esphome/components/mqtt/mqtt_backend_esp8266.h +3 -1
  212. esphome/components/mqtt/mqtt_backend_libretiny.h +3 -1
  213. esphome/components/mqtt/mqtt_client.cpp +16 -3
  214. esphome/components/mqtt/mqtt_client.h +5 -1
  215. esphome/components/mqtt/mqtt_component.cpp +32 -4
  216. esphome/components/mqtt/mqtt_const.h +2 -0
  217. esphome/components/network/__init__.py +10 -11
  218. esphome/components/network/ip_address.h +3 -0
  219. esphome/components/network/util.cpp +2 -1
  220. esphome/components/network/util.h +3 -1
  221. esphome/components/nextion/base_component.py +5 -8
  222. esphome/components/number/__init__.py +7 -8
  223. esphome/components/online_image/__init__.py +167 -0
  224. esphome/components/online_image/image_decoder.cpp +44 -0
  225. esphome/components/online_image/image_decoder.h +112 -0
  226. esphome/components/online_image/online_image.cpp +283 -0
  227. esphome/components/online_image/online_image.h +195 -0
  228. esphome/components/online_image/png_image.cpp +68 -0
  229. esphome/components/online_image/png_image.h +33 -0
  230. esphome/components/ota/__init__.py +8 -4
  231. esphome/components/pid/pid_climate.h +2 -0
  232. esphome/components/remote_transmitter/remote_transmitter.h +1 -1
  233. esphome/components/rgbct/rgbct_light_output.h +3 -2
  234. esphome/components/rgbw/rgbw_light_output.h +3 -2
  235. esphome/components/rgbww/rgbww_light_output.h +3 -2
  236. esphome/components/select/__init__.py +7 -7
  237. esphome/components/sensor/__init__.py +29 -10
  238. esphome/components/sensor/filter.cpp +8 -0
  239. esphome/components/sensor/filter.h +9 -0
  240. esphome/components/sml/sml_parser.cpp +48 -22
  241. esphome/components/socket/socket.cpp +11 -14
  242. esphome/components/speaker/__init__.py +14 -5
  243. esphome/components/speaker/automation.h +10 -0
  244. esphome/components/speaker/speaker.h +5 -0
  245. esphome/components/spi/spi.cpp +0 -6
  246. esphome/components/spi/spi.h +2 -19
  247. esphome/components/spi_led_strip/spi_led_strip.h +5 -4
  248. esphome/components/sprinkler/sprinkler.cpp +2 -2
  249. esphome/components/sprinkler/sprinkler.h +1 -1
  250. esphome/components/switch/__init__.py +3 -3
  251. esphome/components/text/__init__.py +5 -5
  252. esphome/components/text_sensor/__init__.py +7 -7
  253. esphome/components/time/__init__.py +8 -8
  254. esphome/components/touchscreen/binary_sensor/__init__.py +24 -10
  255. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.cpp +3 -2
  256. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.h +4 -2
  257. esphome/components/uart/uart_component_host.cpp +6 -2
  258. esphome/components/update/__init__.py +33 -15
  259. esphome/components/update/automation.h +23 -0
  260. esphome/components/update/update_entity.h +3 -1
  261. esphome/components/valve/__init__.py +3 -3
  262. esphome/components/voice_assistant/__init__.py +7 -8
  263. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -0
  264. esphome/components/wake_on_lan/wake_on_lan.h +3 -1
  265. esphome/components/watchdog/__init__.py +1 -0
  266. esphome/components/{http_request → watchdog}/watchdog.cpp +0 -2
  267. esphome/components/{http_request → watchdog}/watchdog.h +0 -2
  268. esphome/components/web_server/server_index_v3.h +3615 -3603
  269. esphome/components/web_server/web_server.cpp +0 -209
  270. esphome/components/web_server/web_server.h +1 -1
  271. esphome/components/web_server/web_server_v1.cpp +217 -0
  272. esphome/components/web_server_base/web_server_base.h +1 -0
  273. esphome/components/wifi/__init__.py +15 -14
  274. esphome/components/wifi/wifi_component.cpp +2 -0
  275. esphome/components/wifi/wifi_component.h +7 -1
  276. esphome/components/wifi/wifi_component_esp32_arduino.cpp +5 -2
  277. esphome/components/wifi/wifi_component_esp8266.cpp +2 -0
  278. esphome/components/wifi/wifi_component_esp_idf.cpp +43 -7
  279. esphome/components/wifi/wifi_component_libretiny.cpp +2 -0
  280. esphome/components/wifi/wifi_component_pico_w.cpp +2 -0
  281. esphome/components/wifi/wpa2_eap.py +6 -7
  282. esphome/components/wifi_info/text_sensor.py +3 -3
  283. esphome/components/wifi_info/wifi_info_text_sensor.cpp +2 -0
  284. esphome/components/wifi_info/wifi_info_text_sensor.h +2 -0
  285. esphome/components/wifi_signal/sensor.py +1 -1
  286. esphome/components/wifi_signal/wifi_signal_sensor.cpp +2 -0
  287. esphome/components/wifi_signal/wifi_signal_sensor.h +2 -1
  288. esphome/components/xiaomi_ble/xiaomi_ble.cpp +20 -3
  289. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  290. esphome/components/xiaomi_lywsd02mmc/__init__.py +0 -0
  291. esphome/components/xiaomi_lywsd02mmc/sensor.py +77 -0
  292. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +73 -0
  293. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +37 -0
  294. esphome/config.py +17 -19
  295. esphome/config_validation.py +41 -23
  296. esphome/const.py +25 -9
  297. esphome/core/__init__.py +17 -14
  298. esphome/core/application.h +42 -21
  299. esphome/core/automation.h +5 -3
  300. esphome/core/base_automation.h +3 -2
  301. esphome/core/bytebuffer.cpp +134 -0
  302. esphome/core/bytebuffer.h +96 -0
  303. esphome/core/color.h +24 -16
  304. esphome/core/config.py +3 -3
  305. esphome/core/defines.h +14 -1
  306. esphome/core/entity_base.h +2 -2
  307. esphome/core/entity_helpers.py +1 -2
  308. esphome/core/gpio.h +0 -18
  309. esphome/core/helpers.h +1 -1
  310. esphome/core/optional.h +15 -16
  311. esphome/coroutine.py +1 -1
  312. esphome/cpp_generator.py +1 -1
  313. esphome/cpp_helpers.py +3 -5
  314. esphome/dashboard/core.py +3 -3
  315. esphome/dashboard/dashboard.py +3 -3
  316. esphome/dashboard/entries.py +1 -1
  317. esphome/dashboard/util/file.py +1 -1
  318. esphome/dashboard/web_server.py +3 -3
  319. esphome/external_files.py +5 -3
  320. esphome/final_validate.py +2 -2
  321. esphome/git.py +4 -4
  322. esphome/helpers.py +5 -5
  323. esphome/loader.py +15 -10
  324. esphome/mqtt.py +4 -8
  325. esphome/pins.py +6 -6
  326. esphome/platformio_api.py +5 -5
  327. esphome/storage_json.py +2 -1
  328. esphome/types.py +1 -1
  329. esphome/util.py +2 -3
  330. esphome/voluptuous_schema.py +1 -0
  331. esphome/vscode.py +5 -4
  332. esphome/wizard.py +1 -1
  333. esphome/writer.py +7 -7
  334. esphome/yaml_util.py +3 -3
  335. esphome/zeroconf.py +1 -1
  336. {esphome-2024.7.3.dist-info → esphome-2024.8.0b1.dist-info}/METADATA +3 -3
  337. {esphome-2024.7.3.dist-info → esphome-2024.8.0b1.dist-info}/RECORD +341 -235
  338. {esphome-2024.7.3.dist-info → esphome-2024.8.0b1.dist-info}/LICENSE +0 -0
  339. {esphome-2024.7.3.dist-info → esphome-2024.8.0b1.dist-info}/WHEEL +0 -0
  340. {esphome-2024.7.3.dist-info → esphome-2024.8.0b1.dist-info}/entry_points.txt +0 -0
  341. {esphome-2024.7.3.dist-info → esphome-2024.8.0b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,195 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/component.h"
4
+ #include "esphome/core/defines.h"
5
+ #include "esphome/core/helpers.h"
6
+ #include "esphome/components/http_request/http_request.h"
7
+ #include "esphome/components/image/image.h"
8
+
9
+ #include "image_decoder.h"
10
+
11
+ namespace esphome {
12
+ namespace online_image {
13
+
14
+ using t_http_codes = enum {
15
+ HTTP_CODE_OK = 200,
16
+ HTTP_CODE_NOT_MODIFIED = 304,
17
+ HTTP_CODE_NOT_FOUND = 404,
18
+ };
19
+
20
+ /**
21
+ * @brief Format that the image is encoded with.
22
+ */
23
+ enum ImageFormat {
24
+ /** Automatically detect from MIME type. Not supported yet. */
25
+ AUTO,
26
+ /** JPEG format. Not supported yet. */
27
+ JPEG,
28
+ /** PNG format. */
29
+ PNG,
30
+ };
31
+
32
+ /**
33
+ * @brief Download an image from a given URL, and decode it using the specified decoder.
34
+ * The image will then be stored in a buffer, so that it can be re-displayed without the
35
+ * need to re-download or re-decode.
36
+ */
37
+ class OnlineImage : public PollingComponent,
38
+ public image::Image,
39
+ public Parented<esphome::http_request::HttpRequestComponent> {
40
+ public:
41
+ /**
42
+ * @brief Construct a new OnlineImage object.
43
+ *
44
+ * @param url URL to download the image from.
45
+ * @param width Desired width of the target image area.
46
+ * @param height Desired height of the target image area.
47
+ * @param format Format that the image is encoded in (@see ImageFormat).
48
+ * @param buffer_size Size of the buffer used to download the image.
49
+ */
50
+ OnlineImage(const std::string &url, int width, int height, ImageFormat format, image::ImageType type,
51
+ uint32_t buffer_size);
52
+
53
+ void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override;
54
+
55
+ void update() override;
56
+ void loop() override;
57
+
58
+ /** Set the URL to download the image from. */
59
+ void set_url(const std::string &url) {
60
+ if (this->validate_url_(url)) {
61
+ this->url_ = url;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * @brief Set the image that needs to be shown as long as the downloaded image
67
+ * is not available.
68
+ *
69
+ * @param placeholder Pointer to the (@link Image) to show as placeholder.
70
+ */
71
+ void set_placeholder(image::Image *placeholder) { this->placeholder_ = placeholder; }
72
+
73
+ /**
74
+ * Release the buffer storing the image. The image will need to be downloaded again
75
+ * to be able to be displayed.
76
+ */
77
+ void release();
78
+
79
+ void add_on_finished_callback(std::function<void()> &&callback);
80
+ void add_on_error_callback(std::function<void()> &&callback);
81
+
82
+ protected:
83
+ bool validate_url_(const std::string &url);
84
+
85
+ using Allocator = ExternalRAMAllocator<uint8_t>;
86
+ Allocator allocator_{Allocator::Flags::ALLOW_FAILURE};
87
+
88
+ uint32_t get_buffer_size_() const { return get_buffer_size_(this->buffer_width_, this->buffer_height_); }
89
+ int get_buffer_size_(int width, int height) const {
90
+ return std::ceil(image::image_type_to_bpp(this->type_) * width * height / 8.0);
91
+ }
92
+
93
+ int get_position_(int x, int y) const {
94
+ return ((x + y * this->buffer_width_) * image::image_type_to_bpp(this->type_)) / 8;
95
+ }
96
+
97
+ ESPHOME_ALWAYS_INLINE bool auto_resize_() const { return this->fixed_width_ == 0 || this->fixed_height_ == 0; }
98
+
99
+ bool resize_(int width, int height);
100
+
101
+ /**
102
+ * @brief Draw a pixel into the buffer.
103
+ *
104
+ * This is used by the decoder to fill the buffer that will later be displayed
105
+ * by the `draw` method. This will internally convert the supplied 32 bit RGBA
106
+ * color into the requested image storage format.
107
+ *
108
+ * @param x Horizontal pixel position.
109
+ * @param y Vertical pixel position.
110
+ * @param color 32 bit color to put into the pixel.
111
+ */
112
+ void draw_pixel_(int x, int y, Color color);
113
+
114
+ void end_connection_();
115
+
116
+ CallbackManager<void()> download_finished_callback_{};
117
+ CallbackManager<void()> download_error_callback_{};
118
+
119
+ std::shared_ptr<http_request::HttpContainer> downloader_{nullptr};
120
+ std::unique_ptr<ImageDecoder> decoder_{nullptr};
121
+
122
+ uint8_t *buffer_;
123
+ DownloadBuffer download_buffer_;
124
+
125
+ const ImageFormat format_;
126
+ image::Image *placeholder_{nullptr};
127
+
128
+ std::string url_{""};
129
+
130
+ /** width requested on configuration, or 0 if non specified. */
131
+ const int fixed_width_;
132
+ /** height requested on configuration, or 0 if non specified. */
133
+ const int fixed_height_;
134
+ /**
135
+ * Actual width of the current image. If fixed_width_ is specified,
136
+ * this will be equal to it; otherwise it will be set once the decoding
137
+ * starts and the original size is known.
138
+ * This needs to be separate from "BaseImage::get_width()" because the latter
139
+ * must return 0 until the image has been decoded (to avoid showing partially
140
+ * decoded images).
141
+ */
142
+ int buffer_width_;
143
+ /**
144
+ * Actual height of the current image. If fixed_height_ is specified,
145
+ * this will be equal to it; otherwise it will be set once the decoding
146
+ * starts and the original size is known.
147
+ * This needs to be separate from "BaseImage::get_height()" because the latter
148
+ * must return 0 until the image has been decoded (to avoid showing partially
149
+ * decoded images).
150
+ */
151
+ int buffer_height_;
152
+
153
+ friend void ImageDecoder::set_size(int width, int height);
154
+ friend void ImageDecoder::draw(int x, int y, int w, int h, const Color &color);
155
+ };
156
+
157
+ template<typename... Ts> class OnlineImageSetUrlAction : public Action<Ts...> {
158
+ public:
159
+ OnlineImageSetUrlAction(OnlineImage *parent) : parent_(parent) {}
160
+ TEMPLATABLE_VALUE(const char *, url)
161
+ void play(Ts... x) override {
162
+ this->parent_->set_url(this->url_.value(x...));
163
+ this->parent_->update();
164
+ }
165
+
166
+ protected:
167
+ OnlineImage *parent_;
168
+ };
169
+
170
+ template<typename... Ts> class OnlineImageReleaseAction : public Action<Ts...> {
171
+ public:
172
+ OnlineImageReleaseAction(OnlineImage *parent) : parent_(parent) {}
173
+ TEMPLATABLE_VALUE(const char *, url)
174
+ void play(Ts... x) override { this->parent_->release(); }
175
+
176
+ protected:
177
+ OnlineImage *parent_;
178
+ };
179
+
180
+ class DownloadFinishedTrigger : public Trigger<> {
181
+ public:
182
+ explicit DownloadFinishedTrigger(OnlineImage *parent) {
183
+ parent->add_on_finished_callback([this]() { this->trigger(); });
184
+ }
185
+ };
186
+
187
+ class DownloadErrorTrigger : public Trigger<> {
188
+ public:
189
+ explicit DownloadErrorTrigger(OnlineImage *parent) {
190
+ parent->add_on_error_callback([this]() { this->trigger(); });
191
+ }
192
+ };
193
+
194
+ } // namespace online_image
195
+ } // namespace esphome
@@ -0,0 +1,68 @@
1
+ #include "png_image.h"
2
+ #ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
3
+
4
+ #include "esphome/components/display/display_buffer.h"
5
+ #include "esphome/core/application.h"
6
+ #include "esphome/core/helpers.h"
7
+ #include "esphome/core/log.h"
8
+
9
+ static const char *const TAG = "online_image.png";
10
+
11
+ namespace esphome {
12
+ namespace online_image {
13
+
14
+ /**
15
+ * @brief Callback method that will be called by the PNGLE engine when the basic
16
+ * data of the image is received (i.e. width and height);
17
+ *
18
+ * @param pngle The PNGLE object, including the context data.
19
+ * @param w The width of the image.
20
+ * @param h The height of the image.
21
+ */
22
+ static void init_callback(pngle_t *pngle, uint32_t w, uint32_t h) {
23
+ PngDecoder *decoder = (PngDecoder *) pngle_get_user_data(pngle);
24
+ decoder->set_size(w, h);
25
+ }
26
+
27
+ /**
28
+ * @brief Callback method that will be called by the PNGLE engine when a chunk
29
+ * of the image is decoded.
30
+ *
31
+ * @param pngle The PNGLE object, including the context data.
32
+ * @param x The X coordinate to draw the rectangle on.
33
+ * @param y The Y coordinate to draw the rectangle on.
34
+ * @param w The width of the rectangle to draw.
35
+ * @param h The height of the rectangle to draw.
36
+ * @param rgba The color to paint the rectangle in.
37
+ */
38
+ static void draw_callback(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]) {
39
+ PngDecoder *decoder = (PngDecoder *) pngle_get_user_data(pngle);
40
+ Color color(rgba[0], rgba[1], rgba[2], rgba[3]);
41
+ decoder->draw(x, y, w, h, color);
42
+ }
43
+
44
+ void PngDecoder::prepare(uint32_t download_size) {
45
+ ImageDecoder::prepare(download_size);
46
+ pngle_set_user_data(this->pngle_, this);
47
+ pngle_set_init_callback(this->pngle_, init_callback);
48
+ pngle_set_draw_callback(this->pngle_, draw_callback);
49
+ }
50
+
51
+ int HOT PngDecoder::decode(uint8_t *buffer, size_t size) {
52
+ if (size < 256 && size < this->download_size_ - this->decoded_bytes_) {
53
+ ESP_LOGD(TAG, "Waiting for data");
54
+ return 0;
55
+ }
56
+ auto fed = pngle_feed(this->pngle_, buffer, size);
57
+ if (fed < 0) {
58
+ ESP_LOGE(TAG, "Error decoding image: %s", pngle_error(this->pngle_));
59
+ } else {
60
+ this->decoded_bytes_ += fed;
61
+ }
62
+ return fed;
63
+ }
64
+
65
+ } // namespace online_image
66
+ } // namespace esphome
67
+
68
+ #endif // USE_ONLINE_IMAGE_PNG_SUPPORT
@@ -0,0 +1,33 @@
1
+ #pragma once
2
+
3
+ #include "image_decoder.h"
4
+ #ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
5
+ #include <pngle.h>
6
+
7
+ namespace esphome {
8
+ namespace online_image {
9
+
10
+ /**
11
+ * @brief Image decoder specialization for PNG images.
12
+ */
13
+ class PngDecoder : public ImageDecoder {
14
+ public:
15
+ /**
16
+ * @brief Construct a new PNG Decoder object.
17
+ *
18
+ * @param display The image to decode the stream into.
19
+ */
20
+ PngDecoder(OnlineImage *image) : ImageDecoder(image), pngle_(pngle_new()) {}
21
+ ~PngDecoder() override { pngle_destroy(this->pngle_); }
22
+
23
+ void prepare(uint32_t download_size) override;
24
+ int HOT decode(uint8_t *buffer, size_t size) override;
25
+
26
+ protected:
27
+ pngle_t *pngle_;
28
+ };
29
+
30
+ } // namespace online_image
31
+ } // namespace esphome
32
+
33
+ #endif // USE_ONLINE_IMAGE_PNG_SUPPORT
@@ -1,10 +1,15 @@
1
+ from esphome import automation
1
2
  import esphome.codegen as cg
2
3
  import esphome.config_validation as cv
3
- from esphome import automation
4
+ from esphome.const import (
5
+ CONF_ESPHOME,
6
+ CONF_ON_ERROR,
7
+ CONF_OTA,
8
+ CONF_PLATFORM,
9
+ CONF_TRIGGER_ID,
10
+ )
4
11
  from esphome.core import CORE, coroutine_with_priority
5
12
 
6
- from esphome.const import CONF_ESPHOME, CONF_OTA, CONF_PLATFORM, CONF_TRIGGER_ID
7
-
8
13
  CODEOWNERS = ["@esphome/core"]
9
14
  AUTO_LOAD = ["md5", "safe_mode"]
10
15
 
@@ -13,7 +18,6 @@ IS_PLATFORM_COMPONENT = True
13
18
  CONF_ON_ABORT = "on_abort"
14
19
  CONF_ON_BEGIN = "on_begin"
15
20
  CONF_ON_END = "on_end"
16
- CONF_ON_ERROR = "on_error"
17
21
  CONF_ON_PROGRESS = "on_progress"
18
22
  CONF_ON_STATE_CHANGE = "on_state_change"
19
23
 
@@ -44,6 +44,8 @@ class PIDClimate : public climate::Climate, public Component {
44
44
  float get_kp() { return controller_.kp_; }
45
45
  float get_ki() { return controller_.ki_; }
46
46
  float get_kd() { return controller_.kd_; }
47
+ float get_min_integral() { return controller_.min_integral_; }
48
+ float get_max_integral() { return controller_.max_integral_; }
47
49
  float get_proportional_term() const { return controller_.proportional_term_; }
48
50
  float get_integral_term() const { return controller_.integral_term_; }
49
51
  float get_derivative_term() const { return controller_.derivative_term_; }
@@ -49,7 +49,7 @@ class RemoteTransmitterComponent : public remote_base::RemoteTransmitterBase,
49
49
  #ifdef USE_ESP32
50
50
  void configure_rmt_();
51
51
 
52
- uint32_t current_carrier_frequency_{UINT32_MAX};
52
+ uint32_t current_carrier_frequency_{38000};
53
53
  bool initialized_{false};
54
54
  std::vector<rmt_item32_t> rmt_temp_;
55
55
  esp_err_t error_code_{ESP_OK};
@@ -23,10 +23,11 @@ class RGBCTLightOutput : public light::LightOutput {
23
23
 
24
24
  light::LightTraits get_traits() override {
25
25
  auto traits = light::LightTraits();
26
- if (this->color_interlock_)
26
+ if (this->color_interlock_) {
27
27
  traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::COLOR_TEMPERATURE});
28
- else
28
+ } else {
29
29
  traits.set_supported_color_modes({light::ColorMode::RGB_COLOR_TEMPERATURE, light::ColorMode::COLOR_TEMPERATURE});
30
+ }
30
31
  traits.set_min_mireds(this->cold_white_temperature_);
31
32
  traits.set_max_mireds(this->warm_white_temperature_);
32
33
  return traits;
@@ -16,10 +16,11 @@ class RGBWLightOutput : public light::LightOutput {
16
16
  void set_color_interlock(bool color_interlock) { color_interlock_ = color_interlock; }
17
17
  light::LightTraits get_traits() override {
18
18
  auto traits = light::LightTraits();
19
- if (this->color_interlock_)
19
+ if (this->color_interlock_) {
20
20
  traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::WHITE});
21
- else
21
+ } else {
22
22
  traits.set_supported_color_modes({light::ColorMode::RGB_WHITE});
23
+ }
23
24
  return traits;
24
25
  }
25
26
  void write_state(light::LightState *state) override {
@@ -20,10 +20,11 @@ class RGBWWLightOutput : public light::LightOutput {
20
20
  void set_color_interlock(bool color_interlock) { color_interlock_ = color_interlock; }
21
21
  light::LightTraits get_traits() override {
22
22
  auto traits = light::LightTraits();
23
- if (this->color_interlock_)
23
+ if (this->color_interlock_) {
24
24
  traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::COLD_WARM_WHITE});
25
- else
25
+ } else {
26
26
  traits.set_supported_color_modes({light::ColorMode::RGB_COLD_WARM_WHITE});
27
+ }
27
28
  traits.set_min_mireds(this->cold_white_temperature_);
28
29
  traits.set_max_mireds(this->warm_white_temperature_);
29
30
  return traits;
@@ -1,20 +1,20 @@
1
- import esphome.codegen as cg
2
- import esphome.config_validation as cv
3
1
  from esphome import automation
2
+ import esphome.codegen as cg
4
3
  from esphome.components import mqtt, web_server
4
+ import esphome.config_validation as cv
5
5
  from esphome.const import (
6
+ CONF_CYCLE,
6
7
  CONF_ENTITY_CATEGORY,
7
8
  CONF_ICON,
8
9
  CONF_ID,
10
+ CONF_INDEX,
11
+ CONF_MODE,
12
+ CONF_MQTT_ID,
9
13
  CONF_ON_VALUE,
14
+ CONF_OPERATION,
10
15
  CONF_OPTION,
11
16
  CONF_TRIGGER_ID,
12
- CONF_MQTT_ID,
13
17
  CONF_WEB_SERVER_ID,
14
- CONF_CYCLE,
15
- CONF_MODE,
16
- CONF_OPERATION,
17
- CONF_INDEX,
18
18
  )
19
19
  from esphome.core import CORE, coroutine_with_priority
20
20
  from esphome.cpp_generator import MockObjClass
@@ -1,22 +1,28 @@
1
1
  import math
2
2
 
3
- import esphome.codegen as cg
4
- import esphome.config_validation as cv
5
3
  from esphome import automation
4
+ import esphome.codegen as cg
6
5
  from esphome.components import mqtt, web_server
6
+ import esphome.config_validation as cv
7
7
  from esphome.const import (
8
- CONF_DEVICE_CLASS,
9
8
  CONF_ABOVE,
10
9
  CONF_ACCURACY_DECIMALS,
11
10
  CONF_ALPHA,
12
11
  CONF_BELOW,
12
+ CONF_DEVICE_CLASS,
13
13
  CONF_ENTITY_CATEGORY,
14
14
  CONF_EXPIRE_AFTER,
15
15
  CONF_FILTERS,
16
+ CONF_FORCE_UPDATE,
16
17
  CONF_FROM,
17
18
  CONF_ICON,
18
19
  CONF_ID,
19
20
  CONF_IGNORE_OUT_OF_RANGE,
21
+ CONF_MAX_VALUE,
22
+ CONF_METHOD,
23
+ CONF_MIN_VALUE,
24
+ CONF_MQTT_ID,
25
+ CONF_MULTIPLE,
20
26
  CONF_ON_RAW_VALUE,
21
27
  CONF_ON_VALUE,
22
28
  CONF_ON_VALUE_RANGE,
@@ -29,14 +35,9 @@ from esphome.const import (
29
35
  CONF_TRIGGER_ID,
30
36
  CONF_TYPE,
31
37
  CONF_UNIT_OF_MEASUREMENT,
32
- CONF_WINDOW_SIZE,
33
- CONF_MQTT_ID,
34
- CONF_WEB_SERVER_ID,
35
- CONF_FORCE_UPDATE,
36
38
  CONF_VALUE,
37
- CONF_MIN_VALUE,
38
- CONF_MAX_VALUE,
39
- CONF_METHOD,
39
+ CONF_WEB_SERVER_ID,
40
+ CONF_WINDOW_SIZE,
40
41
  DEVICE_CLASS_APPARENT_POWER,
41
42
  DEVICE_CLASS_AQI,
42
43
  DEVICE_CLASS_ATMOSPHERIC_PRESSURE,
@@ -249,6 +250,7 @@ CalibratePolynomialFilter = sensor_ns.class_("CalibratePolynomialFilter", Filter
249
250
  SensorInRangeCondition = sensor_ns.class_("SensorInRangeCondition", Filter)
250
251
  ClampFilter = sensor_ns.class_("ClampFilter", Filter)
251
252
  RoundFilter = sensor_ns.class_("RoundFilter", Filter)
253
+ RoundMultipleFilter = sensor_ns.class_("RoundMultipleFilter", Filter)
252
254
 
253
255
  validate_unit_of_measurement = cv.string_strict
254
256
  validate_accuracy_decimals = cv.int_
@@ -734,6 +736,23 @@ async def round_filter_to_code(config, filter_id):
734
736
  )
735
737
 
736
738
 
739
+ @FILTER_REGISTRY.register(
740
+ "round_to_multiple_of",
741
+ RoundMultipleFilter,
742
+ cv.maybe_simple_value(
743
+ {
744
+ cv.Required(CONF_MULTIPLE): cv.positive_not_null_float,
745
+ },
746
+ key=CONF_MULTIPLE,
747
+ ),
748
+ )
749
+ async def round_multiple_filter_to_code(config, filter_id):
750
+ return cg.new_Pvariable(
751
+ filter_id,
752
+ config[CONF_MULTIPLE],
753
+ )
754
+
755
+
737
756
  async def build_filters(config):
738
757
  return await cg.build_registry_list(FILTER_REGISTRY, config)
739
758
 
@@ -472,5 +472,13 @@ optional<float> RoundFilter::new_value(float value) {
472
472
  return value;
473
473
  }
474
474
 
475
+ RoundMultipleFilter::RoundMultipleFilter(float multiple) : multiple_(multiple) {}
476
+ optional<float> RoundMultipleFilter::new_value(float value) {
477
+ if (std::isfinite(value)) {
478
+ return value - remainderf(value, this->multiple_);
479
+ }
480
+ return value;
481
+ }
482
+
475
483
  } // namespace sensor
476
484
  } // namespace esphome
@@ -431,5 +431,14 @@ class RoundFilter : public Filter {
431
431
  uint8_t precision_;
432
432
  };
433
433
 
434
+ class RoundMultipleFilter : public Filter {
435
+ public:
436
+ explicit RoundMultipleFilter(float multiple);
437
+ optional<float> new_value(float value) override;
438
+
439
+ protected:
440
+ float multiple_;
441
+ };
442
+
434
443
  } // namespace sensor
435
444
  } // namespace esphome
@@ -10,7 +10,7 @@ SmlFile::SmlFile(bytes buffer) : buffer_(std::move(buffer)) {
10
10
  this->pos_ = 0;
11
11
  while (this->pos_ < this->buffer_.size()) {
12
12
  if (this->buffer_[this->pos_] == 0x00)
13
- break; // fill byte detected -> no more messages
13
+ break; // EndOfSmlMsg
14
14
 
15
15
  SmlNode message = SmlNode();
16
16
  if (!this->setup_node(&message))
@@ -20,40 +20,66 @@ SmlFile::SmlFile(bytes buffer) : buffer_(std::move(buffer)) {
20
20
  }
21
21
 
22
22
  bool SmlFile::setup_node(SmlNode *node) {
23
- uint8_t type = this->buffer_[this->pos_] >> 4; // type including overlength info
24
- uint8_t length = this->buffer_[this->pos_] & 0x0f; // length including TL bytes
25
- bool is_list = (type & 0x07) == SML_LIST;
26
- bool has_extended_length = type & 0x08; // we have a long list/value (>15 entries)
27
- uint8_t parse_length = length;
28
- if (has_extended_length) {
23
+ // If the TL field is 0x00, this is the end of the message
24
+ // (see 6.3.1 of SML protocol definition)
25
+ if (this->buffer_[this->pos_] == 0x00) {
26
+ // Increment past this byte and signal that the message is done
27
+ this->pos_ += 1;
28
+ return true;
29
+ }
30
+
31
+ // Extract data from initial TL field
32
+ uint8_t type = (this->buffer_[this->pos_] >> 4) & 0x07; // type without overlength info
33
+ bool overlength = (this->buffer_[this->pos_] >> 4) & 0x08; // overlength information
34
+ uint8_t length = this->buffer_[this->pos_] & 0x0f; // length (including TL bytes)
35
+
36
+ // Check if we need additional length bytes
37
+ if (overlength) {
38
+ // Shift the current length to the higher nibble
39
+ // and add the lower nibble of the next byte to the length
29
40
  length = (length << 4) + (this->buffer_[this->pos_ + 1] & 0x0f);
30
- parse_length = length;
41
+ // We are basically done with the first TL field now,
42
+ // so increment past that, we now point to the second TL field
31
43
  this->pos_ += 1;
44
+ // Decrement the length for value fields (not lists),
45
+ // since the byte we just handled is counted as part of the field
46
+ // in case of values but not for lists
47
+ if (type != SML_LIST)
48
+ length -= 1;
49
+
50
+ // Technically, this is not enough, the standard allows for more than two length fields.
51
+ // However I don't think it is very common to have more than 255 entries in a list
32
52
  }
33
53
 
34
- if (this->pos_ + parse_length >= this->buffer_.size())
54
+ // We are done with the last TL field(s), so advance the position
55
+ this->pos_ += 1;
56
+ // and decrement the length for non-list fields
57
+ if (type != SML_LIST)
58
+ length -= 1;
59
+
60
+ // Check if the buffer length is long enough
61
+ if (this->pos_ + length > this->buffer_.size())
35
62
  return false;
36
63
 
37
- node->type = type & 0x07;
64
+ node->type = type;
38
65
  node->nodes.clear();
39
66
  node->value_bytes.clear();
40
67
 
41
- // if the list is a has_extended_length list with e.g. 16 elements this is a 0x00 byte but not the end of message
42
- if (!has_extended_length && this->buffer_[this->pos_] == 0x00) { // end of message
43
- this->pos_ += 1;
44
- } else if (is_list) { // list
45
- this->pos_ += 1;
46
- node->nodes.reserve(parse_length);
47
- for (size_t i = 0; i != parse_length; i++) {
68
+ if (type == SML_LIST) {
69
+ node->nodes.reserve(length);
70
+ for (size_t i = 0; i != length; i++) {
48
71
  SmlNode child_node = SmlNode();
49
72
  if (!this->setup_node(&child_node))
50
73
  return false;
51
74
  node->nodes.emplace_back(child_node);
52
75
  }
53
- } else { // value
54
- node->value_bytes =
55
- bytes(this->buffer_.begin() + this->pos_ + 1, this->buffer_.begin() + this->pos_ + parse_length);
56
- this->pos_ += parse_length;
76
+ } else {
77
+ // Value starts at the current position
78
+ // Value ends "length" bytes later,
79
+ // (since the TL field is counted but already subtracted from length)
80
+ node->value_bytes = bytes(this->buffer_.begin() + this->pos_, this->buffer_.begin() + this->pos_ + length);
81
+ // Increment the pointer past all consumed bytes
82
+ this->pos_ += length;
57
83
  }
58
84
  return true;
59
85
  }
@@ -101,7 +127,7 @@ int64_t bytes_to_int(const bytes &buffer) {
101
127
  // see https://stackoverflow.com/questions/42534749/signed-extension-from-24-bit-to-32-bit-in-c
102
128
  if (buffer.size() < 8) {
103
129
  const int bits = buffer.size() * 8;
104
- const uint64_t m = 1u << (bits - 1);
130
+ const uint64_t m = 1ull << (bits - 1);
105
131
  tmp = (tmp ^ m) - m;
106
132
  }
107
133
 
@@ -19,24 +19,22 @@ std::unique_ptr<Socket> socket_ip(int type, int protocol) {
19
19
 
20
20
  socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const std::string &ip_address, uint16_t port) {
21
21
  #if USE_NETWORK_IPV6
22
- if (addrlen < sizeof(sockaddr_in6)) {
23
- errno = EINVAL;
24
- return 0;
25
- }
26
- auto *server = reinterpret_cast<sockaddr_in6 *>(addr);
27
- memset(server, 0, sizeof(sockaddr_in6));
28
- server->sin6_family = AF_INET6;
29
- server->sin6_port = htons(port);
22
+ if (ip_address.find(':') != std::string::npos) {
23
+ if (addrlen < sizeof(sockaddr_in6)) {
24
+ errno = EINVAL;
25
+ return 0;
26
+ }
27
+ auto *server = reinterpret_cast<sockaddr_in6 *>(addr);
28
+ memset(server, 0, sizeof(sockaddr_in6));
29
+ server->sin6_family = AF_INET6;
30
+ server->sin6_port = htons(port);
30
31
 
31
- if (ip_address.find('.') != std::string::npos) {
32
- server->sin6_addr.un.u32_addr[3] = inet_addr(ip_address.c_str());
33
- } else {
34
32
  ip6_addr_t ip6;
35
33
  inet6_aton(ip_address.c_str(), &ip6);
36
34
  memcpy(server->sin6_addr.un.u32_addr, ip6.addr, sizeof(ip6.addr));
35
+ return sizeof(sockaddr_in6);
37
36
  }
38
- return sizeof(sockaddr_in6);
39
- #else
37
+ #endif /* USE_NETWORK_IPV6 */
40
38
  if (addrlen < sizeof(sockaddr_in)) {
41
39
  errno = EINVAL;
42
40
  return 0;
@@ -47,7 +45,6 @@ socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const std::stri
47
45
  server->sin_addr.s_addr = inet_addr(ip_address.c_str());
48
46
  server->sin_port = htons(port);
49
47
  return sizeof(sockaddr_in);
50
- #endif /* USE_NETWORK_IPV6 */
51
48
  }
52
49
 
53
50
  socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port) {