LTR-501, LTR-301, LTR-558 Series of Lite-On Light (ALS) and Proximity(PS) sensors (#6262)

Co-authored-by: root <root@LAOX1>
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
This commit is contained in:
Anton Viktorov
2024-09-09 19:25:37 +02:00
committed by GitHub
parent 7a93dde5d4
commit c90dcfc0ca
16 changed files with 1313 additions and 4 deletions
+1
View File
@@ -227,6 +227,7 @@ esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
esphome/components/lock/* @esphome/core
esphome/components/logger/* @esphome/core
esphome/components/ltr390/* @latonita @sjtrny
esphome/components/ltr501/* @latonita
esphome/components/ltr_als_ps/* @latonita
esphome/components/lvgl/* @clydebarrow
esphome/components/m5stack_8angle/* @rnauber
+1
View File
@@ -0,0 +1 @@
CODEOWNERS = ["@latonita"]
File diff suppressed because it is too large Load Diff
+184
View File
@@ -0,0 +1,184 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
#include "esphome/core/optional.h"
#include "esphome/core/automation.h"
#include "ltr_definitions_501.h"
namespace esphome {
namespace ltr501 {
enum DataAvail : uint8_t { NO_DATA, BAD_DATA, DATA_OK };
enum LtrType : uint8_t {
LTR_TYPE_UNKNOWN = 0,
LTR_TYPE_ALS_ONLY = 1,
LTR_TYPE_PS_ONLY = 2,
LTR_TYPE_ALS_AND_PS = 3,
};
class LTRAlsPs501Component : public PollingComponent, public i2c::I2CDevice {
public:
//
// EspHome framework functions
//
float get_setup_priority() const override { return setup_priority::DATA; }
void setup() override;
void dump_config() override;
void update() override;
void loop() override;
// Configuration setters : General
//
void set_ltr_type(LtrType type) { this->ltr_type_ = type; }
// Configuration setters : ALS
//
void set_als_auto_mode(bool enable) { this->automatic_mode_enabled_ = enable; }
void set_als_gain(AlsGain501 gain) { this->gain_ = gain; }
void set_als_integration_time(IntegrationTime501 time) { this->integration_time_ = time; }
void set_als_meas_repeat_rate(MeasurementRepeatRate rate) { this->repeat_rate_ = rate; }
void set_als_glass_attenuation_factor(float factor) { this->glass_attenuation_factor_ = factor; }
// Configuration setters : PS
//
void set_ps_high_threshold(uint16_t threshold) { this->ps_threshold_high_ = threshold; }
void set_ps_low_threshold(uint16_t threshold) { this->ps_threshold_low_ = threshold; }
void set_ps_cooldown_time_s(uint16_t time) { this->ps_cooldown_time_s_ = time; }
void set_ps_gain(PsGain501 gain) { this->ps_gain_ = gain; }
// Sensors setters
//
void set_ambient_light_sensor(sensor::Sensor *sensor) { this->ambient_light_sensor_ = sensor; }
void set_full_spectrum_counts_sensor(sensor::Sensor *sensor) { this->full_spectrum_counts_sensor_ = sensor; }
void set_infrared_counts_sensor(sensor::Sensor *sensor) { this->infrared_counts_sensor_ = sensor; }
void set_actual_gain_sensor(sensor::Sensor *sensor) { this->actual_gain_sensor_ = sensor; }
void set_actual_integration_time_sensor(sensor::Sensor *sensor) { this->actual_integration_time_sensor_ = sensor; }
void set_proximity_counts_sensor(sensor::Sensor *sensor) { this->proximity_counts_sensor_ = sensor; }
protected:
//
// Internal state machine, used to split all the actions into
// small steps in loop() to make sure we are not blocking execution
//
enum class State : uint8_t {
NOT_INITIALIZED,
DELAYED_SETUP,
IDLE,
WAITING_FOR_DATA,
COLLECTING_DATA_AUTO,
DATA_COLLECTED,
ADJUSTMENT_IN_PROGRESS,
READY_TO_PUBLISH,
KEEP_PUBLISHING
} state_{State::NOT_INITIALIZED};
LtrType ltr_type_{LtrType::LTR_TYPE_ALS_ONLY};
//
// Current measurements data
//
struct AlsReadings {
uint16_t ch0{0};
uint16_t ch1{0};
AlsGain501 gain{AlsGain501::GAIN_1};
IntegrationTime501 integration_time{IntegrationTime501::INTEGRATION_TIME_100MS};
float lux{0.0f};
uint8_t number_of_adjustments{0};
} als_readings_;
uint16_t ps_readings_{0xfffe};
inline bool is_als_() const {
return this->ltr_type_ == LtrType::LTR_TYPE_ALS_ONLY || this->ltr_type_ == LtrType::LTR_TYPE_ALS_AND_PS;
}
inline bool is_ps_() const {
return this->ltr_type_ == LtrType::LTR_TYPE_PS_ONLY || this->ltr_type_ == LtrType::LTR_TYPE_ALS_AND_PS;
}
//
// Device interaction and data manipulation
//
bool check_part_number_();
void configure_reset_();
void configure_als_();
void configure_integration_time_(IntegrationTime501 time);
void configure_gain_(AlsGain501 gain);
DataAvail is_als_data_ready_(AlsReadings &data);
void read_sensor_data_(AlsReadings &data);
bool are_adjustments_required_(AlsReadings &data);
void apply_lux_calculation_(AlsReadings &data);
void publish_data_part_1_(AlsReadings &data);
void publish_data_part_2_(AlsReadings &data);
void configure_ps_();
uint16_t read_ps_data_();
void check_and_trigger_ps_();
//
// Component configuration
//
bool automatic_mode_enabled_{false};
AlsGain501 gain_{AlsGain501::GAIN_1};
IntegrationTime501 integration_time_{IntegrationTime501::INTEGRATION_TIME_100MS};
MeasurementRepeatRate repeat_rate_{MeasurementRepeatRate::REPEAT_RATE_500MS};
float glass_attenuation_factor_{1.0};
uint16_t ps_cooldown_time_s_{5};
PsGain501 ps_gain_{PsGain501::PS_GAIN_1};
uint16_t ps_threshold_high_{0xffff};
uint16_t ps_threshold_low_{0x0000};
//
// Sensors for publishing data
//
sensor::Sensor *infrared_counts_sensor_{nullptr}; // direct reading CH1, infrared only
sensor::Sensor *full_spectrum_counts_sensor_{nullptr}; // direct reading CH0, infrared + visible light
sensor::Sensor *ambient_light_sensor_{nullptr}; // calculated lux
sensor::Sensor *actual_gain_sensor_{nullptr}; // actual gain of reading
sensor::Sensor *actual_integration_time_sensor_{nullptr}; // actual integration time
sensor::Sensor *proximity_counts_sensor_{nullptr}; // proximity sensor
bool is_any_als_sensor_enabled_() const {
return this->ambient_light_sensor_ != nullptr || this->full_spectrum_counts_sensor_ != nullptr ||
this->infrared_counts_sensor_ != nullptr || this->actual_gain_sensor_ != nullptr ||
this->actual_integration_time_sensor_ != nullptr;
}
bool is_any_ps_sensor_enabled_() const { return this->proximity_counts_sensor_ != nullptr; }
//
// Trigger section for the automations
//
friend class LTRPsHighTrigger;
friend class LTRPsLowTrigger;
CallbackManager<void()> on_ps_high_trigger_callback_;
CallbackManager<void()> on_ps_low_trigger_callback_;
void add_on_ps_high_trigger_callback_(std::function<void()> callback) {
this->on_ps_high_trigger_callback_.add(std::move(callback));
}
void add_on_ps_low_trigger_callback_(std::function<void()> callback) {
this->on_ps_low_trigger_callback_.add(std::move(callback));
}
};
class LTRPsHighTrigger : public Trigger<> {
public:
explicit LTRPsHighTrigger(LTRAlsPs501Component *parent) {
parent->add_on_ps_high_trigger_callback_([this]() { this->trigger(); });
}
};
class LTRPsLowTrigger : public Trigger<> {
public:
explicit LTRPsLowTrigger(LTRAlsPs501Component *parent) {
parent->add_on_ps_low_trigger_callback_([this]() { this->trigger(); });
}
};
} // namespace ltr501
} // namespace esphome
@@ -0,0 +1,260 @@
#pragma once
#include <cstdint>
namespace esphome {
namespace ltr501 {
enum class CommandRegisters : uint8_t {
ALS_CONTR = 0x80, // ALS operation mode control and SW reset
PS_CONTR = 0x81, // PS operation mode control
PS_LED = 0x82, // PS LED pulse frequency control
PS_N_PULSES = 0x83, // PS number of pulses control
PS_MEAS_RATE = 0x84, // PS measurement rate in active mode
MEAS_RATE = 0x85, // ALS measurement rate in active mode
PART_ID = 0x86, // Part Number ID and Revision ID
MANUFAC_ID = 0x87, // Manufacturer ID
ALS_DATA_CH1_0 = 0x88, // ALS measurement CH1 data, lower byte - infrared only
ALS_DATA_CH1_1 = 0x89, // ALS measurement CH1 data, upper byte - infrared only
ALS_DATA_CH0_0 = 0x8A, // ALS measurement CH0 data, lower byte - visible + infrared
ALS_DATA_CH0_1 = 0x8B, // ALS measurement CH0 data, upper byte - visible + infrared
ALS_PS_STATUS = 0x8C, // ALS PS new data status
PS_DATA_0 = 0x8D, // PS measurement data, lower byte
PS_DATA_1 = 0x8E, // PS measurement data, upper byte
ALS_PS_INTERRUPT = 0x8F, // Interrupt status
PS_THRES_UP_0 = 0x90, // PS interrupt upper threshold, lower byte
PS_THRES_UP_1 = 0x91, // PS interrupt upper threshold, upper byte
PS_THRES_LOW_0 = 0x92, // PS interrupt lower threshold, lower byte
PS_THRES_LOW_1 = 0x93, // PS interrupt lower threshold, upper byte
PS_OFFSET_1 = 0x94, // PS offset, upper byte
PS_OFFSET_0 = 0x95, // PS offset, lower byte
// 0x96 - reserved
ALS_THRES_UP_0 = 0x97, // ALS interrupt upper threshold, lower byte
ALS_THRES_UP_1 = 0x98, // ALS interrupt upper threshold, upper byte
ALS_THRES_LOW_0 = 0x99, // ALS interrupt lower threshold, lower byte
ALS_THRES_LOW_1 = 0x9A, // ALS interrupt lower threshold, upper byte
// 0x9B - reserved
// 0x9C - reserved
// 0x9D - reserved
INTERRUPT_PERSIST = 0x9E // Interrupt persistence filter
};
// ALS Sensor gain levels
enum AlsGain501 : uint8_t {
GAIN_1 = 0, // GAIN_RANGE_2 // default
GAIN_150 = 1, // GAIN_RANGE_1
};
static const uint8_t GAINS_COUNT = 2;
// ALS Sensor integration times
enum IntegrationTime501 : uint8_t {
INTEGRATION_TIME_100MS = 0, // default
INTEGRATION_TIME_50MS = 1, // only in Dynamic GAIN_RANGE_2
INTEGRATION_TIME_200MS = 2, // only in Dynamic GAIN_RANGE_1
INTEGRATION_TIME_400MS = 3, // only in Dynamic GAIN_RANGE_1
};
static const uint8_t TIMES_COUNT = 4;
// ALS Sensor measurement repeat rate
enum MeasurementRepeatRate {
REPEAT_RATE_50MS = 0,
REPEAT_RATE_100MS = 1,
REPEAT_RATE_200MS = 2,
REPEAT_RATE_500MS = 3, // default
REPEAT_RATE_1000MS = 4,
REPEAT_RATE_2000MS = 5
};
// PS Sensor gain levels
enum PsGain501 : uint8_t {
PS_GAIN_1 = 0, // default
PS_GAIN_4 = 1,
PS_GAIN_8 = 2,
PS_GAIN_16 = 3,
};
// LED Pulse Modulation Frequency
enum PsLedFreq : uint8_t {
PS_LED_FREQ_30KHZ = 0,
PS_LED_FREQ_40KHZ = 1,
PS_LED_FREQ_50KHZ = 2,
PS_LED_FREQ_60KHZ = 3, // default
PS_LED_FREQ_70KHZ = 4,
PS_LED_FREQ_80KHZ = 5,
PS_LED_FREQ_90KHZ = 6,
PS_LED_FREQ_100KHZ = 7,
};
// LED current duty
enum PsLedDuty : uint8_t {
PS_LED_DUTY_25 = 0,
PS_LED_DUTY_50 = 1, // default
PS_LED_DUTY_75 = 2,
PS_LED_DUTY_100 = 3,
};
// LED pulsed current level
enum PsLedCurrent : uint8_t {
PS_LED_CURRENT_5MA = 0,
PS_LED_CURRENT_10MA = 1,
PS_LED_CURRENT_20MA = 2,
PS_LED_CURRENT_50MA = 3, // default
PS_LED_CURRENT_100MA = 4,
PS_LED_CURRENT_100MA1 = 5,
PS_LED_CURRENT_100MA2 = 6,
PS_LED_CURRENT_100MA3 = 7,
};
// PS measurement rate
enum PsMeasurementRate : uint8_t {
PS_MEAS_RATE_50MS = 0,
PS_MEAS_RATE_70MS = 1,
PS_MEAS_RATE_100MS = 2, // default
PS_MEAS_RATE_200MS = 3,
PS_MEAS_RATE_500MS = 4,
PS_MEAS_RATE_1000MS = 5,
PS_MEAS_RATE_2000MS = 6,
PS_MEAS_RATE_2000MS1 = 7,
};
//
// ALS_CONTR Register (0x80)
//
union AlsControlRegister501 {
uint8_t raw;
struct {
bool asl_mode_xxx : 1;
bool als_mode_active : 1;
bool sw_reset : 1;
AlsGain501 gain : 1;
uint8_t reserved : 4;
} __attribute__((packed));
};
//
// PS_CONTR Register (0x81)
//
union PsControlRegister501 {
uint8_t raw;
struct {
bool ps_mode_xxx : 1;
bool ps_mode_active : 1;
PsGain501 ps_gain : 2;
bool reserved_4 : 1;
bool reserved_5 : 1;
bool reserved_6 : 1;
bool reserved_7 : 1;
} __attribute__((packed));
};
//
// PS_LED Register (0x82)
//
union PsLedRegister {
uint8_t raw;
struct {
PsLedCurrent ps_led_current : 3;
PsLedDuty ps_led_duty : 2;
PsLedFreq ps_led_freq : 3;
} __attribute__((packed));
};
//
// PS_N_PULSES Register (0x83)
//
union PsNPulsesRegister501 {
uint8_t raw;
uint8_t number_of_pulses;
};
//
// PS_MEAS_RATE Register (0x84)
//
union PsMeasurementRateRegister {
uint8_t raw;
struct {
PsMeasurementRate ps_measurement_rate : 4;
uint8_t reserved : 4;
} __attribute__((packed));
};
//
// ALS_MEAS_RATE Register (0x85)
//
union MeasurementRateRegister501 {
uint8_t raw;
struct {
MeasurementRepeatRate measurement_repeat_rate : 3;
IntegrationTime501 integration_time : 2;
bool reserved_5 : 1;
bool reserved_6 : 1;
bool reserved_7 : 1;
} __attribute__((packed));
};
//
// PART_ID Register (0x86) (Read Only)
//
union PartIdRegister {
uint8_t raw;
struct {
uint8_t part_number_id : 4;
uint8_t revision_id : 4;
} __attribute__((packed));
};
//
// ALS_PS_STATUS Register (0x8C) (Read Only)
//
union AlsPsStatusRegister {
uint8_t raw;
struct {
bool ps_new_data : 1; // 0 - old data, 1 - new data
bool ps_interrupt : 1; // 0 - interrupt signal not active, 1 - interrupt signal active
bool als_new_data : 1; // 0 - old data, 1 - new data
bool als_interrupt : 1; // 0 - interrupt signal not active, 1 - interrupt signal active
AlsGain501 gain : 1; // current ALS gain
bool reserved_5 : 1;
bool reserved_6 : 1;
bool reserved_7 : 1;
} __attribute__((packed));
};
//
// PS_DATA_1 Register (0x8E) (Read Only)
//
union PsData1Register {
uint8_t raw;
struct {
uint8_t ps_data_high : 3;
uint8_t reserved : 4;
bool ps_saturation_flag : 1;
} __attribute__((packed));
};
//
// INTERRUPT Register (0x8F) (Read Only)
//
union InterruptRegister {
uint8_t raw;
struct {
bool ps_interrupt : 1;
bool als_interrupt : 1;
bool interrupt_polarity : 1; // 0 - active low (default), 1 - active high
uint8_t reserved : 5;
} __attribute__((packed));
};
//
// INTERRUPT_PERSIST Register (0x9E)
//
union InterruptPersistRegister {
uint8_t raw;
struct {
uint8_t als_persist : 4; // 0 - every ALS cycle, 1 - every 2 ALS cycles, ... 15 - every 16 ALS cycles
uint8_t ps_persist : 4; // 0 - every PS cycle, 1 - every 2 PS cycles, ... 15 - every 16 PS cycles
} __attribute__((packed));
};
} // namespace ltr501
} // namespace esphome
+274
View File
@@ -0,0 +1,274 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.components import i2c, sensor
from esphome.const import (
CONF_ACTUAL_GAIN,
CONF_ACTUAL_INTEGRATION_TIME,
CONF_AMBIENT_LIGHT,
CONF_AUTO_MODE,
CONF_FULL_SPECTRUM_COUNTS,
CONF_GAIN,
CONF_GLASS_ATTENUATION_FACTOR,
CONF_ID,
CONF_INTEGRATION_TIME,
CONF_NAME,
CONF_REPEAT,
CONF_TRIGGER_ID,
CONF_TYPE,
DEVICE_CLASS_DISTANCE,
DEVICE_CLASS_ILLUMINANCE,
ICON_BRIGHTNESS_5,
ICON_BRIGHTNESS_6,
ICON_TIMER,
STATE_CLASS_MEASUREMENT,
UNIT_LUX,
UNIT_MILLISECOND,
)
CODEOWNERS = ["@latonita"]
DEPENDENCIES = ["i2c"]
CONF_INFRARED_COUNTS = "infrared_counts"
CONF_ON_PS_HIGH_THRESHOLD = "on_ps_high_threshold"
CONF_ON_PS_LOW_THRESHOLD = "on_ps_low_threshold"
CONF_PS_COOLDOWN = "ps_cooldown"
CONF_PS_COUNTS = "ps_counts"
CONF_PS_GAIN = "ps_gain"
CONF_PS_HIGH_THRESHOLD = "ps_high_threshold"
CONF_PS_LOW_THRESHOLD = "ps_low_threshold"
ICON_BRIGHTNESS_7 = "mdi:brightness-7"
ICON_GAIN = "mdi:multiplication"
ICON_PROXIMITY = "mdi:hand-wave-outline"
UNIT_COUNTS = "#"
ltr501_ns = cg.esphome_ns.namespace("ltr501")
LTRAlsPsComponent = ltr501_ns.class_(
"LTRAlsPs501Component", cg.PollingComponent, i2c.I2CDevice
)
LtrType = ltr501_ns.enum("LtrType")
LTR_TYPES = {
"ALS": LtrType.LTR_TYPE_ALS_ONLY,
"PS": LtrType.LTR_TYPE_PS_ONLY,
"ALS_PS": LtrType.LTR_TYPE_ALS_AND_PS,
}
AlsGain = ltr501_ns.enum("AlsGain501")
ALS_GAINS = {
"1X": AlsGain.GAIN_1,
"150X": AlsGain.GAIN_150,
}
IntegrationTime = ltr501_ns.enum("IntegrationTime501")
INTEGRATION_TIMES = {
50: IntegrationTime.INTEGRATION_TIME_50MS,
100: IntegrationTime.INTEGRATION_TIME_100MS,
200: IntegrationTime.INTEGRATION_TIME_200MS,
400: IntegrationTime.INTEGRATION_TIME_400MS,
}
MeasurementRepeatRate = ltr501_ns.enum("MeasurementRepeatRate")
MEASUREMENT_REPEAT_RATES = {
50: MeasurementRepeatRate.REPEAT_RATE_50MS,
100: MeasurementRepeatRate.REPEAT_RATE_100MS,
200: MeasurementRepeatRate.REPEAT_RATE_200MS,
500: MeasurementRepeatRate.REPEAT_RATE_500MS,
1000: MeasurementRepeatRate.REPEAT_RATE_1000MS,
2000: MeasurementRepeatRate.REPEAT_RATE_2000MS,
}
PsGain = ltr501_ns.enum("PsGain501")
PS_GAINS = {
"1X": PsGain.PS_GAIN_1,
"4X": PsGain.PS_GAIN_4,
"8X": PsGain.PS_GAIN_8,
"16X": PsGain.PS_GAIN_16,
}
LTRPsHighTrigger = ltr501_ns.class_("LTRPsHighTrigger", automation.Trigger.template())
LTRPsLowTrigger = ltr501_ns.class_("LTRPsLowTrigger", automation.Trigger.template())
def validate_integration_time(value):
value = cv.positive_time_period_milliseconds(value).total_milliseconds
return cv.enum(INTEGRATION_TIMES, int=True)(value)
def validate_repeat_rate(value):
value = cv.positive_time_period_milliseconds(value).total_milliseconds
return cv.enum(MEASUREMENT_REPEAT_RATES, int=True)(value)
def validate_time_and_repeat_rate(config):
integraton_time = config[CONF_INTEGRATION_TIME]
repeat_rate = config[CONF_REPEAT]
if integraton_time > repeat_rate:
raise cv.Invalid(
f"Measurement repeat rate ({repeat_rate}ms) shall be greater or equal to integration time ({integraton_time}ms)"
)
return config
def validate_als_gain_and_integration_time(config):
integraton_time = config[CONF_INTEGRATION_TIME]
if config[CONF_GAIN] == "1X" and integraton_time > 100:
raise cv.Invalid(
"ALS gain 1X can only be used with integration time 50ms or 100ms"
)
if config[CONF_GAIN] == "200X" and integraton_time == 50:
raise cv.Invalid("ALS gain 200X can not be used with integration time 50ms")
return config
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(LTRAlsPsComponent),
cv.Optional(CONF_TYPE, default="ALS_PS"): cv.enum(LTR_TYPES, upper=True),
cv.Optional(CONF_AUTO_MODE, default=True): cv.boolean,
cv.Optional(CONF_GAIN, default="1X"): cv.enum(ALS_GAINS, upper=True),
cv.Optional(
CONF_INTEGRATION_TIME, default="100ms"
): validate_integration_time,
cv.Optional(CONF_REPEAT, default="500ms"): validate_repeat_rate,
cv.Optional(CONF_GLASS_ATTENUATION_FACTOR, default=1.0): cv.float_range(
min=1.0
),
cv.Optional(
CONF_PS_COOLDOWN, default="5s"
): cv.positive_time_period_seconds,
cv.Optional(CONF_PS_GAIN, default="1X"): cv.enum(PS_GAINS, upper=True),
cv.Optional(CONF_PS_HIGH_THRESHOLD, default=65535): cv.int_range(
min=0, max=65535
),
cv.Optional(CONF_PS_LOW_THRESHOLD, default=0): cv.int_range(
min=0, max=65535
),
cv.Optional(CONF_ON_PS_HIGH_THRESHOLD): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LTRPsHighTrigger),
}
),
cv.Optional(CONF_ON_PS_LOW_THRESHOLD): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LTRPsLowTrigger),
}
),
cv.Optional(CONF_AMBIENT_LIGHT): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_LUX,
icon=ICON_BRIGHTNESS_6,
accuracy_decimals=1,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_INFRARED_COUNTS): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
icon=ICON_BRIGHTNESS_5,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_FULL_SPECTRUM_COUNTS): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
icon=ICON_BRIGHTNESS_7,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_PS_COUNTS): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
icon=ICON_PROXIMITY,
accuracy_decimals=0,
device_class=DEVICE_CLASS_DISTANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_ACTUAL_GAIN): cv.maybe_simple_value(
sensor.sensor_schema(
icon=ICON_GAIN,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_ACTUAL_INTEGRATION_TIME): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_MILLISECOND,
icon=ICON_TIMER,
accuracy_decimals=0,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
}
)
.extend(cv.polling_component_schema("60s"))
.extend(i2c.i2c_device_schema(0x23)),
validate_time_and_repeat_rate,
validate_als_gain_and_integration_time,
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
if als_config := config.get(CONF_AMBIENT_LIGHT):
sens = await sensor.new_sensor(als_config)
cg.add(var.set_ambient_light_sensor(sens))
if infrared_cnt_config := config.get(CONF_INFRARED_COUNTS):
sens = await sensor.new_sensor(infrared_cnt_config)
cg.add(var.set_infrared_counts_sensor(sens))
if full_spect_cnt_config := config.get(CONF_FULL_SPECTRUM_COUNTS):
sens = await sensor.new_sensor(full_spect_cnt_config)
cg.add(var.set_full_spectrum_counts_sensor(sens))
if act_gain_config := config.get(CONF_ACTUAL_GAIN):
sens = await sensor.new_sensor(act_gain_config)
cg.add(var.set_actual_gain_sensor(sens))
if act_itime_config := config.get(CONF_ACTUAL_INTEGRATION_TIME):
sens = await sensor.new_sensor(act_itime_config)
cg.add(var.set_actual_integration_time_sensor(sens))
if prox_cnt_config := config.get(CONF_PS_COUNTS):
sens = await sensor.new_sensor(prox_cnt_config)
cg.add(var.set_proximity_counts_sensor(sens))
for prox_high_tr in config.get(CONF_ON_PS_HIGH_THRESHOLD, []):
trigger = cg.new_Pvariable(prox_high_tr[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], prox_high_tr)
for prox_low_tr in config.get(CONF_ON_PS_LOW_THRESHOLD, []):
trigger = cg.new_Pvariable(prox_low_tr[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [], prox_low_tr)
cg.add(var.set_ltr_type(config[CONF_TYPE]))
cg.add(var.set_als_auto_mode(config[CONF_AUTO_MODE]))
cg.add(var.set_als_gain(config[CONF_GAIN]))
cg.add(var.set_als_integration_time(config[CONF_INTEGRATION_TIME]))
cg.add(var.set_als_meas_repeat_rate(config[CONF_REPEAT]))
cg.add(var.set_als_glass_attenuation_factor(config[CONF_GLASS_ATTENUATION_FACTOR]))
cg.add(var.set_ps_cooldown_time_s(config[CONF_PS_COOLDOWN]))
cg.add(var.set_ps_gain(config[CONF_PS_GAIN]))
cg.add(var.set_ps_high_threshold(config[CONF_PS_HIGH_THRESHOLD]))
cg.add(var.set_ps_low_threshold(config[CONF_PS_LOW_THRESHOLD]))
+2 -2
View File
@@ -4,8 +4,10 @@ from esphome import automation
from esphome.components import i2c, sensor
from esphome.const import (
CONF_ACTUAL_GAIN,
CONF_ACTUAL_INTEGRATION_TIME,
CONF_AMBIENT_LIGHT,
CONF_AUTO_MODE,
CONF_FULL_SPECTRUM_COUNTS,
CONF_GAIN,
CONF_GLASS_ATTENUATION_FACTOR,
CONF_ID,
@@ -27,8 +29,6 @@ from esphome.const import (
CODEOWNERS = ["@latonita"]
DEPENDENCIES = ["i2c"]
CONF_ACTUAL_INTEGRATION_TIME = "actual_integration_time"
CONF_FULL_SPECTRUM_COUNTS = "full_spectrum_counts"
CONF_INFRARED_COUNTS = "infrared_counts"
CONF_ON_PS_HIGH_THRESHOLD = "on_ps_high_threshold"
CONF_ON_PS_LOW_THRESHOLD = "on_ps_low_threshold"
+2 -2
View File
@@ -3,9 +3,11 @@ import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import (
CONF_ACTUAL_GAIN,
CONF_ACTUAL_INTEGRATION_TIME,
CONF_AMBIENT_LIGHT,
CONF_AUTO_MODE,
CONF_FULL_SPECTRUM,
CONF_FULL_SPECTRUM_COUNTS,
CONF_GAIN,
CONF_GLASS_ATTENUATION_FACTOR,
CONF_ID,
@@ -28,9 +30,7 @@ UNIT_COUNTS = "#"
ICON_MULTIPLICATION = "mdi:multiplication"
ICON_BRIGHTNESS_7 = "mdi:brightness-7"
CONF_ACTUAL_INTEGRATION_TIME = "actual_integration_time"
CONF_AMBIENT_LIGHT_COUNTS = "ambient_light_counts"
CONF_FULL_SPECTRUM_COUNTS = "full_spectrum_counts"
CONF_LUX_COMPENSATION = "lux_compensation"
veml7700_ns = cg.esphome_ns.namespace("veml7700")
+2
View File
@@ -44,6 +44,7 @@ CONF_ACTIONS = "actions"
CONF_ACTIVE = "active"
CONF_ACTIVE_POWER = "active_power"
CONF_ACTUAL_GAIN = "actual_gain"
CONF_ACTUAL_INTEGRATION_TIME = "actual_integration_time"
CONF_ADDRESS = "address"
CONF_ADDRESSABLE_LIGHT_ID = "addressable_light_id"
CONF_ADVANCED = "advanced"
@@ -323,6 +324,7 @@ CONF_FREQUENCY = "frequency"
CONF_FRIENDLY_NAME = "friendly_name"
CONF_FROM = "from"
CONF_FULL_SPECTRUM = "full_spectrum"
CONF_FULL_SPECTRUM_COUNTS = "full_spectrum_counts"
CONF_FULL_UPDATE_EVERY = "full_update_every"
CONF_GAIN = "gain"
CONF_GAMMA_CORRECT = "gamma_correct"
+9
View File
@@ -0,0 +1,9 @@
sensor:
- platform: ltr501
address: 0x23
i2c_id: i2c_ltr501
type: ALS_PS
gain: 1X
integration_time: 100ms
ambient_light: "Ambient light"
ps_counts: "Proximity counts"
@@ -0,0 +1,6 @@
i2c:
- id: i2c_ltr501
scl: 16
sda: 17
<<: !include common.yaml
@@ -0,0 +1,6 @@
i2c:
- id: i2c_ltr501
scl: 5
sda: 4
<<: !include common.yaml
@@ -0,0 +1,6 @@
i2c:
- id: i2c_ltr501
scl: 5
sda: 4
<<: !include common.yaml
@@ -0,0 +1,6 @@
i2c:
- id: i2c_ltr501
scl: 16
sda: 17
<<: !include common.yaml
@@ -0,0 +1,6 @@
i2c:
- id: i2c_ltr501
scl: 5
sda: 4
<<: !include common.yaml
@@ -0,0 +1,6 @@
i2c:
- id: i2c_ltr501
scl: 5
sda: 4
<<: !include common.yaml