2 * Copyright (c) 2010-2021 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.omnilink.internal.handler;
15 import static org.openhab.binding.omnilink.internal.OmnilinkBindingConstants.*;
18 import java.util.concurrent.ScheduledFuture;
19 import java.util.concurrent.TimeUnit;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.omnilink.internal.discovery.ObjectPropertyRequest;
24 import org.openhab.binding.omnilink.internal.discovery.ObjectPropertyRequests;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.library.types.StringType;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.types.Command;
32 import org.openhab.core.types.RefreshType;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 import com.digitaldan.jomnilinkII.Message;
37 import com.digitaldan.jomnilinkII.MessageTypes.AudioSourceStatus;
38 import com.digitaldan.jomnilinkII.MessageTypes.properties.AudioSourceProperties;
39 import com.digitaldan.jomnilinkII.OmniInvalidResponseException;
40 import com.digitaldan.jomnilinkII.OmniUnknownMessageTypeException;
43 * The {@link AudioSourceHandler} defines some methods that are used to
44 * interface with an OmniLink Audio Source. This by extension also defines the
45 * Audio Source thing that openHAB will be able to pick up and interface with.
47 * @author Brian O'Connell - Initial contribution
48 * @author Ethan Dye - openHAB3 rewrite
51 public class AudioSourceHandler extends AbstractOmnilinkHandler {
52 private final Logger logger = LoggerFactory.getLogger(AudioSourceHandler.class);
53 private final int POLL_DELAY_SECONDS = 5;
54 private final int thingID = getThingNumber();
55 private @Nullable ScheduledFuture<?> scheduledPolling = null;
56 public @Nullable String number;
58 public AudioSourceHandler(Thing thing) {
63 public void initialize() {
64 final OmnilinkBridgeHandler bridgeHandler = getOmnilinkBridgeHandler();
65 if (bridgeHandler != null) {
66 updateStatus(ThingStatus.ONLINE);
67 if (((Boolean) getThing().getConfiguration().get(THING_PROPERTIES_AUTO_START)).booleanValue()) {
68 logger.debug("Autostart enabled, scheduling polling for Audio Source: {}", thingID);
71 logger.debug("Autostart disabled, not scheduling polling for Audio Source: {}", thingID);
74 updateAudioSourceProperties(bridgeHandler);
76 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
77 "Received null bridge while initializing Audio Source!");
81 private void updateAudioSourceProperties(OmnilinkBridgeHandler bridgeHandler) {
82 ObjectPropertyRequest<AudioSourceProperties> objectPropertyRequest = ObjectPropertyRequest
83 .builder(bridgeHandler, ObjectPropertyRequests.AUDIO_SOURCE, thingID, 0).selectNamed().build();
85 for (AudioSourceProperties audioSourceProperties : objectPropertyRequest) {
86 Map<String, String> properties = editProperties();
87 properties.put(THING_PROPERTIES_NAME, audioSourceProperties.getName());
88 updateProperties(properties);
93 public synchronized void dispose() {
98 private synchronized void cancelPolling() {
99 final ScheduledFuture<?> scheduledPolling = this.scheduledPolling;
100 if (scheduledPolling != null) {
101 logger.debug("Cancelling polling for Audio Source: {}", thingID);
102 scheduledPolling.cancel(false);
106 private synchronized void schedulePolling() {
108 logger.debug("Scheduling polling for Audio Source: {}", thingID);
109 scheduledPolling = super.scheduler.scheduleWithFixedDelay(this::pollAudioSource, 0, POLL_DELAY_SECONDS,
114 public void handleCommand(ChannelUID channelUID, Command command) {
115 logger.debug("handleCommand called for channel: {}, command: {}", channelUID, command);
116 final ScheduledFuture<?> scheduledPolling = this.scheduledPolling;
118 switch (channelUID.getId()) {
119 case CHANNEL_AUDIO_SOURCE_POLLING:
120 if (command instanceof RefreshType) {
121 updateState(CHANNEL_AUDIO_SOURCE_POLLING,
122 OnOffType.from((scheduledPolling != null && !scheduledPolling.isDone())));
123 } else if (command instanceof OnOffType) {
124 handlePolling(channelUID, (OnOffType) command);
126 logger.debug("Invalid command: {}, must be RefreshType or OnOffType", command);
130 logger.warn("Unknown channel for Audio Source thing: {}", channelUID);
134 private void handlePolling(ChannelUID channelUID, OnOffType command) {
135 logger.debug("handlePolling called for channel: {}, command: {}", channelUID, command);
136 if (OnOffType.ON.equals(command)) {
143 public void pollAudioSource() {
145 final OmnilinkBridgeHandler bridge = getOmnilinkBridgeHandler();
146 if (bridge != null) {
149 while ((message = bridge.requestAudioSourceStatus(thingID, position))
150 .getMessageType() == Message.MESG_TYPE_AUDIO_SOURCE_STATUS) {
151 logger.trace("Polling for Audio Source statuses on thing: {}", thingID);
152 AudioSourceStatus audioSourceStatus = (AudioSourceStatus) message;
153 position = audioSourceStatus.getPosition();
156 updateState(CHANNEL_AUDIO_SOURCE_TEXT1, new StringType(audioSourceStatus.getSourceData()));
159 updateState(CHANNEL_AUDIO_SOURCE_TEXT2, new StringType(audioSourceStatus.getSourceData()));
162 updateState(CHANNEL_AUDIO_SOURCE_TEXT3, new StringType(audioSourceStatus.getSourceData()));
165 updateState(CHANNEL_AUDIO_SOURCE_TEXT4, new StringType(audioSourceStatus.getSourceData()));
168 updateState(CHANNEL_AUDIO_SOURCE_TEXT5, new StringType(audioSourceStatus.getSourceData()));
171 updateState(CHANNEL_AUDIO_SOURCE_TEXT6, new StringType(audioSourceStatus.getSourceData()));
176 logger.debug("Received null bridge while polling Audio Source statuses!");
178 } catch (OmniInvalidResponseException | OmniUnknownMessageTypeException | BridgeOfflineException e) {
179 logger.debug("Exception recieved while polling for Audio Source statuses: {}", e.getMessage());