2 * Copyright (c) 2010-2022 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.rotel.internal.protocol.ascii;
15 import static org.openhab.binding.rotel.internal.RotelBindingConstants.*;
17 import java.nio.charset.StandardCharsets;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.rotel.internal.RotelException;
22 import org.openhab.binding.rotel.internal.RotelModel;
23 import org.openhab.binding.rotel.internal.communication.RotelCommand;
24 import org.openhab.binding.rotel.internal.protocol.RotelProtocol;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Class for handling the Rotel ASCII V2 protocol (build of command messages, decoding of incoming data)
31 * @author Laurent Garnier - Initial contribution
34 public class RotelAsciiV2ProtocolHandler extends RotelAbstractAsciiProtocolHandler {
36 private static final char CHAR_END_RESPONSE = '$';
38 private final Logger logger = LoggerFactory.getLogger(RotelAsciiV2ProtocolHandler.class);
43 * @param model the Rotel model in use
45 public RotelAsciiV2ProtocolHandler(RotelModel model) {
46 super(model, CHAR_END_RESPONSE);
50 public RotelProtocol getProtocol() {
51 return RotelProtocol.ASCII_V2;
55 public byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) throws RotelException {
56 String messageStr = cmd.getAsciiCommandV2();
57 if (messageStr == null) {
58 throw new RotelException("Command \"" + cmd.getName() + "\" ignored: not available for ASCII V2 protocol");
63 case ZONE1_VOLUME_SET:
64 case ZONE2_VOLUME_SET:
65 case ZONE3_VOLUME_SET:
66 case ZONE4_VOLUME_SET:
67 messageStr += String.format("%02d", value);
75 case ZONE1_TREBLE_SET:
76 case ZONE2_TREBLE_SET:
77 case ZONE3_TREBLE_SET:
78 case ZONE4_TREBLE_SET:
81 } else if (value > 0) {
82 messageStr += String.format("+%02d", value);
84 messageStr += String.format("-%02d", -value);
88 case ZONE1_BALANCE_SET:
89 case ZONE2_BALANCE_SET:
90 case ZONE3_BALANCE_SET:
91 case ZONE4_BALANCE_SET:
94 } else if (value > 0) {
95 messageStr += String.format("r%02d", value);
97 messageStr += String.format("l%02d", -value);
100 case DIMMER_LEVEL_SET:
101 if (value > 0 && model.getDimmerLevelMin() < 0) {
102 messageStr += String.format("+%d", value);
104 messageStr += String.format("%d", value);
111 if (!messageStr.endsWith("?")) {
114 byte[] message = messageStr.getBytes(StandardCharsets.US_ASCII);
115 logger.debug("Command \"{}\" => {}", cmd.getName(), messageStr);
120 protected void dispatchKeyValue(String key, String value) {
121 // For distribution amplifiers, we need to split certain values to get the value for each zone
122 if (model == RotelModel.C8 && value.contains(",")) {
131 String[] splitValues = value.split(",");
132 int nb = splitValues.length;
133 if (nb > MAX_NUMBER_OF_ZONES) {
134 nb = MAX_NUMBER_OF_ZONES;
136 for (int i = 1; i <= nb; i++) {
137 String val = KEY_INPUT.equals(key) ? String.format("z%d:input_%s", i, splitValues[i - 1])
138 : splitValues[i - 1];
139 dispatchKeyValue(String.format("%s_zone%d", key, i), val);
143 super.dispatchKeyValue(key, value);
147 super.dispatchKeyValue(key, value);