esphome 2024.8.2__py3-none-any.whl → 2024.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +6 -2
- esphome/components/api/api_connection.cpp +53 -0
- esphome/components/api/api_connection.h +4 -0
- esphome/components/api/api_pb2.cpp +280 -0
- esphome/components/api/api_pb2.h +91 -0
- esphome/components/api/api_pb2_service.cpp +85 -0
- esphome/components/api/api_pb2_service.h +28 -0
- esphome/components/async_tcp/__init__.py +3 -3
- esphome/components/atm90e26/sensor.py +10 -10
- esphome/components/atm90e32/sensor.py +1 -1
- esphome/components/bl0906/__init__.py +1 -0
- esphome/components/bl0906/bl0906.cpp +238 -0
- esphome/components/bl0906/bl0906.h +96 -0
- esphome/components/bl0906/const.py +4 -0
- esphome/components/bl0906/constants.h +122 -0
- esphome/components/bl0906/sensor.py +184 -0
- esphome/components/bl0942/__init__.py +1 -1
- esphome/components/bl0942/bl0942.cpp +127 -34
- esphome/components/bl0942/bl0942.h +87 -3
- esphome/components/bl0942/sensor.py +46 -8
- esphome/components/ble_client/__init__.py +1 -3
- esphome/components/ble_presence/binary_sensor.py +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
- esphome/components/bmp280/sensor.py +2 -93
- esphome/components/bmp280_base/__init__.py +88 -0
- esphome/components/{bmp280/bmp280.cpp → bmp280_base/bmp280_base.cpp} +11 -4
- esphome/components/{bmp280/bmp280.h → bmp280_base/bmp280_base.h} +9 -5
- esphome/components/bmp280_i2c/__init__.py +0 -0
- esphome/components/bmp280_i2c/bmp280_i2c.cpp +27 -0
- esphome/components/bmp280_i2c/bmp280_i2c.h +22 -0
- esphome/components/bmp280_i2c/sensor.py +22 -0
- esphome/components/bmp280_spi/__init__.py +0 -0
- esphome/components/bmp280_spi/bmp280_spi.cpp +65 -0
- esphome/components/bmp280_spi/bmp280_spi.h +20 -0
- esphome/components/bmp280_spi/sensor.py +22 -0
- esphome/components/captive_portal/captive_portal.cpp +2 -0
- esphome/components/captive_portal/captive_portal.h +3 -1
- esphome/components/ch422g/__init__.py +67 -0
- esphome/components/ch422g/ch422g.cpp +122 -0
- esphome/components/ch422g/ch422g.h +70 -0
- esphome/components/debug/debug_esp32.cpp +3 -1
- esphome/components/display/__init__.py +5 -4
- esphome/components/dsmr/dsmr.cpp +6 -0
- esphome/components/dsmr/dsmr.h +6 -0
- esphome/components/dsmr/text_sensor.py +7 -2
- esphome/components/e131/e131.cpp +2 -0
- esphome/components/e131/e131.h +3 -1
- esphome/components/e131/e131_addressable_light_effect.cpp +2 -0
- esphome/components/e131/e131_addressable_light_effect.h +2 -1
- esphome/components/e131/e131_packet.cpp +2 -0
- esphome/components/esp32_ble/ble_uuid.cpp +7 -0
- esphome/components/esp32_ble/ble_uuid.h +1 -0
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -9
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +3 -3
- esphome/components/esp32_camera/__init__.py +4 -0
- esphome/components/esp32_camera/esp32_camera.cpp +9 -1
- esphome/components/esp32_camera/esp32_camera.h +3 -0
- esphome/components/esp32_can/canbus.py +18 -7
- esphome/components/esp32_can/esp32_can.cpp +8 -0
- esphome/components/esp32_can/esp32_can.h +4 -0
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +14 -2
- esphome/components/esp32_rmt_led_strip/led_strip.h +3 -2
- esphome/components/esp32_rmt_led_strip/light.py +21 -4
- esphome/components/esphome/ota/ota_esphome.cpp +2 -1
- esphome/components/esphome/ota/ota_esphome.h +2 -0
- esphome/components/font/__init__.py +11 -22
- esphome/components/font/font.cpp +3 -2
- esphome/components/font/font.h +12 -3
- esphome/components/gree/climate.py +2 -1
- esphome/components/gree/gree.cpp +54 -3
- esphome/components/gree/gree.h +10 -2
- esphome/components/gt911/touchscreen/__init__.py +6 -4
- esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +17 -0
- esphome/components/gt911/touchscreen/gt911_touchscreen.h +2 -0
- esphome/components/hmac_md5/__init__.py +2 -0
- esphome/components/hmac_md5/hmac_md5.cpp +56 -0
- esphome/components/hmac_md5/hmac_md5.h +48 -0
- esphome/components/homeassistant/__init__.py +13 -0
- esphome/components/homeassistant/switch/__init__.py +15 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/i2s_audio/__init__.py +88 -9
- esphome/components/i2s_audio/i2s_audio.h +20 -2
- esphome/components/i2s_audio/media_player/__init__.py +8 -4
- esphome/components/i2s_audio/media_player/i2s_audio_media_player.h +1 -1
- esphome/components/i2s_audio/microphone/__init__.py +19 -51
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +18 -15
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +0 -12
- esphome/components/i2s_audio/speaker/__init__.py +39 -27
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +49 -37
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +3 -4
- esphome/components/ili9xxx/display.py +16 -17
- esphome/components/ili9xxx/ili9xxx_display.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.h +18 -18
- esphome/components/ili9xxx/ili9xxx_init.h +0 -3
- esphome/components/improv_serial/improv_serial_component.cpp +2 -1
- esphome/components/improv_serial/improv_serial_component.h +2 -1
- esphome/components/ledc/ledc_output.cpp +11 -7
- esphome/components/libretiny/__init__.py +8 -13
- esphome/components/ltr501/__init__.py +1 -0
- esphome/components/ltr501/ltr501.cpp +542 -0
- esphome/components/ltr501/ltr501.h +184 -0
- esphome/components/ltr501/ltr_definitions_501.h +260 -0
- esphome/components/ltr501/sensor.py +274 -0
- esphome/components/ltr_als_ps/sensor.py +2 -2
- esphome/components/lvgl/__init__.py +19 -16
- esphome/components/lvgl/automation.py +90 -9
- esphome/components/lvgl/defines.py +29 -2
- esphome/components/lvgl/gradient.py +61 -0
- esphome/components/lvgl/lv_validation.py +45 -27
- esphome/components/lvgl/lvcode.py +8 -3
- esphome/components/lvgl/lvgl_esphome.cpp +54 -0
- esphome/components/lvgl/lvgl_esphome.h +9 -3
- esphome/components/lvgl/number/__init__.py +1 -0
- esphome/components/lvgl/number/lvgl_number.h +3 -1
- esphome/components/lvgl/schemas.py +16 -11
- esphome/components/lvgl/select/__init__.py +1 -0
- esphome/components/lvgl/select/lvgl_select.h +3 -1
- esphome/components/lvgl/switch/__init__.py +2 -1
- esphome/components/lvgl/switch/lvgl_switch.h +3 -1
- esphome/components/lvgl/text/__init__.py +1 -0
- esphome/components/lvgl/text/lvgl_text.h +3 -1
- esphome/components/lvgl/trigger.py +3 -2
- esphome/components/lvgl/types.py +2 -1
- esphome/components/lvgl/widgets/__init__.py +23 -8
- esphome/components/lvgl/widgets/arc.py +5 -1
- esphome/components/lvgl/widgets/buttonmatrix.py +5 -1
- esphome/components/lvgl/widgets/checkbox.py +8 -3
- esphome/components/lvgl/widgets/meter.py +8 -1
- esphome/components/lvgl/widgets/msgbox.py +26 -15
- esphome/components/lvgl/widgets/page.py +51 -7
- esphome/components/lvgl/widgets/tileview.py +2 -8
- esphome/components/max31856/max31856.cpp +12 -1
- esphome/components/max31856/max31856.h +5 -2
- esphome/components/max31856/sensor.py +20 -0
- esphome/components/mcp9600/sensor.py +2 -2
- esphome/components/mdns/__init__.py +6 -6
- esphome/components/media_player/media_player.h +16 -0
- esphome/components/micro_wake_word/__init__.py +2 -25
- esphome/components/microphone/microphone.h +1 -1
- esphome/components/mics_4514/mics_4514.cpp +26 -36
- esphome/components/modbus_controller/__init__.py +6 -0
- esphome/components/modbus_controller/const.py +2 -0
- esphome/components/modbus_controller/modbus_controller.cpp +30 -27
- esphome/components/modbus_controller/modbus_controller.h +22 -4
- esphome/components/network/__init__.py +11 -8
- esphome/components/pipsolar/pipsolar.cpp +3 -0
- esphome/components/pipsolar/pipsolar.h +1 -0
- esphome/components/pipsolar/switch/__init__.py +2 -0
- esphome/components/prometheus/prometheus_handler.cpp +2 -0
- esphome/components/prometheus/prometheus_handler.h +3 -1
- esphome/components/rp2040/__init__.py +7 -8
- esphome/components/rpi_dpi_rgb/display.py +20 -17
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +36 -6
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h +4 -0
- esphome/components/socket/socket.cpp +2 -0
- esphome/components/socket/socket.h +2 -0
- esphome/components/speaker/speaker.h +1 -1
- esphome/components/st7701s/display.py +35 -37
- esphome/components/st7701s/st7701s.cpp +11 -6
- esphome/components/st7701s/st7701s.h +1 -0
- esphome/components/statsd/__init__.py +65 -0
- esphome/components/statsd/statsd.cpp +156 -0
- esphome/components/statsd/statsd.h +86 -0
- esphome/components/tuya/__init__.py +1 -0
- esphome/components/tuya/number/__init__.py +39 -2
- esphome/components/tuya/number/tuya_number.cpp +58 -2
- esphome/components/tuya/number/tuya_number.h +12 -3
- esphome/components/udp/__init__.py +158 -0
- esphome/components/udp/binary_sensor.py +27 -0
- esphome/components/udp/sensor.py +27 -0
- esphome/components/udp/udp_component.cpp +616 -0
- esphome/components/udp/udp_component.h +158 -0
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +4 -6
- esphome/components/uponor_smatrix/uponor_smatrix.h +0 -1
- esphome/components/veml7700/sensor.py +2 -2
- esphome/components/voice_assistant/__init__.py +6 -0
- esphome/components/voice_assistant/voice_assistant.cpp +24 -2
- esphome/components/voice_assistant/voice_assistant.h +20 -0
- esphome/components/web_server/__init__.py +11 -11
- esphome/components/web_server/list_entities.cpp +2 -0
- esphome/components/web_server/list_entities.h +3 -1
- esphome/components/web_server/web_server.cpp +2 -1
- esphome/components/web_server/web_server.h +2 -0
- esphome/components/web_server_base/web_server_base.cpp +2 -0
- esphome/components/web_server_base/web_server_base.h +3 -1
- esphome/components/wifi/wifi_component_libretiny.cpp +15 -1
- esphome/components/wireguard/__init__.py +9 -6
- esphome/components/wireguard/wireguard.cpp +2 -1
- esphome/components/wireguard/wireguard.h +3 -1
- esphome/config_validation.py +8 -0
- esphome/const.py +8 -1
- esphome/core/bytebuffer.cpp +117 -84
- esphome/core/bytebuffer.h +69 -21
- esphome/core/config.py +0 -3
- esphome/core/defines.h +2 -0
- esphome/core/ring_buffer.cpp +13 -2
- esphome/core/ring_buffer.h +56 -0
- esphome/external_files.py +5 -3
- {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/METADATA +1 -1
- {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/RECORD +204 -169
- {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/LICENSE +0 -0
- {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/WHEEL +0 -0
- {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,542 @@
|
|
1
|
+
#include "ltr501.h"
|
2
|
+
#include "esphome/core/application.h"
|
3
|
+
#include "esphome/core/log.h"
|
4
|
+
#include "esphome/core/helpers.h"
|
5
|
+
|
6
|
+
using esphome::i2c::ErrorCode;
|
7
|
+
|
8
|
+
namespace esphome {
|
9
|
+
namespace ltr501 {
|
10
|
+
|
11
|
+
static const char *const TAG = "ltr501";
|
12
|
+
|
13
|
+
static const uint8_t MAX_TRIES = 5;
|
14
|
+
static const uint8_t MAX_SENSITIVITY_ADJUSTMENTS = 10;
|
15
|
+
|
16
|
+
struct GainTimePair {
|
17
|
+
AlsGain501 gain;
|
18
|
+
IntegrationTime501 time;
|
19
|
+
};
|
20
|
+
|
21
|
+
bool operator==(const GainTimePair &lhs, const GainTimePair &rhs) {
|
22
|
+
return lhs.gain == rhs.gain && lhs.time == rhs.time;
|
23
|
+
}
|
24
|
+
|
25
|
+
bool operator!=(const GainTimePair &lhs, const GainTimePair &rhs) {
|
26
|
+
return !(lhs.gain == rhs.gain && lhs.time == rhs.time);
|
27
|
+
}
|
28
|
+
|
29
|
+
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
30
|
+
size_t i = 0;
|
31
|
+
size_t idx = -1;
|
32
|
+
while (idx == -1 && i < size) {
|
33
|
+
if (array[i] == val) {
|
34
|
+
idx = i;
|
35
|
+
break;
|
36
|
+
}
|
37
|
+
i++;
|
38
|
+
}
|
39
|
+
if (idx == -1 || i + 1 >= size)
|
40
|
+
return val;
|
41
|
+
return array[i + 1];
|
42
|
+
}
|
43
|
+
|
44
|
+
template<typename T, size_t size> T get_prev(const T (&array)[size], const T val) {
|
45
|
+
size_t i = size - 1;
|
46
|
+
size_t idx = -1;
|
47
|
+
while (idx == -1 && i > 0) {
|
48
|
+
if (array[i] == val) {
|
49
|
+
idx = i;
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
i--;
|
53
|
+
}
|
54
|
+
if (idx == -1 || i == 0)
|
55
|
+
return val;
|
56
|
+
return array[i - 1];
|
57
|
+
}
|
58
|
+
|
59
|
+
static uint16_t get_itime_ms(IntegrationTime501 time) {
|
60
|
+
static const uint16_t ALS_INT_TIME[4] = {100, 50, 200, 400};
|
61
|
+
return ALS_INT_TIME[time & 0b11];
|
62
|
+
}
|
63
|
+
|
64
|
+
static uint16_t get_meas_time_ms(MeasurementRepeatRate rate) {
|
65
|
+
static const uint16_t ALS_MEAS_RATE[8] = {50, 100, 200, 500, 1000, 2000, 2000, 2000};
|
66
|
+
return ALS_MEAS_RATE[rate & 0b111];
|
67
|
+
}
|
68
|
+
|
69
|
+
static float get_gain_coeff(AlsGain501 gain) { return gain == AlsGain501::GAIN_1 ? 1.0f : 150.0f; }
|
70
|
+
|
71
|
+
static float get_ps_gain_coeff(PsGain501 gain) {
|
72
|
+
static const float PS_GAIN[4] = {1, 4, 8, 16};
|
73
|
+
return PS_GAIN[gain & 0b11];
|
74
|
+
}
|
75
|
+
|
76
|
+
void LTRAlsPs501Component::setup() {
|
77
|
+
ESP_LOGCONFIG(TAG, "Setting up LTR-501/301/558");
|
78
|
+
// As per datasheet we need to wait at least 100ms after power on to get ALS chip responsive
|
79
|
+
this->set_timeout(100, [this]() { this->state_ = State::DELAYED_SETUP; });
|
80
|
+
}
|
81
|
+
|
82
|
+
void LTRAlsPs501Component::dump_config() {
|
83
|
+
auto get_device_type = [](LtrType typ) {
|
84
|
+
switch (typ) {
|
85
|
+
case LtrType::LTR_TYPE_ALS_ONLY:
|
86
|
+
return "ALS only";
|
87
|
+
case LtrType::LTR_TYPE_PS_ONLY:
|
88
|
+
return "PS only";
|
89
|
+
case LtrType::LTR_TYPE_ALS_AND_PS:
|
90
|
+
return "Als + PS";
|
91
|
+
default:
|
92
|
+
return "Unknown";
|
93
|
+
}
|
94
|
+
};
|
95
|
+
|
96
|
+
LOG_I2C_DEVICE(this);
|
97
|
+
ESP_LOGCONFIG(TAG, " Device type: %s", get_device_type(this->ltr_type_));
|
98
|
+
ESP_LOGCONFIG(TAG, " Automatic mode: %s", ONOFF(this->automatic_mode_enabled_));
|
99
|
+
ESP_LOGCONFIG(TAG, " Gain: %.0fx", get_gain_coeff(this->gain_));
|
100
|
+
ESP_LOGCONFIG(TAG, " Integration time: %d ms", get_itime_ms(this->integration_time_));
|
101
|
+
ESP_LOGCONFIG(TAG, " Measurement repeat rate: %d ms", get_meas_time_ms(this->repeat_rate_));
|
102
|
+
ESP_LOGCONFIG(TAG, " Glass attenuation factor: %f", this->glass_attenuation_factor_);
|
103
|
+
ESP_LOGCONFIG(TAG, " Proximity gain: %.0fx", get_ps_gain_coeff(this->ps_gain_));
|
104
|
+
ESP_LOGCONFIG(TAG, " Proximity cooldown time: %d s", this->ps_cooldown_time_s_);
|
105
|
+
ESP_LOGCONFIG(TAG, " Proximity high threshold: %d", this->ps_threshold_high_);
|
106
|
+
ESP_LOGCONFIG(TAG, " Proximity low threshold: %d", this->ps_threshold_low_);
|
107
|
+
|
108
|
+
LOG_UPDATE_INTERVAL(this);
|
109
|
+
|
110
|
+
LOG_SENSOR(" ", "ALS calculated lux", this->ambient_light_sensor_);
|
111
|
+
LOG_SENSOR(" ", "CH1 Infrared counts", this->infrared_counts_sensor_);
|
112
|
+
LOG_SENSOR(" ", "CH0 Visible+IR counts", this->full_spectrum_counts_sensor_);
|
113
|
+
LOG_SENSOR(" ", "Actual gain", this->actual_gain_sensor_);
|
114
|
+
|
115
|
+
if (this->is_failed()) {
|
116
|
+
ESP_LOGE(TAG, "Communication with I2C LTR-501/301/558 failed!");
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
void LTRAlsPs501Component::update() {
|
121
|
+
if (!this->is_als_()) {
|
122
|
+
ESP_LOGW(TAG, "Update. ALS data not available. Change configuration to ALS or ALS_PS.");
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
if (this->is_ready() && this->is_als_() && this->state_ == State::IDLE) {
|
126
|
+
ESP_LOGV(TAG, "Update. Initiating new ALS data collection.");
|
127
|
+
|
128
|
+
this->state_ = this->automatic_mode_enabled_ ? State::COLLECTING_DATA_AUTO : State::WAITING_FOR_DATA;
|
129
|
+
|
130
|
+
this->als_readings_.ch0 = 0;
|
131
|
+
this->als_readings_.ch1 = 0;
|
132
|
+
this->als_readings_.gain = this->gain_;
|
133
|
+
this->als_readings_.integration_time = this->integration_time_;
|
134
|
+
this->als_readings_.lux = 0;
|
135
|
+
this->als_readings_.number_of_adjustments = 0;
|
136
|
+
|
137
|
+
} else {
|
138
|
+
ESP_LOGV(TAG, "Update. Component not ready yet.");
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
void LTRAlsPs501Component::loop() {
|
143
|
+
ErrorCode err = i2c::ERROR_OK;
|
144
|
+
static uint8_t tries{0};
|
145
|
+
|
146
|
+
switch (this->state_) {
|
147
|
+
case State::DELAYED_SETUP:
|
148
|
+
err = this->write(nullptr, 0);
|
149
|
+
if (err != i2c::ERROR_OK) {
|
150
|
+
ESP_LOGW(TAG, "i2c connection failed");
|
151
|
+
this->mark_failed();
|
152
|
+
}
|
153
|
+
this->configure_reset_();
|
154
|
+
if (this->is_als_()) {
|
155
|
+
this->configure_als_();
|
156
|
+
this->configure_integration_time_(this->integration_time_);
|
157
|
+
}
|
158
|
+
if (this->is_ps_()) {
|
159
|
+
this->configure_ps_();
|
160
|
+
}
|
161
|
+
|
162
|
+
this->state_ = State::IDLE;
|
163
|
+
break;
|
164
|
+
|
165
|
+
case State::IDLE:
|
166
|
+
if (this->is_ps_()) {
|
167
|
+
this->check_and_trigger_ps_();
|
168
|
+
}
|
169
|
+
break;
|
170
|
+
|
171
|
+
case State::WAITING_FOR_DATA:
|
172
|
+
if (this->is_als_data_ready_(this->als_readings_) == DataAvail::DATA_OK) {
|
173
|
+
tries = 0;
|
174
|
+
ESP_LOGV(TAG, "Reading sensor data assuming gain = %.0fx, time = %d ms",
|
175
|
+
get_gain_coeff(this->als_readings_.gain), get_itime_ms(this->als_readings_.integration_time));
|
176
|
+
this->read_sensor_data_(this->als_readings_);
|
177
|
+
this->apply_lux_calculation_(this->als_readings_);
|
178
|
+
this->state_ = State::DATA_COLLECTED;
|
179
|
+
} else if (tries >= MAX_TRIES) {
|
180
|
+
ESP_LOGW(TAG, "Can't get data after several tries. Aborting.");
|
181
|
+
tries = 0;
|
182
|
+
this->status_set_warning();
|
183
|
+
this->state_ = State::IDLE;
|
184
|
+
return;
|
185
|
+
} else {
|
186
|
+
tries++;
|
187
|
+
}
|
188
|
+
break;
|
189
|
+
|
190
|
+
case State::COLLECTING_DATA_AUTO:
|
191
|
+
case State::DATA_COLLECTED:
|
192
|
+
// first measurement in auto mode (COLLECTING_DATA_AUTO state) require device reconfiguration
|
193
|
+
if (this->state_ == State::COLLECTING_DATA_AUTO || this->are_adjustments_required_(this->als_readings_)) {
|
194
|
+
this->state_ = State::ADJUSTMENT_IN_PROGRESS;
|
195
|
+
ESP_LOGD(TAG, "Reconfiguring sensitivity: gain = %.0fx, time = %d ms", get_gain_coeff(this->als_readings_.gain),
|
196
|
+
get_itime_ms(this->als_readings_.integration_time));
|
197
|
+
this->configure_integration_time_(this->als_readings_.integration_time);
|
198
|
+
this->configure_gain_(this->als_readings_.gain);
|
199
|
+
// if sensitivity adjustment needed - need to wait for first data samples after setting new parameters
|
200
|
+
this->set_timeout(2 * get_meas_time_ms(this->repeat_rate_),
|
201
|
+
[this]() { this->state_ = State::WAITING_FOR_DATA; });
|
202
|
+
} else {
|
203
|
+
this->state_ = State::READY_TO_PUBLISH;
|
204
|
+
}
|
205
|
+
break;
|
206
|
+
|
207
|
+
case State::ADJUSTMENT_IN_PROGRESS:
|
208
|
+
// nothing to be done, just waiting for the timeout
|
209
|
+
break;
|
210
|
+
|
211
|
+
case State::READY_TO_PUBLISH:
|
212
|
+
this->publish_data_part_1_(this->als_readings_);
|
213
|
+
this->state_ = State::KEEP_PUBLISHING;
|
214
|
+
break;
|
215
|
+
|
216
|
+
case State::KEEP_PUBLISHING:
|
217
|
+
this->publish_data_part_2_(this->als_readings_);
|
218
|
+
this->status_clear_warning();
|
219
|
+
this->state_ = State::IDLE;
|
220
|
+
break;
|
221
|
+
|
222
|
+
default:
|
223
|
+
break;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
void LTRAlsPs501Component::check_and_trigger_ps_() {
|
228
|
+
static uint32_t last_high_trigger_time{0};
|
229
|
+
static uint32_t last_low_trigger_time{0};
|
230
|
+
uint16_t ps_data = this->read_ps_data_();
|
231
|
+
uint32_t now = millis();
|
232
|
+
|
233
|
+
if (ps_data != this->ps_readings_) {
|
234
|
+
this->ps_readings_ = ps_data;
|
235
|
+
// Higher values - object is closer to sensor
|
236
|
+
if (ps_data > this->ps_threshold_high_ && now - last_high_trigger_time >= this->ps_cooldown_time_s_ * 1000) {
|
237
|
+
last_high_trigger_time = now;
|
238
|
+
ESP_LOGD(TAG, "Proximity high threshold triggered. Value = %d, Trigger level = %d", ps_data,
|
239
|
+
this->ps_threshold_high_);
|
240
|
+
this->on_ps_high_trigger_callback_.call();
|
241
|
+
} else if (ps_data < this->ps_threshold_low_ && now - last_low_trigger_time >= this->ps_cooldown_time_s_ * 1000) {
|
242
|
+
last_low_trigger_time = now;
|
243
|
+
ESP_LOGD(TAG, "Proximity low threshold triggered. Value = %d, Trigger level = %d", ps_data,
|
244
|
+
this->ps_threshold_low_);
|
245
|
+
this->on_ps_low_trigger_callback_.call();
|
246
|
+
}
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
bool LTRAlsPs501Component::check_part_number_() {
|
251
|
+
uint8_t manuf_id = this->reg((uint8_t) CommandRegisters::MANUFAC_ID).get();
|
252
|
+
if (manuf_id != 0x05) { // 0x05 is Lite-On Semiconductor Corp. ID
|
253
|
+
ESP_LOGW(TAG, "Unknown manufacturer ID: 0x%02X", manuf_id);
|
254
|
+
this->mark_failed();
|
255
|
+
return false;
|
256
|
+
}
|
257
|
+
|
258
|
+
// Things getting not really funny here, we can't identify device type by part number ID
|
259
|
+
// ======================== ========= ===== =================
|
260
|
+
// Device Part ID Rev Capabilities
|
261
|
+
// ======================== ========= ===== =================
|
262
|
+
// ltr-558als 0x08 0 als + ps
|
263
|
+
// ltr-501als 0x08 0 als + ps
|
264
|
+
// ltr-301als - 0x08 0 als only
|
265
|
+
|
266
|
+
PartIdRegister part_id{0};
|
267
|
+
part_id.raw = this->reg((uint8_t) CommandRegisters::PART_ID).get();
|
268
|
+
if (part_id.part_number_id != 0x08) {
|
269
|
+
ESP_LOGW(TAG, "Unknown part number ID: 0x%02X. LTR-501/301 shall have 0x08. It might not work properly.",
|
270
|
+
part_id.part_number_id);
|
271
|
+
this->status_set_warning();
|
272
|
+
return true;
|
273
|
+
}
|
274
|
+
return true;
|
275
|
+
}
|
276
|
+
|
277
|
+
void LTRAlsPs501Component::configure_reset_() {
|
278
|
+
ESP_LOGV(TAG, "Resetting");
|
279
|
+
|
280
|
+
AlsControlRegister501 als_ctrl{0};
|
281
|
+
als_ctrl.sw_reset = true;
|
282
|
+
this->reg((uint8_t) CommandRegisters::ALS_CONTR) = als_ctrl.raw;
|
283
|
+
delay(2);
|
284
|
+
|
285
|
+
uint8_t tries = MAX_TRIES;
|
286
|
+
do {
|
287
|
+
ESP_LOGV(TAG, "Waiting chip to reset");
|
288
|
+
delay(2);
|
289
|
+
als_ctrl.raw = this->reg((uint8_t) CommandRegisters::ALS_CONTR).get();
|
290
|
+
} while (als_ctrl.sw_reset && tries--); // while sw reset bit is on - keep waiting
|
291
|
+
|
292
|
+
if (als_ctrl.sw_reset) {
|
293
|
+
ESP_LOGW(TAG, "Reset failed");
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
void LTRAlsPs501Component::configure_als_() {
|
298
|
+
AlsControlRegister501 als_ctrl{0};
|
299
|
+
als_ctrl.sw_reset = false;
|
300
|
+
als_ctrl.als_mode_active = true;
|
301
|
+
als_ctrl.gain = this->gain_;
|
302
|
+
|
303
|
+
ESP_LOGV(TAG, "Setting active mode and gain reg 0x%02X", als_ctrl.raw);
|
304
|
+
this->reg((uint8_t) CommandRegisters::ALS_CONTR) = als_ctrl.raw;
|
305
|
+
delay(5);
|
306
|
+
|
307
|
+
uint8_t tries = MAX_TRIES;
|
308
|
+
do {
|
309
|
+
ESP_LOGV(TAG, "Waiting for ALS device to become active...");
|
310
|
+
delay(2);
|
311
|
+
als_ctrl.raw = this->reg((uint8_t) CommandRegisters::ALS_CONTR).get();
|
312
|
+
} while (!als_ctrl.als_mode_active && tries--); // while active mode is not set - keep waiting
|
313
|
+
|
314
|
+
if (!als_ctrl.als_mode_active) {
|
315
|
+
ESP_LOGW(TAG, "Failed to activate ALS device");
|
316
|
+
}
|
317
|
+
}
|
318
|
+
|
319
|
+
void LTRAlsPs501Component::configure_ps_() {
|
320
|
+
PsMeasurementRateRegister ps_meas{0};
|
321
|
+
ps_meas.ps_measurement_rate = PsMeasurementRate::PS_MEAS_RATE_50MS;
|
322
|
+
this->reg((uint8_t) CommandRegisters::PS_MEAS_RATE) = ps_meas.raw;
|
323
|
+
|
324
|
+
PsControlRegister501 ps_ctrl{0};
|
325
|
+
ps_ctrl.ps_mode_active = true;
|
326
|
+
ps_ctrl.ps_mode_xxx = true;
|
327
|
+
this->reg((uint8_t) CommandRegisters::PS_CONTR) = ps_ctrl.raw;
|
328
|
+
}
|
329
|
+
|
330
|
+
uint16_t LTRAlsPs501Component::read_ps_data_() {
|
331
|
+
AlsPsStatusRegister als_status{0};
|
332
|
+
als_status.raw = this->reg((uint8_t) CommandRegisters::ALS_PS_STATUS).get();
|
333
|
+
if (!als_status.ps_new_data) {
|
334
|
+
return this->ps_readings_;
|
335
|
+
}
|
336
|
+
|
337
|
+
uint8_t ps_low = this->reg((uint8_t) CommandRegisters::PS_DATA_0).get();
|
338
|
+
PsData1Register ps_high;
|
339
|
+
ps_high.raw = this->reg((uint8_t) CommandRegisters::PS_DATA_1).get();
|
340
|
+
|
341
|
+
uint16_t val = encode_uint16(ps_high.ps_data_high, ps_low);
|
342
|
+
return val;
|
343
|
+
}
|
344
|
+
|
345
|
+
void LTRAlsPs501Component::configure_gain_(AlsGain501 gain) {
|
346
|
+
AlsControlRegister501 als_ctrl{0};
|
347
|
+
als_ctrl.als_mode_active = true;
|
348
|
+
als_ctrl.gain = gain;
|
349
|
+
this->reg((uint8_t) CommandRegisters::ALS_CONTR) = als_ctrl.raw;
|
350
|
+
delay(2);
|
351
|
+
|
352
|
+
AlsControlRegister501 read_als_ctrl{0};
|
353
|
+
read_als_ctrl.raw = this->reg((uint8_t) CommandRegisters::ALS_CONTR).get();
|
354
|
+
if (read_als_ctrl.gain != gain) {
|
355
|
+
ESP_LOGW(TAG, "Failed to set gain. We will try one more time.");
|
356
|
+
this->reg((uint8_t) CommandRegisters::ALS_CONTR) = als_ctrl.raw;
|
357
|
+
delay(2);
|
358
|
+
}
|
359
|
+
}
|
360
|
+
|
361
|
+
void LTRAlsPs501Component::configure_integration_time_(IntegrationTime501 time) {
|
362
|
+
MeasurementRateRegister501 meas{0};
|
363
|
+
meas.measurement_repeat_rate = this->repeat_rate_;
|
364
|
+
meas.integration_time = time;
|
365
|
+
this->reg((uint8_t) CommandRegisters::MEAS_RATE) = meas.raw;
|
366
|
+
delay(2);
|
367
|
+
|
368
|
+
MeasurementRateRegister501 read_meas{0};
|
369
|
+
read_meas.raw = this->reg((uint8_t) CommandRegisters::MEAS_RATE).get();
|
370
|
+
if (read_meas.integration_time != time) {
|
371
|
+
ESP_LOGW(TAG, "Failed to set integration time. We will try one more time.");
|
372
|
+
this->reg((uint8_t) CommandRegisters::MEAS_RATE) = meas.raw;
|
373
|
+
delay(2);
|
374
|
+
}
|
375
|
+
}
|
376
|
+
|
377
|
+
DataAvail LTRAlsPs501Component::is_als_data_ready_(AlsReadings &data) {
|
378
|
+
AlsPsStatusRegister als_status{0};
|
379
|
+
als_status.raw = this->reg((uint8_t) CommandRegisters::ALS_PS_STATUS).get();
|
380
|
+
if (!als_status.als_new_data)
|
381
|
+
return DataAvail::NO_DATA;
|
382
|
+
ESP_LOGV(TAG, "Data ready, reported gain is %.0fx", get_gain_coeff(als_status.gain));
|
383
|
+
if (data.gain != als_status.gain) {
|
384
|
+
ESP_LOGW(TAG, "Actual gain differs from requested (%.0f)", get_gain_coeff(data.gain));
|
385
|
+
return DataAvail::BAD_DATA;
|
386
|
+
}
|
387
|
+
data.gain = als_status.gain;
|
388
|
+
return DataAvail::DATA_OK;
|
389
|
+
}
|
390
|
+
|
391
|
+
void LTRAlsPs501Component::read_sensor_data_(AlsReadings &data) {
|
392
|
+
data.ch1 = 0;
|
393
|
+
data.ch0 = 0;
|
394
|
+
uint8_t ch1_0 = this->reg((uint8_t) CommandRegisters::ALS_DATA_CH1_0).get();
|
395
|
+
uint8_t ch1_1 = this->reg((uint8_t) CommandRegisters::ALS_DATA_CH1_1).get();
|
396
|
+
uint8_t ch0_0 = this->reg((uint8_t) CommandRegisters::ALS_DATA_CH0_0).get();
|
397
|
+
uint8_t ch0_1 = this->reg((uint8_t) CommandRegisters::ALS_DATA_CH0_1).get();
|
398
|
+
data.ch1 = encode_uint16(ch1_1, ch1_0);
|
399
|
+
data.ch0 = encode_uint16(ch0_1, ch0_0);
|
400
|
+
|
401
|
+
ESP_LOGD(TAG, "Got sensor data: CH1 = %d, CH0 = %d", data.ch1, data.ch0);
|
402
|
+
}
|
403
|
+
|
404
|
+
bool LTRAlsPs501Component::are_adjustments_required_(AlsReadings &data) {
|
405
|
+
if (!this->automatic_mode_enabled_)
|
406
|
+
return false;
|
407
|
+
|
408
|
+
// sometimes sensors fail to change sensitivity. this prevents us from infinite loop
|
409
|
+
if (data.number_of_adjustments++ > MAX_SENSITIVITY_ADJUSTMENTS) {
|
410
|
+
ESP_LOGW(TAG, "Too many sensitivity adjustments done. Something wrong with the sensor. Stopping.");
|
411
|
+
return false;
|
412
|
+
}
|
413
|
+
|
414
|
+
ESP_LOGV(TAG, "Adjusting sensitivity, run #%d", data.number_of_adjustments);
|
415
|
+
|
416
|
+
// available combinations of gain and integration times:
|
417
|
+
static const GainTimePair GAIN_TIME_PAIRS[] = {
|
418
|
+
{AlsGain501::GAIN_1, INTEGRATION_TIME_50MS}, {AlsGain501::GAIN_1, INTEGRATION_TIME_100MS},
|
419
|
+
{AlsGain501::GAIN_150, INTEGRATION_TIME_100MS}, {AlsGain501::GAIN_150, INTEGRATION_TIME_200MS},
|
420
|
+
{AlsGain501::GAIN_150, INTEGRATION_TIME_400MS},
|
421
|
+
};
|
422
|
+
|
423
|
+
GainTimePair current_pair = {data.gain, data.integration_time};
|
424
|
+
|
425
|
+
// Here comes funky business with this sensor. it has no internal error checking mechanism
|
426
|
+
// as in later versions (LTR-303/329/559/..) and sensor gets overwhelmed when saturated
|
427
|
+
// and readings are strange. We only check high sensitivity mode for now.
|
428
|
+
// Nothing is documented and it is a result of real-world testing.
|
429
|
+
if (data.gain == AlsGain501::GAIN_150) {
|
430
|
+
// when sensor is saturated it returns various crazy numbers
|
431
|
+
// CH1 = 1, CH0 = 0
|
432
|
+
if (data.ch1 == 1 && data.ch0 == 0) {
|
433
|
+
ESP_LOGV(TAG, "Looks like sensor got saturated (?) CH1 = 1, CH0 = 0, Gain 150x");
|
434
|
+
// fake saturation
|
435
|
+
data.ch0 = 0xffff;
|
436
|
+
data.ch1 = 0xffff;
|
437
|
+
} else if (data.ch1 == 65535 && data.ch0 == 0) {
|
438
|
+
ESP_LOGV(TAG, "Looks like sensor got saturated (?) CH1 = 65535, CH0 = 0, Gain 150x");
|
439
|
+
data.ch0 = 0xffff;
|
440
|
+
} else if (data.ch1 > 1000 && data.ch0 == 0) {
|
441
|
+
ESP_LOGV(TAG, "Looks like sensor got saturated (?) CH1 = %d, CH0 = 0, Gain 150x", data.ch1);
|
442
|
+
data.ch0 = 0xffff;
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
446
|
+
static const uint16_t LOW_INTENSITY_THRESHOLD_1 = 100;
|
447
|
+
static const uint16_t LOW_INTENSITY_THRESHOLD_200 = 2000;
|
448
|
+
static const uint16_t HIGH_INTENSITY_THRESHOLD = 25000;
|
449
|
+
|
450
|
+
if (data.ch0 <= (data.gain == AlsGain501::GAIN_1 ? LOW_INTENSITY_THRESHOLD_1 : LOW_INTENSITY_THRESHOLD_200) ||
|
451
|
+
(data.gain == AlsGain501::GAIN_1 && data.lux < 320)) {
|
452
|
+
GainTimePair next_pair = get_next(GAIN_TIME_PAIRS, current_pair);
|
453
|
+
if (next_pair != current_pair) {
|
454
|
+
data.gain = next_pair.gain;
|
455
|
+
data.integration_time = next_pair.time;
|
456
|
+
ESP_LOGV(TAG, "Low illuminance. Increasing sensitivity.");
|
457
|
+
return true;
|
458
|
+
}
|
459
|
+
|
460
|
+
} else if (data.ch0 >= HIGH_INTENSITY_THRESHOLD || data.ch1 >= HIGH_INTENSITY_THRESHOLD) {
|
461
|
+
GainTimePair prev_pair = get_prev(GAIN_TIME_PAIRS, current_pair);
|
462
|
+
if (prev_pair != current_pair) {
|
463
|
+
data.gain = prev_pair.gain;
|
464
|
+
data.integration_time = prev_pair.time;
|
465
|
+
ESP_LOGV(TAG, "High illuminance. Decreasing sensitivity.");
|
466
|
+
return true;
|
467
|
+
}
|
468
|
+
} else {
|
469
|
+
ESP_LOGD(TAG, "Illuminance is good enough.");
|
470
|
+
return false;
|
471
|
+
}
|
472
|
+
ESP_LOGD(TAG, "Can't adjust sensitivity anymore.");
|
473
|
+
return false;
|
474
|
+
}
|
475
|
+
|
476
|
+
void LTRAlsPs501Component::apply_lux_calculation_(AlsReadings &data) {
|
477
|
+
if ((data.ch0 == 0xFFFF) || (data.ch1 == 0xFFFF)) {
|
478
|
+
ESP_LOGW(TAG, "Sensors got saturated");
|
479
|
+
data.lux = 0.0f;
|
480
|
+
return;
|
481
|
+
}
|
482
|
+
|
483
|
+
if ((data.ch0 == 0x0000) && (data.ch1 == 0x0000)) {
|
484
|
+
ESP_LOGW(TAG, "Sensors blacked out");
|
485
|
+
data.lux = 0.0f;
|
486
|
+
return;
|
487
|
+
}
|
488
|
+
|
489
|
+
float ch0 = data.ch0;
|
490
|
+
float ch1 = data.ch1;
|
491
|
+
float ratio = ch1 / (ch0 + ch1);
|
492
|
+
float als_gain = get_gain_coeff(data.gain);
|
493
|
+
float als_time = ((float) get_itime_ms(data.integration_time)) / 100.0f;
|
494
|
+
float inv_pfactor = this->glass_attenuation_factor_;
|
495
|
+
float lux = 0.0f;
|
496
|
+
|
497
|
+
// method from
|
498
|
+
// https://github.com/fards/Ainol_fire_kernel/blob/83832cf8a3082fd8e963230f4b1984479d1f1a84/customer/drivers/lightsensor/ltr501als.c#L295
|
499
|
+
|
500
|
+
if (ratio < 0.45) {
|
501
|
+
lux = 1.7743 * ch0 + 1.1059 * ch1;
|
502
|
+
} else if (ratio < 0.64) {
|
503
|
+
lux = 3.7725 * ch0 - 1.3363 * ch1;
|
504
|
+
} else if (ratio < 0.85) {
|
505
|
+
lux = 1.6903 * ch0 - 0.1693 * ch1;
|
506
|
+
} else {
|
507
|
+
ESP_LOGW(TAG, "Impossible ch1/(ch0 + ch1) ratio");
|
508
|
+
lux = 0.0f;
|
509
|
+
}
|
510
|
+
|
511
|
+
lux = inv_pfactor * lux / als_gain / als_time;
|
512
|
+
data.lux = lux;
|
513
|
+
|
514
|
+
ESP_LOGD(TAG, "Lux calculation: ratio %.3f, gain %.0fx, int time %.1f, inv_pfactor %.3f, lux %.3f", ratio, als_gain,
|
515
|
+
als_time, inv_pfactor, lux);
|
516
|
+
}
|
517
|
+
|
518
|
+
void LTRAlsPs501Component::publish_data_part_1_(AlsReadings &data) {
|
519
|
+
if (this->proximity_counts_sensor_ != nullptr) {
|
520
|
+
this->proximity_counts_sensor_->publish_state(this->ps_readings_);
|
521
|
+
}
|
522
|
+
if (this->ambient_light_sensor_ != nullptr) {
|
523
|
+
this->ambient_light_sensor_->publish_state(data.lux);
|
524
|
+
}
|
525
|
+
if (this->infrared_counts_sensor_ != nullptr) {
|
526
|
+
this->infrared_counts_sensor_->publish_state(data.ch1);
|
527
|
+
}
|
528
|
+
if (this->full_spectrum_counts_sensor_ != nullptr) {
|
529
|
+
this->full_spectrum_counts_sensor_->publish_state(data.ch0);
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
void LTRAlsPs501Component::publish_data_part_2_(AlsReadings &data) {
|
534
|
+
if (this->actual_gain_sensor_ != nullptr) {
|
535
|
+
this->actual_gain_sensor_->publish_state(get_gain_coeff(data.gain));
|
536
|
+
}
|
537
|
+
if (this->actual_integration_time_sensor_ != nullptr) {
|
538
|
+
this->actual_integration_time_sensor_->publish_state(get_itime_ms(data.integration_time));
|
539
|
+
}
|
540
|
+
}
|
541
|
+
} // namespace ltr501
|
542
|
+
} // namespace esphome
|