diff --git a/CODEOWNERS b/CODEOWNERS index 3ae9f71ead..8aa96d14af 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -94,6 +94,7 @@ esphome/components/ota/* @esphome/core esphome/components/output/* @esphome/core esphome/components/pid/* @OttoWinter esphome/components/pipsolar/* @andreashergert1984 +esphome/components/pm1006/* @habbie esphome/components/pmsa003i/* @sjtrny esphome/components/pn532/* @OttoWinter @jesserockz esphome/components/pn532_i2c/* @OttoWinter @jesserockz diff --git a/esphome/components/pm1006/pm1006.cpp b/esphome/components/pm1006/pm1006.cpp index 9bedb3cfc0..1a89307eee 100644 --- a/esphome/components/pm1006/pm1006.cpp +++ b/esphome/components/pm1006/pm1006.cpp @@ -7,6 +7,7 @@ namespace pm1006 { static const char *const TAG = "pm1006"; static const uint8_t PM1006_RESPONSE_HEADER[] = {0x16, 0x11, 0x0B}; +static const uint8_t PM1006_REQUEST[] = {0x11, 0x02, 0x0B, 0x01, 0xE1}; void PM1006Component::setup() { // because this implementation is currently rx-only, there is nothing to setup @@ -15,9 +16,15 @@ void PM1006Component::setup() { void PM1006Component::dump_config() { ESP_LOGCONFIG(TAG, "PM1006:"); LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_); + LOG_UPDATE_INTERVAL(this); this->check_uart_settings(9600); } +void PM1006Component::update() { + ESP_LOGV(TAG, "sending measurement request"); + this->write_array(PM1006_REQUEST, sizeof(PM1006_REQUEST)); +} + void PM1006Component::loop() { while (this->available() != 0) { this->read_byte(&this->data_[this->data_index_]); diff --git a/esphome/components/pm1006/pm1006.h b/esphome/components/pm1006/pm1006.h index 66f4cf0311..238ac67006 100644 --- a/esphome/components/pm1006/pm1006.h +++ b/esphome/components/pm1006/pm1006.h @@ -7,7 +7,7 @@ namespace esphome { namespace pm1006 { -class PM1006Component : public Component, public uart::UARTDevice { +class PM1006Component : public PollingComponent, public uart::UARTDevice { public: PM1006Component() = default; @@ -15,6 +15,7 @@ class PM1006Component : public Component, public uart::UARTDevice { void setup() override; void dump_config() override; void loop() override; + void update() override; float get_setup_priority() const override; diff --git a/esphome/components/pm1006/sensor.py b/esphome/components/pm1006/sensor.py index 0423be61e2..1e648be199 100644 --- a/esphome/components/pm1006/sensor.py +++ b/esphome/components/pm1006/sensor.py @@ -4,12 +4,15 @@ from esphome.components import sensor, uart from esphome.const import ( CONF_ID, CONF_PM_2_5, + CONF_UPDATE_INTERVAL, DEVICE_CLASS_PM25, STATE_CLASS_MEASUREMENT, UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_BLUR, ) +from esphome.core import TimePeriodMilliseconds +CODEOWNERS = ["@habbie"] DEPENDENCIES = ["uart"] pm1006_ns = cg.esphome_ns.namespace("pm1006") @@ -30,10 +33,28 @@ CONFIG_SCHEMA = cv.All( } ) .extend(cv.COMPONENT_SCHEMA) - .extend(uart.UART_DEVICE_SCHEMA), + .extend(uart.UART_DEVICE_SCHEMA) + .extend(cv.polling_component_schema("never")), ) +def validate_interval_uart(config): + require_tx = False + + interval = config.get(CONF_UPDATE_INTERVAL) + + if isinstance(interval, TimePeriodMilliseconds): + # 'never' is encoded as a very large int, not as a TimePeriodMilliseconds objects + require_tx = True + + uart.final_validate_device_schema( + "pm1006", baud_rate=9600, require_rx=True, require_tx=require_tx + )(config) + + +FINAL_VALIDATE_SCHEMA = validate_interval_uart + + async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config)