8 static const char *
const TAG =
"veml7700";
9 static const size_t VEML_REG_SIZE = 2;
11 static float reduce_to_zero(
float a,
float b) {
return (a > b) ? (a - b) : 0; }
13 template<
typename T,
size_t size> T
get_next(
const T (&array)[size],
const T
val) {
16 while (idx == -1 && i < size) {
17 if (array[i] == val) {
23 if (idx == -1 || i + 1 >= size)
28 template<
typename T,
size_t size> T
get_prev(
const T (&array)[size],
const T
val) {
31 while (idx == -1 && i > 0) {
32 if (array[i] == val) {
38 if (idx == -1 || i == 0)
70 static float get_gain_coeff(
Gain gain) {
71 static const float GAIN_FLOAT[
GAINS_COUNT] = {1.0f, 2.0f, 0.125f, 0.25f};
72 return GAIN_FLOAT[gain & 0
b11];
75 static const char *get_gain_str(
Gain gain) {
76 static const char *gain_str[
GAINS_COUNT] = {
"1x",
"2x",
"1/8x",
"1/4x"};
77 return gain_str[gain & 0
b11];
81 ESP_LOGCONFIG(TAG,
"Setting up VEML7700/6030...");
85 ESP_LOGW(TAG,
"Sensor configuration failed");
96 ESP_LOGCONFIG(TAG,
" Gain: %s", get_gain_str(this->
gain_));
97 ESP_LOGCONFIG(TAG,
" Integration time: %d ms", get_itime_ms(this->
integration_time_));
101 LOG_UPDATE_INTERVAL(
this);
112 ESP_LOGE(TAG,
"Communication with I2C VEML7700/6030 failed!");
118 ESP_LOGV(TAG,
"Update: Initiating new data collection");
130 ESP_LOGV(TAG,
"Update: Component not ready yet");
145 switch (this->state_) {
166 [
this]() { this->state_ = State::READY_TO_APPLY_ADJUSTMENTS; });
184 [
this]() { this->state_ = State::COLLECTING_DATA; });
220 ESP_LOGV(TAG,
"Configure");
226 als_conf.ALS_GAIN = this->
gain_;
228 als_conf.ALS_SD =
true;
229 ESP_LOGV(TAG,
"Shutdown before config. ALS_CONF_0 to 0x%04X", als_conf.raw);
232 ESP_LOGW(TAG,
"Failed to shutdown, I2C error %d", err);
237 als_conf.ALS_SD =
false;
238 ESP_LOGV(TAG,
"Turning on. Setting ALS_CONF_0 to 0x%04X", als_conf.raw);
239 err = this->
write_register((uint8_t) CommandRegisters::ALS_CONF_0, als_conf.raw_bytes, VEML_REG_SIZE);
241 ESP_LOGW(TAG,
"Failed to turn on, I2C error %d", err);
248 ESP_LOGV(TAG,
"Setting PSM to 0x%04X", psm.raw);
251 ESP_LOGW(TAG,
"Failed to set PSM, I2C error %d", err);
259 ESP_LOGV(TAG,
"Reconfigure time and gain (%d ms, %s) %s", get_itime_ms(time), get_gain_str(gain),
260 shutdown ?
"Shutting down" :
"Turning back on");
266 als_conf.ALS_SD = shutdown;
267 als_conf.ALS_INT_EN =
false;
269 als_conf.ALS_IT = time;
270 als_conf.ALS_GAIN =
gain;
273 ESP_LOGW(TAG,
"%s failed", shutdown ?
"Shutdown" :
"Turn on");
283 ESP_LOGW(TAG,
"Error reading ALS register, err = %d", als_err);
288 ESP_LOGW(TAG,
"Error reading WHITE register, err = %d", white_err);
295 ESP_LOGW(TAG,
"Error reading ALS_CONF_0 register, err = %d", white_err);
300 ESP_LOGV(TAG,
"Data from sensors: ALS = %d, WHITE = %d, Gain = %s, Time = %d ms", data.
als_counts, data.
white_counts,
302 return std::max(als_err, white_err);
315 static constexpr uint16_t LOW_INTENSITY_THRESHOLD = 100;
316 static constexpr uint16_t HIGH_INTENSITY_THRESHOLD = 10000;
323 if (data.
als_counts <= LOW_INTENSITY_THRESHOLD) {
334 }
else if (data.
als_counts >= HIGH_INTENSITY_THRESHOLD) {
353 static const float MAX_GAIN = 2.0f;
354 static const float MAX_ITIME_MS = 800.0f;
355 static const float MAX_LX_RESOLUTION = 0.0036f;
356 float lux_resolution = (MAX_ITIME_MS / (float) get_itime_ms(data.
actual_time)) *
357 (MAX_GAIN / get_gain_coeff(data.
actual_gain)) * MAX_LX_RESOLUTION;
358 ESP_LOGV(TAG,
"Lux resolution for (%d, %s) = %.4f ", get_itime_ms(data.
actual_time), get_gain_str(data.
actual_gain),
365 ESP_LOGV(TAG,
"%s mode - ALS = %.1f lx, WHITE = %.1f lx, FAKE_IR = %.1f lx",
373 auto &local_data = data;
381 auto compensate = [&local_data](
float &lux) {
382 auto calculate_high_lux_compensation = [](
float lux_veml) ->
float {
383 return (((6.0135e-13 * lux_veml - 9.3924e-9) * lux_veml + 8.1488e-5) * lux_veml + 1.0023) * lux_veml;
387 lux = calculate_high_lux_compensation(lux);
395 ESP_LOGV(TAG,
"Lux compensation - ALS = %.1f lx, WHITE = %.1f lx, FAKE_IR = %.1f lx", data.
als_lux, data.
white_lux,
403 ESP_LOGV(TAG,
"Glass attenuation - ALS = %.1f lx, WHITE = %.1f lx, FAKE_IR = %.1f lx", data.
als_lux, data.
white_lux,
bool lux_compensation_enabled_
struct esphome::veml7700::VEML7700Component::Readings readings_
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
sensor::Sensor * white_sensor_
void status_set_warning(const char *message="unspecified")
void apply_lux_compensation_(Readings &data)
bool are_adjustments_required_(Readings &data)
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
const uint8_t INTEGRATION_TIMES_COUNT
sensor::Sensor * actual_integration_time_sensor_
sensor::Sensor * ambient_light_sensor_
sensor::Sensor * fake_infrared_sensor_
sensor::Sensor * ambient_light_counts_sensor_
sensor::Sensor * actual_gain_sensor_
void apply_glass_attenuation_(Readings &data)
No error found during execution of method.
void status_clear_warning()
void publish_state(float state)
Publish a new state to the front-end.
bool automatic_mode_enabled_
IntegrationTime actual_time
void apply_lux_calculation_(Readings &data)
const uint8_t GAINS_COUNT
ErrorCode read_sensor_output_(Readings &data)
T get_next(const T(&array)[size], const T val)
float glass_attenuation_factor_
void publish_data_part_1_(Readings &data)
void publish_data_part_2_(Readings &data)
virtual void mark_failed()
Mark this component as failed.
IntegrationTime integration_time_
Implementation of SPI Controller mode.
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a specific register in the I²C device
T get_prev(const T(&array)[size], const T val)
void publish_data_part_3_(Readings &data)
void dump_config() override
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
ErrorCode reconfigure_time_and_gain_(IntegrationTime time, Gain gain, bool shutdown)
sensor::Sensor * white_counts_sensor_
void IRAM_ATTR HOT delay(uint32_t ms)