]> git.basschouten.com Git - openhab-addons.git/blob
8d5c2c25eaf2cb2986980dd828ad37fb47040035
[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.homematic.internal.communicator.parser;
14
15 import static org.openhab.binding.homematic.internal.misc.HomematicConstants.*;
16
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
21
22 import org.openhab.binding.homematic.internal.model.HmChannel;
23 import org.openhab.binding.homematic.internal.model.HmDatapoint;
24 import org.openhab.binding.homematic.internal.model.HmDatapointInfo;
25 import org.openhab.binding.homematic.internal.model.HmParamsetType;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Extracts the possible options from the remote control metadata and parses the DISPLAY_OPTIONS virtual datapoint.
31  *
32  * @author Gerhard Riegler - Initial contribution
33  */
34
35 public class DisplayOptionsParser extends CommonRpcParser<Object, Void> {
36     private final Logger logger = LoggerFactory.getLogger(DisplayOptionsParser.class);
37     private static final String[] ON_OFF = new String[] { "ON", "OFF" };
38     private static final int IDX_NOT_FOUND = -1;
39     private HmChannel channel;
40     private String text;
41     private int beep = 0;
42     private int backlight = 0;
43     private int unit = 0;
44     private List<String> symbols = new ArrayList<>();
45
46     public DisplayOptionsParser(HmChannel channel) {
47         this.channel = channel;
48     }
49
50     @Override
51     public Void parse(Object value) throws IOException {
52         String valueString = toString(value);
53         String optionsString = valueString == null ? null : valueString.replace(" ", "");
54         if (optionsString != null) {
55             int idxFirstSep = optionsString.indexOf(",");
56             if (idxFirstSep == -1) {
57                 text = optionsString;
58                 optionsString = "";
59             } else {
60                 text = optionsString.substring(0, idxFirstSep);
61                 optionsString = optionsString.substring(idxFirstSep + 1);
62             }
63
64             String[] options = optionsString.split(",");
65
66             String[] availableSymbols = getAvailableSymbols(channel);
67             String[] availableBeepOptions = getAvailableOptions(channel, DATAPOINT_NAME_BEEP);
68             String[] availableBacklightOptions = getAvailableOptions(channel, DATAPOINT_NAME_BACKLIGHT);
69             String[] availableUnitOptions = getAvailableOptions(channel, DATAPOINT_NAME_UNIT);
70
71             String deviceAddress = channel.getDevice().getAddress();
72             if (logger.isDebugEnabled()) {
73                 logger.debug("Remote control '{}' supports these beep options: {}", deviceAddress,
74                         availableBeepOptions);
75                 logger.debug("Remote control '{}' supports these backlight options: {}", deviceAddress,
76                         availableBacklightOptions);
77                 logger.debug("Remote control '{}' supports these unit options: {}", deviceAddress,
78                         availableUnitOptions);
79                 logger.debug("Remote control '{}' supports these symbols: {}", deviceAddress, symbols);
80             }
81
82             if (options != null) {
83                 for (String parameter : options) {
84                     logger.debug("Parsing remote control option '{}'", parameter);
85                     beep = getIntParameter(availableBeepOptions, beep, parameter, DATAPOINT_NAME_BEEP, deviceAddress);
86                     backlight = getIntParameter(availableBacklightOptions, backlight, parameter,
87                             DATAPOINT_NAME_BACKLIGHT, deviceAddress);
88                     unit = getIntParameter(availableUnitOptions, unit, parameter, DATAPOINT_NAME_UNIT, deviceAddress);
89
90                     if (findInArray(availableSymbols, parameter) != IDX_NOT_FOUND) {
91                         logger.debug("Symbol '{}' found for remote control '{}'", parameter, deviceAddress);
92                         symbols.add(parameter);
93                     }
94                 }
95             }
96         }
97         return null;
98     }
99
100     /**
101      * Returns the first found parameter index of the options.
102      */
103     private int getIntParameter(String[] options, int currentValue, String parameter, String parameterName,
104             String deviceAddress) {
105         int idx = findInArray(options, parameter);
106         if (idx != IDX_NOT_FOUND) {
107             if (currentValue == 0) {
108                 logger.debug("{} option '{}' found at index {} for remote control '{}'", parameterName, parameter,
109                         idx + 1, deviceAddress);
110                 return idx + 1;
111             } else {
112                 logger.warn("{} option already set for remote control '{}', ignoring '{}'!", parameterName,
113                         deviceAddress, parameter);
114                 return currentValue;
115             }
116         } else {
117             return currentValue;
118         }
119     }
120
121     /**
122      * Returns all possible options from the given datapoint.
123      */
124     private String[] getAvailableOptions(HmChannel channel, String datapointName) {
125         HmDatapointInfo dpInfo = HmDatapointInfo.createValuesInfo(channel, datapointName);
126         HmDatapoint dp = channel.getDatapoint(dpInfo);
127         if (dp != null) {
128             String[] dpOpts = dp.getOptions();
129             String[] options = new String[dpOpts.length - 1];
130             options = Arrays.copyOfRange(dpOpts, 1, dpOpts.length);
131             for (String onOffString : ON_OFF) {
132                 int onIdx = findInArray(options, onOffString);
133                 if (onIdx != IDX_NOT_FOUND) {
134                     options[onIdx] = datapointName + "_" + onOffString;
135                 }
136             }
137             return options;
138         }
139         return new String[0];
140     }
141
142     private int findInArray(String[] arr, String searchString) {
143         if (arr.length == 0) {
144             return IDX_NOT_FOUND;
145         }
146         for (int i = 0; i < arr.length; i++) {
147             if (arr[i].equals(searchString)) {
148                 return i;
149             }
150         }
151         return IDX_NOT_FOUND;
152     }
153
154     /**
155      * Returns all possible symbols from the remote control.
156      */
157     private String[] getAvailableSymbols(HmChannel channel) {
158         List<String> symbols = new ArrayList<>();
159         for (HmDatapoint datapoint : channel.getDatapoints()) {
160             if (!datapoint.isReadOnly() && datapoint.isBooleanType()
161                     && datapoint.getParamsetType() == HmParamsetType.VALUES
162                     && !DATAPOINT_NAME_SUBMIT.equals(datapoint.getName())
163                     && !DATAPOINT_NAME_INSTALL_TEST.equals(datapoint.getName())) {
164                 symbols.add(datapoint.getName());
165             }
166         }
167         return symbols.toArray(new String[0]);
168     }
169
170     /**
171      * Returns the parsed text.
172      */
173     public String getText() {
174         return text;
175     }
176
177     /**
178      * Returns the parsed beep value.
179      */
180     public int getBeep() {
181         return beep;
182     }
183
184     /**
185      * Returns the parsed backlight value.
186      */
187     public int getBacklight() {
188         return backlight;
189     }
190
191     /**
192      * Returns the parsed unit value.
193      */
194     public int getUnit() {
195         return unit;
196     }
197
198     /**
199      * Returns the parsed symbols.
200      */
201     public List<String> getSymbols() {
202         return symbols;
203     }
204 }