Skip to content

Commit

Permalink
Merge branch 'dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaszduda23 authored May 28, 2023
2 parents 4ced5e3 + 97c1c34 commit 3bae698
Show file tree
Hide file tree
Showing 26 changed files with 480 additions and 24 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ esphome/components/tm1637/* @glmnet
esphome/components/tm1638/* @skykingjwc
esphome/components/tm1651/* @freekode
esphome/components/tmp102/* @timsavage
esphome/components/tmp1075/* @sybrenstuvel
esphome/components/tmp117/* @Azimath
esphome/components/tof10120/* @wstrzalka
esphome/components/toshiba/* @kbx81
Expand Down
2 changes: 2 additions & 0 deletions esphome/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,8 @@ def run_esphome(argv):
_LOGGER.error(e, exc_info=args.verbose)
return 1

safe_print(f"ESPHome {const.__version__}")

for conf_path in args.configuration:
if any(os.path.basename(conf_path) == x for x in SECRETS_FILES):
_LOGGER.warning("Skipping secrets file %s", conf_path)
Expand Down
25 changes: 24 additions & 1 deletion esphome/components/animation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,25 @@
from esphome.components.image import CONF_USE_TRANSPARENCY
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import CONF_FILE, CONF_ID, CONF_RAW_DATA_ID, CONF_RESIZE, CONF_TYPE
from esphome.const import (
CONF_FILE,
CONF_ID,
CONF_RAW_DATA_ID,
CONF_REPEAT,
CONF_RESIZE,
CONF_TYPE,
)
from esphome.core import CORE, HexInt

_LOGGER = logging.getLogger(__name__)

DEPENDENCIES = ["display"]
MULTI_CONF = True

CONF_LOOP = "loop"
CONF_START_FRAME = "start_frame"
CONF_END_FRAME = "end_frame"

Animation_ = display.display_ns.class_("Animation", espImage.Image_)


Expand Down Expand Up @@ -48,6 +59,13 @@ def validate_cross_dependencies(config):
# Not setting default here on purpose; the default depends on the image type,
# and thus will be set in the "validate_cross_dependencies" validator.
cv.Optional(CONF_USE_TRANSPARENCY): cv.boolean,
cv.Optional(CONF_LOOP): cv.All(
{
cv.Optional(CONF_START_FRAME, default=0): cv.positive_int,
cv.Optional(CONF_END_FRAME): cv.positive_int,
cv.Optional(CONF_REPEAT): cv.positive_int,
}
),
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
},
validate_cross_dependencies,
Expand Down Expand Up @@ -227,3 +245,8 @@ async def to_code(config):
espImage.IMAGE_TYPE[config[CONF_TYPE]],
)
cg.add(var.set_transparency(transparent))
if CONF_LOOP in config:
start = config[CONF_LOOP][CONF_START_FRAME]
end = config[CONF_LOOP].get(CONF_END_FRAME, frames)
count = config[CONF_LOOP].get(CONF_REPEAT, -1)
cg.add(var.set_loop(start, end, count))
3 changes: 2 additions & 1 deletion esphome/components/cover/cover.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ class Cover : public EntityBase, public EntityBase_DeviceClass {
/** Stop the cover.
*
* This is a legacy method and may be removed later, please use `.make_call()` instead.
* As per solution from issue #2885 the call should include perform()
*/
ESPDEPRECATED("stop() is deprecated, use make_call().set_command_stop() instead.", "2021.9")
ESPDEPRECATED("stop() is deprecated, use make_call().set_command_stop().perform() instead.", "2021.9")
void stop();

void add_on_state_callback(std::function<void()> &&f);
Expand Down
23 changes: 21 additions & 2 deletions esphome/components/display/display_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,12 +773,31 @@ Color Animation::get_grayscale_pixel(int x, int y) const {
return Color(gray, gray, gray, alpha);
}
Animation::Animation(const uint8_t *data_start, int width, int height, uint32_t animation_frame_count, ImageType type)
: Image(data_start, width, height, type), current_frame_(0), animation_frame_count_(animation_frame_count) {}
int Animation::get_animation_frame_count() const { return this->animation_frame_count_; }
: Image(data_start, width, height, type),
current_frame_(0),
animation_frame_count_(animation_frame_count),
loop_start_frame_(0),
loop_end_frame_(animation_frame_count_),
loop_count_(0),
loop_current_iteration_(1) {}
void Animation::set_loop(uint32_t start_frame, uint32_t end_frame, int count) {
loop_start_frame_ = std::min(start_frame, animation_frame_count_);
loop_end_frame_ = std::min(end_frame, animation_frame_count_);
loop_count_ = count;
loop_current_iteration_ = 1;
}

