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;
42 * @param address the IP address of the music player daemon
43 * @param port the TCP port to be used
44 * @param password the password to connect to the music player daemon
46 public MPDConnection(MPDEventListener listener) {
47 this.listener = listener;
51 * start the connection
53 * @param address the IP address of the music player daemon
54 * @param port the TCP port to be used
55 * @param password the password to connect to the music player daemon
56 * @param threadName the name of the thread
58 public void start(String address, Integer port, String password, String threadName) {
59 if (connectionThread == null) {
60 final MPDConnectionThread connectionThread = new MPDConnectionThread(this, address, port, password);
61 connectionThread.setName(threadName);
62 connectionThread.start();
63 this.connectionThread = connectionThread;
68 * dispose the connection
70 public void dispose() {
71 final MPDConnectionThread connectionThread = this.connectionThread;
72 if (connectionThread != null) {
73 connectionThread.dispose();
74 connectionThread.interrupt();
76 connectionThread.join(DISPOSE_TIMEOUT_MS);
77 } catch (InterruptedException ignore) {
79 this.connectionThread = null;
84 * send a command to the music player daemon
86 * @param command command to send
87 * @param parameter parameter of command
89 public void sendCommand(String command, String... parameter) {
90 addCommand(new MPDCommand(command, parameter));
101 * pause the music player daemon
103 public void pause() {
104 addCommand(new MPDCommand("pause", 1));
110 public void playNext() {
115 * play previous track
117 public void playPrevious() {
118 sendCommand("previous");
122 * stop the music player daemon
131 public void updateStatus() {
132 sendCommand("status");
136 * update information regarding current song
138 public void updateCurrentSong() {
139 sendCommand("currentsong");
145 * @param volume set new volume
147 public void setVolume(int volume) {
148 addCommand(new MPDCommand("setvol", volume));
151 private void addCommand(MPDCommand command) {
152 MPDConnectionThread connectionThread = this.connectionThread;
153 if (connectionThread != null) {
154 connectionThread.addCommand(command);
156 logger.debug("could not add command {} since thing offline", command.getCommand());
161 public void updateThingStatus(ThingStatus status, ThingStatusDetail statusDetail, @Nullable String cause) {
162 listener.updateThingStatus(status, statusDetail, cause);
166 public void onResponse(MPDResponse response) {
167 switch (response.getCommand()) {
169 handleResponseIdle(response);
172 handleResponseStatus(response);
175 handleResponseCurrentSong(response);
182 private void handleResponseCurrentSong(MPDResponse response) {
183 MPDSong song = new MPDSong(response);
184 listener.updateMPDSong(song);
187 private void handleResponseIdle(MPDResponse response) {
188 boolean updateStatus = false;
189 boolean updateCurrentSong = false;
190 for (String line : response.getLines()) {
191 if (line.startsWith("changed:")) {
192 line = line.substring(8).trim();
196 updateCurrentSong = true;
202 updateCurrentSong = true;
211 if (updateCurrentSong) {
216 private void handleResponseStatus(MPDResponse response) {
217 MPDStatus song = new MPDStatus(response);
218 listener.updateMPDStatus(song);