2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mpd.internal.protocol;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.binding.mpd.internal.handler.MPDEventListener;
18 import org.openhab.core.thing.ThingStatus;
19 import org.openhab.core.thing.ThingStatusDetail;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * Class for communicating with the music player daemon through an IP connection
26 * @author Stefan Röllin - Initial contribution
29 public class MPDConnection implements MPDResponseListener {
31 private static final int DISPOSE_TIMEOUT_MS = 1000;
33 private final Logger logger = LoggerFactory.getLogger(MPDConnection.class);
35 private final MPDEventListener listener;
37 private @Nullable MPDConnectionThread connectionThread = null;
44 public MPDConnection(MPDEventListener listener) {
45 this.listener = listener;
49 * start the connection
51 * @param address the IP address of the music player daemon
52 * @param port the TCP port to be used
53 * @param password the password to connect to the music player daemon
54 * @param threadName the name of the thread
56 public void start(String address, Integer port, String password, String threadName) {
57 if (connectionThread == null) {
58 final MPDConnectionThread connectionThread = new MPDConnectionThread(this, address, port, password);
59 connectionThread.setName(threadName);
60 connectionThread.start();
61 this.connectionThread = connectionThread;
66 * dispose the connection
68 public void dispose() {
69 final MPDConnectionThread connectionThread = this.connectionThread;
70 if (connectionThread != null) {
71 connectionThread.dispose();
72 connectionThread.interrupt();
74 connectionThread.join(DISPOSE_TIMEOUT_MS);
75 } catch (InterruptedException ignore) {
77 this.connectionThread = null;
82 * send a command to the music player daemon
84 * @param command command to send
85 * @param parameter parameter of command
87 public void sendCommand(String command, String... parameter) {
88 addCommand(new MPDCommand(command, parameter));
99 * pause the music player daemon
101 public void pause() {
102 addCommand(new MPDCommand("pause", 1));
108 public void playNext() {
113 * play previous track
115 public void playPrevious() {
116 sendCommand("previous");
120 * stop the music player daemon
129 public void updateStatus() {
130 sendCommand("status");
134 * update information regarding current song
136 public void updateCurrentSong() {
137 sendCommand("currentsong");
143 * @param volume set new volume
145 public void setVolume(int volume) {
146 addCommand(new MPDCommand("setvol", volume));
149 private void addCommand(MPDCommand command) {
150 MPDConnectionThread connectionThread = this.connectionThread;
151 if (connectionThread != null) {
152 connectionThread.addCommand(command);
154 logger.debug("could not add command {} since thing offline", command.getCommand());
159 public void updateThingStatus(ThingStatus status, ThingStatusDetail statusDetail, @Nullable String cause) {
160 listener.updateThingStatus(status, statusDetail, cause);
164 public void onResponse(MPDResponse response) {
165 switch (response.getCommand()) {
167 handleResponseIdle(response);
170 handleResponseStatus(response);
173 handleResponseCurrentSong(response);
180 private void handleResponseCurrentSong(MPDResponse response) {
181 MPDSong song = new MPDSong(response);
182 listener.updateMPDSong(song);
185 private void handleResponseIdle(MPDResponse response) {
186 boolean updateStatus = false;
187 boolean updateCurrentSong = false;
188 for (String line : response.getLines()) {
189 if (line.startsWith("changed:")) {
190 line = line.substring(8).trim();
194 updateCurrentSong = true;
200 updateCurrentSong = true;
209 if (updateCurrentSong) {
214 private void handleResponseStatus(MPDResponse response) {
215 MPDStatus song = new MPDStatus(response);
216 listener.updateMPDStatus(song);