From 4d50891a639e9c65c654d22c49d7e9171ccd8d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 2 Jan 2022 22:57:15 +0100 Subject: [PATCH] add bsec persistence --- main/co2_sensor.c | 13 +++++++++---- main/settings.c | 10 +++++++++- main/settings.h | 2 ++ main/voc_sensor.c | 39 +++++++++++++++++++++++++++------------ 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/main/co2_sensor.c b/main/co2_sensor.c index 2293752..ed47a15 100644 --- a/main/co2_sensor.c +++ b/main/co2_sensor.c @@ -13,6 +13,8 @@ #include "settings.h" #include #include +#include +#include static const char *TAG = "co2"; @@ -77,7 +79,7 @@ static bool ppm_looks_valid(uint16_t ppm) { } void co2_read_task(void *param) { - esp_err_t rv; + (void) param; vTaskDelay(pdMS_TO_TICKS(500)); @@ -91,8 +93,10 @@ void co2_read_task(void *param) { write_saved_calib_to_sensor(); - const uint32_t read_cycle_time_ticks = pdMS_TO_TICKS(10 * 1000); - const uint32_t calib_persist_time_ticks = pdMS_TO_TICKS(6 * 3600 * 1000); + const uint32_t read_cycle_time_ticks = 10 * 1000; + const uint32_t calib_persist_time_ticks = 12 * 3600 * 1000; + _Static_assert(configTICK_RATE_HZ == 1000, "1kHz tick"); + uint32_t last_calib_persist = xTaskGetTickCount(); ESP_LOGD(TAG, "Calib persist time = %d ticks", calib_persist_time_ticks); @@ -176,7 +180,8 @@ void co2_read_task(void *param) { // CO2 measurement looks OK uint32_t tickNow = xTaskGetTickCount(); - if ((tickNow - last_calib_persist) > calib_persist_time_ticks) { + uint32_t elapsed = tickNow - last_calib_persist; + if (elapsed > calib_persist_time_ticks) { ESP_LOGI(TAG, "Read & persist CO2 calibration"); last_calib_persist = tickNow; diff --git a/main/settings.c b/main/settings.c index 1cdebb1..88a2e10 100644 --- a/main/settings.c +++ b/main/settings.c @@ -122,12 +122,16 @@ void settings_load(void) size_t capacity = 10; NVSCHECK(nvs_get_blob(storage, "co2_calib", g_Settings.co2_calib, &capacity)); } + { + size_t capacity = BSEC_MAX_STATE_BLOB_SIZE; + NVSCHECK(nvs_get_blob(storage, "bsec_state", g_Settings.bsec_state, &capacity)); + } } void settings_persist(enum settings_key_enum what) { esp_err_t rv; - char name[24]; +// char name[24]; #undef NVSCHECK #define NVSCHECK(callback) \ @@ -160,6 +164,10 @@ void settings_persist(enum settings_key_enum what) if (what==SETTINGS_ALL || what==SETTINGS_co2_calib) { NVSCHECK(nvs_set_blob(storage, "co2_calib", (void*) g_Settings.co2_calib, 5*sizeof(uint16_t))); } + + if (what==SETTINGS_ALL || what==SETTINGS_bsec_state) { + NVSCHECK(nvs_set_blob(storage, "bsec_state", (void*) g_Settings.bsec_state, BSEC_MAX_STATE_BLOB_SIZE)); + } } uint16_t app_get_bootcount() diff --git a/main/settings.h b/main/settings.h index 0e0e026..297f217 100644 --- a/main/settings.h +++ b/main/settings.h @@ -10,6 +10,7 @@ #include #include #include +#include #define CONSOLE_TELNET_PORT CONFIG_CONSOLE_TELNET_PORT #define CONSOLE_PW_LEN CONFIG_CONSOLE_PW_LEN @@ -35,6 +36,7 @@ extern nvs_handle g_nvs_storage; X(bool , ntp_enable , , 1 , true , bool , &) \ X(char , ntp_srv ,[NTP_SRV_LEN], DEF_NTP_SRV , false, none , ) \ X(uint16_t , co2_calib ,[5], {}, false, none , ) \ + X(uint8_t , bsec_state ,[BSEC_MAX_STATE_BLOB_SIZE], {}, false, none , ) \ X(bool , dhcp_wd_enable , , 1 , true , bool , &) \ X(bool , dhcp_enable , , 1 , true , bool , &) \ X(uint32_t , static_ip , , 0 , true , u32 , &) \ diff --git a/main/voc_sensor.c b/main/voc_sensor.c index aa1f17e..a947fe3 100644 --- a/main/voc_sensor.c +++ b/main/voc_sensor.c @@ -23,6 +23,7 @@ static const char *TAG = "voc"; #include "bme68x_defs.h" #include "bsec2.h" #include "periph_init.h" +#include "settings.h" struct sensor_itf { uint8_t dev_addr; @@ -30,7 +31,7 @@ struct sensor_itf { static struct sensor_itf gas_sensor_intf = {}; static struct bme68x_dev gas_sensor = {}; -static struct bsec2 gas_sensor_bsec = {}; +static struct bsec2 hBsec = {}; void bsec2_errormsg(const char *msg) { ESP_LOGE("BSEC", "%s", msg); @@ -103,7 +104,7 @@ static esp_err_t voc_init(void) { int8_t rslt; gas_sensor_intf.dev_addr = BME68X_I2C_ADDR_LOW; gas_sensor.intf_ptr = &gas_sensor_intf; - gas_sensor.amb_temp = 25; // TODO set this from senseair! + gas_sensor.amb_temp = 25; gas_sensor.intf = BME68X_I2C_INTF; gas_sensor.read = user_i2c_read; gas_sensor.write = user_i2c_write; @@ -243,7 +244,7 @@ void voc_read_task(void *param) { goto abort; } - int rv = bsec2_init(&gas_sensor_bsec, &gas_sensor); + int rv = bsec2_init(&hBsec, &gas_sensor); if (rv != 0) { ESP_LOGE(TAG, "Error in bsec init: %d", rv); goto abort; @@ -267,7 +268,7 @@ void voc_read_task(void *param) { BSEC_OUTPUT_RUN_IN_STATUS, }; - rv = bsec2_updateSubscription(&gas_sensor_bsec, + rv = bsec2_updateSubscription(&hBsec, sensorList, sizeof(sensorList) / sizeof(bsecSensor), BSEC_SAMPLE_RATE_LP); @@ -277,21 +278,35 @@ void voc_read_task(void *param) { goto abort; } - bsec2_attachCallback(&gas_sensor_bsec, new_data_callback); + bsec2_attachCallback(&hBsec, new_data_callback); ESP_LOGI(TAG, "BSEC library version %d.%d.%d.%d", - gas_sensor_bsec.version.major, - gas_sensor_bsec.version.minor, - gas_sensor_bsec.version.major_bugfix, - gas_sensor_bsec.version.minor_bugfix); + hBsec.version.major, + hBsec.version.minor, + hBsec.version.major_bugfix, + hBsec.version.minor_bugfix); - // TODO add bsec state persistence to NVS at some landmark intervals, e.g. 1 day - // TODO periodic updating of sensor ambient temp + const uint32_t state_persist_time_ticks = 12 * 3600 * 1000; + _Static_assert(configTICK_RATE_HZ == 1000, "1kHz tick"); + uint32_t last_state_persist = xTaskGetTickCount(); + + ESP_LOGI(TAG, "Restore BSEC state"); + bsec2_setState(&hBsec, g_Settings.bsec_state); while (1) { - rv = bsec2_run(&gas_sensor_bsec); + rv = bsec2_run(&hBsec); if (false == rv) { ESP_LOGE(TAG, "Error in bsec run!"); + } else { + uint32_t tickNow = xTaskGetTickCount(); + uint32_t elapsed = tickNow - last_state_persist; + if (elapsed > state_persist_time_ticks) { + ESP_LOGI(TAG, "Read & persist BSEC state"); + last_state_persist = tickNow; + if (bsec2_getState(&hBsec, g_Settings.bsec_state)) { + settings_persist(SETTINGS_bsec_state); + } + } } vTaskDelay(pdMS_TO_TICKS(100)); }