Fit this lamp: 4 alarms, full data model, knock snooze, server use
Decode DP127 as 48 bytes (4 alarms), plus DP128, DP107 and DP126, from Tuya's data model. Add day switches, alarm and sunset controls, a knock sensor on PA18, display schedule, bedtime fade, radio timer and grouped web UI. Pin LibreTiny v1.14.0 for the OTA restart fix. Ship the patched UART as an external component so a server needs only a short YAML. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3e3358af08
commit
a8f6bb3ca5
36 files changed
+5132
-214
No files matched your search
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <driver/uart.h>
|
||||
#include "esphome/core/component.h"
|
||||
#include "uart_component.h"
|
||||
#ifdef USE_UART_WAKE_LOOP_ON_RX
|
||||
#include <driver/uart_select.h>
|
||||
#endif
|
||||
|
||||
namespace esphome::uart {
|
||||
|
||||
/// ESP-IDF UART driver wrapper.
|
||||
///
|
||||
/// Thread safety: All public methods must only be called from the main loop.
|
||||
/// The ESP-IDF UART driver API does not guarantee thread safety, and ESPHome's
|
||||
/// peek byte state (has_peek_/peek_byte_) is not synchronized.
|
||||
class IDFUARTComponent final : public UARTComponent, public Component {
|
||||
public:
|
||||
// User provided, not "= default": `new(p) IDFUARTComponent()` would zero-fill .bss that is already zero.
|
||||
IDFUARTComponent() {}
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
float get_setup_priority() const override { return setup_priority::BUS; }
|
||||
|
||||
void set_rx_full_threshold(size_t rx_full_threshold) override;
|
||||
void set_rx_timeout(size_t rx_timeout) override;
|
||||
|
||||
void write_array(const uint8_t *data, size_t len) override;
|
||||
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
|
||||
size_t available() override;
|
||||
size_t available_for_write() override;
|
||||
UARTFlushResult flush() override;
|
||||
|
||||
void set_flush_timeout(uint32_t flush_timeout_ms) override { this->flush_timeout_ms_ = flush_timeout_ms; }
|
||||
|
||||
/// TX ring buffer size for the driver; 0 leaves TX unbuffered so write_array() blocks until
|
||||
/// the FIFO has taken everything.
|
||||
void set_tx_buffer_size(size_t tx_buffer_size) { this->tx_buffer_size_ = tx_buffer_size; }
|
||||
|
||||
void set_clock_source(uart_sclk_t clock_source) { this->clock_source_ = static_cast<uint8_t>(clock_source); }
|
||||
|
||||
uint8_t get_hw_serial_number() { return this->uart_num_; }
|
||||
|
||||
/// Discard everything received so far: the peek cache and the driver's RX buffer.
|
||||
void flush_input() {
|
||||
this->has_peek_ = false;
|
||||
uart_flush_input(this->uart_num_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the UART with the current settings.
|
||||
* @param dump_config (Optional, default `true`): True for displaying new settings or
|
||||
* false to change it quitely
|
||||
*
|
||||
* Example:
|
||||
* ```cpp
|
||||
* id(uart1).load_settings();
|
||||
* ```
|
||||
*
|
||||
* This will load the current UART interface with the latest settings (baud_rate, parity, etc).
|
||||
*/
|
||||
void load_settings(bool dump_config) override;
|
||||
using UARTComponent::load_settings; // also bring in the no-arg overload for convenience
|
||||
|
||||
/**
|
||||
* Apply the current framing (baud rate, parity, data/stop bits) to the installed
|
||||
* driver in place, without the delete/reinstall of load_settings(). Tasks blocked in
|
||||
* the driver survive and the ring buffers are kept, but both hardware FIFOs are
|
||||
* flushed: a frame in flight reaches the peer truncated and bytes not yet out of the
|
||||
* RX FIFO are dropped. No lock is taken: quiesce writers first if that matters.
|
||||
* rx_full_threshold is not rescaled (call set_rx_full_threshold_ms() first if it
|
||||
* should follow the baud rate); a rollback restores the value from the last accepted
|
||||
* configuration, undoing a standalone set_rx_full_threshold() made since. Without an
|
||||
* installed driver this is a full load_settings(false) instead.
|
||||
*
|
||||
* @return ESP_OK once the new framing is live (a line-setting error after that only
|
||||
* logs). On rejection (unreachable baud rate) the previous framing is restored and
|
||||
* the driver's error returned; if the restore fails too the component is marked
|
||||
* failed. ESP_ERR_INVALID_STATE if already failed; ESP_FAIL if the fallback
|
||||
* load_settings() fails.
|
||||
*/
|
||||
esp_err_t apply_settings_live();
|
||||
|
||||
void on_shutdown() override;
|
||||
|
||||
protected:
|
||||
void check_logger_conflict() override;
|
||||
uint32_t line_inversion_mask_();
|
||||
// Re-applies what uart_param_config() resets: inversion, RX threshold/timeout, mode.
|
||||
esp_err_t apply_line_settings_();
|
||||
uart_port_t uart_num_{UART_NUM_MAX};
|
||||
uart_config_t get_config_();
|
||||
|
||||
struct Framing {
|
||||
uint32_t baud_rate;
|
||||
uint8_t data_bits;
|
||||
uint8_t stop_bits;
|
||||
UARTParityOptions parity;
|
||||
size_t rx_full_threshold; // sized for the baud rate, so rolled back with it
|
||||
};
|
||||
Framing framing_() const {
|
||||
return {this->baud_rate_, this->data_bits_, this->stop_bits_, this->parity_, this->rx_full_threshold_};
|
||||
}
|
||||
void set_framing_(const Framing &framing);
|
||||
// Last framing the driver accepted; baud_rate 0 means none yet.
|
||||
Framing last_good_framing_{};
|
||||
|
||||
bool has_peek_{false};
|
||||
uint8_t peek_byte_{0};
|
||||
uint8_t clock_source_{UART_SCLK_DEFAULT}; ///< uart_sclk_t stored in a byte; the IDF values are all small.
|
||||
uint32_t flush_timeout_ms_{0}; ///< 0 means wait indefinitely (portMAX_DELAY).
|
||||
size_t tx_buffer_size_{0};
|
||||
|
||||
#ifdef USE_UART_WAKE_LOOP_ON_RX
|
||||
// ISR callback for UART RX data notification — wakes the main loop directly.
|
||||
static void uart_rx_isr_callback(uart_port_t uart_num, uart_select_notif_t uart_select_notif, BaseType_t *task_woken);
|
||||
#endif // USE_UART_WAKE_LOOP_ON_RX
|
||||
};
|
||||
|
||||
} // namespace esphome::uart
|
||||
#endif // USE_ESP32
|
||||
Reference in new issue
Block a user