1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-15 17:38:15 +00:00

Merge pull request #8251 from esphome/bump-2025.2.0b3

2025.2.0b3
This commit is contained in:
Jesse Hills 2025-02-14 16:43:58 +13:00 committed by GitHub
commit 6e45a7c9af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 78 additions and 33 deletions

View File

@ -7,13 +7,16 @@
#ifdef USE_ARDUINO
#include <esp32-hal-dac.h>
#endif
#ifdef USE_ESP_IDF
#include <driver/dac.h>
#endif
namespace esphome {
namespace esp32_dac {
#ifdef USE_ESP32_VARIANT_ESP32S2
static constexpr uint8_t DAC0_PIN = 17;
#else
static constexpr uint8_t DAC0_PIN = 25;
#endif
static const char *const TAG = "esp32_dac";
void ESP32DAC::setup() {
@ -22,8 +25,15 @@ void ESP32DAC::setup() {
this->turn_off();
#ifdef USE_ESP_IDF
auto channel = pin_->get_pin() == 25 ? DAC_CHANNEL_1 : DAC_CHANNEL_2;
dac_output_enable(channel);
const dac_channel_t channel = this->pin_->get_pin() == DAC0_PIN ? DAC_CHAN_0 : DAC_CHAN_1;
const dac_oneshot_config_t oneshot_cfg{channel};
dac_oneshot_new_channel(&oneshot_cfg, &this->dac_handle_);
#endif
}
void ESP32DAC::on_safe_shutdown() {
#ifdef USE_ESP_IDF
dac_oneshot_del_channel(this->dac_handle_);
#endif
}
@ -40,8 +50,7 @@ void ESP32DAC::write_state(float state) {
state = state * 255;
#ifdef USE_ESP_IDF
auto channel = pin_->get_pin() == 25 ? DAC_CHANNEL_1 : DAC_CHANNEL_2;
dac_output_voltage(channel, (uint8_t) state);
dac_oneshot_output_voltage(this->dac_handle_, state);
#endif
#ifdef USE_ARDUINO
dacWrite(this->pin_->get_pin(), state);

View File

@ -7,6 +7,10 @@
#ifdef USE_ESP32
#ifdef USE_ESP_IDF
#include <driver/dac_oneshot.h>
#endif
namespace esphome {
namespace esp32_dac {
@ -16,6 +20,7 @@ class ESP32DAC : public output::FloatOutput, public Component {
/// Initialize pin
void setup() override;
void on_safe_shutdown() override;
void dump_config() override;
/// HARDWARE setup_priority
float get_setup_priority() const override { return setup_priority::HARDWARE; }
@ -24,6 +29,9 @@ class ESP32DAC : public output::FloatOutput, public Component {
void write_state(float state) override;
InternalGPIOPin *pin_;
#ifdef USE_ESP_IDF
dac_oneshot_handle_t dac_handle_;
#endif
};
} // namespace esp32_dac

View File

@ -1,15 +1,27 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import output
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.components.esp32 import get_esp32_variant
from esphome.components.esp32.const import VARIANT_ESP32, VARIANT_ESP32S2
from esphome.const import CONF_ID, CONF_NUMBER, CONF_PIN
DEPENDENCIES = ["esp32"]
DAC_PINS = {
VARIANT_ESP32: (25, 26),
VARIANT_ESP32S2: (17, 18),
}
def valid_dac_pin(value):
num = value[CONF_NUMBER]
cv.one_of(25, 26)(num)
variant = get_esp32_variant()
try:
valid_pins = DAC_PINS[variant]
except KeyError as ex:
raise cv.Invalid(f"DAC is not supported on {variant}") from ex
given_pin = value[CONF_NUMBER]
cv.one_of(*valid_pins)(given_pin)
return value

View File

@ -247,8 +247,8 @@ async def to_code(config):
)
cg.add(log.pre_setup())
for tag, level in config[CONF_LOGS].items():
cg.add(log.set_log_level(tag, LOG_LEVELS[level]))
for tag, log_level in config[CONF_LOGS].items():
cg.add(log.set_log_level(tag, LOG_LEVELS[log_level]))
cg.add_define("USE_LOGGER")
this_severity = LOG_LEVEL_SEVERITY.index(level)

View File

@ -102,9 +102,6 @@ void Logger::log_vprintf_(int level, const char *tag, int line, const __FlashStr
#endif
int HOT Logger::level_for(const char *tag) {
// Uses std::vector<> for low memory footprint, though the vector
// could be sorted to minimize lookup times. This feature isn't used that
// much anyway so it doesn't matter too much.
if (this->log_levels_.count(tag) != 0)
return this->log_levels_[tag];
return this->current_level_;

View File

@ -9,10 +9,10 @@ namespace online_image {
static const char *const TAG = "online_image.decoder";
bool ImageDecoder::set_size(int width, int height) {
bool resized = this->image_->resize_(width, height);
bool success = this->image_->resize_(width, height) > 0;
this->x_scale_ = static_cast<double>(this->image_->buffer_width_) / width;
this->y_scale_ = static_cast<double>(this->image_->buffer_height_) / height;
return resized;
return success;
}
void ImageDecoder::draw(int x, int y, int w, int h, const Color &color) {
@ -51,8 +51,9 @@ size_t DownloadBuffer::read(size_t len) {
}
size_t DownloadBuffer::resize(size_t size) {
if (this->size_ == size) {
return size;
if (this->size_ >= size) {
// Avoid useless reallocations; if the buffer is big enough, don't reallocate.
return this->size_;
}
this->allocator_.deallocate(this->buffer_, this->size_);
this->buffer_ = this->allocator_.allocate(size);
@ -61,6 +62,8 @@ size_t DownloadBuffer::resize(size_t size) {
this->size_ = size;
return size;
} else {
ESP_LOGE(TAG, "allocation of %zu bytes failed. Biggest block in heap: %zu Bytes", size,
this->allocator_.get_max_free_block_size());
this->size_ = 0;
return 0;
}

View File

@ -58,7 +58,7 @@ int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) {
}
if (!this->jpeg_.openRAM(buffer, size, draw_callback)) {
ESP_LOGE(TAG, "Could not open image for decoding.");
ESP_LOGE(TAG, "Could not open image for decoding: %d", this->jpeg_.getLastError());
return DECODE_ERROR_INVALID_TYPE;
}
auto jpeg_type = this->jpeg_.getJPEGType();
@ -73,7 +73,9 @@ int HOT JpegDecoder::decode(uint8_t *buffer, size_t size) {
this->jpeg_.setUserPointer(this);
this->jpeg_.setPixelType(RGB8888);
this->set_size(this->jpeg_.getWidth(), this->jpeg_.getHeight());
if (!this->set_size(this->jpeg_.getWidth(), this->jpeg_.getHeight())) {
return DECODE_ERROR_OUT_OF_MEMORY;
}
if (!this->jpeg_.decode(0, 0, 0)) {
ESP_LOGE(TAG, "Error while decoding.");
this->jpeg_.close();

View File

@ -64,33 +64,34 @@ void OnlineImage::release() {
}
}
bool OnlineImage::resize_(int width_in, int height_in) {
size_t OnlineImage::resize_(int width_in, int height_in) {
int width = this->fixed_width_;
int height = this->fixed_height_;
if (this->auto_resize_()) {
if (this->is_auto_resize_()) {
width = width_in;
height = height_in;
if (this->width_ != width && this->height_ != height) {
this->release();
}
}
if (this->buffer_) {
return false;
}
size_t new_size = this->get_buffer_size_(width, height);
if (this->buffer_) {
// Buffer already allocated => no need to resize
return new_size;
}
ESP_LOGD(TAG, "Allocating new buffer of %zu bytes", new_size);
this->buffer_ = this->allocator_.allocate(new_size);
if (this->buffer_ == nullptr) {
ESP_LOGE(TAG, "allocation of %zu bytes failed. Biggest block in heap: %zu Bytes", new_size,
this->allocator_.get_max_free_block_size());
this->end_connection_();
return false;
return 0;
}
this->buffer_width_ = width;
this->buffer_height_ = height;
this->width_ = width;
ESP_LOGV(TAG, "New size: (%d, %d)", width, height);
return true;
return new_size;
}
void OnlineImage::update() {

View File

@ -99,9 +99,22 @@ class OnlineImage : public PollingComponent,
int get_position_(int x, int y) const { return (x + y * this->buffer_width_) * this->get_bpp() / 8; }
ESPHOME_ALWAYS_INLINE bool auto_resize_() const { return this->fixed_width_ == 0 || this->fixed_height_ == 0; }
ESPHOME_ALWAYS_INLINE bool is_auto_resize_() const { return this->fixed_width_ == 0 || this->fixed_height_ == 0; }
bool resize_(int width, int height);
/**
* @brief Resize the image buffer to the requested dimensions.
*
* The buffer will be allocated if not existing.
* If the dimensions have been fixed in the yaml config, the buffer will be created
* with those dimensions and not resized, even on request.
* Otherwise, the old buffer will be deallocated and a new buffer with the requested
* allocated
*
* @param width
* @param height
* @return 0 if no memory could be allocated, the size of the new buffer otherwise.
*/
size_t resize_(int width, int height);
/**
* @brief Draw a pixel into the buffer.

View File

@ -1,6 +1,6 @@
"""Constants used by esphome."""
__version__ = "2025.2.0b2"
__version__ = "2025.2.0b3"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
VALID_SUBSTITUTIONS_CHARACTERS = (

View File

@ -853,7 +853,7 @@ class InfoRequestHandler(BaseHandler):
dashboard = DASHBOARD
entry = dashboard.entries.get(yaml_path)
if not entry:
if not entry or entry.storage is None:
self.set_status(404)
return