mirror of
https://github.com/esphome/esphome.git
synced 2025-03-20 09:38:18 +00:00
* LTR303 and LTR329 light sensors * LTR303 tidy up * LTR303 unused var * LTR303 tidy up + test * LTR303 auto sensitivity mode * LTR303 auto sensitivity mode tidy * LTR303 State machine version * LTR303 name fix * publish split * minor * new definitions for LTR * als-ps test * als-ps test * als-ps test * ps options * ps options * trgger bug fixed * trgger bug fixed * Minor comments * ltr303->ltr_als_ps * codeowners, tests * tidy up * tidy up * tidy up * gain enum name fix * auto gain fix * tweaks * new style tests * als/ps separate init * logd->logv * reconfiguration count changed * old-style tests removed * const py * ambient light const in vmel7700 and ltr390 * Update esphome/components/ltr_als_ps/ltr_als_ps.cpp Co-authored-by: Keith Burzinski <kbx81x@gmail.com> * Apply suggestions from code review Co-authored-by: Keith Burzinski <kbx81x@gmail.com> * remove commented code --------- Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
272 lines
9.8 KiB
Python
272 lines
9.8 KiB
Python
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_AMBIENT_LIGHT,
|
|
CONF_AUTO_MODE,
|
|
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_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"
|
|
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 = "#"
|
|
|
|
ltr_als_ps_ns = cg.esphome_ns.namespace("ltr_als_ps")
|
|
|
|
LTRAlsPsComponent = ltr_als_ps_ns.class_(
|
|
"LTRAlsPsComponent", cg.PollingComponent, i2c.I2CDevice
|
|
)
|
|
|
|
LtrType = ltr_als_ps_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 = ltr_als_ps_ns.enum("AlsGain")
|
|
ALS_GAINS = {
|
|
"1X": AlsGain.GAIN_1,
|
|
"2X": AlsGain.GAIN_2,
|
|
"4X": AlsGain.GAIN_4,
|
|
"8X": AlsGain.GAIN_8,
|
|
"48X": AlsGain.GAIN_48,
|
|
"96X": AlsGain.GAIN_96,
|
|
}
|
|
|
|
IntegrationTime = ltr_als_ps_ns.enum("IntegrationTime")
|
|
INTEGRATION_TIMES = {
|
|
50: IntegrationTime.INTEGRATION_TIME_50MS,
|
|
100: IntegrationTime.INTEGRATION_TIME_100MS,
|
|
150: IntegrationTime.INTEGRATION_TIME_150MS,
|
|
200: IntegrationTime.INTEGRATION_TIME_200MS,
|
|
250: IntegrationTime.INTEGRATION_TIME_250MS,
|
|
300: IntegrationTime.INTEGRATION_TIME_300MS,
|
|
350: IntegrationTime.INTEGRATION_TIME_350MS,
|
|
400: IntegrationTime.INTEGRATION_TIME_400MS,
|
|
}
|
|
|
|
MeasurementRepeatRate = ltr_als_ps_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 = ltr_als_ps_ns.enum("PsGain")
|
|
PS_GAINS = {
|
|
"16X": PsGain.PS_GAIN_16,
|
|
"32X": PsGain.PS_GAIN_32,
|
|
"64X": PsGain.PS_GAIN_64,
|
|
}
|
|
|
|
LTRPsHighTrigger = ltr_als_ps_ns.class_(
|
|
"LTRPsHighTrigger", automation.Trigger.template()
|
|
)
|
|
LTRPsLowTrigger = ltr_als_ps_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
|
|
|
|
|
|
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="16X"): 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(0x29)),
|
|
validate_time_and_repeat_rate,
|
|
)
|
|
|
|
|
|
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]))
|