esphome 2024.11.3__py3-none-any.whl → 2024.12.0b1__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/components/adc/adc_sensor.h +7 -8
- esphome/components/adc/adc_sensor_common.cpp +24 -0
- esphome/components/adc/{adc_sensor.cpp → adc_sensor_esp32.cpp} +10 -179
- esphome/components/adc/adc_sensor_esp8266.cpp +58 -0
- esphome/components/adc/adc_sensor_rp2040.cpp +93 -0
- esphome/components/alarm_control_panel/alarm_control_panel_call.cpp +3 -4
- esphome/components/animation/__init__.py +1 -2
- esphome/components/apds9306/apds9306.cpp +2 -1
- esphome/components/audio/audio.h +1 -1
- esphome/components/bk72xx/__init__.py +1 -1
- esphome/components/cse7766/cse7766.cpp +1 -1
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +2 -2
- esphome/components/dht/dht.cpp +2 -1
- esphome/components/display/display.cpp +10 -6
- esphome/components/display/display.h +14 -0
- esphome/components/display_menu_base/__init__.py +0 -2
- esphome/components/display_menu_base/display_menu_base.cpp +1 -1
- esphome/components/dsmr/dsmr.cpp +1 -1
- esphome/components/esp32/__init__.py +94 -12
- esphome/components/esp32/boards.py +222 -14
- esphome/components/esp32_ble/__init__.py +22 -2
- esphome/components/esp32_ble/ble.cpp +13 -5
- esphome/components/esp32_ble/ble.h +2 -0
- esphome/components/esp32_ble/ble_advertising.cpp +1 -1
- esphome/components/esp32_ble/ble_uuid.cpp +9 -10
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +4 -1
- esphome/components/esp32_camera_web_server/camera_web_server.h +1 -1
- esphome/components/esp32_rmt_led_strip/light.py +3 -3
- esphome/components/esp8266/__init__.py +5 -7
- esphome/components/ezo/ezo.cpp +14 -26
- esphome/components/font/__init__.py +5 -23
- esphome/components/font/font.cpp +5 -3
- esphome/components/graphical_display_menu/__init__.py +2 -0
- esphome/components/haier/hon_climate.cpp +79 -80
- esphome/components/hbridge/switch/__init__.py +44 -0
- esphome/components/hbridge/switch/hbridge_switch.cpp +95 -0
- esphome/components/hbridge/switch/hbridge_switch.h +50 -0
- esphome/components/hitachi_ac344/hitachi_ac344.cpp +4 -2
- esphome/components/hitachi_ac424/hitachi_ac424.cpp +4 -2
- esphome/components/homeassistant/number/homeassistant_number.cpp +3 -0
- esphome/components/hx711/hx711.cpp +1 -1
- esphome/components/hx711/hx711.h +1 -1
- esphome/components/i2c/i2c_bus_esp_idf.cpp +2 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +61 -59
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -17
- esphome/components/ili9xxx/display.py +1 -2
- esphome/components/ili9xxx/ili9xxx_display.cpp +3 -2
- esphome/components/image/__init__.py +1 -2
- esphome/components/logger/logger.cpp +1 -1
- esphome/components/ltr501/ltr501.cpp +1 -1
- esphome/components/lvgl/defines.py +8 -1
- esphome/components/lvgl/lv_validation.py +8 -3
- esphome/components/lvgl/lvgl_esphome.cpp +1 -1
- esphome/components/lvgl/lvgl_esphome.h +16 -0
- esphome/components/lvgl/widgets/animimg.py +12 -17
- esphome/components/lvgl/widgets/img.py +1 -3
- esphome/components/matrix_keypad/__init__.py +15 -3
- esphome/components/matrix_keypad/matrix_keypad.cpp +4 -0
- esphome/components/matrix_keypad/matrix_keypad.h +5 -0
- esphome/components/max31865/max31865.cpp +4 -2
- esphome/components/modbus_controller/modbus_controller.cpp +24 -24
- esphome/components/modbus_controller/modbus_controller.h +22 -22
- esphome/components/modbus_controller/number/modbus_number.cpp +8 -8
- esphome/components/modbus_controller/number/modbus_number.h +4 -4
- esphome/components/modbus_controller/output/modbus_output.cpp +7 -6
- esphome/components/modbus_controller/output/modbus_output.h +5 -5
- esphome/components/modbus_controller/select/modbus_select.cpp +4 -3
- esphome/components/modbus_controller/select/modbus_select.h +4 -4
- esphome/components/modbus_controller/switch/modbus_switch.cpp +5 -5
- esphome/components/modbus_controller/switch/modbus_switch.h +2 -2
- esphome/components/mqtt/__init__.py +4 -0
- esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -5
- esphome/components/mqtt/mqtt_backend_esp32.cpp +3 -3
- esphome/components/mqtt/mqtt_client.cpp +4 -0
- esphome/components/mqtt/mqtt_client.h +6 -0
- esphome/components/mqtt/mqtt_climate.cpp +13 -3
- esphome/components/mqtt/mqtt_sensor.cpp +2 -0
- esphome/components/network/ip_address.h +1 -1
- esphome/components/nextion/__init__.py +2 -0
- esphome/components/nextion/automation.h +76 -0
- esphome/components/nextion/base_component.py +1 -0
- esphome/components/nextion/binary_sensor/__init__.py +43 -2
- esphome/components/nextion/display.py +15 -0
- esphome/components/nextion/nextion.cpp +8 -5
- esphome/components/nextion/nextion.h +7 -0
- esphome/components/nextion/nextion_upload_idf.cpp +2 -2
- esphome/components/nextion/sensor/__init__.py +38 -5
- esphome/components/nextion/switch/__init__.py +38 -2
- esphome/components/nextion/text_sensor/__init__.py +37 -2
- esphome/components/nfc/ndef_record.cpp +3 -3
- esphome/components/online_image/__init__.py +1 -0
- esphome/components/opentherm/opentherm.cpp +3 -3
- esphome/components/opentherm/opentherm.h +1 -1
- esphome/components/ota/automation.h +1 -1
- esphome/components/output/float_output.cpp +1 -1
- esphome/components/pca6416a/pca6416a.cpp +5 -3
- esphome/components/pca9554/pca9554.cpp +4 -4
- esphome/components/pipsolar/pipsolar.cpp +2 -2
- esphome/components/pipsolar/switch/pipsolar_switch.cpp +2 -2
- esphome/components/pn532/pn532_mifare_ultralight.cpp +2 -2
- esphome/components/pn7150/pn7150_mifare_ultralight.cpp +2 -2
- esphome/components/pn7160/pn7160_mifare_ultralight.cpp +2 -2
- esphome/components/qmc5883l/qmc5883l.cpp +45 -19
- esphome/components/qmc5883l/qmc5883l.h +1 -1
- esphome/components/qspi_dbi/qspi_dbi.cpp +2 -1
- esphome/components/remote_base/raw_protocol.cpp +1 -1
- esphome/components/rotary_encoder/rotary_encoder.cpp +3 -1
- esphome/components/rp2040/__init__.py +1 -1
- esphome/components/rtl87xx/__init__.py +1 -1
- esphome/components/safe_mode/automation.h +1 -1
- esphome/components/seeed_mr60bha2/__init__.py +41 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +173 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +61 -0
- esphome/components/seeed_mr60bha2/sensor.py +57 -0
- esphome/components/seeed_mr60fda2/__init__.py +41 -0
- esphome/components/seeed_mr60fda2/binary_sensor.py +33 -0
- esphome/components/seeed_mr60fda2/button/__init__.py +45 -0
- esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.cpp +9 -0
- esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.h +18 -0
- esphome/components/seeed_mr60fda2/button/reset_radar_button.cpp +9 -0
- esphome/components/seeed_mr60fda2/button/reset_radar_button.h +18 -0
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +368 -0
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.h +101 -0
- esphome/components/seeed_mr60fda2/select/__init__.py +59 -0
- esphome/components/seeed_mr60fda2/select/height_threshold_select.cpp +15 -0
- esphome/components/seeed_mr60fda2/select/height_threshold_select.h +18 -0
- esphome/components/seeed_mr60fda2/select/install_height_select.cpp +15 -0
- esphome/components/seeed_mr60fda2/select/install_height_select.h +18 -0
- esphome/components/seeed_mr60fda2/select/sensitivity_select.cpp +15 -0
- esphome/components/seeed_mr60fda2/select/sensitivity_select.h +18 -0
- esphome/components/sen5x/sensor.py +5 -6
- esphome/components/shelly_dimmer/shelly_dimmer.cpp +1 -1
- esphome/components/sim800l/sim800l.cpp +1 -1
- esphome/components/sntp/sntp_component.cpp +14 -20
- esphome/components/sntp/sntp_component.h +6 -9
- esphome/components/sntp/time.py +4 -7
- esphome/components/sprinkler/sprinkler.cpp +2 -2
- esphome/components/st7735/st7735.cpp +1 -1
- esphome/components/st7789v/st7789v.cpp +1 -1
- esphome/components/stepper/stepper.h +0 -1
- esphome/components/sun_gtil2/sun_gtil2.cpp +1 -1
- esphome/components/switch/binary_sensor/__init__.py +31 -0
- esphome/components/switch/binary_sensor/switch_binary_sensor.cpp +17 -0
- esphome/components/switch/binary_sensor/switch_binary_sensor.h +22 -0
- esphome/components/sx1509/sx1509_gpio_pin.cpp +2 -1
- esphome/components/sx1509/sx1509_gpio_pin.h +5 -5
- esphome/components/uart/uart.h +1 -1
- esphome/components/udp/udp_component.cpp +32 -16
- esphome/components/ufire_ec/sensor.py +4 -4
- esphome/components/uln2003/uln2003.cpp +4 -1
- esphome/components/waveshare_epaper/display.py +8 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +191 -0
- esphome/components/waveshare_epaper/waveshare_epaper.h +56 -0
- esphome/components/wiegand/__init__.py +3 -4
- esphome/components/wifi/__init__.py +42 -0
- esphome/components/wifi/wifi_component.cpp +2 -2
- esphome/components/wifi/wifi_component.h +82 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +1 -1
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
- esphome/components/wifi/wifi_component_libretiny.cpp +1 -1
- esphome/components/wifi/wifi_component_pico_w.cpp +1 -1
- esphome/components/wireguard/wireguard.cpp +2 -2
- esphome/components/xiaomi_ble/xiaomi_ble.cpp +1 -1
- esphome/config_validation.py +15 -11
- esphome/const.py +7 -1
- esphome/core/component.cpp +1 -1
- esphome/core/config.py +1 -2
- esphome/core/defines.h +3 -1
- esphome/core/helpers.cpp +6 -1
- esphome/core/helpers.h +2 -1
- esphome/core/optional.h +2 -2
- {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/METADATA +3 -3
- {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/RECORD +178 -149
- {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/LICENSE +0 -0
- {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/WHEEL +0 -0
- {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2024.11.3.dist-info → esphome-2024.12.0b1.dist-info}/top_level.txt +0 -0
@@ -33,14 +33,15 @@ enum SpeakerEventGroupBits : uint32_t {
|
|
33
33
|
STATE_RUNNING = (1 << 11),
|
34
34
|
STATE_STOPPING = (1 << 12),
|
35
35
|
STATE_STOPPED = (1 << 13),
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
ERR_TASK_FAILED_TO_START = (1 << 14),
|
37
|
+
ERR_ESP_INVALID_STATE = (1 << 15),
|
38
|
+
ERR_ESP_NOT_SUPPORTED = (1 << 16),
|
39
39
|
ERR_ESP_INVALID_ARG = (1 << 17),
|
40
40
|
ERR_ESP_INVALID_SIZE = (1 << 18),
|
41
41
|
ERR_ESP_NO_MEM = (1 << 19),
|
42
42
|
ERR_ESP_FAIL = (1 << 20),
|
43
|
-
ALL_ERR_ESP_BITS = ERR_ESP_INVALID_STATE |
|
43
|
+
ALL_ERR_ESP_BITS = ERR_ESP_INVALID_STATE | ERR_ESP_NOT_SUPPORTED | ERR_ESP_INVALID_ARG | ERR_ESP_INVALID_SIZE |
|
44
|
+
ERR_ESP_NO_MEM | ERR_ESP_FAIL,
|
44
45
|
ALL_BITS = 0x00FFFFFF, // All valid FreeRTOS event group bits
|
45
46
|
};
|
46
47
|
|
@@ -55,6 +56,8 @@ static esp_err_t err_bit_to_esp_err(uint32_t bit) {
|
|
55
56
|
return ESP_ERR_INVALID_SIZE;
|
56
57
|
case SpeakerEventGroupBits::ERR_ESP_NO_MEM:
|
57
58
|
return ESP_ERR_NO_MEM;
|
59
|
+
case SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED:
|
60
|
+
return ESP_ERR_NOT_SUPPORTED;
|
58
61
|
default:
|
59
62
|
return ESP_FAIL;
|
60
63
|
}
|
@@ -135,19 +138,19 @@ void I2SAudioSpeaker::loop() {
|
|
135
138
|
xEventGroupClearBits(this->event_group_, SpeakerEventGroupBits::ERR_TASK_FAILED_TO_START);
|
136
139
|
}
|
137
140
|
|
138
|
-
if (event_group_bits & SpeakerEventGroupBits::
|
141
|
+
if (event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS) {
|
142
|
+
uint32_t error_bits = event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS;
|
143
|
+
ESP_LOGW(TAG, "Error writing to I2S: %s", esp_err_to_name(err_bit_to_esp_err(error_bits)));
|
144
|
+
this->status_set_warning();
|
145
|
+
}
|
146
|
+
|
147
|
+
if (event_group_bits & SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED) {
|
139
148
|
this->status_set_error("Failed to adjust I2S bus to match the incoming audio");
|
140
149
|
ESP_LOGE(TAG,
|
141
150
|
"Incompatible audio format: sample rate = %" PRIu32 ", channels = %" PRIu8 ", bits per sample = %" PRIu8,
|
142
151
|
this->audio_stream_info_.sample_rate, this->audio_stream_info_.channels,
|
143
152
|
this->audio_stream_info_.bits_per_sample);
|
144
153
|
}
|
145
|
-
|
146
|
-
if (event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS) {
|
147
|
-
uint32_t error_bits = event_group_bits & SpeakerEventGroupBits::ALL_ERR_ESP_BITS;
|
148
|
-
ESP_LOGW(TAG, "Error writing to I2S: %s", esp_err_to_name(err_bit_to_esp_err(error_bits)));
|
149
|
-
this->status_set_warning();
|
150
|
-
}
|
151
154
|
}
|
152
155
|
|
153
156
|
void I2SAudioSpeaker::set_volume(float volume) {
|
@@ -236,13 +239,15 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
236
239
|
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_STARTING);
|
237
240
|
|
238
241
|
audio::AudioStreamInfo audio_stream_info = this_speaker->audio_stream_info_;
|
239
|
-
const ssize_t bytes_per_sample = audio_stream_info.get_bytes_per_sample();
|
240
|
-
const uint8_t number_of_channels = audio_stream_info.channels;
|
241
242
|
|
242
|
-
const
|
243
|
-
|
243
|
+
const uint32_t bytes_per_ms =
|
244
|
+
audio_stream_info.channels * audio_stream_info.get_bytes_per_sample() * audio_stream_info.sample_rate / 1000;
|
245
|
+
|
246
|
+
const size_t dma_buffers_size = DMA_BUFFERS_COUNT * DMA_BUFFER_DURATION_MS * bytes_per_ms;
|
247
|
+
|
248
|
+
// Ensure ring buffer is at least as large as the total size of the DMA buffers
|
244
249
|
const size_t ring_buffer_size =
|
245
|
-
|
250
|
+
std::min((uint32_t) dma_buffers_size, this_speaker->buffer_duration_ms_ * bytes_per_ms);
|
246
251
|
|
247
252
|
if (this_speaker->send_esp_err_to_event_group_(this_speaker->allocate_buffers_(dma_buffers_size, ring_buffer_size))) {
|
248
253
|
// Failed to allocate buffers
|
@@ -250,14 +255,7 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
250
255
|
this_speaker->delete_task_(dma_buffers_size);
|
251
256
|
}
|
252
257
|
|
253
|
-
if (this_speaker->send_esp_err_to_event_group_(this_speaker->start_i2s_driver_())) {
|
254
|
-
// Failed to start I2S driver
|
255
|
-
this_speaker->delete_task_(dma_buffers_size);
|
256
|
-
}
|
257
|
-
|
258
|
-
if (!this_speaker->send_esp_err_to_event_group_(this_speaker->reconfigure_i2s_stream_info_(audio_stream_info))) {
|
259
|
-
// Successfully set the I2S stream info, ready to write audio data to the I2S port
|
260
|
-
|
258
|
+
if (!this_speaker->send_esp_err_to_event_group_(this_speaker->start_i2s_driver_(audio_stream_info))) {
|
261
259
|
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_RUNNING);
|
262
260
|
|
263
261
|
bool stop_gracefully = false;
|
@@ -275,6 +273,12 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
275
273
|
stop_gracefully = true;
|
276
274
|
}
|
277
275
|
|
276
|
+
if (this_speaker->audio_stream_info_ != audio_stream_info) {
|
277
|
+
// Audio stream info has changed, stop the speaker task so it will restart with the proper settings.
|
278
|
+
|
279
|
+
break;
|
280
|
+
}
|
281
|
+
|
278
282
|
i2s_event_t i2s_event;
|
279
283
|
while (xQueueReceive(this_speaker->i2s_event_queue_, &i2s_event, 0)) {
|
280
284
|
if (i2s_event.type == I2S_EVENT_TX_Q_OVF) {
|
@@ -316,17 +320,14 @@ void I2SAudioSpeaker::speaker_task(void *params) {
|
|
316
320
|
}
|
317
321
|
}
|
318
322
|
}
|
319
|
-
} else {
|
320
|
-
// Couldn't configure the I2S port to be compatible with the incoming audio
|
321
|
-
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::ERR_INVALID_FORMAT);
|
322
|
-
}
|
323
|
-
i2s_zero_dma_buffer(this_speaker->parent_->get_port());
|
324
323
|
|
325
|
-
|
324
|
+
xEventGroupSetBits(this_speaker->event_group_, SpeakerEventGroupBits::STATE_STOPPING);
|
325
|
+
|
326
|
+
i2s_driver_uninstall(this_speaker->parent_->get_port());
|
326
327
|
|
327
|
-
|
328
|
+
this_speaker->parent_->unlock();
|
329
|
+
}
|
328
330
|
|
329
|
-
this_speaker->parent_->unlock();
|
330
331
|
this_speaker->delete_task_(dma_buffers_size);
|
331
332
|
}
|
332
333
|
|
@@ -382,6 +383,9 @@ bool I2SAudioSpeaker::send_esp_err_to_event_group_(esp_err_t err) {
|
|
382
383
|
case ESP_ERR_NO_MEM:
|
383
384
|
xEventGroupSetBits(this->event_group_, SpeakerEventGroupBits::ERR_ESP_NO_MEM);
|
384
385
|
return true;
|
386
|
+
case ESP_ERR_NOT_SUPPORTED:
|
387
|
+
xEventGroupSetBits(this->event_group_, SpeakerEventGroupBits::ERR_ESP_NOT_SUPPORTED);
|
388
|
+
return true;
|
385
389
|
default:
|
386
390
|
xEventGroupSetBits(this->event_group_, SpeakerEventGroupBits::ERR_ESP_FAIL);
|
387
391
|
return true;
|
@@ -411,18 +415,40 @@ esp_err_t I2SAudioSpeaker::allocate_buffers_(size_t data_buffer_size, size_t rin
|
|
411
415
|
return ESP_OK;
|
412
416
|
}
|
413
417
|
|
414
|
-
esp_err_t I2SAudioSpeaker::start_i2s_driver_() {
|
418
|
+
esp_err_t I2SAudioSpeaker::start_i2s_driver_(audio::AudioStreamInfo &audio_stream_info) {
|
419
|
+
if ((this->i2s_mode_ & I2S_MODE_SLAVE) && (this->sample_rate_ != audio_stream_info.sample_rate)) { // NOLINT
|
420
|
+
// Can't reconfigure I2S bus, so the sample rate must match the configured value
|
421
|
+
return ESP_ERR_NOT_SUPPORTED;
|
422
|
+
}
|
423
|
+
|
424
|
+
if ((i2s_bits_per_sample_t) audio_stream_info.bits_per_sample > this->bits_per_sample_) {
|
425
|
+
// Currently can't handle the case when the incoming audio has more bits per sample than the configured value
|
426
|
+
return ESP_ERR_NOT_SUPPORTED;
|
427
|
+
}
|
428
|
+
|
415
429
|
if (!this->parent_->try_lock()) {
|
416
430
|
return ESP_ERR_INVALID_STATE;
|
417
431
|
}
|
418
432
|
|
433
|
+
i2s_channel_fmt_t channel = this->channel_;
|
434
|
+
|
435
|
+
if (audio_stream_info.channels == 1) {
|
436
|
+
if (this->channel_ == I2S_CHANNEL_FMT_ONLY_LEFT) {
|
437
|
+
channel = I2S_CHANNEL_FMT_ONLY_LEFT;
|
438
|
+
} else {
|
439
|
+
channel = I2S_CHANNEL_FMT_ONLY_RIGHT;
|
440
|
+
}
|
441
|
+
} else if (audio_stream_info.channels == 2) {
|
442
|
+
channel = I2S_CHANNEL_FMT_RIGHT_LEFT;
|
443
|
+
}
|
444
|
+
|
419
445
|
int dma_buffer_length = DMA_BUFFER_DURATION_MS * this->sample_rate_ / 1000;
|
420
446
|
|
421
447
|
i2s_driver_config_t config = {
|
422
448
|
.mode = (i2s_mode_t) (this->i2s_mode_ | I2S_MODE_TX),
|
423
|
-
.sample_rate =
|
449
|
+
.sample_rate = audio_stream_info.sample_rate,
|
424
450
|
.bits_per_sample = this->bits_per_sample_,
|
425
|
-
.channel_format =
|
451
|
+
.channel_format = channel,
|
426
452
|
.communication_format = this->i2s_comm_fmt_,
|
427
453
|
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
|
428
454
|
.dma_buf_count = DMA_BUFFERS_COUNT,
|
@@ -477,30 +503,6 @@ esp_err_t I2SAudioSpeaker::start_i2s_driver_() {
|
|
477
503
|
return err;
|
478
504
|
}
|
479
505
|
|
480
|
-
esp_err_t I2SAudioSpeaker::reconfigure_i2s_stream_info_(audio::AudioStreamInfo &audio_stream_info) {
|
481
|
-
if (this->i2s_mode_ & I2S_MODE_MASTER) {
|
482
|
-
// ESP controls for the the I2S bus, so adjust the sample rate and bits per sample to match the incoming audio
|
483
|
-
this->sample_rate_ = audio_stream_info.sample_rate;
|
484
|
-
this->bits_per_sample_ = (i2s_bits_per_sample_t) audio_stream_info.bits_per_sample;
|
485
|
-
} else if (this->sample_rate_ != audio_stream_info.sample_rate) {
|
486
|
-
// Can't reconfigure I2S bus, so the sample rate must match the configured value
|
487
|
-
return ESP_ERR_INVALID_ARG;
|
488
|
-
}
|
489
|
-
|
490
|
-
if ((i2s_bits_per_sample_t) audio_stream_info.bits_per_sample > this->bits_per_sample_) {
|
491
|
-
// Currently can't handle the case when the incoming audio has more bits per sample than the configured value
|
492
|
-
return ESP_ERR_INVALID_ARG;
|
493
|
-
}
|
494
|
-
|
495
|
-
if (audio_stream_info.channels == 1) {
|
496
|
-
return i2s_set_clk(this->parent_->get_port(), this->sample_rate_, this->bits_per_sample_, I2S_CHANNEL_MONO);
|
497
|
-
} else if (audio_stream_info.channels == 2) {
|
498
|
-
return i2s_set_clk(this->parent_->get_port(), this->sample_rate_, this->bits_per_sample_, I2S_CHANNEL_STEREO);
|
499
|
-
}
|
500
|
-
|
501
|
-
return ESP_ERR_INVALID_ARG;
|
502
|
-
}
|
503
|
-
|
504
506
|
void I2SAudioSpeaker::delete_task_(size_t buffer_size) {
|
505
507
|
this->audio_ring_buffer_.reset(); // Releases onwership of the shared_ptr
|
506
508
|
|
@@ -91,24 +91,15 @@ class I2SAudioSpeaker : public I2SAudioOut, public speaker::Speaker, public Comp
|
|
91
91
|
esp_err_t allocate_buffers_(size_t data_buffer_size, size_t ring_buffer_size);
|
92
92
|
|
93
93
|
/// @brief Starts the ESP32 I2S driver.
|
94
|
-
/// Attempts to lock the I2S port, starts the I2S driver
|
95
|
-
/// the I2S port and uninstall the driver, if necessary.
|
96
|
-
/// @
|
97
|
-
///
|
94
|
+
/// Attempts to lock the I2S port, starts the I2S driver using the passed in stream information, and sets the data out
|
95
|
+
/// pin. If it fails, it will unlock the I2S port and uninstall the driver, if necessary.
|
96
|
+
/// @param audio_stream_info Stream information for the I2S driver.
|
97
|
+
/// @return ESP_ERR_NOT_ALLOWED if the I2S port can't play the incoming audio stream.
|
98
|
+
/// ESP_ERR_INVALID_STATE if the I2S port is already locked.
|
99
|
+
/// ESP_ERR_INVALID_ARG if nstalling the driver or setting the data outpin fails due to a parameter error.
|
98
100
|
/// ESP_ERR_NO_MEM if the driver fails to install due to a memory allocation error.
|
99
|
-
/// ESP_FAIL if setting the data out pin fails due to an IO error
|
100
|
-
|
101
|
-
esp_err_t start_i2s_driver_();
|
102
|
-
|
103
|
-
/// @brief Adjusts the I2S driver configuration to match the incoming audio stream.
|
104
|
-
/// Modifies I2S driver's sample rate, bits per sample, and number of channel settings. If the I2S is in secondary
|
105
|
-
/// mode, it only modifies the number of channels.
|
106
|
-
/// @param audio_stream_info Describes the incoming audio stream
|
107
|
-
/// @return ESP_ERR_INVALID_ARG if there is a parameter error, if there is more than 2 channels in the stream, or if
|
108
|
-
/// the audio settings are incompatible with the configuration.
|
109
|
-
/// ESP_ERR_NO_MEM if the driver fails to reconfigure due to a memory allocation error.
|
110
|
-
/// ESP_OK if successful.
|
111
|
-
esp_err_t reconfigure_i2s_stream_info_(audio::AudioStreamInfo &audio_stream_info);
|
101
|
+
/// ESP_FAIL if setting the data out pin fails due to an IO error ESP_OK if successful
|
102
|
+
esp_err_t start_i2s_driver_(audio::AudioStreamInfo &audio_stream_info);
|
112
103
|
|
113
104
|
/// @brief Deletes the speaker's task.
|
114
105
|
/// Deallocates the data_buffer_ and audio_ring_buffer_, if necessary, and deletes the task. Should only be called by
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from esphome import core, pins
|
2
2
|
import esphome.codegen as cg
|
3
|
-
from esphome.components import display,
|
3
|
+
from esphome.components import display, spi
|
4
4
|
from esphome.components.display import validate_rotation
|
5
5
|
import esphome.config_validation as cv
|
6
6
|
from esphome.const import (
|
@@ -147,7 +147,6 @@ def _validate(config):
|
|
147
147
|
|
148
148
|
|
149
149
|
CONFIG_SCHEMA = cv.All(
|
150
|
-
font.validate_pillow_installed,
|
151
150
|
display.FULL_DISPLAY_SCHEMA.extend(
|
152
151
|
{
|
153
152
|
cv.GenerateID(): cv.declare_id(ILI9XXXDisplay),
|
@@ -313,8 +313,9 @@ void ILI9XXXDisplay::draw_pixels_at(int x_start, int y_start, int w, int h, cons
|
|
313
313
|
// do color conversion pixel-by-pixel into the buffer and draw it later. If this is happening the user has not
|
314
314
|
// configured the renderer well.
|
315
315
|
if (this->rotation_ != display::DISPLAY_ROTATION_0_DEGREES || bitness != display::COLOR_BITNESS_565 || !big_endian) {
|
316
|
-
|
317
|
-
|
316
|
+
display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset,
|
317
|
+
x_pad);
|
318
|
+
return;
|
318
319
|
}
|
319
320
|
this->set_addr_window_(x_start, y_start, x_start + w - 1, y_start + h - 1);
|
320
321
|
// x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display.
|
@@ -10,7 +10,6 @@ import puremagic
|
|
10
10
|
|
11
11
|
from esphome import core, external_files
|
12
12
|
import esphome.codegen as cg
|
13
|
-
from esphome.components import font
|
14
13
|
import esphome.config_validation as cv
|
15
14
|
from esphome.const import (
|
16
15
|
CONF_DITHER,
|
@@ -233,7 +232,7 @@ IMAGE_SCHEMA = cv.Schema(
|
|
233
232
|
)
|
234
233
|
)
|
235
234
|
|
236
|
-
CONFIG_SCHEMA =
|
235
|
+
CONFIG_SCHEMA = IMAGE_SCHEMA
|
237
236
|
|
238
237
|
|
239
238
|
def load_svg_image(file: bytes, resize: tuple[int, int]):
|
@@ -47,7 +47,7 @@ void Logger::write_header_(int level, const char *tag, int line) {
|
|
47
47
|
if (current_task == main_task_) {
|
48
48
|
this->printf_to_buffer_("%s[%s][%s:%03u]: ", color, letter, tag, line);
|
49
49
|
} else {
|
50
|
-
const char *thread_name = "";
|
50
|
+
const char *thread_name = ""; // NOLINT(clang-analyzer-deadcode.DeadStores)
|
51
51
|
#if defined(USE_ESP32)
|
52
52
|
thread_name = pcTaskGetName(current_task);
|
53
53
|
#elif defined(USE_LIBRETINY)
|
@@ -23,7 +23,7 @@ bool operator==(const GainTimePair &lhs, const GainTimePair &rhs) {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
bool operator!=(const GainTimePair &lhs, const GainTimePair &rhs) {
|
26
|
-
return
|
26
|
+
return lhs.gain != rhs.gain || lhs.time != rhs.time;
|
27
27
|
}
|
28
28
|
|
29
29
|
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
@@ -8,7 +8,7 @@ import logging
|
|
8
8
|
|
9
9
|
from esphome import codegen as cg, config_validation as cv
|
10
10
|
from esphome.const import CONF_ITEMS
|
11
|
-
from esphome.core import Lambda
|
11
|
+
from esphome.core import ID, Lambda
|
12
12
|
from esphome.cpp_generator import LambdaExpression, MockObj
|
13
13
|
from esphome.cpp_types import uint32
|
14
14
|
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
@@ -72,6 +72,12 @@ class LValidator:
|
|
72
72
|
)
|
73
73
|
if self.retmapper is not None:
|
74
74
|
return self.retmapper(value)
|
75
|
+
if isinstance(value, ID):
|
76
|
+
return await cg.get_variable(value)
|
77
|
+
if isinstance(value, list):
|
78
|
+
value = [
|
79
|
+
await cg.get_variable(x) if isinstance(x, ID) else x for x in value
|
80
|
+
]
|
75
81
|
return cg.safe_exp(value)
|
76
82
|
|
77
83
|
|
@@ -162,6 +168,7 @@ LV_EVENT_MAP = {
|
|
162
168
|
"READY": "READY",
|
163
169
|
"CANCEL": "CANCEL",
|
164
170
|
"ALL_EVENTS": "ALL",
|
171
|
+
"CHANGE": "VALUE_CHANGED",
|
165
172
|
}
|
166
173
|
|
167
174
|
LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Union
|
2
2
|
|
3
3
|
import esphome.codegen as cg
|
4
|
+
from esphome.components import image
|
4
5
|
from esphome.components.color import CONF_HEX, ColorStruct, from_rgbw
|
5
6
|
from esphome.components.font import Font
|
6
7
|
from esphome.components.image import Image_
|
@@ -31,7 +32,7 @@ from .defines import (
|
|
31
32
|
literal,
|
32
33
|
)
|
33
34
|
from .helpers import add_lv_use, esphome_fonts_used, lv_fonts_used, requires_component
|
34
|
-
from .types import lv_font_t, lv_gradient_t
|
35
|
+
from .types import lv_font_t, lv_gradient_t
|
35
36
|
|
36
37
|
opacity_consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
|
37
38
|
|
@@ -332,8 +333,12 @@ def image_validator(value):
|
|
332
333
|
|
333
334
|
lv_image = LValidator(
|
334
335
|
image_validator,
|
335
|
-
|
336
|
-
|
336
|
+
image.Image_.operator("ptr"),
|
337
|
+
requires="image",
|
338
|
+
)
|
339
|
+
lv_image_list = LValidator(
|
340
|
+
cv.ensure_list(image_validator),
|
341
|
+
cg.std_vector.template(image.Image_.operator("ptr")),
|
337
342
|
requires="image",
|
338
343
|
)
|
339
344
|
lv_bool = LValidator(cv.boolean, cg.bool_, retmapper=literal)
|
@@ -279,7 +279,7 @@ std::string LvSelectable::get_selected_text() {
|
|
279
279
|
static std::string join_string(std::vector<std::string> options) {
|
280
280
|
return std::accumulate(
|
281
281
|
options.begin(), options.end(), std::string(),
|
282
|
-
[](const std::string &a, const std::string &b) -> std::string { return a + (a.
|
282
|
+
[](const std::string &a, const std::string &b) -> std::string { return a + (!a.empty() ? "\n" : "") + b; });
|
283
283
|
}
|
284
284
|
|
285
285
|
void LvSelectable::set_selected_text(const std::string &text, lv_anim_enable_t anim) {
|
@@ -60,6 +60,22 @@ inline void lv_disp_set_bg_image(lv_disp_t *disp, esphome::image::Image *image)
|
|
60
60
|
lv_disp_set_bg_image(disp, image->get_lv_img_dsc());
|
61
61
|
}
|
62
62
|
#endif // USE_LVGL_IMAGE
|
63
|
+
#ifdef USE_LVGL_ANIMIMG
|
64
|
+
inline void lv_animimg_set_src(lv_obj_t *img, std::vector<image::Image *> images) {
|
65
|
+
auto *dsc = static_cast<std::vector<lv_img_dsc_t *> *>(lv_obj_get_user_data(img));
|
66
|
+
if (dsc == nullptr) {
|
67
|
+
// object will be lazily allocated but never freed.
|
68
|
+
dsc = new std::vector<lv_img_dsc_t *>(images.size()); // NOLINT
|
69
|
+
lv_obj_set_user_data(img, dsc);
|
70
|
+
}
|
71
|
+
dsc->clear();
|
72
|
+
for (auto &image : images) {
|
73
|
+
dsc->push_back(image->get_lv_img_dsc());
|
74
|
+
}
|
75
|
+
lv_animimg_set_src(img, (const void **) dsc->data(), dsc->size());
|
76
|
+
}
|
77
|
+
|
78
|
+
#endif // USE_LVGL_ANIMIMG
|
63
79
|
|
64
80
|
// Parent class for things that wrap an LVGL object
|
65
81
|
class LvCompound {
|
@@ -1,20 +1,18 @@
|
|
1
1
|
from esphome import automation
|
2
|
-
import esphome.codegen as cg
|
3
2
|
import esphome.config_validation as cv
|
4
3
|
from esphome.const import CONF_DURATION, CONF_ID
|
5
4
|
|
6
5
|
from ..automation import action_to_code
|
7
6
|
from ..defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
|
8
7
|
from ..helpers import lvgl_components_required
|
9
|
-
from ..lv_validation import
|
8
|
+
from ..lv_validation import lv_image_list, lv_milliseconds
|
10
9
|
from ..lvcode import lv
|
11
|
-
from ..types import LvType, ObjUpdateAction
|
10
|
+
from ..types import LvType, ObjUpdateAction
|
12
11
|
from . import Widget, WidgetType, get_widgets
|
13
12
|
from .img import CONF_IMAGE
|
14
13
|
from .label import CONF_LABEL
|
15
14
|
|
16
15
|
CONF_ANIMIMG = "animimg"
|
17
|
-
CONF_SRC_LIST_ID = "src_list_id"
|
18
16
|
|
19
17
|
|
20
18
|
def lv_repeat_count(value):
|
@@ -32,14 +30,14 @@ ANIMIMG_BASE_SCHEMA = cv.Schema(
|
|
32
30
|
ANIMIMG_SCHEMA = ANIMIMG_BASE_SCHEMA.extend(
|
33
31
|
{
|
34
32
|
cv.Required(CONF_DURATION): lv_milliseconds,
|
35
|
-
cv.Required(CONF_SRC):
|
36
|
-
cv.GenerateID(CONF_SRC_LIST_ID): cv.declare_id(void_ptr),
|
33
|
+
cv.Required(CONF_SRC): lv_image_list,
|
37
34
|
}
|
38
35
|
)
|
39
36
|
|
40
37
|
ANIMIMG_MODIFY_SCHEMA = ANIMIMG_BASE_SCHEMA.extend(
|
41
38
|
{
|
42
39
|
cv.Optional(CONF_DURATION): lv_milliseconds,
|
40
|
+
cv.Optional(CONF_SRC): lv_image_list,
|
43
41
|
}
|
44
42
|
)
|
45
43
|
|
@@ -59,17 +57,14 @@ class AnimimgType(WidgetType):
|
|
59
57
|
async def to_code(self, w: Widget, config):
|
60
58
|
lvgl_components_required.add(CONF_IMAGE)
|
61
59
|
lvgl_components_required.add(CONF_ANIMIMG)
|
62
|
-
if
|
63
|
-
srcs =
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
lv.animimg_set_repeat_count(w.obj, config[CONF_REPEAT_COUNT])
|
71
|
-
lv.animimg_set_duration(w.obj, config[CONF_DURATION])
|
72
|
-
if config.get(CONF_AUTO_START):
|
60
|
+
if srcs := config.get(CONF_SRC):
|
61
|
+
srcs = await lv_image_list.process(srcs)
|
62
|
+
lv.animimg_set_src(w.obj, srcs)
|
63
|
+
if repeat_count := config.get(CONF_REPEAT_COUNT):
|
64
|
+
lv.animimg_set_repeat_count(w.obj, repeat_count)
|
65
|
+
if duration := config.get(CONF_DURATION):
|
66
|
+
lv.animimg_set_duration(w.obj, duration)
|
67
|
+
if config[CONF_AUTO_START]:
|
73
68
|
lv.animimg_start(w.obj)
|
74
69
|
|
75
70
|
def get_uses(self):
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import esphome.codegen as cg
|
2
1
|
import esphome.config_validation as cv
|
3
2
|
from esphome.const import CONF_ANGLE, CONF_MODE
|
4
3
|
|
@@ -65,7 +64,6 @@ class ImgType(WidgetType):
|
|
65
64
|
|
66
65
|
async def to_code(self, w: Widget, config):
|
67
66
|
if src := config.get(CONF_SRC):
|
68
|
-
src = await cg.get_variable(src)
|
69
67
|
lv.img_set_src(w.obj, await lv_image.process(src))
|
70
68
|
if (cf_angle := config.get(CONF_ANGLE)) is not None:
|
71
69
|
pivot_x = config[CONF_PIVOT_X]
|
@@ -81,7 +79,7 @@ class ImgType(WidgetType):
|
|
81
79
|
if CONF_ANTIALIAS in config:
|
82
80
|
lv.img_set_antialias(w.obj, config[CONF_ANTIALIAS])
|
83
81
|
if mode := config.get(CONF_MODE):
|
84
|
-
|
82
|
+
await w.set_property("size_mode", mode)
|
85
83
|
|
86
84
|
|
87
85
|
img_spec = ImgType()
|
@@ -1,8 +1,8 @@
|
|
1
|
+
from esphome import automation, pins
|
1
2
|
import esphome.codegen as cg
|
2
|
-
import esphome.config_validation as cv
|
3
|
-
from esphome import pins
|
4
3
|
from esphome.components import key_provider
|
5
|
-
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
from esphome.const import CONF_ID, CONF_ON_KEY, CONF_PIN, CONF_TRIGGER_ID
|
6
6
|
|
7
7
|
CODEOWNERS = ["@ssieb"]
|
8
8
|
|
@@ -14,6 +14,9 @@ matrix_keypad_ns = cg.esphome_ns.namespace("matrix_keypad")
|
|
14
14
|
MatrixKeypad = matrix_keypad_ns.class_(
|
15
15
|
"MatrixKeypad", key_provider.KeyProvider, cg.Component
|
16
16
|
)
|
17
|
+
MatrixKeyTrigger = matrix_keypad_ns.class_(
|
18
|
+
"MatrixKeyTrigger", automation.Trigger.template(cg.uint8)
|
19
|
+
)
|
17
20
|
|
18
21
|
CONF_KEYPAD_ID = "keypad_id"
|
19
22
|
CONF_ROWS = "rows"
|
@@ -47,6 +50,11 @@ CONFIG_SCHEMA = cv.All(
|
|
47
50
|
cv.Optional(CONF_DEBOUNCE_TIME, default=1): cv.int_range(min=1, max=100),
|
48
51
|
cv.Optional(CONF_HAS_DIODES): cv.boolean,
|
49
52
|
cv.Optional(CONF_HAS_PULLDOWNS): cv.boolean,
|
53
|
+
cv.Optional(CONF_ON_KEY): automation.validate_automation(
|
54
|
+
{
|
55
|
+
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MatrixKeyTrigger),
|
56
|
+
}
|
57
|
+
),
|
50
58
|
}
|
51
59
|
),
|
52
60
|
check_keys,
|
@@ -73,3 +81,7 @@ async def to_code(config):
|
|
73
81
|
cg.add(var.set_has_diodes(config[CONF_HAS_DIODES]))
|
74
82
|
if CONF_HAS_PULLDOWNS in config:
|
75
83
|
cg.add(var.set_has_pulldowns(config[CONF_HAS_PULLDOWNS]))
|
84
|
+
for conf in config.get(CONF_ON_KEY, []):
|
85
|
+
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
|
86
|
+
cg.add(var.register_key_trigger(trigger))
|
87
|
+
await automation.build_automation(trigger, [(cg.uint8, "x")], conf)
|
@@ -86,6 +86,8 @@ void MatrixKeypad::loop() {
|
|
86
86
|
if (!this->keys_.empty()) {
|
87
87
|
uint8_t keycode = this->keys_[key];
|
88
88
|
ESP_LOGD(TAG, "key '%c' pressed", keycode);
|
89
|
+
for (auto &trigger : this->key_triggers_)
|
90
|
+
trigger->trigger(keycode);
|
89
91
|
for (auto &listener : this->listeners_)
|
90
92
|
listener->key_pressed(keycode);
|
91
93
|
this->send_key_(keycode);
|
@@ -107,5 +109,7 @@ void MatrixKeypad::dump_config() {
|
|
107
109
|
|
108
110
|
void MatrixKeypad::register_listener(MatrixKeypadListener *listener) { this->listeners_.push_back(listener); }
|
109
111
|
|
112
|
+
void MatrixKeypad::register_key_trigger(MatrixKeyTrigger *trig) { this->key_triggers_.push_back(trig); }
|
113
|
+
|
110
114
|
} // namespace matrix_keypad
|
111
115
|
} // namespace esphome
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "esphome/components/key_provider/key_provider.h"
|
4
|
+
#include "esphome/core/automation.h"
|
4
5
|
#include "esphome/core/component.h"
|
5
6
|
#include "esphome/core/hal.h"
|
6
7
|
#include "esphome/core/helpers.h"
|
@@ -18,6 +19,8 @@ class MatrixKeypadListener {
|
|
18
19
|
virtual void key_released(uint8_t key){};
|
19
20
|
};
|
20
21
|
|
22
|
+
class MatrixKeyTrigger : public Trigger<uint8_t> {};
|
23
|
+
|
21
24
|
class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
22
25
|
public:
|
23
26
|
void setup() override;
|
@@ -31,6 +34,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
|
31
34
|
void set_has_pulldowns(int has_pulldowns) { has_pulldowns_ = has_pulldowns; };
|
32
35
|
|
33
36
|
void register_listener(MatrixKeypadListener *listener);
|
37
|
+
void register_key_trigger(MatrixKeyTrigger *trig);
|
34
38
|
|
35
39
|
protected:
|
36
40
|
std::vector<GPIOPin *> rows_;
|
@@ -42,6 +46,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component {
|
|
42
46
|
int pressed_key_ = -1;
|
43
47
|
|
44
48
|
std::vector<MatrixKeypadListener *> listeners_{};
|
49
|
+
std::vector<MatrixKeyTrigger *> key_triggers_;
|
45
50
|
};
|
46
51
|
|
47
52
|
} // namespace matrix_keypad
|
@@ -106,7 +106,8 @@ void MAX31865Sensor::read_data_() {
|
|
106
106
|
|
107
107
|
// Check faults
|
108
108
|
const uint8_t faults = this->read_register_(FAULT_STATUS_REG);
|
109
|
-
|
109
|
+
has_fault_ = faults & 0b00111100;
|
110
|
+
if (has_fault_) {
|
110
111
|
if (faults & (1 << 2)) {
|
111
112
|
ESP_LOGE(TAG, "Overvoltage/undervoltage fault");
|
112
113
|
}
|
@@ -125,7 +126,8 @@ void MAX31865Sensor::read_data_() {
|
|
125
126
|
} else {
|
126
127
|
this->status_clear_error();
|
127
128
|
}
|
128
|
-
|
129
|
+
has_warn_ = faults & 0b11000000;
|
130
|
+
if (has_warn_) {
|
129
131
|
if (faults & (1 << 6)) {
|
130
132
|
ESP_LOGW(TAG, "RTD Low Threshold");
|
131
133
|
}
|