mirror of
https://github.com/esphome/esphome.git
synced 2024-11-12 18:27:46 +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())
|
if (this->is_failed())
|
||||||
return;
|
return;
|
||||||
if (this->state_ == speaker::STATE_STOPPED)
|
if (this->state_ == speaker::STATE_STOPPED)
|
||||||
|
@ -192,7 +196,11 @@ void I2SAudioSpeaker::stop() {
|
||||||
this->state_ = speaker::STATE_STOPPING;
|
this->state_ = speaker::STATE_STOPPING;
|
||||||
DataEvent data;
|
DataEvent data;
|
||||||
data.stop = true;
|
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_() {
|
void I2SAudioSpeaker::watch_() {
|
||||||
|
|
|
@ -53,6 +53,7 @@ class I2SAudioSpeaker : public Component, public speaker::Speaker, public I2SAud
|
||||||
|
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
void finish() override;
|
||||||
|
|
||||||
size_t play(const uint8_t *data, size_t length) 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:
|
protected:
|
||||||
void start_();
|
void start_();
|
||||||
|
void stop_(bool wait_on_empty);
|
||||||
void watch_();
|
void watch_();
|
||||||
|
|
||||||
static void player_task(void *params);
|
static void player_task(void *params);
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.codegen as cg
|
|
||||||
|
|
||||||
from esphome.automation import maybe_simple_id
|
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.core import CORE
|
||||||
from esphome.coroutine import coroutine_with_priority
|
from esphome.coroutine import coroutine_with_priority
|
||||||
|
|
||||||
|
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
@ -22,8 +20,12 @@ PlayAction = speaker_ns.class_(
|
||||||
StopAction = speaker_ns.class_(
|
StopAction = speaker_ns.class_(
|
||||||
"StopAction", automation.Action, cg.Parented.template(Speaker)
|
"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)
|
IsPlayingCondition = speaker_ns.class_("IsPlayingCondition", automation.Condition)
|
||||||
|
IsStoppedCondition = speaker_ns.class_("IsStoppedCondition", automation.Condition)
|
||||||
|
|
||||||
|
|
||||||
async def setup_speaker_core_(var, config):
|
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)(
|
automation.register_action("speaker.stop", StopAction, SPEAKER_AUTOMATION_SCHEMA)(
|
||||||
speaker_action
|
speaker_action
|
||||||
)
|
)
|
||||||
|
automation.register_action("speaker.finish", FinishAction, SPEAKER_AUTOMATION_SCHEMA)(
|
||||||
|
speaker_action
|
||||||
|
)
|
||||||
|
|
||||||
automation.register_condition(
|
automation.register_condition(
|
||||||
"speaker.is_playing", IsPlayingCondition, SPEAKER_AUTOMATION_SCHEMA
|
"speaker.is_playing", IsPlayingCondition, SPEAKER_AUTOMATION_SCHEMA
|
||||||
)(speaker_action)
|
)(speaker_action)
|
||||||
|
|
||||||
|
automation.register_condition(
|
||||||
|
"speaker.is_stopped", IsStoppedCondition, SPEAKER_AUTOMATION_SCHEMA
|
||||||
|
)(speaker_action)
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(100.0)
|
@coroutine_with_priority(100.0)
|
||||||
async def to_code(config):
|
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(); }
|
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> {
|
template<typename... Ts> class IsPlayingCondition : public Condition<Ts...>, public Parented<Speaker> {
|
||||||
public:
|
public:
|
||||||
bool check(Ts... x) override { return this->parent_->is_running(); }
|
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 speaker
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -17,10 +17,15 @@ class Speaker {
|
||||||
|
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
virtual void stop() = 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;
|
virtual bool has_buffered_data() const = 0;
|
||||||
|
|
||||||
bool is_running() const { return this->state_ == STATE_RUNNING; }
|
bool is_running() const { return this->state_ == STATE_RUNNING; }
|
||||||
|
bool is_stopped() const { return this->state_ == STATE_STOPPED; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
State state_{STATE_STOPPED};
|
State state_{STATE_STOPPED};
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
esphome:
|
esphome:
|
||||||
on_boot:
|
on_boot:
|
||||||
then:
|
then:
|
||||||
- speaker.play: [0, 1, 2, 3]
|
- if:
|
||||||
- speaker.stop
|
condition: speaker.is_stopped
|
||||||
|
then:
|
||||||
|
- speaker.play: [0, 1, 2, 3]
|
||||||
|
- if:
|
||||||
|
condition: speaker.is_playing
|
||||||
|
then:
|
||||||
|
- speaker.finish:
|
||||||
|
- speaker.stop:
|
||||||
|
|
||||||
i2s_audio:
|
i2s_audio:
|
||||||
i2s_lrclk_pin: 16
|
i2s_lrclk_pin: 16
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
esphome:
|
esphome:
|
||||||
on_boot:
|
on_boot:
|
||||||
then:
|
then:
|
||||||
- speaker.play: [0, 1, 2, 3]
|
- if:
|
||||||
- speaker.stop
|
condition: speaker.is_stopped
|
||||||
|
then:
|
||||||
|
- speaker.play: [0, 1, 2, 3]
|
||||||
|
- if:
|
||||||
|
condition: speaker.is_playing
|
||||||
|
then:
|
||||||
|
- speaker.finish:
|
||||||
|
- speaker.stop:
|
||||||
|
|
||||||
i2s_audio:
|
i2s_audio:
|
||||||
i2s_lrclk_pin: 6
|
i2s_lrclk_pin: 6
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
esphome:
|
esphome:
|
||||||
on_boot:
|
on_boot:
|
||||||
then:
|
then:
|
||||||
- speaker.play: [0, 1, 2, 3]
|
- if:
|
||||||
- speaker.stop
|
condition: speaker.is_stopped
|
||||||
|
then:
|
||||||
|
- speaker.play: [0, 1, 2, 3]
|
||||||
|
- if:
|
||||||
|
condition: speaker.is_playing
|
||||||
|
then:
|
||||||
|
- speaker.finish:
|
||||||
|
- speaker.stop:
|
||||||
|
|
||||||
i2s_audio:
|
i2s_audio:
|
||||||
i2s_lrclk_pin: 6
|
i2s_lrclk_pin: 6
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
esphome:
|
esphome:
|
||||||
on_boot:
|
on_boot:
|
||||||
then:
|
then:
|
||||||
- speaker.play: [0, 1, 2, 3]
|
- if:
|
||||||
- speaker.stop
|
condition: speaker.is_stopped
|
||||||
|
then:
|
||||||
|
- speaker.play: [0, 1, 2, 3]
|
||||||
|
- if:
|
||||||
|
condition: speaker.is_playing
|
||||||
|
then:
|
||||||
|
- speaker.finish:
|
||||||
|
- speaker.stop:
|
||||||
|
|
||||||
i2s_audio:
|
i2s_audio:
|
||||||
i2s_lrclk_pin: 16
|
i2s_lrclk_pin: 16
|
||||||
|
|
Loading…
Reference in a new issue