mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Implement the finish() method and action. implement the is_stopped condition (#7255)
This commit is contained in:
parent
d6f130e35a
commit
cf6ea7cb2c
9 changed files with 77 additions and 15 deletions
|
@ -180,7 +180,11 @@ void I2SAudioSpeaker::player_task(void *params) {
|
|||
}
|
||||
}
|
||||
|
||||
void I2SAudioSpeaker::stop() {
|
||||
void I2SAudioSpeaker::stop() { this->stop_(false); }
|
||||
|
||||
void I2SAudioSpeaker::finish() { this->stop_(true); }
|
||||
|
||||
void I2SAudioSpeaker::stop_(bool wait_on_empty) {
|
||||
if (this->is_failed())
|
||||
return;
|
||||
if (this->state_ == speaker::STATE_STOPPED)
|
||||
|
@ -192,7 +196,11 @@ void I2SAudioSpeaker::stop() {
|
|||
this->state_ = speaker::STATE_STOPPING;
|
||||
DataEvent data;
|
||||
data.stop = true;
|
||||
xQueueSendToFront(this->buffer_queue_, &data, portMAX_DELAY);
|
||||
if (wait_on_empty) {
|
||||
xQueueSend(this->buffer_queue_, &data, portMAX_DELAY);
|
||||
} else {
|
||||
xQueueSendToFront(this->buffer_queue_, &data, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void I2SAudioSpeaker::watch_() {
|
||||
|
|
|
@ -53,6 +53,7 @@ class I2SAudioSpeaker : public Component, public speaker::Speaker, public I2SAud
|
|||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void finish() override;
|
||||
|
||||
size_t play(const uint8_t *data, size_t length) override;
|
||||
|
||||
|
@ -60,6 +61,7 @@ class I2SAudioSpeaker : public Component, public speaker::Speaker, public I2SAud
|
|||
|
||||
protected:
|
||||
void start_();
|
||||
void stop_(bool wait_on_empty);
|
||||
void watch_();
|
||||
|
||||
static void player_task(void *params);
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
from esphome import automation
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
|
||||
from esphome.automation import maybe_simple_id
|
||||
from esphome.const import CONF_ID, CONF_DATA
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_DATA, CONF_ID
|
||||
from esphome.core import CORE
|
||||
from esphome.coroutine import coroutine_with_priority
|
||||
|
||||
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
@ -22,8 +20,12 @@ PlayAction = speaker_ns.class_(
|
|||
StopAction = speaker_ns.class_(
|
||||
"StopAction", automation.Action, cg.Parented.template(Speaker)
|
||||
)
|
||||
FinishAction = speaker_ns.class_(
|
||||
"FinishAction", automation.Action, cg.Parented.template(Speaker)
|
||||
)
|
||||
|
||||
IsPlayingCondition = speaker_ns.class_("IsPlayingCondition", automation.Condition)
|
||||
IsStoppedCondition = speaker_ns.class_("IsStoppedCondition", automation.Condition)
|
||||
|
||||
|
||||
async def setup_speaker_core_(var, config):
|
||||
|
@ -75,11 +77,18 @@ async def speaker_play_action(config, action_id, template_arg, args):
|
|||
automation.register_action("speaker.stop", StopAction, SPEAKER_AUTOMATION_SCHEMA)(
|
||||
speaker_action
|
||||
)
|
||||
automation.register_action("speaker.finish", FinishAction, SPEAKER_AUTOMATION_SCHEMA)(
|
||||
speaker_action
|
||||
)
|
||||
|
||||
automation.register_condition(
|
||||
"speaker.is_playing", IsPlayingCondition, SPEAKER_AUTOMATION_SCHEMA
|
||||
)(speaker_action)
|
||||
|
||||
automation.register_condition(
|
||||
"speaker.is_stopped", IsStoppedCondition, SPEAKER_AUTOMATION_SCHEMA
|
||||
)(speaker_action)
|
||||
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
async def to_code(config):
|
||||
|
|
|
@ -39,10 +39,20 @@ template<typename... Ts> class StopAction : public Action<Ts...>, public Parente
|
|||
void play(Ts... x) override { this->parent_->stop(); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class FinishAction : public Action<Ts...>, public Parented<Speaker> {
|
||||
public:
|
||||
void play(Ts... x) override { this->parent_->finish(); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class IsPlayingCondition : public Condition<Ts...>, public Parented<Speaker> {
|
||||
public:
|
||||
bool check(Ts... x) override { return this->parent_->is_running(); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class IsStoppedCondition : public Condition<Ts...>, public Parented<Speaker> {
|
||||
public:
|
||||
bool check(Ts... x) override { return this->parent_->is_stopped(); }
|
||||
};
|
||||
|
||||
} // namespace speaker
|
||||
} // namespace esphome
|
||||
|
|
|
@ -17,10 +17,15 @@ class Speaker {
|
|||
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
// In compare between *STOP()* and *FINISH()*; *FINISH()* will stop after emptying the play buffer,
|
||||
// while *STOP()* will break directly.
|
||||
// When finish() is not implemented on the plateform component it should just do a normal stop.
|
||||
virtual void finish() { this->stop(); }
|
||||
|
||||
virtual bool has_buffered_data() const = 0;
|
||||
|
||||
bool is_running() const { return this->state_ == STATE_RUNNING; }
|
||||
bool is_stopped() const { return this->state_ == STATE_STOPPED; }
|
||||
|
||||
protected:
|
||||
State state_{STATE_STOPPED};
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- speaker.stop
|
||||
- if:
|
||||
condition: speaker.is_stopped
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- if:
|
||||
condition: speaker.is_playing
|
||||
then:
|
||||
- speaker.finish:
|
||||
- speaker.stop:
|
||||
|
||||
i2s_audio:
|
||||
i2s_lrclk_pin: 16
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- speaker.stop
|
||||
- if:
|
||||
condition: speaker.is_stopped
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- if:
|
||||
condition: speaker.is_playing
|
||||
then:
|
||||
- speaker.finish:
|
||||
- speaker.stop:
|
||||
|
||||
i2s_audio:
|
||||
i2s_lrclk_pin: 6
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- speaker.stop
|
||||
- if:
|
||||
condition: speaker.is_stopped
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- if:
|
||||
condition: speaker.is_playing
|
||||
then:
|
||||
- speaker.finish:
|
||||
- speaker.stop:
|
||||
|
||||
i2s_audio:
|
||||
i2s_lrclk_pin: 6
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- speaker.stop
|
||||
- if:
|
||||
condition: speaker.is_stopped
|
||||
then:
|
||||
- speaker.play: [0, 1, 2, 3]
|
||||
- if:
|
||||
condition: speaker.is_playing
|
||||
then:
|
||||
- speaker.finish:
|
||||
- speaker.stop:
|
||||
|
||||
i2s_audio:
|
||||
i2s_lrclk_pin: 16
|
||||
|
|
Loading…
Reference in a new issue