]> git.basschouten.com Git - openhab-addons.git/blob
b5eb8a102a307821b92e165c9935c65c42ffa6c1
[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.milight.internal.handler;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.binding.milight.internal.MilightBindingConstants;
17 import org.openhab.binding.milight.internal.MilightThingState;
18 import org.openhab.binding.milight.internal.protocol.MilightV6SessionManager;
19 import org.openhab.binding.milight.internal.protocol.ProtocolConstants;
20 import org.openhab.binding.milight.internal.protocol.QueueItem;
21 import org.openhab.binding.milight.internal.protocol.QueuedSend;
22 import org.openhab.core.thing.ChannelUID;
23 import org.openhab.core.thing.Thing;
24 import org.openhab.core.types.Command;
25 import org.openhab.core.types.RefreshType;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Implements basic V6 bulb functionally. But commands are different for different v6 bulbs, so almost all the work is
31  * done in subclasses.
32  *
33  * @author David Graeff - Initial contribution
34  */
35 @NonNullByDefault
36 public abstract class AbstractLedV6Handler extends AbstractLedHandler {
37     protected final Logger logger = LoggerFactory.getLogger(AbstractLedV6Handler.class);
38
39     protected static final int MAX_BR = 100; // Maximum brightness (0x64)
40     protected static final int MAX_SAT = 100; // Maximum saturation (0x64)
41     protected static final int MAX_TEMP = 100; // Maximum colour temperature (0x64)
42
43     protected @NonNullByDefault({}) MilightV6SessionManager session;
44
45     public AbstractLedV6Handler(Thing thing, QueuedSend sendQueue, int typeOffset) {
46         super(thing, sendQueue, typeOffset);
47     }
48
49     @Override
50     protected void start(AbstractBridgeHandler handler) {
51         BridgeV6Handler h = (BridgeV6Handler) handler;
52         session = h.getSessionManager();
53     }
54
55     protected abstract byte getAddr();
56
57     protected abstract byte getBrCmd();
58
59     @Override
60     public void setHSB(int hue, int saturation, int brightness, MilightThingState state) {
61         if (hue > 360 || hue < 0) {
62             logger.error("Hue argument out of range");
63             return;
64         }
65
66         // 0xFF = Red, D9 = Lavender, BA = Blue, 85 = Aqua, 7A = Green, 54 = Lime, 3B = Yellow, 1E = Orange
67         // we have to map [0,360] to [0,0xFF], where red equals hue=0 and the milight color 0xFF (=255)
68         // Integer milightColorNo = (256 + 0xFF - (int) (hue / 360.0 * 255.0)) % 256;
69
70         // Compute destination hue and current hue value, each mapped to 256 values.
71         // int cHue = state.hue360 * 255 / 360; // map to 256 values
72         int dHue = hue * 255 / 360; // map to 256 values
73         sendRepeatableCat(ProtocolConstants.CAT_COLOR_SET, 1, dHue, dHue, dHue, dHue);
74
75         state.hue360 = hue;
76
77         if (brightness != -1) {
78             setBrightness(brightness, state);
79         }
80
81         if (saturation != -1) {
82             setSaturation(saturation, state);
83         }
84     }
85
86     @Override
87     public void setBrightness(int newvalue, MilightThingState state) {
88         int value = Math.min(Math.max(newvalue, 0), 100);
89
90         if (value == 0) {
91             setPower(false, state);
92         } else if (state.brightness == 0) {
93             // If if was dimmed to minimum (off), turn it on again
94             setPower(true, state);
95         }
96
97         int br = (value * MAX_BR) / 100;
98         br = Math.min(br, MAX_BR);
99         br = Math.max(br, 0);
100         sendRepeatableCat(ProtocolConstants.CAT_BRIGHTNESS_SET, getBrCmd(), br);
101
102         state.brightness = value;
103     }
104
105     @Override
106     public void changeColorTemperature(int colorTempRelative, MilightThingState state) {
107         if (!session.isValid()) {
108             logger.error("Bridge communication session not valid yet!");
109             return;
110         }
111
112         if (colorTempRelative == 0) {
113             return;
114         }
115
116         int ct = (state.colorTemperature * MAX_TEMP) / 100 + colorTempRelative;
117         ct = Math.min(ct, MAX_TEMP);
118         ct = Math.max(ct, 0);
119         setColorTemperature(ct * 100 / MAX_TEMP, state);
120     }
121
122     @Override
123     public void changeBrightness(int relativeBrightness, MilightThingState state) {
124         if (!session.isValid()) {
125             logger.error("Bridge communication session not valid yet!");
126             return;
127         }
128
129         if (relativeBrightness == 0) {
130             return;
131         }
132
133         int br = (state.brightness * MAX_BR) / 100 + relativeBrightness;
134         br = Math.min(br, MAX_BR);
135         br = Math.max(br, 0);
136
137         setBrightness(br * 100 / MAX_BR, state);
138     }
139
140     @Override
141     public void changeSaturation(int relativeSaturation, MilightThingState state) {
142         if (!session.isValid()) {
143             logger.error("Bridge communication session not valid yet!");
144             return;
145         }
146
147         if (relativeSaturation == 0) {
148             return;
149         }
150
151         int br = (state.brightness * MAX_BR) / 100 + relativeSaturation;
152         br = Math.min(br, MAX_BR);
153         br = Math.max(br, 0);
154
155         setSaturation(br * 100 / MAX_BR, state);
156     }
157
158     @Override
159     public void previousAnimationMode(MilightThingState state) {
160         if (!session.isValid()) {
161             logger.error("Bridge communication session not valid yet!");
162             return;
163         }
164
165         int mode = state.animationMode - 1;
166         mode = Math.min(mode, 9);
167         mode = Math.max(mode, 1);
168
169         setLedMode(mode, state);
170     }
171
172     @Override
173     public void nextAnimationMode(MilightThingState state) {
174         if (!session.isValid()) {
175             logger.error("Bridge communication session not valid yet!");
176             return;
177         }
178
179         int mode = state.animationMode + 1;
180         mode = Math.min(mode, 9);
181         mode = Math.max(mode, 1);
182
183         setLedMode(mode, state);
184     }
185
186     @Override
187     public void handleCommand(ChannelUID channelUID, Command command) {
188         if (command instanceof RefreshType) {
189             super.handleCommand(channelUID, command);
190             return;
191         }
192
193         switch (channelUID.getId()) {
194             case MilightBindingConstants.CHANNEL_LINKLED: {
195                 sendQueue.queue(new QueueItem(socket, uidc(ProtocolConstants.CAT_LINK),
196                         session.makeLink(getAddr(), config.zone, true), true, delayTimeMS, repeatTimes, address, port));
197                 break;
198             }
199             case MilightBindingConstants.CHANNEL_UNLINKLED: {
200                 sendQueue.queue(new QueueItem(socket, uidc(ProtocolConstants.CAT_LINK),
201                         session.makeLink(getAddr(), config.zone, false), true, delayTimeMS, repeatTimes, address,
202                         port));
203                 break;
204             }
205             default:
206                 super.handleCommand(channelUID, command);
207         }
208     }
209
210     protected void sendNonRepeatable(int... data) {
211         sendQueue.queue(QueueItem.createNonRepeatable(socket, delayTimeMS, address, port,
212                 session.makeCommand(getAddr(), config.zone, data)));
213     }
214
215     protected void sendRepeatableCat(int cat, int... data) {
216         sendQueue.queue(new QueueItem(socket, uidc(cat), session.makeCommand(getAddr(), config.zone, data), true,
217                 delayTimeMS, repeatTimes, address, port));
218     }
219
220     protected void sendRepeatable(int... data) {
221         sendQueue.queue(QueueItem.createRepeatable(socket, delayTimeMS, repeatTimes, address, port,
222                 session.makeCommand(getAddr(), config.zone, data)));
223     }
224 }