uint32_t Animation::get_animation_frame_count() const { return this->animation_frame_count_; }
int Animation::get_current_frame() const { return this->current_frame_; }
void Animation::next_frame() {
this->current_frame_++;
if (loop_count_ && this->current_frame_ == loop_end_frame_ &&
(this->loop_current_iteration_ < loop_count_ || loop_count_ < 0)) {
this->current_frame_ = loop_start_frame_;
this->loop_current_iteration_++;
}
if (this->current_frame_ >= animation_frame_count_) {
this->loop_current_iteration_ = 1;
this->current_frame_ = 0;
}
}
Expand Down
10 changes: 8 additions & 2 deletions esphome/components/display/display_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ class Animation : public Image {
Color get_rgb565_pixel(int x, int y) const override;
Color get_grayscale_pixel(int x, int y) const override;

int get_animation_frame_count() const;
uint32_t get_animation_frame_count() const;
int get_current_frame() const override;
void next_frame();
void prev_frame();
Expand All @@ -580,9 +580,15 @@ class Animation : public Image {
*/
void set_frame(int frame);

void set_loop(uint32_t start_frame, uint32_t end_frame, int count);

protected:
int current_frame_;
int animation_frame_count_;
uint32_t animation_frame_count_;
uint32_t loop_start_frame_;
uint32_t loop_end_frame_;
int loop_count_;
int loop_current_iteration_;
};

template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
Expand Down
2 changes: 1 addition & 1 deletion esphome/components/esp32_rmt_led_strip/led_strip.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
light::LightTraits get_traits() override {
auto traits = light::LightTraits();
if (this->is_rgbw_) {
traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::RGB_WHITE});
traits.set_supported_color_modes({light::ColorMode::RGB_WHITE, light::ColorMode::WHITE});
} else {
traits.set_supported_color_modes({light::ColorMode::RGB});
}
Expand Down
4 changes: 4 additions & 0 deletions esphome/components/i2s_audio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

CONF_I2S_DOUT_PIN = "i2s_dout_pin"
CONF_I2S_DIN_PIN = "i2s_din_pin"
CONF_I2S_MCLK_PIN = "i2s_mclk_pin"
CONF_I2S_BCLK_PIN = "i2s_bclk_pin"
CONF_I2S_LRCLK_PIN = "i2s_lrclk_pin"

Expand All @@ -44,6 +45,7 @@
cv.GenerateID(): cv.declare_id(I2SAudioComponent),
cv.Required(CONF_I2S_LRCLK_PIN): pins.internal_gpio_output_pin_number,
cv.Optional(CONF_I2S_BCLK_PIN): pins.internal_gpio_output_pin_number,
cv.Optional(CONF_I2S_MCLK_PIN): pins.internal_gpio_output_pin_number,
}
)

