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] 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