[pulseaudio] Fix exception handling when connecting (#12423)
Fix bridge/thing status update Also update log levels Fix #12419 Fix #12424 Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
20f6b52e71
commit
e3ca3b01bf
|
@ -18,7 +18,6 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
@ -129,20 +128,18 @@ public class PulseaudioClient {
|
|||
*/
|
||||
private static final String MODULE_COMBINE_SINK = "module-combine-sink";
|
||||
|
||||
public PulseaudioClient(String host, int port, PulseAudioBindingConfiguration configuration) throws IOException {
|
||||
public PulseaudioClient(String host, int port, PulseAudioBindingConfiguration configuration) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.configuration = configuration;
|
||||
|
||||
items = new ArrayList<>();
|
||||
modules = new ArrayList<>();
|
||||
|
||||
connect();
|
||||
update();
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return client != null ? client.isConnected() : false;
|
||||
Socket clientSocket = client;
|
||||
return clientSocket != null ? clientSocket.isConnected() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -378,9 +375,6 @@ public class PulseaudioClient {
|
|||
* 0 - 65536)
|
||||
*/
|
||||
public void setVolume(AbstractAudioDeviceConfig item, int vol) {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
String itemCommandName = getItemCommandName(item);
|
||||
if (itemCommandName == null) {
|
||||
return;
|
||||
|
@ -485,7 +479,7 @@ public class PulseaudioClient {
|
|||
.map(portS -> Integer.parseInt(portS));
|
||||
}
|
||||
|
||||
private @NonNull Optional<@NonNull String> extractArgumentFromLine(String argumentWanted, String argumentLine) {
|
||||
private Optional<@NonNull String> extractArgumentFromLine(String argumentWanted, String argumentLine) {
|
||||
String argument = null;
|
||||
int startPortIndex = argumentLine.indexOf(argumentWanted + "=");
|
||||
if (startPortIndex != -1) {
|
||||
|
@ -525,11 +519,8 @@ public class PulseaudioClient {
|
|||
* @param vol the new volume percent value the {@link AbstractAudioDeviceConfig} should be changed to (possible
|
||||
* values from 0 - 100)
|
||||
*/
|
||||
public void setVolumePercent(@Nullable AbstractAudioDeviceConfig item, int vol) {
|
||||
public void setVolumePercent(AbstractAudioDeviceConfig item, int vol) {
|
||||
int volumeToSet = vol;
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (volumeToSet <= 100) {
|
||||
volumeToSet = toAbsoluteVolume(volumeToSet);
|
||||
}
|
||||
|
@ -662,15 +653,16 @@ public class PulseaudioClient {
|
|||
|
||||
private synchronized void sendRawCommand(String command) {
|
||||
checkConnection();
|
||||
if (client != null && client.isConnected()) {
|
||||
Socket clientSocket = client;
|
||||
if (clientSocket != null && clientSocket.isConnected()) {
|
||||
try {
|
||||
PrintStream out = new PrintStream(client.getOutputStream(), true);
|
||||
PrintStream out = new PrintStream(clientSocket.getOutputStream(), true);
|
||||
logger.trace("sending command {} to pa-server {}", command, host);
|
||||
out.print(command + "\r\n");
|
||||
out.close();
|
||||
client.close();
|
||||
clientSocket.close();
|
||||
} catch (IOException e) {
|
||||
logger.error("{}", e.getLocalizedMessage(), e);
|
||||
logger.warn("{}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -679,12 +671,13 @@ public class PulseaudioClient {
|
|||
logger.trace("_sendRawRequest({})", command);
|
||||
checkConnection();
|
||||
String result = "";
|
||||
if (client != null && client.isConnected()) {
|
||||
Socket clientSocket = client;
|
||||
if (clientSocket != null && clientSocket.isConnected()) {
|
||||
try {
|
||||
PrintStream out = new PrintStream(client.getOutputStream(), true);
|
||||
PrintStream out = new PrintStream(clientSocket.getOutputStream(), true);
|
||||
out.print(command + "\r\n");
|
||||
|
||||
InputStream instr = client.getInputStream();
|
||||
InputStream instr = clientSocket.getInputStream();
|
||||
|
||||
try {
|
||||
byte[] buff = new byte[1024];
|
||||
|
@ -709,42 +702,52 @@ public class PulseaudioClient {
|
|||
} catch (SocketException e) {
|
||||
logger.warn("Socket exception while sending pulseaudio command: {}", e.getMessage());
|
||||
} catch (IOException e) {
|
||||
logger.error("Exception while reading socket: {}", e.getMessage());
|
||||
logger.warn("Exception while reading socket: {}", e.getMessage());
|
||||
}
|
||||
instr.close();
|
||||
out.close();
|
||||
client.close();
|
||||
clientSocket.close();
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
logger.error("{}", e.getLocalizedMessage(), e);
|
||||
logger.warn("{}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkConnection() {
|
||||
if (client == null || client.isClosed() || !client.isConnected()) {
|
||||
try {
|
||||
connect();
|
||||
} catch (IOException e) {
|
||||
logger.error("{}", e.getLocalizedMessage(), e);
|
||||
}
|
||||
try {
|
||||
connect();
|
||||
} catch (IOException e) {
|
||||
logger.debug("{}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the pulseaudio server (timeout 500ms)
|
||||
*/
|
||||
private void connect() throws IOException {
|
||||
try {
|
||||
client = new Socket(host, port);
|
||||
client.setSoTimeout(500);
|
||||
} catch (UnknownHostException e) {
|
||||
logger.error("unknown socket host {}", host);
|
||||
} catch (NoRouteToHostException e) {
|
||||
logger.error("no route to host {}", host);
|
||||
} catch (SocketException e) {
|
||||
logger.error("cannot connect to host {} : {}", host, e.getMessage());
|
||||
public void connect() throws IOException {
|
||||
Socket clientSocket = client;
|
||||
if (clientSocket == null || clientSocket.isClosed() || !clientSocket.isConnected()) {
|
||||
logger.trace("Try to connect...");
|
||||
try {
|
||||
client = new Socket(host, port);
|
||||
client.setSoTimeout(500);
|
||||
logger.trace("connected");
|
||||
} catch (UnknownHostException e) {
|
||||
client = null;
|
||||
throw new IOException("Unknown host", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
client = null;
|
||||
throw new IOException("Invalid port", e);
|
||||
} catch (SecurityException | SocketException e) {
|
||||
client = null;
|
||||
throw new IOException(
|
||||
String.format("Cannot connect socket: %s", e.getMessage() != null ? e.getMessage() : ""), e);
|
||||
} catch (IOException e) {
|
||||
client = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,11 +755,12 @@ public class PulseaudioClient {
|
|||
* Disconnects from the pulseaudio server
|
||||
*/
|
||||
public void disconnect() {
|
||||
if (client != null) {
|
||||
Socket clientSocket = client;
|
||||
if (clientSocket != null) {
|
||||
try {
|
||||
client.close();
|
||||
clientSocket.close();
|
||||
} catch (IOException e) {
|
||||
logger.error("{}", e.getLocalizedMessage(), e);
|
||||
logger.debug("{}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.openhab.core.config.core.Configuration;
|
|||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
|
@ -67,11 +68,22 @@ public class PulseaudioBridgeHandler extends BaseBridgeHandler implements PulseA
|
|||
private HashSet<String> lastActiveDevices = new HashSet<>();
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
private Runnable pollingRunnable = () -> {
|
||||
update();
|
||||
};
|
||||
|
||||
private synchronized void update() {
|
||||
try {
|
||||
client.connect();
|
||||
if (getThing().getStatus() != ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
logger.debug("Established connection to Pulseaudio server on Host '{}':'{}'.", host, port);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.debug("{}", e.getMessage(), e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
String.format("Couldn't connect to Pulsaudio server [Host '%s':'%d']: %s", host, port,
|
||||
e.getMessage() != null ? e.getMessage() : ""));
|
||||
return;
|
||||
}
|
||||
|
||||
client.update();
|
||||
for (AbstractAudioDeviceConfig device : client.getItems()) {
|
||||
if (lastActiveDevices != null && lastActiveDevices.contains(device.getPaName())) {
|
||||
|
@ -79,7 +91,7 @@ public class PulseaudioBridgeHandler extends BaseBridgeHandler implements PulseA
|
|||
try {
|
||||
deviceStatusListener.onDeviceStateChanged(getThing().getUID(), device);
|
||||
} catch (Exception e) {
|
||||
logger.error("An exception occurred while calling the DeviceStatusListener", e);
|
||||
logger.warn("An exception occurred while calling the DeviceStatusListener", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -88,7 +100,7 @@ public class PulseaudioBridgeHandler extends BaseBridgeHandler implements PulseA
|
|||
deviceStatusListener.onDeviceAdded(getThing(), device);
|
||||
deviceStatusListener.onDeviceStateChanged(getThing().getUID(), device);
|
||||
} catch (Exception e) {
|
||||
logger.error("An exception occurred while calling the DeviceStatusListener", e);
|
||||
logger.warn("An exception occurred while calling the DeviceStatusListener", e);
|
||||
}
|
||||
lastActiveDevices.add(device.getPaName());
|
||||
}
|
||||
|
@ -106,13 +118,7 @@ public class PulseaudioBridgeHandler extends BaseBridgeHandler implements PulseA
|
|||
if (command instanceof RefreshType) {
|
||||
client.update();
|
||||
} else {
|
||||
logger.warn("received invalid command for pulseaudio bridge '{}'.", host);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void startAutomaticRefresh() {
|
||||
if (pollingJob == null || pollingJob.isCancelled()) {
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(pollingRunnable, 0, refreshInterval, TimeUnit.MILLISECONDS);
|
||||
logger.debug("received unexpected command for pulseaudio bridge '{}'.", host);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,26 +146,15 @@ public class PulseaudioBridgeHandler extends BaseBridgeHandler implements PulseA
|
|||
}
|
||||
|
||||
if (host != null && !host.isEmpty()) {
|
||||
Runnable connectRunnable = () -> {
|
||||
try {
|
||||
client = new PulseaudioClient(host, port, configuration);
|
||||
if (client.isConnected()) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
logger.info("Established connection to Pulseaudio server on Host '{}':'{}'.", host, port);
|
||||
startAutomaticRefresh();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Couldn't connect to Pulsaudio server [Host '{}':'{}']: {}", host, port,
|
||||
e.getLocalizedMessage());
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
};
|
||||
scheduler.schedule(connectRunnable, 0, TimeUnit.SECONDS);
|
||||
client = new PulseaudioClient(host, port, configuration);
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
if (pollingJob == null || pollingJob.isCancelled()) {
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(this::update, 0, refreshInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} else {
|
||||
logger.warn(
|
||||
"Couldn't connect to Pulseaudio server because of missing connection parameters [Host '{}':'{}'].",
|
||||
host, port);
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, String.format(
|
||||
"Couldn't connect to Pulseaudio server because of missing connection parameters [Host '%s':'%d']",
|
||||
host, port));
|
||||
}
|
||||
|
||||
this.configuration.addPulseAudioBindingConfigurationListener(this);
|
||||
|
@ -168,8 +163,10 @@ public class PulseaudioBridgeHandler extends BaseBridgeHandler implements PulseA
|
|||
@Override
|
||||
public void dispose() {
|
||||
this.configuration.removePulseAudioBindingConfigurationListener(this);
|
||||
if (pollingJob != null) {
|
||||
pollingJob.cancel(true);
|
||||
ScheduledFuture<?> job = pollingJob;
|
||||
if (job != null) {
|
||||
job.cancel(true);
|
||||
pollingJob = null;
|
||||
}
|
||||
if (client != null) {
|
||||
client.disconnect();
|
||||
|
|
|
@ -50,6 +50,8 @@ import org.openhab.core.thing.Bridge;
|
|||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
|
@ -101,15 +103,13 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
Configuration config = getThing().getConfiguration();
|
||||
name = (String) config.get(DEVICE_PARAMETER_NAME);
|
||||
|
||||
// until we get an update put the Thing offline
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
deviceOnlineWatchdog();
|
||||
|
||||
// if it's a SINK thing, then maybe we have to activate the audio sink
|
||||
if (PulseaudioBindingConstants.SINK_THING_TYPE.equals(thing.getThingTypeUID())) {
|
||||
if (SINK_THING_TYPE.equals(thing.getThingTypeUID())) {
|
||||
// check the property to see if we it's enabled :
|
||||
Boolean sinkActivated = (Boolean) thing.getConfiguration()
|
||||
.get(PulseaudioBindingConstants.DEVICE_PARAMETER_AUDIO_SINK_ACTIVATION);
|
||||
Boolean sinkActivated = (Boolean) thing.getConfiguration().get(DEVICE_PARAMETER_AUDIO_SINK_ACTIVATION);
|
||||
if (sinkActivated != null && sinkActivated) {
|
||||
audioSinkSetup();
|
||||
}
|
||||
|
@ -182,22 +182,25 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (refreshJob != null && !refreshJob.isCancelled()) {
|
||||
refreshJob.cancel(true);
|
||||
ScheduledFuture<?> job = refreshJob;
|
||||
if (job != null && !job.isCancelled()) {
|
||||
job.cancel(true);
|
||||
refreshJob = null;
|
||||
}
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
if (bridgeHandler != null) {
|
||||
bridgeHandler.unregisterDeviceStatusListener(this);
|
||||
PulseaudioBridgeHandler briHandler = bridgeHandler;
|
||||
if (briHandler != null) {
|
||||
briHandler.unregisterDeviceStatusListener(this);
|
||||
bridgeHandler = null;
|
||||
}
|
||||
logger.trace("Thing {} {} disposed.", getThing().getUID(), name);
|
||||
super.dispose();
|
||||
if (audioSink != null) {
|
||||
audioSink.disconnect();
|
||||
PulseAudioAudioSink sink = audioSink;
|
||||
if (sink != null) {
|
||||
sink.disconnect();
|
||||
}
|
||||
if (audioSource != null) {
|
||||
audioSource.disconnect();
|
||||
PulseAudioAudioSource source = audioSource;
|
||||
if (source != null) {
|
||||
source.disconnect();
|
||||
}
|
||||
// Unregister the potential pulse audio sink's audio sink
|
||||
ServiceRegistration<AudioSink> sinkReg = audioSinkRegistrations.remove(getThing().getUID().toString());
|
||||
|
@ -213,20 +216,42 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE
|
||||
&& getThing().getStatusInfo().getStatusDetail() == ThingStatusDetail.BRIDGE_OFFLINE) {
|
||||
// Bridge is now ONLINE, restart the refresh job to get an update of the thing status without waiting
|
||||
// its next planned run
|
||||
ScheduledFuture<?> job = refreshJob;
|
||||
if (job != null && !job.isCancelled()) {
|
||||
job.cancel(true);
|
||||
refreshJob = null;
|
||||
}
|
||||
deviceOnlineWatchdog();
|
||||
} else if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE
|
||||
|| bridgeStatusInfo.getStatus() == ThingStatus.UNKNOWN) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
}
|
||||
|
||||
private void deviceOnlineWatchdog() {
|
||||
Runnable runnable = () -> {
|
||||
try {
|
||||
PulseaudioBridgeHandler bridgeHandler = getPulseaudioBridgeHandler();
|
||||
if (bridgeHandler != null) {
|
||||
if (bridgeHandler.getDevice(name) == null) {
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
this.bridgeHandler = null;
|
||||
if (bridgeHandler.getThing().getStatus() == ThingStatus.ONLINE) {
|
||||
if (bridgeHandler.getDevice(name) == null) {
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
this.bridgeHandler = null;
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
}
|
||||
} else {
|
||||
logger.debug("Bridge for pulseaudio device {} not found.", name);
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.debug("Exception occurred during execution: {}", e.getMessage(), e);
|
||||
|
@ -258,17 +283,17 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
PulseaudioBridgeHandler bridge = getPulseaudioBridgeHandler();
|
||||
if (bridge == null) {
|
||||
logger.warn("pulseaudio server bridge handler not found. Cannot handle command without bridge.");
|
||||
PulseaudioBridgeHandler briHandler = getPulseaudioBridgeHandler();
|
||||
if (briHandler == null) {
|
||||
logger.debug("pulseaudio server bridge handler not found. Cannot handle command without bridge.");
|
||||
return;
|
||||
}
|
||||
if (command instanceof RefreshType) {
|
||||
bridge.handleCommand(channelUID, command);
|
||||
briHandler.handleCommand(channelUID, command);
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractAudioDeviceConfig device = bridge.getDevice(name);
|
||||
AbstractAudioDeviceConfig device = briHandler.getDevice(name);
|
||||
if (device == null) {
|
||||
logger.warn("device {} not found", name);
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
|
@ -279,8 +304,8 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
if (channelUID.getId().equals(VOLUME_CHANNEL)) {
|
||||
if (command instanceof IncreaseDecreaseType) {
|
||||
// refresh to get the current volume level
|
||||
bridge.getClient().update();
|
||||
device = bridge.getDevice(name);
|
||||
briHandler.getClient().update();
|
||||
device = briHandler.getDevice(name);
|
||||
if (device == null) {
|
||||
logger.warn("missing device info, aborting");
|
||||
return;
|
||||
|
@ -293,24 +318,24 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
if (command.equals(IncreaseDecreaseType.DECREASE)) {
|
||||
newVolume = Math.max(0, oldVolume - 5);
|
||||
}
|
||||
bridge.getClient().setVolumePercent(device, newVolume);
|
||||
briHandler.getClient().setVolumePercent(device, newVolume);
|
||||
updateState = new PercentType(newVolume);
|
||||
savedVolume = newVolume;
|
||||
} else if (command instanceof PercentType) {
|
||||
DecimalType volume = (DecimalType) command;
|
||||
bridge.getClient().setVolumePercent(device, volume.intValue());
|
||||
briHandler.getClient().setVolumePercent(device, volume.intValue());
|
||||
updateState = (PercentType) command;
|
||||
savedVolume = volume.intValue();
|
||||
} else if (command instanceof DecimalType) {
|
||||
// set volume
|
||||
DecimalType volume = (DecimalType) command;
|
||||
bridge.getClient().setVolume(device, volume.intValue());
|
||||
briHandler.getClient().setVolume(device, volume.intValue());
|
||||
updateState = (DecimalType) command;
|
||||
savedVolume = volume.intValue();
|
||||
}
|
||||
} else if (channelUID.getId().equals(MUTE_CHANNEL)) {
|
||||
if (command instanceof OnOffType) {
|
||||
bridge.getClient().setMute(device, OnOffType.ON.equals(command));
|
||||
briHandler.getClient().setMute(device, OnOffType.ON.equals(command));
|
||||
updateState = (OnOffType) command;
|
||||
}
|
||||
} else if (channelUID.getId().equals(SLAVES_CHANNEL)) {
|
||||
|
@ -318,32 +343,32 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
if (command instanceof StringType) {
|
||||
List<Sink> slaves = new ArrayList<>();
|
||||
for (String slaveName : command.toString().split(",")) {
|
||||
Sink slave = bridge.getClient().getSink(slaveName.trim());
|
||||
Sink slave = briHandler.getClient().getSink(slaveName.trim());
|
||||
if (slave != null) {
|
||||
slaves.add(slave);
|
||||
}
|
||||
}
|
||||
if (!slaves.isEmpty()) {
|
||||
bridge.getClient().setCombinedSinkSlaves(((Sink) device), slaves);
|
||||
briHandler.getClient().setCombinedSinkSlaves(((Sink) device), slaves);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.error("{} is no combined sink", device);
|
||||
logger.warn("{} is no combined sink", device);
|
||||
}
|
||||
} else if (channelUID.getId().equals(ROUTE_TO_SINK_CHANNEL)) {
|
||||
if (device instanceof SinkInput) {
|
||||
Sink newSink = null;
|
||||
if (command instanceof DecimalType) {
|
||||
newSink = bridge.getClient().getSink(((DecimalType) command).intValue());
|
||||
newSink = briHandler.getClient().getSink(((DecimalType) command).intValue());
|
||||
} else {
|
||||
newSink = bridge.getClient().getSink(command.toString());
|
||||
newSink = briHandler.getClient().getSink(command.toString());
|
||||
}
|
||||
if (newSink != null) {
|
||||
logger.debug("rerouting {} to {}", device, newSink);
|
||||
bridge.getClient().moveSinkInput(((SinkInput) device), newSink);
|
||||
briHandler.getClient().moveSinkInput(((SinkInput) device), newSink);
|
||||
updateState = new StringType(newSink.getPaName());
|
||||
} else {
|
||||
logger.error("no sink {} found", command.toString());
|
||||
logger.warn("no sink {} found", command.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -361,25 +386,31 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
*/
|
||||
public int getLastVolume() {
|
||||
if (savedVolume == null) {
|
||||
PulseaudioBridgeHandler bridge = getPulseaudioBridgeHandler();
|
||||
// refresh to get the current volume level
|
||||
bridge.getClient().update();
|
||||
AbstractAudioDeviceConfig device = bridge.getDevice(name);
|
||||
if (device != null) {
|
||||
savedVolume = device.getVolume();
|
||||
PulseaudioBridgeHandler briHandler = getPulseaudioBridgeHandler();
|
||||
if (briHandler != null) {
|
||||
// refresh to get the current volume level
|
||||
briHandler.getClient().update();
|
||||
AbstractAudioDeviceConfig device = briHandler.getDevice(name);
|
||||
if (device != null) {
|
||||
savedVolume = device.getVolume();
|
||||
}
|
||||
}
|
||||
}
|
||||
return savedVolume == null ? 50 : savedVolume;
|
||||
}
|
||||
|
||||
public void setVolume(int volume) {
|
||||
PulseaudioBridgeHandler bridge = getPulseaudioBridgeHandler();
|
||||
AbstractAudioDeviceConfig device = bridge.getDevice(name);
|
||||
PulseaudioBridgeHandler briHandler = getPulseaudioBridgeHandler();
|
||||
if (briHandler == null) {
|
||||
logger.warn("bridge is not ready");
|
||||
return;
|
||||
}
|
||||
AbstractAudioDeviceConfig device = briHandler.getDevice(name);
|
||||
if (device == null) {
|
||||
logger.warn("missing device info, aborting");
|
||||
return;
|
||||
}
|
||||
bridge.getClient().setVolumePercent(device, volume);
|
||||
briHandler.getClient().setVolumePercent(device, volume);
|
||||
updateState(VOLUME_CHANNEL, new PercentType(volume));
|
||||
savedVolume = volume;
|
||||
}
|
||||
|
@ -411,7 +442,7 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
if (bridge != null) {
|
||||
return (String) bridge.getConfiguration().get(PulseaudioBindingConstants.BRIDGE_PARAMETER_HOST);
|
||||
} else {
|
||||
logger.error("A bridge must be configured for this pulseaudio thing");
|
||||
logger.warn("A bridge must be configured for this pulseaudio thing");
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
@ -425,8 +456,11 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
* @throws InterruptedException when interrupted during the loading module wait
|
||||
*/
|
||||
public int getSimpleTcpPort() throws IOException, InterruptedException {
|
||||
var bridgeHandler = getPulseaudioBridgeHandler();
|
||||
AbstractAudioDeviceConfig device = bridgeHandler.getDevice(name);
|
||||
var briHandler = getPulseaudioBridgeHandler();
|
||||
if (briHandler == null) {
|
||||
throw new IOException("bridge is not ready");
|
||||
}
|
||||
AbstractAudioDeviceConfig device = briHandler.getDevice(name);
|
||||
if (device == null) {
|
||||
throw new IOException("missing device info, device appears to be offline");
|
||||
}
|
||||
|
@ -439,7 +473,7 @@ public class PulseaudioHandler extends BaseThingHandler implements DeviceStatusL
|
|||
BigDecimal simpleRate = (BigDecimal) getThing().getConfiguration().get(DEVICE_PARAMETER_AUDIO_SOURCE_RATE);
|
||||
BigDecimal simpleChannels = (BigDecimal) getThing().getConfiguration()
|
||||
.get(DEVICE_PARAMETER_AUDIO_SOURCE_CHANNELS);
|
||||
return getPulseaudioBridgeHandler().getClient()
|
||||
return briHandler.getClient()
|
||||
.loadModuleSimpleProtocolTcpIfNeeded(device, simpleTcpPort, simpleFormat, simpleRate, simpleChannels)
|
||||
.orElse(simpleTcpPort);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue