[as734x] [3/3] Add illuminance, photopic irradiance, PAR, PPFD, colour temperature and RGB (#18012)

Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
Anton Viktorov
2026-10-15 11:38:15 -10:00
committed by GitHub
co-authored by J. Nick Koston
parent 27c6b7caf5
commit c0d8a0dfe9
8 changed files with 399 additions and 6 deletions
+162
View File
@@ -1,10 +1,12 @@
#include "as734x.h"
#include "color_helpers.h"
#include "esphome/core/application.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include "esphome/core/progmem.h"
#include <algorithm>
#include <cstdio>
namespace esphome::as734x {
@@ -78,6 +80,41 @@ static_assert(sizeof(AS7341_WAVELENGTHS) == NUM_BANDS * sizeof(uint16_t));
static const float AS7341_GAIN_CORRECTION[] PROGMEM = {1.0577f, 1.0491f, 1.0479f, 1.0491f, 1.0207f, 1.0158f, 1.0109f,
1.0000f, 1.0003f, 0.9873f, 0.9593f, 0.0f, 0.0f};
static_assert(sizeof(AS7341_GAIN_CORRECTION) == GAIN_COUNT * sizeof(float));
// clang-format off
// The three bands this chip does not have contribute nothing to the weighted sums.
static const ChannelContribution AS7341_CONTRIBUTIONS[] PROGMEM = {
{0.005261294f, 5.936230324f, 0.020518273f}, // F1
{0.242615252f, 3.572528495f, 0.013525490f}, // F2
{0.0f, 0.0f, 0.0f}, // FZ, absent
{0.174482552f, 2.914113437f, 0.011585145f}, // F3
{1.479499075f, 2.452851227f, 0.010604986f}, // F4
{0.0f, 0.0f, 0.0f}, // FY, absent
{1.906818555f, 1.940656433f, 0.008890531f}, // F5
{0.0f, 0.0f, 0.0f}, // FXL, absent
{1.162058142f, 1.533976606f, 0.007441544f}, // F6
{0.462374845f, 1.819838250f, 0.009393590f}, // F7
{-0.017794572f, 1.232942274f, 0.006890812f}, // F8
{-0.260730901f, -1.102368000f, -0.004647911f}, // NIR
{-0.022604075f, -0.033304813f, -0.000129106f}, // Clear
};
static const ChannelTristimulus AS7341_TRISTIMULUS[] PROGMEM = {
{0.39814f, 0.01396f, 1.95010f}, // F1
{1.29540f, 0.16748f, 6.45490f}, // F2
{0.0f, 0.0f, 0.0f}, // FZ, absent
{0.36956f, 0.23538f, 2.78010f}, // F3
{0.10902f, 1.42750f, 0.18501f}, // F4
{0.0f, 0.0f, 0.0f}, // FY, absent
{0.71942f, 1.88670f, 0.15325f}, // F5
{0.0f, 0.0f, 0.0f}, // FXL, absent
{1.78180f, 1.14200f, 0.09539f}, // F6
{1.10110f, 0.46497f, 0.10563f}, // F7
{-0.03991f, -0.02702f, 0.08866f}, // F8
{-0.27597f, -0.24468f, -0.61140f}, // NIR
{-0.02347f, -0.01993f, -0.00938f}, // Clear
};
// clang-format on
static_assert(sizeof(AS7341_CONTRIBUTIONS) == NUM_BANDS * sizeof(ChannelContribution));
static_assert(sizeof(AS7341_TRISTIMULUS) == NUM_BANDS * sizeof(ChannelTristimulus));
const ChipInfo AS7341_CHIP PROGMEM = {
.name = AS7341_NAME,
.init = AS7341_INIT,
@@ -85,6 +122,8 @@ const ChipInfo AS7341_CHIP PROGMEM = {
.readout = AS7341_READOUT,
.wavelengths = AS7341_WAVELENGTHS,
.gain_correction = AS7341_GAIN_CORRECTION,
.contributions = AS7341_CONTRIBUTIONS,
.tristimulus = AS7341_TRISTIMULUS,
.init_count = 1,
.astep_reg = 0xCA,
.cfg0_reg = 0xA9,
@@ -147,6 +186,40 @@ static const float AS7343_GAIN_CORRECTION[] PROGMEM = {
};
// clang-format on
static_assert(sizeof(AS7343_GAIN_CORRECTION) == GAIN_COUNT * NUM_BANDS * sizeof(float));
// clang-format off
static const ChannelContribution AS7343_CONTRIBUTIONS[] PROGMEM = {
{-0.028559089f, 0.450293995f, 0.001266925f}, // F1
{-0.042150948f, 3.566379984f, 0.012515925f}, // F2
{0.000661721f, 2.877424672f, 0.010243005f}, // FZ
{-0.108791278f, 2.273837581f, 0.009376157f}, // F3
{-0.167172180f, 1.519298503f, 0.006017556f}, // F4
{5.726660294f, 4.199345859f, 0.019357905f}, // FY
{0.0f, 0.0f, 0.0f}, // F5
{-0.241492014f, 1.185259160f, 0.006516325f}, // FXL
{-0.047665296f, 1.759469826f, 0.009780714f}, // F6
{-0.012516990f, 1.702006611f, 0.009950228f}, // F7
{-0.026424974f, -1.059196137f, -0.005425656f}, // F8
{-0.007565221f, -0.064827881f, -0.000232267f}, // NIR
{0.0f, 0.0f, 0.0f}, // Clear
};
static const ChannelTristimulus AS7343_TRISTIMULUS[] PROGMEM = {
{-0.07879f, -0.03269f, -0.31295f}, // F1
{-0.12235f, -0.01297f, -0.57885f}, // F2
{1.99879f, -0.04011f, 10.00197f}, // FZ
{-0.33364f, -0.06889f, -0.31281f}, // F3
{-0.06795f, -0.17453f, -0.19657f}, // F4
{-0.45419f, 5.69083f, -0.11077f}, // FY
{0.0f, 0.0f, 0.0f}, // F5
{5.27242f, -0.22956f, -0.06132f}, // FXL
{-0.05072f, -0.04762f, -0.03536f}, // F6
{-0.04666f, -0.01295f, -0.06025f}, // F7
{-0.03931f, -0.02797f, -0.12174f}, // F8
{0.0f, 0.0f, 0.0f}, // NIR
{0.0f, 0.0f, 0.0f}, // Clear
};
// clang-format on
static_assert(sizeof(AS7343_CONTRIBUTIONS) == NUM_BANDS * sizeof(ChannelContribution));
static_assert(sizeof(AS7343_TRISTIMULUS) == NUM_BANDS * sizeof(ChannelTristimulus));
static constexpr ChipInfo as7343_chip(const char *name) {
return {
.name = name,
@@ -155,6 +228,8 @@ static constexpr ChipInfo as7343_chip(const char *name) {
.readout = AS7343_READOUT,
.wavelengths = AS7343_WAVELENGTHS,
.gain_correction = AS7343_GAIN_CORRECTION,
.contributions = AS7343_CONTRIBUTIONS,
.tristimulus = AS7343_TRISTIMULUS,
.init_count = sizeof(AS7343_INIT) / sizeof(RegValue),
.astep_reg = 0xD4,
.cfg0_reg = 0xBF,
@@ -272,6 +347,14 @@ void AS734XComponent::dump_config() {
sensor::log_sensor(TAG, " ", label, this->basic_counts_sensors_[band]);
}
LOG_SENSOR(" ", "Saturation level", this->saturation_level_sensor_);
LOG_SENSOR(" ", "Illuminance", this->illuminance_sensor_);
LOG_SENSOR(" ", "Irradiance photopic", this->irradiance_photopic_sensor_);
LOG_SENSOR(" ", "Irradiance PAR", this->irradiance_par_sensor_);
LOG_SENSOR(" ", "PPFD", this->ppfd_sensor_);
LOG_SENSOR(" ", "Color temperature", this->color_temperature_sensor_);
#ifdef USE_AS734X_RGB
LOG_TEXT_SENSOR(" ", "RGB hex", this->rgb_hex_sensor_);
#endif
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
}
@@ -484,6 +567,83 @@ void AS734XComponent::publish_basic_counts_() {
}
}
// Each band contributes a fixed amount per basic count to every integrated quantity, so the
// totals are a weighted sum over the bands.
// The weighted sums can go negative under light the tables were not fitted for, such as pure blue or
// far red, so the published values are floored at zero.
void AS734XComponent::publish_light_metrics_() {
float irradiance_photopic = 0.0f;
float irradiance_par = 0.0f;
float ppfd = 0.0f;
const ChannelContribution *contributions = pgm(this->chip_->contributions);
for (uint8_t band = 0; band < NUM_BANDS; band++) {
const float basic_count = this->basic_counts_[band];
const ChannelContribution contribution = pgm(contributions[band]);
irradiance_photopic += contribution.irradiance_photopic * basic_count;
irradiance_par += contribution.irradiance_par * basic_count;
ppfd += contribution.ppfd * basic_count;
}
irradiance_photopic = std::max(irradiance_photopic, 0.0f);
irradiance_par = std::max(irradiance_par, 0.0f);
ppfd = std::max(ppfd, 0.0f) * 1e3f;
const float illuminance = irradiance_photopic * LUMENS_PER_WATT;
ESP_LOGV(TAG, "Photopic irradiance %.4f, PAR %.4f, PPFD %.4f, illuminance %.2f lx", irradiance_photopic,
irradiance_par, ppfd, illuminance);
if (this->illuminance_sensor_ != nullptr) {
this->illuminance_sensor_->publish_state(illuminance);
}
if (this->irradiance_photopic_sensor_ != nullptr) {
this->irradiance_photopic_sensor_->publish_state(irradiance_photopic);
}
if (this->irradiance_par_sensor_ != nullptr) {
this->irradiance_par_sensor_->publish_state(irradiance_par);
}
if (this->ppfd_sensor_ != nullptr) {
this->ppfd_sensor_->publish_state(ppfd);
}
}
void AS734XComponent::publish_color_() {
float tri_x = 0.0f;
float tri_y = 0.0f;
float tri_z = 0.0f;
const ChannelTristimulus *table = pgm(this->chip_->tristimulus);
for (uint8_t band = 0; band < NUM_BANDS; band++) {
const float basic_count = this->basic_counts_[band];
const ChannelTristimulus tristimulus = pgm(table[band]);
tri_x += tristimulus.x * basic_count;
tri_y += tristimulus.y * basic_count;
tri_z += tristimulus.z * basic_count;
}
const float color_temperature = tristimulus_to_cct(tri_x, tri_y, tri_z);
ESP_LOGV(TAG, "XYZ %.4f, %.4f, %.4f -> CCT %.0f K", tri_x, tri_y, tri_z, color_temperature);
if (this->color_temperature_sensor_ != nullptr) {
this->color_temperature_sensor_->publish_state(color_temperature);
}
#ifdef USE_AS734X_RGB
if (this->rgb_hex_sensor_ == nullptr) {
return;
}
// Convert to chromaticity first, so the colour describes the hue rather than the brightness.
// Absolute tristimulus values clamp to white under anything but dim light.
char rgb_hex[7] = "000000"; // no usable chromaticity reads as black rather than an empty string
const float sum = tri_x + tri_y + tri_z;
if (sum > MIN_TRISTIMULUS_SUM) {
uint8_t rgb[3];
tristimulus_to_rgb(tri_x / sum, tri_y / sum, tri_z / sum, rgb[0], rgb[1], rgb[2]);
format_hex_to(rgb_hex, rgb, sizeof(rgb));
}
this->rgb_hex_sensor_->publish_state(rgb_hex);
#endif
}
void AS734XComponent::publish_measurement_() {
this->calculate_basic_counts_();
for (uint8_t band = 0; band < NUM_BANDS; band++) {
@@ -492,6 +652,8 @@ void AS734XComponent::publish_measurement_() {
}
}
this->publish_basic_counts_();
this->publish_light_metrics_();
this->publish_color_();
if (this->saturation_level_sensor_ != nullptr) {
const uint32_t max_adc =
std::min<uint32_t>((this->reading_atime_ + 1UL) * (this->reading_astep_ + 1UL), MAX_ADC_COUNT);
+42 -5
View File
@@ -7,6 +7,9 @@
#include "esphome/core/hal.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h"
#ifdef USE_AS734X_RGB
#include "esphome/components/text_sensor/text_sensor.h"
#endif
namespace esphome::as734x {
@@ -47,6 +50,24 @@ static constexpr uint16_t VISIBLE_MAX_NM = 700;
static constexpr uint16_t WIDEBAND_NM = 0;
static constexpr uint16_t ABSENT_NM = 0xFFFF; // band this chip does not have
// Luminous efficacy at 555 nm, for turning photopic irradiance into lux.
static constexpr float LUMENS_PER_WATT = 683.002f;
// How much one basic count of a band contributes to each integrated quantity. The factors come
// from the manufacturer's golden-device calibration, convolved for a reconstructed spectrum.
struct ChannelContribution {
float irradiance_photopic; // weighted by the CIE 1931 V(lambda) curve
float irradiance_par; // 400-700 nm only
float ppfd; // 400-700 nm only, scaled by 1e3 before publishing
};
// CIE 1931 tristimulus contribution of one basic count of a band.
struct ChannelTristimulus {
float x;
float y;
float z;
};
struct RegValue {
uint8_t reg;
uint8_t value;
@@ -55,11 +76,13 @@ struct RegValue {
/// Per-chip constants, stored in flash. The pointed-to tables are in flash too.
struct ChipInfo {
const char *name;
const RegValue *init; // written in order; the bank is selected per register address
const uint8_t *smux; // AS7341: SMUX RAM image per step; AS7343: the three chain images
const uint8_t *readout; // per step, the ADC slot of each band (0xFF: not read in this step)
const uint16_t *wavelengths; // per band, WIDEBAND_NM for clear and ABSENT_NM for a missing band
const float *gain_correction; // GAIN_COUNT entries, or GAIN_COUNT * NUM_BANDS when per band
const RegValue *init; // written in order; the bank is selected per register address
const uint8_t *smux; // AS7341: SMUX RAM image per step; AS7343: the three chain images
const uint8_t *readout; // per step, the ADC slot of each band (0xFF: not read in this step)
const uint16_t *wavelengths; // per band, WIDEBAND_NM for clear and ABSENT_NM for a missing band
const float *gain_correction; // GAIN_COUNT entries, or GAIN_COUNT * NUM_BANDS when per band
const ChannelContribution *contributions; // per band
const ChannelTristimulus *tristimulus; // per band
uint8_t init_count;
uint8_t astep_reg;
uint8_t cfg0_reg;
@@ -117,6 +140,15 @@ class AS734XComponent : public PollingComponent, public i2c::I2CDevice {
void set_basic_counts_sensor(sensor::Sensor *sensor, uint8_t band) { this->basic_counts_sensors_[band] = sensor; }
SUB_SENSOR(saturation_level)
SUB_SENSOR(illuminance)
SUB_SENSOR(irradiance_photopic)
SUB_SENSOR(irradiance_par)
SUB_SENSOR(ppfd)
SUB_SENSOR(color_temperature)
#ifdef USE_AS734X_RGB
void set_rgb_hex_sensor(text_sensor::TextSensor *sensor) { this->rgb_hex_sensor_ = sensor; }
#endif
protected:
bool select_bank_(uint8_t reg);
@@ -126,6 +158,8 @@ class AS734XComponent : public PollingComponent, public i2c::I2CDevice {
void read_step_();
void abort_measurement_(const LogString *reason);
void calculate_basic_counts_();
void publish_light_metrics_();
void publish_color_();
void publish_measurement_();
void publish_basic_counts_();
float normalization_divisor_() const;
@@ -157,6 +191,9 @@ class AS734XComponent : public PollingComponent, public i2c::I2CDevice {
uint8_t atime_{0};
uint8_t step_{0};
bool bank_low_{true}; // unknown until setup() writes CFG0
#ifdef USE_AS734X_RGB
text_sensor::TextSensor *rgb_hex_sensor_{nullptr};
#endif
};
} // namespace esphome::as734x
@@ -0,0 +1,63 @@
#include "color_helpers.h"
#include <algorithm>
#include <cmath>
namespace esphome::as734x {
namespace {
// Range McCamy's approximation is meaningful over.
constexpr float CCT_MIN_K = 1000.0f;
constexpr float CCT_MAX_K = 25000.0f;
#ifdef USE_AS734X_RGB
// sRGB transfer function.
float gamma_correct(float channel) {
if (channel <= 0.0031308f) {
return 12.92f * channel;
}
return 1.055f * std::pow(channel, 1.0f / 2.4f) - 0.055f;
}
uint8_t to_byte(float channel) { return static_cast<uint8_t>(std::clamp(channel, 0.0f, 1.0f) * 255.0f); }
#endif
} // namespace
float tristimulus_to_cct(float x, float y, float z) {
const float sum = x + y + z;
// The conversion matrices carry negative coefficients, so a spectrum unlike the one they were
// calibrated against can drive the sum to zero or below. Chromaticity is undefined there, and
// McCamy's formula would still return a plausible looking number from it.
if (sum <= MIN_TRISTIMULUS_SUM) {
return NAN;
}
const float chroma_x = x / sum;
const float chroma_y = y / sum;
// McCamy's approximation: cct = 437 n^3 + 3601 n^2 + 6861 n + 5517. The pole at
// chroma_y = 0.1858 sends the cubic off to either infinity, and it stays meaningless well
// either side of that, so the answer is only reported where the approximation holds.
const float denominator = 0.1858f - chroma_y;
if (std::abs(denominator) < 1e-4f) {
return NAN;
}
const float n = (chroma_x - 0.3320f) / denominator;
const float cct = ((437.0f * n + 3601.0f) * n + 6861.0f) * n + 5517.0f;
return (cct >= CCT_MIN_K && cct <= CCT_MAX_K) ? cct : NAN;
}
#ifdef USE_AS734X_RGB
void tristimulus_to_rgb(float x, float y, float z, uint8_t &r, uint8_t &g, uint8_t &b) {
const float r_linear = 3.2406f * x - 1.5372f * y - 0.4986f * z;
const float g_linear = -0.9689f * x + 1.8758f * y + 0.0415f * z;
const float b_linear = 0.0557f * x - 0.2040f * y + 1.0570f * z;
r = to_byte(gamma_correct(r_linear));
g = to_byte(gamma_correct(g_linear));
b = to_byte(gamma_correct(b_linear));
}
#endif
} // namespace esphome::as734x
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <cstdint>
#include "esphome/core/defines.h"
namespace esphome::as734x {
// Smallest tristimulus sum that still carries a usable hue.
constexpr float MIN_TRISTIMULUS_SUM = 0.001f;
// Correlated colour temperature in kelvin from CIE 1931 tristimulus values, using McCamy's
// approximation. Returns NAN when the input carries no usable hue, or when the result falls
// outside the range the approximation holds over.
float tristimulus_to_cct(float x, float y, float z);
#ifdef USE_AS734X_RGB
// sRGB components for CIE 1931 tristimulus values. Pass chromaticity (x + y + z == 1) rather than
// absolute values, otherwise anything but dim light clamps to white.
void tristimulus_to_rgb(float x, float y, float z, uint8_t &r, uint8_t &g, uint8_t &b);
#endif
} // namespace esphome::as734x
+61 -1
View File
@@ -2,7 +2,18 @@ import esphome.codegen as cg
from esphome.components import sensor
from esphome.components.const import UNIT_COUNTS
import esphome.config_validation as cv
from esphome.const import CONF_COUNTS, CONF_TYPE, STATE_CLASS_MEASUREMENT, UNIT_PERCENT
from esphome.const import (
CONF_COLOR_TEMPERATURE,
CONF_COUNTS,
CONF_ILLUMINANCE,
CONF_TYPE,
DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_IRRADIANCE,
STATE_CLASS_MEASUREMENT,
UNIT_KELVIN,
UNIT_LUX,
UNIT_PERCENT,
)
import esphome.final_validate as fv
from esphome.types import ConfigType
@@ -11,10 +22,21 @@ from . import BANDS_41, BANDS_43, CONF_AS734X_ID, DOMAIN, AS734XComponent
DEPENDENCIES = [DOMAIN]
CONF_BASIC_COUNTS = "basic_counts"
CONF_IRRADIANCE_PAR = "irradiance_par"
CONF_IRRADIANCE_PHOTOPIC = "irradiance_photopic"
CONF_PPFD = "ppfd"
CONF_SATURATION_LEVEL = "saturation_level"
UNIT_IRRADIANCE = "W/m\u00b2"
UNIT_PPFD = "\u00b5mol/m\u00b2/s"
ICON_COUNTS = "mdi:counter"
ICON_SATURATION = "mdi:weather-sunny-alert"
ICON_ILLUMINANCE = "mdi:weather-sunny"
ICON_IRRADIANCE_PHOTOPIC = "mdi:sun-wireless-outline"
ICON_PAR = "mdi:sprout"
ICON_PPFD = "mdi:sprout-outline"
ICON_COLOR_TEMPERATURE = "mdi:sun-thermometer-outline"
_COUNTS_SENSOR = sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
@@ -48,6 +70,39 @@ CONFIG_SCHEMA = cv.Schema(
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_ILLUMINANCE): sensor.sensor_schema(
unit_of_measurement=UNIT_LUX,
icon=ICON_ILLUMINANCE,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_IRRADIANCE_PHOTOPIC): sensor.sensor_schema(
unit_of_measurement=UNIT_IRRADIANCE,
icon=ICON_IRRADIANCE_PHOTOPIC,
accuracy_decimals=3,
device_class=DEVICE_CLASS_IRRADIANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_IRRADIANCE_PAR): sensor.sensor_schema(
unit_of_measurement=UNIT_IRRADIANCE,
icon=ICON_PAR,
accuracy_decimals=3,
device_class=DEVICE_CLASS_IRRADIANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_PPFD): sensor.sensor_schema(
unit_of_measurement=UNIT_PPFD,
icon=ICON_PPFD,
accuracy_decimals=3,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_COLOR_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_KELVIN,
icon=ICON_COLOR_TEMPERATURE,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
}
)
@@ -82,3 +137,8 @@ async def to_code(config: ConfigType) -> None:
sensors = sensor.sub_sensors(config)
await sensors(CONF_SATURATION_LEVEL, hub.set_saturation_level_sensor)
await sensors(CONF_ILLUMINANCE, hub.set_illuminance_sensor)
await sensors(CONF_IRRADIANCE_PHOTOPIC, hub.set_irradiance_photopic_sensor)
await sensors(CONF_IRRADIANCE_PAR, hub.set_irradiance_par_sensor)
await sensors(CONF_PPFD, hub.set_ppfd_sensor)
await sensors(CONF_COLOR_TEMPERATURE, hub.set_color_temperature_sensor)
+28
View File
@@ -0,0 +1,28 @@
import esphome.codegen as cg
from esphome.components import text_sensor
import esphome.config_validation as cv
from esphome.types import ConfigType
from . import CONF_AS734X_ID, DOMAIN, AS734XComponent
DEPENDENCIES = [DOMAIN]
CONF_RGB_HEX = "rgb_hex"
ICON_PALETTE = "mdi:palette"
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_AS734X_ID): cv.use_id(AS734XComponent),
cv.Optional(CONF_RGB_HEX): text_sensor.text_sensor_schema(icon=ICON_PALETTE),
}
)
async def to_code(config: ConfigType) -> None:
if (conf := config.get(CONF_RGB_HEX)) is None:
return
hub = await cg.get_variable(config[CONF_AS734X_ID])
cg.add_define("USE_AS734X_RGB")
sens = await text_sensor.new_text_sensor(conf)
cg.add(hub.set_rgb_hex_sensor(sens))
+1
View File
@@ -45,6 +45,7 @@
#define USE_AREAS
#define USE_AS7341
#define USE_AS7343
#define USE_AS734X_RGB
#define USE_BINARY_SENSOR
#define USE_BINARY_SENSOR_CLICK_TRIGGER
#define USE_BINARY_SENSOR_FILTER
+20
View File
@@ -42,6 +42,16 @@ sensor:
name: AS7341 Clear basic
saturation_level:
name: AS7341 Saturation
illuminance:
name: AS7341 Illuminance
irradiance_photopic:
name: AS7341 Photopic irradiance
irradiance_par:
name: AS7341 PAR
ppfd:
name: AS7341 PPFD
color_temperature:
name: AS7341 Colour temperature
- platform: as734x
as734x_id: as7343_hub
counts:
@@ -58,6 +68,10 @@ sensor:
name: AS7343 FY basic
saturation_level:
name: AS7343 Saturation
illuminance:
name: AS7343 Illuminance
color_temperature:
name: AS7343 Colour temperature
- platform: as734x
as734x_id: tcs3448_hub
counts:
@@ -65,3 +79,9 @@ sensor:
name: TCS3448 F1
fy:
name: TCS3448 FY
text_sensor:
- platform: as734x
as734x_id: as7343_hub
rgb_hex:
name: AS7343 RGB