From 203b8b01bf02c132f660bef95c8eab5bc51766de Mon Sep 17 00:00:00 2001 From: Sergey Dudanov Date: Sat, 18 Jun 2022 09:21:42 +0400 Subject: [PATCH] Media Player: added triggers (#3576) --- esphome/components/media_player/__init__.py | 48 +++++++++++++++++++- esphome/components/media_player/automation.h | 22 +++++++++ tests/test4.yaml | 19 ++++---- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/esphome/components/media_player/__init__.py b/esphome/components/media_player/__init__.py index 877dd693e3..3456417370 100644 --- a/esphome/components/media_player/__init__.py +++ b/esphome/components/media_player/__init__.py @@ -3,7 +3,7 @@ import esphome.config_validation as cv import esphome.codegen as cg from esphome.automation import maybe_simple_id -from esphome.const import CONF_ID +from esphome.const import CONF_ID, CONF_ON_STATE, CONF_TRIGGER_ID from esphome.core import CORE from esphome.coroutine import coroutine_with_priority from esphome.cpp_helpers import setup_entity @@ -39,11 +39,32 @@ VolumeSetAction = media_player_ns.class_( "VolumeSetAction", automation.Action, cg.Parented.template(MediaPlayer) ) + CONF_VOLUME = "volume" +CONF_ON_IDLE = "on_idle" +CONF_ON_PLAY = "on_play" +CONF_ON_PAUSE = "on_pause" + +StateTrigger = media_player_ns.class_("StateTrigger", automation.Trigger.template()) +IdleTrigger = media_player_ns.class_("IdleTrigger", automation.Trigger.template()) +PlayTrigger = media_player_ns.class_("PlayTrigger", automation.Trigger.template()) +PauseTrigger = media_player_ns.class_("PauseTrigger", automation.Trigger.template()) async def setup_media_player_core_(var, config): await setup_entity(var, config) + for conf in config.get(CONF_ON_STATE, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) + for conf in config.get(CONF_ON_IDLE, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) + for conf in config.get(CONF_ON_PLAY, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) + for conf in config.get(CONF_ON_PAUSE, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) async def register_media_player(var, config): @@ -53,7 +74,30 @@ async def register_media_player(var, config): await setup_media_player_core_(var, config) -MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.Schema({})) +MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend( + { + cv.Optional(CONF_ON_STATE): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger), + } + ), + cv.Optional(CONF_ON_IDLE): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(IdleTrigger), + } + ), + cv.Optional(CONF_ON_PLAY): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PlayTrigger), + } + ), + cv.Optional(CONF_ON_PAUSE): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger), + } + ), + } +) MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id({cv.GenerateID(): cv.use_id(MediaPlayer)}) diff --git a/esphome/components/media_player/automation.h b/esphome/components/media_player/automation.h index 4dc324eb9c..c6deba7dc6 100644 --- a/esphome/components/media_player/automation.h +++ b/esphome/components/media_player/automation.h @@ -14,6 +14,17 @@ namespace media_player { } \ }; +#define MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(TRIGGER_CLASS, TRIGGER_STATE) \ + class TRIGGER_CLASS : public Trigger<> { \ + public: \ + TRIGGER_CLASS(MediaPlayer *player) { \ + player->add_on_state_callback([this, player]() { \ + if (player->state == MediaPlayerState::MEDIA_PLAYER_STATE_##TRIGGER_STATE) \ + this->trigger(); \ + }); \ + } \ + }; + MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(PlayAction, PLAY) MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(PauseAction, PAUSE) MEDIA_PLAYER_SIMPLE_COMMAND_ACTION(StopAction, STOP) @@ -26,5 +37,16 @@ template class VolumeSetAction : public Action, public Pa void play(Ts... x) override { this->parent_->make_call().set_volume(this->volume_.value(x...)).perform(); } }; +class StateTrigger : public Trigger<> { + public: + StateTrigger(MediaPlayer *player) { + player->add_on_state_callback([this]() { this->trigger(); }); + } +}; + +MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(IdleTrigger, IDLE) +MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PlayTrigger, PLAYING) +MEDIA_PLAYER_SIMPLE_STATE_TRIGGER(PauseTrigger, PAUSED) + } // namespace media_player } // namespace esphome diff --git a/tests/test4.yaml b/tests/test4.yaml index 6b633fbe9b..c82673b196 100644 --- a/tests/test4.yaml +++ b/tests/test4.yaml @@ -604,14 +604,6 @@ 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 @@ -621,3 +613,14 @@ media_player: i2s_dout_pin: GPIO25 i2s_bclk_pin: GPIO27 mute_pin: GPIO14 + on_state: + - media_player.play: + on_idle: + - media_player.pause: + on_play: + - media_player.stop: + on_pause: + - media_player.toggle: + - media_player.volume_up: + - media_player.volume_down: + - media_player.volume_set: 50%