mirror of
https://github.com/esphome/esphome.git
synced 2026-11-15 09:36:04 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3c043ac1b | ||
|
|
ef6248dd20 | ||
|
|
bfdd0ad82f | ||
|
|
e683b58d6e |
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user