From ec1fae68830e1416aeeb92392d1c1633d9336159 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 8 Jun 2022 22:46:20 +1200 Subject: [PATCH 01/96] Bump version to 2022.7.0-dev --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index b73d7e33bd..bdf8257024 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2022.6.0-dev" +__version__ = "2022.7.0-dev" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" From c3da42516b67e6dc508bda075d47b308b54f6569 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Wed, 8 Jun 2022 20:27:04 -0700 Subject: [PATCH 02/96] publish fan speed count for discovery (#3537) Co-authored-by: Samuel Sieb --- esphome/components/mqtt/mqtt_fan.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/components/mqtt/mqtt_fan.cpp b/esphome/components/mqtt/mqtt_fan.cpp index 6433ead6b2..32892199fe 100644 --- a/esphome/components/mqtt/mqtt_fan.cpp +++ b/esphome/components/mqtt/mqtt_fan.cpp @@ -114,6 +114,7 @@ void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig if (this->state_->get_traits().supports_speed()) { root[MQTT_PERCENTAGE_COMMAND_TOPIC] = this->get_speed_level_command_topic(); root[MQTT_PERCENTAGE_STATE_TOPIC] = this->get_speed_level_state_topic(); + root[MQTT_SPEED_RANGE_MAX] = this->state_->get_traits().supported_speed_count(); } } bool MQTTFanComponent::publish_state() { From 5abd91d6d512b84bd557ceae1bd56459291f13cf Mon Sep 17 00:00:00 2001 From: Viktor Nagy <126671+nagyv@users.noreply.github.com> Date: Thu, 9 Jun 2022 06:20:05 +0200 Subject: [PATCH 03/96] Nextion brightness setting requires an assignment (#3533) --- esphome/components/nextion/nextion_commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/nextion/nextion_commands.cpp b/esphome/components/nextion/nextion_commands.cpp index f83aafc595..308e02bce8 100644 --- a/esphome/components/nextion/nextion_commands.cpp +++ b/esphome/components/nextion/nextion_commands.cpp @@ -115,7 +115,7 @@ void Nextion::set_backlight_brightness(float brightness) { ESP_LOGD(TAG, "Brightness out of bounds, percentage range 0-1.0"); return; } - this->add_no_result_to_queue_with_set("backlight_brightness", "dim", static_cast(brightness * 100)); + this->add_no_result_to_queue_with_printf_("backlight_brightness", "dim=%d", static_cast(brightness * 100)); } void Nextion::set_auto_wake_on_touch(bool auto_wake) { From 3a9ab50dd28ff72d61118fecb9d0465add778b36 Mon Sep 17 00:00:00 2001 From: RoboMagus <68224306+RoboMagus@users.noreply.github.com> Date: Thu, 9 Jun 2022 06:24:56 +0200 Subject: [PATCH 04/96] Refactor vl53l0x to remove code from header. (#3536) --- esphome/components/vl53l0x/vl53l0x_sensor.cpp | 219 +++++++++++++++++ esphome/components/vl53l0x/vl53l0x_sensor.h | 226 +----------------- 2 files changed, 232 insertions(+), 213 deletions(-) diff --git a/esphome/components/vl53l0x/vl53l0x_sensor.cpp b/esphome/components/vl53l0x/vl53l0x_sensor.cpp index 171484f6f2..f851cf6d73 100644 --- a/esphome/components/vl53l0x/vl53l0x_sensor.cpp +++ b/esphome/components/vl53l0x/vl53l0x_sensor.cpp @@ -257,6 +257,7 @@ void VL53L0XSensor::setup() { ESP_LOGD(TAG, "'%s' - setup END", this->name_.c_str()); } + void VL53L0XSensor::update() { if (this->initiated_read_ || this->waiting_for_interrupt_) { this->publish_state(NAN); @@ -280,6 +281,7 @@ void VL53L0XSensor::update() { this->initiated_read_ = true; // wait for timeout } + void VL53L0XSensor::loop() { if (this->initiated_read_) { if (reg(0x00).get() & 0x01) { @@ -311,5 +313,222 @@ void VL53L0XSensor::loop() { } } +uint32_t VL53L0XSensor::get_measurement_timing_budget_() { + SequenceStepEnables enables{}; + SequenceStepTimeouts timeouts{}; + + uint16_t start_overhead = 1910; + uint16_t end_overhead = 960; + uint16_t msrc_overhead = 660; + uint16_t tcc_overhead = 590; + uint16_t dss_overhead = 690; + uint16_t pre_range_overhead = 660; + uint16_t final_range_overhead = 550; + + // "Start and end overhead times always present" + uint32_t budget_us = start_overhead + end_overhead; + + get_sequence_step_enables_(&enables); + get_sequence_step_timeouts_(&enables, &timeouts); + + if (enables.tcc) + budget_us += (timeouts.msrc_dss_tcc_us + tcc_overhead); + + if (enables.dss) { + budget_us += 2 * (timeouts.msrc_dss_tcc_us + dss_overhead); + } else if (enables.msrc) { + budget_us += (timeouts.msrc_dss_tcc_us + msrc_overhead); + } + + if (enables.pre_range) + budget_us += (timeouts.pre_range_us + pre_range_overhead); + + if (enables.final_range) + budget_us += (timeouts.final_range_us + final_range_overhead); + + measurement_timing_budget_us_ = budget_us; // store for internal reuse + return budget_us; +} + +bool VL53L0XSensor::set_measurement_timing_budget_(uint32_t budget_us) { + SequenceStepEnables enables{}; + SequenceStepTimeouts timeouts{}; + + uint16_t start_overhead = 1320; // note that this is different than the value in get_ + uint16_t end_overhead = 960; + uint16_t msrc_overhead = 660; + uint16_t tcc_overhead = 590; + uint16_t dss_overhead = 690; + uint16_t pre_range_overhead = 660; + uint16_t final_range_overhead = 550; + + uint32_t min_timing_budget = 20000; + + if (budget_us < min_timing_budget) { + return false; + } + + uint32_t used_budget_us = start_overhead + end_overhead; + + get_sequence_step_enables_(&enables); + get_sequence_step_timeouts_(&enables, &timeouts); + + if (enables.tcc) { + used_budget_us += (timeouts.msrc_dss_tcc_us + tcc_overhead); + } + + if (enables.dss) { + used_budget_us += 2 * (timeouts.msrc_dss_tcc_us + dss_overhead); + } else if (enables.msrc) { + used_budget_us += (timeouts.msrc_dss_tcc_us + msrc_overhead); + } + + if (enables.pre_range) { + used_budget_us += (timeouts.pre_range_us + pre_range_overhead); + } + + if (enables.final_range) { + used_budget_us += final_range_overhead; + + // "Note that the final range timeout is determined by the timing + // budget and the sum of all other timeouts within the sequence. + // If there is no room for the final range timeout, then an error + // will be set. Otherwise the remaining time will be applied to + // the final range." + + if (used_budget_us > budget_us) { + // "Requested timeout too big." + return false; + } + + uint32_t final_range_timeout_us = budget_us - used_budget_us; + + // set_sequence_step_timeout() begin + // (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) + + // "For the final range timeout, the pre-range timeout + // must be added. To do this both final and pre-range + // timeouts must be expressed in macro periods MClks + // because they have different vcsel periods." + + uint16_t final_range_timeout_mclks = + timeout_microseconds_to_mclks_(final_range_timeout_us, timeouts.final_range_vcsel_period_pclks); + + if (enables.pre_range) { + final_range_timeout_mclks += timeouts.pre_range_mclks; + } + + write_byte_16(0x71, encode_timeout_(final_range_timeout_mclks)); + + // set_sequence_step_timeout() end + + measurement_timing_budget_us_ = budget_us; // store for internal reuse + } + return true; +} + +void VL53L0XSensor::get_sequence_step_enables_(SequenceStepEnables *enables) { + uint8_t sequence_config = reg(0x01).get(); + enables->tcc = (sequence_config >> 4) & 0x1; + enables->dss = (sequence_config >> 3) & 0x1; + enables->msrc = (sequence_config >> 2) & 0x1; + enables->pre_range = (sequence_config >> 6) & 0x1; + enables->final_range = (sequence_config >> 7) & 0x1; +} + +void VL53L0XSensor::get_sequence_step_timeouts_(SequenceStepEnables const *enables, SequenceStepTimeouts *timeouts) { + timeouts->pre_range_vcsel_period_pclks = get_vcsel_pulse_period_(VCSEL_PERIOD_PRE_RANGE); + + timeouts->msrc_dss_tcc_mclks = reg(0x46).get() + 1; + timeouts->msrc_dss_tcc_us = + timeout_mclks_to_microseconds_(timeouts->msrc_dss_tcc_mclks, timeouts->pre_range_vcsel_period_pclks); + + uint16_t value; + read_byte_16(0x51, &value); + timeouts->pre_range_mclks = decode_timeout_(value); + timeouts->pre_range_us = + timeout_mclks_to_microseconds_(timeouts->pre_range_mclks, timeouts->pre_range_vcsel_period_pclks); + + timeouts->final_range_vcsel_period_pclks = get_vcsel_pulse_period_(VCSEL_PERIOD_FINAL_RANGE); + + read_byte_16(0x71, &value); + timeouts->final_range_mclks = decode_timeout_(value); + + if (enables->pre_range) { + timeouts->final_range_mclks -= timeouts->pre_range_mclks; + } + + timeouts->final_range_us = + timeout_mclks_to_microseconds_(timeouts->final_range_mclks, timeouts->final_range_vcsel_period_pclks); +} + +uint8_t VL53L0XSensor::get_vcsel_pulse_period_(VcselPeriodType type) { + uint8_t vcsel; + if (type == VCSEL_PERIOD_PRE_RANGE) { + vcsel = reg(0x50).get(); + } else if (type == VCSEL_PERIOD_FINAL_RANGE) { + vcsel = reg(0x70).get(); + } else { + return 255; + } + + return (vcsel + 1) << 1; +} + +uint32_t VL53L0XSensor::get_macro_period_(uint8_t vcsel_period_pclks) { + return ((2304UL * vcsel_period_pclks * 1655UL) + 500UL) / 1000UL; +} + +uint32_t VL53L0XSensor::timeout_mclks_to_microseconds_(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks) { + uint32_t macro_period_ns = get_macro_period_(vcsel_period_pclks); + return ((timeout_period_mclks * macro_period_ns) + (macro_period_ns / 2)) / 1000; +} + +uint32_t VL53L0XSensor::timeout_microseconds_to_mclks_(uint32_t timeout_period_us, uint8_t vcsel_period_pclks) { + uint32_t macro_period_ns = get_macro_period_(vcsel_period_pclks); + return (((timeout_period_us * 1000) + (macro_period_ns / 2)) / macro_period_ns); +} + +uint16_t VL53L0XSensor::decode_timeout_(uint16_t reg_val) { + // format: "(LSByte * 2^MSByte) + 1" + uint8_t msb = (reg_val >> 8) & 0xFF; + uint8_t lsb = (reg_val >> 0) & 0xFF; + return (uint16_t(lsb) << msb) + 1; +} + +uint16_t VL53L0XSensor::encode_timeout_(uint16_t timeout_mclks) { + // format: "(LSByte * 2^MSByte) + 1" + uint32_t ls_byte = 0; + uint16_t ms_byte = 0; + + if (timeout_mclks <= 0) + return 0; + + ls_byte = timeout_mclks - 1; + + while ((ls_byte & 0xFFFFFF00) > 0) { + ls_byte >>= 1; + ms_byte++; + } + + return (ms_byte << 8) | (ls_byte & 0xFF); +} + +bool VL53L0XSensor::perform_single_ref_calibration_(uint8_t vhv_init_byte) { + reg(0x00) = 0x01 | vhv_init_byte; // VL53L0X_REG_SYSRANGE_MODE_START_STOP + + uint32_t start = millis(); + while ((reg(0x13).get() & 0x07) == 0) { + if (millis() - start > 1000) + return false; + yield(); + } + + reg(0x0B) = 0x01; + reg(0x00) = 0x00; + + return true; +} + } // namespace vl53l0x } // namespace esphome diff --git a/esphome/components/vl53l0x/vl53l0x_sensor.h b/esphome/components/vl53l0x/vl53l0x_sensor.h index 85b5e3b31d..971fb458bb 100644 --- a/esphome/components/vl53l0x/vl53l0x_sensor.h +++ b/esphome/components/vl53l0x/vl53l0x_sensor.h @@ -21,6 +21,8 @@ struct SequenceStepTimeouts { uint32_t msrc_dss_tcc_us, pre_range_us, final_range_us; }; +enum VcselPeriodType { VCSEL_PERIOD_PRE_RANGE, VCSEL_PERIOD_FINAL_RANGE }; + class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice { public: VL53L0XSensor(); @@ -39,222 +41,20 @@ class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c void set_enable_pin(GPIOPin *enable) { this->enable_pin_ = enable; } protected: - uint32_t get_measurement_timing_budget_() { - SequenceStepEnables enables{}; - SequenceStepTimeouts timeouts{}; + uint32_t get_measurement_timing_budget_(); + bool set_measurement_timing_budget_(uint32_t budget_us); + void get_sequence_step_enables_(SequenceStepEnables *enables); + void get_sequence_step_timeouts_(SequenceStepEnables const *enables, SequenceStepTimeouts *timeouts); + uint8_t get_vcsel_pulse_period_(VcselPeriodType type); + uint32_t get_macro_period_(uint8_t vcsel_period_pclks); - uint16_t start_overhead = 1910; - uint16_t end_overhead = 960; - uint16_t msrc_overhead = 660; - uint16_t tcc_overhead = 590; - uint16_t dss_overhead = 690; - uint16_t pre_range_overhead = 660; - uint16_t final_range_overhead = 550; + uint32_t timeout_mclks_to_microseconds_(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks); + uint32_t timeout_microseconds_to_mclks_(uint32_t timeout_period_us, uint8_t vcsel_period_pclks); - // "Start and end overhead times always present" - uint32_t budget_us = start_overhead + end_overhead; + uint16_t decode_timeout_(uint16_t reg_val); + uint16_t encode_timeout_(uint16_t timeout_mclks); - get_sequence_step_enables_(&enables); - get_sequence_step_timeouts_(&enables, &timeouts); - - if (enables.tcc) - budget_us += (timeouts.msrc_dss_tcc_us + tcc_overhead); - - if (enables.dss) { - budget_us += 2 * (timeouts.msrc_dss_tcc_us + dss_overhead); - } else if (enables.msrc) { - budget_us += (timeouts.msrc_dss_tcc_us + msrc_overhead); - } - - if (enables.pre_range) - budget_us += (timeouts.pre_range_us + pre_range_overhead); - - if (enables.final_range) - budget_us += (timeouts.final_range_us + final_range_overhead); - - measurement_timing_budget_us_ = budget_us; // store for internal reuse - return budget_us; - } - - bool set_measurement_timing_budget_(uint32_t budget_us) { - SequenceStepEnables enables{}; - SequenceStepTimeouts timeouts{}; - - uint16_t start_overhead = 1320; // note that this is different than the value in get_ - uint16_t end_overhead = 960; - uint16_t msrc_overhead = 660; - uint16_t tcc_overhead = 590; - uint16_t dss_overhead = 690; - uint16_t pre_range_overhead = 660; - uint16_t final_range_overhead = 550; - - uint32_t min_timing_budget = 20000; - - if (budget_us < min_timing_budget) { - return false; - } - - uint32_t used_budget_us = start_overhead + end_overhead; - - get_sequence_step_enables_(&enables); - get_sequence_step_timeouts_(&enables, &timeouts); - - if (enables.tcc) { - used_budget_us += (timeouts.msrc_dss_tcc_us + tcc_overhead); - } - - if (enables.dss) { - used_budget_us += 2 * (timeouts.msrc_dss_tcc_us + dss_overhead); - } else if (enables.msrc) { - used_budget_us += (timeouts.msrc_dss_tcc_us + msrc_overhead); - } - - if (enables.pre_range) { - used_budget_us += (timeouts.pre_range_us + pre_range_overhead); - } - - if (enables.final_range) { - used_budget_us += final_range_overhead; - - // "Note that the final range timeout is determined by the timing - // budget and the sum of all other timeouts within the sequence. - // If there is no room for the final range timeout, then an error - // will be set. Otherwise the remaining time will be applied to - // the final range." - - if (used_budget_us > budget_us) { - // "Requested timeout too big." - return false; - } - - uint32_t final_range_timeout_us = budget_us - used_budget_us; - - // set_sequence_step_timeout() begin - // (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) - - // "For the final range timeout, the pre-range timeout - // must be added. To do this both final and pre-range - // timeouts must be expressed in macro periods MClks - // because they have different vcsel periods." - - uint16_t final_range_timeout_mclks = - timeout_microseconds_to_mclks_(final_range_timeout_us, timeouts.final_range_vcsel_period_pclks); - - if (enables.pre_range) { - final_range_timeout_mclks += timeouts.pre_range_mclks; - } - - write_byte_16(0x71, encode_timeout_(final_range_timeout_mclks)); - - // set_sequence_step_timeout() end - - measurement_timing_budget_us_ = budget_us; // store for internal reuse - } - return true; - } - - void get_sequence_step_enables_(SequenceStepEnables *enables) { - uint8_t sequence_config = reg(0x01).get(); - enables->tcc = (sequence_config >> 4) & 0x1; - enables->dss = (sequence_config >> 3) & 0x1; - enables->msrc = (sequence_config >> 2) & 0x1; - enables->pre_range = (sequence_config >> 6) & 0x1; - enables->final_range = (sequence_config >> 7) & 0x1; - } - - enum VcselPeriodType { VCSEL_PERIOD_PRE_RANGE, VCSEL_PERIOD_FINAL_RANGE }; - - void get_sequence_step_timeouts_(SequenceStepEnables const *enables, SequenceStepTimeouts *timeouts) { - timeouts->pre_range_vcsel_period_pclks = get_vcsel_pulse_period_(VCSEL_PERIOD_PRE_RANGE); - - timeouts->msrc_dss_tcc_mclks = reg(0x46).get() + 1; - timeouts->msrc_dss_tcc_us = - timeout_mclks_to_microseconds_(timeouts->msrc_dss_tcc_mclks, timeouts->pre_range_vcsel_period_pclks); - - uint16_t value; - read_byte_16(0x51, &value); - timeouts->pre_range_mclks = decode_timeout_(value); - timeouts->pre_range_us = - timeout_mclks_to_microseconds_(timeouts->pre_range_mclks, timeouts->pre_range_vcsel_period_pclks); - - timeouts->final_range_vcsel_period_pclks = get_vcsel_pulse_period_(VCSEL_PERIOD_FINAL_RANGE); - - read_byte_16(0x71, &value); - timeouts->final_range_mclks = decode_timeout_(value); - - if (enables->pre_range) { - timeouts->final_range_mclks -= timeouts->pre_range_mclks; - } - - timeouts->final_range_us = - timeout_mclks_to_microseconds_(timeouts->final_range_mclks, timeouts->final_range_vcsel_period_pclks); - } - - uint8_t get_vcsel_pulse_period_(VcselPeriodType type) { - uint8_t vcsel; - if (type == VCSEL_PERIOD_PRE_RANGE) { - vcsel = reg(0x50).get(); - } else if (type == VCSEL_PERIOD_FINAL_RANGE) { - vcsel = reg(0x70).get(); - } else { - return 255; - } - - return (vcsel + 1) << 1; - } - - uint32_t get_macro_period_(uint8_t vcsel_period_pclks) { - return ((2304UL * vcsel_period_pclks * 1655UL) + 500UL) / 1000UL; - } - - uint32_t timeout_mclks_to_microseconds_(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks) { - uint32_t macro_period_ns = get_macro_period_(vcsel_period_pclks); - return ((timeout_period_mclks * macro_period_ns) + (macro_period_ns / 2)) / 1000; - } - uint32_t timeout_microseconds_to_mclks_(uint32_t timeout_period_us, uint8_t vcsel_period_pclks) { - uint32_t macro_period_ns = get_macro_period_(vcsel_period_pclks); - return (((timeout_period_us * 1000) + (macro_period_ns / 2)) / macro_period_ns); - } - - uint16_t decode_timeout_(uint16_t reg_val) { - // format: "(LSByte * 2^MSByte) + 1" - uint8_t msb = (reg_val >> 8) & 0xFF; - uint8_t lsb = (reg_val >> 0) & 0xFF; - return (uint16_t(lsb) << msb) + 1; - } - uint16_t encode_timeout_(uint16_t timeout_mclks) { - // format: "(LSByte * 2^MSByte) + 1" - uint32_t ls_byte = 0; - uint16_t ms_byte = 0; - - if (timeout_mclks <= 0) - return 0; - - ls_byte = timeout_mclks - 1; - - while ((ls_byte & 0xFFFFFF00) > 0) { - ls_byte >>= 1; - ms_byte++; - } - - return (ms_byte << 8) | (ls_byte & 0xFF); - } - - bool perform_single_ref_calibration_(uint8_t vhv_init_byte) { - reg(0x00) = 0x01 | vhv_init_byte; // VL53L0X_REG_SYSRANGE_MODE_START_STOP - - uint32_t start = millis(); - while ((reg(0x13).get() & 0x07) == 0) { - if (millis() - start > 1000) - return false; - yield(); - } - - reg(0x0B) = 0x01; - reg(0x00) = 0x00; - - return true; - } + bool perform_single_ref_calibration_(uint8_t vhv_init_byte); float signal_rate_limit_; bool long_range_; From 8998c5f6dd5291c0bfb881dda4068627a51e037a Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 13 Jun 2022 13:28:55 +1200 Subject: [PATCH 05/96] Implement media player volume actions (#3551) --- .../i2s_audio/i2s_audio_media_player.cpp | 16 ++++++++ esphome/components/media_player/__init__.py | 40 +++++++++++++++++-- esphome/components/media_player/automation.h | 35 +++++++--------- .../components/media_player/media_player.h | 4 +- tests/test4.yaml | 8 ++++ 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/esphome/components/i2s_audio/i2s_audio_media_player.cpp b/esphome/components/i2s_audio/i2s_audio_media_player.cpp index 9ddc8419bf..2b624a3917 100644 --- a/esphome/components/i2s_audio/i2s_audio_media_player.cpp +++ b/esphome/components/i2s_audio/i2s_audio_media_player.cpp @@ -51,6 +51,22 @@ void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) { this->state = media_player::MEDIA_PLAYER_STATE_PAUSED; } break; + case media_player::MEDIA_PLAYER_COMMAND_VOLUME_UP: { + float new_volume = this->volume + 0.1f; + if (new_volume > 1.0f) + new_volume = 1.0f; + this->set_volume_(new_volume); + this->unmute_(); + break; + } + case media_player::MEDIA_PLAYER_COMMAND_VOLUME_DOWN: { + float new_volume = this->volume - 0.1f; + if (new_volume < 0.0f) + new_volume = 0.0f; + this->set_volume_(new_volume); + this->unmute_(); + break; + } } } this->publish_state(); diff --git a/esphome/components/media_player/__init__.py b/esphome/components/media_player/__init__.py index 98b93a7ee7..877dd693e3 100644 --- a/esphome/components/media_player/__init__.py +++ b/esphome/components/media_player/__init__.py @@ -29,6 +29,17 @@ PauseAction = media_player_ns.class_( StopAction = media_player_ns.class_( "StopAction", automation.Action, cg.Parented.template(MediaPlayer) ) +VolumeUpAction = media_player_ns.class_( + "VolumeUpAction", automation.Action, cg.Parented.template(MediaPlayer) +) +VolumeDownAction = media_player_ns.class_( + "VolumeDownAction", automation.Action, cg.Parented.template(MediaPlayer) +) +VolumeSetAction = media_player_ns.class_( + "VolumeSetAction", automation.Action, cg.Parented.template(MediaPlayer) +) + +CONF_VOLUME = "volume" async def setup_media_player_core_(var, config): @@ -45,9 +56,7 @@ async def register_media_player(var, config): MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.Schema({})) -MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id( - {cv.Required(CONF_ID): cv.use_id(MediaPlayer)} -) +MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id({cv.GenerateID(): cv.use_id(MediaPlayer)}) @automation.register_action("media_player.play", PlayAction, MEDIA_PLAYER_ACTION_SCHEMA) @@ -58,12 +67,37 @@ MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id( "media_player.pause", PauseAction, MEDIA_PLAYER_ACTION_SCHEMA ) @automation.register_action("media_player.stop", StopAction, MEDIA_PLAYER_ACTION_SCHEMA) +@automation.register_action( + "media_player.volume_up", VolumeUpAction, MEDIA_PLAYER_ACTION_SCHEMA +) +@automation.register_action( + "media_player.volume_down", VolumeDownAction, MEDIA_PLAYER_ACTION_SCHEMA +) async def media_player_action(config, action_id, template_arg, args): var = cg.new_Pvariable(action_id, template_arg) await cg.register_parented(var, config[CONF_ID]) return var +@automation.register_action( + "media_player.volume_set", + VolumeSetAction, + cv.maybe_simple_value( + { + cv.GenerateID(): cv.use_id(MediaPlayer), + cv.Required(CONF_VOLUME): cv.templatable(cv.percentage), + }, + key=CONF_VOLUME, + ), +) +async def media_player_volume_set_action(config, action_id, template_arg, args): + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + volume = await cg.templatable(config[CONF_VOLUME], args, float) + cg.add(var.set_volume(volume)) + return var + + @coroutine_with_priority(100.0) async def to_code(config): cg.add_global(media_player_ns.using) diff --git a/esphome/components/media_player/automation.h b/esphome/components/media_player/automation.h index e2b40d6a00..4dc324eb9c 100644 --- a/esphome/components/media_player/automation.h +++ b/esphome/components/media_player/automation.h @@ -7,28 +7,23 @@ namespace esphome { namespace media_player { -template class PlayAction : public Action, public Parented { - void play(Ts... x) override { - this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_PLAY).perform(); - } -}; +#define MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(ACTION_CLASS, ACTION_COMMAND) \ + template class ACTION_CLASS : public Action, public Parented { \ + void play(Ts... x) override { \ + this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_##ACTION_COMMAND).perform(); \ + } \ + }; -template class ToggleAction : public Action, public Parented { - void play(Ts... x) override { - this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_TOGGLE).perform(); - } -}; +MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(PlayAction, PLAY) +MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(PauseAction, PAUSE) +MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(StopAction, STOP) +MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(ToggleAction, TOGGLE) +MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(VolumeUpAction, VOLUME_UP) +MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(VolumeDownAction, VOLUME_DOWN) -template class PauseAction : public Action, public Parented { - void play(Ts... x) override { - this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_PAUSE).perform(); - } -}; - -template class StopAction : public Action, public Parented { - void play(Ts... x) override { - this->parent_->make_call().set_command(MediaPlayerCommand::MEDIA_PLAYER_COMMAND_STOP).perform(); - } +template class VolumeSetAction : public Action, public Parented { + TEMPLATABLE_VALUE(float, volume) + void play(Ts... x) override { this->parent_->make_call().set_volume(this->volume_.value(x...)).perform(); } }; } // namespace media_player diff --git a/esphome/components/media_player/media_player.h b/esphome/components/media_player/media_player.h index 6a2643b713..88114d5337 100644 --- a/esphome/components/media_player/media_player.h +++ b/esphome/components/media_player/media_player.h @@ -20,7 +20,9 @@ enum MediaPlayerCommand : uint8_t { MEDIA_PLAYER_COMMAND_STOP = 2, MEDIA_PLAYER_COMMAND_MUTE = 3, MEDIA_PLAYER_COMMAND_UNMUTE = 4, - MEDIA_PLAYER_COMMAND_TOGGLE = 5 + MEDIA_PLAYER_COMMAND_TOGGLE = 5, + MEDIA_PLAYER_COMMAND_VOLUME_UP = 6, + MEDIA_PLAYER_COMMAND_VOLUME_DOWN = 7, }; const char *media_player_command_to_string(MediaPlayerCommand command); diff --git a/tests/test4.yaml b/tests/test4.yaml index ce7a87411e..6b633fbe9b 100644 --- a/tests/test4.yaml +++ b/tests/test4.yaml @@ -604,6 +604,14 @@ touchscreen: - logger.log: format: Touch at (%d, %d) args: ["touch.x", "touch.y"] + - media_player.play: + - media_player.pause: + - media_player.stop: + - media_player.toggle: + - media_player.volume_up: + - media_player.volume_down: + - media_player.volume_set: 50% + media_player: - platform: i2s_audio From 0ecf9f4f2f3d89244f0df78ec1ff825469a68fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Tue, 14 Jun 2022 10:36:38 +0200 Subject: [PATCH 06/96] Fix compilation with ESP32-S3 (#3543) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/logger/logger.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/logger/logger.cpp b/esphome/components/logger/logger.cpp index 08c83035b6..c97677c887 100644 --- a/esphome/components/logger/logger.cpp +++ b/esphome/components/logger/logger.cpp @@ -178,7 +178,8 @@ void Logger::pre_setup() { Serial1.setDebugOutput(ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE); #endif break; -#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) +#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2) && \ + !defined(USE_ESP32_VARIANT_ESP32S3) case UART_SELECTION_UART2: this->hw_serial_ = &Serial2; Serial2.begin(this->baud_rate_); From 06440d0202930de8c44cc6197281c19e566a3cd4 Mon Sep 17 00:00:00 2001 From: Martin <25747549+martgras@users.noreply.github.com> Date: Tue, 14 Jun 2022 10:38:09 +0200 Subject: [PATCH 07/96] Bm3xx: Fix typo (#3559) --- esphome/components/bmp3xx/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/bmp3xx/sensor.py b/esphome/components/bmp3xx/sensor.py index 736e6df3d8..f0da1c3c24 100644 --- a/esphome/components/bmp3xx/sensor.py +++ b/esphome/components/bmp3xx/sensor.py @@ -25,7 +25,7 @@ OVERSAMPLING_OPTIONS = { "4X": Oversampling.OVERSAMPLING_X4, "8X": Oversampling.OVERSAMPLING_X8, "16X": Oversampling.OVERSAMPLING_X16, - "32x": Oversampling.OVERSAMPLING_X32, + "32X": Oversampling.OVERSAMPLING_X32, } IIRFilter = bmp3xx_ns.enum("IIRFilter") From 01bfafc5f1defeaacbc1b4bd84d4952553c9bf82 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 17 Jun 2022 13:30:21 +1200 Subject: [PATCH 08/96] Setup the mute pin if configured (#3568) --- esphome/components/i2s_audio/i2s_audio_media_player.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/esphome/components/i2s_audio/i2s_audio_media_player.cpp b/esphome/components/i2s_audio/i2s_audio_media_player.cpp index 2b624a3917..f1f1dc0d51 100644 --- a/esphome/components/i2s_audio/i2s_audio_media_player.cpp +++ b/esphome/components/i2s_audio/i2s_audio_media_player.cpp @@ -109,6 +109,10 @@ void I2SAudioMediaPlayer::setup() { this->audio_ = make_unique