From a04c9724ccc9a60897d72568f9006b5391cea833 Mon Sep 17 00:00:00 2001 From: Anton Viktorov Date: Thu, 14 Mar 2024 12:32:31 +0100 Subject: [PATCH] glass attn --- esphome/components/as7343/as7343.cpp | 48 +++++++++++++++++++--------- esphome/components/as7343/as7343.h | 4 ++- esphome/components/as7343/sensor.py | 5 +++ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/esphome/components/as7343/as7343.cpp b/esphome/components/as7343/as7343.cpp index 4fa9388de3..c25a5b0499 100644 --- a/esphome/components/as7343/as7343.cpp +++ b/esphome/components/as7343/as7343.cpp @@ -133,6 +133,7 @@ void AS7343Component::dump_config() { ESP_LOGCONFIG(TAG, " Gain: %.1f", get_gain_multiplier(get_gain())); ESP_LOGCONFIG(TAG, " ATIME: %u", get_atime()); ESP_LOGCONFIG(TAG, " ASTEP: %u", get_astep()); + ESP_LOGCONFIG(TAG, " Glass attenuation factor: %f", this->glass_attenuation_factor_); LOG_SENSOR(" ", "F1", this->f1_); LOG_SENSOR(" ", "F2", this->f2_); @@ -174,7 +175,6 @@ void AS7343Component::update() { this->enable_spectral_measurement(false); this->calculate_basic_counts(); - log13_s(TAG, "Channel", CHANNEL_NAMES); log13_f(TAG, "Nm", CHANNEL_NM); log13_d(TAG, "Counts", this->readings_.raw_counts); @@ -183,9 +183,9 @@ void AS7343Component::update() { uint16_t highest_adc = this->get_highest_value(this->readings_.raw_counts); if (highest_adc >= max_adc) { - ESP_LOGW(TAG, "Max ADC: %u, Highest ADC: %u", max_adc, highest_adc); + ESP_LOGW(TAG, "Max ADC: %u, Highest reading: %u", max_adc, highest_adc); } else { - ESP_LOGD(TAG, "Max ADC: %u, Highest ADC: %u", max_adc, highest_adc); + ESP_LOGD(TAG, "Max ADC: %u, Highest reading: %u", max_adc, highest_adc); } ESP_LOGD(TAG, " ,Gain , %.1f,X", this->readings_.gain_x); @@ -206,15 +206,29 @@ void AS7343Component::update() { // this->channel_readings_[CHANNEL_IDX[12]]); float irradiance; + float irradiance_photopic; float lux; float ppfd; - this->calculate_irradiance(irradiance, lux); + this->calculate_irradiance(irradiance, irradiance_photopic, lux); this->calculate_ppfd(ppfd); - ESP_LOGD(TAG, " ,Irradiance, %f, W/m²", irradiance); - ESP_LOGD(TAG, " ,Lux solar , %f, lx", lux); - ESP_LOGD(TAG, " ,PPFD , %.2f, µmol/s⋅m²", ppfd); + ESP_LOGD(TAG, "BEFORE GLASS ATTENUATION"); + ESP_LOGD(TAG, " ,Irradiance , %f, W/m²", irradiance); + ESP_LOGD(TAG, " ,Irradiance(photopic), %f, W/m²", irradiance_photopic); + ESP_LOGD(TAG, " ,Lux(solar coeff) , %f, lx", lux); + ESP_LOGD(TAG, " ,PPFD , %.2f, µmol/s⋅m²", ppfd); + + irradiance *= this->glass_attenuation_factor_; + irradiance_photopic *= this->glass_attenuation_factor_; + lux *= this->glass_attenuation_factor_; + ppfd *= this->glass_attenuation_factor_; + + ESP_LOGD(TAG, "AFTER GLASS ATTENUATION"); + ESP_LOGD(TAG, " ,Irradiance , %f, W/m²", irradiance); + ESP_LOGD(TAG, " ,Irradiance(photopic), %f, W/m²", irradiance_photopic); + ESP_LOGD(TAG, " ,Lux(solar coeff) , %f, lx", lux); + ESP_LOGD(TAG, " ,PPFD , %.2f, µmol/s⋅m²", ppfd); if (this->illuminance_ != nullptr) { this->illuminance_->publish_state(lux); @@ -387,25 +401,29 @@ void AS7343Component::calculate_ppfd(float &ppfd) { } } -void AS7343Component::calculate_irradiance(float &irradiance_in_w_per_m2, float &lux) { +void AS7343Component::calculate_irradiance(float &irradiance_in_w_per_m2, float &irradiance_in_w_per_m2_photopic, + float &lux) { // Total irradiance in a whole wavelenght interval float irr_band; - float lux_band; + float photo_band; irradiance_in_w_per_m2 = 0; + irradiance_in_w_per_m2_photopic = 0; + lux = 0; + // walk through all bands except for Clear (VIS) for (uint8_t i = 0; i < AS7343_NUM_CHANNELS - 1; i++) { irr_band = this->readings_.basic_counts[i] * CHANNEL_IRRAD_MW_PER_BASIC_COUNT[i] / 1000; - - // irr_band *= CHANNEL_ENERGY_CONTRIBUTION[i]; ? - lux_band = irr_band * CHANNEL_PHOTOPIC_LUMINOSITY[i]; - - lux += lux_band; irradiance_in_w_per_m2 += irr_band; + + // photo_band *= CHANNEL_ENERGY_CONTRIBUTION[i]; ?? ideas + // let's make model assumption bands are adjacent and cover whole range + photo_band = irr_band * CHANNEL_PHOTOPIC_LUMINOSITY[i]; + irradiance_in_w_per_m2_photopic += photo_band; } // sunlight equivalent // 1 W/m2 = 116 ± 3 lx solar // https://www.extrica.com/article/21667/pdf - lux *= 116; + lux = irradiance_in_w_per_m2_photopic * 116; } bool AS7343Component::read_all_channels() { diff --git a/esphome/components/as7343/as7343.h b/esphome/components/as7343/as7343.h index 79c4967c4e..156a90d089 100644 --- a/esphome/components/as7343/as7343.h +++ b/esphome/components/as7343/as7343.h @@ -37,6 +37,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { void set_gain(AS7343Gain gain) { gain_ = gain; } void set_atime(uint8_t atime) { atime_ = atime; } void set_astep(uint16_t astep) { astep_ = astep; } + void set_glass_attenuation_factor(float factor) { this->glass_attenuation_factor_ = factor; } AS7343Gain get_gain(); uint8_t get_atime(); @@ -54,7 +55,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { void calculate_basic_counts(); void calculate_ppfd(float &ppfd); - void calculate_irradiance(float &irradiance, float &lux); + void calculate_irradiance(float &irradiance, float &irradiance_photopic, float &lux); bool wait_for_data(uint16_t timeout = 1000); bool is_data_ready(); @@ -94,6 +95,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { uint16_t astep_; AS7343Gain gain_; uint8_t atime_; + float glass_attenuation_factor_{1.0}; struct { std::array raw_counts; diff --git a/esphome/components/as7343/sensor.py b/esphome/components/as7343/sensor.py index 3760774eeb..24ec7e4549 100644 --- a/esphome/components/as7343/sensor.py +++ b/esphome/components/as7343/sensor.py @@ -7,6 +7,7 @@ from esphome.const import ( CONF_NAME, CONF_ILLUMINANCE, DEVICE_CLASS_ILLUMINANCE, + CONF_GLASS_ATTENUATION_FACTOR, ICON_BRIGHTNESS_5, STATE_CLASS_MEASUREMENT, UNIT_LUX, @@ -98,6 +99,9 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_GAIN, default="X8"): cv.enum(GAIN_OPTIONS), cv.Optional(CONF_ATIME, default=29): cv.int_range(min=0, max=255), cv.Optional(CONF_ASTEP, default=599): cv.int_range(min=0, max=65534), + cv.Optional(CONF_GLASS_ATTENUATION_FACTOR, default=1.0): cv.float_range( + min=1.0 + ), cv.Optional(CONF_ILLUMINANCE): cv.maybe_simple_value( sensor.sensor_schema( unit_of_measurement=UNIT_LUX, @@ -173,6 +177,7 @@ async def to_code(config): cg.add(var.set_gain(config[CONF_GAIN])) cg.add(var.set_atime(config[CONF_ATIME])) cg.add(var.set_astep(config[CONF_ASTEP])) + cg.add(var.set_glass_attenuation_factor(config[CONF_GLASS_ATTENUATION_FACTOR])) for conf_id, set_sensor_func in SENSORS.items(): if sens_config := config.get(conf_id):