add detection range

This commit is contained in:
Fabio Pugliese Ornellas 2024-02-25 13:06:06 +00:00
parent bbf7e2be28
commit b53adcb4d6
3 changed files with 65 additions and 1 deletions

View File

@ -11,6 +11,9 @@ static const uint8_t MHZ19_COMMAND_GET_PPM[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x
static const uint8_t MHZ19_COMMAND_ABC_ENABLE[] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00};
static const uint8_t MHZ19_COMMAND_ABC_DISABLE[] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t MHZ19_COMMAND_CALIBRATE_ZERO[] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t MHZ19_COMMAND_DETECTION_RANGE_0_2000PPM[] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x07, 0xD0};
static const uint8_t MHZ19_COMMAND_DETECTION_RANGE_0_5000PPM[] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88};
static const uint8_t MHZ19_COMMAND_DETECTION_RANGE_0_10000PPM[] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x27, 0x10};
uint8_t mhz19_checksum(const uint8_t *command) {
uint8_t sum = 0;
@ -26,6 +29,24 @@ void MHZ19Component::setup() {
} else if (this->abc_boot_logic_ == MHZ19_ABC_DISABLED) {
this->abc_disable();
}
switch (this->detection_range_) {
case MHZ19_DETECTION_RANGE_DEFAULT:
ESP_LOGD(TAG, "Using previously set detection range (no change)");
break;
case MHZ19_DETECTION_RANGE_0_2000PPM:
ESP_LOGD(TAG, "Setting detection range to 0 to 2000ppm");
this->mhz19_write_command_(MHZ19_COMMAND_DETECTION_RANGE_0_2000PPM, nullptr);
break;
case MHZ19_DETECTION_RANGE_0_5000PPM:
ESP_LOGD(TAG, "Setting detection range to 0 to 5000ppm");
this->mhz19_write_command_(MHZ19_COMMAND_DETECTION_RANGE_0_5000PPM, nullptr);
break;
case MHZ19_DETECTION_RANGE_0_10000PPM:
ESP_LOGD(TAG, "Setting detection range to 0 to 10000ppm");
this->mhz19_write_command_(MHZ19_COMMAND_DETECTION_RANGE_0_10000PPM, nullptr);
break;
}
}
void MHZ19Component::update() {
@ -97,7 +118,9 @@ bool MHZ19Component::mhz19_write_command_(const uint8_t *command, uint8_t *respo
return this->read_array(response, MHZ19_RESPONSE_LENGTH);
}
float MHZ19Component::get_setup_priority() const { return setup_priority::DATA; }
void MHZ19Component::dump_config() {
ESP_LOGCONFIG(TAG, "MH-Z19:");
LOG_SENSOR(" ", "CO2", this->co2_sensor_);
@ -111,6 +134,23 @@ void MHZ19Component::dump_config() {
}
ESP_LOGCONFIG(TAG, " Warmup seconds: %ds", this->warmup_seconds_);
const char *range_str;
switch (this->detection_range_) {
case MHZ19_DETECTION_RANGE_DEFAULT:
range_str = "default";
break;
case MHZ19_DETECTION_RANGE_0_2000PPM:
range_str = "0 to 2000ppm";
break;
case MHZ19_DETECTION_RANGE_0_5000PPM:
range_str = "0 to 5000ppm";
break;
case MHZ19_DETECTION_RANGE_0_10000PPM:
range_str = "0 to 10000ppm";
break;
}
ESP_LOGCONFIG(TAG, " Detection range: %s", range_str);
}
} // namespace mhz19

View File

@ -8,7 +8,18 @@
namespace esphome {
namespace mhz19 {
enum MHZ19ABCLogic { MHZ19_ABC_NONE = 0, MHZ19_ABC_ENABLED, MHZ19_ABC_DISABLED };
enum MHZ19ABCLogic {
MHZ19_ABC_NONE = 0,
MHZ19_ABC_ENABLED,
MHZ19_ABC_DISABLED,
};
enum MHZ19DetectionRange {
MHZ19_DETECTION_RANGE_DEFAULT = 0,
MHZ19_DETECTION_RANGE_0_2000PPM,
MHZ19_DETECTION_RANGE_0_5000PPM,
MHZ19_DETECTION_RANGE_0_10000PPM,
};
class MHZ19Component : public PollingComponent, public uart::UARTDevice {
public:
@ -27,13 +38,18 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice {
void set_abc_enabled(bool abc_enabled) { abc_boot_logic_ = abc_enabled ? MHZ19_ABC_ENABLED : MHZ19_ABC_DISABLED; }
void set_warmup_seconds(uint32_t seconds) { warmup_seconds_ = seconds; }
void set_detection_range(MHZ19DetectionRange detection_range) { detection_range_ = detection_range; }
protected:
bool mhz19_write_command_(const uint8_t *command, uint8_t *response);
sensor::Sensor *temperature_sensor_{nullptr};
sensor::Sensor *co2_sensor_{nullptr};
MHZ19ABCLogic abc_boot_logic_{MHZ19_ABC_NONE};
uint32_t warmup_seconds_;
MHZ19DetectionRange detection_range_{MHZ19_DETECTION_RANGE_DEFAULT};
};
template<typename... Ts> class MHZ19CalibrateZeroAction : public Action<Ts...> {

View File

@ -19,6 +19,7 @@ DEPENDENCIES = ["uart"]
CONF_AUTOMATIC_BASELINE_CALIBRATION = "automatic_baseline_calibration"
CONF_WARMUP_TIME = "warmup_time"
CONF_DETECTION_RANGE = "detection_range"
mhz19_ns = cg.esphome_ns.namespace("mhz19")
MHZ19Component = mhz19_ns.class_("MHZ19Component", cg.PollingComponent, uart.UARTDevice)
@ -49,6 +50,10 @@ CONFIG_SCHEMA = (
cv.Optional(
CONF_WARMUP_TIME, default="75s"
): cv.positive_time_period_seconds,
cv.Optional(CONF_DETECTION_RANGE): cv.All(
cv.float_with_unit("parts per million", "(ppm)"),
cv.one_of(2000, 5000, 10000, int=True),
),
}
)
.extend(cv.polling_component_schema("60s"))
@ -74,6 +79,9 @@ async def to_code(config):
cg.add(var.set_warmup_seconds(config[CONF_WARMUP_TIME]))
if CONF_DETECTION_RANGE in config:
cg.add(var.set_detection_range(config[CONF_DETECTION_RANGE]))
CALIBRATION_ACTION_SCHEMA = maybe_simple_id(
{