esphome 2025.4.1__py3-none-any.whl → 2025.5.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +77 -10
- esphome/components/api/api_connection.h +6 -1
- esphome/components/api/api_frame_helper.cpp +98 -130
- esphome/components/api/api_frame_helper.h +12 -2
- 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 +38 -9
- esphome/components/as3935_i2c/as3935_i2c.h +0 -3
- esphome/components/as7341/as7341.h +1 -1
- 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/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/binary_sensor/binary_sensor.cpp +6 -10
- esphome/components/binary_sensor/binary_sensor.h +1 -1
- esphome/components/binary_sensor/filter.cpp +21 -21
- esphome/components/binary_sensor/filter.h +10 -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 +135 -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/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/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/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/debug/debug_component.cpp +5 -0
- esphome/components/debug/debug_component.h +6 -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/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- 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.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_can/esp32_can.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/esp8266/gpio.cpp +69 -8
- 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/fujitsu_general/climate.py +2 -9
- 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 +11 -2
- esphome/components/gps/gps.cpp +11 -8
- esphome/components/gps/gps.h +9 -6
- 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/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/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/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/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 +21 -0
- esphome/components/logger/logger.cpp +125 -95
- esphome/components/logger/logger.h +160 -35
- 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/max7219digit/max7219digit.cpp +27 -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/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/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +5 -1
- 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/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 +193 -229
- 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/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/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -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/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/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/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/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/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/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_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +1 -0
- esphome/core/application.h +4 -0
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +19 -3
- esphome/core/component.h +5 -0
- esphome/core/defines.h +23 -17
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +3 -0
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/mqtt.py +21 -8
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +2 -2
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/METADATA +10 -11
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/RECORD +411 -352
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/WHEEL +1 -1
- esphome/components/esp32_ble/const_esp32c6.h +0 -74
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/top_level.txt +0 -0
@@ -6,45 +6,39 @@ namespace pmsx003 {
|
|
6
6
|
|
7
7
|
static const char *const TAG = "pmsx003";
|
8
8
|
|
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
|
-
}
|
9
|
+
static const uint8_t START_CHARACTER_1 = 0x42;
|
10
|
+
static const uint8_t START_CHARACTER_2 = 0x4D;
|
18
11
|
|
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; }
|
12
|
+
static const uint16_t PMS_STABILISING_MS = 30000; // time taken for the sensor to become stable after power on in ms
|
22
13
|
|
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
|
-
}
|
14
|
+
static const uint16_t PMS_CMD_MEASUREMENT_MODE_PASSIVE =
|
15
|
+
0x0000; // use `PMS_CMD_MANUAL_MEASUREMENT` to trigger a measurement
|
16
|
+
static const uint16_t PMS_CMD_MEASUREMENT_MODE_ACTIVE = 0x0001; // automatically perform measurements
|
17
|
+
static const uint16_t PMS_CMD_SLEEP_MODE_SLEEP = 0x0000; // go to sleep mode
|
18
|
+
static const uint16_t PMS_CMD_SLEEP_MODE_WAKEUP = 0x0001; // wake up from sleep mode
|
41
19
|
|
42
|
-
void PMSX003Component::
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
20
|
+
void PMSX003Component::dump_config() {
|
21
|
+
ESP_LOGCONFIG(TAG, "PMSX003:");
|
22
|
+
LOG_SENSOR(" ", "PM1.0STD", this->pm_1_0_std_sensor_);
|
23
|
+
LOG_SENSOR(" ", "PM2.5STD", this->pm_2_5_std_sensor_);
|
24
|
+
LOG_SENSOR(" ", "PM10.0STD", this->pm_10_0_std_sensor_);
|
25
|
+
|
26
|
+
LOG_SENSOR(" ", "PM1.0", this->pm_1_0_sensor_);
|
27
|
+
LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_);
|
28
|
+
LOG_SENSOR(" ", "PM10.0", this->pm_10_0_sensor_);
|
29
|
+
|
30
|
+
LOG_SENSOR(" ", "PM0.3um", this->pm_particles_03um_sensor_);
|
31
|
+
LOG_SENSOR(" ", "PM0.5um", this->pm_particles_05um_sensor_);
|
32
|
+
LOG_SENSOR(" ", "PM1.0um", this->pm_particles_10um_sensor_);
|
33
|
+
LOG_SENSOR(" ", "PM2.5um", this->pm_particles_25um_sensor_);
|
34
|
+
LOG_SENSOR(" ", "PM5.0um", this->pm_particles_50um_sensor_);
|
35
|
+
LOG_SENSOR(" ", "PM10.0um", this->pm_particles_100um_sensor_);
|
36
|
+
|
37
|
+
LOG_SENSOR(" ", "Formaldehyde", this->formaldehyde_sensor_);
|
38
|
+
|
39
|
+
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
40
|
+
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
|
41
|
+
this->check_uart_settings(9600);
|
48
42
|
}
|
49
43
|
|
50
44
|
void PMSX003Component::loop() {
|
@@ -55,8 +49,8 @@ void PMSX003Component::loop() {
|
|
55
49
|
// need to keep track of what state we're in.
|
56
50
|
if (this->update_interval_ > PMS_STABILISING_MS) {
|
57
51
|
if (this->initialised_ == 0) {
|
58
|
-
this->send_command_(
|
59
|
-
this->send_command_(
|
52
|
+
this->send_command_(PMS_CMD_MEASUREMENT_MODE, PMS_CMD_MEASUREMENT_MODE_PASSIVE);
|
53
|
+
this->send_command_(PMS_CMD_SLEEP_MODE, PMS_CMD_SLEEP_MODE_WAKEUP);
|
60
54
|
this->initialised_ = 1;
|
61
55
|
}
|
62
56
|
switch (this->state_) {
|
@@ -66,7 +60,7 @@ void PMSX003Component::loop() {
|
|
66
60
|
return;
|
67
61
|
|
68
62
|
this->state_ = PMSX003_STATE_STABILISING;
|
69
|
-
this->send_command_(
|
63
|
+
this->send_command_(PMS_CMD_SLEEP_MODE, PMS_CMD_SLEEP_MODE_WAKEUP);
|
70
64
|
this->fan_on_time_ = now;
|
71
65
|
return;
|
72
66
|
case PMSX003_STATE_STABILISING:
|
@@ -77,7 +71,7 @@ void PMSX003Component::loop() {
|
|
77
71
|
while (this->available())
|
78
72
|
this->read_byte(&this->data_[0]);
|
79
73
|
// Trigger a new read
|
80
|
-
this->send_command_(
|
74
|
+
this->send_command_(PMS_CMD_MANUAL_MEASUREMENT, 0);
|
81
75
|
this->state_ = PMSX003_STATE_WAITING;
|
82
76
|
break;
|
83
77
|
case PMSX003_STATE_WAITING:
|
@@ -116,242 +110,212 @@ void PMSX003Component::loop() {
|
|
116
110
|
}
|
117
111
|
}
|
118
112
|
}
|
119
|
-
|
113
|
+
|
120
114
|
optional<bool> PMSX003Component::check_byte_() {
|
121
|
-
uint8_t index = this->data_index_;
|
122
|
-
uint8_t byte = this->data_[index];
|
115
|
+
const uint8_t index = this->data_index_;
|
116
|
+
const uint8_t byte = this->data_[index];
|
123
117
|
|
124
|
-
if (index == 0)
|
125
|
-
|
118
|
+
if (index == 0 || index == 1) {
|
119
|
+
const uint8_t start_char = index == 0 ? START_CHARACTER_1 : START_CHARACTER_2;
|
120
|
+
if (byte == start_char) {
|
121
|
+
return true;
|
122
|
+
}
|
126
123
|
|
127
|
-
|
128
|
-
return
|
124
|
+
ESP_LOGW(TAG, "Start character %u mismatch: 0x%02X != 0x%02X", index + 1, byte, START_CHARACTER_1);
|
125
|
+
return false;
|
126
|
+
}
|
129
127
|
|
130
|
-
if (index == 2)
|
128
|
+
if (index == 2) {
|
131
129
|
return true;
|
130
|
+
}
|
132
131
|
|
133
|
-
uint16_t payload_length = this->get_16_bit_uint_(2);
|
132
|
+
const uint16_t payload_length = this->get_16_bit_uint_(2);
|
134
133
|
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);
|
134
|
+
if (this->check_payload_length_(payload_length)) {
|
135
|
+
return true;
|
136
|
+
} else {
|
137
|
+
ESP_LOGW(TAG, "Payload length %u doesn't match. Are you using the correct PMSX003 type?", payload_length);
|
151
138
|
return false;
|
152
139
|
}
|
153
|
-
return true;
|
154
140
|
}
|
155
141
|
|
156
|
-
// start (16bit) + length (16bit) + DATA (payload_length-
|
157
|
-
|
142
|
+
// start (16bit) + length (16bit) + DATA (payload_length - 16bit) + checksum (16bit)
|
143
|
+
const uint16_t total_size = 4 + payload_length;
|
158
144
|
|
159
|
-
if (index < total_size - 1)
|
145
|
+
if (index < total_size - 1) {
|
160
146
|
return true;
|
147
|
+
}
|
161
148
|
|
162
149
|
// checksum is without checksum bytes
|
163
150
|
uint16_t checksum = 0;
|
164
|
-
for (
|
151
|
+
for (uint16_t i = 0; i < total_size - 2; i++) {
|
165
152
|
checksum += this->data_[i];
|
153
|
+
}
|
166
154
|
|
167
|
-
uint16_t check = this->get_16_bit_uint_(total_size - 2);
|
155
|
+
const uint16_t check = this->get_16_bit_uint_(total_size - 2);
|
168
156
|
if (checksum != check) {
|
169
|
-
ESP_LOGW(TAG, "PMSX003 checksum mismatch! 0x%02X!=0x%02X", checksum, check);
|
157
|
+
ESP_LOGW(TAG, "PMSX003 checksum mismatch! 0x%02X != 0x%02X", checksum, check);
|
170
158
|
return false;
|
171
159
|
}
|
172
160
|
|
173
161
|
return {};
|
174
162
|
}
|
175
163
|
|
176
|
-
|
177
|
-
this->
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
164
|
+
bool PMSX003Component::check_payload_length_(uint16_t payload_length) {
|
165
|
+
switch (this->type_) {
|
166
|
+
case PMSX003_TYPE_X003:
|
167
|
+
// The expected payload length is typically 28 bytes.
|
168
|
+
// However, a 20-byte payload check was already present in the code.
|
169
|
+
// No official documentation was found confirming this.
|
170
|
+
// Retaining this check to avoid breaking existing behavior.
|
171
|
+
return payload_length == 28 || payload_length == 20; // 2*13+2
|
172
|
+
case PMSX003_TYPE_5003T:
|
173
|
+
case PMSX003_TYPE_5003S:
|
174
|
+
return payload_length == 28; // 2*13+2 (Data 13 not set/reserved)
|
175
|
+
case PMSX003_TYPE_5003ST:
|
176
|
+
return payload_length == 36; // 2*17+2 (Data 16 not set/reserved)
|
186
177
|
}
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
178
|
+
return false;
|
179
|
+
}
|
180
|
+
|
181
|
+
void PMSX003Component::send_command_(PMSX0003Command cmd, uint16_t data) {
|
182
|
+
uint8_t send_data[7] = {
|
183
|
+
START_CHARACTER_1, // Start Byte 1
|
184
|
+
START_CHARACTER_2, // Start Byte 2
|
185
|
+
cmd, // Command
|
186
|
+
uint8_t((data >> 8) & 0xFF), // Data 1
|
187
|
+
uint8_t((data >> 0) & 0xFF), // Data 2
|
188
|
+
0, // Verify Byte 1
|
189
|
+
0, // Verify Byte 2
|
190
|
+
};
|
191
|
+
|
192
|
+
// Calculate checksum
|
193
|
+
uint16_t checksum = 0;
|
194
|
+
for (uint8_t i = 0; i < 5; i++) {
|
195
|
+
checksum += send_data[i];
|
196
|
+
}
|
197
|
+
send_data[5] = (checksum >> 8) & 0xFF; // Verify Byte 1
|
198
|
+
send_data[6] = (checksum >> 0) & 0xFF; // Verify Byte 2
|
199
|
+
|
200
|
+
for (auto send_byte : send_data) {
|
201
|
+
this->write_byte(send_byte);
|
191
202
|
}
|
192
|
-
this->data_index_ = 0;
|
193
203
|
}
|
194
204
|
|
195
205
|
void PMSX003Component::parse_data_() {
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
206
|
+
// Particle Matter
|
207
|
+
const uint16_t pm_1_0_std_concentration = this->get_16_bit_uint_(4);
|
208
|
+
const uint16_t pm_2_5_std_concentration = this->get_16_bit_uint_(6);
|
209
|
+
const uint16_t pm_10_0_std_concentration = this->get_16_bit_uint_(8);
|
210
|
+
|
211
|
+
const uint16_t pm_1_0_concentration = this->get_16_bit_uint_(10);
|
212
|
+
const uint16_t pm_2_5_concentration = this->get_16_bit_uint_(12);
|
213
|
+
const uint16_t pm_10_0_concentration = this->get_16_bit_uint_(14);
|
214
|
+
|
215
|
+
const uint16_t pm_particles_03um = this->get_16_bit_uint_(16);
|
216
|
+
const uint16_t pm_particles_05um = this->get_16_bit_uint_(18);
|
217
|
+
const uint16_t pm_particles_10um = this->get_16_bit_uint_(20);
|
218
|
+
const uint16_t pm_particles_25um = this->get_16_bit_uint_(22);
|
219
|
+
|
220
|
+
ESP_LOGD(TAG,
|
221
|
+
"Got PM1.0 Standard Concentration: %u µg/m³, PM2.5 Standard Concentration %u µg/m³, PM10.0 Standard "
|
222
|
+
"Concentration: %u µg/m³, PM1.0 Concentration: %u µg/m³, PM2.5 Concentration %u µg/m³, PM10.0 "
|
223
|
+
"Concentration: %u µg/m³",
|
224
|
+
pm_1_0_std_concentration, pm_2_5_std_concentration, pm_10_0_std_concentration, pm_1_0_concentration,
|
225
|
+
pm_2_5_concentration, pm_10_0_concentration);
|
226
|
+
|
227
|
+
if (this->pm_1_0_std_sensor_ != nullptr)
|
228
|
+
this->pm_1_0_std_sensor_->publish_state(pm_1_0_std_concentration);
|
229
|
+
if (this->pm_2_5_std_sensor_ != nullptr)
|
230
|
+
this->pm_2_5_std_sensor_->publish_state(pm_2_5_std_concentration);
|
231
|
+
if (this->pm_10_0_std_sensor_ != nullptr)
|
232
|
+
this->pm_10_0_std_sensor_->publish_state(pm_10_0_std_concentration);
|
233
|
+
|
234
|
+
if (this->pm_1_0_sensor_ != nullptr)
|
235
|
+
this->pm_1_0_sensor_->publish_state(pm_1_0_concentration);
|
236
|
+
if (this->pm_2_5_sensor_ != nullptr)
|
237
|
+
this->pm_2_5_sensor_->publish_state(pm_2_5_concentration);
|
238
|
+
if (this->pm_10_0_sensor_ != nullptr)
|
239
|
+
this->pm_10_0_sensor_->publish_state(pm_10_0_concentration);
|
240
|
+
|
241
|
+
if (this->pm_particles_03um_sensor_ != nullptr)
|
242
|
+
this->pm_particles_03um_sensor_->publish_state(pm_particles_03um);
|
243
|
+
if (this->pm_particles_05um_sensor_ != nullptr)
|
244
|
+
this->pm_particles_05um_sensor_->publish_state(pm_particles_05um);
|
245
|
+
if (this->pm_particles_10um_sensor_ != nullptr)
|
246
|
+
this->pm_particles_10um_sensor_->publish_state(pm_particles_10um);
|
247
|
+
if (this->pm_particles_25um_sensor_ != nullptr)
|
248
|
+
this->pm_particles_25um_sensor_->publish_state(pm_particles_25um);
|
249
|
+
|
250
|
+
if (this->type_ == PMSX003_TYPE_5003T) {
|
251
|
+
ESP_LOGD(TAG,
|
252
|
+
"Got PM0.3 Particles: %u Count/0.1L, PM0.5 Particles: %u Count/0.1L, PM1.0 Particles: %u Count/0.1L, "
|
253
|
+
"PM2.5 Particles %u Count/0.1L",
|
254
|
+
pm_particles_03um, pm_particles_05um, pm_particles_10um, pm_particles_25um);
|
255
|
+
} else {
|
256
|
+
// Note the pm particles 50um & 100um are not returned,
|
257
|
+
// as PMS5003T uses those data values for temperature and humidity.
|
258
|
+
const uint16_t pm_particles_50um = this->get_16_bit_uint_(24);
|
259
|
+
const uint16_t pm_particles_100um = this->get_16_bit_uint_(26);
|
260
|
+
|
261
|
+
ESP_LOGD(TAG,
|
262
|
+
"Got PM0.3 Particles: %u Count/0.1L, PM0.5 Particles: %u Count/0.1L, PM1.0 Particles: %u Count/0.1L, "
|
263
|
+
"PM2.5 Particles %u Count/0.1L, PM5.0 Particles: %u Count/0.1L, PM10.0 Particles %u Count/0.1L",
|
264
|
+
pm_particles_03um, pm_particles_05um, pm_particles_10um, pm_particles_25um, pm_particles_50um,
|
265
|
+
pm_particles_100um);
|
266
|
+
|
267
|
+
if (this->pm_particles_50um_sensor_ != nullptr)
|
268
|
+
this->pm_particles_50um_sensor_->publish_state(pm_particles_50um);
|
269
|
+
if (this->pm_particles_100um_sensor_ != nullptr)
|
270
|
+
this->pm_particles_100um_sensor_->publish_state(pm_particles_100um);
|
271
|
+
}
|
200
272
|
|
201
|
-
|
273
|
+
// Formaldehyde
|
274
|
+
if (this->type_ == PMSX003_TYPE_5003ST || this->type_ == PMSX003_TYPE_5003S) {
|
275
|
+
const uint16_t formaldehyde = this->get_16_bit_uint_(28);
|
202
276
|
|
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);
|
277
|
+
ESP_LOGD(TAG, "Got Formaldehyde: %u µg/m^3", formaldehyde);
|
211
278
|
|
212
|
-
|
279
|
+
if (this->formaldehyde_sensor_ != nullptr)
|
280
|
+
this->formaldehyde_sensor_->publish_state(formaldehyde);
|
281
|
+
}
|
213
282
|
|
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
|
-
}
|
283
|
+
// Temperature and Humidity
|
284
|
+
if (this->type_ == PMSX003_TYPE_5003ST || this->type_ == PMSX003_TYPE_5003T) {
|
285
|
+
const uint8_t temperature_offset = (this->type_ == PMSX003_TYPE_5003T) ? 24 : 30;
|
286
|
+
|
287
|
+
const float temperature = static_cast<int16_t>(this->get_16_bit_uint_(temperature_offset)) / 10.0f;
|
288
|
+
const float humidity = this->get_16_bit_uint_(temperature_offset + 2) / 10.0f;
|
289
|
+
|
290
|
+
ESP_LOGD(TAG, "Got Temperature: %.1f°C, Humidity: %.1f%%", temperature, humidity);
|
291
|
+
|
292
|
+
if (this->temperature_sensor_ != nullptr)
|
293
|
+
this->temperature_sensor_->publish_state(temperature);
|
294
|
+
if (this->humidity_sensor_ != nullptr)
|
295
|
+
this->humidity_sensor_->publish_state(humidity);
|
296
|
+
}
|
297
|
+
|
298
|
+
// Firmware Version and Error Code
|
299
|
+
if (this->type_ == PMSX003_TYPE_5003ST) {
|
300
|
+
const uint8_t firmware_version = this->data_[36];
|
301
|
+
const uint8_t error_code = this->data_[37];
|
302
|
+
|
303
|
+
ESP_LOGD(TAG, "Got Firmware Version: 0x%02X, Error Code: 0x%02X", firmware_version, error_code);
|
319
304
|
}
|
320
305
|
|
321
306
|
// Spin down the sensor again if we aren't going to need it until more time has
|
322
307
|
// passed than it takes to stabilise
|
323
308
|
if (this->update_interval_ > PMS_STABILISING_MS) {
|
324
|
-
this->send_command_(
|
309
|
+
this->send_command_(PMS_CMD_SLEEP_MODE, PMS_CMD_SLEEP_MODE_SLEEP);
|
325
310
|
this->state_ = PMSX003_STATE_IDLE;
|
326
311
|
}
|
327
312
|
|
328
313
|
this->status_clear_warning();
|
329
314
|
}
|
315
|
+
|
330
316
|
uint16_t PMSX003Component::get_16_bit_uint_(uint8_t start_index) {
|
331
317
|
return (uint16_t(this->data_[start_index]) << 8) | uint16_t(this->data_[start_index + 1]);
|
332
318
|
}
|
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
319
|
|
356
320
|
} // namespace pmsx003
|
357
321
|
} // 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
|