]> git.basschouten.com Git - openhab-addons.git/blob
a18d2610feb0f642bef9d2121dd33205ded745c6
[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.loxone.internal.controls;
14
15 import static org.openhab.binding.loxone.internal.LxBindingConstants.*;
16
17 import java.io.IOException;
18 import java.math.BigDecimal;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.stream.Collectors;
23
24 import org.openhab.binding.loxone.internal.types.LxUuid;
25 import org.openhab.core.library.types.DecimalType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.type.ChannelTypeUID;
29 import org.openhab.core.types.Command;
30 import org.openhab.core.types.StateDescriptionFragmentBuilder;
31 import org.openhab.core.types.StateOption;
32
33 /**
34  * A radio-button type of control on Loxone Miniserver.
35  *
36  * @author Pawel Pieczul - initial contribution
37  *
38  */
39 class LxControlRadio extends LxControl {
40
41     static class Factory extends LxControlInstance {
42         @Override
43         LxControl create(LxUuid uuid) {
44             return new LxControlRadio(uuid);
45         }
46
47         @Override
48         String getType() {
49             return "radio";
50         }
51     }
52
53     /**
54      * Number of outputs a radio controller may have
55      */
56     private static final int MAX_RADIO_OUTPUTS = 16;
57
58     /**
59      * Radio-button has one state that is a number representing current active output
60      */
61     private static final String STATE_ACTIVE_OUTPUT = "activeoutput";
62
63     /**
64      * Command string used to set radio button to all outputs off
65      */
66     private static final String CMD_RESET = "reset";
67
68     private Map<String, String> outputsMap;
69
70     @Override
71     public void initialize(LxControlConfig config) {
72         super.initialize(config);
73         // add both channel and state description (all needed configuration is available)
74         ChannelUID cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RADIO_BUTTON),
75                 defaultChannelLabel, "Radio button", tags, this::handleCommands, this::getChannelState);
76
77         if (details != null) {
78             List<StateOption> outputs = new ArrayList<>();
79             if (details.outputs != null) {
80                 outputsMap = details.outputs;
81                 outputs = details.outputs.entrySet().stream().map(e -> new StateOption(e.getKey(), e.getValue()))
82                         .collect(Collectors.toList());
83             }
84             if (details.allOff != null && !details.allOff.isEmpty()) {
85                 outputs.add(new StateOption("0", details.allOff));
86                 outputsMap.put("0", details.allOff);
87             }
88             addChannelStateDescriptionFragment(cid,
89                     StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.ZERO)
90                             .withMaximum(new BigDecimal(MAX_RADIO_OUTPUTS)).withStep(BigDecimal.ONE).withReadOnly(false)
91                             .withOptions(outputs).build());
92         }
93     }
94
95     private LxControlRadio(LxUuid uuid) {
96         super(uuid);
97     }
98
99     private void handleCommands(Command command) throws IOException {
100         if (((command instanceof OnOffType && (OnOffType) command == OnOffType.OFF) || DecimalType.ZERO.equals(command))
101                 && outputsMap.containsKey("0")) {
102             sendAction(CMD_RESET);
103         } else if (command instanceof DecimalType) {
104             DecimalType output = (DecimalType) command;
105             if (outputsMap.containsKey(output.toString())) {
106                 sendAction(String.valueOf(output.intValue()));
107             }
108         }
109     }
110
111     private DecimalType getChannelState() {
112         Double output = getStateDoubleValue(STATE_ACTIVE_OUTPUT);
113         if (output != null && output % 1 == 0 && outputsMap.containsKey(String.valueOf(output.intValue()))) {
114             return new DecimalType(output);
115         }
116         return null;
117     }
118 }