Expand All @@ -69,3 +71,5 @@ async def to_code(config):
cg.add(var.set_lrclk_pin(config[CONF_I2S_LRCLK_PIN]))
if CONF_I2S_BCLK_PIN in config:
cg.add(var.set_bclk_pin(config[CONF_I2S_BCLK_PIN]))
if CONF_I2S_MCLK_PIN in config:
cg.add(var.set_mclk_pin(config[CONF_I2S_MCLK_PIN]))
4 changes: 3 additions & 1 deletion esphome/components/i2s_audio/i2s_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ class I2SAudioComponent : public Component {

i2s_pin_config_t get_pin_config() const {
return {
.mck_io_num = I2S_PIN_NO_CHANGE,
.mck_io_num = this->mclk_pin_,
.bck_io_num = this->bclk_pin_,
.ws_io_num = this->lrclk_pin_,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_PIN_NO_CHANGE,
};
}

void set_mclk_pin(int pin) { this->mclk_pin_ = pin; }
void set_bclk_pin(int pin) { this->bclk_pin_ = pin; }
void set_lrclk_pin(int pin) { this->lrclk_pin_ = pin; }

Expand All @@ -44,6 +45,7 @@ class I2SAudioComponent : public Component {
I2SAudioIn *audio_in_{nullptr};
I2SAudioOut *audio_out_{nullptr};

int mclk_pin_{I2S_PIN_NO_CHANGE};
int bclk_pin_{I2S_PIN_NO_CHANGE};
int lrclk_pin_;
i2s_port_t port_{};
Expand Down
14 changes: 13 additions & 1 deletion esphome/components/i2s_audio/microphone/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
CONF_ADC_PIN = "adc_pin"
CONF_ADC_TYPE = "adc_type"
CONF_PDM = "pdm"
CONF_BITS_PER_SAMPLE = "bits_per_sample"

I2SAudioMicrophone = i2s_audio_ns.class_(
"I2SAudioMicrophone", I2SAudioIn, microphone.Microphone, cg.Component
Expand All @@ -30,10 +31,17 @@
"left": i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_LEFT,
"right": i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_RIGHT,
}
i2s_bits_per_sample_t = cg.global_ns.enum("i2s_bits_per_sample_t")
BITS_PER_SAMPLE = {
16: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_16BIT,
32: i2s_bits_per_sample_t.I2S_BITS_PER_SAMPLE_32BIT,
}

INTERNAL_ADC_VARIANTS = [esp32.const.VARIANT_ESP32]
PDM_VARIANTS = [esp32.const.VARIANT_ESP32, esp32.const.VARIANT_ESP32S3]

_validate_bits = cv.float_with_unit("bits", "bit")


def validate_esp32_variant(config):
variant = esp32.get_esp32_variant()
Expand All @@ -54,6 +62,9 @@ def validate_esp32_variant(config):
cv.GenerateID(): cv.declare_id(I2SAudioMicrophone),
cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
cv.Optional(CONF_CHANNEL, default="right"): cv.enum(CHANNELS),
cv.Optional(CONF_BITS_PER_SAMPLE, default="16bit"): cv.All(
_validate_bits, cv.enum(BITS_PER_SAMPLE)
),
}
).extend(cv.COMPONENT_SCHEMA)

Expand Down Expand Up @@ -93,6 +104,7 @@ async def to_code(config):
cg.add(var.set_din_pin(config[CONF_I2S_DIN_PIN]))
cg.add(var.set_pdm(config[CONF_PDM]))

cg.add(var.set_channel(CHANNELS[config[CONF_CHANNEL]]))
cg.add(var.set_channel(config[CONF_CHANNEL]))
cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))

await microphone.register_microphone(var, config)
35 changes: 30 additions & 5 deletions esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ static const char *const TAG = "i2s_audio.microphone";

void I2SAudioMicrophone::setup() {
ESP_LOGCONFIG(TAG, "Setting up I2S Audio Microphone...");
this->buffer_.resize(BUFFER_SIZE);
ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
this->buffer_ = allocator.allocate(BUFFER_SIZE);
if (this->buffer_ == nullptr) {
ESP_LOGE(TAG, "Failed to allocate buffer!");
this->mark_failed();
return;
}

#if SOC_I2S_SUPPORTS_ADC
if (this->adc_) {
Expand Down Expand Up @@ -48,7 +54,7 @@ void I2SAudioMicrophone::start_() {
i2s_driver_config_t config = {
.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.bits_per_sample = this->bits_per_sample_,
.channel_format = this->channel_,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
Expand Down Expand Up @@ -107,16 +113,35 @@ void I2SAudioMicrophone::stop_() {
void I2SAudioMicrophone::read_() {
size_t bytes_read = 0;
esp_err_t err =
i2s_read(this->parent_->get_port(), this->buffer_.data(), BUFFER_SIZE, &bytes_read, (100 / portTICK_PERIOD_MS));
i2s_read(this->parent_->get_port(), this->buffer_, BUFFER_SIZE, &bytes_read, (100 / portTICK_PERIOD_MS));
if (err != ESP_OK) {
ESP_LOGW(TAG, "Error reading from I2S microphone: %s", esp_err_to_name(err));
this->status_set_warning();
return;
}

this->status_clear_warning();

this->data_callbacks_.call(this->buffer_);
std::vector<int16_t> samples;
size_t samples_read = 0;
if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_16BIT) {
samples_read = bytes_read / sizeof(int16_t);
} else if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_32BIT) {
samples_read = bytes_read / sizeof(int32_t);
} else {
ESP_LOGE(TAG, "Unsupported bits per sample: %d", this->bits_per_sample_);
return;
}
samples.resize(samples_read);
if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_16BIT) {
memcpy(samples.data(), this->buffer_, bytes_read);
} else if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_32BIT) {
for (size_t i = 0; i < samples_read; i++) {
int32_t temp = reinterpret_cast<int32_t *>(this->buffer_)[i] >> 14;
samples[i] = clamp<int16_t>(temp, INT16_MIN, INT16_MAX);
}
}

this->data_callbacks_.call(samples);
}

void I2SAudioMicrophone::loop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
#endif

void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }
void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }

