]> git.basschouten.com Git - openhab-addons.git/blob
a884120fd3d655ea43d89f049ce43ff3fcd82c47
[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.openhab.binding.milight.internal.MilightThingState;
16 import org.openhab.binding.milight.internal.protocol.ProtocolConstants;
17 import org.openhab.binding.milight.internal.protocol.QueuedSend;
18 import org.openhab.core.thing.Thing;
19
20 /**
21  * Implements functionality for the RGB/White bulbs for protocol version 3.
22  * Color temperature and saturation are not supported for this type of bulbs.
23  *
24  * @author David Graeff - Initial contribution
25  */
26 public class MilightV3RGBWHandler extends AbstractLedV3Handler {
27     protected static final int BRIGHTNESS_LEVELS = 26;
28
29     private static final byte COMMAND_ON[] = { (byte) 0x42, (byte) 0x45, (byte) 0x47, (byte) 0x49, (byte) 0x4B };
30     private static final byte COMMAND_OFF[] = { (byte) 0x41, (byte) 0x46, (byte) 0x48, (byte) 0x4A, (byte) 0x4C };
31     private static final byte COMMAND_WHITEMODE[] = { (byte) 0xC2, (byte) 0xC5, (byte) 0xC7, (byte) 0xC9, (byte) 0xCB };
32     private static final byte NIGHTMODE_FIRST[] = { 0x41, 0x46, 0x48, 0x4A, 0x4C };
33     private static final byte NIGHTMODE_SECOND[] = { (byte) 0xC1, (byte) 0xC6, (byte) 0xC8, (byte) 0xCA, (byte) 0xCC };
34     private static final byte NEXT_ANIMATION_MODE[] = { 0x4D, 0x00, 0x55 };
35
36     public MilightV3RGBWHandler(Thing thing, QueuedSend sendQueue) {
37         super(thing, sendQueue, 10);
38     }
39
40     // We have no real saturation control for RGBW bulbs. If the saturation is under a 50% threshold
41     // we just change to white mode instead.
42     @Override
43     public void setHSB(int hue, int saturation, int brightness, MilightThingState state) {
44         if (saturation < 50) {
45             whiteMode(state);
46         } else {
47             state.hue360 = hue;
48             final byte messageBytes[] = new byte[] { 0x40, makeColor(hue), 0x55 };
49             final byte cOn[] = { COMMAND_ON[config.zone], 0x00, 0x55 };
50             sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_COLOR_SET), cOn).addRepeatable(messageBytes));
51         }
52
53         if (brightness != -1) {
54             setBrightness(brightness, state);
55         }
56     }
57
58     @Override
59     public void setPower(boolean on, MilightThingState state) {
60         if (on) {
61             sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_POWER_MODE),
62                     new byte[] { COMMAND_ON[config.zone], 0x00, 0x55 }));
63         } else {
64             sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_POWER_MODE),
65                     new byte[] { COMMAND_OFF[config.zone], 0x00, 0x55 }));
66         }
67     }
68
69     @Override
70     public void whiteMode(MilightThingState state) {
71         final byte cOn[] = { COMMAND_ON[config.zone], 0x00, 0x55 };
72         final byte cWhite[] = { COMMAND_WHITEMODE[config.zone], 0x00, 0x55 };
73         sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_WHITEMODE), cOn).addRepeatable(cWhite));
74     }
75
76     @Override
77     public void nightMode(MilightThingState state) {
78         final byte cN1[] = { NIGHTMODE_FIRST[config.zone], 0x00, 0x55 };
79         final byte cN2[] = { NIGHTMODE_SECOND[config.zone], 0x00, 0x55 };
80         sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_POWER_MODE), cN1).addRepeatable(cN2));
81     }
82
83     @Override
84     public void setColorTemperature(int colorTemp, MilightThingState state) {
85     }
86
87     @Override
88     public void changeColorTemperature(int colorTempRelative, MilightThingState state) {
89     }
90
91     @Override
92     public void setBrightness(int newvalue, MilightThingState state) {
93         int value = Math.min(Math.max(newvalue, 0), 100);
94
95         if (value == 0) {
96             state.brightness = value;
97             sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_POWER_MODE),
98                     new byte[] { COMMAND_OFF[config.zone], 0x00, 0x55 }));
99             return;
100         }
101
102         int br = (int) Math.ceil((value * BRIGHTNESS_LEVELS) / 100.0) + 1;
103
104         final byte cOn[] = { COMMAND_ON[config.zone], 0x00, 0x55 };
105         sendQueue.queue(createRepeatable(uidc(ProtocolConstants.CAT_BRIGHTNESS_SET), cOn)
106                 .addRepeatable(new byte[] { 0x4E, (byte) br, 0x55 }));
107
108         state.brightness = value;
109     }
110
111     @Override
112     public void changeBrightness(int relativeBrightness, MilightThingState state) {
113         setBrightness(Math.max(0, Math.min(100, state.brightness + relativeBrightness)), state);
114     }
115
116     @Override
117     public void changeSpeed(int relativeSpeed, MilightThingState state) {
118         if (relativeSpeed == 0) {
119             return;
120         }
121
122         final byte cOn[] = { COMMAND_ON[config.zone], 0x00, 0x55 };
123         final byte cSpeed[] = { (byte) (relativeSpeed > 0 ? 0x44 : 0x43), 0x00, 0x55 };
124         sendQueue.queue(createRepeatable(cOn).addNonRepeatable(cSpeed));
125     }
126
127     // This bulb actually doesn't implement a previous animation mode command. We just use the next mode command
128     // instead.
129     @Override
130     public void previousAnimationMode(MilightThingState state) {
131         final byte cOn[] = { COMMAND_ON[config.zone], 0x00, 0x55 };
132         sendQueue.queue(createRepeatable(cOn).addNonRepeatable(NEXT_ANIMATION_MODE));
133         state.animationMode = (state.animationMode + 1) % (MAX_ANIM_MODES + 1);
134     }
135
136     @Override
137     public void nextAnimationMode(MilightThingState state) {
138         final byte cOn[] = { COMMAND_ON[config.zone], 0x00, 0x55 };
139         sendQueue.queue(createRepeatable(cOn).addNonRepeatable(NEXT_ANIMATION_MODE));
140         state.animationMode = (state.animationMode + 1) % (MAX_ANIM_MODES + 1);
141     }
142 }