38
38
_OK_RESPONSE = "OK"
39
39
40
40
41
- class DF1201S (object ):
41
+ def _unwrap_int (value : str ) -> int :
42
+ """
43
+ Convert a string to an int if it only contains digits, otherwise return -1.
44
+
45
+ :param str value: the string to attempt to convert to an int
46
+ :return: the int value of the string, or -1 if it could not be converted
47
+ """
48
+ if value .isdigit ():
49
+ return int (value )
50
+ return - 1
51
+
52
+
53
+ def _map_volume (volume : float ) -> int :
54
+ """
55
+ Map 0.0 to 1.0 volume value to DFPlayer's volume range.
56
+
57
+ :param float volume: the volume, from 0 to 1, to convert
58
+ :return: the volume mapped to a valid DFPlayer Pro volume value
59
+ """
60
+ return max (min (int (volume * _DFPLAYER_VOLUME_MAX ), _DFPLAYER_VOLUME_MAX ), 0 )
61
+
62
+
63
+ class DF1201S :
42
64
"""Driver for DFRobot DFPlayer Pro (DF1201S) MP3 player with onboard storage."""
43
65
66
+ # pylint: disable=too-many-public-methods
67
+
44
68
PLAYMODE_REPEAT_ONE_SONG = const (1 )
45
69
"""play_mode: Repeat one sound."""
46
70
PLAYMODE_REPEAT_ALL = const (2 )
@@ -56,7 +80,7 @@ def __init__(self, uart: busio.UART) -> None:
56
80
"""
57
81
Initialize the DFPlayer connection.
58
82
59
- :param busio.UART uart: the serial connection to the DFPlayer
83
+ :param busio.UART uart: the serial connection to the DFPlayer
60
84
"""
61
85
self ._uart = uart
62
86
if not self .connected :
@@ -66,14 +90,14 @@ def _send_query(self, command: str, arg=None) -> str:
66
90
"""
67
91
Send AT command and return the response.
68
92
69
- :param str command: the command to send (without AT prefix or CR\ LF)
93
+ :param str command: the command to send (without AT prefix or CR/ LF)
70
94
:param arg: optional command argument
71
- :return: the response to the command (CR\ LF removed)
95
+ :return: the response to the command (CR/ LF removed)
72
96
"""
73
97
# format the AT command, adding the argument if given
74
98
at_command = "AT"
75
99
if command != "" :
76
- if arg != None :
100
+ if arg is not None :
77
101
at_command = f"AT+{ command } ={ arg } "
78
102
else :
79
103
at_command = f"AT+{ command } "
@@ -86,7 +110,7 @@ def _send_query(self, command: str, arg=None) -> str:
86
110
# read the response and strip the \r\n
87
111
response = self ._uart .readline ()
88
112
89
- parsed = "" if response == None else str (response [0 :- 2 ], ' ascii' )
113
+ parsed = "" if response is None else str (response [0 :- 2 ], " ascii" )
90
114
91
115
print ("DFPlayer Response: " , parsed )
92
116
@@ -96,42 +120,20 @@ def _send_command(self, command: str, arg=None) -> bool:
96
120
"""
97
121
Send AT command and return true for an OK response.
98
122
99
- :param str command: the command to send (without AT prefix or CR\ LF)
123
+ :param str command: the command to send (without AT prefix or CR/ LF)
100
124
:param arg: optional command argument
101
125
:return: True if the command was successful
102
126
"""
103
127
return self ._send_query (command , arg ) == _OK_RESPONSE
104
128
105
- def _unwrap_int (self , value : str ) -> int :
106
- """
107
- Convert a string to an int if it only contains digits, otherwise return -1.
108
-
109
- :param str value: the string to attempt to convert to an int
110
- :return: the int value of the string, or -1 if it could not be converted
111
- """
112
- if value .isdigit ():
113
- return int (value )
114
- return - 1
115
-
116
- def _map_volume (self , volume : float ) -> int :
117
- """
118
- Map 0.0 to 1.0 volume value to DFPlayer's volume range.
119
-
120
- :param float volume: the volume, from 0 to 1, to convert
121
- :return: the volume mapped to a valid DFPlayer Pro volume value
122
- """
123
- return max (min (int (volume * _DFPLAYER_VOLUME_MAX ), _DFPLAYER_VOLUME_MAX ), 0 )
124
-
125
129
@property
126
130
def connected (self ) -> bool :
127
- """
128
- :return: True if the DFPlayer is connected.
129
- """
131
+ """True if the DFPlayer is connected."""
130
132
return self ._send_command ("" )
131
133
132
134
def set_baud_rate (self , rate : int ) -> bool :
133
135
"""
134
- Set baud rate for the serial DFPlayer connection.
136
+ Set baud rate for the serial DFPlayer connection.
135
137
136
138
.. note:: Persists after power off.
137
139
@@ -143,11 +145,9 @@ def set_baud_rate(self, rate: int) -> bool:
143
145
144
146
@property
145
147
def volume (self ) -> float :
146
- """
147
- :return: Volume level, as a float between 0 and 1.
148
- """
148
+ """Volume level, as a float between 0 and 1."""
149
149
response = self ._send_query ("VOL" , "?" )
150
- df_volume = self . _unwrap_int (response [7 :- 1 ])
150
+ df_volume = _unwrap_int (response [7 :- 1 ])
151
151
if df_volume < 0 :
152
152
return 0
153
153
@@ -163,7 +163,7 @@ def volume(self, volume: float) -> bool:
163
163
:param float volume: the volume level, as a float between 0 and 1.
164
164
:return: True if the volume was set.
165
165
"""
166
- df_volume = self . _map_volume (volume )
166
+ df_volume = _map_volume (volume )
167
167
return self ._send_command ("VOL" , df_volume )
168
168
169
169
def increase_volume (self , increment : float ) -> bool :
@@ -175,7 +175,7 @@ def increase_volume(self, increment: float) -> bool:
175
175
:param float increment: the amount to increase the volume, as a float between 0 and 1.
176
176
:return: True if the volume was increased.
177
177
"""
178
- df_volume = self . _map_volume (increment )
178
+ df_volume = _map_volume (increment )
179
179
return self ._send_command ("VOL" , f"+{ df_volume } " )
180
180
181
181
def decrease_volume (self , decrement : float ) -> bool :
@@ -187,7 +187,7 @@ def decrease_volume(self, decrement: float) -> bool:
187
187
:param float decrement: the amount to decrement the volume, as a float between 0 and 1.
188
188
:return: True if the volume was decreased.
189
189
"""
190
- df_volume = self . _map_volume (decrement )
190
+ df_volume = _map_volume (decrement )
191
191
return self ._send_command ("VOL" , f"-{ df_volume } " )
192
192
193
193
def enable_led (self ) -> bool :
@@ -251,20 +251,22 @@ def play_mode(self) -> int:
251
251
"""
252
252
Returns the current play mode.
253
253
254
- :return: One of the play mode constants (`PLAYMODE_REPEAT_ONE_SONG`, `PLAYMODE_REPEAT_ALL`, or `PLAYMODE_PLAY_ONCE`).
254
+ :return: One of the play mode constants, `PLAYMODE_REPEAT_ONE_SONG`, `PLAYMODE_REPEAT_ALL`,
255
+ or `PLAYMODE_PLAY_ONCE`.
255
256
`PLAYMODE_RANDOM` can be set, but this function will return -1. Bug in the device?
256
257
`PLAYMODE_REPEAT_FOLDER` can be set, but this function will return 3. Bug in the device?
257
258
258
259
"""
259
260
response = self ._send_query ("PLAYMODE" , "?" )
260
- return self . _unwrap_int (response [10 :])
261
+ return _unwrap_int (response [10 :])
261
262
262
263
@play_mode .setter
263
264
def play_mode (self , new_mode : int ) -> bool :
264
265
"""
265
266
Set the play mode.
266
267
267
- :param int new_mode: One of `PLAYMODE_REPEAT_ONE_SONG`, `PLAYMODE_REPEAT_ALL`, `PLAYMODE_PLAY_ONCE`, `PLAYMODE_RANDOM`, or `PLAYMODE_REPEAT_FOLDER`.
268
+ :param int new_mode: One of `PLAYMODE_REPEAT_ONE_SONG`, `PLAYMODE_REPEAT_ALL`,
269
+ `PLAYMODE_PLAY_ONCE`, `PLAYMODE_RANDOM`, or `PLAYMODE_REPEAT_FOLDER`.
268
270
:return: True if the play mode was set.
269
271
"""
270
272
return self ._send_command ("PLAYMODE" , new_mode )
@@ -289,7 +291,8 @@ def play_file_number(self, file_number: int) -> bool:
289
291
"""
290
292
Play the sound at the given file number.
291
293
292
- .. note:: Plays the first sound if the file number is invalid. I don't see a way to turn off this behavior.
294
+ .. note:: Plays the first sound if the file number is invalid. I don't see a way to turn
295
+ off this behavior.
293
296
294
297
:param int file_number: the file number to play.
295
298
:return: True if the given file number is playing, False if the first file is playing.
@@ -300,7 +303,8 @@ def play_file_name(self, file_name: str) -> bool:
300
303
"""
301
304
Play the sound with the given file name.
302
305
303
- .. note:: Plays the first sound if the file name is invalid. I don't see a way to turn off this behavior.
306
+ .. note:: Plays the first sound if the file name is invalid. I don't see a way to turn
307
+ off this behavior.
304
308
305
309
:param str file_name: the file name to play.
306
310
:return: True if the given file is playing, False if the first file if playing.
@@ -329,49 +333,40 @@ def fast_seek(self, seconds: int) -> bool:
329
333
"""
330
334
Start playing the current sound at a specific time offset.
331
335
332
- .. note:: If the offset exceeds the sound length, this function still returns `True` and the sound stops.
336
+ .. note:: If the offset exceeds the sound length, this function still returns `True`
337
+ and the sound stops.
333
338
334
339
:param int seconds: the time offset, in seconds.
335
- :return: True if the current offset was set.
340
+ :return: True if the current offset was set.
336
341
"""
337
342
return self ._send_command ("TIME" , seconds )
338
343
339
344
@property
340
345
def total_files (self ) -> int :
341
346
"""The total count of sound files available."""
342
- return self . _unwrap_int (self ._send_query ("QUERY" , 2 ))
347
+ return _unwrap_int (self ._send_query ("QUERY" , 2 ))
343
348
344
349
@property
345
350
def file_number (self ) -> int :
346
- """
347
- :return: The file number of the currently playing file.
348
- """
349
- return self ._unwrap_int (self ._send_query ("QUERY" , 1 ))
351
+ """The file number of the currently playing file."""
352
+ return _unwrap_int (self ._send_query ("QUERY" , 1 ))
350
353
351
354
@property
352
355
def file_name (self ) -> str :
353
- """
354
- :return: The file name of the currently playing file.
355
- """
356
+ """The file name of the currently playing file."""
356
357
return self ._send_query ("QUERY" , 5 )
357
358
358
359
@property
359
360
def played_time (self ) -> int :
360
- """
361
- :return: The number of seconds the current sound has played.
362
- """
363
- return self ._unwrap_int (self ._send_query ("QUERY" , 3 ))
361
+ """The number of seconds the current sound has played."""
362
+ return _unwrap_int (self ._send_query ("QUERY" , 3 ))
364
363
365
364
@property
366
365
def total_time (self ) -> int :
367
- """
368
- :return: The length of the current sound in seconds.
369
- """
370
- return self ._unwrap_int (self ._send_query ("QUERY" , 4 ))
366
+ """The length of the current sound in seconds."""
367
+ return _unwrap_int (self ._send_query ("QUERY" , 4 ))
371
368
372
369
@property
373
370
def playing (self ) -> bool :
374
- """
375
- :return: True if a sound is currently playing.
376
- """
371
+ """True if a sound is currently playing."""
377
372
return self .played_time < self .total_time
0 commit comments