esphome 2025.4.1__py3-none-any.whl → 2025.5.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 +16 -14
- esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
- esphome/components/adc/__init__.py +51 -34
- esphome/components/airthings_wave_base/__init__.py +1 -1
- esphome/components/alarm_control_panel/__init__.py +37 -2
- esphome/components/am43/cover/__init__.py +4 -5
- esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
- esphome/components/analog_threshold/binary_sensor.py +10 -8
- esphome/components/anova/climate.py +4 -5
- esphome/components/api/__init__.py +25 -8
- esphome/components/api/api_connection.cpp +416 -662
- esphome/components/api/api_connection.h +256 -57
- esphome/components/api/api_frame_helper.cpp +232 -177
- esphome/components/api/api_frame_helper.h +61 -8
- esphome/components/api/api_noise_context.h +13 -4
- esphome/components/api/api_pb2.cpp +1422 -1
- esphome/components/api/api_pb2.h +255 -1
- esphome/components/api/api_pb2_service.cpp +162 -49
- esphome/components/api/api_pb2_service.h +90 -51
- esphome/components/api/api_pb2_size.h +361 -0
- esphome/components/api/api_server.cpp +110 -34
- esphome/components/api/api_server.h +8 -0
- esphome/components/api/proto.h +86 -17
- esphome/components/as3935_i2c/as3935_i2c.h +0 -3
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/at581x/at581x.h +4 -4
- esphome/components/atm90e32/__init__.py +1 -0
- esphome/components/atm90e32/atm90e32.cpp +576 -199
- esphome/components/atm90e32/atm90e32.h +128 -31
- esphome/components/atm90e32/atm90e32_reg.h +4 -2
- esphome/components/atm90e32/button/__init__.py +62 -10
- esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
- esphome/components/atm90e32/button/atm90e32_button.h +36 -4
- esphome/components/atm90e32/number/__init__.py +130 -0
- esphome/components/atm90e32/number/atm90e32_number.h +16 -0
- esphome/components/atm90e32/sensor.py +21 -4
- esphome/components/atm90e32/text_sensor/__init__.py +48 -0
- esphome/components/audio/__init__.py +96 -49
- esphome/components/audio/audio.h +48 -0
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_resampler.cpp +2 -0
- esphome/components/audio/audio_resampler.h +1 -0
- esphome/components/ballu/climate.py +2 -9
- esphome/components/bang_bang/climate.py +5 -6
- esphome/components/bedjet/bedjet_hub.cpp +1 -0
- esphome/components/bedjet/climate/__init__.py +3 -8
- esphome/components/bedjet/fan/__init__.py +2 -11
- esphome/components/binary/fan/__init__.py +13 -16
- esphome/components/binary_sensor/__init__.py +13 -10
- esphome/components/bl0906/constants.h +16 -16
- esphome/components/ble_client/text_sensor/__init__.py +3 -5
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
- esphome/components/button/__init__.py +11 -8
- esphome/components/canbus/canbus.cpp +3 -0
- esphome/components/canbus/canbus.h +16 -0
- esphome/components/ccs811/sensor.py +9 -6
- esphome/components/climate/__init__.py +35 -2
- esphome/components/climate/climate_mode.h +1 -1
- esphome/components/climate/climate_traits.h +63 -57
- esphome/components/climate_ir/__init__.py +57 -17
- esphome/components/climate_ir_lg/climate.py +2 -5
- esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
- esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
- esphome/components/color/__init__.py +2 -0
- esphome/components/const/__init__.py +5 -0
- esphome/components/coolix/climate.py +2 -9
- esphome/components/copy/cover/__init__.py +10 -9
- esphome/components/copy/fan/__init__.py +11 -9
- esphome/components/copy/lock/__init__.py +11 -9
- esphome/components/copy/text/__init__.py +9 -6
- esphome/components/cover/__init__.py +37 -2
- esphome/components/cse7766/cse7766.cpp +2 -1
- esphome/components/cst226/binary_sensor/__init__.py +28 -0
- esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
- esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
- esphome/components/current_based/cover.py +37 -36
- esphome/components/current_based/current_based_cover.cpp +2 -1
- esphome/components/daikin/climate.py +2 -9
- esphome/components/daikin/daikin.cpp +15 -9
- esphome/components/daikin/daikin.h +5 -5
- esphome/components/daikin_arc/climate.py +2 -7
- esphome/components/daikin_brc/climate.py +3 -5
- esphome/components/dallas_temp/dallas_temp.cpp +17 -24
- esphome/components/dallas_temp/dallas_temp.h +0 -1
- esphome/components/daly_bms/daly_bms.cpp +2 -1
- esphome/components/debug/debug_component.cpp +6 -1
- esphome/components/debug/debug_component.h +8 -0
- esphome/components/debug/debug_esp32.cpp +109 -254
- esphome/components/debug/sensor.py +14 -0
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
- esphome/components/delonghi/climate.py +2 -9
- esphome/components/demo/__init__.py +18 -20
- esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
- esphome/components/display/rect.cpp +4 -9
- esphome/components/display/rect.h +1 -1
- esphome/components/dps310/sensor.py +6 -6
- esphome/components/ee895/sensor.py +9 -9
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/endstop/endstop_cover.cpp +2 -1
- esphome/components/ens160_base/__init__.py +12 -9
- esphome/components/esp32/__init__.py +60 -3
- esphome/components/esp32/core.cpp +11 -5
- esphome/components/esp32/gpio.cpp +86 -24
- esphome/components/esp32/gpio.py +15 -16
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -1
- esphome/components/esp32/gpio_esp32_c3.py +1 -1
- esphome/components/esp32/gpio_esp32_c6.py +1 -1
- esphome/components/esp32/gpio_esp32_h2.py +1 -1
- esphome/components/esp32_ble/ble.cpp +1 -8
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.cpp +2 -1
- esphome/components/esp32_ble/ble_advertising.h +1 -0
- esphome/components/esp32_ble_server/__init__.py +3 -0
- esphome/components/esp32_ble_tracker/__init__.py +7 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
- esphome/components/esp32_camera/__init__.py +1 -1
- esphome/components/esp32_camera/esp32_camera.cpp +2 -10
- esphome/components/esp32_camera/esp32_camera.h +1 -1
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
- esphome/components/esp32_rmt_led_strip/light.py +9 -1
- esphome/components/esp32_touch/esp32_touch.cpp +1 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/event/__init__.py +13 -10
- esphome/components/factory_reset/switch/__init__.py +7 -21
- esphome/components/fan/__init__.py +52 -5
- esphome/components/fastled_base/__init__.py +1 -4
- esphome/components/fastled_base/fastled_light.cpp +1 -1
- esphome/components/feedback/cover.py +38 -33
- esphome/components/feedback/feedback_cover.cpp +2 -1
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
- esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
- esphome/components/gpio_expander/cached_gpio.h +22 -7
- esphome/components/gps/__init__.py +47 -17
- esphome/components/gps/gps.cpp +42 -23
- esphome/components/gps/gps.h +17 -13
- esphome/components/graph/__init__.py +1 -2
- esphome/components/gree/climate.py +4 -6
- esphome/components/gree/gree.cpp +16 -2
- esphome/components/gree/gree.h +2 -2
- esphome/components/growatt_solar/growatt_solar.cpp +2 -1
- esphome/components/haier/climate.py +37 -34
- esphome/components/hbridge/fan/__init__.py +19 -17
- esphome/components/he60r/cover.py +4 -5
- esphome/components/heatpumpir/climate.py +3 -6
- esphome/components/hitachi_ac344/climate.py +2 -9
- esphome/components/hitachi_ac424/climate.py +2 -9
- esphome/components/hlw8012/hlw8012.cpp +1 -1
- esphome/components/hm3301/hm3301.h +1 -1
- esphome/components/hte501/sensor.py +6 -6
- esphome/components/http_request/__init__.py +39 -6
- esphome/components/http_request/http_request.cpp +20 -0
- esphome/components/http_request/http_request.h +57 -15
- esphome/components/http_request/http_request_arduino.cpp +22 -6
- esphome/components/http_request/http_request_arduino.h +4 -3
- esphome/components/http_request/http_request_host.cpp +141 -0
- esphome/components/http_request/http_request_host.h +37 -0
- esphome/components/http_request/http_request_idf.cpp +35 -3
- esphome/components/http_request/http_request_idf.h +10 -3
- esphome/components/http_request/httplib.h +9691 -0
- esphome/components/http_request/update/__init__.py +11 -8
- esphome/components/hyt271/sensor.py +6 -6
- esphome/components/i2c/i2c.h +4 -0
- esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
- esphome/components/i2s_audio/__init__.py +131 -22
- esphome/components/i2s_audio/i2s_audio.h +44 -4
- esphome/components/i2s_audio/media_player/__init__.py +19 -9
- esphome/components/i2s_audio/microphone/__init__.py +63 -5
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
- esphome/components/i2s_audio/speaker/__init__.py +31 -5
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
- esphome/components/ili9xxx/ili9xxx_init.h +1 -1
- esphome/components/image/__init__.py +37 -17
- esphome/components/image/image.cpp +25 -8
- esphome/components/internal_temperature/internal_temperature.cpp +6 -4
- esphome/components/key_collector/__init__.py +35 -0
- esphome/components/key_collector/key_collector.cpp +8 -0
- esphome/components/key_collector/key_collector.h +10 -0
- esphome/components/kuntze/kuntze.cpp +2 -1
- esphome/components/ld2410/ld2410.h +1 -1
- esphome/components/ld2450/ld2450.h +1 -1
- esphome/components/light/__init__.py +57 -0
- esphome/components/lock/__init__.py +51 -4
- esphome/components/lock/automation.h +2 -13
- esphome/components/logger/__init__.py +22 -0
- esphome/components/logger/logger.cpp +154 -103
- esphome/components/logger/logger.h +211 -36
- esphome/components/logger/task_log_buffer.cpp +138 -0
- esphome/components/logger/task_log_buffer.h +69 -0
- esphome/components/lvgl/__init__.py +13 -5
- esphome/components/lvgl/automation.py +50 -1
- esphome/components/lvgl/defines.py +0 -1
- esphome/components/lvgl/lv_validation.py +10 -1
- esphome/components/lvgl/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/schemas.py +14 -14
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/lvgl/widgets/arc.py +7 -6
- esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
- esphome/components/lvgl/widgets/checkbox.py +2 -2
- esphome/components/lvgl/widgets/dropdown.py +2 -1
- esphome/components/lvgl/widgets/img.py +15 -12
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
- esphome/components/max7219digit/max7219digit.cpp +28 -27
- esphome/components/mdns/__init__.py +11 -5
- esphome/components/mdns/mdns_component.cpp +11 -5
- esphome/components/mdns/mdns_component.h +3 -2
- esphome/components/mdns/mdns_esp32.cpp +4 -3
- esphome/components/mdns/mdns_esp8266.cpp +4 -2
- esphome/components/mdns/mdns_libretiny.cpp +4 -2
- esphome/components/mdns/mdns_rp2040.cpp +4 -2
- esphome/components/media_player/__init__.py +40 -6
- esphome/components/mhz19/sensor.py +11 -7
- esphome/components/micro_wake_word/__init__.py +99 -31
- esphome/components/micro_wake_word/automation.h +54 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
- esphome/components/micro_wake_word/micro_wake_word.h +58 -105
- esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
- esphome/components/micro_wake_word/streaming_model.cpp +158 -41
- esphome/components/micro_wake_word/streaming_model.h +85 -13
- esphome/components/microphone/__init__.py +139 -9
- esphome/components/microphone/automation.h +14 -2
- esphome/components/microphone/microphone.cpp +21 -0
- esphome/components/microphone/microphone.h +14 -5
- esphome/components/microphone/microphone_source.cpp +95 -0
- esphome/components/microphone/microphone_source.h +80 -0
- esphome/components/mics_4514/sensor.py +25 -14
- esphome/components/midea/climate.py +3 -4
- esphome/components/midea_ir/climate.py +3 -5
- esphome/components/mipi_spi/__init__.py +15 -0
- esphome/components/mipi_spi/display.py +474 -0
- esphome/components/mipi_spi/mipi_spi.cpp +481 -0
- esphome/components/mipi_spi/mipi_spi.h +171 -0
- esphome/components/mipi_spi/models/__init__.py +65 -0
- esphome/components/mipi_spi/models/amoled.py +72 -0
- esphome/components/mipi_spi/models/commands.py +82 -0
- esphome/components/mipi_spi/models/cyd.py +10 -0
- esphome/components/mipi_spi/models/ili.py +749 -0
- esphome/components/mipi_spi/models/jc.py +260 -0
- esphome/components/mipi_spi/models/lanbon.py +15 -0
- esphome/components/mipi_spi/models/lilygo.py +60 -0
- esphome/components/mipi_spi/models/waveshare.py +139 -0
- esphome/components/mitsubishi/climate.py +2 -5
- esphome/components/mitsubishi/mitsubishi.cpp +9 -9
- esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
- esphome/components/mixer/speaker/mixer_speaker.h +1 -3
- esphome/components/mlx90393/sensor.py +5 -0
- esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
- esphome/components/mlx90393/sensor_mlx90393.h +21 -4
- esphome/components/modbus/modbus.cpp +2 -1
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +6 -2
- esphome/components/mqtt/mqtt_const.h +4 -0
- esphome/components/mqtt/mqtt_fan.cpp +39 -0
- esphome/components/mqtt/mqtt_fan.h +2 -0
- esphome/components/ms5611/sensor.py +6 -6
- esphome/components/ms8607/sensor.py +3 -3
- esphome/components/network/__init__.py +1 -1
- esphome/components/nextion/base_component.py +17 -16
- esphome/components/nextion/display.py +11 -2
- esphome/components/nextion/nextion.cpp +39 -1
- esphome/components/nextion/nextion.h +50 -0
- esphome/components/noblex/climate.py +2 -9
- esphome/components/number/__init__.py +12 -9
- esphome/components/one_wire/one_wire_bus.cpp +14 -10
- esphome/components/one_wire/one_wire_bus.h +14 -8
- esphome/components/online_image/bmp_image.cpp +48 -11
- esphome/components/online_image/bmp_image.h +2 -0
- esphome/components/opentherm/binary_sensor/__init__.py +2 -4
- esphome/components/opentherm/number/__init__.py +11 -20
- esphome/components/opentherm/sensor/__init__.py +3 -3
- esphome/components/opentherm/switch/__init__.py +3 -5
- esphome/components/output/lock/__init__.py +11 -9
- esphome/components/packages/__init__.py +33 -31
- esphome/components/packet_transport/__init__.py +201 -0
- esphome/components/packet_transport/binary_sensor.py +19 -0
- esphome/components/packet_transport/packet_transport.cpp +534 -0
- esphome/components/packet_transport/packet_transport.h +154 -0
- esphome/components/packet_transport/sensor.py +19 -0
- esphome/components/pca9685/pca9685_output.cpp +2 -1
- esphome/components/pid/climate.py +2 -4
- esphome/components/pm2005/__init__.py +1 -0
- esphome/components/pm2005/pm2005.cpp +123 -0
- esphome/components/pm2005/pm2005.h +46 -0
- esphome/components/pm2005/sensor.py +86 -0
- esphome/components/pmsa003i/pmsa003i.cpp +43 -16
- esphome/components/pmsa003i/pmsa003i.h +25 -25
- esphome/components/pmsx003/pmsx003.cpp +195 -230
- esphome/components/pmsx003/pmsx003.h +51 -33
- esphome/components/pmsx003/sensor.py +21 -11
- esphome/components/pn7150/pn7150.h +2 -2
- esphome/components/pn7160/pn7160.h +2 -2
- esphome/components/prometheus/prometheus_handler.cpp +174 -0
- esphome/components/prometheus/prometheus_handler.h +17 -0
- esphome/components/psram/__init__.py +7 -5
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
- esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
- esphome/components/pzem004t/pzem004t.cpp +2 -1
- esphome/components/qspi_dbi/__init__.py +0 -1
- esphome/components/qspi_dbi/display.py +2 -1
- esphome/components/qspi_dbi/models.py +1 -2
- esphome/components/remote_base/__init__.py +91 -0
- esphome/components/remote_base/beo4_protocol.cpp +153 -0
- esphome/components/remote_base/beo4_protocol.h +43 -0
- esphome/components/remote_base/gobox_protocol.cpp +131 -0
- esphome/components/remote_base/gobox_protocol.h +54 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
- esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
- esphome/components/resampler/speaker/resampler_speaker.h +1 -1
- esphome/components/rf_bridge/rf_bridge.cpp +2 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/sds011/sds011.cpp +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sen5x.cpp +55 -36
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp30/sensor.py +14 -16
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/shtcx/sensor.py +6 -6
- esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
- esphome/components/sml/text_sensor/__init__.py +4 -6
- esphome/components/sound_level/__init__.py +0 -0
- esphome/components/sound_level/sensor.py +97 -0
- esphome/components/sound_level/sound_level.cpp +194 -0
- esphome/components/sound_level/sound_level.h +73 -0
- esphome/components/speaker/media_player/__init__.py +4 -8
- esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
- esphome/components/speaker/media_player/speaker_media_player.h +0 -11
- esphome/components/speaker/speaker.h +4 -7
- esphome/components/speed/fan/__init__.py +17 -16
- esphome/components/spi/spi.h +11 -1
- esphome/components/sprinkler/__init__.py +18 -19
- esphome/components/sprinkler/sprinkler.cpp +6 -5
- esphome/components/switch/__init__.py +32 -42
- esphome/components/syslog/__init__.py +41 -0
- esphome/components/syslog/esphome_syslog.cpp +49 -0
- esphome/components/syslog/esphome_syslog.h +27 -0
- esphome/components/t6615/sensor.py +3 -3
- esphome/components/t6615/t6615.cpp +2 -1
- esphome/components/tca9555/tca9555.cpp +11 -6
- esphome/components/tcl112/climate.py +2 -9
- esphome/components/template/alarm_control_panel/__init__.py +7 -6
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
- esphome/components/template/cover/__init__.py +27 -21
- esphome/components/template/fan/__init__.py +14 -12
- esphome/components/template/lock/__init__.py +20 -25
- esphome/components/template/lock/automation.h +18 -0
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/valve/__init__.py +32 -21
- esphome/components/template/valve/automation.h +24 -0
- esphome/components/text/__init__.py +32 -1
- esphome/components/text_sensor/__init__.py +24 -29
- esphome/components/thermostat/climate.py +5 -5
- esphome/components/time_based/cover.py +17 -16
- esphome/components/time_based/time_based_cover.cpp +2 -1
- esphome/components/tm1638/switch/__init__.py +10 -7
- esphome/components/tormatic/cover.py +4 -5
- esphome/components/toshiba/climate.py +3 -5
- esphome/components/touchscreen/touchscreen.cpp +3 -1
- esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
- esphome/components/tuya/climate/__init__.py +5 -6
- esphome/components/tuya/cover/__init__.py +6 -11
- esphome/components/tuya/select/__init__.py +15 -5
- esphome/components/tuya/select/tuya_select.cpp +6 -1
- esphome/components/tuya/select/tuya_select.h +5 -1
- esphome/components/uart/packet_transport/__init__.py +20 -0
- esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
- esphome/components/uart/packet_transport/uart_transport.h +41 -0
- esphome/components/uart/switch/uart_switch.cpp +2 -1
- esphome/components/udp/__init__.py +126 -128
- esphome/components/udp/automation.h +40 -0
- esphome/components/udp/binary_sensor.py +3 -25
- esphome/components/udp/packet_transport/__init__.py +29 -0
- esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
- esphome/components/udp/packet_transport/udp_transport.h +28 -0
- esphome/components/udp/sensor.py +3 -25
- esphome/components/udp/udp_component.cpp +26 -470
- esphome/components/udp/udp_component.h +21 -128
- esphome/components/update/__init__.py +31 -1
- esphome/components/uponor_smatrix/climate/__init__.py +4 -9
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- esphome/components/uptime/text_sensor/__init__.py +47 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
- esphome/components/valve/__init__.py +34 -3
- esphome/components/valve/automation.h +1 -19
- esphome/components/vl53l0x/sensor.py +11 -0
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
- esphome/components/voice_assistant/__init__.py +36 -10
- esphome/components/voice_assistant/voice_assistant.cpp +170 -144
- esphome/components/voice_assistant/voice_assistant.h +26 -25
- esphome/components/waveshare_epaper/display.py +6 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
- esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
- esphome/components/weikai/weikai.cpp +0 -52
- esphome/components/whirlpool/climate.py +3 -5
- esphome/components/whynter/climate.py +3 -5
- esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
- esphome/components/yashima/climate.py +6 -6
- esphome/components/zhlt01/climate.py +2 -7
- esphome/config.py +13 -13
- esphome/config_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +27 -10
- esphome/core/application.h +9 -1
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +28 -7
- esphome/core/component.h +10 -1
- esphome/core/defines.h +23 -17
- esphome/core/doxygen.h +13 -0
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +7 -1
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/log.py +15 -19
- esphome/mqtt.py +23 -10
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/voluptuous_schema.py +3 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +47 -37
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/RECORD +456 -396
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
- esphome/components/esp32_ble/const_esp32c6.h +0 -74
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -1,62 +1,57 @@
|
|
1
1
|
#include "pmsx003.h"
|
2
2
|
#include "esphome/core/log.h"
|
3
|
+
#include "esphome/core/application.h"
|
3
4
|
|
4
5
|
namespace esphome {
|
5
6
|
namespace pmsx003 {
|
6
7
|
|
7
8
|
static const char *const TAG = "pmsx003";
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
}
|
12
|
-
void PMSX003Component::set_pm_2_5_std_sensor(sensor::Sensor *pm_2_5_std_sensor) {
|
13
|
-
pm_2_5_std_sensor_ = pm_2_5_std_sensor;
|
14
|
-
}
|
15
|
-
void PMSX003Component::set_pm_10_0_std_sensor(sensor::Sensor *pm_10_0_std_sensor) {
|
16
|
-
pm_10_0_std_sensor_ = pm_10_0_std_sensor;
|
17
|
-
}
|
10
|
+
static const uint8_t START_CHARACTER_1 = 0x42;
|
11
|
+
static const uint8_t START_CHARACTER_2 = 0x4D;
|
18
12
|
|
19
|
-
|
20
|
-
void PMSX003Component::set_pm_2_5_sensor(sensor::Sensor *pm_2_5_sensor) { pm_2_5_sensor_ = pm_2_5_sensor; }
|
21
|
-
void PMSX003Component::set_pm_10_0_sensor(sensor::Sensor *pm_10_0_sensor) { pm_10_0_sensor_ = pm_10_0_sensor; }
|
13
|
+
static const uint16_t PMS_STABILISING_MS = 30000; // time taken for the sensor to become stable after power on in ms
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
}
|
29
|
-
void PMSX003Component::set_pm_particles_10um_sensor(sensor::Sensor *pm_particles_10um_sensor) {
|
30
|
-
pm_particles_10um_sensor_ = pm_particles_10um_sensor;
|
31
|
-
}
|
32
|
-
void PMSX003Component::set_pm_particles_25um_sensor(sensor::Sensor *pm_particles_25um_sensor) {
|
33
|
-
pm_particles_25um_sensor_ = pm_particles_25um_sensor;
|
34
|
-
}
|
35
|
-
void PMSX003Component::set_pm_particles_50um_sensor(sensor::Sensor *pm_particles_50um_sensor) {
|
36
|
-
pm_particles_50um_sensor_ = pm_particles_50um_sensor;
|
37
|
-
}
|
38
|
-
void PMSX003Component::set_pm_particles_100um_sensor(sensor::Sensor *pm_particles_100um_sensor) {
|
39
|
-
pm_particles_100um_sensor_ = pm_particles_100um_sensor;
|
40
|
-
}
|
15
|
+
static const uint16_t PMS_CMD_MEASUREMENT_MODE_PASSIVE =
|
16
|
+
0x0000; // use `PMS_CMD_MANUAL_MEASUREMENT` to trigger a measurement
|
17
|
+
static const uint16_t PMS_CMD_MEASUREMENT_MODE_ACTIVE = 0x0001; // automatically perform measurements
|
18
|
+
static const uint16_t PMS_CMD_SLEEP_MODE_SLEEP = 0x0000; // go to sleep mode
|
19
|
+
static const uint16_t PMS_CMD_SLEEP_MODE_WAKEUP = 0x0001; // wake up from sleep mode
|
41
20
|
|
42
|
-
void PMSX003Component::
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
21
|
+
void PMSX003Component::dump_config() {
|
22
|
+
ESP_LOGCONFIG(TAG, "PMSX003:");
|
23
|
+
LOG_SENSOR(" ", "PM1.0STD", this->pm_1_0_std_sensor_);
|
24
|
+
LOG_SENSOR(" ", "PM2.5STD", this->pm_2_5_std_sensor_);
|
25
|
+
LOG_SENSOR(" ", "PM10.0STD", this->pm_10_0_std_sensor_);
|
26
|
+
|
27
|
+
LOG_SENSOR(" ", "PM1.0", this->pm_1_0_sensor_);
|
28
|
+
LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_);
|
29
|
+
LOG_SENSOR(" ", "PM10.0", this->pm_10_0_sensor_);
|
30
|
+
|
31
|
+
LOG_SENSOR(" ", "PM0.3um", this->pm_particles_03um_sensor_);
|
32
|
+
LOG_SENSOR(" ", "PM0.5um", this->pm_particles_05um_sensor_);
|
33
|
+
LOG_SENSOR(" ", "PM1.0um", this->pm_particles_10um_sensor_);
|
34
|
+
LOG_SENSOR(" ", "PM2.5um", this->pm_particles_25um_sensor_);
|
35
|
+
LOG_SENSOR(" ", "PM5.0um", this->pm_particles_50um_sensor_);
|
36
|
+
LOG_SENSOR(" ", "PM10.0um", this->pm_particles_100um_sensor_);
|
37
|
+
|
38
|
+
LOG_SENSOR(" ", "Formaldehyde", this->formaldehyde_sensor_);
|
39
|
+
|
40
|
+
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
41
|
+
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
|
42
|
+
this->check_uart_settings(9600);
|
48
43
|
}
|
49
44
|
|
50
45
|
void PMSX003Component::loop() {
|
51
|
-
const uint32_t now =
|
46
|
+
const uint32_t now = App.get_loop_component_start_time();
|
52
47
|
|
53
48
|
// If we update less often than it takes the device to stabilise, spin the fan down
|
54
49
|
// rather than running it constantly. It does take some time to stabilise, so we
|
55
50
|
// need to keep track of what state we're in.
|
56
51
|
if (this->update_interval_ > PMS_STABILISING_MS) {
|
57
52
|
if (this->initialised_ == 0) {
|
58
|
-
this->send_command_(
|
59
|
-
this->send_command_(
|
53
|
+
this->send_command_(PMS_CMD_MEASUREMENT_MODE, PMS_CMD_MEASUREMENT_MODE_PASSIVE);
|
54
|
+
this->send_command_(PMS_CMD_SLEEP_MODE, PMS_CMD_SLEEP_MODE_WAKEUP);
|
60
55
|
this->initialised_ = 1;
|
61
56
|
}
|
62
57
|
switch (this->state_) {
|
@@ -66,7 +61,7 @@ void PMSX003Component::loop() {
|
|
66
61
|
return;
|
67
62
|
|
68
63
|
this->state_ = PMSX003_STATE_STABILISING;
|
69
|
-
this->send_command_(
|
64
|
+
this->send_command_(PMS_CMD_SLEEP_MODE, PMS_CMD_SLEEP_MODE_WAKEUP);
|
70
65
|
this->fan_on_time_ = now;
|
71
66
|
return;
|
72
67
|
case PMSX003_STATE_STABILISING:
|
@@ -77,7 +72,7 @@ void PMSX003Component::loop() {
|
|
77
72
|
while (this->available())
|
78
73
|
this->read_byte(&this->data_[0]);
|
79
74
|
// Trigger a new read
|
80
|
-
this->send_command_(
|
75
|
+
this->send_command_(PMS_CMD_MANUAL_MEASUREMENT, 0);
|
81
76
|
this->state_ = PMSX003_STATE_WAITING;
|
82
77
|
break;
|
83
78
|
case PMSX003_STATE_WAITING:
|
@@ -116,242 +111,212 @@ void PMSX003Component::loop() {
|
|
116
111
|
}
|
117
112
|
}
|
118
113
|
}
|
119
|
-
|
114
|
+
|
120
115
|
optional<bool> PMSX003Component::check_byte_() {
|
121
|
-
uint8_t index = this->data_index_;
|
122
|
-
uint8_t byte = this->data_[index];
|
116
|
+
const uint8_t index = this->data_index_;
|
117
|
+
const uint8_t byte = this->data_[index];
|
123
118
|
|
124
|
-
if (index == 0)
|
125
|
-
|
119
|
+
if (index == 0 || index == 1) {
|
120
|
+
const uint8_t start_char = index == 0 ? START_CHARACTER_1 : START_CHARACTER_2;
|
121
|
+
if (byte == start_char) {
|
122
|
+
return true;
|
123
|
+
}
|
126
124
|
|
127
|
-
|
128
|
-
return
|
125
|
+
ESP_LOGW(TAG, "Start character %u mismatch: 0x%02X != 0x%02X", index + 1, byte, START_CHARACTER_1);
|
126
|
+
return false;
|
127
|
+
}
|
129
128
|
|
130
|
-
if (index == 2)
|
129
|
+
if (index == 2) {
|
131
130
|
return true;
|
131
|
+
}
|
132
132
|
|
133
|
-
uint16_t payload_length = this->get_16_bit_uint_(2);
|
133
|
+
const uint16_t payload_length = this->get_16_bit_uint_(2);
|
134
134
|
if (index == 3) {
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
break;
|
140
|
-
case PMSX003_TYPE_5003T:
|
141
|
-
case PMSX003_TYPE_5003S:
|
142
|
-
length_matches = payload_length == 28;
|
143
|
-
break;
|
144
|
-
case PMSX003_TYPE_5003ST:
|
145
|
-
length_matches = payload_length == 36;
|
146
|
-
break;
|
147
|
-
}
|
148
|
-
|
149
|
-
if (!length_matches) {
|
150
|
-
ESP_LOGW(TAG, "PMSX003 length %u doesn't match. Are you using the correct PMSX003 type?", payload_length);
|
135
|
+
if (this->check_payload_length_(payload_length)) {
|
136
|
+
return true;
|
137
|
+
} else {
|
138
|
+
ESP_LOGW(TAG, "Payload length %u doesn't match. Are you using the correct PMSX003 type?", payload_length);
|
151
139
|
return false;
|
152
140
|
}
|
153
|
-
return true;
|
154
141
|
}
|
155
142
|
|
156
|
-
// start (16bit) + length (16bit) + DATA (payload_length-
|
157
|
-
|
143
|
+
// start (16bit) + length (16bit) + DATA (payload_length - 16bit) + checksum (16bit)
|
144
|
+
const uint16_t total_size = 4 + payload_length;
|
158
145
|
|
159
|
-
if (index < total_size - 1)
|
146
|
+
if (index < total_size - 1) {
|
160
147
|
return true;
|
148
|
+
}
|
161
149
|
|
162
150
|
// checksum is without checksum bytes
|
163
151
|
uint16_t checksum = 0;
|
164
|
-
for (
|
152
|
+
for (uint16_t i = 0; i < total_size - 2; i++) {
|
165
153
|
checksum += this->data_[i];
|
154
|
+
}
|
166
155
|
|
167
|
-
uint16_t check = this->get_16_bit_uint_(total_size - 2);
|
156
|
+
const uint16_t check = this->get_16_bit_uint_(total_size - 2);
|
168
157
|
if (checksum != check) {
|
169
|
-
ESP_LOGW(TAG, "PMSX003 checksum mismatch! 0x%02X!=0x%02X", checksum, check);
|
158
|
+
ESP_LOGW(TAG, "PMSX003 checksum mismatch! 0x%02X != 0x%02X", checksum, check);
|
170
159
|
return false;
|
171
160
|
}
|
172
161
|
|
173
162
|
return {};
|
174
163
|
}
|
175
164
|
|
176
|
-
|
177
|
-
this->
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
165
|
+
bool PMSX003Component::check_payload_length_(uint16_t payload_length) {
|
166
|
+
switch (this->type_) {
|
167
|
+
case PMSX003_TYPE_X003:
|
168
|
+
// The expected payload length is typically 28 bytes.
|
169
|
+
// However, a 20-byte payload check was already present in the code.
|
170
|
+
// No official documentation was found confirming this.
|
171
|
+
// Retaining this check to avoid breaking existing behavior.
|
172
|
+
return payload_length == 28 || payload_length == 20; // 2*13+2
|
173
|
+
case PMSX003_TYPE_5003T:
|
174
|
+
case PMSX003_TYPE_5003S:
|
175
|
+
return payload_length == 28; // 2*13+2 (Data 13 not set/reserved)
|
176
|
+
case PMSX003_TYPE_5003ST:
|
177
|
+
return payload_length == 36; // 2*17+2 (Data 16 not set/reserved)
|
186
178
|
}
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
179
|
+
return false;
|
180
|
+
}
|
181
|
+
|
182
|
+
void PMSX003Component::send_command_(PMSX0003Command cmd, uint16_t data) {
|
183
|
+
uint8_t send_data[7] = {
|
184
|
+
START_CHARACTER_1, // Start Byte 1
|
185
|
+
START_CHARACTER_2, // Start Byte 2
|
186
|
+
cmd, // Command
|
187
|
+
uint8_t((data >> 8) & 0xFF), // Data 1
|
188
|
+
uint8_t((data >> 0) & 0xFF), // Data 2
|
189
|
+
0, // Verify Byte 1
|
190
|
+
0, // Verify Byte 2
|
191
|
+
};
|
192
|
+
|
193
|
+
// Calculate checksum
|
194
|
+
uint16_t checksum = 0;
|
195
|
+
for (uint8_t i = 0; i < 5; i++) {
|
196
|
+
checksum += send_data[i];
|
197
|
+
}
|
198
|
+
send_data[5] = (checksum >> 8) & 0xFF; // Verify Byte 1
|
199
|
+
send_data[6] = (checksum >> 0) & 0xFF; // Verify Byte 2
|
200
|
+
|
201
|
+
for (auto send_byte : send_data) {
|
202
|
+
this->write_byte(send_byte);
|
191
203
|
}
|
192
|
-
this->data_index_ = 0;
|
193
204
|
}
|
194
205
|
|
195
206
|
void PMSX003Component::parse_data_() {
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
207
|
+
// Particle Matter
|
208
|
+
const uint16_t pm_1_0_std_concentration = this->get_16_bit_uint_(4);
|
209
|
+
const uint16_t pm_2_5_std_concentration = this->get_16_bit_uint_(6);
|
210
|
+
const uint16_t pm_10_0_std_concentration = this->get_16_bit_uint_(8);
|
211
|
+
|
212
|
+
const uint16_t pm_1_0_concentration = this->get_16_bit_uint_(10);
|
213
|
+
const uint16_t pm_2_5_concentration = this->get_16_bit_uint_(12);
|
214
|
+
const uint16_t pm_10_0_concentration = this->get_16_bit_uint_(14);
|
215
|
+
|
216
|
+
const uint16_t pm_particles_03um = this->get_16_bit_uint_(16);
|
217
|
+
const uint16_t pm_particles_05um = this->get_16_bit_uint_(18);
|
218
|
+
const uint16_t pm_particles_10um = this->get_16_bit_uint_(20);
|
219
|
+
const uint16_t pm_particles_25um = this->get_16_bit_uint_(22);
|
220
|
+
|
221
|
+
ESP_LOGD(TAG,
|
222
|
+
"Got PM1.0 Standard Concentration: %u µg/m³, PM2.5 Standard Concentration %u µg/m³, PM10.0 Standard "
|
223
|
+
"Concentration: %u µg/m³, PM1.0 Concentration: %u µg/m³, PM2.5 Concentration %u µg/m³, PM10.0 "
|
224
|
+
"Concentration: %u µg/m³",
|
225
|
+
pm_1_0_std_concentration, pm_2_5_std_concentration, pm_10_0_std_concentration, pm_1_0_concentration,
|
226
|
+
pm_2_5_concentration, pm_10_0_concentration);
|
227
|
+
|
228
|
+
if (this->pm_1_0_std_sensor_ != nullptr)
|
229
|
+
this->pm_1_0_std_sensor_->publish_state(pm_1_0_std_concentration);
|
230
|
+
if (this->pm_2_5_std_sensor_ != nullptr)
|
231
|
+
this->pm_2_5_std_sensor_->publish_state(pm_2_5_std_concentration);
|
232
|
+
if (this->pm_10_0_std_sensor_ != nullptr)
|
233
|
+
this->pm_10_0_std_sensor_->publish_state(pm_10_0_std_concentration);
|
234
|
+
|
235
|
+
if (this->pm_1_0_sensor_ != nullptr)
|
236
|
+
this->pm_1_0_sensor_->publish_state(pm_1_0_concentration);
|
237
|
+
if (this->pm_2_5_sensor_ != nullptr)
|
238
|
+
this->pm_2_5_sensor_->publish_state(pm_2_5_concentration);
|
239
|
+
if (this->pm_10_0_sensor_ != nullptr)
|
240
|
+
this->pm_10_0_sensor_->publish_state(pm_10_0_concentration);
|
241
|
+
|
242
|
+
if (this->pm_particles_03um_sensor_ != nullptr)
|
243
|
+
this->pm_particles_03um_sensor_->publish_state(pm_particles_03um);
|
244
|
+
if (this->pm_particles_05um_sensor_ != nullptr)
|
245
|
+
this->pm_particles_05um_sensor_->publish_state(pm_particles_05um);
|
246
|
+
if (this->pm_particles_10um_sensor_ != nullptr)
|
247
|
+
this->pm_particles_10um_sensor_->publish_state(pm_particles_10um);
|
248
|
+
if (this->pm_particles_25um_sensor_ != nullptr)
|
249
|
+
this->pm_particles_25um_sensor_->publish_state(pm_particles_25um);
|
250
|
+
|
251
|
+
if (this->type_ == PMSX003_TYPE_5003T) {
|
252
|
+
ESP_LOGD(TAG,
|
253
|
+
"Got PM0.3 Particles: %u Count/0.1L, PM0.5 Particles: %u Count/0.1L, PM1.0 Particles: %u Count/0.1L, "
|
254
|
+
"PM2.5 Particles %u Count/0.1L",
|
255
|
+
pm_particles_03um, pm_particles_05um, pm_particles_10um, pm_particles_25um);
|
256
|
+
} else {
|
257
|
+
// Note the pm particles 50um & 100um are not returned,
|
258
|
+
// as PMS5003T uses those data values for temperature and humidity.
|
259
|
+
const uint16_t pm_particles_50um = this->get_16_bit_uint_(24);
|
260
|
+
const uint16_t pm_particles_100um = this->get_16_bit_uint_(26);
|
261
|
+
|
262
|
+
ESP_LOGD(TAG,
|
263
|
+
"Got PM0.3 Particles: %u Count/0.1L, PM0.5 Particles: %u Count/0.1L, PM1.0 Particles: %u Count/0.1L, "
|
264
|
+
"PM2.5 Particles %u Count/0.1L, PM5.0 Particles: %u Count/0.1L, PM10.0 Particles %u Count/0.1L",
|
265
|
+
pm_particles_03um, pm_particles_05um, pm_particles_10um, pm_particles_25um, pm_particles_50um,
|
266
|
+
pm_particles_100um);
|
267
|
+
|
268
|
+
if (this->pm_particles_50um_sensor_ != nullptr)
|
269
|
+
this->pm_particles_50um_sensor_->publish_state(pm_particles_50um);
|
270
|
+
if (this->pm_particles_100um_sensor_ != nullptr)
|
271
|
+
this->pm_particles_100um_sensor_->publish_state(pm_particles_100um);
|
272
|
+
}
|
200
273
|
|
201
|
-
|
274
|
+
// Formaldehyde
|
275
|
+
if (this->type_ == PMSX003_TYPE_5003ST || this->type_ == PMSX003_TYPE_5003S) {
|
276
|
+
const uint16_t formaldehyde = this->get_16_bit_uint_(28);
|
202
277
|
|
203
|
-
|
204
|
-
this->temperature_sensor_->publish_state(temperature);
|
205
|
-
if (this->humidity_sensor_ != nullptr)
|
206
|
-
this->humidity_sensor_->publish_state(humidity);
|
207
|
-
// The rest of the PMS5003ST matches the PMS5003S, continue on
|
208
|
-
}
|
209
|
-
case PMSX003_TYPE_5003S: {
|
210
|
-
uint16_t formaldehyde = this->get_16_bit_uint_(28);
|
278
|
+
ESP_LOGD(TAG, "Got Formaldehyde: %u µg/m^3", formaldehyde);
|
211
279
|
|
212
|
-
|
280
|
+
if (this->formaldehyde_sensor_ != nullptr)
|
281
|
+
this->formaldehyde_sensor_->publish_state(formaldehyde);
|
282
|
+
}
|
213
283
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
"Got PM1.0 Concentration: %u µg/m^3, PM2.5 Concentration %u µg/m^3, PM10.0 Concentration: %u µg/m^3",
|
236
|
-
pm_1_0_concentration, pm_2_5_concentration, pm_10_0_concentration);
|
237
|
-
|
238
|
-
if (this->pm_1_0_std_sensor_ != nullptr)
|
239
|
-
this->pm_1_0_std_sensor_->publish_state(pm_1_0_std_concentration);
|
240
|
-
if (this->pm_2_5_std_sensor_ != nullptr)
|
241
|
-
this->pm_2_5_std_sensor_->publish_state(pm_2_5_std_concentration);
|
242
|
-
if (this->pm_10_0_std_sensor_ != nullptr)
|
243
|
-
this->pm_10_0_std_sensor_->publish_state(pm_10_0_std_concentration);
|
244
|
-
|
245
|
-
if (this->pm_1_0_sensor_ != nullptr)
|
246
|
-
this->pm_1_0_sensor_->publish_state(pm_1_0_concentration);
|
247
|
-
if (this->pm_2_5_sensor_ != nullptr)
|
248
|
-
this->pm_2_5_sensor_->publish_state(pm_2_5_concentration);
|
249
|
-
if (this->pm_10_0_sensor_ != nullptr)
|
250
|
-
this->pm_10_0_sensor_->publish_state(pm_10_0_concentration);
|
251
|
-
|
252
|
-
if (this->pm_particles_03um_sensor_ != nullptr)
|
253
|
-
this->pm_particles_03um_sensor_->publish_state(pm_particles_03um);
|
254
|
-
if (this->pm_particles_05um_sensor_ != nullptr)
|
255
|
-
this->pm_particles_05um_sensor_->publish_state(pm_particles_05um);
|
256
|
-
if (this->pm_particles_10um_sensor_ != nullptr)
|
257
|
-
this->pm_particles_10um_sensor_->publish_state(pm_particles_10um);
|
258
|
-
if (this->pm_particles_25um_sensor_ != nullptr)
|
259
|
-
this->pm_particles_25um_sensor_->publish_state(pm_particles_25um);
|
260
|
-
if (this->pm_particles_50um_sensor_ != nullptr)
|
261
|
-
this->pm_particles_50um_sensor_->publish_state(pm_particles_50um);
|
262
|
-
if (this->pm_particles_100um_sensor_ != nullptr)
|
263
|
-
this->pm_particles_100um_sensor_->publish_state(pm_particles_100um);
|
264
|
-
break;
|
265
|
-
}
|
266
|
-
case PMSX003_TYPE_5003T: {
|
267
|
-
uint16_t pm_1_0_std_concentration = this->get_16_bit_uint_(4);
|
268
|
-
uint16_t pm_2_5_std_concentration = this->get_16_bit_uint_(6);
|
269
|
-
uint16_t pm_10_0_std_concentration = this->get_16_bit_uint_(8);
|
270
|
-
|
271
|
-
uint16_t pm_1_0_concentration = this->get_16_bit_uint_(10);
|
272
|
-
uint16_t pm_2_5_concentration = this->get_16_bit_uint_(12);
|
273
|
-
uint16_t pm_10_0_concentration = this->get_16_bit_uint_(14);
|
274
|
-
|
275
|
-
uint16_t pm_particles_03um = this->get_16_bit_uint_(16);
|
276
|
-
uint16_t pm_particles_05um = this->get_16_bit_uint_(18);
|
277
|
-
uint16_t pm_particles_10um = this->get_16_bit_uint_(20);
|
278
|
-
uint16_t pm_particles_25um = this->get_16_bit_uint_(22);
|
279
|
-
// Note the pm particles 50um & 100um are not returned,
|
280
|
-
// as PMS5003T uses those data values for temperature and humidity.
|
281
|
-
|
282
|
-
float temperature = (int16_t) this->get_16_bit_uint_(24) / 10.0f;
|
283
|
-
float humidity = this->get_16_bit_uint_(26) / 10.0f;
|
284
|
-
|
285
|
-
ESP_LOGD(TAG,
|
286
|
-
"Got PM1.0 Concentration: %u µg/m^3, PM2.5 Concentration %u µg/m^3, PM10.0 Concentration: %u µg/m^3, "
|
287
|
-
"Temperature: %.1f°C, Humidity: %.1f%%",
|
288
|
-
pm_1_0_concentration, pm_2_5_concentration, pm_10_0_concentration, temperature, humidity);
|
289
|
-
|
290
|
-
if (this->pm_1_0_std_sensor_ != nullptr)
|
291
|
-
this->pm_1_0_std_sensor_->publish_state(pm_1_0_std_concentration);
|
292
|
-
if (this->pm_2_5_std_sensor_ != nullptr)
|
293
|
-
this->pm_2_5_std_sensor_->publish_state(pm_2_5_std_concentration);
|
294
|
-
if (this->pm_10_0_std_sensor_ != nullptr)
|
295
|
-
this->pm_10_0_std_sensor_->publish_state(pm_10_0_std_concentration);
|
296
|
-
|
297
|
-
if (this->pm_1_0_sensor_ != nullptr)
|
298
|
-
this->pm_1_0_sensor_->publish_state(pm_1_0_concentration);
|
299
|
-
if (this->pm_2_5_sensor_ != nullptr)
|
300
|
-
this->pm_2_5_sensor_->publish_state(pm_2_5_concentration);
|
301
|
-
if (this->pm_10_0_sensor_ != nullptr)
|
302
|
-
this->pm_10_0_sensor_->publish_state(pm_10_0_concentration);
|
303
|
-
|
304
|
-
if (this->pm_particles_03um_sensor_ != nullptr)
|
305
|
-
this->pm_particles_03um_sensor_->publish_state(pm_particles_03um);
|
306
|
-
if (this->pm_particles_05um_sensor_ != nullptr)
|
307
|
-
this->pm_particles_05um_sensor_->publish_state(pm_particles_05um);
|
308
|
-
if (this->pm_particles_10um_sensor_ != nullptr)
|
309
|
-
this->pm_particles_10um_sensor_->publish_state(pm_particles_10um);
|
310
|
-
if (this->pm_particles_25um_sensor_ != nullptr)
|
311
|
-
this->pm_particles_25um_sensor_->publish_state(pm_particles_25um);
|
312
|
-
|
313
|
-
if (this->temperature_sensor_ != nullptr)
|
314
|
-
this->temperature_sensor_->publish_state(temperature);
|
315
|
-
if (this->humidity_sensor_ != nullptr)
|
316
|
-
this->humidity_sensor_->publish_state(humidity);
|
317
|
-
break;
|
318
|
-
}
|
284
|
+
// Temperature and Humidity
|
285
|
+
if (this->type_ == PMSX003_TYPE_5003ST || this->type_ == PMSX003_TYPE_5003T) {
|
286
|
+
const uint8_t temperature_offset = (this->type_ == PMSX003_TYPE_5003T) ? 24 : 30;
|
287
|
+
|
288
|
+
const float temperature = static_cast<int16_t>(this->get_16_bit_uint_(temperature_offset)) / 10.0f;
|
289
|
+
const float humidity = this->get_16_bit_uint_(temperature_offset + 2) / 10.0f;
|
290
|
+
|
291
|
+
ESP_LOGD(TAG, "Got Temperature: %.1f°C, Humidity: %.1f%%", temperature, humidity);
|
292
|
+
|
293
|
+
if (this->temperature_sensor_ != nullptr)
|
294
|
+
this->temperature_sensor_->publish_state(temperature);
|
295
|
+
if (this->humidity_sensor_ != nullptr)
|
296
|
+
this->humidity_sensor_->publish_state(humidity);
|
297
|
+
}
|
298
|
+
|
299
|
+
// Firmware Version and Error Code
|
300
|
+
if (this->type_ == PMSX003_TYPE_5003ST) {
|
301
|
+
const uint8_t firmware_version = this->data_[36];
|
302
|
+
const uint8_t error_code = this->data_[37];
|
303
|
+
|
304
|
+
ESP_LOGD(TAG, "Got Firmware Version: 0x%02X, Error Code: 0x%02X", firmware_version, error_code);
|
319
305
|
}
|
320
306
|
|
321
307
|
// Spin down the sensor again if we aren't going to need it until more time has
|
322
308
|
// passed than it takes to stabilise
|
323
309
|
if (this->update_interval_ > PMS_STABILISING_MS) {
|
324
|
-
this->send_command_(
|
310
|
+
this->send_command_(PMS_CMD_SLEEP_MODE, PMS_CMD_SLEEP_MODE_SLEEP);
|
325
311
|
this->state_ = PMSX003_STATE_IDLE;
|
326
312
|
}
|
327
313
|
|
328
314
|
this->status_clear_warning();
|
329
315
|
}
|
316
|
+
|
330
317
|
uint16_t PMSX003Component::get_16_bit_uint_(uint8_t start_index) {
|
331
318
|
return (uint16_t(this->data_[start_index]) << 8) | uint16_t(this->data_[start_index + 1]);
|
332
319
|
}
|
333
|
-
void PMSX003Component::dump_config() {
|
334
|
-
ESP_LOGCONFIG(TAG, "PMSX003:");
|
335
|
-
LOG_SENSOR(" ", "PM1.0STD", this->pm_1_0_std_sensor_);
|
336
|
-
LOG_SENSOR(" ", "PM2.5STD", this->pm_2_5_std_sensor_);
|
337
|
-
LOG_SENSOR(" ", "PM10.0STD", this->pm_10_0_std_sensor_);
|
338
|
-
|
339
|
-
LOG_SENSOR(" ", "PM1.0", this->pm_1_0_sensor_);
|
340
|
-
LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_);
|
341
|
-
LOG_SENSOR(" ", "PM10.0", this->pm_10_0_sensor_);
|
342
|
-
|
343
|
-
LOG_SENSOR(" ", "PM0.3um", this->pm_particles_03um_sensor_);
|
344
|
-
LOG_SENSOR(" ", "PM0.5um", this->pm_particles_05um_sensor_);
|
345
|
-
LOG_SENSOR(" ", "PM1.0um", this->pm_particles_10um_sensor_);
|
346
|
-
LOG_SENSOR(" ", "PM2.5um", this->pm_particles_25um_sensor_);
|
347
|
-
LOG_SENSOR(" ", "PM5.0um", this->pm_particles_50um_sensor_);
|
348
|
-
LOG_SENSOR(" ", "PM10.0um", this->pm_particles_100um_sensor_);
|
349
|
-
|
350
|
-
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
351
|
-
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
|
352
|
-
LOG_SENSOR(" ", "Formaldehyde", this->formaldehyde_sensor_);
|
353
|
-
this->check_uart_settings(9600);
|
354
|
-
}
|
355
320
|
|
356
321
|
} // namespace pmsx003
|
357
322
|
} // namespace esphome
|
@@ -7,13 +7,12 @@
|
|
7
7
|
namespace esphome {
|
8
8
|
namespace pmsx003 {
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
static const uint16_t PMS_STABILISING_MS = 30000; // time taken for the sensor to become stable after power on
|
10
|
+
enum PMSX0003Command : uint8_t {
|
11
|
+
PMS_CMD_MEASUREMENT_MODE =
|
12
|
+
0xE1, // Data Options: `PMS_CMD_MEASUREMENT_MODE_PASSIVE`, `PMS_CMD_MEASUREMENT_MODE_ACTIVE`
|
13
|
+
PMS_CMD_MANUAL_MEASUREMENT = 0xE2,
|
14
|
+
PMS_CMD_SLEEP_MODE = 0xE4, // Data Options: `PMS_CMD_SLEEP_MODE_SLEEP`, `PMS_CMD_SLEEP_MODE_WAKEUP`
|
15
|
+
};
|
17
16
|
|
18
17
|
enum PMSX003Type {
|
19
18
|
PMSX003_TYPE_X003 = 0,
|
@@ -31,37 +30,53 @@ enum PMSX003State {
|
|
31
30
|
class PMSX003Component : public uart::UARTDevice, public Component {
|
32
31
|
public:
|
33
32
|
PMSX003Component() = default;
|
34
|
-
|
35
|
-
float get_setup_priority() const override;
|
33
|
+
float get_setup_priority() const override { return setup_priority::DATA; }
|
36
34
|
void dump_config() override;
|
35
|
+
void loop() override;
|
37
36
|
|
38
|
-
void
|
39
|
-
|
40
|
-
void
|
41
|
-
|
42
|
-
void set_pm_1_0_std_sensor(sensor::Sensor *pm_1_0_std_sensor);
|
43
|
-
void set_pm_2_5_std_sensor(sensor::Sensor *pm_2_5_std_sensor);
|
44
|
-
void set_pm_10_0_std_sensor(sensor::Sensor *pm_10_0_std_sensor);
|
45
|
-
|
46
|
-
void set_pm_1_0_sensor(sensor::Sensor *pm_1_0_sensor);
|
47
|
-
void set_pm_2_5_sensor(sensor::Sensor *pm_2_5_sensor);
|
48
|
-
void set_pm_10_0_sensor(sensor::Sensor *pm_10_0_sensor);
|
49
|
-
|
50
|
-
void set_pm_particles_03um_sensor(sensor::Sensor *pm_particles_03um_sensor)
|
51
|
-
|
52
|
-
|
53
|
-
void
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
void
|
37
|
+
void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
|
38
|
+
|
39
|
+
void set_type(PMSX003Type type) { this->type_ = type; }
|
40
|
+
|
41
|
+
void set_pm_1_0_std_sensor(sensor::Sensor *pm_1_0_std_sensor) { this->pm_1_0_std_sensor_ = pm_1_0_std_sensor; }
|
42
|
+
void set_pm_2_5_std_sensor(sensor::Sensor *pm_2_5_std_sensor) { this->pm_2_5_std_sensor_ = pm_2_5_std_sensor; }
|
43
|
+
void set_pm_10_0_std_sensor(sensor::Sensor *pm_10_0_std_sensor) { this->pm_10_0_std_sensor_ = pm_10_0_std_sensor; }
|
44
|
+
|
45
|
+
void set_pm_1_0_sensor(sensor::Sensor *pm_1_0_sensor) { this->pm_1_0_sensor_ = pm_1_0_sensor; }
|
46
|
+
void set_pm_2_5_sensor(sensor::Sensor *pm_2_5_sensor) { this->pm_2_5_sensor_ = pm_2_5_sensor; }
|
47
|
+
void set_pm_10_0_sensor(sensor::Sensor *pm_10_0_sensor) { this->pm_10_0_sensor_ = pm_10_0_sensor; }
|
48
|
+
|
49
|
+
void set_pm_particles_03um_sensor(sensor::Sensor *pm_particles_03um_sensor) {
|
50
|
+
this->pm_particles_03um_sensor_ = pm_particles_03um_sensor;
|
51
|
+
}
|
52
|
+
void set_pm_particles_05um_sensor(sensor::Sensor *pm_particles_05um_sensor) {
|
53
|
+
this->pm_particles_05um_sensor_ = pm_particles_05um_sensor;
|
54
|
+
}
|
55
|
+
void set_pm_particles_10um_sensor(sensor::Sensor *pm_particles_10um_sensor) {
|
56
|
+
this->pm_particles_10um_sensor_ = pm_particles_10um_sensor;
|
57
|
+
}
|
58
|
+
void set_pm_particles_25um_sensor(sensor::Sensor *pm_particles_25um_sensor) {
|
59
|
+
this->pm_particles_25um_sensor_ = pm_particles_25um_sensor;
|
60
|
+
}
|
61
|
+
void set_pm_particles_50um_sensor(sensor::Sensor *pm_particles_50um_sensor) {
|
62
|
+
this->pm_particles_50um_sensor_ = pm_particles_50um_sensor;
|
63
|
+
}
|
64
|
+
void set_pm_particles_100um_sensor(sensor::Sensor *pm_particles_100um_sensor) {
|
65
|
+
this->pm_particles_100um_sensor_ = pm_particles_100um_sensor;
|
66
|
+
}
|
67
|
+
|
68
|
+
void set_formaldehyde_sensor(sensor::Sensor *formaldehyde_sensor) {
|
69
|
+
this->formaldehyde_sensor_ = formaldehyde_sensor;
|
70
|
+
}
|
71
|
+
|
72
|
+
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { this->temperature_sensor_ = temperature_sensor; }
|
73
|
+
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { this->humidity_sensor_ = humidity_sensor; }
|
60
74
|
|
61
75
|
protected:
|
62
76
|
optional<bool> check_byte_();
|
63
77
|
void parse_data_();
|
64
|
-
|
78
|
+
bool check_payload_length_(uint16_t payload_length);
|
79
|
+
void send_command_(PMSX0003Command cmd, uint16_t data);
|
65
80
|
uint16_t get_16_bit_uint_(uint8_t start_index);
|
66
81
|
|
67
82
|
uint8_t data_[64];
|
@@ -92,9 +107,12 @@ class PMSX003Component : public uart::UARTDevice, public Component {
|
|
92
107
|
sensor::Sensor *pm_particles_50um_sensor_{nullptr};
|
93
108
|
sensor::Sensor *pm_particles_100um_sensor_{nullptr};
|
94
109
|
|
110
|
+
// Formaldehyde
|
111
|
+
sensor::Sensor *formaldehyde_sensor_{nullptr};
|
112
|
+
|
113
|
+
// Temperature and Humidity
|
95
114
|
sensor::Sensor *temperature_sensor_{nullptr};
|
96
115
|
sensor::Sensor *humidity_sensor_{nullptr};
|
97
|
-
sensor::Sensor *formaldehyde_sensor_{nullptr};
|
98
116
|
};
|
99
117
|
|
100
118
|
} // namespace pmsx003
|