]> git.basschouten.com Git - openhab-addons.git/blob
6fc2dc6c8b839aa85e4358543ed096d262478163
[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.monopriceaudio.internal.communication;
14
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.monopriceaudio.internal.configuration.MonopriceAudioThingConfiguration;
23 import org.openhab.binding.monopriceaudio.internal.dto.MonopriceAudioZoneDTO;
24 import org.openhab.core.types.StateOption;
25
26 /**
27  * The {@link AmplifierModel} is responsible for mapping low level communications for each supported amplifier model.
28  *
29  * @author Michael Lobstein - Initial contribution
30  */
31 @NonNullByDefault
32 public enum AmplifierModel {
33
34     // Monoprice 10761/Dayton Audio DAX66
35     MONOPRICE("<", "\r", "?", "", "#>", "PR", "CH", "VO", "MU", "TR", "BS", "BL", "DT", 38, -7, 7, 7, -10, 10, 10, 18,
36             6, true, List.of("11", "12", "13", "14", "15", "16", "21", "22", "23", "24", "25", "26", "31", "32", "33",
37                     "34", "35", "36")) {
38         @Override
39         public MonopriceAudioZoneDTO getZoneData(String newZoneData) {
40             return getMonopriceZoneData(newZoneData);
41         }
42
43         @Override
44         public List<StateOption> getSourceLabels(MonopriceAudioThingConfiguration config) {
45             return List.of(new StateOption("1", config.inputLabel1), new StateOption("2", config.inputLabel2),
46                     new StateOption("3", config.inputLabel3), new StateOption("4", config.inputLabel4),
47                     new StateOption("5", config.inputLabel5), new StateOption("6", config.inputLabel6));
48         }
49     },
50     // Dayton Audio DAX88
51     DAX88("<", "\r", "?", "", ">", "PR", "CH", "VO", "MU", "TR", "BS", "BL", "DT", 38, -12, 12, 12, -10, 10, 10, 8, 8,
52             true, List.of("01", "02", "03", "04", "05", "06", "07", "08")) {
53         @Override
54         public MonopriceAudioZoneDTO getZoneData(String newZoneData) {
55             return getMonopriceZoneData(newZoneData);
56         }
57
58         @Override
59         public List<StateOption> getSourceLabels(MonopriceAudioThingConfiguration config) {
60             return List.of(new StateOption("1", config.inputLabel1), new StateOption("2", config.inputLabel2),
61                     new StateOption("3", config.inputLabel3), new StateOption("4", config.inputLabel4),
62                     new StateOption("5", config.inputLabel5), new StateOption("6", config.inputLabel6),
63                     new StateOption("7", config.inputLabel7), new StateOption("8", config.inputLabel8));
64         }
65     },
66     MONOPRICE70("!", "+\r", "?", "ZS", "?", "PR", "IS", "VO", "MU", "TR", "BS", "BA", "", 38, -7, 7, 7, -32, 31, 32, 6,
67             2, false, List.of("1", "2", "3", "4", "5", "6")) {
68         @Override
69         public MonopriceAudioZoneDTO getZoneData(String newZoneData) {
70             MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO();
71
72             Matcher matcher = MONOPRICE70_PATTERN.matcher(newZoneData);
73             if (matcher.find()) {
74                 zoneData.setZone(matcher.group(1));
75                 zoneData.setVolume(Integer.parseInt(matcher.group(2)));
76                 zoneData.setPower(matcher.group(3));
77                 zoneData.setMute(matcher.group(4));
78                 zoneData.setSource(matcher.group(5));
79                 return zoneData;
80             }
81
82             matcher = MONOPRICE70_TREB_PATTERN.matcher(newZoneData);
83             if (matcher.find()) {
84                 zoneData.setZone(matcher.group(1));
85                 zoneData.setTreble(Integer.parseInt(matcher.group(2)));
86                 return zoneData;
87             }
88
89             matcher = MONOPRICE70_BASS_PATTERN.matcher(newZoneData);
90             if (matcher.find()) {
91                 zoneData.setZone(matcher.group(1));
92                 zoneData.setBass(Integer.parseInt(matcher.group(2)));
93                 return zoneData;
94             }
95
96             matcher = MONOPRICE70_BALN_PATTERN.matcher(newZoneData);
97             if (matcher.find()) {
98                 zoneData.setZone(matcher.group(1));
99                 zoneData.setBalance(Integer.parseInt(matcher.group(2)));
100                 return zoneData;
101             }
102
103             return zoneData;
104         }
105
106         @Override
107         public List<StateOption> getSourceLabels(MonopriceAudioThingConfiguration config) {
108             return List.of(new StateOption("0", config.inputLabel1), new StateOption("1", config.inputLabel2));
109         }
110     },
111     XANTECH("!", "+\r", "?", "ZD", "#", "PR", "SS", "VO", "MU", "TR", "BS", "BL", "", 38, -7, 7, 7, -32, 31, 32, 16, 8,
112             false, List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16")) {
113         @Override
114         public MonopriceAudioZoneDTO getZoneData(String newZoneData) {
115             MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO();
116             Matcher matcher = XANTECH_PATTERN.matcher(newZoneData);
117
118             if (matcher.find()) {
119                 zoneData.setZone(matcher.group(1));
120                 zoneData.setPower(matcher.group(2));
121                 zoneData.setSource(matcher.group(3));
122                 zoneData.setVolume(Integer.parseInt(matcher.group(4)));
123                 zoneData.setMute(matcher.group(5));
124                 zoneData.setTreble(Integer.parseInt(matcher.group(6)));
125                 zoneData.setBass(Integer.parseInt(matcher.group(7)));
126                 zoneData.setBalance(Integer.parseInt(matcher.group(8)));
127                 zoneData.setKeypad(matcher.group(9));
128                 zoneData.setPage(matcher.group(10));
129             }
130             return zoneData;
131         }
132
133         @Override
134         public List<StateOption> getSourceLabels(MonopriceAudioThingConfiguration config) {
135             return List.of(new StateOption("1", config.inputLabel1), new StateOption("2", config.inputLabel2),
136                     new StateOption("3", config.inputLabel3), new StateOption("4", config.inputLabel4),
137                     new StateOption("5", config.inputLabel5), new StateOption("6", config.inputLabel6),
138                     new StateOption("7", config.inputLabel7), new StateOption("8", config.inputLabel8));
139         }
140     };
141
142     // Used by 10761/DAX66 and DAX88
143     private static MonopriceAudioZoneDTO getMonopriceZoneData(String newZoneData) {
144         MonopriceAudioZoneDTO zoneData = new MonopriceAudioZoneDTO();
145         Matcher matcher = MONOPRICE_PATTERN.matcher(newZoneData);
146
147         if (matcher.find()) {
148             zoneData.setZone(matcher.group(1));
149             zoneData.setPage(matcher.group(2));
150             zoneData.setPower(matcher.group(3));
151             zoneData.setMute(matcher.group(4));
152             zoneData.setDnd(matcher.group(5));
153             zoneData.setVolume(Integer.parseInt(matcher.group(6)));
154             zoneData.setTreble(Integer.parseInt(matcher.group(7)));
155             zoneData.setBass(Integer.parseInt(matcher.group(8)));
156             zoneData.setBalance(Integer.parseInt(matcher.group(9)));
157             zoneData.setSource(matcher.group(10));
158             zoneData.setKeypad(matcher.group(11));
159         }
160         return zoneData;
161     }
162
163     // Monoprice 10761/DAX66 status string: #>1200010000130809100601
164     // DAX88 status string is the same but does not have leading '#': >xxaabbccddeeffgghhiijj
165     private static final Pattern MONOPRICE_PATTERN = Pattern
166             .compile("^#?>(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})");
167
168     // Monoprice 31028 / PAM1270 status string: ?6ZS VO8 PO1 MU0 IS0+ (does not include treble, bass & balance)
169     private static final Pattern MONOPRICE70_PATTERN = Pattern
170             .compile("^\\?(\\d{1})ZS VO(\\d{1,2}) PO(\\d{1}) MU(\\d{1}) IS(\\d{1})+");
171     private static final Pattern MONOPRICE70_TREB_PATTERN = Pattern.compile("^\\?(\\d{1})TR(\\d{1,2})+");
172     private static final Pattern MONOPRICE70_BASS_PATTERN = Pattern.compile("^\\?(\\d{1})BS(\\d{1,2})+");
173     private static final Pattern MONOPRICE70_BALN_PATTERN = Pattern.compile("^\\?(\\d{1})BA(\\d{1,2})+");
174
175     // Xantech status string: #1ZS PR0 SS1 VO0 MU1 TR7 BS7 BA32 LS0 PS0+
176     private static final Pattern XANTECH_PATTERN = Pattern.compile(
177             "^#(\\d{1,2})ZS PR(\\d{1}) SS(\\d{1}) VO(\\d{1,2}) MU(\\d{1}) TR(\\d{1,2}) BS(\\d{1,2}) BA(\\d{1,2}) LS(\\d{1}) PS(\\d{1})+");
178
179     private String cmdPrefix;
180     private String cmdSuffix;
181     private String queryPrefix;
182     private String querySuffix;
183     private String respPrefix;
184     private String powerCmd;
185     private String sourceCmd;
186     private String volumeCmd;
187     private String muteCmd;
188     private String trebleCmd;
189     private String bassCmd;
190     private String balanceCmd;
191     private String dndCmd;
192     private int maxVol;
193     private int minTone;
194     private int maxTone;
195     private int toneOffset;
196     private int minBal;
197     private int maxBal;
198     private int balOffset;
199     private int maxZones;
200     private int numSources;
201     private boolean padNumbers;
202     private List<String> zoneIds;
203     private Map<String, String> zoneIdMap = new HashMap<>();
204
205     private static final String ON_STR = "1";
206     private static final String OFF_STR = "0";
207
208     private static final String ON_STR_PAD = "01";
209     private static final String OFF_STR_PAD = "00";
210
211     /**
212      * Constructor for all the enum parameters
213      *
214      **/
215     AmplifierModel(String cmdPrefix, String cmdSuffix, String queryPrefix, String querySuffix, String respPrefix,
216             String powerCmd, String sourceCmd, String volumeCmd, String muteCmd, String trebleCmd, String bassCmd,
217             String balanceCmd, String dndCmd, int maxVol, int minTone, int maxTone, int toneOffset, int minBal,
218             int maxBal, int balOffset, int maxZones, int numSources, boolean padNumbers, List<String> zoneIds) {
219         this.cmdPrefix = cmdPrefix;
220         this.cmdSuffix = cmdSuffix;
221         this.queryPrefix = queryPrefix;
222         this.querySuffix = querySuffix;
223         this.respPrefix = respPrefix;
224         this.powerCmd = powerCmd;
225         this.sourceCmd = sourceCmd;
226         this.volumeCmd = volumeCmd;
227         this.muteCmd = muteCmd;
228         this.trebleCmd = trebleCmd;
229         this.bassCmd = bassCmd;
230         this.balanceCmd = balanceCmd;
231         this.dndCmd = dndCmd;
232         this.maxVol = maxVol;
233         this.minTone = minTone;
234         this.maxTone = maxTone;
235         this.toneOffset = toneOffset;
236         this.minBal = minBal;
237         this.maxBal = maxBal;
238         this.balOffset = balOffset;
239         this.maxZones = maxZones;
240         this.numSources = numSources;
241         this.padNumbers = padNumbers;
242         this.zoneIds = zoneIds;
243
244         int i = 1;
245         for (String zoneId : zoneIds) {
246             zoneIdMap.put(zoneId, "zone" + i);
247             i++;
248         }
249     }
250
251     public abstract MonopriceAudioZoneDTO getZoneData(String newZoneData);
252
253     public abstract List<StateOption> getSourceLabels(MonopriceAudioThingConfiguration config);
254
255     public String getZoneIdFromZoneName(String zoneName) {
256         for (String zoneId : zoneIdMap.keySet()) {
257             if (zoneIdMap.get(zoneId).equals(zoneName)) {
258                 return zoneId;
259             }
260         }
261         return "";
262     }
263
264     public String getZoneName(String zoneId) {
265         String zoneName = zoneIdMap.get(zoneId);
266         if (zoneName != null) {
267             return zoneName;
268         } else {
269             return "";
270         }
271     }
272
273     public String getCmdPrefix() {
274         return cmdPrefix;
275     }
276
277     public String getQueryPrefix() {
278         return queryPrefix;
279     }
280
281     public String getQuerySuffix() {
282         return querySuffix;
283     }
284
285     public String getRespPrefix() {
286         return respPrefix;
287     }
288
289     public String getPowerCmd() {
290         return powerCmd;
291     }
292
293     public String getSourceCmd() {
294         return sourceCmd;
295     }
296
297     public String getVolumeCmd() {
298         return volumeCmd;
299     }
300
301     public String getMuteCmd() {
302         return muteCmd;
303     }
304
305     public String getTrebleCmd() {
306         return trebleCmd;
307     }
308
309     public String getBassCmd() {
310         return bassCmd;
311     }
312
313     public String getBalanceCmd() {
314         return balanceCmd;
315     }
316
317     public String getDndCmd() {
318         return dndCmd;
319     }
320
321     public int getMaxVol() {
322         return maxVol;
323     }
324
325     public int getMinTone() {
326         return minTone;
327     }
328
329     public int getMaxTone() {
330         return maxTone;
331     }
332
333     public int getMinBal() {
334         return minBal;
335     }
336
337     public int getMaxBal() {
338         return maxBal;
339     }
340
341     public int getBalOffset() {
342         return balOffset;
343     }
344
345     public int getToneOffset() {
346         return toneOffset;
347     }
348
349     public int getMaxZones() {
350         return maxZones;
351     }
352
353     public int getNumSources() {
354         return numSources;
355     }
356
357     public String getCmdSuffix() {
358         return cmdSuffix;
359     }
360
361     public List<String> getZoneIds() {
362         return zoneIds;
363     }
364
365     public String getFormattedValue(Integer value) {
366         if (padNumbers) {
367             return String.format("%02d", value);
368         } else {
369             return value.toString();
370         }
371     }
372
373     public String getOnStr() {
374         if (padNumbers) {
375             return ON_STR_PAD;
376         } else {
377             return ON_STR;
378         }
379     }
380
381     public String getOffStr() {
382         if (padNumbers) {
383             return OFF_STR_PAD;
384         } else {
385             return OFF_STR;
386         }
387     }
388 }