protected:
void start_();
Expand All @@ -41,8 +42,9 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
bool adc_{false};
#endif
bool pdm_{false};
std::vector<uint8_t> buffer_;
uint8_t *buffer_;
i2s_channel_fmt_t channel_;
i2s_bits_per_sample_t bits_per_sample_;

HighFrequencyLoopRequester high_freq_;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ void InternalTemperatureSensor::update() {
temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT();
temp_sensor_set_config(tsens);
temp_sensor_start();
#if defined(USE_ESP32_VARIANT_ESP32S3) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 3))
#error \
"ESP32-S3 internal temperature sensor requires ESP IDF V4.4.3 or higher. See https://github.com/esphome/issues/issues/4271"
#endif
esp_err_t result = temp_sensor_read_celsius(&temperature);
temp_sensor_stop();
success = (result == ESP_OK);
Expand Down
28 changes: 28 additions & 0 deletions esphome/components/internal_temperature/sensor.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,45 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
from esphome.components.esp32 import get_esp32_variant
from esphome.components.esp32.const import (
VARIANT_ESP32S3,
)
from esphome.const import (
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
DEVICE_CLASS_TEMPERATURE,
ENTITY_CATEGORY_DIAGNOSTIC,
KEY_CORE,
KEY_FRAMEWORK_VERSION,
)
from esphome.core import CORE

internal_temperature_ns = cg.esphome_ns.namespace("internal_temperature")
InternalTemperatureSensor = internal_temperature_ns.class_(
"InternalTemperatureSensor", sensor.Sensor, cg.PollingComponent
)


def validate_config(config):
if CORE.is_esp32:
variant = get_esp32_variant()
if variant == VARIANT_ESP32S3:
if CORE.using_arduino and CORE.data[KEY_CORE][
KEY_FRAMEWORK_VERSION
] < cv.Version(2, 0, 6):
raise cv.Invalid(
"ESP32-S3 Internal Temperature Sensor requires framework version 2.0.6 or higher. See <https://github.com/esphome/issues/issues/4271>."
)
if CORE.using_esp_idf and CORE.data[KEY_CORE][
KEY_FRAMEWORK_VERSION
] < cv.Version(4, 4, 3):
raise cv.Invalid(
"ESP32-S3 Internal Temperature Sensor requires framework version 4.4.3 or higher. See <https://github.com/esphome/issues/issues/4271>."
)
return config


CONFIG_SCHEMA = cv.All(
sensor.sensor_schema(
InternalTemperatureSensor,
Expand All @@ -23,6 +50,7 @@
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
).extend(cv.polling_component_schema("60s")),
cv.only_on(["esp32", "rp2040"]),
validate_config,
)


Expand Down
2 changes: 1 addition & 1 deletion esphome/components/microphone/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async def setup_microphone_core_(var, config):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(
trigger,
[(cg.std_vector.template(cg.uint8).operator("ref").operator("const"), "x")],
[(cg.std_vector.template(cg.int16).operator("ref").operator("const"), "x")],
conf,
)

Expand Down
Loading

0 comments on commit 3bae698

Please sign in to comment.