diff --git a/esphome/components/as7343/as7343.cpp b/esphome/components/as7343/as7343.cpp index 557e899e49..16a75bf98e 100644 --- a/esphome/components/as7343/as7343.cpp +++ b/esphome/components/as7343/as7343.cpp @@ -24,10 +24,11 @@ static constexpr float CHANNEL_BASIC_CORRECTIONS[NUM_USEFUL_CHANNELS] = { 1.055464349, 1.043509797, 1.029576268, 1.0175052, 1.00441899, 0.987356499, 0.957597044, 0.995863485, 1.014628964, 0.996500814, 0.933072749, 1.052236338, 0.999570232}; +static const float OFFSETS[NUM_USEFUL_CHANNELS] = {0.000281, 0.000281, 0.000281, 0.000281, 0.000281, 0.000281, + 0.000281, 0.000281, 0.000422, 0.000281, 0.000422, 0.000281}; + static constexpr float CHANNEL_NM[NUM_USEFUL_CHANNELS] = {405, 425, 450, 475, 515, 555, 550, 600, 640, 690, 745, 855, 718}; -// static constexpr float CHANNEL_CONTRIB[NUM_USEFUL_CHANNELS] = { -// 0.0603622, 0.0442656, 0.110664, 0.0603622, 0.0804829, 0.201207, 0.0704225, 0.160966, 0.100604, 0.110664, 0}; static constexpr float CHANNEL_NM_WIDTH[NUM_USEFUL_CHANNELS] = {30, 22, 55, 30, 40, 100, 35, 80, 50, 55, 60, 54, 0}; // Irradiation in mW/m² per basic count @@ -40,6 +41,8 @@ static constexpr float PHOTON_ENERGIES[NUM_USEFUL_CHANNELS] = { 4.9048E-19f, 4.67399E-19f, 4.41432E-19f, 4.18199E-19f, 3.85718E-19f, 3.57918E-19f, 3.61172E-19f, 3.31074E-19f, 3.10382E-19f, 2.87891E-19f, 2.66637E-19f, 2.32333E-19f, 2.76664E-19f}; +// static constexpr float CHANNEL_CONTRIB[NUM_USEFUL_CHANNELS] = { +// 0.0603622, 0.0442656, 0.110664, 0.0603622, 0.0804829, 0.201207, 0.0704225, 0.160966, 0.100604, 0.110664, 0}; static constexpr float CHANNEL_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773, 0.04848841, 0.114486525, @@ -54,16 +57,6 @@ static constexpr float CHANNEL_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773, 0.059160501, 0}; -// constexpr std::array fill_photon_energy() { -// std::array v{0}; -// for(int i = 0; i < NUM_USEFUL_CHANNELS; ++i) { -// v[i] = CHANNEL_NM[i]> 0 ? CONST_H * CONST_C / (CHANNEL_NM[i] * 1e9) : 0; -// } -// return v; -// } - -// constexpr std::array v = fill_photon_energy(); - void AS7343Component::setup() { ESP_LOGCONFIG(TAG, "Setting up AS7343..."); LOG_I2C_DEVICE(this); @@ -123,6 +116,8 @@ void AS7343Component::dump_config() { LOG_SENSOR(" ", "F8", this->f8_); LOG_SENSOR(" ", "NIR", this->nir_); LOG_SENSOR(" ", "Clear", this->clear_); + LOG_SENSOR(" ", "Clear", this->clear_); + LOG_SENSOR(" ", "Clear", this->clear_); } float AS7343Component::get_setup_priority() const { return setup_priority::DATA; } @@ -157,10 +152,10 @@ void AS7343Component::update() { float irradiance; float lux; this->calculate_irradiance(tint_ms, gain_x, irradiance, lux, gain); - ESP_LOGD(TAG, " ,Irradiance, %f, W/m^2", irradiance); + ESP_LOGD(TAG, " ,Irradiance, %f, W/m²", irradiance); ESP_LOGD(TAG, " ,Lux solar , %f, lx", lux); - float par = this->calculate_ppfd(tint_ms, gain_x, gain); - ESP_LOGD(TAG, " ,PAR , %.2f", par); + float ppfd = this->calculate_ppfd(tint_ms, gain_x, gain); + ESP_LOGD(TAG, " ,PPFD , %.2f, µmol/sm²", ppfd); if (this->illuminance_ != nullptr) { this->illuminance_->publish_state(lux); @@ -170,6 +165,10 @@ void AS7343Component::update() { this->irradiance_->publish_state(irradiance); } + if (this->ppfd_ != nullptr) { + this->ppfd_->publish_state(ppfd); + } + // for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) { // this->channel_readings_[CHANNEL_IDX[1]] /= CHANNEL_SENS[i] * 65535; // } @@ -216,6 +215,9 @@ void AS7343Component::update() { 3; this->clear_->publish_state(clear); } + if (this->saturated_ != nullptr) { + this->saturated_->publish_state(this->readings_saturated_); + } } AS7343Gain AS7343Component::get_gain() { @@ -254,8 +256,10 @@ bool AS7343Component::setup_astep(uint16_t astep) { return this->write_byte_16((uint8_t) AS7343Registers::ASTEP_LSB, swap_bytes(astep)); } -static const float OFFSETS[NUM_USEFUL_CHANNELS] = {0.000281, 0.000281, 0.000281, 0.000281, 0.000281, 0.000281, - 0.000281, 0.000281, 0.000422, 0.000281, 0.000422, 0.000281}; +bool AS7343Component::change_gain(AS7343Gain gain) { + this->enable_spectral_measurement(false); + return this->write_byte((uint8_t) AS7343Registers::CFG1, gain); +} float AS7343Component::calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain) { float par = 0; @@ -316,6 +320,7 @@ bool AS7343Component::read_channels(uint16_t *data) { if (astatus.asat_status) { ESP_LOGW(TAG, "AS7343 affected by analog or digital saturation. Readings are not reliable."); } + this->readings_saturated_ = astatus.asat_status; return this->read_bytes_16((uint8_t) AS7343Registers::DATA_O, this->channel_readings_, AS7343_NUM_CHANNELS); } diff --git a/esphome/components/as7343/as7343.h b/esphome/components/as7343/as7343.h index a439a86b7b..21ebf3d601 100644 --- a/esphome/components/as7343/as7343.h +++ b/esphome/components/as7343/as7343.h @@ -9,57 +9,6 @@ namespace esphome { namespace as7343 { -static const uint8_t AS7341_CONFIG = 0x70; -static const uint8_t AS7341_LED = 0x74; - -static const uint8_t AS7341_ENABLE = 0x80; -static const uint8_t AS7341_ATIME = 0x81; - -static const uint8_t AS7341_WTIME = 0x83; - -static const uint8_t AS7341_AUXID = 0x90; -static const uint8_t AS7341_REVID = 0x91; -static const uint8_t AS7341_ID = 0x92; -static const uint8_t AS7341_STATUS = 0x93; - -// static const uint8_t AS7341_CH0_DATA_L = 0x95; -// static const uint8_t AS7341_CH0_DATA_H = 0x96; -// static const uint8_t AS7341_CH1_DATA_L = 0x97; -// static const uint8_t AS7341_CH1_DATA_H = 0x98; -// static const uint8_t AS7341_CH2_DATA_L = 0x99; -// static const uint8_t AS7341_CH2_DATA_H = 0x9A; -// static const uint8_t AS7341_CH3_DATA_L = 0x9B; -// static const uint8_t AS7341_CH3_DATA_H = 0x9C; -// static const uint8_t AS7341_CH4_DATA_L = 0x9D; -// static const uint8_t AS7341_CH4_DATA_H = 0x9E; -// static const uint8_t AS7341_CH5_DATA_L = 0x9F; -// static const uint8_t AS7341_CH5_DATA_H = 0xA0; - -// static const uint8_t AS7341_STATUS2 = 0xA3; - -// static const uint8_t AS7341_CFG1 = 0xAA; ///< Controls ADC Gain - -// static const uint8_t AS7341_CFG6 = 0xAF; // Stores SMUX command -// static const uint8_t AS7341_CFG9 = 0xB2; // Config for system interrupts (SMUX, Flicker detection) - -// static const uint8_t AS7341_ASTEP = 0xCA; // LSB -// static const uint8_t AS7341_ASTEP_MSB = 0xCB; // MSB - -// enum AS7343AdcChannel { -// AS7343_ADC_CHANNEL_0, -// AS7343_ADC_CHANNEL_1, -// AS7343_ADC_CHANNEL_2, -// AS7343_ADC_CHANNEL_3, -// AS7343_ADC_CHANNEL_4, -// AS7343_ADC_CHANNEL_5, -// }; - -// enum AS7343SmuxCommand { -// AS7343_SMUX_CMD_ROM_RESET, ///< ROM code initialization of SMUX -// AS7343_SMUX_CMD_READ, ///< Read SMUX configuration to RAM from SMUX chain -// AS7343_SMUX_CMD_WRITE, ///< Write SMUX configuration from RAM to SMUX chain -// }; - class AS7343Component : public PollingComponent, public i2c::I2CDevice { public: void setup() override; @@ -82,6 +31,8 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { void set_clear_sensor(sensor::Sensor *clear_sensor) { clear_ = clear_sensor; } void set_illuminance_sensor(sensor::Sensor *sensor) { illuminance_ = sensor; } void set_irradiance_sensor(sensor::Sensor *sensor) { irradiance_ = sensor; } + void set_ppfd_sensor(sensor::Sensor *sensor) { ppfd_ = sensor; } + void set_saturation_sensor(sensor::Sensor *sensor) { this->saturated_ = sensor; } void set_gain(AS7343Gain gain) { gain_ = gain; } void set_gain(esphome::optional g); @@ -96,19 +47,15 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { bool setup_atime(uint8_t atime); bool setup_astep(uint16_t astep); + bool change_gain(AS7343Gain gain); + float get_gain_multiplier(AS7343Gain gain); - // uint16_t read_channel(AS7343AdcChannel channel); + bool read_channels(uint16_t *data); float calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain); void calculate_irradiance(float tint_ms, float gain_x, float &irradiance, float &lux, AS7343Gain gain); float calculate_spectre_(); - // void set_smux_low_channels(bool enable); - // bool set_smux_command(AS7343SmuxCommand command); - // void configure_smux_low_channels(); - // void configure_smux_high_channels(); - // bool enable_smux(); - bool wait_for_data(uint16_t timeout = 1000); bool is_data_ready(); bool enable_power(bool enable); @@ -123,6 +70,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { protected: void set_bank_for_reg_(AS7343Registers reg = AS7343Registers::ENABLE); bool bank_{false}; + bool readings_saturated_{false}; sensor::Sensor *f1_{nullptr}; sensor::Sensor *f2_{nullptr}; @@ -139,6 +87,9 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { sensor::Sensor *clear_{nullptr}; sensor::Sensor *illuminance_{nullptr}; sensor::Sensor *irradiance_{nullptr}; + sensor::Sensor *ppfd_{nullptr}; + + sensor::Sensor *saturated_{nullptr}; sensor::Sensor *bf1_{nullptr}; sensor::Sensor *bf2_{nullptr}; diff --git a/esphome/components/as7343/as7343_calibration.cpp b/esphome/components/as7343/as7343_calibration.cpp index 92954afeff..607c05ebc2 100644 --- a/esphome/components/as7343/as7343_calibration.cpp +++ b/esphome/components/as7343/as7343_calibration.cpp @@ -5,19 +5,19 @@ namespace esphome { namespace as7343 { const float AS7343_GAIN_CORRECTION[13][12+1] PROGMEM = { -{1.149000,1.100000,1.060000,1.070000,1.063000,1.051000,1.062000,1.056000,1.049000,1.040000,1.080000,1.038000,1.065000}, -{1.090000,1.128000,1.064000,1.071000,1.063000,1.050000,1.068000,1.055000,1.047000,1.039000,1.075000,1.038000,1.085000}, -{1.083000,1.086000,1.062000,1.070000,1.062000,1.049000,1.057000,1.053000,1.045000,1.038000,1.063000,1.037000,1.069000}, -{1.059000,1.068000,1.056000,1.066000,1.058000,1.046000,1.051000,1.051000,1.044000,1.036000,1.059000,1.035000,1.053000}, -{1.100000,1.109000,1.096000,1.108000,1.099000,1.089000,1.091000,1.092000,1.082000,1.078000,1.100000,1.076000,1.088000}, -{1.099000,1.109000,1.096000,1.108000,1.099000,1.089000,1.091000,1.092000,1.082000,1.078000,1.100000,1.075000,1.087000}, -{1.088000,1.096000,1.085000,1.097000,1.087000,1.078000,1.079000,1.080000,1.071000,1.067000,1.087000,1.064000,1.076000}, -{1.083000,1.091000,1.078000,1.090000,1.079000,1.072000,1.072000,1.073000,1.064000,1.062000,1.080000,1.057000,1.069000}, -{1.076000,1.084000,1.072000,1.085000,1.074000,1.066000,1.062000,1.067000,1.055000,1.056000,1.074000,1.051000,1.061000}, -{1.067000,1.074000,1.063000,1.075000,1.064000,1.059000,1.055000,1.058000,1.049000,1.051000,1.064000,1.044000,1.053000}, -{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000}, -{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000}, -{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000}, +{1.149000,1.100000,1.060000,1.070000,1.063000,1.051000,1.062000,1.056000,1.049000,1.040000,1.080000,1.038000,1.065000},// 0.5x +{1.090000,1.128000,1.064000,1.071000,1.063000,1.050000,1.068000,1.055000,1.047000,1.039000,1.075000,1.038000,1.085000},// 1x +{1.083000,1.086000,1.062000,1.070000,1.062000,1.049000,1.057000,1.053000,1.045000,1.038000,1.063000,1.037000,1.069000},// 2x +{1.059000,1.068000,1.056000,1.066000,1.058000,1.046000,1.051000,1.051000,1.044000,1.036000,1.059000,1.035000,1.053000},// 4x +{1.100000,1.109000,1.096000,1.108000,1.099000,1.089000,1.091000,1.092000,1.082000,1.078000,1.100000,1.076000,1.088000},// 8x +{1.099000,1.109000,1.096000,1.108000,1.099000,1.089000,1.091000,1.092000,1.082000,1.078000,1.100000,1.075000,1.087000},// 16x +{1.088000,1.096000,1.085000,1.097000,1.087000,1.078000,1.079000,1.080000,1.071000,1.067000,1.087000,1.064000,1.076000},// 32x +{1.083000,1.091000,1.078000,1.090000,1.079000,1.072000,1.072000,1.073000,1.064000,1.062000,1.080000,1.057000,1.069000},// 64x +{1.076000,1.084000,1.072000,1.085000,1.074000,1.066000,1.062000,1.067000,1.055000,1.056000,1.074000,1.051000,1.061000},// 128x +{1.067000,1.074000,1.063000,1.075000,1.064000,1.059000,1.055000,1.058000,1.049000,1.051000,1.064000,1.044000,1.053000},// 256x +{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000},// 512x +{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000},// 1024x +{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000},// 2048x }; diff --git a/esphome/components/as7343/sensor.py b/esphome/components/as7343/sensor.py index 2547ce6427..780699f241 100644 --- a/esphome/components/as7343/sensor.py +++ b/esphome/components/as7343/sensor.py @@ -39,11 +39,14 @@ CONF_F8 = "f8" CONF_NIR = "nir" CONF_CLEAR = "clear" CONF_IRRADIANCE = "irradiance" -CONF_DIGITAL_SATURATION = "digital_saturation" -CONF_ANALOG_SATURATION = "analog_saturation" +CONF_PPFD = "ppfd" +CONF_SATURATION = "saturation" UNIT_COUNTS = "#" UNIT_IRRADIANCE = "W/m²" +UNIT_PPFD = "µmol/sm²" + +ICON_SATURATION = "mdi:weather-sunny-alert" AS7343_GAIN = as7343_ns.enum("AS7343Gain") GAIN_OPTIONS = { @@ -67,7 +70,7 @@ SENSOR_SCHEMA = cv.maybe_simple_value( sensor.sensor_schema( unit_of_measurement=UNIT_COUNTS, icon=ICON_BRIGHTNESS_5, - accuracy_decimals=4, + accuracy_decimals=0, device_class=DEVICE_CLASS_ILLUMINANCE, state_class=STATE_CLASS_MEASUREMENT, ), @@ -115,6 +118,26 @@ CONFIG_SCHEMA = ( ), key=CONF_NAME, ), + cv.Optional(CONF_PPFD): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_PPFD, + icon=ICON_BRIGHTNESS_5, + accuracy_decimals=0, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_SATURATION): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS, + icon=ICON_SATURATION, + accuracy_decimals=0, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), } ) .extend(cv.polling_component_schema("60s")) @@ -137,6 +160,8 @@ SENSORS = { CONF_CLEAR: "set_clear_sensor", CONF_ILLUMINANCE: "set_illuminance_sensor", CONF_IRRADIANCE: "set_irradiance_sensor", + CONF_PPFD: "set_ppfd_sensor", + CONF_SATURATION: "set_saturation_sensor", }