Skip to content

Commit

Permalink
[rotel] New channel for other commands provided by the API
Browse files Browse the repository at this point in the history
Models covered by this PR:
A11, A12, A14, CD11, CD12, RA11, RA12, RA1570, RA1572, RC1570, RC1572, RCD1572, P5, X3, X5,
RSP-1066, RSP-1068, RSP-1069, RSP-1098, RSP-1570, RSP-1572,
RSX-1055, RSX-1056, RSX-1057, RSX-1058, RSX-1065, RSX-1067, RSX-1550, RSX-1560, RSX-1562

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
  • Loading branch information
lolodomo committed Jul 30, 2022
1 parent cf32ecf commit 3d5b9f6
Show file tree
Hide file tree
Showing 30 changed files with 821 additions and 133 deletions.
98 changes: 68 additions & 30 deletions bundles/org.openhab.binding.rotel/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public class RotelBindingConstants {
public static final String CHANNEL_BALANCE = "balance";
public static final String CHANNEL_SPEAKER_A = "speakera";
public static final String CHANNEL_SPEAKER_B = "speakerb";
public static final String CHANNEL_OTHER_COMMAND = "otherCommand";

public static final String CHANNEL_GROUP_ALL_ZONES = "allZones";
public static final String CHANNEL_ALL_POWER = CHANNEL_GROUP_ALL_ZONES + "#" + CHANNEL_POWER;
Expand All @@ -161,6 +162,7 @@ public class RotelBindingConstants {
public static final String CHANNEL_MAIN_MUTE = CHANNEL_GROUP_MAIN_ZONE + "#" + CHANNEL_MUTE;
public static final String CHANNEL_MAIN_BASS = CHANNEL_GROUP_MAIN_ZONE + "#" + CHANNEL_BASS;
public static final String CHANNEL_MAIN_TREBLE = CHANNEL_GROUP_MAIN_ZONE + "#" + CHANNEL_TREBLE;
public static final String CHANNEL_MAIN_OTHER_COMMAND = CHANNEL_GROUP_MAIN_ZONE + "#" + CHANNEL_OTHER_COMMAND;

public static final String CHANNEL_GROUP_ZONE1 = "zone1";
public static final String CHANNEL_ZONE1_SOURCE = CHANNEL_GROUP_ZONE1 + "#" + CHANNEL_SOURCE;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.rotel.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.thing.binding.BaseDynamicCommandDescriptionProvider;
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
import org.openhab.core.thing.type.DynamicCommandDescriptionProvider;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* Dynamic provider of command options
*
* @author Laurent Garnier - Initial contribution
*/
@Component(service = { DynamicCommandDescriptionProvider.class, RotelCommandDescriptionOptionProvider.class })
@NonNullByDefault
public class RotelCommandDescriptionOptionProvider extends BaseDynamicCommandDescriptionProvider {

@Activate
public RotelCommandDescriptionOptionProvider(final @Reference EventPublisher eventPublisher, //
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, //
final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
this.eventPublisher = eventPublisher;
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ public class RotelHandlerFactory extends BaseThingHandlerFactory {

private final SerialPortManager serialPortManager;
private final RotelStateDescriptionOptionProvider stateDescriptionProvider;
private final RotelCommandDescriptionOptionProvider commandDescriptionProvider;

@Activate
public RotelHandlerFactory(final @Reference SerialPortManager serialPortManager,
final @Reference RotelStateDescriptionOptionProvider stateDescriptionProvider) {
final @Reference RotelStateDescriptionOptionProvider stateDescriptionProvider,
final @Reference RotelCommandDescriptionOptionProvider commandDescriptionProvider) {
this.serialPortManager = serialPortManager;
this.stateDescriptionProvider = stateDescriptionProvider;
this.commandDescriptionProvider = commandDescriptionProvider;
}

@Override
Expand All @@ -74,7 +77,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
return new RotelHandler(thing, stateDescriptionProvider, serialPortManager);
return new RotelHandler(thing, stateDescriptionProvider, commandDescriptionProvider, serialPortManager);
}

return null;
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,6 @@ public static RotelDsp getFromCommand(int category, RotelCommand command) throws
return value;
}
}
throw new RotelException("Invalid command for a DSP mode: " + command.getName());
throw new RotelException("Invalid command for a DSP mode: " + command.getLabel());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -770,11 +770,11 @@ public void buildFeedbackMessage(RotelCommand cmd, @Nullable Integer value) {
case PLAY_STATUS:
textAscii = buildPlayStatusAsciiResponse();
break;
case TRACK_FORWARD:
case TRACK_FWD:
track++;
textAscii = buildTrackAsciiResponse();
break;
case TRACK_BACKWORD:
case TRACK_BACK:
if (track > 1) {
track--;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,6 @@ public static RotelSource getFromCommand(int category, RotelCommand command, int
return value;
}
}
throw new RotelException("Invalid command for a source: " + command.getName());
throw new RotelException("Invalid command for a source: " + command.getLabel());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.rotel.internal.RotelBindingConstants;
import org.openhab.binding.rotel.internal.RotelCommandDescriptionOptionProvider;
import org.openhab.binding.rotel.internal.RotelException;
import org.openhab.binding.rotel.internal.RotelModel;
import org.openhab.binding.rotel.internal.RotelPlayStatus;
Expand Down Expand Up @@ -60,6 +61,7 @@
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.CommandOption;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.StateOption;
Expand All @@ -82,13 +84,14 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL
private static final boolean USE_SIMULATED_DEVICE = false;
private static final int SLEEP_INTV = 30;

private final RotelStateDescriptionOptionProvider stateDescriptionProvider;
private final RotelCommandDescriptionOptionProvider commandDescriptionProvider;
private final SerialPortManager serialPortManager;

private @Nullable ScheduledFuture<?> reconnectJob;
private @Nullable ScheduledFuture<?> powerOffJob;
private @Nullable ScheduledFuture<?>[] powerOnZoneJobs = { null, null, null, null, null };

private RotelStateDescriptionOptionProvider stateDescriptionProvider;
private SerialPortManager serialPortManager;

private RotelModel model;
private RotelProtocol protocol;
private RotelAbstractProtocolHandler protocolHandler;
Expand Down Expand Up @@ -132,9 +135,10 @@ public class RotelHandler extends BaseThingHandler implements RotelMessageEventL
* Constructor
*/
public RotelHandler(Thing thing, RotelStateDescriptionOptionProvider stateDescriptionProvider,
SerialPortManager serialPortManager) {
RotelCommandDescriptionOptionProvider commandDescriptionProvider, SerialPortManager serialPortManager) {
super(thing);
this.stateDescriptionProvider = stateDescriptionProvider;
this.commandDescriptionProvider = commandDescriptionProvider;
this.serialPortManager = serialPortManager;
this.model = DEFAULT_MODEL;
this.protocolHandler = new RotelHexProtocolHandler(model, Map.of());
Expand Down Expand Up @@ -460,6 +464,14 @@ public void initialize() {
model.getDspStateOptions());
}

List<CommandOption> options = model.getOtherCommandsOptions(protocol);
if (!options.isEmpty()) {
commandDescriptionProvider.setCommandOptions(new ChannelUID(getThing().getUID(), CHANNEL_OTHER_COMMAND),
options);
commandDescriptionProvider
.setCommandOptions(new ChannelUID(getThing().getUID(), CHANNEL_MAIN_OTHER_COMMAND), options);
}

updateStatus(ThingStatus.UNKNOWN);

scheduleReconnectJob();
Expand Down Expand Up @@ -785,9 +797,9 @@ public void handleCommand(ChannelUID channelUID, Command command) {
sendCommand(RotelCommand.PLAY_STATUS);
}
} else if (command instanceof NextPreviousType && command == NextPreviousType.NEXT) {
sendCommand(RotelCommand.TRACK_FORWARD);
sendCommand(RotelCommand.TRACK_FWD);
} else if (command instanceof NextPreviousType && command == NextPreviousType.PREVIOUS) {
sendCommand(RotelCommand.TRACK_BACKWORD);
sendCommand(RotelCommand.TRACK_BACK);
} else {
success = false;
logger.debug("Command {} from channel {} failed: invalid command value", command, channel);
Expand Down Expand Up @@ -903,6 +915,24 @@ public void handleCommand(ChannelUID channelUID, Command command) {
RotelCommand.SPEAKER_B_OFF, RotelCommand.SPEAKER_B_TOGGLE);
}
break;
case CHANNEL_OTHER_COMMAND:
case CHANNEL_MAIN_OTHER_COMMAND:
if (!isPowerOn()) {
success = false;
logger.debug("Command {} from channel {} ignored: device in standby", command, channel);
} else {
try {
cmd = RotelCommand.getFromName(command.toString());
} catch (RotelException e) {
success = false;
logger.debug("Command {} from channel {} failed: undefined command", command, channel);
cmd = null;
}
if (cmd != null) {
sendCommand(cmd);
}
}
break;
default:
success = false;
logger.debug("Command {} from channel {} failed: nnexpected command", command, channel);
Expand Down Expand Up @@ -2717,7 +2747,7 @@ private void sendCommand(RotelCommand cmd, @Nullable Integer value) throws Rotel
logger.debug("sendCommand: {}", e.getMessage());
return;
}
connector.writeOutput(cmd.getName(), message);
connector.writeOutput(cmd.getLabel(), message);

if (connector instanceof RotelSimuConnector) {
if ((protocol == RotelProtocol.HEX && cmd.getHexType() != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public RotelProtocol getProtocol() {
public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) throws RotelException {
String messageStr = cmd.getAsciiCommandV1();
if (messageStr == null) {
throw new RotelException("Command \"" + cmd.getName() + "\" ignored: not available for ASCII V1 protocol");
throw new RotelException("Command \"" + cmd.getLabel() + "\" ignored: not available for ASCII V1 protocol");
}
if (value != null) {
switch (cmd) {
Expand Down Expand Up @@ -94,7 +94,7 @@ public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) thr
messageStr += "!";
}
byte[] message = messageStr.getBytes(StandardCharsets.US_ASCII);
logger.debug("Command \"{}\" => {}", cmd.getName(), messageStr);
logger.debug("Command \"{}\" => {}", cmd.getLabel(), messageStr);
return message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public RotelProtocol getProtocol() {
public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) throws RotelException {
String messageStr = cmd.getAsciiCommandV2();
if (messageStr == null) {
throw new RotelException("Command \"" + cmd.getName() + "\" ignored: not available for ASCII V2 protocol");
throw new RotelException("Command \"" + cmd.getLabel() + "\" ignored: not available for ASCII V2 protocol");
}
if (value != null) {
switch (cmd) {
Expand Down Expand Up @@ -112,7 +112,7 @@ public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) thr
messageStr += "!";
}
byte[] message = messageStr.getBytes(StandardCharsets.US_ASCII);
logger.debug("Command \"{}\" => {}", cmd.getName(), messageStr);
logger.debug("Command \"{}\" => {}", cmd.getLabel(), messageStr);
return message;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public RotelProtocol getProtocol() {
@Override
public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) throws RotelException {
if (cmd.getHexType() == 0) {
throw new RotelException("Command \"" + cmd.getName() + "\" ignored: not available for HEX protocol");
throw new RotelException("Command \"" + cmd.getLabel() + "\" ignored: not available for HEX protocol");
}
final int size = 6;
byte[] message = new byte[size];
Expand All @@ -151,7 +151,7 @@ public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) thr
} else {
message[idx++] = checksum;
}
logger.debug("Command \"{}\" => {}", cmd.getName(), HexUtils.bytesToHex(message));
logger.debug("Command \"{}\" => {}", cmd.getLabel(), HexUtils.bytesToHex(message));
return message;
}

Expand Down
Loading

0 comments on commit 3d5b9f6

Please sign in to comment.