diff --git a/esphome/components/dfplayer/__init__.py b/esphome/components/dfplayer/__init__.py index bb18e6ba8c..afe8c72675 100644 --- a/esphome/components/dfplayer/__init__.py +++ b/esphome/components/dfplayer/__init__.py @@ -1,3 +1,5 @@ +from typing import Any + from esphome import automation import esphome.codegen as cg from esphome.components import uart @@ -16,6 +18,7 @@ DFPlayerIsPlayingCondition = dfplayer_ns.class_( MULTI_CONF = True CONF_FOLDER = "folder" +CONF_ENABLE = "enable" CONF_EQ_PRESET = "eq_preset" CONF_ON_FINISHED_PLAYBACK = "on_finished_playback" @@ -375,6 +378,32 @@ async def dfplayer_random_to_code(config, action_id, template_arg, args): return var +def _default_enable(value: Any) -> Any: + """Fill in ``enable: true`` for a bare action or a mapping that only picks the player. + + Done before ``maybe_simple_value`` so neither form is wrapped as the ``enable`` value. + """ + if value is None or isinstance(value, dict): + return {CONF_ENABLE: True, **(value or {})} + return value + + +automation.register_apply_action( + "dfplayer.set_current_track_repeat", + cv.All( + _default_enable, + cv.maybe_simple_value( + { + cv.GenerateID(): cv.use_id(DFPlayer), + cv.Optional(CONF_ENABLE, default=True): cv.templatable(cv.boolean), + }, + key=CONF_ENABLE, + ), + ), + automation.ApplyField(CONF_ENABLE, "set_current_track_repeat", cg.bool_), +) + + @automation.register_condition( "dfplayer.is_playing", DFPlayerIsPlayingCondition, diff --git a/esphome/components/dfplayer/dfplayer.cpp b/esphome/components/dfplayer/dfplayer.cpp index f81d1cd1b6..1195f595c8 100644 --- a/esphome/components/dfplayer/dfplayer.cpp +++ b/esphome/components/dfplayer/dfplayer.cpp @@ -102,6 +102,13 @@ void DFPlayer::random() { this->send_cmd_(0x18); } +void DFPlayer::set_current_track_repeat(bool enable) { + uint16_t arg = enable ? 0x00 : 0x01; + ESP_LOGD(TAG, "Setting current track repeat to %s", + enable ? LOG_STR_LITERAL("enabled") : LOG_STR_LITERAL("disabled")); + this->send_cmd_(0x19, arg); +} + void DFPlayer::play_folder(uint16_t folder, uint16_t file) { ESP_LOGD(TAG, "Playing file %d in folder %d", file, folder); if (folder < 100 && file < 256) { diff --git a/esphome/components/dfplayer/dfplayer.h b/esphome/components/dfplayer/dfplayer.h index 1db6b394c5..66cf929408 100644 --- a/esphome/components/dfplayer/dfplayer.h +++ b/esphome/components/dfplayer/dfplayer.h @@ -46,6 +46,7 @@ class DFPlayer final : public uart::UARTDevice, public Component { void pause(); void stop(); void random(); + void set_current_track_repeat(bool enable); bool is_playing() { return is_playing_; } void dump_config() override; diff --git a/tests/components/dfplayer/common.yaml b/tests/components/dfplayer/common.yaml index 5d2540c275..940f07a2ed 100644 --- a/tests/components/dfplayer/common.yaml +++ b/tests/components/dfplayer/common.yaml @@ -25,8 +25,17 @@ esphome: - dfplayer.volume_up - dfplayer.volume_down - dfplayer.sleep + - dfplayer.set_current_track_repeat + - dfplayer.set_current_track_repeat: true + - dfplayer.set_current_track_repeat: + enable: false + - dfplayer.set_current_track_repeat: + enable: !lambda return true; + - dfplayer.set_current_track_repeat: + id: dfplayer_test dfplayer: + id: dfplayer_test on_finished_playback: then: if: