Compare commits

...
4 changed files with 96 additions and 29 deletions

No files matched your search

+29 -25
View File
@@ -49,36 +49,40 @@ void BME680BSECComponent::setup() {
this->load_state_();
}
void BME680BSECComponent::set_config_() {
if (this->sample_rate_ == SAMPLE_RATE_ULP) {
if (this->supply_voltage_ == SUPPLY_VOLTAGE_3V3) {
const uint8_t config[] = {
// BSEC configuration blobs, kept in flash on ESP8266
static constexpr uint8_t CONFIG_33V_300S[] PROGMEM = {
#include "config/generic_33v_300s_28d/bsec_iaq.txt"
};
this->bsec_status_ =
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
} else { // SUPPLY_VOLTAGE_1V8
const uint8_t config[] = {
};
static constexpr uint8_t CONFIG_18V_300S[] PROGMEM = {
#include "config/generic_18v_300s_28d/bsec_iaq.txt"
};
this->bsec_status_ =
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
}
} else { // SAMPLE_RATE_LP
if (this->supply_voltage_ == SUPPLY_VOLTAGE_3V3) {
const uint8_t config[] = {
};
static constexpr uint8_t CONFIG_33V_3S[] PROGMEM = {
#include "config/generic_33v_3s_28d/bsec_iaq.txt"
};
this->bsec_status_ =
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
} else { // SUPPLY_VOLTAGE_1V8
const uint8_t config[] = {
};
static constexpr uint8_t CONFIG_18V_3S[] PROGMEM = {
#include "config/generic_18v_3s_28d/bsec_iaq.txt"
};
this->bsec_status_ =
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
}
};
static_assert(sizeof(CONFIG_33V_300S) <= BSEC_MAX_PROPERTY_BLOB_SIZE &&
sizeof(CONFIG_18V_300S) <= BSEC_MAX_PROPERTY_BLOB_SIZE &&
sizeof(CONFIG_33V_3S) <= BSEC_MAX_PROPERTY_BLOB_SIZE &&
sizeof(CONFIG_18V_3S) <= BSEC_MAX_PROPERTY_BLOB_SIZE);
void BME680BSECComponent::set_config_() {
const bool v33 = this->supply_voltage_ == SUPPLY_VOLTAGE_3V3;
const uint8_t *source;
size_t size;
if (this->sample_rate_ == SAMPLE_RATE_ULP) {
source = v33 ? CONFIG_33V_300S : CONFIG_18V_300S;
size = v33 ? sizeof(CONFIG_33V_300S) : sizeof(CONFIG_18V_300S);
} else { // SAMPLE_RATE_LP
source = v33 ? CONFIG_33V_3S : CONFIG_18V_3S;
size = v33 ? sizeof(CONFIG_33V_3S) : sizeof(CONFIG_18V_3S);
}
// BSEC reads the blob with plain loads, so copy the selected one to RAM
uint8_t config[BSEC_MAX_PROPERTY_BLOB_SIZE]{};
progmem_memcpy(config, source, size);
this->bsec_status_ =
bsec_set_configuration(config, BSEC_MAX_PROPERTY_BLOB_SIZE, this->work_buffer_, sizeof(this->work_buffer_));
}
float BME680BSECComponent::calc_sensor_sample_rate_(SampleRate sample_rate) {
+8 -3
View File
@@ -7,7 +7,8 @@ from esphome.helpers import write_file_if_changed
from esphome.types import ConfigType
from tests.testing_helpers import ComponentManifestOverride
# set_config_() includes one of these library blobs; the double only needs them to exist.
# set_config_() includes one of these library blobs; each gets distinct bytes so test_config.cpp can tell
# which one reached bsec_set_configuration().
_CONFIG_BLOBS = (
"generic_33v_300s_28d",
"generic_18v_300s_28d",
@@ -23,8 +24,12 @@ def override_manifest(manifest: ComponentManifestOverride) -> None:
async def to_code_testing(config: ConfigType) -> None:
blobs = CORE.relative_build_path("bsec_config")
for name in _CONFIG_BLOBS:
write_file_if_changed(blobs / "config" / name / "bsec_iaq.txt", "0\n")
for index, name in enumerate(_CONFIG_BLOBS):
first = 0x10 * (index + 1)
write_file_if_changed(
blobs / "config" / name / "bsec_iaq.txt",
f"{first}, {first + 1}, {first + 2}\n",
)
cg.add_build_flag(f"-I{blobs}")
cg.add_build_flag(f"-I{CORE.relative_src_path('bme680_bsec', '__sdk')}")
cg.add_define("USE_BSEC")
+8 -1
View File
@@ -57,6 +57,9 @@ inline uint8_t num_outputs = 0;
inline bool armed = false;
// Counts bsec_get_state calls, which the component makes only when it saves its state.
inline int get_state_calls = 0;
// The blob and length the last bsec_set_configuration call received.
inline uint8_t config[BSEC_MAX_PROPERTY_BLOB_SIZE]{};
inline uint32_t config_size = 0;
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
inline void arm(const bsec_output_t *reading, uint8_t count) {
@@ -71,7 +74,11 @@ inline bsec_library_return_t bsec_get_version(bsec_version_t *version) {
*version = {};
return BSEC_OK;
}
inline bsec_library_return_t bsec_set_configuration(const uint8_t *, uint32_t, uint8_t *, uint32_t) { return BSEC_OK; }
inline bsec_library_return_t bsec_set_configuration(const uint8_t *config, uint32_t size, uint8_t *, uint32_t) {
std::memcpy(bsec_double::config, config, size < sizeof(bsec_double::config) ? size : sizeof(bsec_double::config));
bsec_double::config_size = size;
return BSEC_OK;
}
inline bsec_library_return_t bsec_update_subscription(const bsec_sensor_configuration_t *, uint8_t,
bsec_sensor_configuration_t *, uint8_t *) {
return BSEC_OK;
@@ -0,0 +1,51 @@
#include <gtest/gtest.h>
#include <cstring>
#include <tuple>
#include "esphome/components/bme680_bsec/bme680_bsec.h"
// The unit test build defines USE_BSEC and builds against the library double in __sdk; clang-tidy does not.
#ifdef USE_BSEC
namespace esphome::bme680_bsec::testing {
namespace {
// Sample rate, supply voltage, and the first byte of the blob __init__.py writes for that pair.
using ConfigCase = std::tuple<SampleRate, SupplyVoltage, uint8_t>;
class BSECConfigTest : public ::testing::TestWithParam<ConfigCase> {};
TEST_P(BSECConfigTest, SetupPassesTheSelectedBlob) {
auto [sample_rate, supply_voltage, first] = GetParam();
bsec_double::config_size = 0;
std::memset(bsec_double::config, 0xEE, sizeof(bsec_double::config));
BME680BSECComponent component;
component.set_sample_rate(sample_rate);
component.set_supply_voltage(supply_voltage);
component.setup();
// setup() registers the component; drop it so later tests do not see a dangling instance
ASSERT_FALSE(BME680BSECComponent::instances.empty());
ASSERT_EQ(BME680BSECComponent::instances.back(), &component);
BME680BSECComponent::instances.pop_back();
// The whole blob, copied out of the selected table, padded with zeros to the blob size
EXPECT_EQ(bsec_double::config_size, BSEC_MAX_PROPERTY_BLOB_SIZE);
EXPECT_EQ(bsec_double::config[0], first);
EXPECT_EQ(bsec_double::config[1], first + 1);
EXPECT_EQ(bsec_double::config[2], first + 2);
for (size_t i = 3; i < BSEC_MAX_PROPERTY_BLOB_SIZE; i++)
EXPECT_EQ(bsec_double::config[i], 0) << "byte " << i;
}
INSTANTIATE_TEST_SUITE_P(AllBlobs, BSECConfigTest,
::testing::Values(ConfigCase{SAMPLE_RATE_ULP, SUPPLY_VOLTAGE_3V3, 0x10},
ConfigCase{SAMPLE_RATE_ULP, SUPPLY_VOLTAGE_1V8, 0x20},
ConfigCase{SAMPLE_RATE_LP, SUPPLY_VOLTAGE_3V3, 0x30},
ConfigCase{SAMPLE_RATE_LP, SUPPLY_VOLTAGE_1V8, 0x40}));
} // namespace
} // namespace esphome::bme680_bsec::testing
#endif // USE_BSEC