]> git.basschouten.com Git - openhab-addons.git/blob
cc9b916179bb8264b8e5ad0367a927a54ca39929
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.denonmarantz.internal.connector;
14
15 import static org.openhab.binding.denonmarantz.internal.DenonMarantzBindingConstants.DB_OFFSET;
16
17 import java.math.BigDecimal;
18 import java.math.RoundingMode;
19 import java.util.concurrent.ScheduledExecutorService;
20
21 import org.openhab.binding.denonmarantz.internal.DenonMarantzState;
22 import org.openhab.binding.denonmarantz.internal.UnsupportedCommandTypeException;
23 import org.openhab.binding.denonmarantz.internal.config.DenonMarantzConfiguration;
24 import org.openhab.core.library.types.DecimalType;
25 import org.openhab.core.library.types.IncreaseDecreaseType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.PercentType;
28 import org.openhab.core.library.types.StringType;
29 import org.openhab.core.types.Command;
30 import org.openhab.core.types.RefreshType;
31
32 /**
33  * Abstract class containing common functionality for the connectors.
34  *
35  * @author Jan-Willem Veldhuis - Initial contribution
36  */
37 public abstract class DenonMarantzConnector {
38
39     private static final BigDecimal POINTFIVE = new BigDecimal("0.5");
40     protected ScheduledExecutorService scheduler;
41     protected DenonMarantzState state;
42     protected DenonMarantzConfiguration config;
43
44     public abstract void connect();
45
46     public abstract void dispose();
47
48     protected abstract void internalSendCommand(String command);
49
50     public void sendCustomCommand(Command command) throws UnsupportedCommandTypeException {
51         String cmd;
52         if (command instanceof StringType) {
53             cmd = command.toString();
54         } else {
55             throw new UnsupportedCommandTypeException();
56         }
57         internalSendCommand(cmd);
58     }
59
60     public void sendInputCommand(Command command, int zone) throws UnsupportedCommandTypeException {
61         String zonePrefix;
62         switch (zone) {
63             case 1:
64                 zonePrefix = "SI";
65                 break;
66             case 2:
67             case 3:
68             case 4:
69                 zonePrefix = "Z" + zone;
70                 break;
71             default:
72                 throw new UnsupportedCommandTypeException("Zone must be in range [1-4], zone: " + zone);
73         }
74         String cmd = zonePrefix;
75         if (command instanceof StringType) {
76             cmd += command.toString();
77         } else if (command instanceof RefreshType) {
78             cmd += "?";
79         } else {
80             throw new UnsupportedCommandTypeException();
81         }
82         internalSendCommand(cmd);
83     }
84
85     public void sendSurroundProgramCommand(Command command) throws UnsupportedCommandTypeException {
86         String cmd = "MS";
87         if (command instanceof RefreshType) {
88             cmd += "?";
89         } else {
90             throw new UnsupportedCommandTypeException();
91         }
92         internalSendCommand(cmd);
93     }
94
95     public void sendMuteCommand(Command command, int zone) throws UnsupportedCommandTypeException {
96         if (zone < 1 || zone > 4) {
97             throw new UnsupportedCommandTypeException("Zone must be in range [1-4], zone: " + zone);
98         }
99         StringBuilder sb = new StringBuilder();
100         if (zone != 1) {
101             sb.append("Z").append(zone);
102         }
103         sb.append("MU");
104         String cmd = sb.toString();
105         if (command == OnOffType.ON) {
106             cmd += "ON";
107         } else if (command == OnOffType.OFF) {
108             cmd += "OFF";
109         } else if (command instanceof RefreshType) {
110             cmd += "?";
111         } else {
112             throw new UnsupportedCommandTypeException();
113         }
114         internalSendCommand(cmd);
115     }
116
117     public void sendPowerCommand(Command command, int zone) throws UnsupportedCommandTypeException {
118         String zonePrefix;
119         switch (zone) {
120             case 0:
121                 zonePrefix = "PW";
122                 break;
123             case 1:
124                 zonePrefix = "ZM";
125                 break;
126             case 2:
127             case 3:
128             case 4:
129                 zonePrefix = "Z" + zone;
130                 break;
131             default:
132                 throw new UnsupportedCommandTypeException("Zone must be in range [0-4], zone: " + zone);
133         }
134         String cmd = zonePrefix;
135         if (command == OnOffType.ON) {
136             cmd += "ON";
137         } else if (command == OnOffType.OFF) {
138             cmd += (zone == 0) ? "STANDBY" : "OFF";
139         } else if (command instanceof RefreshType) {
140             cmd += "?";
141         } else {
142             throw new UnsupportedCommandTypeException();
143         }
144         internalSendCommand(cmd);
145     }
146
147     public void sendVolumeCommand(Command command, int zone) throws UnsupportedCommandTypeException {
148         String zonePrefix;
149         switch (zone) {
150             case 1:
151                 zonePrefix = "MV";
152                 break;
153             case 2:
154             case 3:
155             case 4:
156                 zonePrefix = "Z" + zone;
157                 break;
158             default:
159                 throw new UnsupportedCommandTypeException("Zone must be in range [1-4], zone: " + zone);
160         }
161         String cmd = zonePrefix;
162         if (command instanceof RefreshType) {
163             cmd += "?";
164         } else if (command == IncreaseDecreaseType.INCREASE) {
165             cmd += "UP";
166         } else if (command == IncreaseDecreaseType.DECREASE) {
167             cmd += "DOWN";
168         } else if (command instanceof DecimalType decimalCommand) {
169             cmd += toDenonValue(decimalCommand);
170         } else if (command instanceof PercentType percentCommand) {
171             cmd += percentToDenonValue(percentCommand.toBigDecimal());
172         } else {
173             throw new UnsupportedCommandTypeException();
174         }
175         internalSendCommand(cmd);
176     }
177
178     public void sendVolumeDbCommand(Command command, int zone) throws UnsupportedCommandTypeException {
179         Command dbCommand = command;
180         if (dbCommand instanceof PercentType) {
181             throw new UnsupportedCommandTypeException();
182         } else if (dbCommand instanceof DecimalType) {
183             // convert dB to 'normal' volume by adding the offset of 80
184             dbCommand = new DecimalType(((DecimalType) command).toBigDecimal().add(DB_OFFSET));
185         }
186         sendVolumeCommand(dbCommand, zone);
187     }
188
189     protected String toDenonValue(DecimalType number) {
190         String dbString = String.valueOf(number.intValue());
191         BigDecimal num = number.toBigDecimal();
192         if (num.compareTo(BigDecimal.TEN) == -1) {
193             dbString = "0" + dbString;
194         }
195         if (num.remainder(BigDecimal.ONE).equals(POINTFIVE)) {
196             dbString = dbString + "5";
197         }
198         return dbString;
199     }
200
201     protected String percentToDenonValue(BigDecimal pct) {
202         // Round to nearest number divisible by 0.5
203         BigDecimal percent = pct.divide(POINTFIVE).setScale(0, RoundingMode.UP).multiply(POINTFIVE)
204                 .min(config.getMainVolumeMax()).max(BigDecimal.ZERO);
205
206         return toDenonValue(new DecimalType(percent));
207     }
208 }