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