2 * Copyright (c) 2010-2020 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.mihome.internal.handler;
15 import static org.openhab.binding.mihome.internal.XiaomiGatewayBindingConstants.*;
17 import org.openhab.binding.mihome.internal.ColorUtil;
18 import org.openhab.core.library.types.DecimalType;
19 import org.openhab.core.library.types.HSBType;
20 import org.openhab.core.library.types.OnOffType;
21 import org.openhab.core.library.types.PercentType;
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.State;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import com.google.gson.JsonObject;
32 * @author Patrick Boos - Initial contribution
33 * @author Dieter Schmidt - Refactor & sound
35 public class XiaomiActorGatewayHandler extends XiaomiActorBaseHandler {
37 private static final int COLOR_TEMPERATURE_MAX = 6500;
38 private static final int COLOR_TEMPERATURE_MIN = 1700;
40 private static final int DEFAULT_BRIGTHNESS_PCENT = 100;
41 private static final int DEFAULT_VOLUME_PCENT = 50;
42 private static final int DEFAULT_COLOR = 0xffffff;
44 private static final String RGB = "rgb";
45 private static final String ILLUMINATION = "illumination";
46 private static final String MID = "mid";
47 private static final String VOL = "vol";
49 private Integer lastBrigthness;
50 private Integer lastVolume;
51 private Integer lastColor;
53 private final Logger logger = LoggerFactory.getLogger(XiaomiActorGatewayHandler.class);
55 public XiaomiActorGatewayHandler(Thing thing) {
57 lastBrigthness = DEFAULT_BRIGTHNESS_PCENT;
58 lastVolume = DEFAULT_VOLUME_PCENT;
59 lastColor = DEFAULT_COLOR;
63 void execute(ChannelUID channelUID, Command command) {
64 switch (channelUID.getId()) {
65 case CHANNEL_BRIGHTNESS:
66 if (command instanceof PercentType) {
67 int newBright = ((PercentType) command).intValue();
68 if (lastBrigthness != newBright) {
69 lastBrigthness = newBright;
70 logger.debug("Set brigthness to {}", lastBrigthness);
71 writeBridgeLightColor(lastColor, lastBrigthness);
73 logger.debug("Do not send this command, value {} already set", newBright);
76 } else if (command instanceof OnOffType) {
77 writeBridgeLightColor(lastColor, command == OnOffType.ON ? lastBrigthness : 0);
82 if (command instanceof HSBType) {
83 lastColor = ((HSBType) command).getRGB() & 0xffffff;
84 writeBridgeLightColor(lastColor, lastBrigthness);
88 case CHANNEL_COLOR_TEMPERATURE:
89 if (command instanceof PercentType) {
90 PercentType colorTemperature = (PercentType) command;
91 int kelvin = (COLOR_TEMPERATURE_MAX - COLOR_TEMPERATURE_MIN) / 100 * colorTemperature.intValue()
92 + COLOR_TEMPERATURE_MIN;
93 int color = ColorUtil.getRGBFromK(kelvin);
94 writeBridgeLightColor(color, lastBrigthness);
95 updateState(CHANNEL_COLOR,
96 HSBType.fromRGB((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff));
100 case CHANNEL_GATEWAY_SOUND:
101 if (command instanceof DecimalType) {
102 writeBridgeRingtone(((DecimalType) command).intValue(), lastVolume);
103 updateState(CHANNEL_GATEWAY_SOUND_SWITCH, OnOffType.ON);
107 case CHANNEL_GATEWAY_SOUND_SWITCH:
108 if (command instanceof OnOffType) {
109 if (((OnOffType) command) == OnOffType.OFF) {
115 case CHANNEL_GATEWAY_VOLUME:
116 if (command instanceof DecimalType) {
117 updateLastVolume((DecimalType) command);
121 // Only gets here, if no condition was met
122 logger.warn("Can't handle command {} on channel {}", command, channelUID);
125 private void updateLastVolume(DecimalType newVolume) {
126 lastVolume = newVolume.intValue();
127 logger.debug("Changed volume to {}", lastVolume);
131 public void handleUpdate(ChannelUID channelUID, State newState) {
132 logger.debug("Update {} for channel {} received", newState, channelUID);
133 switch (channelUID.getId()) {
134 case CHANNEL_BRIGHTNESS:
135 if (newState instanceof PercentType) {
136 lastBrigthness = ((PercentType) newState).intValue();
140 if (newState instanceof HSBType) {
141 lastColor = ((HSBType) newState).getRGB();
144 case CHANNEL_GATEWAY_VOLUME:
145 if (newState instanceof DecimalType) {
146 updateLastVolume((DecimalType) newState);
153 void parseReport(JsonObject data) {
158 void parseHeartbeat(JsonObject data) {
163 void parseReadAck(JsonObject data) {
168 void parseWriteAck(JsonObject data) {
173 void parseDefault(JsonObject data) {
175 long rgb = data.get(RGB).getAsLong();
176 updateState(CHANNEL_BRIGHTNESS, new PercentType((int) (((rgb >> 24) & 0xff))));
177 updateState(CHANNEL_COLOR,
178 HSBType.fromRGB((int) (rgb >> 16) & 0xff, (int) (rgb >> 8) & 0xff, (int) rgb & 0xff));
180 if (data.has(ILLUMINATION)) {
181 int illu = data.get(ILLUMINATION).getAsInt();
182 updateState(CHANNEL_ILLUMINATION, new DecimalType(illu));
186 private void writeBridgeLightColor(int color, int brightness) {
187 long brightnessInt = brightness << 24;
188 writeBridgeLightColor((color & 0xffffff) | brightnessInt & 0xff000000);
191 private void writeBridgeLightColor(long color) {
192 getXiaomiBridgeHandler().writeToBridge(new String[] { RGB }, new Object[] { color });
196 * Play ringtone on Xiaomi Gateway
197 * 0 - 8, 10 - 13, 20 - 29 -- ringtones that come with the system)
198 * > 10001 -- user-defined ringtones
202 private void writeBridgeRingtone(int ringtoneId, int volume) {
203 getXiaomiBridgeHandler().writeToBridge(new String[] { MID, VOL }, new Object[] { ringtoneId, volume });
207 * Stop playing ringtone on Xiaomi Gateway
208 * by setting "mid" parameter to 10000
210 private void stopRingtone() {
211 getXiaomiBridgeHandler().writeToBridge(new String[] { MID }, new Object[] { 10000 });