SCD30 Added support for manual calibration (#4362)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Florian Trück 2023-02-03 09:13:27 +01:00 committed by GitHub
parent 8d6ffb9169
commit 6b7b076875
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 1 deletions

View file

@ -0,0 +1,23 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/automation.h"
#include "scd30.h"
namespace esphome {
namespace scd30 {
template<typename... Ts> class ForceRecalibrationWithReference : public Action<Ts...>, public Parented<SCD30Component> {
public:
void play(Ts... x) override {
if (this->value_.has_value()) {
this->parent_->force_recalibration_with_reference(this->value_.value(x...));
}
}
protected:
TEMPLATABLE_VALUE(uint16_t, value)
};
} // namespace scd30
} // namespace esphome

View file

@ -202,5 +202,27 @@ bool SCD30Component::is_data_ready_() {
return is_data_ready == 1;
}
bool SCD30Component::force_recalibration_with_reference(uint16_t co2_reference) {
ESP_LOGD(TAG, "Performing CO2 force recalibration with reference %dppm.", co2_reference);
if (this->write_command(SCD30_CMD_FORCED_CALIBRATION, co2_reference)) {
ESP_LOGD(TAG, "Force recalibration complete.");
return true;
} else {
ESP_LOGE(TAG, "Failed to force recalibration with reference.");
this->error_code_ = FORCE_RECALIBRATION_FAILED;
this->status_set_warning();
return false;
}
}
uint16_t SCD30Component::get_forced_calibration_reference() {
uint16_t forced_calibration_reference;
// Get current CO2 calibration
if (!this->get_register(SCD30_CMD_FORCED_CALIBRATION, forced_calibration_reference)) {
ESP_LOGE(TAG, "Unable to read forced calibration reference.");
}
return forced_calibration_reference;
}
} // namespace scd30
} // namespace esphome

View file

@ -20,6 +20,8 @@ class SCD30Component : public Component, public sensirion_common::SensirionI2CDe
}
void set_temperature_offset(float offset) { temperature_offset_ = offset; }
void set_update_interval(uint16_t interval) { update_interval_ = interval; }
bool force_recalibration_with_reference(uint16_t co2_reference);
uint16_t get_forced_calibration_reference();
void setup() override;
void update();
@ -33,6 +35,7 @@ class SCD30Component : public Component, public sensirion_common::SensirionI2CDe
COMMUNICATION_FAILED,
FIRMWARE_IDENTIFICATION_FAILED,
MEASUREMENT_INIT_FAILED,
FORCE_RECALIBRATION_FAILED,
UNKNOWN
} error_code_{UNKNOWN};
bool enable_asc_{true};

View file

@ -1,4 +1,4 @@
from esphome import core
from esphome import automation, core
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
@ -9,6 +9,7 @@ from esphome.const import (
CONF_TEMPERATURE,
CONF_CO2,
CONF_UPDATE_INTERVAL,
CONF_VALUE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
@ -26,6 +27,11 @@ SCD30Component = scd30_ns.class_(
"SCD30Component", cg.Component, sensirion_common.SensirionI2CDevice
)
# Actions
ForceRecalibrationWithReference = scd30_ns.class_(
"ForceRecalibrationWithReference", automation.Action
)
CONF_AUTOMATIC_SELF_CALIBRATION = "automatic_self_calibration"
CONF_ALTITUDE_COMPENSATION = "altitude_compensation"
CONF_AMBIENT_PRESSURE_COMPENSATION = "ambient_pressure_compensation"
@ -106,3 +112,26 @@ async def to_code(config):
if CONF_TEMPERATURE in config:
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
cg.add(var.set_temperature_sensor(sens))
@automation.register_action(
"scd30.force_recalibration_with_reference",
ForceRecalibrationWithReference,
cv.maybe_simple_value(
{
cv.GenerateID(): cv.use_id(SCD30Component),
cv.Required(CONF_VALUE): cv.templatable(
cv.int_range(min=400, max=2000, max_included=True)
),
},
key=CONF_VALUE,
),
)
async def scd30_force_recalibration_with_reference_to_code(
config, action_id, template_arg, args
):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
template_ = await cg.templatable(config[CONF_VALUE], args, cg.uint16)
cg.add(var.set_value(template_))
return var