ESPHome  2024.4.0
dfplayer.h
Go to the documentation of this file.
1 #pragma once
2 
6 
7 const size_t DFPLAYER_READ_BUFFER_LENGTH = 25; // two messages + some extra
8 
9 namespace esphome {
10 namespace dfplayer {
11 
12 enum EqPreset {
13  NORMAL = 0,
14  POP = 1,
15  ROCK = 2,
16  JAZZ = 3,
17  CLASSIC = 4,
18  BASS = 5,
19 };
20 
21 enum Device {
22  USB = 1,
23  TF_CARD = 2,
24 };
25 
26 class DFPlayer : public uart::UARTDevice, public Component {
27  public:
28  void loop() override;
29 
30  void next() {
31  this->ack_set_is_playing_ = true;
32  this->send_cmd_(0x01);
33  }
34  void previous() {
35  this->ack_set_is_playing_ = true;
36  this->send_cmd_(0x02);
37  }
38  void play_mp3(uint16_t file) {
39  this->ack_set_is_playing_ = true;
40  this->send_cmd_(0x12, file);
41  }
42  void play_file(uint16_t file) {
43  this->ack_set_is_playing_ = true;
44  this->send_cmd_(0x03, file);
45  }
46  void play_file_loop(uint16_t file) {
47  this->ack_set_is_playing_ = true;
48  this->send_cmd_(0x08, file);
49  }
50  void play_folder(uint16_t folder, uint16_t file);
51  void play_folder_loop(uint16_t folder) {
52  this->ack_set_is_playing_ = true;
53  this->send_cmd_(0x17, folder);
54  }
55  void volume_up() { this->send_cmd_(0x04); }
56  void volume_down() { this->send_cmd_(0x05); }
57  void set_device(Device device) { this->send_cmd_(0x09, device); }
58  void set_volume(uint8_t volume) { this->send_cmd_(0x06, volume); }
59  void set_eq(EqPreset preset) { this->send_cmd_(0x07, preset); }
60  void sleep() {
61  this->ack_reset_is_playing_ = true;
62  this->send_cmd_(0x0A);
63  }
64  void reset() {
65  this->ack_reset_is_playing_ = true;
66  this->send_cmd_(0x0C);
67  }
68  void start() {
69  this->ack_set_is_playing_ = true;
70  this->send_cmd_(0x0D);
71  }
72  void pause() {
73  this->ack_reset_is_playing_ = true;
74  this->send_cmd_(0x0E);
75  }
76  void stop() {
77  this->ack_reset_is_playing_ = true;
78  this->send_cmd_(0x16);
79  }
80  void random() {
81  this->ack_set_is_playing_ = true;
82  this->send_cmd_(0x18);
83  }
84 
85  bool is_playing() { return is_playing_; }
86  void dump_config() override;
87 
88  void add_on_finished_playback_callback(std::function<void()> callback) {
89  this->on_finished_playback_callback_.add(std::move(callback));
90  }
91 
92  protected:
93  void send_cmd_(uint8_t cmd, uint16_t argument = 0);
94  void send_cmd_(uint8_t cmd, uint16_t high, uint16_t low) {
95  this->send_cmd_(cmd, ((high & 0xFF) << 8) | (low & 0xFF));
96  }
97  uint8_t sent_cmd_{0};
98 
100  size_t read_pos_{0};
101 
102  bool is_playing_{false};
103  bool ack_set_is_playing_{false};
105 
107 };
108 
109 #define DFPLAYER_SIMPLE_ACTION(ACTION_CLASS, ACTION_METHOD) \
110  template<typename... Ts> \
111  class ACTION_CLASS : /* NOLINT */ \
112  public Action<Ts...>, \
113  public Parented<DFPlayer> { \
114  void play(Ts... x) override { this->parent_->ACTION_METHOD(); } \
115  };
116 
117 DFPLAYER_SIMPLE_ACTION(NextAction, next)
118 DFPLAYER_SIMPLE_ACTION(PreviousAction, previous)
119 
120 template<typename... Ts> class PlayMp3Action : public Action<Ts...>, public Parented<DFPlayer> {
121  public:
122  TEMPLATABLE_VALUE(uint16_t, file)
123 
124  void play(Ts... x) override {
125  auto file = this->file_.value(x...);
126  this->parent_->play_mp3(file);
127  }
128 };
129 
130 template<typename... Ts> class PlayFileAction : public Action<Ts...>, public Parented<DFPlayer> {
131  public:
132  TEMPLATABLE_VALUE(uint16_t, file)
133  TEMPLATABLE_VALUE(bool, loop)
134 
135  void play(Ts... x) override {
136  auto file = this->file_.value(x...);
137  auto loop = this->loop_.value(x...);
138  if (loop) {
139  this->parent_->play_file_loop(file);
140  } else {
141  this->parent_->play_file(file);
142  }
143  }
144 };
145 
146 template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public Parented<DFPlayer> {
147  public:
148  TEMPLATABLE_VALUE(uint16_t, folder)
149  TEMPLATABLE_VALUE(uint16_t, file)
150  TEMPLATABLE_VALUE(bool, loop)
151 
152  void play(Ts... x) override {
153  auto folder = this->folder_.value(x...);
154  auto file = this->file_.value(x...);
155  auto loop = this->loop_.value(x...);
156  if (loop) {
157  this->parent_->play_folder_loop(folder);
158  } else {
159  this->parent_->play_folder(folder, file);
160  }
161  }
162 };
163 
164 template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Parented<DFPlayer> {
165  public:
167 
168  void play(Ts... x) override {
169  auto device = this->device_.value(x...);
170  this->parent_->set_device(device);
171  }
172 };
173 
174 template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Parented<DFPlayer> {
175  public:
176  TEMPLATABLE_VALUE(uint8_t, volume)
177 
178  void play(Ts... x) override {
179  auto volume = this->volume_.value(x...);
180  this->parent_->set_volume(volume);
181  }
182 };
183 
184 template<typename... Ts> class SetEqAction : public Action<Ts...>, public Parented<DFPlayer> {
185  public:
187 
188  void play(Ts... x) override {
189  auto eq = this->eq_.value(x...);
190  this->parent_->set_eq(eq);
191  }
192 };
193 
194 DFPLAYER_SIMPLE_ACTION(SleepAction, sleep)
195 DFPLAYER_SIMPLE_ACTION(ResetAction, reset)
196 DFPLAYER_SIMPLE_ACTION(StartAction, start)
197 DFPLAYER_SIMPLE_ACTION(PauseAction, pause)
198 DFPLAYER_SIMPLE_ACTION(StopAction, stop)
199 DFPLAYER_SIMPLE_ACTION(RandomAction, random)
200 DFPLAYER_SIMPLE_ACTION(VolumeUpAction, volume_up)
201 DFPLAYER_SIMPLE_ACTION(VolumeDownAction, volume_down)
202 
203 template<typename... Ts> class DFPlayerIsPlayingCondition : public Condition<Ts...>, public Parented<DFPlayer> {
204  public:
205  bool check(Ts... x) override { return this->parent_->is_playing(); }
206 };
207 
209  public:
211  parent->add_on_finished_playback_callback([this]() { this->trigger(); });
212  }
213 };
214 
215 } // namespace dfplayer
216 } // namespace esphome
void loop() override
Definition: dfplayer.cpp:36
void send_cmd_(uint8_t cmd, uint16_t argument=0)
Definition: dfplayer.cpp:21
void dump_config() override
Definition: dfplayer.cpp:131
CallbackManager< void()> on_finished_playback_callback_
Definition: dfplayer.h:106
void play_file_loop(uint16_t file)
Definition: dfplayer.h:46
void add_on_finished_playback_callback(std::function< void()> callback)
Definition: dfplayer.h:88
DFPLAYER_SIMPLE_ACTION(NextAction, next) DFPLAYER_SIMPLE_ACTION(PreviousAction
uint16_t x
Definition: tt21100.cpp:17
void set_device(Device device)
Definition: dfplayer.h:57
void send_cmd_(uint8_t cmd, uint16_t high, uint16_t low)
Definition: dfplayer.h:94
void play_file(uint16_t file)
Definition: dfplayer.h:42
void play_folder_loop(uint16_t folder)
Definition: dfplayer.h:51
UARTComponent * parent_
Definition: uart.h:68
TEMPLATABLE_VALUE(Device, device) void play(Ts... x) override
Definition: dfplayer.h:166
Base class for all automation conditions.
Definition: automation.h:74
TEMPLATABLE_VALUE(uint16_t, file) void play(Ts... x) override
Definition: dfplayer.h:122
const size_t DFPLAYER_READ_BUFFER_LENGTH
Definition: dfplayer.h:7
void play_folder(uint16_t folder, uint16_t file)
Definition: dfplayer.cpp:9
TEMPLATABLE_VALUE(uint8_t, volume) void play(Ts... x) override
Definition: dfplayer.h:176
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void set_eq(EqPreset preset)
Definition: dfplayer.h:59
TEMPLATABLE_VALUE(EqPreset, eq) void play(Ts... x) override
Definition: dfplayer.h:186
void set_volume(uint8_t volume)
Definition: dfplayer.h:58
char read_buffer_[DFPLAYER_READ_BUFFER_LENGTH]
Definition: dfplayer.h:99
void play_mp3(uint16_t file)
Definition: dfplayer.h:38
Helper class to easily give an object a parent of type T.
Definition: helpers.h:515
ClimatePreset preset
Definition: climate.h:578
stm32_cmd_t * cmd
Definition: stm32flash.h:96