]> git.basschouten.com Git - openhab-addons.git/blob
9ad2bbb92db3788d1a9fe915134ac9de2383c015
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.List;
20
21 import org.apache.commons.lang.ArrayUtils;
22 import org.apache.commons.lang.StringUtils;
23 import org.openhab.binding.homematic.internal.model.HmChannel;
24 import org.openhab.binding.homematic.internal.model.HmDatapoint;
25 import org.openhab.binding.homematic.internal.model.HmDatapointInfo;
26 import org.openhab.binding.homematic.internal.model.HmParamsetType;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Extracts the possible options from the remote control metadata and parses the DISPLAY_OPTIONS virtual datapoint.
32  *
33  * @author Gerhard Riegler - Initial contribution
34  */
35
36 public class DisplayOptionsParser extends CommonRpcParser<Object, Void> {
37     private final Logger logger = LoggerFactory.getLogger(DisplayOptionsParser.class);
38     private static final String[] onOff = new String[] { "ON", "OFF" };
39
40     private HmChannel channel;
41     private String text;
42     private int beep = 0;
43     private int backlight = 0;
44     private int unit = 0;
45     private List<String> symbols = new ArrayList<>();
46
47     public DisplayOptionsParser(HmChannel channel) {
48         this.channel = channel;
49     }
50
51     @Override
52     public Void parse(Object value) throws IOException {
53         String optionsString = StringUtils.remove(toString(value), ' ');
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 = StringUtils.split(optionsString, ",");
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 (ArrayUtils.contains(availableSymbols, parameter)) {
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 = ArrayUtils.indexOf(options, parameter);
106         if (idx != -1) {
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[] options = (String[]) ArrayUtils.remove(dp.getOptions(), 0);
129             for (String onOffString : onOff) {
130                 int onIdx = ArrayUtils.indexOf(options, onOffString);
131                 if (onIdx != -1) {
132                     options[onIdx] = datapointName + "_" + onOffString;
133                 }
134             }
135             return options;
136         }
137         return new String[0];
138     }
139
140     /**
141      * Returns all possible symbols from the remote control.
142      */
143     private String[] getAvailableSymbols(HmChannel channel) {
144         List<String> symbols = new ArrayList<>();
145         for (HmDatapoint datapoint : channel.getDatapoints()) {
146             if (!datapoint.isReadOnly() && datapoint.isBooleanType()
147                     && datapoint.getParamsetType() == HmParamsetType.VALUES
148                     && !DATAPOINT_NAME_SUBMIT.equals(datapoint.getName())
149                     && !DATAPOINT_NAME_INSTALL_TEST.equals(datapoint.getName())) {
150                 symbols.add(datapoint.getName());
151             }
152         }
153         return symbols.toArray(new String[0]);
154     }
155
156     /**
157      * Returns the parsed text.
158      */
159     public String getText() {
160         return text;
161     }
162
163     /**
164      * Returns the parsed beep value.
165      */
166     public int getBeep() {
167         return beep;
168     }
169
170     /**
171      * Returns the parsed backlight value.
172      */
173     public int getBacklight() {
174         return backlight;
175     }
176
177     /**
178      * Returns the parsed unit value.
179      */
180     public int getUnit() {
181         return unit;
182     }
183
184     /**
185      * Returns the parsed symbols.
186      */
187     public List<String> getSymbols() {
188         return symbols;
189     }
190 }