2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.loxone.internal.controls;
15 import static org.openhab.binding.loxone.internal.LxBindingConstants.*;
17 import java.io.IOException;
18 import java.math.BigDecimal;
19 import java.util.ArrayList;
20 import java.util.List;
22 import org.openhab.binding.loxone.internal.types.LxState;
23 import org.openhab.binding.loxone.internal.types.LxTags;
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.library.types.UpDownType;
28 import org.openhab.core.thing.ChannelUID;
29 import org.openhab.core.thing.type.ChannelTypeUID;
30 import org.openhab.core.types.Command;
31 import org.openhab.core.types.StateDescriptionFragmentBuilder;
32 import org.openhab.core.types.StateOption;
35 * A Light Controller type of control on Loxone Miniserver.
37 * According to Loxone API documentation, a light controller is one of following functional blocks:
39 * <li>Lighting Controller
40 * <li>Hotel Lighting Controller
43 * @author Pawel Pieczul - initial contribution
46 class LxControlLightController extends LxControl {
48 static class Factory extends LxControlInstance {
50 LxControl create(LxUuid uuid) {
51 return new LxControlLightController(uuid);
56 return "lightcontroller";
61 * Number of scenes supported by the Miniserver. Indexing starts with 0 to NUM_OF_SCENES-1.
63 private static final int NUM_OF_SCENES = 10;
66 * Current active scene number (0-9)
68 private static final String STATE_ACTIVE_SCENE = "activescene";
70 * List of available scenes (public state, so user can monitor scene list updates)
72 private static final String STATE_SCENE_LIST = "scenelist";
74 * Command string used to set control's state to ON
76 private static final String CMD_ON = "On";
78 * Command string used to set control's state to OFF
80 private static final String CMD_OFF = "Off";
82 * Command string used to go to the next scene
84 private static final String CMD_NEXT_SCENE = "plus";
86 * Command string used to go to the previous scene
88 private static final String CMD_PREVIOUS_SCENE = "minus";
89 private static final int SCENE_ALL_ON = 9;
91 private List<StateOption> sceneNames = new ArrayList<>();
92 private ChannelUID channelId;
94 private LxControlLightController(LxUuid uuid) {
99 public void initialize(LxControlConfig config) {
100 super.initialize(config);
101 tags.addAll(LxTags.SCENE);
102 // add only channel, state description will be added later when a control state update message is received
103 channelId = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_LIGHT_CTRL),
104 defaultChannelLabel, "Light controller", tags, this::handleCommands, this::getChannelState);
107 private void handleCommands(Command command) throws IOException {
108 if (command instanceof OnOffType) {
109 if ((OnOffType) command == OnOffType.ON) {
114 } else if (command instanceof UpDownType) {
115 if ((UpDownType) command == UpDownType.UP) {
116 sendAction(CMD_NEXT_SCENE);
118 sendAction(CMD_PREVIOUS_SCENE);
120 } else if (command instanceof DecimalType) {
121 int scene = ((DecimalType) command).intValue();
122 if (scene == SCENE_ALL_ON) {
124 } else if (scene >= 0 && scene < NUM_OF_SCENES) {
125 sendAction(Long.toString(scene));
130 private DecimalType getChannelState() {
131 Double value = getStateDoubleValue(STATE_ACTIVE_SCENE);
132 if (value != null && value >= 0 && value < NUM_OF_SCENES) {
133 return new DecimalType(value);
139 * Get scene names from new state value received from the Miniserver
142 public void onStateChange(LxState state) {
143 if (STATE_SCENE_LIST.equals(state.getName()) && channelId != null) {
144 Object value = state.getStateValue();
145 if (value instanceof String) {
147 String[] scenes = ((String) value).split(",");
148 for (String line : scenes) {
149 line = line.replaceAll("\"", "");
150 String[] params = line.split("=");
151 if (params.length == 2) {
152 sceneNames.add(new StateOption(params[0], params[1]));
155 addChannelStateDescriptionFragment(channelId,
156 StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.ZERO)
157 .withMaximum(new BigDecimal(NUM_OF_SCENES - 1)).withStep(BigDecimal.ONE)
158 .withReadOnly(false).withOptions(sceneNames).build());
161 super.onStateChange(state);