Good day
For now MPD component is implemented as Local Poll device. But it is possible to get state updates using idle
MPD command: https://pythonhosted.org/python-mpd2/topics/commands.html#MPDClient.idle.
In short, if idle
command was sent to MPD server, then MPD disables any timeouts and keeps TCP socket opened. If there is any “noteworthy” change on server (like player stopped/started or playlist changed, whatever), then MPD sends a string like b'changed: player\nOK\n'
to socket’s buffer.
At the same time any other command is prohibited in idle
state. To perform any other command, idle
must be canceled using noidle
command. In response to noidle
command server sends b'OK\n'
string. And after that any other command can be sent and executed by server. If idle
was not canceled, MPD closes TCP connection.
So, to implement idling and event-based status update for MPD component:
- Separated idle thread must be started
- Function in this thread must perform something like this (python-like pseudo-code):
def idle_thread():
while True:
event_idling_allowed.wait() # wait until idling was allowed
mpd.idle() # block until some change happened
if not idling_canceled:
mpd.update_state() # update state of the mpd client
- Any MPD command must perform something like this:
def send_command():
event_idling_allowed.clear() # disallow idle thread to start new loop iteration
mpd.noidle() # send `noidle` command to MPD server, cancel idling
mpd.command() # send some command to server
event_idling_allowed.clear() # allow idle thread to start new loop iteration
Or async libraries can be used.
For examples of implementation of MPD idling and event-based state updates, see this repository: https://github.com/s-kostyuk/sockets_samples/tree/devel/nih_mpd_lib