esphome 2024.7.2__py3-none-any.whl → 2024.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +15 -81
- esphome/automation.py +1 -1
- esphome/codegen.py +53 -53
- esphome/components/ade7953/sensor.py +1 -1
- esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
- esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +5 -2
- esphome/components/airthings_wave_plus/airthings_wave_plus.h +2 -0
- esphome/components/airthings_wave_plus/sensor.py +12 -0
- esphome/components/alarm_control_panel/__init__.py +75 -66
- esphome/components/apds9306/__init__.py +4 -0
- esphome/components/apds9306/apds9306.cpp +151 -0
- esphome/components/apds9306/apds9306.h +66 -0
- esphome/components/apds9306/sensor.py +95 -0
- esphome/components/api/__init__.py +80 -52
- esphome/components/api/api_connection.cpp +14 -1
- esphome/components/api/api_pb2.cpp +33 -4
- esphome/components/api/api_pb2.h +8 -1
- esphome/components/api/api_server.cpp +10 -0
- esphome/components/api/api_server.h +3 -0
- esphome/components/atm90e32/__init__.py +7 -0
- esphome/components/atm90e32/atm90e32.cpp +68 -16
- esphome/components/atm90e32/atm90e32.h +20 -7
- esphome/components/atm90e32/atm90e32_reg.h +2 -0
- esphome/components/atm90e32/button/__init__.py +43 -0
- esphome/components/atm90e32/button/atm90e32_button.cpp +20 -0
- esphome/components/atm90e32/button/atm90e32_button.h +27 -0
- esphome/components/atm90e32/sensor.py +15 -11
- esphome/components/bedjet/bedjet_codec.h +1 -1
- esphome/components/binary/light/binary_light_output.h +3 -2
- esphome/components/binary_sensor/__init__.py +5 -5
- esphome/components/ble_client/__init__.py +3 -3
- esphome/components/ble_client/output/__init__.py +1 -1
- esphome/components/ble_client/sensor/__init__.py +4 -3
- esphome/components/ble_client/switch/__init__.py +2 -1
- esphome/components/ble_client/text_sensor/__init__.py +4 -3
- esphome/components/ble_presence/binary_sensor.py +3 -3
- esphome/components/ble_rssi/sensor.py +2 -2
- esphome/components/ble_scanner/text_sensor.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +3 -3
- esphome/components/bme68x_bsec2/__init__.py +196 -0
- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +523 -0
- esphome/components/bme68x_bsec2/bme68x_bsec2.h +163 -0
- esphome/components/bme68x_bsec2/sensor.py +130 -0
- esphome/components/bme68x_bsec2/text_sensor.py +33 -0
- esphome/components/bme68x_bsec2_i2c/__init__.py +28 -0
- esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +53 -0
- esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.h +28 -0
- esphome/components/bmp3xx/sensor.py +1 -1
- esphome/components/button/__init__.py +4 -4
- esphome/components/climate/__init__.py +5 -5
- esphome/components/climate/climate.h +1 -1
- esphome/components/cover/__init__.py +8 -8
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +11 -7
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +1 -1
- esphome/components/datetime/__init__.py +11 -13
- esphome/components/demo/demo_sensor.h +3 -2
- esphome/components/display/display.cpp +31 -0
- esphome/components/display/display.h +3 -0
- esphome/components/display_menu_base/__init__.py +14 -13
- esphome/components/ens160/sensor.py +1 -1
- esphome/components/esp32/__init__.py +22 -10
- esphome/components/esp32/boards.py +1 -1
- esphome/components/esp32/gpio.py +12 -13
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -2
- esphome/components/esp32/gpio_esp32_c3.py +1 -5
- esphome/components/esp32/gpio_esp32_c6.py +1 -2
- esphome/components/esp32/gpio_esp32_h2.py +1 -2
- esphome/components/esp32/gpio_esp32_s2.py +1 -2
- esphome/components/esp32/gpio_esp32_s3.py +1 -6
- esphome/components/esp32_ble/__init__.py +20 -3
- esphome/components/esp32_ble/ble.cpp +9 -1
- esphome/components/esp32_ble/ble.h +9 -0
- esphome/components/esp32_ble/ble_advertising.cpp +42 -9
- esphome/components/esp32_ble/ble_advertising.h +21 -1
- esphome/components/esp32_ble_beacon/__init__.py +17 -7
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +45 -113
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.h +17 -19
- esphome/components/esp32_ble_client/__init__.py +0 -1
- esphome/components/esp32_ble_server/__init__.py +2 -3
- esphome/components/esp32_ble_tracker/__init__.py +2 -2
- esphome/components/esp32_improv/__init__.py +2 -4
- esphome/components/ethernet/__init__.py +17 -17
- esphome/components/ethernet_info/text_sensor.py +2 -2
- esphome/components/event/__init__.py +5 -5
- esphome/components/fan/__init__.py +14 -14
- esphome/components/fan/fan.cpp +2 -2
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +1 -1
- esphome/components/graphical_display_menu/__init__.py +11 -8
- esphome/components/haier/haier_base.h +2 -2
- esphome/components/homeassistant/__init__.py +8 -1
- esphome/components/homeassistant/number/__init__.py +33 -0
- esphome/components/homeassistant/number/homeassistant_number.cpp +100 -0
- esphome/components/homeassistant/number/homeassistant_number.h +31 -0
- esphome/components/homeassistant/switch/__init__.py +30 -0
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +59 -0
- esphome/components/homeassistant/switch/homeassistant_switch.h +22 -0
- esphome/components/host/__init__.py +3 -7
- esphome/components/http_request/__init__.py +12 -1
- esphome/components/http_request/http_request_arduino.cpp +2 -2
- esphome/components/http_request/http_request_idf.cpp +11 -2
- esphome/components/http_request/http_request_idf.h +10 -0
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/http_request/update/http_request_update.cpp +2 -2
- esphome/components/http_request/update/http_request_update.h +2 -1
- esphome/components/hx711/hx711.cpp +10 -1
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +1 -1
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +11 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +2 -0
- esphome/components/ili9xxx/ili9xxx_defines.h +3 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +9 -22
- esphome/components/ili9xxx/ili9xxx_display.h +5 -7
- esphome/components/ili9xxx/ili9xxx_init.h +4 -4
- esphome/components/improv_base/__init__.py +2 -3
- esphome/components/improv_serial/__init__.py +4 -10
- esphome/components/improv_serial/improv_serial_component.cpp +4 -0
- esphome/components/jsn_sr04t/jsn_sr04t.cpp +18 -1
- esphome/components/jsn_sr04t/jsn_sr04t.h +7 -1
- esphome/components/jsn_sr04t/sensor.py +13 -0
- esphome/components/kalman_combinator/sensor.py +1 -1
- esphome/components/light/__init__.py +16 -15
- esphome/components/light/addressable_light_effect.h +12 -8
- esphome/components/light/automation.h +16 -1
- esphome/components/light/automation.py +21 -0
- esphome/components/light/base_light_effects.h +5 -5
- esphome/components/light/esp_color_correction.h +8 -8
- esphome/components/light/types.py +7 -0
- esphome/components/lock/__init__.py +3 -3
- esphome/components/logger/__init__.py +15 -18
- esphome/components/lvgl/__init__.py +346 -0
- esphome/components/lvgl/automation.py +226 -0
- esphome/components/lvgl/binary_sensor/__init__.py +43 -0
- esphome/components/lvgl/defines.py +508 -0
- esphome/components/lvgl/encoders.py +77 -0
- esphome/components/lvgl/font.cpp +76 -0
- esphome/components/lvgl/helpers.py +49 -0
- esphome/components/lvgl/light/__init__.py +32 -0
- esphome/components/lvgl/light/lvgl_light.h +48 -0
- esphome/components/lvgl/lv_validation.py +303 -0
- esphome/components/lvgl/lvcode.py +349 -0
- esphome/components/lvgl/lvgl_esphome.cpp +407 -0
- esphome/components/lvgl/lvgl_esphome.h +274 -0
- esphome/components/lvgl/lvgl_hal.h +21 -0
- esphome/components/lvgl/number/__init__.py +66 -0
- esphome/components/lvgl/number/lvgl_number.h +34 -0
- esphome/components/lvgl/schemas.py +436 -0
- esphome/components/lvgl/select/__init__.py +55 -0
- esphome/components/lvgl/select/lvgl_select.h +62 -0
- esphome/components/lvgl/sensor/__init__.py +47 -0
- esphome/components/lvgl/styles.py +58 -0
- esphome/components/lvgl/switch/__init__.py +56 -0
- esphome/components/lvgl/switch/lvgl_switch.h +34 -0
- esphome/components/lvgl/text/__init__.py +50 -0
- esphome/components/lvgl/text/lvgl_text.h +34 -0
- esphome/components/lvgl/text_sensor/__init__.py +42 -0
- esphome/components/lvgl/touchscreens.py +45 -0
- esphome/components/lvgl/trigger.py +74 -0
- esphome/components/lvgl/types.py +191 -0
- esphome/components/lvgl/widgets/__init__.py +419 -0
- esphome/components/lvgl/widgets/animimg.py +117 -0
- esphome/components/lvgl/widgets/arc.py +78 -0
- esphome/components/lvgl/widgets/button.py +20 -0
- esphome/components/lvgl/widgets/buttonmatrix.py +275 -0
- esphome/components/lvgl/widgets/checkbox.py +27 -0
- esphome/components/lvgl/widgets/dropdown.py +76 -0
- esphome/components/lvgl/widgets/img.py +85 -0
- esphome/components/lvgl/widgets/keyboard.py +49 -0
- esphome/components/lvgl/widgets/label.py +42 -0
- esphome/components/lvgl/widgets/led.py +29 -0
- esphome/components/lvgl/widgets/line.py +50 -0
- esphome/components/lvgl/widgets/lv_bar.py +55 -0
- esphome/components/lvgl/widgets/meter.py +302 -0
- esphome/components/lvgl/widgets/msgbox.py +134 -0
- esphome/components/lvgl/widgets/obj.py +28 -0
- esphome/components/lvgl/widgets/page.py +113 -0
- esphome/components/lvgl/widgets/roller.py +77 -0
- esphome/components/lvgl/widgets/slider.py +63 -0
- esphome/components/lvgl/widgets/spinbox.py +178 -0
- esphome/components/lvgl/widgets/spinner.py +43 -0
- esphome/components/lvgl/widgets/switch.py +20 -0
- esphome/components/lvgl/widgets/tabview.py +114 -0
- esphome/components/lvgl/widgets/textarea.py +66 -0
- esphome/components/lvgl/widgets/tileview.py +128 -0
- esphome/components/m5stack_8angle/__init__.py +33 -0
- esphome/components/m5stack_8angle/binary_sensor/__init__.py +30 -0
- esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +17 -0
- esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.h +19 -0
- esphome/components/m5stack_8angle/light/__init__.py +31 -0
- esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +45 -0
- esphome/components/m5stack_8angle/light/m5stack_8angle_light.h +37 -0
- esphome/components/m5stack_8angle/m5stack_8angle.cpp +74 -0
- esphome/components/m5stack_8angle/m5stack_8angle.h +34 -0
- esphome/components/m5stack_8angle/sensor/__init__.py +66 -0
- esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +24 -0
- esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.h +27 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -0
- esphome/components/max31856/sensor.py +5 -5
- esphome/components/media_player/__init__.py +3 -5
- esphome/components/media_player/automation.h +31 -27
- esphome/components/micro_wake_word/__init__.py +20 -25
- esphome/components/micro_wake_word/streaming_model.cpp +6 -4
- esphome/components/microphone/microphone.h +4 -1
- esphome/components/mitsubishi/mitsubishi.cpp +7 -1
- esphome/components/modbus_controller/__init__.py +26 -2
- esphome/components/modbus_controller/automation.h +19 -0
- esphome/components/modbus_controller/const.py +1 -0
- esphome/components/modbus_controller/modbus_controller.cpp +8 -0
- esphome/components/modbus_controller/modbus_controller.h +3 -0
- esphome/components/mqtt/__init__.py +20 -9
- esphome/components/mqtt/mqtt_alarm_control_panel.cpp +128 -0
- esphome/components/mqtt/mqtt_alarm_control_panel.h +39 -0
- esphome/components/mqtt/mqtt_backend.h +3 -1
- esphome/components/mqtt/mqtt_backend_esp32.cpp +4 -1
- esphome/components/mqtt/mqtt_backend_esp32.h +3 -1
- esphome/components/mqtt/mqtt_backend_esp8266.h +3 -1
- esphome/components/mqtt/mqtt_backend_libretiny.h +3 -1
- esphome/components/mqtt/mqtt_client.cpp +16 -3
- esphome/components/mqtt/mqtt_client.h +5 -1
- esphome/components/mqtt/mqtt_component.cpp +32 -4
- esphome/components/mqtt/mqtt_const.h +2 -0
- esphome/components/network/__init__.py +15 -12
- esphome/components/network/ip_address.h +3 -0
- esphome/components/network/util.cpp +2 -1
- esphome/components/network/util.h +3 -1
- esphome/components/nextion/base_component.py +5 -8
- esphome/components/number/__init__.py +7 -8
- esphome/components/online_image/__init__.py +167 -0
- esphome/components/online_image/image_decoder.cpp +44 -0
- esphome/components/online_image/image_decoder.h +112 -0
- esphome/components/online_image/online_image.cpp +283 -0
- esphome/components/online_image/online_image.h +195 -0
- esphome/components/online_image/png_image.cpp +68 -0
- esphome/components/online_image/png_image.h +33 -0
- esphome/components/ota/__init__.py +8 -4
- esphome/components/pid/pid_climate.h +2 -0
- esphome/components/pmwcs3/pmwcs3.cpp +31 -30
- esphome/components/remote_base/pronto_protocol.cpp +0 -3
- esphome/components/remote_transmitter/remote_transmitter.h +1 -1
- esphome/components/rgbct/rgbct_light_output.h +3 -2
- esphome/components/rgbw/rgbw_light_output.h +3 -2
- esphome/components/rgbww/rgbww_light_output.h +3 -2
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +31 -5
- esphome/components/rp2040_pio_led_strip/led_strip.h +5 -0
- esphome/components/rtttl/rtttl.cpp +108 -21
- esphome/components/rtttl/rtttl.h +15 -6
- esphome/components/select/__init__.py +7 -7
- esphome/components/sensor/__init__.py +29 -10
- esphome/components/sensor/filter.cpp +8 -0
- esphome/components/sensor/filter.h +9 -0
- esphome/components/sml/sml_parser.cpp +48 -22
- esphome/components/socket/socket.cpp +11 -14
- esphome/components/speaker/__init__.py +14 -5
- esphome/components/speaker/automation.h +10 -0
- esphome/components/speaker/speaker.h +9 -0
- esphome/components/spi/spi.cpp +0 -6
- esphome/components/spi/spi.h +2 -19
- esphome/components/spi_led_strip/spi_led_strip.h +5 -4
- esphome/components/sprinkler/sprinkler.cpp +2 -2
- esphome/components/sprinkler/sprinkler.h +1 -1
- esphome/components/switch/__init__.py +3 -3
- esphome/components/text/__init__.py +5 -5
- esphome/components/text_sensor/__init__.py +7 -7
- esphome/components/time/__init__.py +8 -8
- esphome/components/touchscreen/binary_sensor/__init__.py +24 -10
- esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.cpp +3 -2
- esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.h +4 -2
- esphome/components/uart/uart_component_host.cpp +6 -2
- esphome/components/update/__init__.py +33 -15
- esphome/components/update/automation.h +23 -0
- esphome/components/update/update_entity.h +3 -1
- esphome/components/valve/__init__.py +3 -3
- esphome/components/voice_assistant/__init__.py +7 -8
- esphome/components/wake_on_lan/wake_on_lan.cpp +2 -0
- esphome/components/wake_on_lan/wake_on_lan.h +3 -1
- esphome/components/watchdog/__init__.py +1 -0
- esphome/components/{http_request → watchdog}/watchdog.cpp +0 -2
- esphome/components/{http_request → watchdog}/watchdog.h +0 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +5 -5
- esphome/components/web_server/server_index_v3.h +3615 -3603
- esphome/components/web_server/web_server.cpp +0 -209
- esphome/components/web_server/web_server.h +1 -1
- esphome/components/web_server/web_server_v1.cpp +217 -0
- esphome/components/web_server_base/web_server_base.h +1 -0
- esphome/components/wifi/__init__.py +15 -14
- esphome/components/wifi/wifi_component.cpp +2 -0
- esphome/components/wifi/wifi_component.h +7 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +5 -2
- esphome/components/wifi/wifi_component_esp8266.cpp +2 -0
- esphome/components/wifi/wifi_component_esp_idf.cpp +43 -7
- esphome/components/wifi/wifi_component_libretiny.cpp +2 -0
- esphome/components/wifi/wifi_component_pico_w.cpp +2 -0
- esphome/components/wifi/wpa2_eap.py +6 -7
- esphome/components/wifi_info/text_sensor.py +3 -3
- esphome/components/wifi_info/wifi_info_text_sensor.cpp +2 -0
- esphome/components/wifi_info/wifi_info_text_sensor.h +2 -0
- esphome/components/wifi_signal/sensor.py +1 -1
- esphome/components/wifi_signal/wifi_signal_sensor.cpp +2 -0
- esphome/components/wifi_signal/wifi_signal_sensor.h +2 -1
- esphome/components/xiaomi_ble/xiaomi_ble.cpp +20 -3
- esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
- esphome/components/xiaomi_lywsd02mmc/__init__.py +0 -0
- esphome/components/xiaomi_lywsd02mmc/sensor.py +77 -0
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +73 -0
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +37 -0
- esphome/config.py +17 -19
- esphome/config_validation.py +55 -23
- esphome/const.py +25 -9
- esphome/core/__init__.py +17 -14
- esphome/core/application.h +42 -21
- esphome/core/automation.h +5 -3
- esphome/core/base_automation.h +3 -2
- esphome/core/bytebuffer.cpp +134 -0
- esphome/core/bytebuffer.h +96 -0
- esphome/core/color.h +24 -16
- esphome/core/config.py +3 -3
- esphome/core/defines.h +14 -1
- esphome/core/entity_base.h +2 -2
- esphome/core/entity_helpers.py +1 -2
- esphome/core/gpio.h +0 -18
- esphome/core/helpers.h +1 -1
- esphome/core/optional.h +15 -16
- esphome/coroutine.py +1 -1
- esphome/cpp_generator.py +1 -1
- esphome/cpp_helpers.py +3 -5
- esphome/dashboard/core.py +3 -3
- esphome/dashboard/dashboard.py +3 -3
- esphome/dashboard/entries.py +1 -1
- esphome/dashboard/util/file.py +1 -1
- esphome/dashboard/web_server.py +3 -3
- esphome/external_files.py +5 -3
- esphome/final_validate.py +2 -2
- esphome/git.py +4 -4
- esphome/helpers.py +5 -5
- esphome/loader.py +15 -10
- esphome/mqtt.py +4 -8
- esphome/pins.py +6 -6
- esphome/platformio_api.py +5 -5
- esphome/storage_json.py +2 -1
- esphome/types.py +1 -1
- esphome/util.py +2 -3
- esphome/voluptuous_schema.py +1 -0
- esphome/vscode.py +5 -4
- esphome/wizard.py +1 -1
- esphome/writer.py +7 -7
- esphome/yaml_util.py +3 -3
- esphome/zeroconf.py +1 -1
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/METADATA +3 -3
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/RECORD +353 -247
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/LICENSE +0 -0
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/WHEEL +0 -0
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,283 @@
|
|
1
|
+
#include "online_image.h"
|
2
|
+
|
3
|
+
#include "esphome/core/log.h"
|
4
|
+
|
5
|
+
static const char *const TAG = "online_image";
|
6
|
+
|
7
|
+
#include "image_decoder.h"
|
8
|
+
|
9
|
+
#ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
|
10
|
+
#include "png_image.h"
|
11
|
+
#endif
|
12
|
+
|
13
|
+
namespace esphome {
|
14
|
+
namespace online_image {
|
15
|
+
|
16
|
+
using image::ImageType;
|
17
|
+
|
18
|
+
inline bool is_color_on(const Color &color) {
|
19
|
+
// This produces the most accurate monochrome conversion, but is slightly slower.
|
20
|
+
// return (0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b) > 127;
|
21
|
+
|
22
|
+
// Approximation using fast integer computations; produces acceptable results
|
23
|
+
// Equivalent to 0.25 * R + 0.5 * G + 0.25 * B
|
24
|
+
return ((color.r >> 2) + (color.g >> 1) + (color.b >> 2)) & 0x80;
|
25
|
+
}
|
26
|
+
|
27
|
+
OnlineImage::OnlineImage(const std::string &url, int width, int height, ImageFormat format, ImageType type,
|
28
|
+
uint32_t download_buffer_size)
|
29
|
+
: Image(nullptr, 0, 0, type),
|
30
|
+
buffer_(nullptr),
|
31
|
+
download_buffer_(download_buffer_size),
|
32
|
+
format_(format),
|
33
|
+
fixed_width_(width),
|
34
|
+
fixed_height_(height) {
|
35
|
+
this->set_url(url);
|
36
|
+
}
|
37
|
+
|
38
|
+
void OnlineImage::draw(int x, int y, display::Display *display, Color color_on, Color color_off) {
|
39
|
+
if (this->data_start_) {
|
40
|
+
Image::draw(x, y, display, color_on, color_off);
|
41
|
+
} else if (this->placeholder_) {
|
42
|
+
this->placeholder_->draw(x, y, display, color_on, color_off);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
void OnlineImage::release() {
|
47
|
+
if (this->buffer_) {
|
48
|
+
ESP_LOGD(TAG, "Deallocating old buffer...");
|
49
|
+
this->allocator_.deallocate(this->buffer_, this->get_buffer_size_());
|
50
|
+
this->data_start_ = nullptr;
|
51
|
+
this->buffer_ = nullptr;
|
52
|
+
this->width_ = 0;
|
53
|
+
this->height_ = 0;
|
54
|
+
this->buffer_width_ = 0;
|
55
|
+
this->buffer_height_ = 0;
|
56
|
+
this->end_connection_();
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
bool OnlineImage::resize_(int width_in, int height_in) {
|
61
|
+
int width = this->fixed_width_;
|
62
|
+
int height = this->fixed_height_;
|
63
|
+
if (this->auto_resize_()) {
|
64
|
+
width = width_in;
|
65
|
+
height = height_in;
|
66
|
+
if (this->width_ != width && this->height_ != height) {
|
67
|
+
this->release();
|
68
|
+
}
|
69
|
+
}
|
70
|
+
if (this->buffer_) {
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
auto new_size = this->get_buffer_size_(width, height);
|
74
|
+
ESP_LOGD(TAG, "Allocating new buffer of %d Bytes...", new_size);
|
75
|
+
delay_microseconds_safe(2000);
|
76
|
+
this->buffer_ = this->allocator_.allocate(new_size);
|
77
|
+
if (this->buffer_) {
|
78
|
+
this->buffer_width_ = width;
|
79
|
+
this->buffer_height_ = height;
|
80
|
+
this->width_ = width;
|
81
|
+
ESP_LOGD(TAG, "New size: (%d, %d)", width, height);
|
82
|
+
} else {
|
83
|
+
#if defined(USE_ESP8266)
|
84
|
+
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
|
85
|
+
int max_block = ESP.getMaxFreeBlockSize();
|
86
|
+
#elif defined(USE_ESP32)
|
87
|
+
int max_block = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
|
88
|
+
#else
|
89
|
+
int max_block = -1;
|
90
|
+
#endif
|
91
|
+
ESP_LOGE(TAG, "allocation failed. Biggest block in heap: %d Bytes", max_block);
|
92
|
+
this->end_connection_();
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
return true;
|
96
|
+
}
|
97
|
+
|
98
|
+
void OnlineImage::update() {
|
99
|
+
if (this->decoder_) {
|
100
|
+
ESP_LOGW(TAG, "Image already being updated.");
|
101
|
+
return;
|
102
|
+
} else {
|
103
|
+
ESP_LOGI(TAG, "Updating image");
|
104
|
+
}
|
105
|
+
|
106
|
+
this->downloader_ = this->parent_->get(this->url_);
|
107
|
+
|
108
|
+
if (this->downloader_ == nullptr) {
|
109
|
+
ESP_LOGE(TAG, "Download failed.");
|
110
|
+
this->end_connection_();
|
111
|
+
this->download_error_callback_.call();
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
|
115
|
+
int http_code = this->downloader_->status_code;
|
116
|
+
if (http_code == HTTP_CODE_NOT_MODIFIED) {
|
117
|
+
// Image hasn't changed on server. Skip download.
|
118
|
+
this->end_connection_();
|
119
|
+
return;
|
120
|
+
}
|
121
|
+
if (http_code != HTTP_CODE_OK) {
|
122
|
+
ESP_LOGE(TAG, "HTTP result: %d", http_code);
|
123
|
+
this->end_connection_();
|
124
|
+
this->download_error_callback_.call();
|
125
|
+
return;
|
126
|
+
}
|
127
|
+
|
128
|
+
ESP_LOGD(TAG, "Starting download");
|
129
|
+
size_t total_size = this->downloader_->content_length;
|
130
|
+
|
131
|
+
#ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
|
132
|
+
if (this->format_ == ImageFormat::PNG) {
|
133
|
+
this->decoder_ = esphome::make_unique<PngDecoder>(this);
|
134
|
+
}
|
135
|
+
#endif // ONLINE_IMAGE_PNG_SUPPORT
|
136
|
+
|
137
|
+
if (!this->decoder_) {
|
138
|
+
ESP_LOGE(TAG, "Could not instantiate decoder. Image format unsupported.");
|
139
|
+
this->end_connection_();
|
140
|
+
this->download_error_callback_.call();
|
141
|
+
return;
|
142
|
+
}
|
143
|
+
this->decoder_->prepare(total_size);
|
144
|
+
ESP_LOGI(TAG, "Downloading image");
|
145
|
+
}
|
146
|
+
|
147
|
+
void OnlineImage::loop() {
|
148
|
+
if (!this->decoder_) {
|
149
|
+
// Not decoding at the moment => nothing to do.
|
150
|
+
return;
|
151
|
+
}
|
152
|
+
if (!this->downloader_ || this->decoder_->is_finished()) {
|
153
|
+
ESP_LOGD(TAG, "Image fully downloaded");
|
154
|
+
this->data_start_ = buffer_;
|
155
|
+
this->width_ = buffer_width_;
|
156
|
+
this->height_ = buffer_height_;
|
157
|
+
this->end_connection_();
|
158
|
+
this->download_finished_callback_.call();
|
159
|
+
return;
|
160
|
+
}
|
161
|
+
if (this->downloader_ == nullptr) {
|
162
|
+
ESP_LOGE(TAG, "Downloader not instantiated; cannot download");
|
163
|
+
return;
|
164
|
+
}
|
165
|
+
size_t available = this->download_buffer_.free_capacity();
|
166
|
+
if (available) {
|
167
|
+
auto len = this->downloader_->read(this->download_buffer_.append(), available);
|
168
|
+
if (len > 0) {
|
169
|
+
this->download_buffer_.write(len);
|
170
|
+
auto fed = this->decoder_->decode(this->download_buffer_.data(), this->download_buffer_.unread());
|
171
|
+
if (fed < 0) {
|
172
|
+
ESP_LOGE(TAG, "Error when decoding image.");
|
173
|
+
this->end_connection_();
|
174
|
+
this->download_error_callback_.call();
|
175
|
+
return;
|
176
|
+
}
|
177
|
+
this->download_buffer_.read(fed);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
void OnlineImage::draw_pixel_(int x, int y, Color color) {
|
183
|
+
if (!this->buffer_) {
|
184
|
+
ESP_LOGE(TAG, "Buffer not allocated!");
|
185
|
+
return;
|
186
|
+
}
|
187
|
+
if (x < 0 || y < 0 || x >= this->buffer_width_ || y >= this->buffer_height_) {
|
188
|
+
ESP_LOGE(TAG, "Tried to paint a pixel (%d,%d) outside the image!", x, y);
|
189
|
+
return;
|
190
|
+
}
|
191
|
+
uint32_t pos = this->get_position_(x, y);
|
192
|
+
switch (this->type_) {
|
193
|
+
case ImageType::IMAGE_TYPE_BINARY: {
|
194
|
+
const uint32_t width_8 = ((this->width_ + 7u) / 8u) * 8u;
|
195
|
+
const uint32_t pos = x + y * width_8;
|
196
|
+
if ((this->has_transparency() && color.w > 127) || is_color_on(color)) {
|
197
|
+
this->buffer_[pos / 8u] |= (0x80 >> (pos % 8u));
|
198
|
+
} else {
|
199
|
+
this->buffer_[pos / 8u] &= ~(0x80 >> (pos % 8u));
|
200
|
+
}
|
201
|
+
break;
|
202
|
+
}
|
203
|
+
case ImageType::IMAGE_TYPE_GRAYSCALE: {
|
204
|
+
uint8_t gray = static_cast<uint8_t>(0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b);
|
205
|
+
if (this->has_transparency()) {
|
206
|
+
if (gray == 1) {
|
207
|
+
gray = 0;
|
208
|
+
}
|
209
|
+
if (color.w < 0x80) {
|
210
|
+
gray = 1;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
this->buffer_[pos] = gray;
|
214
|
+
break;
|
215
|
+
}
|
216
|
+
case ImageType::IMAGE_TYPE_RGB565: {
|
217
|
+
uint16_t col565 = display::ColorUtil::color_to_565(color);
|
218
|
+
if (this->has_transparency()) {
|
219
|
+
if (col565 == 0x0020) {
|
220
|
+
col565 = 0;
|
221
|
+
}
|
222
|
+
if (color.w < 0x80) {
|
223
|
+
col565 = 0x0020;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
this->buffer_[pos + 0] = static_cast<uint8_t>((col565 >> 8) & 0xFF);
|
227
|
+
this->buffer_[pos + 1] = static_cast<uint8_t>(col565 & 0xFF);
|
228
|
+
break;
|
229
|
+
}
|
230
|
+
case ImageType::IMAGE_TYPE_RGBA: {
|
231
|
+
this->buffer_[pos + 0] = color.r;
|
232
|
+
this->buffer_[pos + 1] = color.g;
|
233
|
+
this->buffer_[pos + 2] = color.b;
|
234
|
+
this->buffer_[pos + 3] = color.w;
|
235
|
+
break;
|
236
|
+
}
|
237
|
+
case ImageType::IMAGE_TYPE_RGB24:
|
238
|
+
default: {
|
239
|
+
if (this->has_transparency()) {
|
240
|
+
if (color.b == 1 && color.r == 0 && color.g == 0) {
|
241
|
+
color.b = 0;
|
242
|
+
}
|
243
|
+
if (color.w < 0x80) {
|
244
|
+
color.r = 0;
|
245
|
+
color.g = 0;
|
246
|
+
color.b = 1;
|
247
|
+
}
|
248
|
+
}
|
249
|
+
this->buffer_[pos + 0] = color.r;
|
250
|
+
this->buffer_[pos + 1] = color.g;
|
251
|
+
this->buffer_[pos + 2] = color.b;
|
252
|
+
break;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
void OnlineImage::end_connection_() {
|
258
|
+
if (this->downloader_) {
|
259
|
+
this->downloader_->end();
|
260
|
+
this->downloader_ = nullptr;
|
261
|
+
}
|
262
|
+
this->decoder_.reset();
|
263
|
+
this->download_buffer_.reset();
|
264
|
+
}
|
265
|
+
|
266
|
+
bool OnlineImage::validate_url_(const std::string &url) {
|
267
|
+
if ((url.length() < 8) || (url.find("http") != 0) || (url.find("://") == std::string::npos)) {
|
268
|
+
ESP_LOGE(TAG, "URL is invalid and/or must be prefixed with 'http://' or 'https://'");
|
269
|
+
return false;
|
270
|
+
}
|
271
|
+
return true;
|
272
|
+
}
|
273
|
+
|
274
|
+
void OnlineImage::add_on_finished_callback(std::function<void()> &&callback) {
|
275
|
+
this->download_finished_callback_.add(std::move(callback));
|
276
|
+
}
|
277
|
+
|
278
|
+
void OnlineImage::add_on_error_callback(std::function<void()> &&callback) {
|
279
|
+
this->download_error_callback_.add(std::move(callback));
|
280
|
+
}
|
281
|
+
|
282
|
+
} // namespace online_image
|
283
|
+
} // namespace esphome
|
@@ -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
|
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_; }
|
@@ -72,43 +72,44 @@ void PMWCS3Component::dump_config() {
|
|
72
72
|
LOG_SENSOR(" ", "vwc", this->vwc_sensor_);
|
73
73
|
}
|
74
74
|
void PMWCS3Component::read_data_() {
|
75
|
-
uint8_t data[8];
|
76
|
-
float e25, ec, temperature, vwc;
|
77
|
-
|
78
75
|
/////// Super important !!!! first activate reading PMWCS3_REG_READ_START (if not, return always the same values) ////
|
79
|
-
|
80
76
|
if (!this->write_bytes(PMWCS3_REG_READ_START, nullptr, 0)) {
|
81
77
|
this->status_set_warning();
|
82
78
|
ESP_LOGVV(TAG, "Failed to write into REG_READ_START register !!!");
|
83
79
|
return;
|
84
80
|
}
|
85
|
-
// NOLINT delay(100);
|
86
81
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
82
|
+
// Wait for the sensor to be ready.
|
83
|
+
// 80ms empirically determined (conservative).
|
84
|
+
this->set_timeout(80, [this] {
|
85
|
+
uint8_t data[8];
|
86
|
+
float e25, ec, temperature, vwc;
|
87
|
+
if (!this->read_bytes(PMWCS3_REG_GET_DATA, (uint8_t *) &data, 8)) {
|
88
|
+
ESP_LOGVV(TAG, "Error reading PMWCS3_REG_GET_DATA registers");
|
89
|
+
this->mark_failed();
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
if (this->e25_sensor_ != nullptr) {
|
93
|
+
e25 = ((data[1] << 8) | data[0]) / 100.0;
|
94
|
+
this->e25_sensor_->publish_state(e25);
|
95
|
+
ESP_LOGVV(TAG, "e25: data[0]=%d, data[1]=%d, result=%f", data[0], data[1], e25);
|
96
|
+
}
|
97
|
+
if (this->ec_sensor_ != nullptr) {
|
98
|
+
ec = ((data[3] << 8) | data[2]) / 10.0;
|
99
|
+
this->ec_sensor_->publish_state(ec);
|
100
|
+
ESP_LOGVV(TAG, "ec: data[2]=%d, data[3]=%d, result=%f", data[2], data[3], ec);
|
101
|
+
}
|
102
|
+
if (this->temperature_sensor_ != nullptr) {
|
103
|
+
temperature = ((data[5] << 8) | data[4]) / 100.0;
|
104
|
+
this->temperature_sensor_->publish_state(temperature);
|
105
|
+
ESP_LOGVV(TAG, "temp: data[4]=%d, data[5]=%d, result=%f", data[4], data[5], temperature);
|
106
|
+
}
|
107
|
+
if (this->vwc_sensor_ != nullptr) {
|
108
|
+
vwc = ((data[7] << 8) | data[6]) / 10.0;
|
109
|
+
this->vwc_sensor_->publish_state(vwc);
|
110
|
+
ESP_LOGVV(TAG, "vwc: data[6]=%d, data[7]=%d, result=%f", data[6], data[7], vwc);
|
111
|
+
}
|
112
|
+
});
|
112
113
|
}
|
113
114
|
|
114
115
|
} // namespace pmwcs3
|