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.hue.internal.action;
15 import java.lang.reflect.Method;
16 import java.lang.reflect.Proxy;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.hue.internal.handler.HueLightHandler;
21 import org.openhab.core.automation.annotation.ActionInput;
22 import org.openhab.core.automation.annotation.RuleAction;
23 import org.openhab.core.library.types.DecimalType;
24 import org.openhab.core.thing.binding.ThingActions;
25 import org.openhab.core.thing.binding.ThingActionsScope;
26 import org.openhab.core.thing.binding.ThingHandler;
27 import org.openhab.core.types.Command;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * The {@link LightActions} defines the thing actions for the hue binding.
34 * <b>Note:</b>The static method <b>invokeMethodOf</b> handles the case where
35 * the test <i>actions instanceof LightActions</i> fails. This test can fail
36 * due to an issue in openHAB core v2.5.0 where the {@link LightActions} class
37 * can be loaded by a different classloader than the <i>actions</i> instance.
39 * @author Jochen Leopold - Initial contribution
40 * @author Laurent Garnier - new method invokeMethodOf + interface ILightActions
42 @ThingActionsScope(name = "hue")
44 public class LightActions implements ThingActions, ILightActions {
45 private final Logger logger = LoggerFactory.getLogger(LightActions.class);
46 private @Nullable HueLightHandler handler;
49 public void setThingHandler(@Nullable ThingHandler handler) {
50 this.handler = (HueLightHandler) handler;
54 public @Nullable ThingHandler getThingHandler() {
59 @RuleAction(label = "@text/actionLabel", description = "@text/actionDesc")
60 public void fadingLightCommand(
61 @ActionInput(name = "channel", label = "@text/actionInputChannelLabel", description = "@text/actionInputChannelDesc") @Nullable String channel,
62 @ActionInput(name = "command", label = "@text/actionInputCommandLabel", description = "@text/actionInputCommandDesc") @Nullable Command command,
63 @ActionInput(name = "fadeTime", label = "@text/actionInputFadeTimeLabel", description = "@text/actionInputFadeTimeDesc") @Nullable DecimalType fadeTime) {
64 HueLightHandler lightHandler = handler;
65 if (lightHandler == null) {
66 logger.warn("Hue Action service ThingHandler is null!");
70 if (channel == null) {
71 logger.debug("skipping Hue fadingLightCommand to channel '{}' due to null value.", channel);
75 if (command == null) {
76 logger.debug("skipping Hue fadingLightCommand to command '{}' due to null value.", command);
79 if (fadeTime == null) {
80 logger.debug("skipping Hue fadingLightCommand to fadeTime '{}' due to null value.", fadeTime);
84 lightHandler.handleCommand(channel, command, fadeTime.longValue());
85 logger.debug("send LightAction to {} with {}ms of fadeTime", channel, fadeTime);
88 private static ILightActions invokeMethodOf(@Nullable ThingActions actions) {
89 if (actions == null) {
90 throw new IllegalArgumentException("actions cannot be null");
92 if (actions.getClass().getName().equals(LightActions.class.getName())) {
93 if (actions instanceof ILightActions) {
94 return (ILightActions) actions;
96 return (ILightActions) Proxy.newProxyInstance(ILightActions.class.getClassLoader(),
97 new Class[] { ILightActions.class }, (Object proxy, Method method, Object[] args) -> {
98 Method m = actions.getClass().getDeclaredMethod(method.getName(),
99 method.getParameterTypes());
100 return m.invoke(actions, args);
104 throw new IllegalArgumentException("Actions is not an instance of LightActions");
107 public static void fadingLightCommand(@Nullable ThingActions actions, @Nullable String channel,
108 @Nullable Command command, @Nullable DecimalType fadeTime) {
109 invokeMethodOf(actions).fadingLightCommand(channel, command, fadeTime);